diff --git a/core/.eslintrc.json b/core/.eslintrc.json index 5a982db5a2..a133f542bb 100644 --- a/core/.eslintrc.json +++ b/core/.eslintrc.json @@ -20,7 +20,8 @@ "Modernizr": true, "Popper": true, "Sortable": true, - "CKEDITOR": true + "CKEDITOR": true, + "tabbable": true }, "settings": { "react": { diff --git a/core/assets/vendor/tabbable/README.txt b/core/assets/vendor/tabbable/README.txt new file mode 100644 index 0000000000..3800e9dc8f --- /dev/null +++ b/core/assets/vendor/tabbable/README.txt @@ -0,0 +1,15 @@ +Drupal core uses the UMD build of tabbable. +To create this build: +Navigate to the root directory of the tabbable library. + +Ensure that dependencies have been installed: +``` +yarn install +``` + +Build files for production: +``` +yarn build +``` + +This will create an index.umd.min.js file in dist/ that can be used in Drupal. diff --git a/core/assets/vendor/tabbable/index.umd.min.js b/core/assets/vendor/tabbable/index.umd.min.js new file mode 100644 index 0000000000..d980f9ac01 --- /dev/null +++ b/core/assets/vendor/tabbable/index.umd.min.js @@ -0,0 +1,6 @@ +/*! +* tabbable 5.1.3 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):(e="undefined"!=typeof globalThis?globalThis:e||self,function(){var n=e.tabbable,r=e.tabbable={};t(r),r.noConflict=function(){return e.tabbable=n,r}}())}(this,(function(e){"use strict";var t=["input","select","textarea","a[href]","button","[tabindex]","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable="false"])',"details>summary:first-of-type","details"],n=t.join(","),r="undefined"==typeof Element?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector;function o(e,t,o){var i=Array.prototype.slice.apply(e.querySelectorAll(n));return t&&r.call(e,n)&&i.unshift(e),i=i.filter(o)}function i(e){return!(!a(e)||function(e){return function(e){return d(e)&&"radio"===e.type}(e)&&!function(e){if(!e.name)return!0;var t=function(e,t){for(var n=0;nsummary:first-of-type")?e.parentElement:e).matches("details:not([open]) *"))return!0;for(;e;){if("none"===getComputedStyle(e).display)return!0;e=e.parentElement}return!1}(e)||function(e){return"DETAILS"===e.tagName&&Array.prototype.slice.apply(e.children).some((function(e){return"SUMMARY"===e.tagName}))}(e))}var u=t.concat("iframe").join(",");function c(e){var t=parseInt(e.getAttribute("tabindex"),10);return isNaN(t)?function(e){return"true"===e.contentEditable}(e)?0:"AUDIO"!==e.nodeName&&"VIDEO"!==e.nodeName&&"DETAILS"!==e.nodeName||null!==e.getAttribute("tabindex")?e.tabIndex:0:t}function f(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex}function d(e){return"INPUT"===e.tagName}e.focusable=function(e,t){return o(e,(t=t||{}).includeContainer,a)},e.isFocusable=function(e){if(!e)throw new Error("No node provided");return!1!==r.call(e,u)&&a(e)},e.isTabbable=function(e){if(!e)throw new Error("No node provided");return!1!==r.call(e,n)&&i(e)},e.tabbable=function(e,t){var n=[],r=[];return o(e,(t=t||{}).includeContainer,i).forEach((function(e,t){var o=c(e);0===o?n.push(e):r.push({documentOrder:t,tabIndex:o,node:e})})),r.sort(f).map((function(e){return e.node})).concat(n)},Object.defineProperty(e,"__esModule",{value:!0})})); +//# sourceMappingURL=index.umd.min.js.map diff --git a/core/assets/vendor/tabbable/index.umd.min.js.map b/core/assets/vendor/tabbable/index.umd.min.js.map new file mode 100644 index 0000000000..823918c775 --- /dev/null +++ b/core/assets/vendor/tabbable/index.umd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.umd.min.js","sources":["../src/index.js"],"sourcesContent":["let candidateSelectors = [\n 'input',\n 'select',\n 'textarea',\n 'a[href]',\n 'button',\n '[tabindex]',\n 'audio[controls]',\n 'video[controls]',\n '[contenteditable]:not([contenteditable=\"false\"])',\n 'details>summary:first-of-type',\n 'details',\n];\nlet candidateSelector = /* #__PURE__ */ candidateSelectors.join(',');\n\nlet matches =\n typeof Element === 'undefined'\n ? function () {}\n : Element.prototype.matches ||\n Element.prototype.msMatchesSelector ||\n Element.prototype.webkitMatchesSelector;\n\nfunction tabbable(el, options) {\n options = options || {};\n\n let regularTabbables = [];\n let orderedTabbables = [];\n\n let candidates = getCandidates(\n el,\n options.includeContainer,\n isNodeMatchingSelectorTabbable\n );\n\n candidates.forEach(function (candidate, i) {\n let candidateTabindex = getTabindex(candidate);\n if (candidateTabindex === 0) {\n regularTabbables.push(candidate);\n } else {\n orderedTabbables.push({\n documentOrder: i,\n tabIndex: candidateTabindex,\n node: candidate,\n });\n }\n });\n\n let tabbableNodes = orderedTabbables\n .sort(sortOrderedTabbables)\n .map((a) => a.node)\n .concat(regularTabbables);\n\n return tabbableNodes;\n}\n\nfunction focusable(el, options) {\n options = options || {};\n\n let candidates = getCandidates(\n el,\n options.includeContainer,\n isNodeMatchingSelectorFocusable\n );\n\n return candidates;\n}\n\nfunction getCandidates(el, includeContainer, filter) {\n let candidates = Array.prototype.slice.apply(\n el.querySelectorAll(candidateSelector)\n );\n if (includeContainer && matches.call(el, candidateSelector)) {\n candidates.unshift(el);\n }\n candidates = candidates.filter(filter);\n return candidates;\n}\n\nfunction isNodeMatchingSelectorTabbable(node) {\n if (\n !isNodeMatchingSelectorFocusable(node) ||\n isNonTabbableRadio(node) ||\n getTabindex(node) < 0\n ) {\n return false;\n }\n return true;\n}\n\nfunction isTabbable(node) {\n if (!node) {\n throw new Error('No node provided');\n }\n if (matches.call(node, candidateSelector) === false) {\n return false;\n }\n return isNodeMatchingSelectorTabbable(node);\n}\n\nfunction isNodeMatchingSelectorFocusable(node) {\n if (\n node.disabled ||\n isHiddenInput(node) ||\n isHidden(node) ||\n /* For a details element with a summary, the summary element gets the focused */\n isDetailsWithSummary(node)\n ) {\n return false;\n }\n return true;\n}\n\nlet focusableCandidateSelector = /* #__PURE__ */ candidateSelectors\n .concat('iframe')\n .join(',');\nfunction isFocusable(node) {\n if (!node) {\n throw new Error('No node provided');\n }\n if (matches.call(node, focusableCandidateSelector) === false) {\n return false;\n }\n return isNodeMatchingSelectorFocusable(node);\n}\n\nfunction getTabindex(node) {\n let tabindexAttr = parseInt(node.getAttribute('tabindex'), 10);\n\n if (!isNaN(tabindexAttr)) {\n return tabindexAttr;\n }\n\n // Browsers do not return `tabIndex` correctly for contentEditable nodes;\n // so if they don't have a tabindex attribute specifically set, assume it's 0.\n if (isContentEditable(node)) {\n return 0;\n }\n\n // in Chrome,
,