diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/shared/focus.js | |
parent | Initial commit. (diff) | |
download | thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/shared/focus.js')
-rw-r--r-- | devtools/client/shared/focus.js | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/devtools/client/shared/focus.js b/devtools/client/shared/focus.js new file mode 100644 index 0000000000..6248c69573 --- /dev/null +++ b/devtools/client/shared/focus.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/* + * Simplied selector targetting elements that can receive the focus, full + * version at http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus + */ +const focusableSelector = [ + "a[href]:not([tabindex='-1'])", + "button:not([disabled], [tabindex='-1'])", + "iframe:not([tabindex='-1'])", + "input:not([disabled], [tabindex='-1'])", + "select:not([disabled], [tabindex='-1'])", + "textarea:not([disabled], [tabindex='-1'])", + "[tabindex]:not([tabindex='-1'])", +].join(", "); + +/** + * Wrap and move keyboard focus to first/last focusable element inside a container + * element to prevent the focus from escaping the container. + * + * @param {Array} elms + * focusable elements inside a container + * @param {DOMNode} current + * currently focused element inside containter + * @param {Boolean} back + * direction + * @return {DOMNode} + * newly focused element + */ +function wrapMoveFocus(elms, current, back) { + let next; + + if (elms.length === 0) { + return false; + } + + if (back) { + if (elms.indexOf(current) === 0) { + next = elms[elms.length - 1]; + next.focus(); + } + } else if (elms.indexOf(current) === elms.length - 1) { + next = elms[0]; + next.focus(); + } + + return next; +} + +/** + * Get a list of all elements that are focusable with a keyboard inside the parent element + * + * @param {DOMNode} parentEl + * parent DOM element to be queried + * @return {Array} + * array of focusable children elements inside the parent + */ +function getFocusableElements(parentEl) { + return parentEl + ? Array.from(parentEl.querySelectorAll(focusableSelector)) + : []; +} + +// Make this available to both AMD and CJS environments +define(function (require, exports, module) { + module.exports.focusableSelector = focusableSelector; + exports.wrapMoveFocus = wrapMoveFocus; + exports.getFocusableElements = getFocusableElements; +}); |