You've already forked Epicnabbo-Catalogus-Updated-Daily
828 lines
28 KiB
JavaScript
828 lines
28 KiB
JavaScript
(() => {
|
|
// node_modules/tabbable/dist/index.esm.js
|
|
/*!
|
|
* tabbable 5.2.1
|
|
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
*/
|
|
var candidateSelectors = ["input", "select", "textarea", "a[href]", "button", "[tabindex]", "audio[controls]", "video[controls]", '[contenteditable]:not([contenteditable="false"])', "details>summary:first-of-type", "details"];
|
|
var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
|
|
var matches = typeof Element === "undefined" ? function() {
|
|
} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
var getCandidates = function getCandidates2(el, includeContainer, filter) {
|
|
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
|
if (includeContainer && matches.call(el, candidateSelector)) {
|
|
candidates.unshift(el);
|
|
}
|
|
candidates = candidates.filter(filter);
|
|
return candidates;
|
|
};
|
|
var isContentEditable = function isContentEditable2(node) {
|
|
return node.contentEditable === "true";
|
|
};
|
|
var getTabindex = function getTabindex2(node) {
|
|
var tabindexAttr = parseInt(node.getAttribute("tabindex"), 10);
|
|
if (!isNaN(tabindexAttr)) {
|
|
return tabindexAttr;
|
|
}
|
|
if (isContentEditable(node)) {
|
|
return 0;
|
|
}
|
|
if ((node.nodeName === "AUDIO" || node.nodeName === "VIDEO" || node.nodeName === "DETAILS") && node.getAttribute("tabindex") === null) {
|
|
return 0;
|
|
}
|
|
return node.tabIndex;
|
|
};
|
|
var sortOrderedTabbables = function sortOrderedTabbables2(a, b) {
|
|
return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
|
|
};
|
|
var isInput = function isInput2(node) {
|
|
return node.tagName === "INPUT";
|
|
};
|
|
var isHiddenInput = function isHiddenInput2(node) {
|
|
return isInput(node) && node.type === "hidden";
|
|
};
|
|
var isDetailsWithSummary = function isDetailsWithSummary2(node) {
|
|
var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) {
|
|
return child.tagName === "SUMMARY";
|
|
});
|
|
return r;
|
|
};
|
|
var getCheckedRadio = function getCheckedRadio2(nodes, form) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
if (nodes[i].checked && nodes[i].form === form) {
|
|
return nodes[i];
|
|
}
|
|
}
|
|
};
|
|
var isTabbableRadio = function isTabbableRadio2(node) {
|
|
if (!node.name) {
|
|
return true;
|
|
}
|
|
var radioScope = node.form || node.ownerDocument;
|
|
var queryRadios = function queryRadios2(name) {
|
|
return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
|
|
};
|
|
var radioSet;
|
|
if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
|
|
radioSet = queryRadios(window.CSS.escape(node.name));
|
|
} else {
|
|
try {
|
|
radioSet = queryRadios(node.name);
|
|
} catch (err) {
|
|
console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message);
|
|
return false;
|
|
}
|
|
}
|
|
var checked = getCheckedRadio(radioSet, node.form);
|
|
return !checked || checked === node;
|
|
};
|
|
var isRadio = function isRadio2(node) {
|
|
return isInput(node) && node.type === "radio";
|
|
};
|
|
var isNonTabbableRadio = function isNonTabbableRadio2(node) {
|
|
return isRadio(node) && !isTabbableRadio(node);
|
|
};
|
|
var isHidden = function isHidden2(node, displayCheck) {
|
|
if (getComputedStyle(node).visibility === "hidden") {
|
|
return true;
|
|
}
|
|
var isDirectSummary = matches.call(node, "details>summary:first-of-type");
|
|
var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
|
|
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
|
|
return true;
|
|
}
|
|
if (!displayCheck || displayCheck === "full") {
|
|
while (node) {
|
|
if (getComputedStyle(node).display === "none") {
|
|
return true;
|
|
}
|
|
node = node.parentElement;
|
|
}
|
|
} else if (displayCheck === "non-zero-area") {
|
|
var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height;
|
|
return width === 0 && height === 0;
|
|
}
|
|
return false;
|
|
};
|
|
var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
|
|
if (isInput(node) || node.tagName === "SELECT" || node.tagName === "TEXTAREA" || node.tagName === "BUTTON") {
|
|
var parentNode = node.parentElement;
|
|
while (parentNode) {
|
|
if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
|
|
for (var i = 0; i < parentNode.children.length; i++) {
|
|
var child = parentNode.children.item(i);
|
|
if (child.tagName === "LEGEND") {
|
|
if (child.contains(node)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
parentNode = parentNode.parentElement;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
|
|
if (node.disabled || isHiddenInput(node) || isHidden(node, options.displayCheck) || isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) {
|
|
if (!isNodeMatchingSelectorFocusable(options, node) || isNonTabbableRadio(node) || getTabindex(node) < 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var tabbable = function tabbable2(el, options) {
|
|
options = options || {};
|
|
var regularTabbables = [];
|
|
var orderedTabbables = [];
|
|
var candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
|
candidates.forEach(function(candidate, i) {
|
|
var candidateTabindex = getTabindex(candidate);
|
|
if (candidateTabindex === 0) {
|
|
regularTabbables.push(candidate);
|
|
} else {
|
|
orderedTabbables.push({
|
|
documentOrder: i,
|
|
tabIndex: candidateTabindex,
|
|
node: candidate
|
|
});
|
|
}
|
|
});
|
|
var tabbableNodes = orderedTabbables.sort(sortOrderedTabbables).map(function(a) {
|
|
return a.node;
|
|
}).concat(regularTabbables);
|
|
return tabbableNodes;
|
|
};
|
|
var focusable = function focusable2(el, options) {
|
|
options = options || {};
|
|
var candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
|
|
return candidates;
|
|
};
|
|
var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors.concat("iframe").join(",");
|
|
var isFocusable = function isFocusable2(node, options) {
|
|
options = options || {};
|
|
if (!node) {
|
|
throw new Error("No node provided");
|
|
}
|
|
if (matches.call(node, focusableCandidateSelector) === false) {
|
|
return false;
|
|
}
|
|
return isNodeMatchingSelectorFocusable(options, node);
|
|
};
|
|
|
|
// node_modules/focus-trap/dist/focus-trap.esm.js
|
|
/*!
|
|
* focus-trap 6.6.1
|
|
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
|
|
*/
|
|
function ownKeys(object, enumerableOnly) {
|
|
var keys = Object.keys(object);
|
|
if (Object.getOwnPropertySymbols) {
|
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
if (enumerableOnly) {
|
|
symbols = symbols.filter(function(sym) {
|
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
});
|
|
}
|
|
keys.push.apply(keys, symbols);
|
|
}
|
|
return keys;
|
|
}
|
|
function _objectSpread2(target) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
if (i % 2) {
|
|
ownKeys(Object(source), true).forEach(function(key) {
|
|
_defineProperty(target, key, source[key]);
|
|
});
|
|
} else if (Object.getOwnPropertyDescriptors) {
|
|
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
} else {
|
|
ownKeys(Object(source)).forEach(function(key) {
|
|
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
});
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
function _defineProperty(obj, key, value) {
|
|
if (key in obj) {
|
|
Object.defineProperty(obj, key, {
|
|
value,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
return obj;
|
|
}
|
|
var activeFocusTraps = function() {
|
|
var trapQueue = [];
|
|
return {
|
|
activateTrap: function activateTrap(trap) {
|
|
if (trapQueue.length > 0) {
|
|
var activeTrap = trapQueue[trapQueue.length - 1];
|
|
if (activeTrap !== trap) {
|
|
activeTrap.pause();
|
|
}
|
|
}
|
|
var trapIndex = trapQueue.indexOf(trap);
|
|
if (trapIndex === -1) {
|
|
trapQueue.push(trap);
|
|
} else {
|
|
trapQueue.splice(trapIndex, 1);
|
|
trapQueue.push(trap);
|
|
}
|
|
},
|
|
deactivateTrap: function deactivateTrap(trap) {
|
|
var trapIndex = trapQueue.indexOf(trap);
|
|
if (trapIndex !== -1) {
|
|
trapQueue.splice(trapIndex, 1);
|
|
}
|
|
if (trapQueue.length > 0) {
|
|
trapQueue[trapQueue.length - 1].unpause();
|
|
}
|
|
}
|
|
};
|
|
}();
|
|
var isSelectableInput = function isSelectableInput2(node) {
|
|
return node.tagName && node.tagName.toLowerCase() === "input" && typeof node.select === "function";
|
|
};
|
|
var isEscapeEvent = function isEscapeEvent2(e) {
|
|
return e.key === "Escape" || e.key === "Esc" || e.keyCode === 27;
|
|
};
|
|
var isTabEvent = function isTabEvent2(e) {
|
|
return e.key === "Tab" || e.keyCode === 9;
|
|
};
|
|
var delay = function delay2(fn) {
|
|
return setTimeout(fn, 0);
|
|
};
|
|
var findIndex = function findIndex2(arr, fn) {
|
|
var idx = -1;
|
|
arr.every(function(value, i) {
|
|
if (fn(value)) {
|
|
idx = i;
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
return idx;
|
|
};
|
|
var valueOrHandler = function valueOrHandler2(value) {
|
|
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
params[_key - 1] = arguments[_key];
|
|
}
|
|
return typeof value === "function" ? value.apply(void 0, params) : value;
|
|
};
|
|
var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
|
var doc = document;
|
|
var config = _objectSpread2({
|
|
returnFocusOnDeactivate: true,
|
|
escapeDeactivates: true,
|
|
delayInitialFocus: true
|
|
}, userOptions);
|
|
var state = {
|
|
containers: [],
|
|
tabbableGroups: [],
|
|
nodeFocusedBeforeActivation: null,
|
|
mostRecentlyFocusedNode: null,
|
|
active: false,
|
|
paused: false,
|
|
delayInitialFocusTimer: void 0
|
|
};
|
|
var trap;
|
|
var getOption = function getOption2(configOverrideOptions, optionName, configOptionName) {
|
|
return configOverrideOptions && configOverrideOptions[optionName] !== void 0 ? configOverrideOptions[optionName] : config[configOptionName || optionName];
|
|
};
|
|
var containersContain = function containersContain2(element) {
|
|
return state.containers.some(function(container) {
|
|
return container.contains(element);
|
|
});
|
|
};
|
|
var getNodeForOption = function getNodeForOption2(optionName) {
|
|
var optionValue = config[optionName];
|
|
if (!optionValue) {
|
|
return null;
|
|
}
|
|
var node = optionValue;
|
|
if (typeof optionValue === "string") {
|
|
node = doc.querySelector(optionValue);
|
|
if (!node) {
|
|
throw new Error("`".concat(optionName, "` refers to no known node"));
|
|
}
|
|
}
|
|
if (typeof optionValue === "function") {
|
|
node = optionValue();
|
|
if (!node) {
|
|
throw new Error("`".concat(optionName, "` did not return a node"));
|
|
}
|
|
}
|
|
return node;
|
|
};
|
|
var getInitialFocusNode = function getInitialFocusNode2() {
|
|
var node;
|
|
if (getOption({}, "initialFocus") === false) {
|
|
return false;
|
|
}
|
|
if (getNodeForOption("initialFocus") !== null) {
|
|
node = getNodeForOption("initialFocus");
|
|
} else if (containersContain(doc.activeElement)) {
|
|
node = doc.activeElement;
|
|
} else {
|
|
var firstTabbableGroup = state.tabbableGroups[0];
|
|
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
|
|
node = firstTabbableNode || getNodeForOption("fallbackFocus");
|
|
}
|
|
if (!node) {
|
|
throw new Error("Your focus-trap needs to have at least one focusable element");
|
|
}
|
|
return node;
|
|
};
|
|
var updateTabbableNodes = function updateTabbableNodes2() {
|
|
state.tabbableGroups = state.containers.map(function(container) {
|
|
var tabbableNodes = tabbable(container);
|
|
if (tabbableNodes.length > 0) {
|
|
return {
|
|
container,
|
|
firstTabbableNode: tabbableNodes[0],
|
|
lastTabbableNode: tabbableNodes[tabbableNodes.length - 1]
|
|
};
|
|
}
|
|
return void 0;
|
|
}).filter(function(group) {
|
|
return !!group;
|
|
});
|
|
if (state.tabbableGroups.length <= 0 && !getNodeForOption("fallbackFocus")) {
|
|
throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");
|
|
}
|
|
};
|
|
var tryFocus = function tryFocus2(node) {
|
|
if (node === false) {
|
|
return;
|
|
}
|
|
if (node === doc.activeElement) {
|
|
return;
|
|
}
|
|
if (!node || !node.focus) {
|
|
tryFocus2(getInitialFocusNode());
|
|
return;
|
|
}
|
|
node.focus({
|
|
preventScroll: !!config.preventScroll
|
|
});
|
|
state.mostRecentlyFocusedNode = node;
|
|
if (isSelectableInput(node)) {
|
|
node.select();
|
|
}
|
|
};
|
|
var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) {
|
|
var node = getNodeForOption("setReturnFocus");
|
|
return node ? node : previousActiveElement;
|
|
};
|
|
var checkPointerDown = function checkPointerDown2(e) {
|
|
if (containersContain(e.target)) {
|
|
return;
|
|
}
|
|
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
trap.deactivate({
|
|
returnFocus: config.returnFocusOnDeactivate && !isFocusable(e.target)
|
|
});
|
|
return;
|
|
}
|
|
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
};
|
|
var checkFocusIn = function checkFocusIn2(e) {
|
|
var targetContained = containersContain(e.target);
|
|
if (targetContained || e.target instanceof Document) {
|
|
if (targetContained) {
|
|
state.mostRecentlyFocusedNode = e.target;
|
|
}
|
|
} else {
|
|
e.stopImmediatePropagation();
|
|
tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
|
|
}
|
|
};
|
|
var checkTab = function checkTab2(e) {
|
|
updateTabbableNodes();
|
|
var destinationNode = null;
|
|
if (state.tabbableGroups.length > 0) {
|
|
var containerIndex = findIndex(state.tabbableGroups, function(_ref) {
|
|
var container = _ref.container;
|
|
return container.contains(e.target);
|
|
});
|
|
if (containerIndex < 0) {
|
|
if (e.shiftKey) {
|
|
destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode;
|
|
} else {
|
|
destinationNode = state.tabbableGroups[0].firstTabbableNode;
|
|
}
|
|
} else if (e.shiftKey) {
|
|
var startOfGroupIndex = findIndex(state.tabbableGroups, function(_ref2) {
|
|
var firstTabbableNode = _ref2.firstTabbableNode;
|
|
return e.target === firstTabbableNode;
|
|
});
|
|
if (startOfGroupIndex < 0 && state.tabbableGroups[containerIndex].container === e.target) {
|
|
startOfGroupIndex = containerIndex;
|
|
}
|
|
if (startOfGroupIndex >= 0) {
|
|
var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
|
|
var destinationGroup = state.tabbableGroups[destinationGroupIndex];
|
|
destinationNode = destinationGroup.lastTabbableNode;
|
|
}
|
|
} else {
|
|
var lastOfGroupIndex = findIndex(state.tabbableGroups, function(_ref3) {
|
|
var lastTabbableNode = _ref3.lastTabbableNode;
|
|
return e.target === lastTabbableNode;
|
|
});
|
|
if (lastOfGroupIndex < 0 && state.tabbableGroups[containerIndex].container === e.target) {
|
|
lastOfGroupIndex = containerIndex;
|
|
}
|
|
if (lastOfGroupIndex >= 0) {
|
|
var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
|
|
var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
|
|
destinationNode = _destinationGroup.firstTabbableNode;
|
|
}
|
|
}
|
|
} else {
|
|
destinationNode = getNodeForOption("fallbackFocus");
|
|
}
|
|
if (destinationNode) {
|
|
e.preventDefault();
|
|
tryFocus(destinationNode);
|
|
}
|
|
};
|
|
var checkKey = function checkKey2(e) {
|
|
if (isEscapeEvent(e) && valueOrHandler(config.escapeDeactivates) !== false) {
|
|
e.preventDefault();
|
|
trap.deactivate();
|
|
return;
|
|
}
|
|
if (isTabEvent(e)) {
|
|
checkTab(e);
|
|
return;
|
|
}
|
|
};
|
|
var checkClick = function checkClick2(e) {
|
|
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
return;
|
|
}
|
|
if (containersContain(e.target)) {
|
|
return;
|
|
}
|
|
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
};
|
|
var addListeners = function addListeners2() {
|
|
if (!state.active) {
|
|
return;
|
|
}
|
|
activeFocusTraps.activateTrap(trap);
|
|
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() {
|
|
tryFocus(getInitialFocusNode());
|
|
}) : tryFocus(getInitialFocusNode());
|
|
doc.addEventListener("focusin", checkFocusIn, true);
|
|
doc.addEventListener("mousedown", checkPointerDown, {
|
|
capture: true,
|
|
passive: false
|
|
});
|
|
doc.addEventListener("touchstart", checkPointerDown, {
|
|
capture: true,
|
|
passive: false
|
|
});
|
|
doc.addEventListener("click", checkClick, {
|
|
capture: true,
|
|
passive: false
|
|
});
|
|
doc.addEventListener("keydown", checkKey, {
|
|
capture: true,
|
|
passive: false
|
|
});
|
|
return trap;
|
|
};
|
|
var removeListeners = function removeListeners2() {
|
|
if (!state.active) {
|
|
return;
|
|
}
|
|
doc.removeEventListener("focusin", checkFocusIn, true);
|
|
doc.removeEventListener("mousedown", checkPointerDown, true);
|
|
doc.removeEventListener("touchstart", checkPointerDown, true);
|
|
doc.removeEventListener("click", checkClick, true);
|
|
doc.removeEventListener("keydown", checkKey, true);
|
|
return trap;
|
|
};
|
|
trap = {
|
|
activate: function activate(activateOptions) {
|
|
if (state.active) {
|
|
return this;
|
|
}
|
|
var onActivate = getOption(activateOptions, "onActivate");
|
|
var onPostActivate = getOption(activateOptions, "onPostActivate");
|
|
var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap");
|
|
if (!checkCanFocusTrap) {
|
|
updateTabbableNodes();
|
|
}
|
|
state.active = true;
|
|
state.paused = false;
|
|
state.nodeFocusedBeforeActivation = doc.activeElement;
|
|
if (onActivate) {
|
|
onActivate();
|
|
}
|
|
var finishActivation = function finishActivation2() {
|
|
if (checkCanFocusTrap) {
|
|
updateTabbableNodes();
|
|
}
|
|
addListeners();
|
|
if (onPostActivate) {
|
|
onPostActivate();
|
|
}
|
|
};
|
|
if (checkCanFocusTrap) {
|
|
checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
|
|
return this;
|
|
}
|
|
finishActivation();
|
|
return this;
|
|
},
|
|
deactivate: function deactivate(deactivateOptions) {
|
|
if (!state.active) {
|
|
return this;
|
|
}
|
|
clearTimeout(state.delayInitialFocusTimer);
|
|
state.delayInitialFocusTimer = void 0;
|
|
removeListeners();
|
|
state.active = false;
|
|
state.paused = false;
|
|
activeFocusTraps.deactivateTrap(trap);
|
|
var onDeactivate = getOption(deactivateOptions, "onDeactivate");
|
|
var onPostDeactivate = getOption(deactivateOptions, "onPostDeactivate");
|
|
var checkCanReturnFocus = getOption(deactivateOptions, "checkCanReturnFocus");
|
|
if (onDeactivate) {
|
|
onDeactivate();
|
|
}
|
|
var returnFocus = getOption(deactivateOptions, "returnFocus", "returnFocusOnDeactivate");
|
|
var finishDeactivation = function finishDeactivation2() {
|
|
delay(function() {
|
|
if (returnFocus) {
|
|
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
|
}
|
|
if (onPostDeactivate) {
|
|
onPostDeactivate();
|
|
}
|
|
});
|
|
};
|
|
if (returnFocus && checkCanReturnFocus) {
|
|
checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation);
|
|
return this;
|
|
}
|
|
finishDeactivation();
|
|
return this;
|
|
},
|
|
pause: function pause() {
|
|
if (state.paused || !state.active) {
|
|
return this;
|
|
}
|
|
state.paused = true;
|
|
removeListeners();
|
|
return this;
|
|
},
|
|
unpause: function unpause() {
|
|
if (!state.paused || !state.active) {
|
|
return this;
|
|
}
|
|
state.paused = false;
|
|
updateTabbableNodes();
|
|
addListeners();
|
|
return this;
|
|
},
|
|
updateContainerElements: function updateContainerElements(containerElements) {
|
|
var elementsAsArray = [].concat(containerElements).filter(Boolean);
|
|
state.containers = elementsAsArray.map(function(element) {
|
|
return typeof element === "string" ? doc.querySelector(element) : element;
|
|
});
|
|
if (state.active) {
|
|
updateTabbableNodes();
|
|
}
|
|
return this;
|
|
}
|
|
};
|
|
trap.updateContainerElements(elements);
|
|
return trap;
|
|
};
|
|
|
|
// packages/focus/src/index.js
|
|
function src_default(Alpine) {
|
|
let lastFocused;
|
|
let currentFocused;
|
|
window.addEventListener("focusin", () => {
|
|
lastFocused = currentFocused;
|
|
currentFocused = document.activeElement;
|
|
});
|
|
Alpine.magic("focus", (el) => {
|
|
let within = el;
|
|
return {
|
|
__noscroll: false,
|
|
__wrapAround: false,
|
|
within(el2) {
|
|
within = el2;
|
|
return this;
|
|
},
|
|
withoutScrolling() {
|
|
this.__noscroll = true;
|
|
return this;
|
|
},
|
|
noscroll() {
|
|
this.__noscroll = true;
|
|
return this;
|
|
},
|
|
withWrapAround() {
|
|
this.__wrapAround = true;
|
|
return this;
|
|
},
|
|
wrap() {
|
|
return this.withWrapAround();
|
|
},
|
|
focusable(el2) {
|
|
return isFocusable(el2);
|
|
},
|
|
previouslyFocused() {
|
|
return lastFocused;
|
|
},
|
|
lastFocused() {
|
|
return lastFocused;
|
|
},
|
|
focused() {
|
|
return currentFocused;
|
|
},
|
|
focusables() {
|
|
if (Array.isArray(within))
|
|
return within;
|
|
return focusable(within, {displayCheck: "none"});
|
|
},
|
|
all() {
|
|
return this.focusables();
|
|
},
|
|
isFirst(el2) {
|
|
let els = this.all();
|
|
return els[0] && els[0].isSameNode(el2);
|
|
},
|
|
isLast(el2) {
|
|
let els = this.all();
|
|
return els.length && els.slice(-1)[0].isSameNode(el2);
|
|
},
|
|
getFirst() {
|
|
return this.all()[0];
|
|
},
|
|
getLast() {
|
|
return this.all().slice(-1)[0];
|
|
},
|
|
getNext() {
|
|
let list = this.all();
|
|
let current = document.activeElement;
|
|
if (list.indexOf(current) === -1)
|
|
return;
|
|
if (this.__wrapAround && list.indexOf(current) === list.length - 1) {
|
|
return list[0];
|
|
}
|
|
return list[list.indexOf(current) + 1];
|
|
},
|
|
getPrevious() {
|
|
let list = this.all();
|
|
let current = document.activeElement;
|
|
if (list.indexOf(current) === -1)
|
|
return;
|
|
if (this.__wrapAround && list.indexOf(current) === 0) {
|
|
return list.slice(-1)[0];
|
|
}
|
|
return list[list.indexOf(current) - 1];
|
|
},
|
|
first() {
|
|
this.focus(this.getFirst());
|
|
},
|
|
last() {
|
|
this.focus(this.getLast());
|
|
},
|
|
next() {
|
|
this.focus(this.getNext());
|
|
},
|
|
previous() {
|
|
this.focus(this.getPrevious());
|
|
},
|
|
prev() {
|
|
return this.previous();
|
|
},
|
|
focus(el2) {
|
|
if (!el2)
|
|
return;
|
|
setTimeout(() => {
|
|
if (!el2.hasAttribute("tabindex"))
|
|
el2.setAttribute("tabindex", "0");
|
|
el2.focus({preventScroll: this._noscroll});
|
|
});
|
|
}
|
|
};
|
|
});
|
|
Alpine.directive("trap", Alpine.skipDuringClone((el, {expression, modifiers}, {effect, evaluateLater, cleanup}) => {
|
|
let evaluator = evaluateLater(expression);
|
|
let oldValue = false;
|
|
let options = {
|
|
escapeDeactivates: false,
|
|
allowOutsideClick: true,
|
|
fallbackFocus: () => el
|
|
};
|
|
let autofocusEl = el.querySelector("[autofocus]");
|
|
if (autofocusEl)
|
|
options.initialFocus = autofocusEl;
|
|
let trap = createFocusTrap(el, options);
|
|
let undoInert = () => {
|
|
};
|
|
let undoDisableScrolling = () => {
|
|
};
|
|
const releaseFocus = () => {
|
|
undoInert();
|
|
undoInert = () => {
|
|
};
|
|
undoDisableScrolling();
|
|
undoDisableScrolling = () => {
|
|
};
|
|
trap.deactivate({
|
|
returnFocus: !modifiers.includes("noreturn")
|
|
});
|
|
};
|
|
effect(() => evaluator((value) => {
|
|
if (oldValue === value)
|
|
return;
|
|
if (value && !oldValue) {
|
|
setTimeout(() => {
|
|
if (modifiers.includes("inert"))
|
|
undoInert = setInert(el);
|
|
if (modifiers.includes("noscroll"))
|
|
undoDisableScrolling = disableScrolling();
|
|
trap.activate();
|
|
});
|
|
}
|
|
if (!value && oldValue) {
|
|
releaseFocus();
|
|
}
|
|
oldValue = !!value;
|
|
}));
|
|
cleanup(releaseFocus);
|
|
}, (el, {expression, modifiers}, {evaluate}) => {
|
|
if (modifiers.includes("inert") && evaluate(expression))
|
|
setInert(el);
|
|
}));
|
|
}
|
|
function setInert(el) {
|
|
let undos = [];
|
|
crawlSiblingsUp(el, (sibling) => {
|
|
let cache = sibling.hasAttribute("aria-hidden");
|
|
sibling.setAttribute("aria-hidden", "true");
|
|
undos.push(() => cache || sibling.removeAttribute("aria-hidden"));
|
|
});
|
|
return () => {
|
|
while (undos.length)
|
|
undos.pop()();
|
|
};
|
|
}
|
|
function crawlSiblingsUp(el, callback) {
|
|
if (el.isSameNode(document.body) || !el.parentNode)
|
|
return;
|
|
Array.from(el.parentNode.children).forEach((sibling) => {
|
|
if (sibling.isSameNode(el)) {
|
|
crawlSiblingsUp(el.parentNode, callback);
|
|
} else {
|
|
callback(sibling);
|
|
}
|
|
});
|
|
}
|
|
function disableScrolling() {
|
|
let overflow = document.documentElement.style.overflow;
|
|
let paddingRight = document.documentElement.style.paddingRight;
|
|
let scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
document.documentElement.style.overflow = "hidden";
|
|
document.documentElement.style.paddingRight = `${scrollbarWidth}px`;
|
|
return () => {
|
|
document.documentElement.style.overflow = overflow;
|
|
document.documentElement.style.paddingRight = paddingRight;
|
|
};
|
|
}
|
|
|
|
// packages/focus/builds/cdn.js
|
|
document.addEventListener("alpine:init", () => {
|
|
window.Alpine.plugin(src_default);
|
|
});
|
|
})();
|