"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.backLastFocusNode = backLastFocusNode; exports.clearLastFocusNode = clearLastFocusNode; exports.getFocusNodeList = getFocusNodeList; exports.limitTabRange = limitTabRange; exports.saveLastFocusNode = saveLastFocusNode; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _isVisible = _interopRequireDefault(require("./isVisible")); function focusable(node) { var includePositive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if ((0, _isVisible.default)(node)) { var nodeName = node.nodeName.toLowerCase(); var isFocusableElement = // Focusable element ['input', 'select', 'textarea', 'button'].includes(nodeName) || // Editable element node.isContentEditable || // Anchor with href element nodeName === 'a' && !!node.getAttribute('href'); // Get tabIndex var tabIndexAttr = node.getAttribute('tabindex'); var tabIndexNum = Number(tabIndexAttr); // Parse as number if validate var tabIndex = null; if (tabIndexAttr && !Number.isNaN(tabIndexNum)) { tabIndex = tabIndexNum; } else if (isFocusableElement && tabIndex === null) { tabIndex = 0; } // Block focusable if disabled if (isFocusableElement && node.disabled) { tabIndex = null; } return tabIndex !== null && (tabIndex >= 0 || includePositive && tabIndex < 0); } return false; } function getFocusNodeList(node) { var includePositive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var res = (0, _toConsumableArray2.default)(node.querySelectorAll('*')).filter(function (child) { return focusable(child, includePositive); }); if (focusable(node, includePositive)) { res.unshift(node); } return res; } var lastFocusElement = null; /** @deprecated Do not use since this may failed when used in async */ function saveLastFocusNode() { lastFocusElement = document.activeElement; } /** @deprecated Do not use since this may failed when used in async */ function clearLastFocusNode() { lastFocusElement = null; } /** @deprecated Do not use since this may failed when used in async */ function backLastFocusNode() { if (lastFocusElement) { try { // 元素可能已经被移动了 lastFocusElement.focus(); /* eslint-disable no-empty */ } catch (e) { // empty } /* eslint-enable no-empty */ } } function limitTabRange(node, e) { if (e.keyCode === 9) { var tabNodeList = getFocusNodeList(node); var lastTabNode = tabNodeList[e.shiftKey ? 0 : tabNodeList.length - 1]; var leavingTab = lastTabNode === document.activeElement || node === document.activeElement; if (leavingTab) { var target = tabNodeList[e.shiftKey ? tabNodeList.length - 1 : 0]; target.focus(); e.preventDefault(); } } }