@out-of-order/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/cli.js +101 -0
- package/dist/inject-overlay.global.js +3686 -0
- package/dist/inject.global.js +1891 -0
- package/package.json +47 -0
|
@@ -0,0 +1,1891 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// ../../node_modules/.pnpm/tabbable@6.5.0/node_modules/tabbable/dist/index.esm.js
|
|
4
|
+
var candidateSelectors = ["input:not([inert]):not([inert] *)", "select:not([inert]):not([inert] *)", "textarea:not([inert]):not([inert] *)", "a[href]:not([inert]):not([inert] *)", "area[href]:not([inert]):not([inert] *)", "button:not([inert]):not([inert] *)", "[tabindex]:not(slot):not([inert]):not([inert] *)", "audio[controls]:not([inert]):not([inert] *)", "video[controls]:not([inert]):not([inert] *)", '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', "details>summary:first-of-type:not([inert]):not([inert] *)", "details:not([inert]):not([inert] *)"];
|
|
5
|
+
var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
|
|
6
|
+
var NoElement = typeof Element === "undefined";
|
|
7
|
+
var matches = NoElement ? function() {
|
|
8
|
+
} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
9
|
+
var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) {
|
|
10
|
+
var _element$getRootNode;
|
|
11
|
+
return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
|
|
12
|
+
} : function(element) {
|
|
13
|
+
return element === null || element === void 0 ? void 0 : element.ownerDocument;
|
|
14
|
+
};
|
|
15
|
+
var _isInert = function isInert(node, lookUp) {
|
|
16
|
+
var _node$getAttribute;
|
|
17
|
+
if (lookUp === void 0) {
|
|
18
|
+
lookUp = true;
|
|
19
|
+
}
|
|
20
|
+
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
|
|
21
|
+
var inert = inertAtt === "" || inertAtt === "true";
|
|
22
|
+
var result = inert || lookUp && node && // closest does not exist on shadow roots, so we fall back to a manual
|
|
23
|
+
// lookup upward, in case it is not defined.
|
|
24
|
+
(typeof node.closest === "function" ? node.closest("[inert]") : _isInert(node.parentNode));
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
var isContentEditable = function isContentEditable2(node) {
|
|
28
|
+
var _node$getAttribute2;
|
|
29
|
+
var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable");
|
|
30
|
+
return attValue === "" || attValue === "true";
|
|
31
|
+
};
|
|
32
|
+
var getCandidates = function getCandidates2(el, includeContainer, filter) {
|
|
33
|
+
if (_isInert(el)) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
|
37
|
+
if (includeContainer && matches.call(el, candidateSelector)) {
|
|
38
|
+
candidates.unshift(el);
|
|
39
|
+
}
|
|
40
|
+
candidates = candidates.filter(filter);
|
|
41
|
+
return candidates;
|
|
42
|
+
};
|
|
43
|
+
var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
|
|
44
|
+
var candidates = [];
|
|
45
|
+
var elementsToCheck = Array.from(elements);
|
|
46
|
+
while (elementsToCheck.length) {
|
|
47
|
+
var element = elementsToCheck.shift();
|
|
48
|
+
if (_isInert(element, false)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (element.tagName === "SLOT") {
|
|
52
|
+
var assigned = element.assignedElements();
|
|
53
|
+
var content = assigned.length ? assigned : element.children;
|
|
54
|
+
var nestedCandidates = _getCandidatesIteratively(content, true, options);
|
|
55
|
+
if (options.flatten) {
|
|
56
|
+
candidates.push.apply(candidates, nestedCandidates);
|
|
57
|
+
} else {
|
|
58
|
+
candidates.push({
|
|
59
|
+
scopeParent: element,
|
|
60
|
+
candidates: nestedCandidates
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
var validCandidate = matches.call(element, candidateSelector);
|
|
65
|
+
if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
|
|
66
|
+
candidates.push(element);
|
|
67
|
+
}
|
|
68
|
+
var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
|
|
69
|
+
typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
|
|
70
|
+
var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
|
|
71
|
+
if (shadowRoot && validShadowRoot) {
|
|
72
|
+
var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
|
73
|
+
if (options.flatten) {
|
|
74
|
+
candidates.push.apply(candidates, _nestedCandidates);
|
|
75
|
+
} else {
|
|
76
|
+
candidates.push({
|
|
77
|
+
scopeParent: element,
|
|
78
|
+
candidates: _nestedCandidates
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
elementsToCheck.unshift.apply(elementsToCheck, element.children);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return candidates;
|
|
87
|
+
};
|
|
88
|
+
var hasTabIndex = function hasTabIndex2(node) {
|
|
89
|
+
return !isNaN(parseInt(node.getAttribute("tabindex"), 10));
|
|
90
|
+
};
|
|
91
|
+
var getTabIndex = function getTabIndex2(node) {
|
|
92
|
+
if (!node) {
|
|
93
|
+
throw new Error("No node provided");
|
|
94
|
+
}
|
|
95
|
+
if (node.tabIndex < 0) {
|
|
96
|
+
if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return node.tabIndex;
|
|
101
|
+
};
|
|
102
|
+
var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) {
|
|
103
|
+
var tabIndex = getTabIndex(node);
|
|
104
|
+
if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
return tabIndex;
|
|
108
|
+
};
|
|
109
|
+
var sortOrderedTabbables = function sortOrderedTabbables2(a, b) {
|
|
110
|
+
return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
|
|
111
|
+
};
|
|
112
|
+
var isInput = function isInput2(node) {
|
|
113
|
+
return node.tagName === "INPUT";
|
|
114
|
+
};
|
|
115
|
+
var isHiddenInput = function isHiddenInput2(node) {
|
|
116
|
+
return isInput(node) && node.type === "hidden";
|
|
117
|
+
};
|
|
118
|
+
var isDetailsWithSummary = function isDetailsWithSummary2(node) {
|
|
119
|
+
var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) {
|
|
120
|
+
return child.tagName === "SUMMARY";
|
|
121
|
+
});
|
|
122
|
+
return r;
|
|
123
|
+
};
|
|
124
|
+
var getCheckedRadio = function getCheckedRadio2(nodes, form) {
|
|
125
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
126
|
+
if (nodes[i].checked && nodes[i].form === form) {
|
|
127
|
+
return nodes[i];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var isTabbableRadio = function isTabbableRadio2(node) {
|
|
132
|
+
if (!node.name) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
var radioScope = node.form || getRootNode(node);
|
|
136
|
+
var queryRadios = function queryRadios2(name) {
|
|
137
|
+
return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
|
|
138
|
+
};
|
|
139
|
+
var radioSet;
|
|
140
|
+
if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
|
|
141
|
+
radioSet = queryRadios(window.CSS.escape(node.name));
|
|
142
|
+
} else {
|
|
143
|
+
try {
|
|
144
|
+
radioSet = queryRadios(node.name);
|
|
145
|
+
} catch (err) {
|
|
146
|
+
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);
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
var checked = getCheckedRadio(radioSet, node.form);
|
|
151
|
+
return !checked || checked === node;
|
|
152
|
+
};
|
|
153
|
+
var isRadio = function isRadio2(node) {
|
|
154
|
+
return isInput(node) && node.type === "radio";
|
|
155
|
+
};
|
|
156
|
+
var isNonTabbableRadio = function isNonTabbableRadio2(node) {
|
|
157
|
+
return isRadio(node) && !isTabbableRadio(node);
|
|
158
|
+
};
|
|
159
|
+
var isNodeAttached = function isNodeAttached2(node) {
|
|
160
|
+
var _nodeRoot;
|
|
161
|
+
var nodeRoot = node && getRootNode(node);
|
|
162
|
+
var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
|
|
163
|
+
var attached = false;
|
|
164
|
+
if (nodeRoot && nodeRoot !== node) {
|
|
165
|
+
var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
|
|
166
|
+
attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node));
|
|
167
|
+
while (!attached && nodeRootHost) {
|
|
168
|
+
var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
|
|
169
|
+
nodeRoot = getRootNode(nodeRootHost);
|
|
170
|
+
nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
|
|
171
|
+
attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return attached;
|
|
175
|
+
};
|
|
176
|
+
var isZeroArea = function isZeroArea2(node) {
|
|
177
|
+
var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height;
|
|
178
|
+
return width === 0 && height === 0;
|
|
179
|
+
};
|
|
180
|
+
var isHidden = function isHidden2(node, _ref) {
|
|
181
|
+
var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
|
|
182
|
+
if (displayCheck === "full-native") {
|
|
183
|
+
if ("checkVisibility" in node) {
|
|
184
|
+
var visible = node.checkVisibility({
|
|
185
|
+
// Checking opacity might be desirable for some use cases, but natively,
|
|
186
|
+
// opacity zero elements _are_ focusable and tabbable.
|
|
187
|
+
checkOpacity: false,
|
|
188
|
+
opacityProperty: false,
|
|
189
|
+
contentVisibilityAuto: true,
|
|
190
|
+
visibilityProperty: true,
|
|
191
|
+
// This is an alias for `visibilityProperty`. Contemporary browsers
|
|
192
|
+
// support both. However, this alias has wider browser support (Chrome
|
|
193
|
+
// >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
|
|
194
|
+
// we include it anyway.
|
|
195
|
+
checkVisibilityCSS: true
|
|
196
|
+
});
|
|
197
|
+
return !visible;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
var _getComputedStyle = getComputedStyle(node), visibility = _getComputedStyle.visibility;
|
|
201
|
+
if (visibility === "hidden" || visibility === "collapse") {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
var isDirectSummary = matches.call(node, "details>summary:first-of-type");
|
|
205
|
+
var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
|
|
206
|
+
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
if (!displayCheck || displayCheck === "full" || // full-native can run this branch when it falls through in case
|
|
210
|
+
// Element#checkVisibility is unsupported
|
|
211
|
+
displayCheck === "full-native" || displayCheck === "legacy-full") {
|
|
212
|
+
if (typeof getShadowRoot === "function") {
|
|
213
|
+
var originalNode = node;
|
|
214
|
+
while (node) {
|
|
215
|
+
var parentElement = node.parentElement;
|
|
216
|
+
var rootNode = getRootNode(node);
|
|
217
|
+
if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) {
|
|
218
|
+
return isZeroArea(node);
|
|
219
|
+
} else if (node.assignedSlot) {
|
|
220
|
+
node = node.assignedSlot;
|
|
221
|
+
} else if (!parentElement && rootNode !== node.ownerDocument) {
|
|
222
|
+
node = rootNode.host;
|
|
223
|
+
} else {
|
|
224
|
+
node = parentElement;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
node = originalNode;
|
|
228
|
+
}
|
|
229
|
+
if (isNodeAttached(node)) {
|
|
230
|
+
return !node.getClientRects().length;
|
|
231
|
+
}
|
|
232
|
+
if (displayCheck !== "legacy-full") {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
} else if (displayCheck === "non-zero-area") {
|
|
236
|
+
return isZeroArea(node);
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
};
|
|
240
|
+
var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
|
|
241
|
+
if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
|
|
242
|
+
var parentNode = node.parentElement;
|
|
243
|
+
while (parentNode) {
|
|
244
|
+
if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
|
|
245
|
+
for (var i = 0; i < parentNode.children.length; i++) {
|
|
246
|
+
var child = parentNode.children.item(i);
|
|
247
|
+
if (child.tagName === "LEGEND") {
|
|
248
|
+
return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
parentNode = parentNode.parentElement;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
};
|
|
258
|
+
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
|
|
259
|
+
if (node.disabled || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
|
|
260
|
+
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
return true;
|
|
264
|
+
};
|
|
265
|
+
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) {
|
|
266
|
+
if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
return true;
|
|
270
|
+
};
|
|
271
|
+
var isShadowRootTabbable = function isShadowRootTabbable2(shadowHostNode) {
|
|
272
|
+
var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
|
|
273
|
+
if (isNaN(tabIndex) || tabIndex >= 0) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
};
|
|
278
|
+
var _sortByOrder = function sortByOrder(candidates) {
|
|
279
|
+
var regularTabbables = [];
|
|
280
|
+
var orderedTabbables = [];
|
|
281
|
+
candidates.forEach(function(item, i) {
|
|
282
|
+
var isScope = !!item.scopeParent;
|
|
283
|
+
var element = isScope ? item.scopeParent : item;
|
|
284
|
+
var candidateTabindex = getSortOrderTabIndex(element, isScope);
|
|
285
|
+
var elements = isScope ? _sortByOrder(item.candidates) : element;
|
|
286
|
+
if (candidateTabindex === 0) {
|
|
287
|
+
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
|
288
|
+
} else {
|
|
289
|
+
orderedTabbables.push({
|
|
290
|
+
documentOrder: i,
|
|
291
|
+
tabIndex: candidateTabindex,
|
|
292
|
+
item,
|
|
293
|
+
isScope,
|
|
294
|
+
content: elements
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) {
|
|
299
|
+
sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
|
|
300
|
+
return acc;
|
|
301
|
+
}, []).concat(regularTabbables);
|
|
302
|
+
};
|
|
303
|
+
var tabbable = function tabbable2(container, options) {
|
|
304
|
+
options = options || {};
|
|
305
|
+
var candidates;
|
|
306
|
+
if (options.getShadowRoot) {
|
|
307
|
+
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
|
308
|
+
filter: isNodeMatchingSelectorTabbable.bind(null, options),
|
|
309
|
+
flatten: false,
|
|
310
|
+
getShadowRoot: options.getShadowRoot,
|
|
311
|
+
shadowRootFilter: isShadowRootTabbable
|
|
312
|
+
});
|
|
313
|
+
} else {
|
|
314
|
+
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
|
315
|
+
}
|
|
316
|
+
return _sortByOrder(candidates);
|
|
317
|
+
};
|
|
318
|
+
var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors.concat("iframe:not([inert]):not([inert] *)").join(",");
|
|
319
|
+
var isFocusable = function isFocusable2(node, options) {
|
|
320
|
+
options = options || {};
|
|
321
|
+
if (!node) {
|
|
322
|
+
throw new Error("No node provided");
|
|
323
|
+
}
|
|
324
|
+
if (matches.call(node, focusableCandidateSelector) === false) {
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
return isNodeMatchingSelectorFocusable(options, node);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// ../core/src/overlay-classes.ts
|
|
331
|
+
var OVERLAY_CLASS_PREFIX = "ooo-";
|
|
332
|
+
|
|
333
|
+
// ../core/src/dom.ts
|
|
334
|
+
function closestAncestor(start, test) {
|
|
335
|
+
for (let node = start; node; node = node.parentElement) {
|
|
336
|
+
if (test(node)) {
|
|
337
|
+
return node;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
function selectorFor(element) {
|
|
343
|
+
const parts = [];
|
|
344
|
+
let node = element;
|
|
345
|
+
let depth = 0;
|
|
346
|
+
while (node && depth < 4) {
|
|
347
|
+
let part = node.tagName.toLowerCase();
|
|
348
|
+
if (node.id) {
|
|
349
|
+
part += `#${node.id}`;
|
|
350
|
+
parts.unshift(part);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
const cls = (node.getAttribute("class") || "").trim().split(/\s+/).filter((c) => c && !c.startsWith(OVERLAY_CLASS_PREFIX));
|
|
354
|
+
if (cls.length) {
|
|
355
|
+
part += `.${cls[0]}`;
|
|
356
|
+
}
|
|
357
|
+
parts.unshift(part);
|
|
358
|
+
node = node.parentElement;
|
|
359
|
+
depth++;
|
|
360
|
+
}
|
|
361
|
+
return parts.join(" > ");
|
|
362
|
+
}
|
|
363
|
+
var NATIVE_FOR_ROLE = {
|
|
364
|
+
button: "<button>",
|
|
365
|
+
link: "<a href>",
|
|
366
|
+
checkbox: '<input type="checkbox">',
|
|
367
|
+
radio: '<input type="radio">',
|
|
368
|
+
switch: '<input type="checkbox" role="switch">',
|
|
369
|
+
slider: '<input type="range">',
|
|
370
|
+
spinbutton: '<input type="number">',
|
|
371
|
+
searchbox: '<input type="search">',
|
|
372
|
+
textbox: "<input> or <textarea>",
|
|
373
|
+
combobox: "<select>",
|
|
374
|
+
option: "<option>"
|
|
375
|
+
};
|
|
376
|
+
var COMPOSITE_ROLES_NO_NATIVE = [
|
|
377
|
+
"menuitem",
|
|
378
|
+
"menuitemcheckbox",
|
|
379
|
+
"menuitemradio",
|
|
380
|
+
"tab",
|
|
381
|
+
"treeitem"
|
|
382
|
+
];
|
|
383
|
+
var INTERACTIVE_ROLES = [...Object.keys(NATIVE_FOR_ROLE), ...COMPOSITE_ROLES_NO_NATIVE];
|
|
384
|
+
function isInteractive(element) {
|
|
385
|
+
const tag = element.tagName.toLowerCase();
|
|
386
|
+
if (tag === "a" && element.hasAttribute("href")) {
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
if (["button", "select", "textarea", "summary"].includes(tag)) {
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
if (tag === "input") {
|
|
393
|
+
const type = (element.getAttribute("type") || "text").toLowerCase();
|
|
394
|
+
return type !== "hidden";
|
|
395
|
+
}
|
|
396
|
+
const role = element.getAttribute("role");
|
|
397
|
+
return !!role && INTERACTIVE_ROLES.includes(role);
|
|
398
|
+
}
|
|
399
|
+
function hasExplicitName(element) {
|
|
400
|
+
return (element.getAttribute("aria-label") || "").trim() !== "" || (element.getAttribute("title") || "").trim() !== "";
|
|
401
|
+
}
|
|
402
|
+
function inAriaHidden(element) {
|
|
403
|
+
return element.closest('[aria-hidden="true"]') !== null;
|
|
404
|
+
}
|
|
405
|
+
function isInert2(element) {
|
|
406
|
+
return element.closest("[inert]") !== null;
|
|
407
|
+
}
|
|
408
|
+
var IGNORE_ATTRIBUTE = "data-ooo-ignore";
|
|
409
|
+
function isRuleIgnored(element, ruleId) {
|
|
410
|
+
const value = element.getAttribute(IGNORE_ATTRIBUTE);
|
|
411
|
+
if (value === null) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
const ids = value.trim().split(/\s+/).filter(Boolean);
|
|
415
|
+
return ids.length === 0 || ids.includes(ruleId);
|
|
416
|
+
}
|
|
417
|
+
function isTransparent(element) {
|
|
418
|
+
const check = element.checkVisibility;
|
|
419
|
+
if (typeof check === "function") {
|
|
420
|
+
return !check.call(element, { opacityProperty: true });
|
|
421
|
+
}
|
|
422
|
+
return closestAncestor(element, (node) => parseFloat(getComputedStyle(node).opacity || "1") === 0) !== null;
|
|
423
|
+
}
|
|
424
|
+
function isScreenReaderOnly(element, rect = element.getBoundingClientRect()) {
|
|
425
|
+
if (rect.width > 2 || rect.height > 2) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
const style = getComputedStyle(element);
|
|
429
|
+
return style.clip !== "" && style.clip !== "auto" || style.clipPath !== "" && style.clipPath !== "none" || style.overflow === "hidden";
|
|
430
|
+
}
|
|
431
|
+
function isClipped(element, rect) {
|
|
432
|
+
for (let node = element.parentElement; node; node = node.parentElement) {
|
|
433
|
+
const containerRect = node.getBoundingClientRect();
|
|
434
|
+
if (containerRect.width === 0 && containerRect.height === 0) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
const style = getComputedStyle(node);
|
|
438
|
+
const outX = rect.right <= containerRect.left || rect.left >= containerRect.right;
|
|
439
|
+
const outY = rect.bottom <= containerRect.top || rect.top >= containerRect.bottom;
|
|
440
|
+
const clipX = style.overflowX === "clip";
|
|
441
|
+
const clipY = style.overflowY === "clip";
|
|
442
|
+
if (outX && clipX || outY && clipY) {
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
function isOffPage(element, rect) {
|
|
449
|
+
const win = element.ownerDocument?.defaultView;
|
|
450
|
+
if (!win) {
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
const pageRight = rect.right + win.scrollX;
|
|
454
|
+
const pageBottom = rect.bottom + win.scrollY;
|
|
455
|
+
return pageRight <= 0 || pageBottom <= 0;
|
|
456
|
+
}
|
|
457
|
+
function staticHiddenReason(element, rect) {
|
|
458
|
+
if (isScreenReaderOnly(element, rect)) {
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
if (element.tagName.toLowerCase() === "area") {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
if (isTransparent(element)) {
|
|
465
|
+
return "opacity:0, invisible but still tabbable";
|
|
466
|
+
}
|
|
467
|
+
if (rect.width < 1 || rect.height < 1) {
|
|
468
|
+
return "zero size, no visible target";
|
|
469
|
+
}
|
|
470
|
+
if (isOffPage(element, rect)) {
|
|
471
|
+
return "positioned off-screen (e.g. left:-9999px), invisible but still tabbable";
|
|
472
|
+
}
|
|
473
|
+
if (isClipped(element, rect)) {
|
|
474
|
+
return "clipped by an overflow:clip ancestor";
|
|
475
|
+
}
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
var REVEALING_PROPS = [
|
|
479
|
+
"opacity",
|
|
480
|
+
"visibility",
|
|
481
|
+
"display",
|
|
482
|
+
"position",
|
|
483
|
+
"left",
|
|
484
|
+
"right",
|
|
485
|
+
"top",
|
|
486
|
+
"bottom",
|
|
487
|
+
"inset",
|
|
488
|
+
"clip",
|
|
489
|
+
"clip-path",
|
|
490
|
+
"transform",
|
|
491
|
+
"translate",
|
|
492
|
+
"scale",
|
|
493
|
+
"width",
|
|
494
|
+
"height",
|
|
495
|
+
"max-width",
|
|
496
|
+
"max-height",
|
|
497
|
+
"overflow"
|
|
498
|
+
];
|
|
499
|
+
function revealSelectors(rules) {
|
|
500
|
+
return Array.from(rules).flatMap((rule) => {
|
|
501
|
+
if (rule instanceof CSSStyleRule) {
|
|
502
|
+
if (!/:focus/i.test(rule.selectorText) || !REVEALING_PROPS.some((p) => rule.style.getPropertyValue(p) !== "")) {
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
const resting = rule.selectorText.replace(/:focus(?:-visible|-within)?/gi, "").trim();
|
|
506
|
+
return resting ? [resting] : [];
|
|
507
|
+
}
|
|
508
|
+
return "cssRules" in rule ? revealSelectors(rule.cssRules) : [];
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
function focusRevealSelectors(doc) {
|
|
512
|
+
const sheets = [...Array.from(doc.styleSheets), ...doc.adoptedStyleSheets ?? []];
|
|
513
|
+
return sheets.flatMap((sheet) => {
|
|
514
|
+
try {
|
|
515
|
+
return revealSelectors(sheet.cssRules);
|
|
516
|
+
} catch {
|
|
517
|
+
return [];
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
function hiddenReason(element, rect, revealOnFocus = []) {
|
|
522
|
+
const reason = staticHiddenReason(element, rect);
|
|
523
|
+
if (!reason) {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
const revealed = revealOnFocus.some((selector) => {
|
|
527
|
+
try {
|
|
528
|
+
return element.matches(selector);
|
|
529
|
+
} catch {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
return revealed ? null : reason;
|
|
534
|
+
}
|
|
535
|
+
var NATIVE_INTERACTIVE_TAGS = ["a", "button", "input", "select", "textarea", "summary", "option"];
|
|
536
|
+
function looksClickable(element) {
|
|
537
|
+
const tag = element.tagName.toLowerCase();
|
|
538
|
+
if (NATIVE_INTERACTIVE_TAGS.includes(tag)) {
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
const role = element.getAttribute("role");
|
|
542
|
+
if (role && INTERACTIVE_ROLES.includes(role)) {
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
return element.hasAttribute("onclick");
|
|
546
|
+
}
|
|
547
|
+
function nativeReplacement(element) {
|
|
548
|
+
if (NATIVE_INTERACTIVE_TAGS.includes(element.tagName.toLowerCase())) {
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
const role = element.getAttribute("role");
|
|
552
|
+
if (!role) {
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
return NATIVE_FOR_ROLE[role] ?? null;
|
|
556
|
+
}
|
|
557
|
+
function isNativelyFocusable(element) {
|
|
558
|
+
const tag = element.tagName.toLowerCase();
|
|
559
|
+
if (tag === "a" || tag === "area") {
|
|
560
|
+
return element.hasAttribute("href");
|
|
561
|
+
}
|
|
562
|
+
if (["button", "select", "textarea", "iframe"].includes(tag)) {
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
if (tag === "input") {
|
|
566
|
+
return (element.getAttribute("type") || "text").toLowerCase() !== "hidden";
|
|
567
|
+
}
|
|
568
|
+
if (tag === "audio" || tag === "video") {
|
|
569
|
+
return element.hasAttribute("controls");
|
|
570
|
+
}
|
|
571
|
+
if (tag === "summary") {
|
|
572
|
+
const parent = element.parentElement;
|
|
573
|
+
return parent?.tagName.toLowerCase() === "details" && parent.querySelector("summary") === element;
|
|
574
|
+
}
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
var COMPOSITE_ROLES = [
|
|
578
|
+
"toolbar",
|
|
579
|
+
"tablist",
|
|
580
|
+
"menu",
|
|
581
|
+
"menubar",
|
|
582
|
+
"radiogroup",
|
|
583
|
+
"listbox",
|
|
584
|
+
"tree",
|
|
585
|
+
"grid"
|
|
586
|
+
];
|
|
587
|
+
function compositeAncestor(element) {
|
|
588
|
+
return closestAncestor(element.parentElement, (node) => {
|
|
589
|
+
const role = node.getAttribute("role");
|
|
590
|
+
return !!role && COMPOSITE_ROLES.includes(role);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
function isFocusManaged(element) {
|
|
594
|
+
const tabindex = element.getAttribute("tabindex");
|
|
595
|
+
if (tabindex !== null && Number(tabindex) < 0) {
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
598
|
+
if (compositeAncestor(element)) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
return element.closest("[aria-activedescendant]") !== null;
|
|
602
|
+
}
|
|
603
|
+
function floatingAncestor(element) {
|
|
604
|
+
return closestAncestor(element, (node) => {
|
|
605
|
+
const pos = getComputedStyle(node).position;
|
|
606
|
+
return pos === "fixed" || pos === "sticky";
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
function isScrollContainer(element) {
|
|
610
|
+
const scrollable = (value) => value === "auto" || value === "scroll" || value === "overlay";
|
|
611
|
+
const style = getComputedStyle(element);
|
|
612
|
+
return scrollable(style.overflowX) || scrollable(style.overflowY);
|
|
613
|
+
}
|
|
614
|
+
function scrollAncestor(element) {
|
|
615
|
+
return closestAncestor(element.parentElement, isScrollContainer);
|
|
616
|
+
}
|
|
617
|
+
function isDisplayed(element) {
|
|
618
|
+
const check = element.checkVisibility;
|
|
619
|
+
if (typeof check === "function") {
|
|
620
|
+
return check.call(element, { visibilityProperty: true });
|
|
621
|
+
}
|
|
622
|
+
return closestAncestor(element, (node) => getComputedStyle(node).display === "none") === null;
|
|
623
|
+
}
|
|
624
|
+
function openModal(root) {
|
|
625
|
+
for (const element of root.querySelectorAll('dialog:modal, [aria-modal="true"]')) {
|
|
626
|
+
if (isDisplayed(element)) {
|
|
627
|
+
return element;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/polyfills/array.from.mjs
|
|
634
|
+
var toStr = Object.prototype.toString;
|
|
635
|
+
function isCallable(fn) {
|
|
636
|
+
return typeof fn === "function" || toStr.call(fn) === "[object Function]";
|
|
637
|
+
}
|
|
638
|
+
function toInteger(value) {
|
|
639
|
+
var number = Number(value);
|
|
640
|
+
if (isNaN(number)) {
|
|
641
|
+
return 0;
|
|
642
|
+
}
|
|
643
|
+
if (number === 0 || !isFinite(number)) {
|
|
644
|
+
return number;
|
|
645
|
+
}
|
|
646
|
+
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
|
647
|
+
}
|
|
648
|
+
var maxSafeInteger = Math.pow(2, 53) - 1;
|
|
649
|
+
function toLength(value) {
|
|
650
|
+
var len = toInteger(value);
|
|
651
|
+
return Math.min(Math.max(len, 0), maxSafeInteger);
|
|
652
|
+
}
|
|
653
|
+
function arrayFrom(arrayLike, mapFn) {
|
|
654
|
+
var C = Array;
|
|
655
|
+
var items = Object(arrayLike);
|
|
656
|
+
if (arrayLike == null) {
|
|
657
|
+
throw new TypeError("Array.from requires an array-like object - not null or undefined");
|
|
658
|
+
}
|
|
659
|
+
if (typeof mapFn !== "undefined") {
|
|
660
|
+
if (!isCallable(mapFn)) {
|
|
661
|
+
throw new TypeError("Array.from: when provided, the second argument must be a function");
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
var len = toLength(items.length);
|
|
665
|
+
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
|
666
|
+
var k = 0;
|
|
667
|
+
var kValue;
|
|
668
|
+
while (k < len) {
|
|
669
|
+
kValue = items[k];
|
|
670
|
+
if (mapFn) {
|
|
671
|
+
A[k] = mapFn(kValue, k);
|
|
672
|
+
} else {
|
|
673
|
+
A[k] = kValue;
|
|
674
|
+
}
|
|
675
|
+
k += 1;
|
|
676
|
+
}
|
|
677
|
+
A.length = len;
|
|
678
|
+
return A;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/polyfills/SetLike.mjs
|
|
682
|
+
function _typeof(o) {
|
|
683
|
+
"@babel/helpers - typeof";
|
|
684
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o2) {
|
|
685
|
+
return typeof o2;
|
|
686
|
+
} : function(o2) {
|
|
687
|
+
return o2 && "function" == typeof Symbol && o2.constructor === Symbol && o2 !== Symbol.prototype ? "symbol" : typeof o2;
|
|
688
|
+
}, _typeof(o);
|
|
689
|
+
}
|
|
690
|
+
function _classCallCheck(instance, Constructor) {
|
|
691
|
+
if (!(instance instanceof Constructor)) {
|
|
692
|
+
throw new TypeError("Cannot call a class as a function");
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
function _defineProperties(target, props) {
|
|
696
|
+
for (var i = 0; i < props.length; i++) {
|
|
697
|
+
var descriptor = props[i];
|
|
698
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
699
|
+
descriptor.configurable = true;
|
|
700
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
701
|
+
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
function _createClass(Constructor, protoProps, staticProps) {
|
|
705
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
706
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
707
|
+
Object.defineProperty(Constructor, "prototype", { writable: false });
|
|
708
|
+
return Constructor;
|
|
709
|
+
}
|
|
710
|
+
function _defineProperty(obj, key, value) {
|
|
711
|
+
key = _toPropertyKey(key);
|
|
712
|
+
if (key in obj) {
|
|
713
|
+
Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true });
|
|
714
|
+
} else {
|
|
715
|
+
obj[key] = value;
|
|
716
|
+
}
|
|
717
|
+
return obj;
|
|
718
|
+
}
|
|
719
|
+
function _toPropertyKey(t) {
|
|
720
|
+
var i = _toPrimitive(t, "string");
|
|
721
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
722
|
+
}
|
|
723
|
+
function _toPrimitive(t, r) {
|
|
724
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
725
|
+
var e = t[Symbol.toPrimitive];
|
|
726
|
+
if (void 0 !== e) {
|
|
727
|
+
var i = e.call(t, r || "default");
|
|
728
|
+
if ("object" != _typeof(i)) return i;
|
|
729
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
730
|
+
}
|
|
731
|
+
return ("string" === r ? String : Number)(t);
|
|
732
|
+
}
|
|
733
|
+
var SetLike = /* @__PURE__ */ (function() {
|
|
734
|
+
function SetLike2() {
|
|
735
|
+
var items = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
|
|
736
|
+
_classCallCheck(this, SetLike2);
|
|
737
|
+
_defineProperty(this, "items", void 0);
|
|
738
|
+
this.items = items;
|
|
739
|
+
}
|
|
740
|
+
return _createClass(SetLike2, [{
|
|
741
|
+
key: "add",
|
|
742
|
+
value: function add(value) {
|
|
743
|
+
if (this.has(value) === false) {
|
|
744
|
+
this.items.push(value);
|
|
745
|
+
}
|
|
746
|
+
return this;
|
|
747
|
+
}
|
|
748
|
+
}, {
|
|
749
|
+
key: "clear",
|
|
750
|
+
value: function clear() {
|
|
751
|
+
this.items = [];
|
|
752
|
+
}
|
|
753
|
+
}, {
|
|
754
|
+
key: "delete",
|
|
755
|
+
value: function _delete(value) {
|
|
756
|
+
var previousLength = this.items.length;
|
|
757
|
+
this.items = this.items.filter(function(item) {
|
|
758
|
+
return item !== value;
|
|
759
|
+
});
|
|
760
|
+
return previousLength !== this.items.length;
|
|
761
|
+
}
|
|
762
|
+
}, {
|
|
763
|
+
key: "forEach",
|
|
764
|
+
value: function forEach(callbackfn) {
|
|
765
|
+
var _this = this;
|
|
766
|
+
this.items.forEach(function(item) {
|
|
767
|
+
callbackfn(item, item, _this);
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}, {
|
|
771
|
+
key: "has",
|
|
772
|
+
value: function has(value) {
|
|
773
|
+
return this.items.indexOf(value) !== -1;
|
|
774
|
+
}
|
|
775
|
+
}, {
|
|
776
|
+
key: "size",
|
|
777
|
+
get: function get() {
|
|
778
|
+
return this.items.length;
|
|
779
|
+
}
|
|
780
|
+
}]);
|
|
781
|
+
})();
|
|
782
|
+
var SetLike_default = typeof Set === "undefined" ? Set : SetLike;
|
|
783
|
+
|
|
784
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/getRole.mjs
|
|
785
|
+
function getLocalName(element) {
|
|
786
|
+
var _element$localName;
|
|
787
|
+
return (
|
|
788
|
+
// eslint-disable-next-line no-restricted-properties -- actual guard for environments without localName
|
|
789
|
+
(_element$localName = element.localName) !== null && _element$localName !== void 0 ? _element$localName : (
|
|
790
|
+
// eslint-disable-next-line no-restricted-properties -- required for the fallback
|
|
791
|
+
element.tagName.toLowerCase()
|
|
792
|
+
)
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
var localNameToRoleMappings = {
|
|
796
|
+
article: "article",
|
|
797
|
+
aside: "complementary",
|
|
798
|
+
button: "button",
|
|
799
|
+
datalist: "listbox",
|
|
800
|
+
dd: "definition",
|
|
801
|
+
details: "group",
|
|
802
|
+
dialog: "dialog",
|
|
803
|
+
dt: "term",
|
|
804
|
+
fieldset: "group",
|
|
805
|
+
figure: "figure",
|
|
806
|
+
// WARNING: Only with an accessible name
|
|
807
|
+
form: "form",
|
|
808
|
+
footer: "contentinfo",
|
|
809
|
+
h1: "heading",
|
|
810
|
+
h2: "heading",
|
|
811
|
+
h3: "heading",
|
|
812
|
+
h4: "heading",
|
|
813
|
+
h5: "heading",
|
|
814
|
+
h6: "heading",
|
|
815
|
+
header: "banner",
|
|
816
|
+
hr: "separator",
|
|
817
|
+
html: "document",
|
|
818
|
+
legend: "legend",
|
|
819
|
+
li: "listitem",
|
|
820
|
+
math: "math",
|
|
821
|
+
main: "main",
|
|
822
|
+
menu: "list",
|
|
823
|
+
nav: "navigation",
|
|
824
|
+
ol: "list",
|
|
825
|
+
optgroup: "group",
|
|
826
|
+
// WARNING: Only in certain context
|
|
827
|
+
option: "option",
|
|
828
|
+
output: "status",
|
|
829
|
+
progress: "progressbar",
|
|
830
|
+
// WARNING: Only with an accessible name
|
|
831
|
+
section: "region",
|
|
832
|
+
summary: "button",
|
|
833
|
+
table: "table",
|
|
834
|
+
tbody: "rowgroup",
|
|
835
|
+
textarea: "textbox",
|
|
836
|
+
tfoot: "rowgroup",
|
|
837
|
+
// WARNING: Only in certain context
|
|
838
|
+
td: "cell",
|
|
839
|
+
th: "columnheader",
|
|
840
|
+
thead: "rowgroup",
|
|
841
|
+
tr: "row",
|
|
842
|
+
ul: "list"
|
|
843
|
+
};
|
|
844
|
+
var prohibitedAttributes = {
|
|
845
|
+
caption: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
846
|
+
code: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
847
|
+
deletion: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
848
|
+
emphasis: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
849
|
+
generic: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby", "aria-roledescription"]),
|
|
850
|
+
insertion: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
851
|
+
none: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
852
|
+
paragraph: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
853
|
+
presentation: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
854
|
+
strong: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
855
|
+
subscript: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"]),
|
|
856
|
+
superscript: /* @__PURE__ */ new Set(["aria-label", "aria-labelledby"])
|
|
857
|
+
};
|
|
858
|
+
function hasGlobalAriaAttributes(element, role) {
|
|
859
|
+
return [
|
|
860
|
+
"aria-atomic",
|
|
861
|
+
"aria-busy",
|
|
862
|
+
"aria-controls",
|
|
863
|
+
"aria-current",
|
|
864
|
+
"aria-description",
|
|
865
|
+
"aria-describedby",
|
|
866
|
+
"aria-details",
|
|
867
|
+
// "disabled",
|
|
868
|
+
"aria-dropeffect",
|
|
869
|
+
// "errormessage",
|
|
870
|
+
"aria-flowto",
|
|
871
|
+
"aria-grabbed",
|
|
872
|
+
// "haspopup",
|
|
873
|
+
"aria-hidden",
|
|
874
|
+
// "invalid",
|
|
875
|
+
"aria-keyshortcuts",
|
|
876
|
+
"aria-label",
|
|
877
|
+
"aria-labelledby",
|
|
878
|
+
"aria-live",
|
|
879
|
+
"aria-owns",
|
|
880
|
+
"aria-relevant",
|
|
881
|
+
"aria-roledescription"
|
|
882
|
+
].some(function(attributeName) {
|
|
883
|
+
var _prohibitedAttributes;
|
|
884
|
+
return element.hasAttribute(attributeName) && !((_prohibitedAttributes = prohibitedAttributes[role]) !== null && _prohibitedAttributes !== void 0 && _prohibitedAttributes.has(attributeName));
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
function ignorePresentationalRole(element, implicitRole) {
|
|
888
|
+
return hasGlobalAriaAttributes(element, implicitRole);
|
|
889
|
+
}
|
|
890
|
+
function getRole(element) {
|
|
891
|
+
var explicitRole = getExplicitRole(element);
|
|
892
|
+
if (explicitRole === null || presentationRoles.indexOf(explicitRole) !== -1) {
|
|
893
|
+
var implicitRole = getImplicitRole(element);
|
|
894
|
+
if (presentationRoles.indexOf(explicitRole || "") === -1 || ignorePresentationalRole(element, implicitRole || "")) {
|
|
895
|
+
return implicitRole;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
return explicitRole;
|
|
899
|
+
}
|
|
900
|
+
function getImplicitRole(element) {
|
|
901
|
+
var mappedByTag = localNameToRoleMappings[getLocalName(element)];
|
|
902
|
+
if (mappedByTag !== void 0) {
|
|
903
|
+
return mappedByTag;
|
|
904
|
+
}
|
|
905
|
+
switch (getLocalName(element)) {
|
|
906
|
+
case "a":
|
|
907
|
+
case "area":
|
|
908
|
+
case "link":
|
|
909
|
+
if (element.hasAttribute("href")) {
|
|
910
|
+
return "link";
|
|
911
|
+
}
|
|
912
|
+
break;
|
|
913
|
+
case "img":
|
|
914
|
+
if (element.getAttribute("alt") === "" && !ignorePresentationalRole(element, "img")) {
|
|
915
|
+
return "presentation";
|
|
916
|
+
}
|
|
917
|
+
return "img";
|
|
918
|
+
case "input": {
|
|
919
|
+
var _ref = element, type = _ref.type;
|
|
920
|
+
switch (type) {
|
|
921
|
+
case "button":
|
|
922
|
+
case "image":
|
|
923
|
+
case "reset":
|
|
924
|
+
case "submit":
|
|
925
|
+
return "button";
|
|
926
|
+
case "checkbox":
|
|
927
|
+
case "radio":
|
|
928
|
+
return type;
|
|
929
|
+
case "range":
|
|
930
|
+
return "slider";
|
|
931
|
+
case "email":
|
|
932
|
+
case "tel":
|
|
933
|
+
case "text":
|
|
934
|
+
case "url":
|
|
935
|
+
if (element.hasAttribute("list")) {
|
|
936
|
+
return "combobox";
|
|
937
|
+
}
|
|
938
|
+
return "textbox";
|
|
939
|
+
case "search":
|
|
940
|
+
if (element.hasAttribute("list")) {
|
|
941
|
+
return "combobox";
|
|
942
|
+
}
|
|
943
|
+
return "searchbox";
|
|
944
|
+
case "number":
|
|
945
|
+
return "spinbutton";
|
|
946
|
+
default:
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
case "select":
|
|
951
|
+
if (element.hasAttribute("multiple") || element.size > 1) {
|
|
952
|
+
return "listbox";
|
|
953
|
+
}
|
|
954
|
+
return "combobox";
|
|
955
|
+
}
|
|
956
|
+
return null;
|
|
957
|
+
}
|
|
958
|
+
function getExplicitRole(element) {
|
|
959
|
+
var role = element.getAttribute("role");
|
|
960
|
+
if (role !== null) {
|
|
961
|
+
var explicitRole = role.trim().split(" ")[0];
|
|
962
|
+
if (explicitRole.length > 0) {
|
|
963
|
+
return explicitRole;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/util.mjs
|
|
970
|
+
var presentationRoles = ["presentation", "none"];
|
|
971
|
+
function isElement(node) {
|
|
972
|
+
return node !== null && node.nodeType === node.ELEMENT_NODE;
|
|
973
|
+
}
|
|
974
|
+
function isHTMLTableCaptionElement(node) {
|
|
975
|
+
return isElement(node) && getLocalName(node) === "caption";
|
|
976
|
+
}
|
|
977
|
+
function isHTMLInputElement(node) {
|
|
978
|
+
return isElement(node) && getLocalName(node) === "input";
|
|
979
|
+
}
|
|
980
|
+
function isHTMLOptGroupElement(node) {
|
|
981
|
+
return isElement(node) && getLocalName(node) === "optgroup";
|
|
982
|
+
}
|
|
983
|
+
function isHTMLSelectElement(node) {
|
|
984
|
+
return isElement(node) && getLocalName(node) === "select";
|
|
985
|
+
}
|
|
986
|
+
function isHTMLTableElement(node) {
|
|
987
|
+
return isElement(node) && getLocalName(node) === "table";
|
|
988
|
+
}
|
|
989
|
+
function isHTMLTextAreaElement(node) {
|
|
990
|
+
return isElement(node) && getLocalName(node) === "textarea";
|
|
991
|
+
}
|
|
992
|
+
function safeWindow(node) {
|
|
993
|
+
var _ref = node.ownerDocument === null ? node : node.ownerDocument, defaultView = _ref.defaultView;
|
|
994
|
+
if (defaultView === null) {
|
|
995
|
+
throw new TypeError("no window available");
|
|
996
|
+
}
|
|
997
|
+
return defaultView;
|
|
998
|
+
}
|
|
999
|
+
function isHTMLFieldSetElement(node) {
|
|
1000
|
+
return isElement(node) && getLocalName(node) === "fieldset";
|
|
1001
|
+
}
|
|
1002
|
+
function isHTMLLegendElement(node) {
|
|
1003
|
+
return isElement(node) && getLocalName(node) === "legend";
|
|
1004
|
+
}
|
|
1005
|
+
function isHTMLSlotElement(node) {
|
|
1006
|
+
return isElement(node) && getLocalName(node) === "slot";
|
|
1007
|
+
}
|
|
1008
|
+
function isSVGElement(node) {
|
|
1009
|
+
return isElement(node) && node.ownerSVGElement !== void 0;
|
|
1010
|
+
}
|
|
1011
|
+
function isSVGSVGElement(node) {
|
|
1012
|
+
return isElement(node) && getLocalName(node) === "svg";
|
|
1013
|
+
}
|
|
1014
|
+
function isSVGTitleElement(node) {
|
|
1015
|
+
return isSVGElement(node) && getLocalName(node) === "title";
|
|
1016
|
+
}
|
|
1017
|
+
function queryIdRefs(node, attributeName) {
|
|
1018
|
+
if (isElement(node) && node.hasAttribute(attributeName)) {
|
|
1019
|
+
var ids = node.getAttribute(attributeName).split(" ");
|
|
1020
|
+
var root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
|
|
1021
|
+
return ids.map(function(id) {
|
|
1022
|
+
return root.getElementById(id);
|
|
1023
|
+
}).filter(
|
|
1024
|
+
function(element) {
|
|
1025
|
+
return element !== null;
|
|
1026
|
+
}
|
|
1027
|
+
// TODO: why does this not narrow?
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
return [];
|
|
1031
|
+
}
|
|
1032
|
+
function hasAnyConcreteRoles(node, roles) {
|
|
1033
|
+
if (isElement(node)) {
|
|
1034
|
+
return roles.indexOf(getRole(node)) !== -1;
|
|
1035
|
+
}
|
|
1036
|
+
return false;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/accessible-name-and-description.mjs
|
|
1040
|
+
function asFlatString(s) {
|
|
1041
|
+
return s.trim().replace(/\s\s+/g, " ");
|
|
1042
|
+
}
|
|
1043
|
+
function isHidden3(node, getComputedStyleImplementation) {
|
|
1044
|
+
if (!isElement(node)) {
|
|
1045
|
+
return false;
|
|
1046
|
+
}
|
|
1047
|
+
if (node.hasAttribute("hidden") || node.getAttribute("aria-hidden") === "true") {
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1050
|
+
var style = getComputedStyleImplementation(node);
|
|
1051
|
+
return style.getPropertyValue("display") === "none" || style.getPropertyValue("visibility") === "hidden";
|
|
1052
|
+
}
|
|
1053
|
+
function isControl(node) {
|
|
1054
|
+
return hasAnyConcreteRoles(node, ["button", "combobox", "listbox", "textbox"]) || hasAbstractRole(node, "range");
|
|
1055
|
+
}
|
|
1056
|
+
function hasAbstractRole(node, role) {
|
|
1057
|
+
if (!isElement(node)) {
|
|
1058
|
+
return false;
|
|
1059
|
+
}
|
|
1060
|
+
switch (role) {
|
|
1061
|
+
case "range":
|
|
1062
|
+
return hasAnyConcreteRoles(node, ["meter", "progressbar", "scrollbar", "slider", "spinbutton"]);
|
|
1063
|
+
default:
|
|
1064
|
+
throw new TypeError("No knowledge about abstract role '".concat(role, "'. This is likely a bug :("));
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
function querySelectorAllSubtree(element, selectors) {
|
|
1068
|
+
var elements = arrayFrom(element.querySelectorAll(selectors));
|
|
1069
|
+
queryIdRefs(element, "aria-owns").forEach(function(root) {
|
|
1070
|
+
elements.push.apply(elements, arrayFrom(root.querySelectorAll(selectors)));
|
|
1071
|
+
});
|
|
1072
|
+
return elements;
|
|
1073
|
+
}
|
|
1074
|
+
function querySelectedOptions(listbox) {
|
|
1075
|
+
if (isHTMLSelectElement(listbox)) {
|
|
1076
|
+
return listbox.selectedOptions || querySelectorAllSubtree(listbox, "[selected]");
|
|
1077
|
+
}
|
|
1078
|
+
return querySelectorAllSubtree(listbox, '[aria-selected="true"]');
|
|
1079
|
+
}
|
|
1080
|
+
function isMarkedPresentational(node) {
|
|
1081
|
+
return hasAnyConcreteRoles(node, presentationRoles);
|
|
1082
|
+
}
|
|
1083
|
+
function isNativeHostLanguageTextAlternativeElement(node) {
|
|
1084
|
+
return isHTMLTableCaptionElement(node);
|
|
1085
|
+
}
|
|
1086
|
+
function allowsNameFromContent(node) {
|
|
1087
|
+
return hasAnyConcreteRoles(node, ["button", "cell", "checkbox", "columnheader", "gridcell", "heading", "label", "legend", "link", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "row", "rowheader", "switch", "tab", "tooltip", "treeitem"]);
|
|
1088
|
+
}
|
|
1089
|
+
function isDescendantOfNativeHostLanguageTextAlternativeElement(node) {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
function getValueOfTextbox(element) {
|
|
1093
|
+
if (isHTMLInputElement(element) || isHTMLTextAreaElement(element)) {
|
|
1094
|
+
return element.value;
|
|
1095
|
+
}
|
|
1096
|
+
return element.textContent || "";
|
|
1097
|
+
}
|
|
1098
|
+
function getTextualContent(declaration) {
|
|
1099
|
+
var content = declaration.getPropertyValue("content");
|
|
1100
|
+
if (/^["'].*["']$/.test(content)) {
|
|
1101
|
+
return content.slice(1, -1);
|
|
1102
|
+
}
|
|
1103
|
+
return "";
|
|
1104
|
+
}
|
|
1105
|
+
function isLabelableElement(element) {
|
|
1106
|
+
var localName = getLocalName(element);
|
|
1107
|
+
return localName === "button" || localName === "input" && element.getAttribute("type") !== "hidden" || localName === "meter" || localName === "output" || localName === "progress" || localName === "select" || localName === "textarea";
|
|
1108
|
+
}
|
|
1109
|
+
function findLabelableElement(element) {
|
|
1110
|
+
if (isLabelableElement(element)) {
|
|
1111
|
+
return element;
|
|
1112
|
+
}
|
|
1113
|
+
var labelableElement = null;
|
|
1114
|
+
element.childNodes.forEach(function(childNode) {
|
|
1115
|
+
if (labelableElement === null && isElement(childNode)) {
|
|
1116
|
+
var descendantLabelableElement = findLabelableElement(childNode);
|
|
1117
|
+
if (descendantLabelableElement !== null) {
|
|
1118
|
+
labelableElement = descendantLabelableElement;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1122
|
+
return labelableElement;
|
|
1123
|
+
}
|
|
1124
|
+
function getControlOfLabel(label) {
|
|
1125
|
+
if (label.control !== void 0) {
|
|
1126
|
+
return label.control;
|
|
1127
|
+
}
|
|
1128
|
+
var htmlFor = label.getAttribute("for");
|
|
1129
|
+
if (htmlFor !== null) {
|
|
1130
|
+
return label.ownerDocument.getElementById(htmlFor);
|
|
1131
|
+
}
|
|
1132
|
+
return findLabelableElement(label);
|
|
1133
|
+
}
|
|
1134
|
+
function getLabels(element) {
|
|
1135
|
+
var labelsProperty = element.labels;
|
|
1136
|
+
if (labelsProperty === null) {
|
|
1137
|
+
return labelsProperty;
|
|
1138
|
+
}
|
|
1139
|
+
if (labelsProperty !== void 0) {
|
|
1140
|
+
return arrayFrom(labelsProperty);
|
|
1141
|
+
}
|
|
1142
|
+
if (!isLabelableElement(element)) {
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
var document2 = element.ownerDocument;
|
|
1146
|
+
return arrayFrom(document2.querySelectorAll("label")).filter(function(label) {
|
|
1147
|
+
return getControlOfLabel(label) === element;
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
function getSlotContents(slot) {
|
|
1151
|
+
var assignedNodes = slot.assignedNodes();
|
|
1152
|
+
if (assignedNodes.length === 0) {
|
|
1153
|
+
return arrayFrom(slot.childNodes);
|
|
1154
|
+
}
|
|
1155
|
+
return assignedNodes;
|
|
1156
|
+
}
|
|
1157
|
+
function computeTextAlternative(root) {
|
|
1158
|
+
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
1159
|
+
var consultedNodes = new SetLike_default();
|
|
1160
|
+
var computedStyles = typeof Map === "undefined" ? void 0 : /* @__PURE__ */ new Map();
|
|
1161
|
+
var window2 = safeWindow(root);
|
|
1162
|
+
var _options$compute = options.compute, compute = _options$compute === void 0 ? "name" : _options$compute, _options$computedStyl = options.computedStyleSupportsPseudoElements, computedStyleSupportsPseudoElements = _options$computedStyl === void 0 ? options.getComputedStyle !== void 0 : _options$computedStyl, _options$getComputedS = options.getComputedStyle, uncachedGetComputedStyle = _options$getComputedS === void 0 ? window2.getComputedStyle.bind(window2) : _options$getComputedS, _options$hidden = options.hidden, hidden = _options$hidden === void 0 ? false : _options$hidden;
|
|
1163
|
+
var getComputedStyle2 = function getComputedStyle3(el, pseudoElement) {
|
|
1164
|
+
if (pseudoElement !== void 0) {
|
|
1165
|
+
throw new Error("use uncachedGetComputedStyle directly for pseudo elements");
|
|
1166
|
+
}
|
|
1167
|
+
if (computedStyles === void 0) {
|
|
1168
|
+
return uncachedGetComputedStyle(el);
|
|
1169
|
+
}
|
|
1170
|
+
var cachedStyles = computedStyles.get(el);
|
|
1171
|
+
if (cachedStyles) {
|
|
1172
|
+
return cachedStyles;
|
|
1173
|
+
}
|
|
1174
|
+
var style = uncachedGetComputedStyle(el, pseudoElement);
|
|
1175
|
+
computedStyles.set(el, style);
|
|
1176
|
+
return style;
|
|
1177
|
+
};
|
|
1178
|
+
function computeMiscTextAlternative(node, context) {
|
|
1179
|
+
var accumulatedText = "";
|
|
1180
|
+
if (isElement(node) && computedStyleSupportsPseudoElements) {
|
|
1181
|
+
var pseudoBefore = uncachedGetComputedStyle(node, "::before");
|
|
1182
|
+
var beforeContent = getTextualContent(pseudoBefore);
|
|
1183
|
+
accumulatedText = "".concat(beforeContent, " ").concat(accumulatedText);
|
|
1184
|
+
}
|
|
1185
|
+
var childNodes = isHTMLSlotElement(node) ? getSlotContents(node) : arrayFrom(node.childNodes).concat(queryIdRefs(node, "aria-owns"));
|
|
1186
|
+
childNodes.forEach(function(child) {
|
|
1187
|
+
var result = computeTextAlternative2(child, {
|
|
1188
|
+
isEmbeddedInLabel: context.isEmbeddedInLabel,
|
|
1189
|
+
isReferenced: false,
|
|
1190
|
+
recursion: true
|
|
1191
|
+
});
|
|
1192
|
+
var display = isElement(child) ? getComputedStyle2(child).getPropertyValue("display") : "inline";
|
|
1193
|
+
var separator = display !== "inline" ? " " : "";
|
|
1194
|
+
accumulatedText += "".concat(separator).concat(result).concat(separator);
|
|
1195
|
+
});
|
|
1196
|
+
if (isElement(node) && computedStyleSupportsPseudoElements) {
|
|
1197
|
+
var pseudoAfter = uncachedGetComputedStyle(node, "::after");
|
|
1198
|
+
var afterContent = getTextualContent(pseudoAfter);
|
|
1199
|
+
accumulatedText = "".concat(accumulatedText, " ").concat(afterContent);
|
|
1200
|
+
}
|
|
1201
|
+
return accumulatedText.trim();
|
|
1202
|
+
}
|
|
1203
|
+
function useAttribute(element, attributeName) {
|
|
1204
|
+
var attribute = element.getAttributeNode(attributeName);
|
|
1205
|
+
if (attribute !== null && !consultedNodes.has(attribute) && attribute.value.trim() !== "") {
|
|
1206
|
+
consultedNodes.add(attribute);
|
|
1207
|
+
return attribute.value;
|
|
1208
|
+
}
|
|
1209
|
+
return null;
|
|
1210
|
+
}
|
|
1211
|
+
function computeTooltipAttributeValue(node) {
|
|
1212
|
+
if (!isElement(node)) {
|
|
1213
|
+
return null;
|
|
1214
|
+
}
|
|
1215
|
+
return useAttribute(node, "title");
|
|
1216
|
+
}
|
|
1217
|
+
function computeElementTextAlternative(node) {
|
|
1218
|
+
if (!isElement(node)) {
|
|
1219
|
+
return null;
|
|
1220
|
+
}
|
|
1221
|
+
if (isHTMLFieldSetElement(node)) {
|
|
1222
|
+
consultedNodes.add(node);
|
|
1223
|
+
var children = arrayFrom(node.childNodes);
|
|
1224
|
+
for (var i = 0; i < children.length; i += 1) {
|
|
1225
|
+
var child = children[i];
|
|
1226
|
+
if (isHTMLLegendElement(child)) {
|
|
1227
|
+
return computeTextAlternative2(child, {
|
|
1228
|
+
isEmbeddedInLabel: false,
|
|
1229
|
+
isReferenced: false,
|
|
1230
|
+
recursion: false
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
} else if (isHTMLTableElement(node)) {
|
|
1235
|
+
consultedNodes.add(node);
|
|
1236
|
+
var _children = arrayFrom(node.childNodes);
|
|
1237
|
+
for (var _i = 0; _i < _children.length; _i += 1) {
|
|
1238
|
+
var _child = _children[_i];
|
|
1239
|
+
if (isHTMLTableCaptionElement(_child)) {
|
|
1240
|
+
return computeTextAlternative2(_child, {
|
|
1241
|
+
isEmbeddedInLabel: false,
|
|
1242
|
+
isReferenced: false,
|
|
1243
|
+
recursion: false
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
} else if (isSVGSVGElement(node)) {
|
|
1248
|
+
consultedNodes.add(node);
|
|
1249
|
+
var _children2 = arrayFrom(node.childNodes);
|
|
1250
|
+
for (var _i2 = 0; _i2 < _children2.length; _i2 += 1) {
|
|
1251
|
+
var _child2 = _children2[_i2];
|
|
1252
|
+
if (isSVGTitleElement(_child2)) {
|
|
1253
|
+
return _child2.textContent;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
return null;
|
|
1257
|
+
} else if (getLocalName(node) === "img" || getLocalName(node) === "area") {
|
|
1258
|
+
var nameFromAlt = useAttribute(node, "alt");
|
|
1259
|
+
if (nameFromAlt !== null) {
|
|
1260
|
+
return nameFromAlt;
|
|
1261
|
+
}
|
|
1262
|
+
} else if (isHTMLOptGroupElement(node)) {
|
|
1263
|
+
var nameFromLabel = useAttribute(node, "label");
|
|
1264
|
+
if (nameFromLabel !== null) {
|
|
1265
|
+
return nameFromLabel;
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
if (isHTMLInputElement(node) && (node.type === "button" || node.type === "submit" || node.type === "reset")) {
|
|
1269
|
+
var nameFromValue = useAttribute(node, "value");
|
|
1270
|
+
if (nameFromValue !== null) {
|
|
1271
|
+
return nameFromValue;
|
|
1272
|
+
}
|
|
1273
|
+
if (node.type === "submit") {
|
|
1274
|
+
return "Submit";
|
|
1275
|
+
}
|
|
1276
|
+
if (node.type === "reset") {
|
|
1277
|
+
return "Reset";
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
var labels = getLabels(node);
|
|
1281
|
+
if (labels !== null && labels.length !== 0) {
|
|
1282
|
+
consultedNodes.add(node);
|
|
1283
|
+
return arrayFrom(labels).map(function(element) {
|
|
1284
|
+
return computeTextAlternative2(element, {
|
|
1285
|
+
isEmbeddedInLabel: true,
|
|
1286
|
+
isReferenced: false,
|
|
1287
|
+
recursion: true
|
|
1288
|
+
});
|
|
1289
|
+
}).filter(function(label) {
|
|
1290
|
+
return label.length > 0;
|
|
1291
|
+
}).join(" ");
|
|
1292
|
+
}
|
|
1293
|
+
if (isHTMLInputElement(node) && node.type === "image") {
|
|
1294
|
+
var _nameFromAlt = useAttribute(node, "alt");
|
|
1295
|
+
if (_nameFromAlt !== null) {
|
|
1296
|
+
return _nameFromAlt;
|
|
1297
|
+
}
|
|
1298
|
+
var nameFromTitle = useAttribute(node, "title");
|
|
1299
|
+
if (nameFromTitle !== null) {
|
|
1300
|
+
return nameFromTitle;
|
|
1301
|
+
}
|
|
1302
|
+
return "Submit Query";
|
|
1303
|
+
}
|
|
1304
|
+
if (hasAnyConcreteRoles(node, ["button"])) {
|
|
1305
|
+
var nameFromSubTree = computeMiscTextAlternative(node, {
|
|
1306
|
+
isEmbeddedInLabel: false,
|
|
1307
|
+
isReferenced: false
|
|
1308
|
+
});
|
|
1309
|
+
if (nameFromSubTree !== "") {
|
|
1310
|
+
return nameFromSubTree;
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
function computeTextAlternative2(current, context) {
|
|
1316
|
+
if (consultedNodes.has(current)) {
|
|
1317
|
+
return "";
|
|
1318
|
+
}
|
|
1319
|
+
if (!hidden && isHidden3(current, getComputedStyle2) && !context.isReferenced) {
|
|
1320
|
+
consultedNodes.add(current);
|
|
1321
|
+
return "";
|
|
1322
|
+
}
|
|
1323
|
+
var labelAttributeNode = isElement(current) ? current.getAttributeNode("aria-labelledby") : null;
|
|
1324
|
+
var labelElements = labelAttributeNode !== null && !consultedNodes.has(labelAttributeNode) ? queryIdRefs(current, "aria-labelledby") : [];
|
|
1325
|
+
if (compute === "name" && !context.isReferenced && labelElements.length > 0) {
|
|
1326
|
+
consultedNodes.add(labelAttributeNode);
|
|
1327
|
+
return labelElements.map(function(element) {
|
|
1328
|
+
return computeTextAlternative2(element, {
|
|
1329
|
+
isEmbeddedInLabel: context.isEmbeddedInLabel,
|
|
1330
|
+
isReferenced: true,
|
|
1331
|
+
// this isn't recursion as specified, otherwise we would skip
|
|
1332
|
+
// `aria-label` in
|
|
1333
|
+
// <input id="myself" aria-label="foo" aria-labelledby="myself"
|
|
1334
|
+
recursion: false
|
|
1335
|
+
});
|
|
1336
|
+
}).join(" ");
|
|
1337
|
+
}
|
|
1338
|
+
var skipToStep2E = context.recursion && isControl(current) && compute === "name";
|
|
1339
|
+
if (!skipToStep2E) {
|
|
1340
|
+
var ariaLabel = (isElement(current) && current.getAttribute("aria-label") || "").trim();
|
|
1341
|
+
if (ariaLabel !== "" && compute === "name") {
|
|
1342
|
+
consultedNodes.add(current);
|
|
1343
|
+
return ariaLabel;
|
|
1344
|
+
}
|
|
1345
|
+
if (!isMarkedPresentational(current)) {
|
|
1346
|
+
var elementTextAlternative = computeElementTextAlternative(current);
|
|
1347
|
+
if (elementTextAlternative !== null) {
|
|
1348
|
+
consultedNodes.add(current);
|
|
1349
|
+
return elementTextAlternative;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
if (hasAnyConcreteRoles(current, ["menu"])) {
|
|
1354
|
+
consultedNodes.add(current);
|
|
1355
|
+
return "";
|
|
1356
|
+
}
|
|
1357
|
+
if (skipToStep2E || context.isEmbeddedInLabel || context.isReferenced) {
|
|
1358
|
+
if (hasAnyConcreteRoles(current, ["combobox", "listbox"])) {
|
|
1359
|
+
consultedNodes.add(current);
|
|
1360
|
+
var selectedOptions = querySelectedOptions(current);
|
|
1361
|
+
if (selectedOptions.length === 0) {
|
|
1362
|
+
return isHTMLInputElement(current) ? current.value : "";
|
|
1363
|
+
}
|
|
1364
|
+
return arrayFrom(selectedOptions).map(function(selectedOption) {
|
|
1365
|
+
return computeTextAlternative2(selectedOption, {
|
|
1366
|
+
isEmbeddedInLabel: context.isEmbeddedInLabel,
|
|
1367
|
+
isReferenced: false,
|
|
1368
|
+
recursion: true
|
|
1369
|
+
});
|
|
1370
|
+
}).join(" ");
|
|
1371
|
+
}
|
|
1372
|
+
if (hasAbstractRole(current, "range")) {
|
|
1373
|
+
consultedNodes.add(current);
|
|
1374
|
+
if (current.hasAttribute("aria-valuetext")) {
|
|
1375
|
+
return current.getAttribute("aria-valuetext");
|
|
1376
|
+
}
|
|
1377
|
+
if (current.hasAttribute("aria-valuenow")) {
|
|
1378
|
+
return current.getAttribute("aria-valuenow");
|
|
1379
|
+
}
|
|
1380
|
+
return current.getAttribute("value") || "";
|
|
1381
|
+
}
|
|
1382
|
+
if (hasAnyConcreteRoles(current, ["textbox"])) {
|
|
1383
|
+
consultedNodes.add(current);
|
|
1384
|
+
return getValueOfTextbox(current);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
if (allowsNameFromContent(current) || isElement(current) && context.isReferenced || isNativeHostLanguageTextAlternativeElement(current) || isDescendantOfNativeHostLanguageTextAlternativeElement(current)) {
|
|
1388
|
+
var accumulatedText2F = computeMiscTextAlternative(current, {
|
|
1389
|
+
isEmbeddedInLabel: context.isEmbeddedInLabel,
|
|
1390
|
+
isReferenced: false
|
|
1391
|
+
});
|
|
1392
|
+
if (accumulatedText2F !== "") {
|
|
1393
|
+
consultedNodes.add(current);
|
|
1394
|
+
return accumulatedText2F;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (current.nodeType === current.TEXT_NODE) {
|
|
1398
|
+
consultedNodes.add(current);
|
|
1399
|
+
return current.textContent || "";
|
|
1400
|
+
}
|
|
1401
|
+
if (context.recursion) {
|
|
1402
|
+
consultedNodes.add(current);
|
|
1403
|
+
return computeMiscTextAlternative(current, {
|
|
1404
|
+
isEmbeddedInLabel: context.isEmbeddedInLabel,
|
|
1405
|
+
isReferenced: false
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
var tooltipAttributeValue = computeTooltipAttributeValue(current);
|
|
1409
|
+
if (tooltipAttributeValue !== null) {
|
|
1410
|
+
consultedNodes.add(current);
|
|
1411
|
+
return tooltipAttributeValue;
|
|
1412
|
+
}
|
|
1413
|
+
consultedNodes.add(current);
|
|
1414
|
+
return "";
|
|
1415
|
+
}
|
|
1416
|
+
return asFlatString(computeTextAlternative2(root, {
|
|
1417
|
+
isEmbeddedInLabel: false,
|
|
1418
|
+
// by spec computeAccessibleDescription starts with the referenced elements as roots
|
|
1419
|
+
isReferenced: compute === "description",
|
|
1420
|
+
recursion: false
|
|
1421
|
+
}));
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// ../../node_modules/.pnpm/dom-accessibility-api@0.7.1/node_modules/dom-accessibility-api/dist/accessible-name.mjs
|
|
1425
|
+
function prohibitsNaming(node) {
|
|
1426
|
+
return hasAnyConcreteRoles(node, ["caption", "code", "deletion", "emphasis", "generic", "insertion", "none", "paragraph", "presentation", "strong", "subscript", "superscript"]);
|
|
1427
|
+
}
|
|
1428
|
+
function computeAccessibleName(root) {
|
|
1429
|
+
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
1430
|
+
if (prohibitsNaming(root)) {
|
|
1431
|
+
return "";
|
|
1432
|
+
}
|
|
1433
|
+
return computeTextAlternative(root, options);
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
// ../core/src/rules.ts
|
|
1437
|
+
var ROW_TOLERANCE_PX = 8;
|
|
1438
|
+
var flagEntries = (sequence, message) => sequence.flatMap((entry) => {
|
|
1439
|
+
const msg = message(entry);
|
|
1440
|
+
return msg ? [{ message: msg, target: entry }] : [];
|
|
1441
|
+
});
|
|
1442
|
+
var noPositiveTabIndex = (sequence) => flagEntries(
|
|
1443
|
+
sequence,
|
|
1444
|
+
(entry) => entry.tabIndex > 0 ? `Element has tabindex="${entry.tabIndex}". Positive tabindex overrides the natural DOM order and is fragile; use 0 or restructure the DOM.` : null
|
|
1445
|
+
);
|
|
1446
|
+
var visualOrderMismatch = (sequence) => {
|
|
1447
|
+
const floats = sequence.map((entry) => floatingAncestor(entry.element));
|
|
1448
|
+
const scrollers = sequence.map((entry) => scrollAncestor(entry.element));
|
|
1449
|
+
const out = [];
|
|
1450
|
+
for (let idx = 1; idx < sequence.length; idx++) {
|
|
1451
|
+
const prev = sequence[idx - 1];
|
|
1452
|
+
const cur = sequence[idx];
|
|
1453
|
+
if (floats[idx - 1] !== floats[idx] || scrollers[idx - 1] !== scrollers[idx]) {
|
|
1454
|
+
continue;
|
|
1455
|
+
}
|
|
1456
|
+
const prevX = prev.rect.left + prev.rect.width / 2;
|
|
1457
|
+
const curX = cur.rect.left + cur.rect.width / 2;
|
|
1458
|
+
const nextColumn = cur.rect.left >= prev.rect.right;
|
|
1459
|
+
const earlierRow = cur.rect.bottom <= prev.rect.top + ROW_TOLERANCE_PX;
|
|
1460
|
+
const sameRow = !earlierRow && cur.rect.top < prev.rect.bottom - ROW_TOLERANCE_PX;
|
|
1461
|
+
const backwardHop = !nextColumn && (earlierRow || sameRow && curX < prevX - 1);
|
|
1462
|
+
if (!backwardHop) {
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
out.push({
|
|
1466
|
+
message: `"${cur.selector}" comes after "${prev.selector}" in the tab order, but sits visually before it (reading order is top\u2192bottom, left\u2192right). Tab makes a backward hop here.`,
|
|
1467
|
+
target: cur
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
return out;
|
|
1471
|
+
};
|
|
1472
|
+
var missingAccessibleName = (sequence) => flagEntries(sequence, (entry) => {
|
|
1473
|
+
if (!isInteractive(entry.element)) {
|
|
1474
|
+
return null;
|
|
1475
|
+
}
|
|
1476
|
+
if (hasExplicitName(entry.element)) {
|
|
1477
|
+
return null;
|
|
1478
|
+
}
|
|
1479
|
+
if (computeAccessibleName(entry.element).trim() !== "") {
|
|
1480
|
+
return null;
|
|
1481
|
+
}
|
|
1482
|
+
return `Focusable element "${entry.selector}" has no accessible name (no text, aria-label, aria-labelledby, associated label, alt, or title).`;
|
|
1483
|
+
});
|
|
1484
|
+
var ariaHiddenFocusable = (sequence) => flagEntries(
|
|
1485
|
+
sequence,
|
|
1486
|
+
(entry) => inAriaHidden(entry.element) ? `"${entry.selector}" is tabbable but inside aria-hidden="true", so a screen-reader user lands on a control the SR won't announce. Add tabindex="-1"/inert, or remove aria-hidden.` : null
|
|
1487
|
+
);
|
|
1488
|
+
var hiddenWhileFocusable = (sequence, { container }) => {
|
|
1489
|
+
const revealOnFocus = focusRevealSelectors(container.ownerDocument);
|
|
1490
|
+
return flagEntries(sequence, (entry) => {
|
|
1491
|
+
const reason = hiddenReason(entry.element, entry.rect, revealOnFocus);
|
|
1492
|
+
return reason ? `"${entry.selector}" is tabbable but ${reason}. Hide it from the tab order too (display:none, the hidden attribute, or tabindex="-1").` : null;
|
|
1493
|
+
});
|
|
1494
|
+
};
|
|
1495
|
+
var clickableNotFocusable = (_sequence, { container, inSequence }) => {
|
|
1496
|
+
const wrapsFocusable = /* @__PURE__ */ new Set();
|
|
1497
|
+
for (const stop of inSequence) {
|
|
1498
|
+
for (let node = stop; node; node = node.parentElement) {
|
|
1499
|
+
if (wrapsFocusable.has(node)) {
|
|
1500
|
+
break;
|
|
1501
|
+
}
|
|
1502
|
+
wrapsFocusable.add(node);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
const out = [];
|
|
1506
|
+
for (const element of container.querySelectorAll("*")) {
|
|
1507
|
+
if (inSequence.has(element)) {
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
if (wrapsFocusable.has(element)) {
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
if (!looksClickable(element)) {
|
|
1514
|
+
continue;
|
|
1515
|
+
}
|
|
1516
|
+
if (isFocusManaged(element)) {
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
if (isInert2(element)) {
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
const rect = element.getBoundingClientRect();
|
|
1523
|
+
if (rect.width < 1 || rect.height < 1) {
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
const selector = selectorFor(element);
|
|
1527
|
+
out.push({
|
|
1528
|
+
message: `"${selector}" looks interactive (role or onclick) but is not in the tab order, so keyboard users can't reach it. Use a <button>/<a>, or add tabindex="0" plus Enter/Space handlers.`,
|
|
1529
|
+
target: element
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
return out;
|
|
1533
|
+
};
|
|
1534
|
+
var compositeRovingTabindex = (sequence) => {
|
|
1535
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1536
|
+
for (const entry of sequence) {
|
|
1537
|
+
const container = compositeAncestor(entry.element);
|
|
1538
|
+
if (!container) {
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1541
|
+
const list = groups.get(container) ?? [];
|
|
1542
|
+
list.push(entry);
|
|
1543
|
+
groups.set(container, list);
|
|
1544
|
+
}
|
|
1545
|
+
const out = [];
|
|
1546
|
+
for (const [container, members] of groups) {
|
|
1547
|
+
if (members.length < 2) {
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
const role = container.getAttribute("role");
|
|
1551
|
+
for (const member of members) {
|
|
1552
|
+
out.push({
|
|
1553
|
+
message: `${members.length} items inside role="${role}" are separate tab stops. A ${role} should expose one tab stop and move between items with the arrow keys (roving tabindex).`,
|
|
1554
|
+
target: member
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
return out;
|
|
1559
|
+
};
|
|
1560
|
+
var focusEscapesModal = (sequence, { container }) => {
|
|
1561
|
+
const modal = openModal(container);
|
|
1562
|
+
if (!modal) {
|
|
1563
|
+
return [];
|
|
1564
|
+
}
|
|
1565
|
+
const leaked = sequence.filter(
|
|
1566
|
+
(entry) => !modal.contains(entry.element) && !isInert2(entry.element)
|
|
1567
|
+
);
|
|
1568
|
+
if (leaked.length === 0) {
|
|
1569
|
+
return [];
|
|
1570
|
+
}
|
|
1571
|
+
const first = leaked[0];
|
|
1572
|
+
const subject = leaked.length === 1 ? `"${first.selector}" outside it is still tabbable` : `${leaked.length} controls outside it are still tabbable (e.g. "${first.selector}")`;
|
|
1573
|
+
return [
|
|
1574
|
+
{
|
|
1575
|
+
message: `A modal dialog is open, but ${subject}, so focus can leak behind the dialog. Mark background content inert (or aria-hidden + remove it from the tab order).`,
|
|
1576
|
+
target: first,
|
|
1577
|
+
// One finding, anchored on the first leaked control, but every other leaked
|
|
1578
|
+
// control shares the root cause (background not inert) and is ringed too.
|
|
1579
|
+
relatedElements: leaked.slice(1).map((entry) => entry.element)
|
|
1580
|
+
}
|
|
1581
|
+
];
|
|
1582
|
+
};
|
|
1583
|
+
var tabindexOnNoninteractive = (sequence) => flagEntries(sequence, (entry) => {
|
|
1584
|
+
if (entry.tabIndex !== 0) {
|
|
1585
|
+
return null;
|
|
1586
|
+
}
|
|
1587
|
+
if (entry.element.getAttribute("tabindex") === null) {
|
|
1588
|
+
return null;
|
|
1589
|
+
}
|
|
1590
|
+
const element = entry.element;
|
|
1591
|
+
if (isNativelyFocusable(element)) {
|
|
1592
|
+
return null;
|
|
1593
|
+
}
|
|
1594
|
+
if (isInteractive(element)) {
|
|
1595
|
+
return null;
|
|
1596
|
+
}
|
|
1597
|
+
if (element.isContentEditable) {
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
const role = element.getAttribute("role");
|
|
1601
|
+
if (role && role !== "presentation" && role !== "none") {
|
|
1602
|
+
return null;
|
|
1603
|
+
}
|
|
1604
|
+
if (isScrollContainer(element)) {
|
|
1605
|
+
return null;
|
|
1606
|
+
}
|
|
1607
|
+
return `"${entry.selector}" has tabindex="0" but is non-interactive (no role, not a control). If it's decorative, remove the tabindex, since it adds a dead stop to the tab order; if it's meant to be a control, give it a real role (or use a <button>).`;
|
|
1608
|
+
});
|
|
1609
|
+
var preferNativeElement = (sequence) => flagEntries(sequence, (entry) => {
|
|
1610
|
+
const native = nativeReplacement(entry.element);
|
|
1611
|
+
if (!native) {
|
|
1612
|
+
return null;
|
|
1613
|
+
}
|
|
1614
|
+
const tag = entry.element.tagName.toLowerCase();
|
|
1615
|
+
const role = entry.element.getAttribute("role");
|
|
1616
|
+
return `"${entry.selector}" is a <${tag}> with role="${role}". Prefer a native ${native}: focus, keyboard activation (Enter/Space), and screen-reader semantics come for free, instead of being reimplemented with ARIA + JS.`;
|
|
1617
|
+
});
|
|
1618
|
+
var duplicateAutofocus = (_sequence, { container }) => {
|
|
1619
|
+
const focusableAutofocus = Array.from(container.querySelectorAll("[autofocus]")).filter(
|
|
1620
|
+
(element) => isFocusable(element, { getShadowRoot: true })
|
|
1621
|
+
);
|
|
1622
|
+
if (focusableAutofocus.length < 2) {
|
|
1623
|
+
return [];
|
|
1624
|
+
}
|
|
1625
|
+
return focusableAutofocus.slice(1).map((element) => {
|
|
1626
|
+
const selector = selectorFor(element);
|
|
1627
|
+
return {
|
|
1628
|
+
message: `"${selector}" also has autofocus, but a page can autofocus only one element; the first focusable one in document order wins, so this one is silently ignored. Remove the extra autofocus.`,
|
|
1629
|
+
target: element
|
|
1630
|
+
};
|
|
1631
|
+
});
|
|
1632
|
+
};
|
|
1633
|
+
var autofocusNotFocusable = (_sequence, { container }) => {
|
|
1634
|
+
const out = [];
|
|
1635
|
+
for (const element of container.querySelectorAll("[autofocus]")) {
|
|
1636
|
+
if (isFocusable(element, { getShadowRoot: true })) {
|
|
1637
|
+
continue;
|
|
1638
|
+
}
|
|
1639
|
+
const selector = selectorFor(element);
|
|
1640
|
+
out.push({
|
|
1641
|
+
message: `"${selector}" has autofocus but isn't focusable (no tabindex, not a form control), so it's ignored on load. Remove the autofocus, or make the element focusable (e.g. tabindex="-1").`,
|
|
1642
|
+
target: element
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
return out;
|
|
1646
|
+
};
|
|
1647
|
+
var nestedInteractive = (sequence, { container, inSequence }) => {
|
|
1648
|
+
const stop = container.parentElement;
|
|
1649
|
+
const out = [];
|
|
1650
|
+
for (const entry of sequence) {
|
|
1651
|
+
for (let node = entry.element.parentElement; node && node !== stop; node = node.parentElement) {
|
|
1652
|
+
if (!inSequence.has(node) && !isInteractive(node)) {
|
|
1653
|
+
continue;
|
|
1654
|
+
}
|
|
1655
|
+
out.push({
|
|
1656
|
+
message: `"${entry.selector}" is focusable but nested inside another focusable element ("${selectorFor(node)}"). Nesting interactive controls stacks two tab stops in one place and can hide the inner control's role/name from screen readers; don't put a focusable element inside another.`,
|
|
1657
|
+
target: entry
|
|
1658
|
+
});
|
|
1659
|
+
break;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
return out;
|
|
1663
|
+
};
|
|
1664
|
+
var redundantTabindex = (sequence) => flagEntries(sequence, (entry) => {
|
|
1665
|
+
if (entry.tabIndex !== 0) {
|
|
1666
|
+
return null;
|
|
1667
|
+
}
|
|
1668
|
+
if (entry.element.getAttribute("tabindex") === null) {
|
|
1669
|
+
return null;
|
|
1670
|
+
}
|
|
1671
|
+
if (!isNativelyFocusable(entry.element)) {
|
|
1672
|
+
return null;
|
|
1673
|
+
}
|
|
1674
|
+
return `"${entry.selector}" is already focusable, so its tabindex="0" is redundant. Remove the attribute; the element stays in the tab order on its own.`;
|
|
1675
|
+
});
|
|
1676
|
+
var ALL_RULES = {
|
|
1677
|
+
"no-positive-tabindex": {
|
|
1678
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",
|
|
1679
|
+
defaultSeverity: "error",
|
|
1680
|
+
run: noPositiveTabIndex
|
|
1681
|
+
},
|
|
1682
|
+
"visual-order-mismatch": {
|
|
1683
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",
|
|
1684
|
+
defaultSeverity: "warning",
|
|
1685
|
+
run: visualOrderMismatch
|
|
1686
|
+
},
|
|
1687
|
+
"missing-accessible-name": {
|
|
1688
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",
|
|
1689
|
+
defaultSeverity: "error",
|
|
1690
|
+
run: missingAccessibleName
|
|
1691
|
+
},
|
|
1692
|
+
"aria-hidden-focusable": {
|
|
1693
|
+
docs: "https://www.w3.org/TR/wai-aria-1.2/#aria-hidden",
|
|
1694
|
+
defaultSeverity: "error",
|
|
1695
|
+
run: ariaHiddenFocusable
|
|
1696
|
+
},
|
|
1697
|
+
"hidden-while-focusable": {
|
|
1698
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html",
|
|
1699
|
+
defaultSeverity: "error",
|
|
1700
|
+
run: hiddenWhileFocusable
|
|
1701
|
+
},
|
|
1702
|
+
"clickable-not-focusable": {
|
|
1703
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html",
|
|
1704
|
+
defaultSeverity: "error",
|
|
1705
|
+
run: clickableNotFocusable
|
|
1706
|
+
},
|
|
1707
|
+
"composite-roving-tabindex": {
|
|
1708
|
+
docs: "https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/",
|
|
1709
|
+
defaultSeverity: "warning",
|
|
1710
|
+
run: compositeRovingTabindex
|
|
1711
|
+
},
|
|
1712
|
+
"focus-escapes-modal": {
|
|
1713
|
+
docs: "https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/",
|
|
1714
|
+
defaultSeverity: "error",
|
|
1715
|
+
run: focusEscapesModal
|
|
1716
|
+
},
|
|
1717
|
+
"tabindex-on-noninteractive": {
|
|
1718
|
+
docs: "https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/",
|
|
1719
|
+
defaultSeverity: "error",
|
|
1720
|
+
run: tabindexOnNoninteractive
|
|
1721
|
+
},
|
|
1722
|
+
"prefer-native-element": {
|
|
1723
|
+
docs: "https://www.w3.org/TR/using-aria/#firstrule",
|
|
1724
|
+
defaultSeverity: "warning",
|
|
1725
|
+
run: preferNativeElement
|
|
1726
|
+
},
|
|
1727
|
+
"duplicate-autofocus": {
|
|
1728
|
+
docs: "https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute",
|
|
1729
|
+
defaultSeverity: "warning",
|
|
1730
|
+
run: duplicateAutofocus
|
|
1731
|
+
},
|
|
1732
|
+
"autofocus-not-focusable": {
|
|
1733
|
+
docs: "https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute",
|
|
1734
|
+
defaultSeverity: "warning",
|
|
1735
|
+
run: autofocusNotFocusable
|
|
1736
|
+
},
|
|
1737
|
+
"nested-interactive": {
|
|
1738
|
+
docs: "https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",
|
|
1739
|
+
defaultSeverity: "error",
|
|
1740
|
+
run: nestedInteractive
|
|
1741
|
+
},
|
|
1742
|
+
"redundant-tabindex": {
|
|
1743
|
+
docs: "https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex",
|
|
1744
|
+
defaultSeverity: "warning",
|
|
1745
|
+
run: redundantTabindex
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
var DEFAULT_SEVERITY = Object.fromEntries(
|
|
1749
|
+
Object.entries(ALL_RULES).map(([id, rule]) => [id, rule.defaultSeverity])
|
|
1750
|
+
);
|
|
1751
|
+
|
|
1752
|
+
// ../core/src/audit.ts
|
|
1753
|
+
function resolveRule(options, rule) {
|
|
1754
|
+
const setting = options.rules?.[rule.id];
|
|
1755
|
+
if (setting === void 0) {
|
|
1756
|
+
return { enabled: true, severity: rule.defaultSeverity };
|
|
1757
|
+
}
|
|
1758
|
+
if (setting === "off") {
|
|
1759
|
+
return { enabled: false, severity: rule.defaultSeverity };
|
|
1760
|
+
}
|
|
1761
|
+
return { enabled: true, severity: setting };
|
|
1762
|
+
}
|
|
1763
|
+
function toIssue(finding, rule, severity) {
|
|
1764
|
+
return {
|
|
1765
|
+
rule: rule.id,
|
|
1766
|
+
severity,
|
|
1767
|
+
message: finding.message,
|
|
1768
|
+
docs: rule.docs,
|
|
1769
|
+
relatedElements: finding.relatedElements
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
function locate(finding) {
|
|
1773
|
+
const { target } = finding;
|
|
1774
|
+
return "orderIndex" in target ? {
|
|
1775
|
+
element: target.element,
|
|
1776
|
+
selector: target.selector,
|
|
1777
|
+
orderIndex: target.orderIndex
|
|
1778
|
+
} : { element: target, selector: selectorFor(target) };
|
|
1779
|
+
}
|
|
1780
|
+
function audit(root = document, options = {}, customRules = []) {
|
|
1781
|
+
const container = root.nodeType === 9 ? root.documentElement : root;
|
|
1782
|
+
if (!container) {
|
|
1783
|
+
return finalize({ valid: true, sequence: [], violations: [] }, options.format);
|
|
1784
|
+
}
|
|
1785
|
+
const elements = tabbable(container, {
|
|
1786
|
+
getShadowRoot: true
|
|
1787
|
+
});
|
|
1788
|
+
const sequence = elements.map((element, orderIndex) => ({
|
|
1789
|
+
element,
|
|
1790
|
+
orderIndex,
|
|
1791
|
+
selector: selectorFor(element),
|
|
1792
|
+
tabIndex: getTabIndex(element),
|
|
1793
|
+
rect: element.getBoundingClientRect()
|
|
1794
|
+
}));
|
|
1795
|
+
const ctx = {
|
|
1796
|
+
container,
|
|
1797
|
+
inSequence: new Set(sequence.map((entry) => entry.element))
|
|
1798
|
+
};
|
|
1799
|
+
const builtins = Object.entries(ALL_RULES).map(([id, def]) => ({
|
|
1800
|
+
id,
|
|
1801
|
+
...def
|
|
1802
|
+
}));
|
|
1803
|
+
const byElement2 = /* @__PURE__ */ new Map();
|
|
1804
|
+
for (const rule of [...builtins, ...customRules]) {
|
|
1805
|
+
const { enabled, severity } = resolveRule(options, rule);
|
|
1806
|
+
if (!enabled) {
|
|
1807
|
+
continue;
|
|
1808
|
+
}
|
|
1809
|
+
for (const finding of rule.run(sequence, ctx)) {
|
|
1810
|
+
const { element, selector, orderIndex } = locate(finding);
|
|
1811
|
+
let violation = byElement2.get(element);
|
|
1812
|
+
if (!violation) {
|
|
1813
|
+
violation = { element, selector, orderIndex, issues: [] };
|
|
1814
|
+
byElement2.set(element, violation);
|
|
1815
|
+
}
|
|
1816
|
+
const issue = toIssue(finding, rule, severity);
|
|
1817
|
+
if (isRuleIgnored(element, rule.id)) {
|
|
1818
|
+
issue.ignored = true;
|
|
1819
|
+
}
|
|
1820
|
+
violation.issues.push(issue);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
const violations = [...byElement2.values()].sort(
|
|
1824
|
+
(a, b) => (a.orderIndex ?? Infinity) - (b.orderIndex ?? Infinity)
|
|
1825
|
+
);
|
|
1826
|
+
for (const violation of violations) {
|
|
1827
|
+
violation.issues.sort(
|
|
1828
|
+
(a, b) => a.severity === b.severity ? 0 : a.severity === "error" ? -1 : 1
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1831
|
+
const hasErrors = violations.some(
|
|
1832
|
+
(violation) => violation.issues.some((issue) => issue.severity === "error" && !issue.ignored)
|
|
1833
|
+
);
|
|
1834
|
+
return finalize({ valid: !hasErrors, sequence, violations }, options.format);
|
|
1835
|
+
}
|
|
1836
|
+
function finalize(result, format) {
|
|
1837
|
+
if (!format) {
|
|
1838
|
+
return result;
|
|
1839
|
+
}
|
|
1840
|
+
return { ...result, violations: reshape(result.violations, format) };
|
|
1841
|
+
}
|
|
1842
|
+
function reshape(violations, format) {
|
|
1843
|
+
switch (format) {
|
|
1844
|
+
case "text":
|
|
1845
|
+
return renderText(violations);
|
|
1846
|
+
case "by-element":
|
|
1847
|
+
return byElement(violations);
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
var related = (issue) => issue.relatedElements?.map(selectorFor);
|
|
1851
|
+
function byElement(violations) {
|
|
1852
|
+
return violations.map((violation) => ({
|
|
1853
|
+
selector: violation.selector,
|
|
1854
|
+
orderIndex: violation.orderIndex,
|
|
1855
|
+
issueCount: violation.issues.length,
|
|
1856
|
+
issues: violation.issues.map((issue) => ({
|
|
1857
|
+
rule: issue.rule,
|
|
1858
|
+
severity: issue.severity,
|
|
1859
|
+
message: issue.message,
|
|
1860
|
+
docs: issue.docs,
|
|
1861
|
+
related: related(issue),
|
|
1862
|
+
ignored: issue.ignored
|
|
1863
|
+
}))
|
|
1864
|
+
}));
|
|
1865
|
+
}
|
|
1866
|
+
function renderText(violations) {
|
|
1867
|
+
if (!violations.length) {
|
|
1868
|
+
return "No tab-order issues.";
|
|
1869
|
+
}
|
|
1870
|
+
return violations.map((violation) => {
|
|
1871
|
+
const pos = violation.orderIndex !== void 0 ? `#${violation.orderIndex + 1} ` : "";
|
|
1872
|
+
const issues = violation.issues.map((issue) => {
|
|
1873
|
+
const rel = related(issue);
|
|
1874
|
+
return ` - ${issue.severity.toUpperCase()} [${issue.rule}] ${issue.message}` + (rel?.length ? ` (related: ${rel.join(", ")})` : "") + (issue.ignored ? " (ignored via data-ooo-ignore)" : "");
|
|
1875
|
+
}).join("\n");
|
|
1876
|
+
return `${pos}${violation.selector}
|
|
1877
|
+
${issues}`;
|
|
1878
|
+
}).join("\n\n");
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
// src/inject.ts
|
|
1882
|
+
globalThis.__ooo = { audit };
|
|
1883
|
+
})();
|
|
1884
|
+
/*! Bundled license information:
|
|
1885
|
+
|
|
1886
|
+
tabbable/dist/index.esm.js:
|
|
1887
|
+
(*!
|
|
1888
|
+
* tabbable 6.5.0
|
|
1889
|
+
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
1890
|
+
*)
|
|
1891
|
+
*/
|