summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/focus.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/client/shared/focus.js
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--devtools/client/shared/focus.js73
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;
+});