UNPKG

3.41 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.focusSolver = void 0;
4var solver_1 = require("./solver");
5var DOMutils_1 = require("./utils/DOMutils");
6var all_affected_1 = require("./utils/all-affected");
7var array_1 = require("./utils/array");
8var auto_focus_1 = require("./utils/auto-focus");
9var getActiveElement_1 = require("./utils/getActiveElement");
10var is_1 = require("./utils/is");
11var parenting_1 = require("./utils/parenting");
12var reorderNodes = function (srcNodes, dstNodes) {
13 var remap = new Map();
14 // no Set(dstNodes) for IE11 :(
15 dstNodes.forEach(function (entity) { return remap.set(entity.node, entity); });
16 // remap to dstNodes
17 return srcNodes.map(function (node) { return remap.get(node); }).filter(is_1.isDefined);
18};
19/**
20 * contains the main logic of the `focus-lock` package.
21 *
22 * ! you probably dont need this function !
23 *
24 * given top node(s) and the last active element returns the element to be focused next
25 * @returns element which should be focused to move focus inside
26 * @param topNode
27 * @param lastNode
28 */
29var focusSolver = function (topNode, lastNode) {
30 var activeElement = (0, getActiveElement_1.getActiveElement)((0, array_1.asArray)(topNode).length > 0 ? document : (0, array_1.getFirst)(topNode).ownerDocument);
31 var entries = (0, all_affected_1.getAllAffectedNodes)(topNode).filter(is_1.isNotAGuard);
32 var commonParent = (0, parenting_1.getTopCommonParent)(activeElement || topNode, topNode, entries);
33 var visibilityCache = new Map();
34 var anyFocusable = (0, DOMutils_1.getFocusableNodes)(entries, visibilityCache);
35 var innerElements = anyFocusable.filter(function (_a) {
36 var node = _a.node;
37 return (0, is_1.isNotAGuard)(node);
38 });
39 if (!innerElements[0]) {
40 return undefined;
41 }
42 var outerNodes = (0, DOMutils_1.getFocusableNodes)([commonParent], visibilityCache).map(function (_a) {
43 var node = _a.node;
44 return node;
45 });
46 var orderedInnerElements = reorderNodes(outerNodes, innerElements);
47 // collect inner focusable and separately tabbables
48 var innerFocusables = orderedInnerElements.map(function (_a) {
49 var node = _a.node;
50 return node;
51 });
52 var innerTabbable = orderedInnerElements.filter(function (_a) {
53 var tabIndex = _a.tabIndex;
54 return tabIndex >= 0;
55 }).map(function (_a) {
56 var node = _a.node;
57 return node;
58 });
59 var newId = (0, solver_1.newFocus)(innerFocusables, innerTabbable, outerNodes, activeElement, lastNode);
60 if (newId === solver_1.NEW_FOCUS) {
61 var focusNode =
62 // first try only tabbable, and the fallback to all focusable, as long as at least one element should be picked for focus
63 (0, auto_focus_1.pickAutofocus)(anyFocusable, innerTabbable, (0, parenting_1.allParentAutofocusables)(entries, visibilityCache)) ||
64 (0, auto_focus_1.pickAutofocus)(anyFocusable, innerFocusables, (0, parenting_1.allParentAutofocusables)(entries, visibilityCache));
65 if (focusNode) {
66 return { node: focusNode };
67 }
68 else {
69 console.warn('focus-lock: cannot find any node to move focus into');
70 return undefined;
71 }
72 }
73 if (newId === undefined) {
74 return newId;
75 }
76 return orderedInnerElements[newId];
77};
78exports.focusSolver = focusSolver;