完全跑通1.0版本
This commit is contained in:
132
frontend/node_modules/element-plus/lib/components/focus-trap/src/utils.js
generated
vendored
Normal file
132
frontend/node_modules/element-plus/lib/components/focus-trap/src/utils.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
||||
require("../../../_virtual/_rolldown/runtime.js");
|
||||
const require_aria = require("../../../utils/dom/aria.js");
|
||||
const require_tokens = require("./tokens.js");
|
||||
let vue = require("vue");
|
||||
//#region ../../packages/components/focus-trap/src/utils.ts
|
||||
const focusReason = (0, vue.ref)();
|
||||
const lastUserFocusTimestamp = (0, vue.ref)(0);
|
||||
const lastAutomatedFocusTimestamp = (0, vue.ref)(0);
|
||||
let focusReasonUserCount = 0;
|
||||
const obtainAllFocusableElements = (element) => {
|
||||
const nodes = [];
|
||||
const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT, { acceptNode: (node) => {
|
||||
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
|
||||
if (node.disabled || node.hidden || isHiddenInput) return NodeFilter.FILTER_SKIP;
|
||||
return node.tabIndex >= 0 || node === document.activeElement ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
||||
} });
|
||||
while (walker.nextNode()) nodes.push(walker.currentNode);
|
||||
return nodes;
|
||||
};
|
||||
const getVisibleElement = (elements, container) => {
|
||||
for (const element of elements) if (!isHidden(element, container)) return element;
|
||||
};
|
||||
const isHidden = (element, container) => {
|
||||
if (process.env.NODE_ENV === "test") return false;
|
||||
if (getComputedStyle(element).visibility === "hidden") return true;
|
||||
while (element) {
|
||||
if (container && element === container) return false;
|
||||
if (getComputedStyle(element).display === "none") return true;
|
||||
element = element.parentElement;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const getEdges = (container) => {
|
||||
const focusable = obtainAllFocusableElements(container);
|
||||
return [getVisibleElement(focusable, container), getVisibleElement(focusable.reverse(), container)];
|
||||
};
|
||||
const isSelectable = (element) => {
|
||||
return element instanceof HTMLInputElement && "select" in element;
|
||||
};
|
||||
const tryFocus = (element, shouldSelect) => {
|
||||
if (element) {
|
||||
const prevFocusedElement = document.activeElement;
|
||||
require_aria.focusElement(element, { preventScroll: true });
|
||||
lastAutomatedFocusTimestamp.value = window.performance.now();
|
||||
if (element !== prevFocusedElement && isSelectable(element) && shouldSelect) element.select();
|
||||
}
|
||||
};
|
||||
function removeFromStack(list, item) {
|
||||
const copy = [...list];
|
||||
const idx = list.indexOf(item);
|
||||
if (idx !== -1) copy.splice(idx, 1);
|
||||
return copy;
|
||||
}
|
||||
const createFocusableStack = () => {
|
||||
let stack = [];
|
||||
const push = (layer) => {
|
||||
const currentLayer = stack[0];
|
||||
if (currentLayer && layer !== currentLayer) currentLayer.pause();
|
||||
stack = removeFromStack(stack, layer);
|
||||
stack.unshift(layer);
|
||||
};
|
||||
const remove = (layer) => {
|
||||
stack = removeFromStack(stack, layer);
|
||||
stack[0]?.resume?.();
|
||||
};
|
||||
return {
|
||||
push,
|
||||
remove
|
||||
};
|
||||
};
|
||||
const focusFirstDescendant = (elements, shouldSelect = false) => {
|
||||
const prevFocusedElement = document.activeElement;
|
||||
for (const element of elements) {
|
||||
tryFocus(element, shouldSelect);
|
||||
if (document.activeElement !== prevFocusedElement) return;
|
||||
}
|
||||
};
|
||||
const focusableStack = createFocusableStack();
|
||||
const isFocusCausedByUserEvent = () => {
|
||||
return lastUserFocusTimestamp.value > lastAutomatedFocusTimestamp.value;
|
||||
};
|
||||
const notifyFocusReasonPointer = () => {
|
||||
focusReason.value = "pointer";
|
||||
lastUserFocusTimestamp.value = window.performance.now();
|
||||
};
|
||||
const notifyFocusReasonKeydown = () => {
|
||||
focusReason.value = "keyboard";
|
||||
lastUserFocusTimestamp.value = window.performance.now();
|
||||
};
|
||||
const useFocusReason = () => {
|
||||
(0, vue.onMounted)(() => {
|
||||
if (focusReasonUserCount === 0) {
|
||||
document.addEventListener("mousedown", notifyFocusReasonPointer);
|
||||
document.addEventListener("touchstart", notifyFocusReasonPointer);
|
||||
document.addEventListener("keydown", notifyFocusReasonKeydown);
|
||||
}
|
||||
focusReasonUserCount++;
|
||||
});
|
||||
(0, vue.onBeforeUnmount)(() => {
|
||||
focusReasonUserCount--;
|
||||
if (focusReasonUserCount <= 0) {
|
||||
document.removeEventListener("mousedown", notifyFocusReasonPointer);
|
||||
document.removeEventListener("touchstart", notifyFocusReasonPointer);
|
||||
document.removeEventListener("keydown", notifyFocusReasonKeydown);
|
||||
}
|
||||
});
|
||||
return {
|
||||
focusReason,
|
||||
lastUserFocusTimestamp,
|
||||
lastAutomatedFocusTimestamp
|
||||
};
|
||||
};
|
||||
const createFocusOutPreventedEvent = (detail) => {
|
||||
return new CustomEvent(require_tokens.FOCUSOUT_PREVENTED, {
|
||||
...require_tokens.FOCUSOUT_PREVENTED_OPTS,
|
||||
detail
|
||||
});
|
||||
};
|
||||
//#endregion
|
||||
exports.createFocusOutPreventedEvent = createFocusOutPreventedEvent;
|
||||
exports.focusFirstDescendant = focusFirstDescendant;
|
||||
exports.focusableStack = focusableStack;
|
||||
exports.getEdges = getEdges;
|
||||
exports.getVisibleElement = getVisibleElement;
|
||||
exports.isFocusCausedByUserEvent = isFocusCausedByUserEvent;
|
||||
exports.isHidden = isHidden;
|
||||
exports.obtainAllFocusableElements = obtainAllFocusableElements;
|
||||
exports.tryFocus = tryFocus;
|
||||
exports.useFocusReason = useFocusReason;
|
||||
|
||||
//# sourceMappingURL=utils.js.map
|
||||
Reference in New Issue
Block a user