@accesslint/core 0.3.9 → 0.3.11
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/dist/index.cjs +5 -5
- package/dist/index.iife.js +5 -5
- package/dist/index.js +802 -724
- package/dist/rules/aria/aria-name-rules.d.ts.map +1 -1
- package/dist/rules/aria/button-name.d.ts.map +1 -1
- package/dist/rules/color/color-contrast.d.ts.map +1 -1
- package/dist/rules/engine.d.ts.map +1 -1
- package/dist/rules/forms/label-content-name-mismatch.d.ts.map +1 -1
- package/dist/rules/forms/label.d.ts.map +1 -1
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/keyboard/interactive-rules.d.ts.map +1 -1
- package/dist/rules/links/link-name.d.ts.map +1 -1
- package/dist/rules/structure/document-rules.d.ts.map +1 -1
- package/dist/rules/structure/list-rules.d.ts +1 -0
- package/dist/rules/structure/list-rules.d.ts.map +1 -1
- package/dist/rules/types.d.ts +2 -0
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/utils/aria.d.ts +6 -0
- package/dist/rules/utils/aria.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
let
|
|
2
|
-
function
|
|
3
|
-
|
|
1
|
+
let B = /* @__PURE__ */ new WeakMap();
|
|
2
|
+
function we() {
|
|
3
|
+
B = /* @__PURE__ */ new WeakMap();
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function de(t) {
|
|
6
6
|
var i;
|
|
7
7
|
const a = t.tagName.toLowerCase(), e = (i = t.getAttribute("type")) == null ? void 0 : i.toLowerCase();
|
|
8
8
|
switch (a) {
|
|
@@ -117,30 +117,30 @@ function ue(t) {
|
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
function
|
|
120
|
+
function q(t) {
|
|
121
121
|
var n;
|
|
122
|
-
const a =
|
|
122
|
+
const a = B.get(t);
|
|
123
123
|
if (a !== void 0) return a;
|
|
124
|
-
const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null ||
|
|
125
|
-
return
|
|
124
|
+
const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null || de(t);
|
|
125
|
+
return B.set(t, i), i;
|
|
126
126
|
}
|
|
127
127
|
let F = /* @__PURE__ */ new WeakMap();
|
|
128
|
-
function
|
|
128
|
+
function Ae() {
|
|
129
129
|
F = /* @__PURE__ */ new WeakMap();
|
|
130
130
|
}
|
|
131
131
|
function v(t) {
|
|
132
132
|
const a = F.get(t);
|
|
133
133
|
if (a !== void 0) return a;
|
|
134
|
-
const e =
|
|
134
|
+
const e = xe(t);
|
|
135
135
|
return F.set(t, e), e;
|
|
136
136
|
}
|
|
137
|
-
function
|
|
137
|
+
function xe(t) {
|
|
138
138
|
var r, o, s, l, h;
|
|
139
139
|
const a = t.getAttribute("aria-labelledby");
|
|
140
140
|
if (a) {
|
|
141
|
-
const c = a.split(/\s+/).map((
|
|
142
|
-
const
|
|
143
|
-
return
|
|
141
|
+
const c = a.split(/\s+/).map((u) => {
|
|
142
|
+
const p = t.ownerDocument.getElementById(u);
|
|
143
|
+
return p ? A(p).trim() : "";
|
|
144
144
|
}).filter(Boolean);
|
|
145
145
|
if (c.length) return c.join(" ");
|
|
146
146
|
}
|
|
@@ -148,11 +148,11 @@ function we(t) {
|
|
|
148
148
|
if (e) return e;
|
|
149
149
|
if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
|
|
150
150
|
if (t.id) {
|
|
151
|
-
const
|
|
151
|
+
const p = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`), b = p ? A(p).trim() : "";
|
|
152
152
|
if (b) return b;
|
|
153
153
|
}
|
|
154
|
-
const c = t.closest("label"),
|
|
155
|
-
if (
|
|
154
|
+
const c = t.closest("label"), u = c ? A(c).trim() : "";
|
|
155
|
+
if (u) return u;
|
|
156
156
|
}
|
|
157
157
|
const i = (o = t.getAttribute("title")) == null ? void 0 : o.trim();
|
|
158
158
|
if (i) return i;
|
|
@@ -164,24 +164,24 @@ function we(t) {
|
|
|
164
164
|
if (n === "fieldset") {
|
|
165
165
|
const c = t.querySelector(":scope > legend");
|
|
166
166
|
if (c) {
|
|
167
|
-
const
|
|
168
|
-
if (
|
|
167
|
+
const u = A(c).trim();
|
|
168
|
+
if (u) return u;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
if (n === "table") {
|
|
172
172
|
const c = t.querySelector(":scope > caption");
|
|
173
173
|
if (c) {
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
174
|
+
const u = A(c).trim();
|
|
175
|
+
if (u) return u;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
if (!(t instanceof HTMLInputElement)) {
|
|
179
|
-
const c =
|
|
179
|
+
const c = A(t).trim();
|
|
180
180
|
if (c) return c;
|
|
181
181
|
}
|
|
182
182
|
return t instanceof HTMLImageElement || t instanceof HTMLAreaElement ? ((l = t.alt) == null ? void 0 : l.trim()) ?? "" : t instanceof HTMLInputElement && t.type === "image" ? ((h = t.alt) == null ? void 0 : h.trim()) ?? "" : "";
|
|
183
183
|
}
|
|
184
|
-
const
|
|
184
|
+
const Se = /* @__PURE__ */ new Set([
|
|
185
185
|
"alert",
|
|
186
186
|
"alertdialog",
|
|
187
187
|
"application",
|
|
@@ -265,24 +265,36 @@ const Ae = /* @__PURE__ */ new Set([
|
|
|
265
265
|
"treegrid",
|
|
266
266
|
"treeitem"
|
|
267
267
|
]);
|
|
268
|
-
function
|
|
268
|
+
function ke(t) {
|
|
269
269
|
const a = t.trim().toLowerCase().replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "");
|
|
270
|
-
return
|
|
270
|
+
return Se.has(a);
|
|
271
271
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
function T(t) {
|
|
273
|
+
let a = t;
|
|
274
|
+
for (; a; ) {
|
|
275
|
+
if (a.getAttribute("aria-hidden") === "true" || a instanceof HTMLElement && a.hidden) return !0;
|
|
276
|
+
if (typeof getComputedStyle == "function") {
|
|
277
|
+
const e = getComputedStyle(a);
|
|
278
|
+
if (e.display === "none" || e.visibility === "hidden") return !0;
|
|
279
|
+
} else if (a instanceof HTMLElement && a.style.display === "none") return !0;
|
|
280
|
+
a = a.parentElement;
|
|
281
|
+
}
|
|
282
|
+
return !1;
|
|
275
283
|
}
|
|
276
|
-
|
|
277
|
-
|
|
284
|
+
let W = /* @__PURE__ */ new WeakMap();
|
|
285
|
+
function Ie() {
|
|
286
|
+
W = /* @__PURE__ */ new WeakMap();
|
|
287
|
+
}
|
|
288
|
+
function g(t) {
|
|
289
|
+
const a = W.get(t);
|
|
278
290
|
if (a !== void 0) return a;
|
|
279
291
|
let e;
|
|
280
|
-
return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e =
|
|
292
|
+
return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e = g(t.parentElement) : e = !1, W.set(t, e), e;
|
|
281
293
|
}
|
|
282
|
-
function
|
|
294
|
+
function Te(t) {
|
|
283
295
|
return !!(t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none"));
|
|
284
296
|
}
|
|
285
|
-
function
|
|
297
|
+
function A(t) {
|
|
286
298
|
var e, i, n, r, o;
|
|
287
299
|
let a = "";
|
|
288
300
|
for (const s of t.childNodes)
|
|
@@ -290,17 +302,17 @@ function w(t) {
|
|
|
290
302
|
a += s.textContent ?? "";
|
|
291
303
|
else if (s.nodeType === 1) {
|
|
292
304
|
const l = s;
|
|
293
|
-
if (!
|
|
305
|
+
if (!Te(l)) {
|
|
294
306
|
const h = (e = l.tagName) == null ? void 0 : e.toLowerCase();
|
|
295
307
|
if (h === "img" || h === "area") {
|
|
296
308
|
const c = l.getAttribute("aria-labelledby");
|
|
297
309
|
if (c) {
|
|
298
|
-
const
|
|
310
|
+
const u = c.split(/\s+/).map((p) => {
|
|
299
311
|
var b, f;
|
|
300
|
-
return ((f = (b = l.ownerDocument.getElementById(
|
|
312
|
+
return ((f = (b = l.ownerDocument.getElementById(p)) == null ? void 0 : b.textContent) == null ? void 0 : f.trim()) ?? "";
|
|
301
313
|
}).filter(Boolean);
|
|
302
|
-
if (
|
|
303
|
-
a +=
|
|
314
|
+
if (u.length) {
|
|
315
|
+
a += u.join(" ");
|
|
304
316
|
continue;
|
|
305
317
|
}
|
|
306
318
|
}
|
|
@@ -310,22 +322,22 @@ function w(t) {
|
|
|
310
322
|
if (c)
|
|
311
323
|
a += c;
|
|
312
324
|
else {
|
|
313
|
-
const
|
|
314
|
-
|
|
325
|
+
const u = l.querySelector("title");
|
|
326
|
+
u && (a += u.textContent ?? "");
|
|
315
327
|
}
|
|
316
|
-
} else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a +=
|
|
328
|
+
} else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a += A(l);
|
|
317
329
|
}
|
|
318
330
|
}
|
|
319
331
|
return a;
|
|
320
332
|
}
|
|
321
|
-
let
|
|
322
|
-
function
|
|
323
|
-
|
|
333
|
+
let _ = /* @__PURE__ */ new WeakMap();
|
|
334
|
+
function Ee() {
|
|
335
|
+
_ = /* @__PURE__ */ new WeakMap();
|
|
324
336
|
}
|
|
325
|
-
function
|
|
337
|
+
function Ce(t) {
|
|
326
338
|
return t.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
327
339
|
}
|
|
328
|
-
const
|
|
340
|
+
const Le = [
|
|
329
341
|
"data-testid",
|
|
330
342
|
"data-test-id",
|
|
331
343
|
"data-cy",
|
|
@@ -335,12 +347,12 @@ const Ee = [
|
|
|
335
347
|
"for",
|
|
336
348
|
"aria-label"
|
|
337
349
|
];
|
|
338
|
-
function
|
|
350
|
+
function qe(t) {
|
|
339
351
|
const a = t.tagName.toLowerCase();
|
|
340
|
-
for (const i of
|
|
352
|
+
for (const i of Le) {
|
|
341
353
|
const n = t.getAttribute(i);
|
|
342
354
|
if (n != null && n.length > 0 && n.length < 100)
|
|
343
|
-
return `${a}[${i}="${
|
|
355
|
+
return `${a}[${i}="${Ce(n)}"]`;
|
|
344
356
|
}
|
|
345
357
|
const e = t.parentElement;
|
|
346
358
|
if (e) {
|
|
@@ -352,7 +364,7 @@ function Ce(t) {
|
|
|
352
364
|
}
|
|
353
365
|
return a;
|
|
354
366
|
}
|
|
355
|
-
function
|
|
367
|
+
function H(t) {
|
|
356
368
|
if (t.id) return `#${CSS.escape(t.id)}`;
|
|
357
369
|
const a = t.getRootNode(), e = a instanceof ShadowRoot ? null : a.documentElement, i = [];
|
|
358
370
|
let n = t;
|
|
@@ -361,7 +373,7 @@ function M(t) {
|
|
|
361
373
|
i.unshift(`#${CSS.escape(n.id)}`);
|
|
362
374
|
break;
|
|
363
375
|
}
|
|
364
|
-
if (i.unshift(
|
|
376
|
+
if (i.unshift(qe(n)), i.length >= 2) {
|
|
365
377
|
const r = i.join(" > ");
|
|
366
378
|
try {
|
|
367
379
|
const o = a.querySelectorAll(r);
|
|
@@ -375,28 +387,28 @@ function M(t) {
|
|
|
375
387
|
}
|
|
376
388
|
function m(t) {
|
|
377
389
|
var r;
|
|
378
|
-
const a =
|
|
390
|
+
const a = _.get(t);
|
|
379
391
|
if (a !== void 0) return a;
|
|
380
392
|
const e = [];
|
|
381
393
|
let i = t;
|
|
382
394
|
for (; i; ) {
|
|
383
395
|
const o = i.getRootNode();
|
|
384
396
|
if (o instanceof ShadowRoot)
|
|
385
|
-
e.unshift({ selector:
|
|
397
|
+
e.unshift({ selector: H(i), delimiter: " >>> " }), i = o.host;
|
|
386
398
|
else {
|
|
387
399
|
const s = (r = o.defaultView) == null ? void 0 : r.frameElement;
|
|
388
400
|
if (s)
|
|
389
|
-
e.unshift({ selector:
|
|
401
|
+
e.unshift({ selector: H(i), delimiter: " >>>iframe> " }), i = s;
|
|
390
402
|
else {
|
|
391
|
-
e.unshift({ selector:
|
|
403
|
+
e.unshift({ selector: H(i), delimiter: "" });
|
|
392
404
|
break;
|
|
393
405
|
}
|
|
394
406
|
}
|
|
395
407
|
}
|
|
396
408
|
const n = e.map((o, s) => (s === 0 ? "" : o.delimiter) + o.selector).join("");
|
|
397
|
-
return
|
|
409
|
+
return _.set(t, n), n;
|
|
398
410
|
}
|
|
399
|
-
function
|
|
411
|
+
function Ti(t) {
|
|
400
412
|
const a = [], e = [];
|
|
401
413
|
let i = t;
|
|
402
414
|
for (; i; ) {
|
|
@@ -429,11 +441,11 @@ function wi(t) {
|
|
|
429
441
|
}
|
|
430
442
|
return null;
|
|
431
443
|
}
|
|
432
|
-
function
|
|
444
|
+
function d(t) {
|
|
433
445
|
const a = t.outerHTML;
|
|
434
446
|
return a.length > 200 ? a.slice(0, 200) + "..." : a;
|
|
435
447
|
}
|
|
436
|
-
const
|
|
448
|
+
const Re = /* @__PURE__ */ new Set([
|
|
437
449
|
"aria-activedescendant",
|
|
438
450
|
"aria-atomic",
|
|
439
451
|
"aria-autocomplete",
|
|
@@ -487,7 +499,7 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
487
499
|
"aria-valuemin",
|
|
488
500
|
"aria-valuenow",
|
|
489
501
|
"aria-valuetext"
|
|
490
|
-
]),
|
|
502
|
+
]), Y = /* @__PURE__ */ new Set([
|
|
491
503
|
"aria-atomic",
|
|
492
504
|
"aria-busy",
|
|
493
505
|
"aria-disabled",
|
|
@@ -498,7 +510,7 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
498
510
|
"aria-multiselectable",
|
|
499
511
|
"aria-readonly",
|
|
500
512
|
"aria-required"
|
|
501
|
-
]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]),
|
|
513
|
+
]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]), Ne = /* @__PURE__ */ new Set([
|
|
502
514
|
"aria-colcount",
|
|
503
515
|
"aria-colindex",
|
|
504
516
|
"aria-colspan",
|
|
@@ -508,11 +520,11 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
508
520
|
"aria-rowindex",
|
|
509
521
|
"aria-rowspan",
|
|
510
522
|
"aria-setsize"
|
|
511
|
-
]),
|
|
523
|
+
]), $e = /* @__PURE__ */ new Set([
|
|
512
524
|
"aria-valuemax",
|
|
513
525
|
"aria-valuemin",
|
|
514
526
|
"aria-valuenow"
|
|
515
|
-
]),
|
|
527
|
+
]), K = {
|
|
516
528
|
"aria-autocomplete": /* @__PURE__ */ new Set(["inline", "list", "both", "none"]),
|
|
517
529
|
"aria-expanded": /* @__PURE__ */ new Set(["true", "false", "undefined"]),
|
|
518
530
|
"aria-current": /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"]),
|
|
@@ -523,7 +535,7 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
523
535
|
"aria-orientation": /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]),
|
|
524
536
|
"aria-relevant": /* @__PURE__ */ new Set(["additions", "all", "removals", "text"]),
|
|
525
537
|
"aria-sort": /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"])
|
|
526
|
-
},
|
|
538
|
+
}, J = /* @__PURE__ */ new Set([
|
|
527
539
|
"caption",
|
|
528
540
|
"code",
|
|
529
541
|
"deletion",
|
|
@@ -540,7 +552,7 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
540
552
|
"suggestion",
|
|
541
553
|
"term",
|
|
542
554
|
"time"
|
|
543
|
-
]),
|
|
555
|
+
]), Me = {
|
|
544
556
|
abbr: !0,
|
|
545
557
|
bdi: !0,
|
|
546
558
|
bdo: !0,
|
|
@@ -568,7 +580,7 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
568
580
|
u: !0,
|
|
569
581
|
var: !0,
|
|
570
582
|
wbr: !0
|
|
571
|
-
},
|
|
583
|
+
}, He = {
|
|
572
584
|
alert: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
|
|
573
585
|
article: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
|
|
574
586
|
banner: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
|
|
@@ -601,13 +613,13 @@ const Le = /* @__PURE__ */ new Set([
|
|
|
601
613
|
time: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
|
|
602
614
|
tooltip: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"])
|
|
603
615
|
};
|
|
604
|
-
let
|
|
605
|
-
function
|
|
606
|
-
|
|
616
|
+
let C = null, L = null;
|
|
617
|
+
function De() {
|
|
618
|
+
C = null, L = null;
|
|
607
619
|
}
|
|
608
|
-
function
|
|
620
|
+
function U(t) {
|
|
609
621
|
var n;
|
|
610
|
-
if (
|
|
622
|
+
if (L && (C == null ? void 0 : C.deref()) === t) return L;
|
|
611
623
|
const a = [], e = [], i = [];
|
|
612
624
|
for (const r of t.querySelectorAll("*")) {
|
|
613
625
|
let o = !1;
|
|
@@ -618,14 +630,14 @@ function z(t) {
|
|
|
618
630
|
}
|
|
619
631
|
if (!o) continue;
|
|
620
632
|
let s, l;
|
|
621
|
-
const h = () => (s === void 0 && (s = m(r), l =
|
|
633
|
+
const h = () => (s === void 0 && (s = m(r), l = d(r)), { selector: s, html: l });
|
|
622
634
|
for (const c of r.attributes)
|
|
623
|
-
if (c.name.startsWith("aria-") && !
|
|
624
|
-
const
|
|
635
|
+
if (c.name.startsWith("aria-") && !Re.has(c.name)) {
|
|
636
|
+
const u = h();
|
|
625
637
|
a.push({
|
|
626
638
|
ruleId: "aria-valid-attr",
|
|
627
|
-
selector:
|
|
628
|
-
html:
|
|
639
|
+
selector: u.selector,
|
|
640
|
+
html: u.html,
|
|
629
641
|
impact: "critical",
|
|
630
642
|
message: `Invalid ARIA attribute "${c.name}".`
|
|
631
643
|
});
|
|
@@ -633,85 +645,85 @@ function z(t) {
|
|
|
633
645
|
}
|
|
634
646
|
for (const c of r.attributes) {
|
|
635
647
|
if (!c.name.startsWith("aria-")) continue;
|
|
636
|
-
const
|
|
637
|
-
if (!(
|
|
638
|
-
if (
|
|
639
|
-
if (
|
|
640
|
-
const
|
|
648
|
+
const u = c.value.trim();
|
|
649
|
+
if (!(u === "" && !Y.has(c.name) && !X.has(c.name))) {
|
|
650
|
+
if (Y.has(c.name)) {
|
|
651
|
+
if (u !== "true" && u !== "false") {
|
|
652
|
+
const p = h();
|
|
641
653
|
e.push({
|
|
642
654
|
ruleId: "aria-valid-attr-value",
|
|
643
|
-
selector:
|
|
644
|
-
html:
|
|
655
|
+
selector: p.selector,
|
|
656
|
+
html: p.html,
|
|
645
657
|
impact: "critical",
|
|
646
|
-
message: `${c.name} must be "true" or "false", got "${
|
|
658
|
+
message: `${c.name} must be "true" or "false", got "${u}".`
|
|
647
659
|
});
|
|
648
660
|
}
|
|
649
661
|
} else if (X.has(c.name)) {
|
|
650
|
-
if (
|
|
651
|
-
const
|
|
662
|
+
if (u !== "true" && u !== "false" && u !== "mixed") {
|
|
663
|
+
const p = h();
|
|
652
664
|
e.push({
|
|
653
665
|
ruleId: "aria-valid-attr-value",
|
|
654
|
-
selector:
|
|
655
|
-
html:
|
|
666
|
+
selector: p.selector,
|
|
667
|
+
html: p.html,
|
|
656
668
|
impact: "critical",
|
|
657
|
-
message: `${c.name} must be "true", "false", or "mixed", got "${
|
|
669
|
+
message: `${c.name} must be "true", "false", or "mixed", got "${u}".`
|
|
658
670
|
});
|
|
659
671
|
}
|
|
660
|
-
} else if (
|
|
661
|
-
if (
|
|
662
|
-
const
|
|
672
|
+
} else if (Ne.has(c.name)) {
|
|
673
|
+
if (u === "" || !/^-?\d+$/.test(u)) {
|
|
674
|
+
const p = h();
|
|
663
675
|
e.push({
|
|
664
676
|
ruleId: "aria-valid-attr-value",
|
|
665
|
-
selector:
|
|
666
|
-
html:
|
|
677
|
+
selector: p.selector,
|
|
678
|
+
html: p.html,
|
|
667
679
|
impact: "critical",
|
|
668
|
-
message: `${c.name} must be an integer, got "${
|
|
680
|
+
message: `${c.name} must be an integer, got "${u}".`
|
|
669
681
|
});
|
|
670
682
|
}
|
|
671
|
-
} else if (
|
|
672
|
-
if (
|
|
673
|
-
const
|
|
683
|
+
} else if ($e.has(c.name)) {
|
|
684
|
+
if (u === "" || isNaN(Number(u))) {
|
|
685
|
+
const p = h();
|
|
674
686
|
e.push({
|
|
675
687
|
ruleId: "aria-valid-attr-value",
|
|
676
|
-
selector:
|
|
677
|
-
html:
|
|
688
|
+
selector: p.selector,
|
|
689
|
+
html: p.html,
|
|
678
690
|
impact: "critical",
|
|
679
|
-
message: `${c.name} must be a number, got "${
|
|
691
|
+
message: `${c.name} must be a number, got "${u}".`
|
|
680
692
|
});
|
|
681
693
|
}
|
|
682
|
-
} else if (
|
|
683
|
-
const
|
|
684
|
-
for (const b of
|
|
685
|
-
if (!
|
|
694
|
+
} else if (K[c.name]) {
|
|
695
|
+
const p = u.split(/\s+/);
|
|
696
|
+
for (const b of p)
|
|
697
|
+
if (!K[c.name].has(b)) {
|
|
686
698
|
const f = h();
|
|
687
699
|
e.push({
|
|
688
700
|
ruleId: "aria-valid-attr-value",
|
|
689
701
|
selector: f.selector,
|
|
690
702
|
html: f.html,
|
|
691
703
|
impact: "critical",
|
|
692
|
-
message: `Invalid value "${
|
|
704
|
+
message: `Invalid value "${u}" for ${c.name}.`
|
|
693
705
|
});
|
|
694
706
|
break;
|
|
695
707
|
}
|
|
696
708
|
}
|
|
697
709
|
}
|
|
698
710
|
}
|
|
699
|
-
if (!
|
|
700
|
-
const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(),
|
|
701
|
-
if (!c &&
|
|
702
|
-
const
|
|
703
|
-
if (
|
|
711
|
+
if (!g(r)) {
|
|
712
|
+
const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(), u = r.tagName.toLowerCase();
|
|
713
|
+
if (!c && Me[u]) {
|
|
714
|
+
const p = r.hasAttribute("aria-label"), b = r.hasAttribute("aria-labelledby");
|
|
715
|
+
if (p || b) {
|
|
704
716
|
const f = h();
|
|
705
717
|
i.push({
|
|
706
718
|
ruleId: "aria-prohibited-attr",
|
|
707
719
|
selector: f.selector,
|
|
708
720
|
html: f.html,
|
|
709
721
|
impact: "serious",
|
|
710
|
-
message: `aria-label and aria-labelledby are prohibited on <${
|
|
722
|
+
message: `aria-label and aria-labelledby are prohibited on <${u}> elements.`
|
|
711
723
|
});
|
|
712
724
|
}
|
|
713
725
|
} else if (c) {
|
|
714
|
-
if (
|
|
726
|
+
if (J.has(c)) {
|
|
715
727
|
const b = r.hasAttribute("aria-label"), f = r.hasAttribute("aria-labelledby");
|
|
716
728
|
if (b || f) {
|
|
717
729
|
const y = h();
|
|
@@ -724,11 +736,11 @@ function z(t) {
|
|
|
724
736
|
});
|
|
725
737
|
}
|
|
726
738
|
}
|
|
727
|
-
const
|
|
728
|
-
if (
|
|
739
|
+
const p = He[c];
|
|
740
|
+
if (p) {
|
|
729
741
|
for (const b of r.attributes)
|
|
730
|
-
if (b.name.startsWith("aria-") &&
|
|
731
|
-
if ((b.name === "aria-label" || b.name === "aria-labelledby") &&
|
|
742
|
+
if (b.name.startsWith("aria-") && p.has(b.name)) {
|
|
743
|
+
if ((b.name === "aria-label" || b.name === "aria-labelledby") && J.has(c))
|
|
732
744
|
continue;
|
|
733
745
|
const f = h();
|
|
734
746
|
i.push({
|
|
@@ -743,28 +755,28 @@ function z(t) {
|
|
|
743
755
|
}
|
|
744
756
|
}
|
|
745
757
|
}
|
|
746
|
-
return
|
|
758
|
+
return C = new WeakRef(t), L = { validAttr: a, validAttrValue: e, prohibitedAttr: i }, L;
|
|
747
759
|
}
|
|
748
|
-
let
|
|
749
|
-
function
|
|
750
|
-
|
|
760
|
+
let P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
|
|
761
|
+
function Oe() {
|
|
762
|
+
P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
|
|
751
763
|
}
|
|
752
|
-
function
|
|
753
|
-
let a =
|
|
754
|
-
return a || (a = getComputedStyle(t),
|
|
764
|
+
function w(t) {
|
|
765
|
+
let a = P.get(t);
|
|
766
|
+
return a || (a = getComputedStyle(t), P.set(t, a), a);
|
|
755
767
|
}
|
|
756
|
-
function
|
|
768
|
+
function R(t, a, e) {
|
|
757
769
|
const [i, n, r] = [t, a, e].map((o) => {
|
|
758
770
|
const s = o / 255;
|
|
759
771
|
return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
|
|
760
772
|
});
|
|
761
773
|
return 0.2126 * i + 0.7152 * n + 0.0722 * r;
|
|
762
774
|
}
|
|
763
|
-
function
|
|
775
|
+
function me(t, a) {
|
|
764
776
|
const e = Math.max(t, a), i = Math.min(t, a);
|
|
765
777
|
return (e + 0.05) / (i + 0.05);
|
|
766
778
|
}
|
|
767
|
-
const
|
|
779
|
+
const Q = {
|
|
768
780
|
black: [0, 0, 0],
|
|
769
781
|
white: [255, 255, 255],
|
|
770
782
|
red: [255, 0, 0],
|
|
@@ -784,9 +796,9 @@ const J = {
|
|
|
784
796
|
lime: [0, 255, 0],
|
|
785
797
|
olive: [128, 128, 0]
|
|
786
798
|
};
|
|
787
|
-
function
|
|
799
|
+
function N(t) {
|
|
788
800
|
const a = t.trim().toLowerCase();
|
|
789
|
-
if (
|
|
801
|
+
if (Q[a]) return Q[a];
|
|
790
802
|
const e = a.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);
|
|
791
803
|
if (e)
|
|
792
804
|
return [parseInt(e[1] + e[1], 16), parseInt(e[2] + e[2], 16), parseInt(e[3] + e[3], 16)];
|
|
@@ -803,16 +815,16 @@ function R(t) {
|
|
|
803
815
|
);
|
|
804
816
|
return r ? [parseInt(r[1]), parseInt(r[2]), parseInt(r[3])] : null;
|
|
805
817
|
}
|
|
806
|
-
function
|
|
807
|
-
const a =
|
|
818
|
+
function Be(t) {
|
|
819
|
+
const a = j.get(t);
|
|
808
820
|
if (a !== void 0) return a;
|
|
809
|
-
const e =
|
|
810
|
-
return
|
|
821
|
+
const e = Fe(t);
|
|
822
|
+
return j.set(t, e), e;
|
|
811
823
|
}
|
|
812
|
-
function
|
|
824
|
+
function Fe(t) {
|
|
813
825
|
let a = t;
|
|
814
826
|
for (; a; ) {
|
|
815
|
-
const e =
|
|
827
|
+
const e = w(a), i = e.backgroundImage;
|
|
816
828
|
if (i && i !== "none" && i !== "initial") return null;
|
|
817
829
|
const n = e.backgroundColor;
|
|
818
830
|
if (n === "transparent" || n === "rgba(0, 0, 0, 0)" || n === "rgba(0 0 0 / 0)") {
|
|
@@ -824,26 +836,26 @@ function Oe(t) {
|
|
|
824
836
|
a = a.parentElement;
|
|
825
837
|
continue;
|
|
826
838
|
}
|
|
827
|
-
return
|
|
839
|
+
return N(n);
|
|
828
840
|
}
|
|
829
841
|
return [255, 255, 255];
|
|
830
842
|
}
|
|
831
|
-
const
|
|
832
|
-
function
|
|
833
|
-
const a =
|
|
843
|
+
const We = /* @__PURE__ */ new Set(["IMG", "PICTURE", "VIDEO", "SVG"]);
|
|
844
|
+
function _e(t) {
|
|
845
|
+
const a = V.get(t);
|
|
834
846
|
if (a !== void 0) return a;
|
|
835
|
-
const e =
|
|
836
|
-
return
|
|
847
|
+
const e = Pe(t);
|
|
848
|
+
return V.set(t, e), e;
|
|
837
849
|
}
|
|
838
|
-
function
|
|
850
|
+
function Pe(t) {
|
|
839
851
|
let a = t, e = !1;
|
|
840
852
|
for (; a; ) {
|
|
841
|
-
const i =
|
|
853
|
+
const i = w(a).position;
|
|
842
854
|
if ((i === "absolute" || i === "fixed") && (e = !0), a !== t && i !== "static") {
|
|
843
855
|
for (const n of a.children)
|
|
844
|
-
if (!(n === t || n.contains(t)) &&
|
|
856
|
+
if (!(n === t || n.contains(t)) && We.has(n.tagName)) {
|
|
845
857
|
if (e) return !0;
|
|
846
|
-
const r =
|
|
858
|
+
const r = w(n).position;
|
|
847
859
|
if (r === "absolute" || r === "fixed") return !0;
|
|
848
860
|
}
|
|
849
861
|
if (e) break;
|
|
@@ -852,15 +864,15 @@ function We(t) {
|
|
|
852
864
|
}
|
|
853
865
|
return !1;
|
|
854
866
|
}
|
|
855
|
-
function
|
|
867
|
+
function je(t) {
|
|
856
868
|
const a = parseFloat(t);
|
|
857
869
|
return t.endsWith("pt") ? a * (4 / 3) : a;
|
|
858
870
|
}
|
|
859
|
-
function
|
|
860
|
-
const a =
|
|
871
|
+
function Ve(t) {
|
|
872
|
+
const a = w(t), e = je(a.fontSize), i = parseInt(a.fontWeight) || (a.fontWeight === "bold" ? 700 : 400);
|
|
861
873
|
return e >= 23.5 || e >= 18.5 && i >= 700;
|
|
862
874
|
}
|
|
863
|
-
function
|
|
875
|
+
function D(t) {
|
|
864
876
|
var r, o;
|
|
865
877
|
const a = [], e = t.closest("a");
|
|
866
878
|
if (e) {
|
|
@@ -880,7 +892,7 @@ function H(t) {
|
|
|
880
892
|
return a.length > 0 ? a.join(`
|
|
881
893
|
`) : void 0;
|
|
882
894
|
}
|
|
883
|
-
function
|
|
895
|
+
function Z(t) {
|
|
884
896
|
let a = t;
|
|
885
897
|
for (; a; ) {
|
|
886
898
|
if (a instanceof HTMLElement && a.style.visibility === "hidden") return !0;
|
|
@@ -888,7 +900,7 @@ function Q(t) {
|
|
|
888
900
|
}
|
|
889
901
|
return !1;
|
|
890
902
|
}
|
|
891
|
-
const
|
|
903
|
+
const ze = {
|
|
892
904
|
id: "img-alt",
|
|
893
905
|
wcag: ["1.1.1"],
|
|
894
906
|
level: "A",
|
|
@@ -898,7 +910,7 @@ const je = {
|
|
|
898
910
|
run(t) {
|
|
899
911
|
const a = [];
|
|
900
912
|
for (const e of t.querySelectorAll("img")) {
|
|
901
|
-
if (
|
|
913
|
+
if (g(e) || Z(e)) continue;
|
|
902
914
|
const i = e.getAttribute("role");
|
|
903
915
|
if (i === "presentation" || i === "none") {
|
|
904
916
|
const r = e.getAttribute("tabindex");
|
|
@@ -909,41 +921,41 @@ const je = {
|
|
|
909
921
|
a.push({
|
|
910
922
|
ruleId: "img-alt",
|
|
911
923
|
selector: m(e),
|
|
912
|
-
html:
|
|
924
|
+
html: d(e),
|
|
913
925
|
impact: "critical",
|
|
914
926
|
message: 'Image has whitespace-only alt text. Use alt="" for decorative images or provide descriptive text.',
|
|
915
|
-
context:
|
|
927
|
+
context: D(e)
|
|
916
928
|
});
|
|
917
929
|
continue;
|
|
918
930
|
}
|
|
919
931
|
!e.hasAttribute("alt") && !v(e) && a.push({
|
|
920
932
|
ruleId: "img-alt",
|
|
921
933
|
selector: m(e),
|
|
922
|
-
html:
|
|
934
|
+
html: d(e),
|
|
923
935
|
impact: "critical",
|
|
924
936
|
message: "Image element missing alt attribute.",
|
|
925
|
-
context:
|
|
937
|
+
context: D(e)
|
|
926
938
|
});
|
|
927
939
|
}
|
|
928
940
|
for (const e of t.querySelectorAll('[role="img"]:not(img):not(svg)'))
|
|
929
|
-
|
|
941
|
+
g(e) || Z(e) || v(e) || a.push({
|
|
930
942
|
ruleId: "img-alt",
|
|
931
943
|
selector: m(e),
|
|
932
|
-
html:
|
|
944
|
+
html: d(e),
|
|
933
945
|
impact: "critical",
|
|
934
946
|
message: 'Element with role="img" has no accessible name. Add aria-label or aria-labelledby.',
|
|
935
|
-
context:
|
|
947
|
+
context: D(e)
|
|
936
948
|
});
|
|
937
949
|
return a;
|
|
938
950
|
}
|
|
939
951
|
};
|
|
940
|
-
function
|
|
952
|
+
function Ue(t) {
|
|
941
953
|
var r, o, s;
|
|
942
954
|
const a = t.getAttribute("aria-labelledby");
|
|
943
955
|
if (a) {
|
|
944
956
|
const l = a.split(/\s+/).map((h) => {
|
|
945
|
-
var c,
|
|
946
|
-
return ((
|
|
957
|
+
var c, u;
|
|
958
|
+
return ((u = (c = t.ownerDocument.getElementById(h)) == null ? void 0 : c.textContent) == null ? void 0 : u.trim()) ?? "";
|
|
947
959
|
}).filter(Boolean);
|
|
948
960
|
if (l.length) return l.join(" ");
|
|
949
961
|
}
|
|
@@ -954,7 +966,7 @@ function Ve(t) {
|
|
|
954
966
|
const n = (s = t.getAttribute("title")) == null ? void 0 : s.trim();
|
|
955
967
|
return n || "";
|
|
956
968
|
}
|
|
957
|
-
const
|
|
969
|
+
const Ge = {
|
|
958
970
|
id: "svg-img-alt",
|
|
959
971
|
wcag: ["1.1.1"],
|
|
960
972
|
level: "A",
|
|
@@ -964,13 +976,13 @@ const ze = {
|
|
|
964
976
|
run(t) {
|
|
965
977
|
const a = [], e = 'svg[role="img"], [role="graphics-document"], [role="graphics-symbol"]';
|
|
966
978
|
for (const i of t.querySelectorAll(e)) {
|
|
967
|
-
if (
|
|
968
|
-
if (!
|
|
979
|
+
if (g(i)) continue;
|
|
980
|
+
if (!Ue(i)) {
|
|
969
981
|
const r = i.getAttribute("role");
|
|
970
982
|
a.push({
|
|
971
983
|
ruleId: "svg-img-alt",
|
|
972
984
|
selector: m(i),
|
|
973
|
-
html:
|
|
985
|
+
html: d(i),
|
|
974
986
|
impact: "serious",
|
|
975
987
|
message: `${i.tagName.toLowerCase()} with role='${r}' has no accessible name.`
|
|
976
988
|
});
|
|
@@ -978,7 +990,7 @@ const ze = {
|
|
|
978
990
|
}
|
|
979
991
|
return a;
|
|
980
992
|
}
|
|
981
|
-
},
|
|
993
|
+
}, Ye = {
|
|
982
994
|
id: "input-image-alt",
|
|
983
995
|
wcag: ["1.1.1", "4.1.2"],
|
|
984
996
|
level: "A",
|
|
@@ -988,16 +1000,16 @@ const ze = {
|
|
|
988
1000
|
run(t) {
|
|
989
1001
|
const a = [];
|
|
990
1002
|
for (const e of t.querySelectorAll('input[type="image"]'))
|
|
991
|
-
|
|
1003
|
+
g(e) || v(e) || a.push({
|
|
992
1004
|
ruleId: "input-image-alt",
|
|
993
1005
|
selector: m(e),
|
|
994
|
-
html:
|
|
1006
|
+
html: d(e),
|
|
995
1007
|
impact: "critical",
|
|
996
1008
|
message: "Image input missing alt text."
|
|
997
1009
|
});
|
|
998
1010
|
return a;
|
|
999
1011
|
}
|
|
1000
|
-
},
|
|
1012
|
+
}, Xe = {
|
|
1001
1013
|
id: "image-redundant-alt",
|
|
1002
1014
|
wcag: [],
|
|
1003
1015
|
level: "A",
|
|
@@ -1019,7 +1031,7 @@ const ze = {
|
|
|
1019
1031
|
a.push({
|
|
1020
1032
|
ruleId: "image-redundant-alt",
|
|
1021
1033
|
selector: m(i),
|
|
1022
|
-
html:
|
|
1034
|
+
html: d(i),
|
|
1023
1035
|
impact: "minor",
|
|
1024
1036
|
message: `Alt text "${i.getAttribute("alt")}" duplicates surrounding ${s} text.`,
|
|
1025
1037
|
context: `Duplicated text: "${i.getAttribute("alt")}", parent element: <${s}>${l ? ` href="${l}"` : ""}`
|
|
@@ -1029,7 +1041,7 @@ const ze = {
|
|
|
1029
1041
|
}
|
|
1030
1042
|
return a;
|
|
1031
1043
|
}
|
|
1032
|
-
},
|
|
1044
|
+
}, Ke = ["image", "picture", "photo", "graphic", "icon", "img"], Je = {
|
|
1033
1045
|
id: "image-alt-redundant-words",
|
|
1034
1046
|
wcag: [],
|
|
1035
1047
|
level: "A",
|
|
@@ -1042,11 +1054,11 @@ const ze = {
|
|
|
1042
1054
|
for (const e of t.querySelectorAll("img[alt]")) {
|
|
1043
1055
|
const i = e.getAttribute("alt").toLowerCase();
|
|
1044
1056
|
if (!i) continue;
|
|
1045
|
-
const n =
|
|
1057
|
+
const n = Ke.filter((r) => i.split(/\s+/).includes(r));
|
|
1046
1058
|
n.length > 0 && a.push({
|
|
1047
1059
|
ruleId: "image-alt-redundant-words",
|
|
1048
1060
|
selector: m(e),
|
|
1049
|
-
html:
|
|
1061
|
+
html: d(e),
|
|
1050
1062
|
impact: "minor",
|
|
1051
1063
|
message: `Alt text "${e.getAttribute("alt")}" contains redundant word(s): ${n.join(", ")}.`,
|
|
1052
1064
|
context: `Current alt: "${e.getAttribute("alt")}", redundant word(s): ${n.join(", ")}`
|
|
@@ -1054,7 +1066,7 @@ const ze = {
|
|
|
1054
1066
|
}
|
|
1055
1067
|
return a;
|
|
1056
1068
|
}
|
|
1057
|
-
},
|
|
1069
|
+
}, Qe = {
|
|
1058
1070
|
id: "area-alt",
|
|
1059
1071
|
wcag: ["1.1.1", "4.1.2"],
|
|
1060
1072
|
level: "A",
|
|
@@ -1064,11 +1076,11 @@ const ze = {
|
|
|
1064
1076
|
run(t) {
|
|
1065
1077
|
const a = [];
|
|
1066
1078
|
for (const e of t.querySelectorAll("area[href]")) {
|
|
1067
|
-
if (
|
|
1079
|
+
if (g(e)) continue;
|
|
1068
1080
|
v(e) || a.push({
|
|
1069
1081
|
ruleId: "area-alt",
|
|
1070
1082
|
selector: m(e),
|
|
1071
|
-
html:
|
|
1083
|
+
html: d(e),
|
|
1072
1084
|
impact: "critical",
|
|
1073
1085
|
message: "Image map <area> element is missing alternative text."
|
|
1074
1086
|
});
|
|
@@ -1076,7 +1088,7 @@ const ze = {
|
|
|
1076
1088
|
return a;
|
|
1077
1089
|
}
|
|
1078
1090
|
};
|
|
1079
|
-
function
|
|
1091
|
+
function Ze(t) {
|
|
1080
1092
|
var n, r;
|
|
1081
1093
|
const a = t.getAttribute("aria-labelledby");
|
|
1082
1094
|
if (a) {
|
|
@@ -1091,7 +1103,7 @@ function Je(t) {
|
|
|
1091
1103
|
const i = (r = t.getAttribute("title")) == null ? void 0 : r.trim();
|
|
1092
1104
|
return i || "";
|
|
1093
1105
|
}
|
|
1094
|
-
const
|
|
1106
|
+
const et = {
|
|
1095
1107
|
id: "object-alt",
|
|
1096
1108
|
wcag: ["1.1.1"],
|
|
1097
1109
|
level: "A",
|
|
@@ -1102,7 +1114,7 @@ const Qe = {
|
|
|
1102
1114
|
var e;
|
|
1103
1115
|
const a = [];
|
|
1104
1116
|
for (const i of t.querySelectorAll("object")) {
|
|
1105
|
-
if (
|
|
1117
|
+
if (g(i) || i instanceof HTMLElement && i.style.visibility === "hidden") continue;
|
|
1106
1118
|
let n = i.parentElement, r = !1;
|
|
1107
1119
|
for (; n; ) {
|
|
1108
1120
|
if (n instanceof HTMLElement && n.style.visibility === "hidden") {
|
|
@@ -1111,7 +1123,7 @@ const Qe = {
|
|
|
1111
1123
|
}
|
|
1112
1124
|
n = n.parentElement;
|
|
1113
1125
|
}
|
|
1114
|
-
if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" ||
|
|
1126
|
+
if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" || Ze(i)) continue;
|
|
1115
1127
|
const o = i.getAttribute("data") || "";
|
|
1116
1128
|
if (!((i.getAttribute("type") || "").startsWith("image/") || /\.(png|jpg|jpeg|gif|svg|webp|bmp|ico)$/i.test(o))) {
|
|
1117
1129
|
const h = i.querySelector("img[alt]");
|
|
@@ -1120,14 +1132,14 @@ const Qe = {
|
|
|
1120
1132
|
a.push({
|
|
1121
1133
|
ruleId: "object-alt",
|
|
1122
1134
|
selector: m(i),
|
|
1123
|
-
html:
|
|
1135
|
+
html: d(i),
|
|
1124
1136
|
impact: "serious",
|
|
1125
1137
|
message: "<object> element is missing alternative text. Add aria-label, aria-labelledby, or a title attribute."
|
|
1126
1138
|
});
|
|
1127
1139
|
}
|
|
1128
1140
|
return a;
|
|
1129
1141
|
}
|
|
1130
|
-
},
|
|
1142
|
+
}, tt = {
|
|
1131
1143
|
id: "role-img-alt",
|
|
1132
1144
|
wcag: ["1.1.1"],
|
|
1133
1145
|
level: "A",
|
|
@@ -1137,11 +1149,11 @@ const Qe = {
|
|
|
1137
1149
|
run(t) {
|
|
1138
1150
|
const a = [];
|
|
1139
1151
|
for (const e of t.querySelectorAll('[role="img"]')) {
|
|
1140
|
-
if (
|
|
1152
|
+
if (g(e) || e.tagName.toLowerCase() === "svg" || e.tagName.toLowerCase() === "img") continue;
|
|
1141
1153
|
v(e) || a.push({
|
|
1142
1154
|
ruleId: "role-img-alt",
|
|
1143
1155
|
selector: m(e),
|
|
1144
|
-
html:
|
|
1156
|
+
html: d(e),
|
|
1145
1157
|
impact: "serious",
|
|
1146
1158
|
message: "Element with role='img' has no accessible name. Add aria-label or aria-labelledby."
|
|
1147
1159
|
});
|
|
@@ -1149,7 +1161,7 @@ const Qe = {
|
|
|
1149
1161
|
return a;
|
|
1150
1162
|
}
|
|
1151
1163
|
};
|
|
1152
|
-
function
|
|
1164
|
+
function Ei(t) {
|
|
1153
1165
|
if (typeof t != "object" || t === null)
|
|
1154
1166
|
return "Rule spec must be an object";
|
|
1155
1167
|
const a = t;
|
|
@@ -1179,10 +1191,10 @@ function Ai(t) {
|
|
|
1179
1191
|
return "Rule must have a wcag array";
|
|
1180
1192
|
if (typeof a.level != "string" || !["A", "AA"].includes(a.level))
|
|
1181
1193
|
return "Rule must have level A or AA";
|
|
1182
|
-
const n =
|
|
1194
|
+
const n = at(e);
|
|
1183
1195
|
return n || null;
|
|
1184
1196
|
}
|
|
1185
|
-
function
|
|
1197
|
+
function at(t) {
|
|
1186
1198
|
switch (t.type) {
|
|
1187
1199
|
case "selector-exists":
|
|
1188
1200
|
return null;
|
|
@@ -1219,112 +1231,118 @@ function k(t) {
|
|
|
1219
1231
|
guidance: t.guidance,
|
|
1220
1232
|
prompt: t.prompt,
|
|
1221
1233
|
run(e) {
|
|
1234
|
+
var n, r;
|
|
1222
1235
|
const i = [];
|
|
1223
1236
|
switch (t.check.type) {
|
|
1224
1237
|
case "selector-exists": {
|
|
1225
|
-
for (const
|
|
1226
|
-
a &&
|
|
1238
|
+
for (const o of e.querySelectorAll(t.selector))
|
|
1239
|
+
a && g(o) || i.push({
|
|
1227
1240
|
ruleId: t.id,
|
|
1228
|
-
selector: m(
|
|
1229
|
-
html:
|
|
1241
|
+
selector: m(o),
|
|
1242
|
+
html: d(o),
|
|
1230
1243
|
impact: t.impact,
|
|
1231
|
-
message: S(t.message,
|
|
1232
|
-
element:
|
|
1244
|
+
message: S(t.message, o, t.check),
|
|
1245
|
+
element: o
|
|
1233
1246
|
});
|
|
1234
1247
|
break;
|
|
1235
1248
|
}
|
|
1236
1249
|
case "attribute-value": {
|
|
1237
|
-
const { attribute:
|
|
1238
|
-
for (const
|
|
1239
|
-
if (a &&
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1250
|
+
const { attribute: o, operator: s, value: l } = t.check;
|
|
1251
|
+
for (const h of e.querySelectorAll(t.selector)) {
|
|
1252
|
+
if (a && g(h)) continue;
|
|
1253
|
+
const c = h.getAttribute(o);
|
|
1254
|
+
c !== null && it(c, s, l) && i.push({
|
|
1242
1255
|
ruleId: t.id,
|
|
1243
|
-
selector: m(
|
|
1244
|
-
html:
|
|
1256
|
+
selector: m(h),
|
|
1257
|
+
html: d(h),
|
|
1245
1258
|
impact: t.impact,
|
|
1246
|
-
message: S(t.message,
|
|
1247
|
-
element:
|
|
1259
|
+
message: S(t.message, h, t.check),
|
|
1260
|
+
element: h
|
|
1248
1261
|
});
|
|
1249
1262
|
}
|
|
1250
1263
|
break;
|
|
1251
1264
|
}
|
|
1252
1265
|
case "attribute-missing": {
|
|
1253
|
-
const { attribute:
|
|
1254
|
-
for (const
|
|
1255
|
-
a &&
|
|
1266
|
+
const { attribute: o } = t.check;
|
|
1267
|
+
for (const s of e.querySelectorAll(t.selector))
|
|
1268
|
+
a && g(s) || s.hasAttribute(o) || i.push({
|
|
1256
1269
|
ruleId: t.id,
|
|
1257
|
-
selector: m(
|
|
1258
|
-
html:
|
|
1270
|
+
selector: m(s),
|
|
1271
|
+
html: d(s),
|
|
1259
1272
|
impact: t.impact,
|
|
1260
|
-
message: S(t.message,
|
|
1261
|
-
element:
|
|
1273
|
+
message: S(t.message, s, t.check),
|
|
1274
|
+
element: s
|
|
1262
1275
|
});
|
|
1263
1276
|
break;
|
|
1264
1277
|
}
|
|
1265
1278
|
case "attribute-regex": {
|
|
1266
|
-
const { attribute:
|
|
1267
|
-
let
|
|
1279
|
+
const { attribute: o, pattern: s, flags: l, shouldMatch: h } = t.check;
|
|
1280
|
+
let c;
|
|
1268
1281
|
try {
|
|
1269
|
-
|
|
1282
|
+
c = new RegExp(s, l);
|
|
1270
1283
|
} catch {
|
|
1271
1284
|
break;
|
|
1272
1285
|
}
|
|
1273
|
-
for (const
|
|
1274
|
-
if (a &&
|
|
1275
|
-
const
|
|
1276
|
-
if (
|
|
1277
|
-
const
|
|
1278
|
-
|
|
1286
|
+
for (const u of e.querySelectorAll(t.selector)) {
|
|
1287
|
+
if (a && g(u)) continue;
|
|
1288
|
+
const p = u.getAttribute(o);
|
|
1289
|
+
if (p === null) continue;
|
|
1290
|
+
const b = c.test(p);
|
|
1291
|
+
h && !b ? i.push({
|
|
1279
1292
|
ruleId: t.id,
|
|
1280
|
-
selector: m(
|
|
1281
|
-
html: u
|
|
1293
|
+
selector: m(u),
|
|
1294
|
+
html: d(u),
|
|
1282
1295
|
impact: t.impact,
|
|
1283
|
-
message: S(t.message,
|
|
1284
|
-
element:
|
|
1285
|
-
}) : !
|
|
1296
|
+
message: S(t.message, u, t.check),
|
|
1297
|
+
element: u
|
|
1298
|
+
}) : !h && b && i.push({
|
|
1286
1299
|
ruleId: t.id,
|
|
1287
|
-
selector: m(
|
|
1288
|
-
html: u
|
|
1300
|
+
selector: m(u),
|
|
1301
|
+
html: d(u),
|
|
1289
1302
|
impact: t.impact,
|
|
1290
|
-
message: S(t.message,
|
|
1291
|
-
element:
|
|
1303
|
+
message: S(t.message, u, t.check),
|
|
1304
|
+
element: u
|
|
1292
1305
|
});
|
|
1293
1306
|
}
|
|
1294
1307
|
break;
|
|
1295
1308
|
}
|
|
1296
1309
|
case "child-required": {
|
|
1297
|
-
const { childSelector:
|
|
1298
|
-
for (const
|
|
1299
|
-
a &&
|
|
1310
|
+
const { childSelector: o } = t.check;
|
|
1311
|
+
for (const s of e.querySelectorAll(t.selector))
|
|
1312
|
+
a && g(s) || s.querySelector(o) || i.push({
|
|
1300
1313
|
ruleId: t.id,
|
|
1301
|
-
selector: m(
|
|
1302
|
-
html:
|
|
1314
|
+
selector: m(s),
|
|
1315
|
+
html: d(s),
|
|
1303
1316
|
impact: t.impact,
|
|
1304
|
-
message: S(t.message,
|
|
1305
|
-
element:
|
|
1317
|
+
message: S(t.message, s, t.check),
|
|
1318
|
+
element: s
|
|
1306
1319
|
});
|
|
1307
1320
|
break;
|
|
1308
1321
|
}
|
|
1309
1322
|
case "child-invalid": {
|
|
1310
|
-
const
|
|
1311
|
-
t.check.allowedChildren.map((
|
|
1312
|
-
);
|
|
1313
|
-
for (const
|
|
1314
|
-
if (
|
|
1315
|
-
|
|
1316
|
-
|
|
1323
|
+
const o = new Set(
|
|
1324
|
+
t.check.allowedChildren.map((l) => l.toLowerCase())
|
|
1325
|
+
), s = t.check.allowedChildRoles ? new Set(t.check.allowedChildRoles.map((l) => l.toLowerCase())) : null;
|
|
1326
|
+
for (const l of e.querySelectorAll(t.selector)) {
|
|
1327
|
+
if (a && g(l)) continue;
|
|
1328
|
+
const h = (n = l.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
|
|
1329
|
+
if (!(h === "presentation" || h === "none"))
|
|
1330
|
+
for (const c of l.children) {
|
|
1331
|
+
if (o.has(c.tagName.toLowerCase())) continue;
|
|
1332
|
+
const u = (r = c.getAttribute("role")) == null ? void 0 : r.trim().toLowerCase();
|
|
1333
|
+
if (!(u && (s != null && s.has(u))) && !(u === "presentation" || u === "none")) {
|
|
1317
1334
|
i.push({
|
|
1318
1335
|
ruleId: t.id,
|
|
1319
|
-
selector: m(
|
|
1320
|
-
html:
|
|
1336
|
+
selector: m(c),
|
|
1337
|
+
html: d(c),
|
|
1321
1338
|
impact: t.impact,
|
|
1322
|
-
message: S(t.message,
|
|
1323
|
-
element:
|
|
1339
|
+
message: S(t.message, c, t.check),
|
|
1340
|
+
element: c
|
|
1324
1341
|
});
|
|
1325
1342
|
break;
|
|
1326
1343
|
}
|
|
1327
|
-
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1328
1346
|
break;
|
|
1329
1347
|
}
|
|
1330
1348
|
}
|
|
@@ -1332,7 +1350,7 @@ function k(t) {
|
|
|
1332
1350
|
}
|
|
1333
1351
|
};
|
|
1334
1352
|
}
|
|
1335
|
-
function
|
|
1353
|
+
function it(t, a, e) {
|
|
1336
1354
|
switch (a) {
|
|
1337
1355
|
case ">":
|
|
1338
1356
|
return parseFloat(t) > e;
|
|
@@ -1350,7 +1368,7 @@ function tt(t, a, e) {
|
|
|
1350
1368
|
return !1;
|
|
1351
1369
|
}
|
|
1352
1370
|
}
|
|
1353
|
-
const
|
|
1371
|
+
const nt = {
|
|
1354
1372
|
id: "server-side-image-map",
|
|
1355
1373
|
selector: "img[ismap], input[type='image'][ismap]",
|
|
1356
1374
|
check: { type: "selector-exists" },
|
|
@@ -1361,7 +1379,7 @@ const at = {
|
|
|
1361
1379
|
level: "A",
|
|
1362
1380
|
guidance: "Server-side image maps (using ismap attribute) send click coordinates to the server, which is inaccessible to keyboard users and screen readers who can't precisely click specific regions. Replace with client-side image maps (<map> with <area> elements) that provide keyboard access and accessible names, or use linked images/buttons instead.",
|
|
1363
1381
|
prompt: "Explain that the ismap attribute should be removed and the functionality replaced with a client-side <map> element with <area> children, or separate linked images/buttons."
|
|
1364
|
-
},
|
|
1382
|
+
}, rt = k(nt), ot = [
|
|
1365
1383
|
'[role="checkbox"]',
|
|
1366
1384
|
'[role="combobox"]',
|
|
1367
1385
|
'[role="listbox"]',
|
|
@@ -1373,13 +1391,13 @@ const at = {
|
|
|
1373
1391
|
'[role="spinbutton"]',
|
|
1374
1392
|
'[role="switch"]',
|
|
1375
1393
|
'[role="textbox"]'
|
|
1376
|
-
].join(", "),
|
|
1394
|
+
].join(", "), st = /* @__PURE__ */ new Set([
|
|
1377
1395
|
"checkbox",
|
|
1378
1396
|
"menuitemcheckbox",
|
|
1379
1397
|
"menuitemradio",
|
|
1380
1398
|
"radio",
|
|
1381
1399
|
"switch"
|
|
1382
|
-
]),
|
|
1400
|
+
]), lt = /* @__PURE__ */ new Set([
|
|
1383
1401
|
"combobox",
|
|
1384
1402
|
"listbox",
|
|
1385
1403
|
"searchbox",
|
|
@@ -1387,16 +1405,16 @@ const at = {
|
|
|
1387
1405
|
"spinbutton",
|
|
1388
1406
|
"textbox"
|
|
1389
1407
|
]);
|
|
1390
|
-
function
|
|
1408
|
+
function ct(t) {
|
|
1391
1409
|
var o, s, l, h;
|
|
1392
1410
|
const a = (o = t.getAttribute("role")) == null ? void 0 : o.trim().toLowerCase();
|
|
1393
|
-
if (a &&
|
|
1411
|
+
if (a && st.has(a) || (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && !(a && lt.has(a)))
|
|
1394
1412
|
return v(t);
|
|
1395
1413
|
const i = t.getAttribute("aria-labelledby");
|
|
1396
1414
|
if (i) {
|
|
1397
|
-
const c = i.split(/\s+/).map((
|
|
1398
|
-
const
|
|
1399
|
-
return
|
|
1415
|
+
const c = i.split(/\s+/).map((u) => {
|
|
1416
|
+
const p = t.ownerDocument.getElementById(u);
|
|
1417
|
+
return p ? A(p).trim() : "";
|
|
1400
1418
|
}).filter(Boolean);
|
|
1401
1419
|
if (c.length) return c.join(" ");
|
|
1402
1420
|
}
|
|
@@ -1404,16 +1422,16 @@ function st(t) {
|
|
|
1404
1422
|
if (n) return n;
|
|
1405
1423
|
if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
|
|
1406
1424
|
if (t.id) {
|
|
1407
|
-
const
|
|
1408
|
-
if (
|
|
1409
|
-
const
|
|
1410
|
-
if (
|
|
1425
|
+
const u = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
|
|
1426
|
+
if (u) {
|
|
1427
|
+
const p = A(u).trim();
|
|
1428
|
+
if (p) return p;
|
|
1411
1429
|
}
|
|
1412
1430
|
}
|
|
1413
1431
|
const c = t.closest("label");
|
|
1414
1432
|
if (c) {
|
|
1415
|
-
const
|
|
1416
|
-
if (
|
|
1433
|
+
const u = A(c).trim();
|
|
1434
|
+
if (u) return u;
|
|
1417
1435
|
}
|
|
1418
1436
|
}
|
|
1419
1437
|
const r = (l = t.getAttribute("title")) == null ? void 0 : l.trim();
|
|
@@ -1424,7 +1442,7 @@ function st(t) {
|
|
|
1424
1442
|
}
|
|
1425
1443
|
return "";
|
|
1426
1444
|
}
|
|
1427
|
-
const
|
|
1445
|
+
const ut = {
|
|
1428
1446
|
id: "label",
|
|
1429
1447
|
wcag: ["4.1.2"],
|
|
1430
1448
|
level: "A",
|
|
@@ -1433,23 +1451,23 @@ const lt = {
|
|
|
1433
1451
|
prompt: `This form field has no accessible label. Based on the context (input type, name attribute, placeholder, or surrounding elements), suggest adding a <label for="id"> element with descriptive text, or an aria-label attribute. The label should describe what information the user should enter, not the field type. For example: 'Email address', 'Search', 'Phone number'.`,
|
|
1434
1452
|
run(t) {
|
|
1435
1453
|
var n;
|
|
1436
|
-
const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${
|
|
1454
|
+
const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${ot}`);
|
|
1437
1455
|
for (const r of i) {
|
|
1438
|
-
if (
|
|
1456
|
+
if (g(r) || T(r) || (r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement || r instanceof HTMLSelectElement || r instanceof HTMLButtonElement) && r.disabled || r.closest("fieldset[disabled]") || r.getAttribute("aria-disabled") === "true") continue;
|
|
1439
1457
|
const o = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
|
|
1440
1458
|
if (o === "presentation" || o === "none") continue;
|
|
1441
|
-
if (!
|
|
1459
|
+
if (!ct(r)) {
|
|
1442
1460
|
const l = [], h = r.tagName.toLowerCase(), c = r.getAttribute("type");
|
|
1443
1461
|
c && h === "input" && l.push(`type: ${c}`);
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
const
|
|
1447
|
-
|
|
1462
|
+
const u = r.getAttribute("name");
|
|
1463
|
+
u && l.push(`name: "${u}"`);
|
|
1464
|
+
const p = r.getAttribute("placeholder");
|
|
1465
|
+
p && l.push(`placeholder: "${p}"`), o && l.push(`role: ${o}`);
|
|
1448
1466
|
const b = r.getAttribute("id");
|
|
1449
1467
|
b && l.push(`id: "${b}"`), a.push({
|
|
1450
1468
|
ruleId: "label",
|
|
1451
1469
|
selector: m(r),
|
|
1452
|
-
html:
|
|
1470
|
+
html: d(r),
|
|
1453
1471
|
impact: "critical",
|
|
1454
1472
|
message: "Form element has no accessible label.",
|
|
1455
1473
|
context: l.length > 0 ? l.join(", ") : void 0
|
|
@@ -1458,7 +1476,7 @@ const lt = {
|
|
|
1458
1476
|
}
|
|
1459
1477
|
return a;
|
|
1460
1478
|
}
|
|
1461
|
-
},
|
|
1479
|
+
}, dt = {
|
|
1462
1480
|
id: "form-field-multiple-labels",
|
|
1463
1481
|
wcag: [],
|
|
1464
1482
|
level: "A",
|
|
@@ -1469,7 +1487,7 @@ const lt = {
|
|
|
1469
1487
|
run(t) {
|
|
1470
1488
|
const a = [], e = t.querySelectorAll('input:not([type="hidden"]), textarea, select');
|
|
1471
1489
|
for (const i of e) {
|
|
1472
|
-
if (
|
|
1490
|
+
if (g(i) || !i.id) continue;
|
|
1473
1491
|
const n = t.querySelectorAll(`label[for="${CSS.escape(i.id)}"]`);
|
|
1474
1492
|
let r = 0, o = i.parentElement;
|
|
1475
1493
|
for (; o; ) {
|
|
@@ -1483,14 +1501,14 @@ const lt = {
|
|
|
1483
1501
|
s > 1 && a.push({
|
|
1484
1502
|
ruleId: "form-field-multiple-labels",
|
|
1485
1503
|
selector: m(i),
|
|
1486
|
-
html:
|
|
1504
|
+
html: d(i),
|
|
1487
1505
|
impact: "moderate",
|
|
1488
1506
|
message: `Form field has ${s} labels. Use a single label element.`
|
|
1489
1507
|
});
|
|
1490
1508
|
}
|
|
1491
1509
|
return a;
|
|
1492
1510
|
}
|
|
1493
|
-
},
|
|
1511
|
+
}, mt = {
|
|
1494
1512
|
id: "select-name",
|
|
1495
1513
|
wcag: ["4.1.2"],
|
|
1496
1514
|
level: "A",
|
|
@@ -1500,16 +1518,16 @@ const lt = {
|
|
|
1500
1518
|
run(t) {
|
|
1501
1519
|
const a = [];
|
|
1502
1520
|
for (const e of t.querySelectorAll("select"))
|
|
1503
|
-
|
|
1521
|
+
g(e) || v(e) || a.push({
|
|
1504
1522
|
ruleId: "select-name",
|
|
1505
1523
|
selector: m(e),
|
|
1506
|
-
html:
|
|
1524
|
+
html: d(e),
|
|
1507
1525
|
impact: "critical",
|
|
1508
1526
|
message: "Select element has no accessible name."
|
|
1509
1527
|
});
|
|
1510
1528
|
return a;
|
|
1511
1529
|
}
|
|
1512
|
-
},
|
|
1530
|
+
}, ht = {
|
|
1513
1531
|
id: "input-button-name",
|
|
1514
1532
|
wcag: ["4.1.2"],
|
|
1515
1533
|
level: "A",
|
|
@@ -1522,19 +1540,19 @@ const lt = {
|
|
|
1522
1540
|
for (const n of t.querySelectorAll(
|
|
1523
1541
|
'input[type="submit"], input[type="button"], input[type="reset"]'
|
|
1524
1542
|
)) {
|
|
1525
|
-
if (
|
|
1543
|
+
if (g(n)) continue;
|
|
1526
1544
|
const r = (e = n.getAttribute("value")) == null ? void 0 : e.trim(), o = (i = n.getAttribute("type")) == null ? void 0 : i.toLowerCase(), s = (o === "submit" || o === "reset") && !n.hasAttribute("value");
|
|
1527
1545
|
!r && !s && !v(n) && a.push({
|
|
1528
1546
|
ruleId: "input-button-name",
|
|
1529
1547
|
selector: m(n),
|
|
1530
|
-
html:
|
|
1548
|
+
html: d(n),
|
|
1531
1549
|
impact: "critical",
|
|
1532
1550
|
message: "Input button has no discernible text."
|
|
1533
1551
|
});
|
|
1534
1552
|
}
|
|
1535
1553
|
return a;
|
|
1536
1554
|
}
|
|
1537
|
-
},
|
|
1555
|
+
}, pt = /* @__PURE__ */ new Set([
|
|
1538
1556
|
"off",
|
|
1539
1557
|
"on",
|
|
1540
1558
|
"name",
|
|
@@ -1589,7 +1607,7 @@ const lt = {
|
|
|
1589
1607
|
"impp",
|
|
1590
1608
|
"url",
|
|
1591
1609
|
"photo"
|
|
1592
|
-
]),
|
|
1610
|
+
]), gt = /* @__PURE__ */ new Set([
|
|
1593
1611
|
"tel",
|
|
1594
1612
|
"tel-country-code",
|
|
1595
1613
|
"tel-national",
|
|
@@ -1598,18 +1616,18 @@ const lt = {
|
|
|
1598
1616
|
"tel-extension",
|
|
1599
1617
|
"email",
|
|
1600
1618
|
"impp"
|
|
1601
|
-
]),
|
|
1602
|
-
function
|
|
1619
|
+
]), bt = /* @__PURE__ */ new Set(["home", "work", "mobile", "fax", "pager"]), ft = /* @__PURE__ */ new Set(["shipping", "billing"]), vt = /* @__PURE__ */ new Set(["webauthn"]);
|
|
1620
|
+
function yt(t) {
|
|
1603
1621
|
const a = t.toLowerCase().split(/\s+/).filter(Boolean);
|
|
1604
1622
|
if (a.length === 0) return !0;
|
|
1605
1623
|
let e = 0;
|
|
1606
|
-
a[e].startsWith("section-") && e++, e < a.length &&
|
|
1624
|
+
a[e].startsWith("section-") && e++, e < a.length && ft.has(a[e]) && e++;
|
|
1607
1625
|
let i = !1;
|
|
1608
|
-
if (e < a.length &&
|
|
1626
|
+
if (e < a.length && bt.has(a[e]) && (i = !0, e++), e >= a.length) return !1;
|
|
1609
1627
|
const n = a[e];
|
|
1610
|
-
return !
|
|
1628
|
+
return !pt.has(n) || i && !gt.has(n) ? !1 : (e++, e < a.length && vt.has(a[e]) && e++, e === a.length);
|
|
1611
1629
|
}
|
|
1612
|
-
const
|
|
1630
|
+
const wt = {
|
|
1613
1631
|
id: "autocomplete-valid",
|
|
1614
1632
|
wcag: ["1.3.5"],
|
|
1615
1633
|
level: "AA",
|
|
@@ -1619,12 +1637,12 @@ const vt = {
|
|
|
1619
1637
|
run(t) {
|
|
1620
1638
|
const a = [];
|
|
1621
1639
|
for (const e of t.querySelectorAll("[autocomplete]")) {
|
|
1622
|
-
if (
|
|
1640
|
+
if (g(e) || e instanceof HTMLElement && e.style.display === "none" || e.disabled || e.getAttribute("aria-disabled") === "true") continue;
|
|
1623
1641
|
const i = e.getAttribute("autocomplete").trim();
|
|
1624
|
-
i && (
|
|
1642
|
+
i && (yt(i) || a.push({
|
|
1625
1643
|
ruleId: "autocomplete-valid",
|
|
1626
1644
|
selector: m(e),
|
|
1627
|
-
html:
|
|
1645
|
+
html: d(e),
|
|
1628
1646
|
impact: "serious",
|
|
1629
1647
|
message: `Invalid autocomplete value "${i}".`
|
|
1630
1648
|
}));
|
|
@@ -1632,16 +1650,16 @@ const vt = {
|
|
|
1632
1650
|
return a;
|
|
1633
1651
|
}
|
|
1634
1652
|
};
|
|
1635
|
-
function
|
|
1653
|
+
function ee(t) {
|
|
1636
1654
|
return t.toLowerCase().replace(/\s+/g, " ").trim();
|
|
1637
1655
|
}
|
|
1638
|
-
function
|
|
1639
|
-
const e =
|
|
1656
|
+
function te(t, a) {
|
|
1657
|
+
const e = ee(t), i = ee(a);
|
|
1640
1658
|
if (!e || !i || e.includes(i) || i.includes(e)) return !0;
|
|
1641
1659
|
const n = i.split(/\s+/).map((r) => r.replace(/[.,;:!?\u2026]+$/g, "")).filter((r) => r.length > 2);
|
|
1642
1660
|
return n.length >= 2 && n.filter((o) => e.includes(o)).length / n.length > 0.5;
|
|
1643
1661
|
}
|
|
1644
|
-
function
|
|
1662
|
+
function z(t) {
|
|
1645
1663
|
let a = "";
|
|
1646
1664
|
for (const e of t.childNodes)
|
|
1647
1665
|
if (e.nodeType === 3)
|
|
@@ -1651,57 +1669,58 @@ function V(t) {
|
|
|
1651
1669
|
if (n === "style" || n === "script" || n === "svg" || i.getAttribute("aria-hidden") === "true" || i instanceof HTMLElement && i.style.display === "none") continue;
|
|
1652
1670
|
const r = i.getAttribute("role");
|
|
1653
1671
|
if (r === "img" || r === "presentation" || r === "none") continue;
|
|
1654
|
-
a +=
|
|
1672
|
+
a += z(i);
|
|
1655
1673
|
}
|
|
1656
1674
|
return a;
|
|
1657
1675
|
}
|
|
1658
|
-
const
|
|
1676
|
+
const At = {
|
|
1659
1677
|
id: "label-content-name-mismatch",
|
|
1660
|
-
wcag: [
|
|
1678
|
+
wcag: [],
|
|
1661
1679
|
level: "A",
|
|
1680
|
+
tags: ["best-practice"],
|
|
1662
1681
|
description: "Interactive elements with visible text must have accessible names that contain that text.",
|
|
1663
1682
|
guidance: "For voice control users who activate controls by speaking their visible label, the accessible name must include the visible text. If aria-label is 'Submit form' but the button shows 'Send', voice users saying 'click Send' won't activate it. Ensure aria-label/aria-labelledby contains or matches the visible text.",
|
|
1664
1683
|
prompt: "Show the mismatch between the visible text and accessible name, and suggest updating aria-label to include the visible text.",
|
|
1665
1684
|
run(t) {
|
|
1666
1685
|
const a = [];
|
|
1667
1686
|
for (const e of t.querySelectorAll('button, [role="button"], a[href], input[type="submit"], input[type="button"]')) {
|
|
1668
|
-
if (
|
|
1687
|
+
if (g(e)) continue;
|
|
1669
1688
|
const i = v(e);
|
|
1670
1689
|
if (!i) continue;
|
|
1671
1690
|
let n = "";
|
|
1672
|
-
e instanceof HTMLInputElement ? n = e.value || "" : n =
|
|
1691
|
+
e instanceof HTMLInputElement ? n = e.value || "" : n = z(e);
|
|
1673
1692
|
const r = n.trim();
|
|
1674
1693
|
if (!r || r.length <= 2) continue;
|
|
1675
1694
|
const o = e.hasAttribute("aria-label"), s = e.hasAttribute("aria-labelledby");
|
|
1676
|
-
!o && !s ||
|
|
1695
|
+
!o && !s || te(i, n) || a.push({
|
|
1677
1696
|
ruleId: "label-content-name-mismatch",
|
|
1678
1697
|
selector: m(e),
|
|
1679
|
-
html:
|
|
1698
|
+
html: d(e),
|
|
1680
1699
|
impact: "serious",
|
|
1681
1700
|
message: `Accessible name "${i}" does not contain visible text "${n.trim()}".`
|
|
1682
1701
|
});
|
|
1683
1702
|
}
|
|
1684
1703
|
for (const e of t.querySelectorAll("input, select, textarea")) {
|
|
1685
|
-
if (
|
|
1704
|
+
if (g(e) || e instanceof HTMLInputElement && ["hidden", "submit", "button", "image"].includes(e.type)) continue;
|
|
1686
1705
|
const i = v(e);
|
|
1687
1706
|
if (!i || !e.hasAttribute("aria-label")) continue;
|
|
1688
1707
|
const r = e.id;
|
|
1689
1708
|
let o = "";
|
|
1690
1709
|
if (r) {
|
|
1691
1710
|
const s = t.querySelector(`label[for="${CSS.escape(r)}"]`);
|
|
1692
|
-
s && (o =
|
|
1711
|
+
s && (o = z(s));
|
|
1693
1712
|
}
|
|
1694
|
-
o.trim() && (
|
|
1713
|
+
o.trim() && (te(i, o) || a.push({
|
|
1695
1714
|
ruleId: "label-content-name-mismatch",
|
|
1696
1715
|
selector: m(e),
|
|
1697
|
-
html:
|
|
1716
|
+
html: d(e),
|
|
1698
1717
|
impact: "serious",
|
|
1699
1718
|
message: `Accessible name "${i}" does not contain visible label "${o.trim()}".`
|
|
1700
1719
|
}));
|
|
1701
1720
|
}
|
|
1702
1721
|
return a;
|
|
1703
1722
|
}
|
|
1704
|
-
},
|
|
1723
|
+
}, xt = {
|
|
1705
1724
|
id: "label-title-only",
|
|
1706
1725
|
wcag: [],
|
|
1707
1726
|
level: "A",
|
|
@@ -1715,26 +1734,26 @@ const yt = {
|
|
|
1715
1734
|
'input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select'
|
|
1716
1735
|
);
|
|
1717
1736
|
for (const s of e) {
|
|
1718
|
-
if (
|
|
1737
|
+
if (g(s)) continue;
|
|
1719
1738
|
const l = s.hasAttribute("title") && ((i = s.getAttribute("title")) == null ? void 0 : i.trim()), h = s.hasAttribute("aria-label") && ((n = s.getAttribute("aria-label")) == null ? void 0 : n.trim()), c = s.hasAttribute("aria-labelledby");
|
|
1720
|
-
let
|
|
1721
|
-
const
|
|
1722
|
-
if (
|
|
1723
|
-
const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(
|
|
1724
|
-
(r = f == null ? void 0 : f.textContent) != null && r.trim() && (
|
|
1739
|
+
let u = !1;
|
|
1740
|
+
const p = s.id;
|
|
1741
|
+
if (p) {
|
|
1742
|
+
const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(p)}"]`);
|
|
1743
|
+
(r = f == null ? void 0 : f.textContent) != null && r.trim() && (u = !0);
|
|
1725
1744
|
}
|
|
1726
1745
|
const b = s.closest("label");
|
|
1727
|
-
(o = b == null ? void 0 : b.textContent) != null && o.trim() && (
|
|
1746
|
+
(o = b == null ? void 0 : b.textContent) != null && o.trim() && (u = !0), l && !h && !c && !u && a.push({
|
|
1728
1747
|
ruleId: "label-title-only",
|
|
1729
1748
|
selector: m(s),
|
|
1730
|
-
html:
|
|
1749
|
+
html: d(s),
|
|
1731
1750
|
impact: "serious",
|
|
1732
1751
|
message: "Form element uses title attribute as only label. Use <label>, aria-label, or aria-labelledby instead."
|
|
1733
1752
|
});
|
|
1734
1753
|
}
|
|
1735
1754
|
return a;
|
|
1736
1755
|
}
|
|
1737
|
-
},
|
|
1756
|
+
}, St = {
|
|
1738
1757
|
id: "tabindex",
|
|
1739
1758
|
selector: "[tabindex]",
|
|
1740
1759
|
check: { type: "attribute-value", attribute: "tabindex", operator: ">", value: 0 },
|
|
@@ -1746,7 +1765,7 @@ const yt = {
|
|
|
1746
1765
|
tags: ["best-practice"],
|
|
1747
1766
|
guidance: "Positive tabindex values force elements to the front of the tab order regardless of DOM position, creating unpredictable navigation for keyboard users. Use tabindex='0' to add elements to the natural tab order, or tabindex='-1' to make elements programmatically focusable but not in tab order. Rely on DOM order for tab sequence.",
|
|
1748
1767
|
prompt: "Change the positive tabindex value to tabindex='0' and rely on DOM order for tab sequence instead."
|
|
1749
|
-
},
|
|
1768
|
+
}, kt = k(St), It = /* @__PURE__ */ new Set([
|
|
1750
1769
|
"div",
|
|
1751
1770
|
"span",
|
|
1752
1771
|
"p",
|
|
@@ -1773,7 +1792,7 @@ const yt = {
|
|
|
1773
1792
|
"tr",
|
|
1774
1793
|
"td",
|
|
1775
1794
|
"th"
|
|
1776
|
-
]),
|
|
1795
|
+
]), Tt = {
|
|
1777
1796
|
id: "focus-order-semantics",
|
|
1778
1797
|
wcag: [],
|
|
1779
1798
|
tags: ["best-practice"],
|
|
@@ -1785,18 +1804,18 @@ const yt = {
|
|
|
1785
1804
|
const a = [];
|
|
1786
1805
|
for (const e of t.querySelectorAll('[tabindex="0"]')) {
|
|
1787
1806
|
const i = e.tagName.toLowerCase();
|
|
1788
|
-
if (!
|
|
1807
|
+
if (!It.has(i)) continue;
|
|
1789
1808
|
e.getAttribute("role") || a.push({
|
|
1790
1809
|
ruleId: "focus-order-semantics",
|
|
1791
1810
|
selector: m(e),
|
|
1792
|
-
html:
|
|
1811
|
+
html: d(e),
|
|
1793
1812
|
impact: "moderate",
|
|
1794
1813
|
message: `Non-interactive <${i}> with tabindex="0" has no interactive role.`
|
|
1795
1814
|
});
|
|
1796
1815
|
}
|
|
1797
1816
|
return a;
|
|
1798
1817
|
}
|
|
1799
|
-
},
|
|
1818
|
+
}, Et = /* @__PURE__ */ new Set([
|
|
1800
1819
|
"a",
|
|
1801
1820
|
"audio",
|
|
1802
1821
|
"button",
|
|
@@ -1805,7 +1824,7 @@ const yt = {
|
|
|
1805
1824
|
"select",
|
|
1806
1825
|
"textarea",
|
|
1807
1826
|
"video"
|
|
1808
|
-
]),
|
|
1827
|
+
]), Ct = /* @__PURE__ */ new Set([
|
|
1809
1828
|
"button",
|
|
1810
1829
|
"checkbox",
|
|
1811
1830
|
"combobox",
|
|
@@ -1829,7 +1848,7 @@ const yt = {
|
|
|
1829
1848
|
"tabpanel",
|
|
1830
1849
|
"textbox",
|
|
1831
1850
|
"treeitem"
|
|
1832
|
-
]),
|
|
1851
|
+
]), Lt = {
|
|
1833
1852
|
grid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader"]),
|
|
1834
1853
|
listbox: /* @__PURE__ */ new Set(["option"]),
|
|
1835
1854
|
menu: /* @__PURE__ */ new Set(["menuitem", "menuitemcheckbox", "menuitemradio"]),
|
|
@@ -1839,26 +1858,26 @@ const yt = {
|
|
|
1839
1858
|
tree: /* @__PURE__ */ new Set(["treeitem"]),
|
|
1840
1859
|
treegrid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader", "treeitem"])
|
|
1841
1860
|
};
|
|
1842
|
-
function
|
|
1861
|
+
function qt(t, a) {
|
|
1843
1862
|
var n, r, o;
|
|
1844
1863
|
const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase(), i = (r = a.getAttribute("role")) == null ? void 0 : r.toLowerCase();
|
|
1845
|
-
return !e || !i ? !1 : ((o =
|
|
1864
|
+
return !e || !i ? !1 : ((o = Lt[e]) == null ? void 0 : o.has(i)) ?? !1;
|
|
1846
1865
|
}
|
|
1847
|
-
function
|
|
1866
|
+
function Rt(t) {
|
|
1848
1867
|
var n;
|
|
1849
1868
|
const a = t.tagName.toLowerCase();
|
|
1850
|
-
if (
|
|
1869
|
+
if (Et.has(a))
|
|
1851
1870
|
return a === "a" && !t.hasAttribute("href") ? !1 : a === "audio" || a === "video" ? t.hasAttribute("controls") : !(a === "img" && !t.hasAttribute("usemap") || a === "input" && t.type === "hidden" || t.disabled);
|
|
1852
1871
|
const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase();
|
|
1853
|
-
if (e &&
|
|
1872
|
+
if (e && Ct.has(e)) return !0;
|
|
1854
1873
|
const i = t.getAttribute("tabindex");
|
|
1855
1874
|
return i !== null && i !== "-1" || t.getAttribute("contenteditable") === "true";
|
|
1856
1875
|
}
|
|
1857
|
-
function
|
|
1876
|
+
function Nt(t) {
|
|
1858
1877
|
const a = t.tagName.toLowerCase();
|
|
1859
1878
|
return !!(a === "a" && t.hasAttribute("href") || a === "button" && !t.disabled);
|
|
1860
1879
|
}
|
|
1861
|
-
const
|
|
1880
|
+
const $t = {
|
|
1862
1881
|
id: "nested-interactive",
|
|
1863
1882
|
wcag: ["4.1.2"],
|
|
1864
1883
|
level: "A",
|
|
@@ -1873,24 +1892,24 @@ const Rt = {
|
|
|
1873
1892
|
for (; o; ) {
|
|
1874
1893
|
for (; r.length > 0 && !r[r.length - 1].contains(o); )
|
|
1875
1894
|
r.pop();
|
|
1876
|
-
if (!
|
|
1895
|
+
if (!g(o) && Rt(o)) {
|
|
1877
1896
|
if (r.length > 0) {
|
|
1878
1897
|
const s = r[r.length - 1];
|
|
1879
|
-
|
|
1898
|
+
qt(s, o) || a.push({
|
|
1880
1899
|
ruleId: "nested-interactive",
|
|
1881
1900
|
selector: m(o),
|
|
1882
|
-
html:
|
|
1901
|
+
html: d(o),
|
|
1883
1902
|
impact: "serious",
|
|
1884
1903
|
message: `Interactive element <${o.tagName.toLowerCase()}> is nested inside <${s.tagName.toLowerCase()}>.`
|
|
1885
1904
|
});
|
|
1886
1905
|
}
|
|
1887
|
-
|
|
1906
|
+
Nt(o) && r.push(o);
|
|
1888
1907
|
}
|
|
1889
1908
|
o = n.nextNode();
|
|
1890
1909
|
}
|
|
1891
1910
|
return a;
|
|
1892
1911
|
}
|
|
1893
|
-
},
|
|
1912
|
+
}, Mt = {
|
|
1894
1913
|
id: "scrollable-region-focusable",
|
|
1895
1914
|
wcag: ["2.1.1"],
|
|
1896
1915
|
level: "A",
|
|
@@ -1898,31 +1917,37 @@ const Rt = {
|
|
|
1898
1917
|
guidance: "Content that scrolls must be accessible to keyboard users. If a region has overflow:scroll or overflow:auto and contains scrollable content, it needs either tabindex='0' to be focusable, or it must contain focusable elements. Without this, keyboard users cannot scroll the content.",
|
|
1899
1918
|
prompt: "Explain how to make this scrollable region keyboard accessible.",
|
|
1900
1919
|
run(t) {
|
|
1920
|
+
var e;
|
|
1901
1921
|
const a = [];
|
|
1902
|
-
for (const
|
|
1903
|
-
if (
|
|
1904
|
-
const
|
|
1905
|
-
if (
|
|
1906
|
-
|
|
1907
|
-
|
|
1922
|
+
for (const i of t.querySelectorAll("*")) {
|
|
1923
|
+
if (g(i) || !(i instanceof HTMLElement)) continue;
|
|
1924
|
+
const n = i.tagName.toLowerCase();
|
|
1925
|
+
if (n === "body" || n === "html") continue;
|
|
1926
|
+
const r = i.getAttribute("role");
|
|
1927
|
+
if (r === "presentation" || r === "none") continue;
|
|
1928
|
+
const o = w(i), s = o.overflowX, l = o.overflowY;
|
|
1929
|
+
if (!(s === "scroll" || s === "auto" || l === "scroll" || l === "auto")) continue;
|
|
1930
|
+
if (i.scrollHeight > 0 || i.clientHeight > 0) {
|
|
1931
|
+
const b = i.scrollHeight - i.clientHeight, f = i.scrollWidth - i.clientWidth;
|
|
1932
|
+
if (b <= 0 && f <= 0 || b < 36 && f < 36 || i.clientWidth < 64 && i.clientHeight < 64) continue;
|
|
1908
1933
|
} else {
|
|
1909
|
-
const
|
|
1910
|
-
if (!
|
|
1934
|
+
const b = o.height !== "" || o.maxHeight !== "", f = ((e = i.textContent) == null ? void 0 : e.trim().length) ?? 0;
|
|
1935
|
+
if (!b || f <= 50) continue;
|
|
1911
1936
|
}
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1937
|
+
const u = i.getAttribute("tabindex");
|
|
1938
|
+
u !== null && u !== "-1" || i.querySelector(
|
|
1914
1939
|
'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
1915
1940
|
) || a.push({
|
|
1916
1941
|
ruleId: "scrollable-region-focusable",
|
|
1917
|
-
selector: m(
|
|
1918
|
-
html:
|
|
1942
|
+
selector: m(i),
|
|
1943
|
+
html: d(i),
|
|
1919
1944
|
impact: "serious",
|
|
1920
1945
|
message: "Scrollable region is not keyboard accessible. Add tabindex='0' or include focusable elements."
|
|
1921
1946
|
});
|
|
1922
1947
|
}
|
|
1923
1948
|
return a;
|
|
1924
1949
|
}
|
|
1925
|
-
},
|
|
1950
|
+
}, Ht = {
|
|
1926
1951
|
id: "accesskeys",
|
|
1927
1952
|
wcag: [],
|
|
1928
1953
|
level: "A",
|
|
@@ -1934,7 +1959,7 @@ const Rt = {
|
|
|
1934
1959
|
var i;
|
|
1935
1960
|
const a = [], e = /* @__PURE__ */ new Map();
|
|
1936
1961
|
for (const n of t.querySelectorAll("[accesskey]")) {
|
|
1937
|
-
if (
|
|
1962
|
+
if (g(n)) continue;
|
|
1938
1963
|
const r = (i = n.getAttribute("accesskey")) == null ? void 0 : i.trim().toLowerCase();
|
|
1939
1964
|
if (!r) continue;
|
|
1940
1965
|
const o = e.get(r) || [];
|
|
@@ -1946,13 +1971,13 @@ const Rt = {
|
|
|
1946
1971
|
a.push({
|
|
1947
1972
|
ruleId: "accesskeys",
|
|
1948
1973
|
selector: m(o),
|
|
1949
|
-
html:
|
|
1974
|
+
html: d(o),
|
|
1950
1975
|
impact: "serious",
|
|
1951
1976
|
message: `Duplicate accesskey "${n}". Each accesskey must be unique.`
|
|
1952
1977
|
});
|
|
1953
1978
|
return a;
|
|
1954
1979
|
}
|
|
1955
|
-
},
|
|
1980
|
+
}, Dt = {
|
|
1956
1981
|
id: "heading-order",
|
|
1957
1982
|
wcag: [],
|
|
1958
1983
|
level: "A",
|
|
@@ -1964,20 +1989,20 @@ const Rt = {
|
|
|
1964
1989
|
const a = [], e = t.querySelectorAll("h1, h2, h3, h4, h5, h6, [role='heading']");
|
|
1965
1990
|
let i = 0, n = null;
|
|
1966
1991
|
for (const r of e) {
|
|
1967
|
-
if (
|
|
1992
|
+
if (g(r)) continue;
|
|
1968
1993
|
let o;
|
|
1969
1994
|
r.hasAttribute("aria-level") ? o = parseInt(r.getAttribute("aria-level"), 10) : o = parseInt(r.tagName[1], 10), i > 0 && o > i + 1 && a.push({
|
|
1970
1995
|
ruleId: "heading-order",
|
|
1971
1996
|
selector: m(r),
|
|
1972
|
-
html:
|
|
1997
|
+
html: d(r),
|
|
1973
1998
|
impact: "moderate",
|
|
1974
1999
|
message: `Heading level ${o} skipped from level ${i}.`,
|
|
1975
|
-
context: n ? `Previous heading: ${
|
|
2000
|
+
context: n ? `Previous heading: ${d(n)}` : void 0
|
|
1976
2001
|
}), i = o, n = r;
|
|
1977
2002
|
}
|
|
1978
2003
|
return a;
|
|
1979
2004
|
}
|
|
1980
|
-
},
|
|
2005
|
+
}, $ = 'article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]', ae = 'main, [role="main"], header, [role="banner"], footer, [role="contentinfo"], nav, [role="navigation"], aside, [role="complementary"], section[aria-label], section[aria-labelledby], [role="region"][aria-label], [role="region"][aria-labelledby], form[aria-label], form[aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"]', Ot = {
|
|
1981
2006
|
id: "landmark-one-main",
|
|
1982
2007
|
wcag: [],
|
|
1983
2008
|
level: "A",
|
|
@@ -1996,12 +2021,12 @@ const Rt = {
|
|
|
1996
2021
|
}] : a.length > 1 ? Array.from(a).slice(1).map((e) => ({
|
|
1997
2022
|
ruleId: "landmark-one-main",
|
|
1998
2023
|
selector: m(e),
|
|
1999
|
-
html:
|
|
2024
|
+
html: d(e),
|
|
2000
2025
|
impact: "moderate",
|
|
2001
2026
|
message: "Page has multiple main landmarks."
|
|
2002
2027
|
})) : [];
|
|
2003
2028
|
}
|
|
2004
|
-
},
|
|
2029
|
+
}, Bt = {
|
|
2005
2030
|
id: "landmark-no-duplicate-banner",
|
|
2006
2031
|
wcag: [],
|
|
2007
2032
|
level: "A",
|
|
@@ -2010,18 +2035,18 @@ const Rt = {
|
|
|
2010
2035
|
guidance: "The banner landmark (typically <header>) identifies site-oriented content like logos and search. Only one top-level banner is allowed per page. If you need multiple headers, nest them inside sectioning elements (article, section, aside) where they become scoped headers rather than page-level banners.",
|
|
2011
2036
|
prompt: "Explain whether to remove this duplicate banner or nest it inside a sectioning element.",
|
|
2012
2037
|
run(t) {
|
|
2013
|
-
const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest(
|
|
2038
|
+
const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest($));
|
|
2014
2039
|
return i.length > 1 && i.slice(1).forEach(
|
|
2015
2040
|
(n) => a.push({
|
|
2016
2041
|
ruleId: "landmark-no-duplicate-banner",
|
|
2017
2042
|
selector: m(n),
|
|
2018
|
-
html:
|
|
2043
|
+
html: d(n),
|
|
2019
2044
|
impact: "moderate",
|
|
2020
2045
|
message: "Page has multiple banner landmarks."
|
|
2021
2046
|
})
|
|
2022
2047
|
), a;
|
|
2023
2048
|
}
|
|
2024
|
-
},
|
|
2049
|
+
}, Ft = {
|
|
2025
2050
|
id: "landmark-no-duplicate-contentinfo",
|
|
2026
2051
|
wcag: [],
|
|
2027
2052
|
level: "A",
|
|
@@ -2030,18 +2055,18 @@ const Rt = {
|
|
|
2030
2055
|
guidance: "The contentinfo landmark (typically <footer>) contains information about the page like copyright and contact info. Only one top-level contentinfo is allowed per page. Nest additional footers inside sectioning elements to scope them.",
|
|
2031
2056
|
prompt: "Explain whether to remove this duplicate footer or nest it inside a sectioning element.",
|
|
2032
2057
|
run(t) {
|
|
2033
|
-
const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest(
|
|
2058
|
+
const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest($));
|
|
2034
2059
|
return i.length > 1 && i.slice(1).forEach(
|
|
2035
2060
|
(n) => a.push({
|
|
2036
2061
|
ruleId: "landmark-no-duplicate-contentinfo",
|
|
2037
2062
|
selector: m(n),
|
|
2038
|
-
html:
|
|
2063
|
+
html: d(n),
|
|
2039
2064
|
impact: "moderate",
|
|
2040
2065
|
message: "Page has multiple contentinfo landmarks."
|
|
2041
2066
|
})
|
|
2042
2067
|
), a;
|
|
2043
2068
|
}
|
|
2044
|
-
},
|
|
2069
|
+
}, Wt = {
|
|
2045
2070
|
id: "landmark-no-duplicate-main",
|
|
2046
2071
|
wcag: [],
|
|
2047
2072
|
level: "A",
|
|
@@ -2055,13 +2080,13 @@ const Rt = {
|
|
|
2055
2080
|
(i) => a.push({
|
|
2056
2081
|
ruleId: "landmark-no-duplicate-main",
|
|
2057
2082
|
selector: m(i),
|
|
2058
|
-
html:
|
|
2083
|
+
html: d(i),
|
|
2059
2084
|
impact: "moderate",
|
|
2060
2085
|
message: "Page has multiple main landmarks."
|
|
2061
2086
|
})
|
|
2062
2087
|
), a;
|
|
2063
2088
|
}
|
|
2064
|
-
},
|
|
2089
|
+
}, _t = {
|
|
2065
2090
|
id: "landmark-banner-is-top-level",
|
|
2066
2091
|
wcag: [],
|
|
2067
2092
|
level: "A",
|
|
@@ -2072,16 +2097,16 @@ const Rt = {
|
|
|
2072
2097
|
run(t) {
|
|
2073
2098
|
const a = [], e = t.querySelectorAll('[role="banner"]');
|
|
2074
2099
|
for (const i of e)
|
|
2075
|
-
i.closest(
|
|
2100
|
+
i.closest($) && a.push({
|
|
2076
2101
|
ruleId: "landmark-banner-is-top-level",
|
|
2077
2102
|
selector: m(i),
|
|
2078
|
-
html:
|
|
2103
|
+
html: d(i),
|
|
2079
2104
|
impact: "moderate",
|
|
2080
2105
|
message: "Banner landmark is nested within another landmark."
|
|
2081
2106
|
});
|
|
2082
2107
|
return a;
|
|
2083
2108
|
}
|
|
2084
|
-
},
|
|
2109
|
+
}, Pt = {
|
|
2085
2110
|
id: "landmark-contentinfo-is-top-level",
|
|
2086
2111
|
wcag: [],
|
|
2087
2112
|
level: "A",
|
|
@@ -2092,16 +2117,16 @@ const Rt = {
|
|
|
2092
2117
|
run(t) {
|
|
2093
2118
|
const a = [], e = t.querySelectorAll('[role="contentinfo"]');
|
|
2094
2119
|
for (const i of e)
|
|
2095
|
-
i.closest(
|
|
2120
|
+
i.closest($) && a.push({
|
|
2096
2121
|
ruleId: "landmark-contentinfo-is-top-level",
|
|
2097
2122
|
selector: m(i),
|
|
2098
|
-
html:
|
|
2123
|
+
html: d(i),
|
|
2099
2124
|
impact: "moderate",
|
|
2100
2125
|
message: "Contentinfo landmark is nested within another landmark."
|
|
2101
2126
|
});
|
|
2102
2127
|
return a;
|
|
2103
2128
|
}
|
|
2104
|
-
},
|
|
2129
|
+
}, jt = {
|
|
2105
2130
|
id: "landmark-main-is-top-level",
|
|
2106
2131
|
wcag: [],
|
|
2107
2132
|
level: "A",
|
|
@@ -2116,14 +2141,14 @@ const Rt = {
|
|
|
2116
2141
|
n != null && n.closest('article, aside, nav, section, [role="article"], [role="complementary"], [role="navigation"], [role="region"]') && a.push({
|
|
2117
2142
|
ruleId: "landmark-main-is-top-level",
|
|
2118
2143
|
selector: m(i),
|
|
2119
|
-
html:
|
|
2144
|
+
html: d(i),
|
|
2120
2145
|
impact: "moderate",
|
|
2121
2146
|
message: "Main landmark is nested within another landmark."
|
|
2122
2147
|
});
|
|
2123
2148
|
}
|
|
2124
2149
|
return a;
|
|
2125
2150
|
}
|
|
2126
|
-
},
|
|
2151
|
+
}, Vt = {
|
|
2127
2152
|
id: "landmark-complementary-is-top-level",
|
|
2128
2153
|
wcag: [],
|
|
2129
2154
|
level: "A",
|
|
@@ -2138,14 +2163,14 @@ const Rt = {
|
|
|
2138
2163
|
n && !n.matches('body, main, [role="main"]') && i.closest('article, nav, section, [role="article"], [role="navigation"], [role="region"]') && a.push({
|
|
2139
2164
|
ruleId: "landmark-complementary-is-top-level",
|
|
2140
2165
|
selector: m(i),
|
|
2141
|
-
html:
|
|
2166
|
+
html: d(i),
|
|
2142
2167
|
impact: "moderate",
|
|
2143
2168
|
message: "Complementary landmark should be top-level."
|
|
2144
2169
|
});
|
|
2145
2170
|
}
|
|
2146
2171
|
return a;
|
|
2147
2172
|
}
|
|
2148
|
-
},
|
|
2173
|
+
}, zt = {
|
|
2149
2174
|
id: "landmark-unique",
|
|
2150
2175
|
wcag: [],
|
|
2151
2176
|
level: "A",
|
|
@@ -2161,7 +2186,7 @@ const Rt = {
|
|
|
2161
2186
|
{ selector: 'form[aria-label], form[aria-labelledby], [role="form"], [role="search"]', type: "form" }
|
|
2162
2187
|
];
|
|
2163
2188
|
for (const { selector: i, type: n } of e) {
|
|
2164
|
-
const r = Array.from(t.querySelectorAll(i)).filter((s) => !
|
|
2189
|
+
const r = Array.from(t.querySelectorAll(i)).filter((s) => !g(s));
|
|
2165
2190
|
if (r.length <= 1) continue;
|
|
2166
2191
|
const o = /* @__PURE__ */ new Map();
|
|
2167
2192
|
for (const s of r) {
|
|
@@ -2174,14 +2199,14 @@ const Rt = {
|
|
|
2174
2199
|
a.push({
|
|
2175
2200
|
ruleId: "landmark-unique",
|
|
2176
2201
|
selector: m(h),
|
|
2177
|
-
html:
|
|
2202
|
+
html: d(h),
|
|
2178
2203
|
impact: "moderate",
|
|
2179
2204
|
message: s ? `Multiple ${n} landmarks have the same label "${s}".` : `Multiple ${n} landmarks have no label. Add unique aria-label attributes.`
|
|
2180
2205
|
});
|
|
2181
2206
|
}
|
|
2182
2207
|
return a;
|
|
2183
2208
|
}
|
|
2184
|
-
},
|
|
2209
|
+
}, Ut = {
|
|
2185
2210
|
id: "region",
|
|
2186
2211
|
wcag: [],
|
|
2187
2212
|
level: "A",
|
|
@@ -2194,22 +2219,22 @@ const Rt = {
|
|
|
2194
2219
|
const a = [], e = t.body;
|
|
2195
2220
|
if (!e) return [];
|
|
2196
2221
|
for (const n of e.children) {
|
|
2197
|
-
if (
|
|
2198
|
-
const r = n.matches(
|
|
2199
|
-
!r && o && (n.querySelector(
|
|
2222
|
+
if (g(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
|
|
2223
|
+
const r = n.matches(ae), o = (i = n.textContent) == null ? void 0 : i.trim();
|
|
2224
|
+
!r && o && (n.querySelector(ae) || a.push({
|
|
2200
2225
|
ruleId: "region",
|
|
2201
2226
|
selector: m(n),
|
|
2202
|
-
html:
|
|
2227
|
+
html: d(n),
|
|
2203
2228
|
impact: "moderate",
|
|
2204
2229
|
message: "Content is not contained within a landmark region."
|
|
2205
2230
|
}));
|
|
2206
2231
|
}
|
|
2207
2232
|
return a;
|
|
2208
2233
|
}
|
|
2209
|
-
},
|
|
2234
|
+
}, Gt = {
|
|
2210
2235
|
id: "list",
|
|
2211
2236
|
selector: "ul, ol",
|
|
2212
|
-
check: { type: "child-invalid", allowedChildren: ["li", "script", "template"] },
|
|
2237
|
+
check: { type: "child-invalid", allowedChildren: ["li", "script", "template"], allowedChildRoles: ["listitem"] },
|
|
2213
2238
|
impact: "serious",
|
|
2214
2239
|
message: "List contains non-<li> child <{{tag}}>.",
|
|
2215
2240
|
description: "<ul> and <ol> must only contain <li>, <script>, or <template> as direct children.",
|
|
@@ -2217,7 +2242,7 @@ const Rt = {
|
|
|
2217
2242
|
level: "A",
|
|
2218
2243
|
guidance: "Screen readers announce list structure ('list with 5 items') based on proper markup. Placing non-<li> elements directly inside <ul> or <ol> breaks this structure. Wrap content in <li> elements, or if you need wrapper divs for styling, restructure your CSS to style the <li> elements directly.",
|
|
2219
2244
|
prompt: "Explain how to restructure this element within the list properly."
|
|
2220
|
-
},
|
|
2245
|
+
}, Yt = k(Gt), Xt = {
|
|
2221
2246
|
id: "dlitem",
|
|
2222
2247
|
wcag: ["1.3.1"],
|
|
2223
2248
|
level: "A",
|
|
@@ -2230,13 +2255,13 @@ const Rt = {
|
|
|
2230
2255
|
(!e.parentElement || e.parentElement.tagName.toLowerCase() !== "dl") && a.push({
|
|
2231
2256
|
ruleId: "dlitem",
|
|
2232
2257
|
selector: m(e),
|
|
2233
|
-
html:
|
|
2258
|
+
html: d(e),
|
|
2234
2259
|
impact: "serious",
|
|
2235
2260
|
message: `<${e.tagName.toLowerCase()}> is not contained in a <dl>.`
|
|
2236
2261
|
});
|
|
2237
2262
|
return a;
|
|
2238
2263
|
}
|
|
2239
|
-
},
|
|
2264
|
+
}, Kt = {
|
|
2240
2265
|
id: "definition-list",
|
|
2241
2266
|
selector: "dl",
|
|
2242
2267
|
check: { type: "child-invalid", allowedChildren: ["dt", "dd", "div", "script", "template"] },
|
|
@@ -2247,7 +2272,32 @@ const Rt = {
|
|
|
2247
2272
|
level: "A",
|
|
2248
2273
|
guidance: "Definition lists have strict content requirements. Only <dt> (terms), <dd> (definitions), and <div> (for grouping dt/dd pairs) are valid children. Other elements break the list structure for screen readers. Move invalid elements outside the <dl>, or restructure using proper definition list markup.",
|
|
2249
2274
|
prompt: "Explain whether to move this element outside the <dl> or convert it to dt/dd."
|
|
2250
|
-
},
|
|
2275
|
+
}, Jt = k(Kt), Qt = {
|
|
2276
|
+
id: "listitem",
|
|
2277
|
+
wcag: ["1.3.1"],
|
|
2278
|
+
level: "A",
|
|
2279
|
+
description: "<li> elements must be contained in a <ul>, <ol>, or <menu>.",
|
|
2280
|
+
guidance: "List items (<li>) only have semantic meaning inside a list container (<ul>, <ol>, or <menu>). Outside of these containers, assistive technologies cannot convey the list relationship. Wrap <li> elements in the appropriate list container.",
|
|
2281
|
+
prompt: "Explain that this <li> must be placed inside a <ul>, <ol>, or <menu> element.",
|
|
2282
|
+
run(t) {
|
|
2283
|
+
var e;
|
|
2284
|
+
const a = [];
|
|
2285
|
+
for (const i of t.querySelectorAll("li")) {
|
|
2286
|
+
if (g(i)) continue;
|
|
2287
|
+
const n = i.parentElement;
|
|
2288
|
+
if (!n) continue;
|
|
2289
|
+
const r = n.tagName.toLowerCase();
|
|
2290
|
+
r === "ul" || r === "ol" || r === "menu" || ((e = n.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase()) === "list" || a.push({
|
|
2291
|
+
ruleId: "listitem",
|
|
2292
|
+
selector: m(i),
|
|
2293
|
+
html: d(i),
|
|
2294
|
+
impact: "serious",
|
|
2295
|
+
message: "<li> is not contained in a <ul>, <ol>, or <menu>."
|
|
2296
|
+
});
|
|
2297
|
+
}
|
|
2298
|
+
return a;
|
|
2299
|
+
}
|
|
2300
|
+
}, Zt = {
|
|
2251
2301
|
id: "document-title",
|
|
2252
2302
|
wcag: ["2.4.2"],
|
|
2253
2303
|
level: "A",
|
|
@@ -2277,10 +2327,11 @@ const Rt = {
|
|
|
2277
2327
|
}
|
|
2278
2328
|
return [];
|
|
2279
2329
|
}
|
|
2280
|
-
},
|
|
2330
|
+
}, ea = {
|
|
2281
2331
|
id: "bypass",
|
|
2282
|
-
wcag: [
|
|
2332
|
+
wcag: [],
|
|
2283
2333
|
level: "A",
|
|
2334
|
+
tags: ["best-practice"],
|
|
2284
2335
|
description: "Page must have a mechanism to bypass repeated blocks of content.",
|
|
2285
2336
|
guidance: 'Keyboard users must be able to skip repetitive content like navigation. Provide a skip link at the top of the page that links to the main content (e.g., <a href="#main">Skip to main content</a>), or use a <main> landmark. Screen readers can jump directly to landmarks, so a properly marked-up <main> element satisfies this requirement.',
|
|
2286
2337
|
prompt: 'The page has no mechanism for keyboard users to skip repeated content. The simplest fix is to wrap the primary content area in a <main> element — screen readers can jump directly to it. Alternatively, add a skip link as the first element in <body>: <a href="#main" class="skip-link">Skip to main content</a>, with a matching id on the target element. Use the context to understand what the page is missing.',
|
|
@@ -2307,7 +2358,7 @@ const Rt = {
|
|
|
2307
2358
|
context: `Missing: ${n.join(", ")}`
|
|
2308
2359
|
}];
|
|
2309
2360
|
}
|
|
2310
|
-
},
|
|
2361
|
+
}, ta = {
|
|
2311
2362
|
id: "page-has-heading-one",
|
|
2312
2363
|
wcag: [],
|
|
2313
2364
|
level: "A",
|
|
@@ -2339,13 +2390,13 @@ const Rt = {
|
|
|
2339
2390
|
}];
|
|
2340
2391
|
}
|
|
2341
2392
|
};
|
|
2342
|
-
function
|
|
2393
|
+
function he(t) {
|
|
2343
2394
|
if (!(t instanceof HTMLElement)) return !1;
|
|
2344
2395
|
if (t.style.display === "none" || t.style.visibility === "hidden") return !0;
|
|
2345
2396
|
const a = t.getAttribute("width"), e = t.getAttribute("height");
|
|
2346
2397
|
return (a === "0" || a === "1") && (e === "0" || e === "1");
|
|
2347
2398
|
}
|
|
2348
|
-
const
|
|
2399
|
+
const aa = {
|
|
2349
2400
|
id: "frame-title",
|
|
2350
2401
|
wcag: ["4.1.2"],
|
|
2351
2402
|
level: "A",
|
|
@@ -2355,13 +2406,13 @@ const Zt = {
|
|
|
2355
2406
|
run(t) {
|
|
2356
2407
|
const a = [];
|
|
2357
2408
|
for (const e of t.querySelectorAll("iframe, frame")) {
|
|
2358
|
-
if (
|
|
2409
|
+
if (g(e) || he(e)) continue;
|
|
2359
2410
|
if (!v(e)) {
|
|
2360
2411
|
const n = e.getAttribute("src");
|
|
2361
2412
|
a.push({
|
|
2362
2413
|
ruleId: "frame-title",
|
|
2363
2414
|
selector: m(e),
|
|
2364
|
-
html:
|
|
2415
|
+
html: d(e),
|
|
2365
2416
|
impact: "serious",
|
|
2366
2417
|
message: "Frame is missing an accessible name. Add a title attribute.",
|
|
2367
2418
|
context: n ? `src: "${n}"` : void 0
|
|
@@ -2370,7 +2421,7 @@ const Zt = {
|
|
|
2370
2421
|
}
|
|
2371
2422
|
return a;
|
|
2372
2423
|
}
|
|
2373
|
-
},
|
|
2424
|
+
}, ia = {
|
|
2374
2425
|
id: "frame-title-unique",
|
|
2375
2426
|
wcag: ["4.1.2"],
|
|
2376
2427
|
level: "A",
|
|
@@ -2382,7 +2433,7 @@ const Zt = {
|
|
|
2382
2433
|
var n;
|
|
2383
2434
|
const a = [], e = Array.from(t.querySelectorAll("iframe[title], frame[title]")), i = /* @__PURE__ */ new Map();
|
|
2384
2435
|
for (const r of e) {
|
|
2385
|
-
if (
|
|
2436
|
+
if (g(r) || he(r)) continue;
|
|
2386
2437
|
const o = (n = r.getAttribute("title")) == null ? void 0 : n.trim().toLowerCase();
|
|
2387
2438
|
if (o) {
|
|
2388
2439
|
const s = i.get(o) || [];
|
|
@@ -2395,13 +2446,13 @@ const Zt = {
|
|
|
2395
2446
|
a.push({
|
|
2396
2447
|
ruleId: "frame-title-unique",
|
|
2397
2448
|
selector: m(o),
|
|
2398
|
-
html:
|
|
2449
|
+
html: d(o),
|
|
2399
2450
|
impact: "moderate",
|
|
2400
2451
|
message: "Frame title is not unique. Use a distinct title for each frame."
|
|
2401
2452
|
});
|
|
2402
2453
|
return a;
|
|
2403
2454
|
}
|
|
2404
|
-
},
|
|
2455
|
+
}, na = {
|
|
2405
2456
|
id: "empty-heading",
|
|
2406
2457
|
wcag: [],
|
|
2407
2458
|
level: "A",
|
|
@@ -2413,7 +2464,7 @@ const Zt = {
|
|
|
2413
2464
|
var i;
|
|
2414
2465
|
const a = [], e = t.querySelectorAll('h1, h2, h3, h4, h5, h6, [role="heading"]');
|
|
2415
2466
|
for (const n of e)
|
|
2416
|
-
if (!
|
|
2467
|
+
if (!g(n) && !v(n)) {
|
|
2417
2468
|
let r;
|
|
2418
2469
|
const o = n.nextElementSibling;
|
|
2419
2470
|
if (o) {
|
|
@@ -2423,7 +2474,7 @@ const Zt = {
|
|
|
2423
2474
|
a.push({
|
|
2424
2475
|
ruleId: "empty-heading",
|
|
2425
2476
|
selector: m(n),
|
|
2426
|
-
html:
|
|
2477
|
+
html: d(n),
|
|
2427
2478
|
impact: "minor",
|
|
2428
2479
|
message: "Heading is empty. Add text content or remove the heading element.",
|
|
2429
2480
|
context: r ? `Following content: "${r}"` : void 0
|
|
@@ -2431,7 +2482,7 @@ const Zt = {
|
|
|
2431
2482
|
}
|
|
2432
2483
|
return a;
|
|
2433
2484
|
}
|
|
2434
|
-
},
|
|
2485
|
+
}, ra = {
|
|
2435
2486
|
id: "meta-viewport",
|
|
2436
2487
|
wcag: ["1.4.4"],
|
|
2437
2488
|
level: "AA",
|
|
@@ -2445,7 +2496,7 @@ const Zt = {
|
|
|
2445
2496
|
(/user-scalable\s*=\s*no/i.test(n) || /user-scalable\s*=\s*0/i.test(n)) && a.push({
|
|
2446
2497
|
ruleId: "meta-viewport",
|
|
2447
2498
|
selector: m(e),
|
|
2448
|
-
html:
|
|
2499
|
+
html: d(e),
|
|
2449
2500
|
impact: "critical",
|
|
2450
2501
|
message: "Viewport disables user scaling. Remove user-scalable=no.",
|
|
2451
2502
|
context: `content: "${i}"`
|
|
@@ -2456,7 +2507,7 @@ const Zt = {
|
|
|
2456
2507
|
s < 2 && a.push({
|
|
2457
2508
|
ruleId: "meta-viewport",
|
|
2458
2509
|
selector: m(e),
|
|
2459
|
-
html:
|
|
2510
|
+
html: d(e),
|
|
2460
2511
|
impact: "critical",
|
|
2461
2512
|
message: `Viewport maximum-scale=${s} restricts zooming. Set to at least 2 or remove.`,
|
|
2462
2513
|
context: `content: "${i}"`
|
|
@@ -2464,7 +2515,7 @@ const Zt = {
|
|
|
2464
2515
|
}
|
|
2465
2516
|
return a;
|
|
2466
2517
|
}
|
|
2467
|
-
},
|
|
2518
|
+
}, oa = {
|
|
2468
2519
|
id: "meta-refresh",
|
|
2469
2520
|
wcag: ["2.2.1", "2.2.4", "3.2.5"],
|
|
2470
2521
|
level: "A",
|
|
@@ -2480,7 +2531,7 @@ const Zt = {
|
|
|
2480
2531
|
return n > 0 && n <= 72e3 ? [{
|
|
2481
2532
|
ruleId: "meta-refresh",
|
|
2482
2533
|
selector: m(a),
|
|
2483
|
-
html:
|
|
2534
|
+
html: d(a),
|
|
2484
2535
|
impact: "critical",
|
|
2485
2536
|
message: `Page redirects after ${n} seconds without warning. Use server-side redirect.`
|
|
2486
2537
|
}] : [];
|
|
@@ -2488,14 +2539,14 @@ const Zt = {
|
|
|
2488
2539
|
return [{
|
|
2489
2540
|
ruleId: "meta-refresh",
|
|
2490
2541
|
selector: m(a),
|
|
2491
|
-
html:
|
|
2542
|
+
html: d(a),
|
|
2492
2543
|
impact: "critical",
|
|
2493
2544
|
message: `Page auto-refreshes after ${n} seconds. Provide user control over refresh.`
|
|
2494
2545
|
}];
|
|
2495
2546
|
}
|
|
2496
2547
|
return [];
|
|
2497
2548
|
}
|
|
2498
|
-
},
|
|
2549
|
+
}, sa = {
|
|
2499
2550
|
id: "blink",
|
|
2500
2551
|
selector: "blink",
|
|
2501
2552
|
check: { type: "selector-exists" },
|
|
@@ -2506,7 +2557,7 @@ const Zt = {
|
|
|
2506
2557
|
level: "A",
|
|
2507
2558
|
guidance: "Blinking content can cause seizures in users with photosensitive epilepsy and is distracting for users with attention disorders. The <blink> element is deprecated and should never be used. If you need to draw attention to content, use less intrusive methods like color, borders, or icons.",
|
|
2508
2559
|
prompt: "Suggest static alternatives to the blinking effect."
|
|
2509
|
-
},
|
|
2560
|
+
}, la = k(sa), ca = {
|
|
2510
2561
|
id: "marquee",
|
|
2511
2562
|
selector: "marquee",
|
|
2512
2563
|
check: { type: "selector-exists" },
|
|
@@ -2517,7 +2568,7 @@ const Zt = {
|
|
|
2517
2568
|
level: "A",
|
|
2518
2569
|
guidance: "Scrolling or moving content is difficult for many users to read, especially those with cognitive or visual disabilities. The <marquee> element is deprecated. Replace scrolling text with static content. If content must scroll, provide pause/stop controls and ensure it stops after 5 seconds.",
|
|
2519
2570
|
prompt: "Suggest static alternatives or accessible carousel patterns."
|
|
2520
|
-
},
|
|
2571
|
+
}, ua = k(ca), da = {
|
|
2521
2572
|
id: "p-as-heading",
|
|
2522
2573
|
wcag: [],
|
|
2523
2574
|
level: "A",
|
|
@@ -2529,14 +2580,14 @@ const Zt = {
|
|
|
2529
2580
|
var e, i;
|
|
2530
2581
|
const a = [];
|
|
2531
2582
|
for (const n of t.querySelectorAll("p")) {
|
|
2532
|
-
if (
|
|
2533
|
-
const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "",
|
|
2534
|
-
if ((o && s || o && h) &&
|
|
2583
|
+
if (g(n)) continue;
|
|
2584
|
+
const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "", u = c.length > 0 && c.length < 50, p = !c.match(/[.!?,;:]$/);
|
|
2585
|
+
if ((o && s || o && h) && u && p) {
|
|
2535
2586
|
const y = n.nextElementSibling;
|
|
2536
2587
|
y && (y.tagName === "P" || y.tagName === "DIV" || y.tagName === "UL") && a.push({
|
|
2537
2588
|
ruleId: "p-as-heading",
|
|
2538
2589
|
selector: m(n),
|
|
2539
|
-
html:
|
|
2590
|
+
html: d(n),
|
|
2540
2591
|
impact: "serious",
|
|
2541
2592
|
message: "Paragraph appears to be styled as a heading. Use an h1-h6 element instead."
|
|
2542
2593
|
});
|
|
@@ -2544,7 +2595,7 @@ const Zt = {
|
|
|
2544
2595
|
}
|
|
2545
2596
|
return a;
|
|
2546
2597
|
}
|
|
2547
|
-
},
|
|
2598
|
+
}, ma = {
|
|
2548
2599
|
id: "aria-roles",
|
|
2549
2600
|
wcag: ["4.1.2"],
|
|
2550
2601
|
level: "A",
|
|
@@ -2555,17 +2606,17 @@ const Zt = {
|
|
|
2555
2606
|
const a = [];
|
|
2556
2607
|
for (const e of t.querySelectorAll("[role]")) {
|
|
2557
2608
|
const r = e.getAttribute("role").replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "").split(/\s+/).filter(Boolean);
|
|
2558
|
-
!r.some((s) =>
|
|
2609
|
+
!r.some((s) => ke(s)) && r.length > 0 && a.push({
|
|
2559
2610
|
ruleId: "aria-roles",
|
|
2560
2611
|
selector: m(e),
|
|
2561
|
-
html:
|
|
2612
|
+
html: d(e),
|
|
2562
2613
|
impact: "critical",
|
|
2563
2614
|
message: `Invalid ARIA role "${r[0]}".`
|
|
2564
2615
|
});
|
|
2565
2616
|
}
|
|
2566
2617
|
return a;
|
|
2567
2618
|
}
|
|
2568
|
-
},
|
|
2619
|
+
}, ha = {
|
|
2569
2620
|
id: "aria-valid-attr",
|
|
2570
2621
|
wcag: ["4.1.2"],
|
|
2571
2622
|
level: "A",
|
|
@@ -2573,9 +2624,9 @@ const Zt = {
|
|
|
2573
2624
|
guidance: "Misspelled ARIA attributes are ignored by assistive technologies. Check the spelling against the WAI-ARIA specification. Common mistakes: aria-labeledby (should be aria-labelledby), aria-role (should be role), aria-description (valid in ARIA 1.3+).",
|
|
2574
2625
|
prompt: "Identify the misspelled attribute and provide the correct spelling.",
|
|
2575
2626
|
run(t) {
|
|
2576
|
-
return
|
|
2627
|
+
return U(t).validAttr;
|
|
2577
2628
|
}
|
|
2578
|
-
},
|
|
2629
|
+
}, pa = {
|
|
2579
2630
|
id: "aria-valid-attr-value",
|
|
2580
2631
|
wcag: ["4.1.2"],
|
|
2581
2632
|
level: "A",
|
|
@@ -2583,9 +2634,9 @@ const Zt = {
|
|
|
2583
2634
|
guidance: "Each ARIA attribute accepts specific value types. Boolean attributes (aria-hidden, aria-disabled) accept only 'true' or 'false'. Tristate attributes (aria-checked, aria-pressed) also accept 'mixed'. Token attributes (aria-live, aria-autocomplete) accept predefined values. ID reference attributes (aria-labelledby, aria-describedby) must reference existing element IDs.",
|
|
2584
2635
|
prompt: "Show the invalid value and list the valid values for this specific attribute.",
|
|
2585
2636
|
run(t) {
|
|
2586
|
-
return
|
|
2637
|
+
return U(t).validAttrValue;
|
|
2587
2638
|
}
|
|
2588
|
-
},
|
|
2639
|
+
}, ga = {
|
|
2589
2640
|
checkbox: ["aria-checked"],
|
|
2590
2641
|
combobox: ["aria-expanded"],
|
|
2591
2642
|
heading: ["aria-level"],
|
|
@@ -2599,7 +2650,7 @@ const Zt = {
|
|
|
2599
2650
|
slider: ["aria-valuenow"],
|
|
2600
2651
|
spinbutton: ["aria-valuenow"],
|
|
2601
2652
|
switch: ["aria-checked"]
|
|
2602
|
-
},
|
|
2653
|
+
}, ba = {
|
|
2603
2654
|
id: "aria-required-attr",
|
|
2604
2655
|
wcag: ["4.1.2"],
|
|
2605
2656
|
level: "A",
|
|
@@ -2609,8 +2660,8 @@ const Zt = {
|
|
|
2609
2660
|
run(t) {
|
|
2610
2661
|
const a = [];
|
|
2611
2662
|
for (const e of t.querySelectorAll("[role]")) {
|
|
2612
|
-
if (
|
|
2613
|
-
const i = e.getAttribute("role").trim().toLowerCase(), n =
|
|
2663
|
+
if (g(e) || e instanceof HTMLElement && e.style.display === "none") continue;
|
|
2664
|
+
const i = e.getAttribute("role").trim().toLowerCase(), n = ga[i];
|
|
2614
2665
|
if (n && !(i === "checkbox" && e instanceof HTMLInputElement && e.type === "checkbox") && !(i === "radio" && e instanceof HTMLInputElement && e.type === "radio") && !(i === "option" && e instanceof HTMLOptionElement) && !(i === "heading" && /^h[1-6]$/i.test(e.tagName))) {
|
|
2615
2666
|
if (i === "separator") {
|
|
2616
2667
|
const r = e.getAttribute("tabindex");
|
|
@@ -2622,7 +2673,7 @@ const Zt = {
|
|
|
2622
2673
|
a.push({
|
|
2623
2674
|
ruleId: "aria-required-attr",
|
|
2624
2675
|
selector: m(e),
|
|
2625
|
-
html:
|
|
2676
|
+
html: d(e),
|
|
2626
2677
|
impact: "critical",
|
|
2627
2678
|
message: `Role "${i}" requires attribute "${r}".`
|
|
2628
2679
|
});
|
|
@@ -2634,7 +2685,7 @@ const Zt = {
|
|
|
2634
2685
|
return a;
|
|
2635
2686
|
}
|
|
2636
2687
|
};
|
|
2637
|
-
function
|
|
2688
|
+
function fa(t) {
|
|
2638
2689
|
var r, o, s;
|
|
2639
2690
|
const a = [], e = t.className;
|
|
2640
2691
|
e && typeof e == "string" && e.trim() && a.push(`Classes: ${e.trim().slice(0, 100)}`);
|
|
@@ -2651,7 +2702,7 @@ function pa(t) {
|
|
|
2651
2702
|
return a.length > 0 ? a.join(`
|
|
2652
2703
|
`) : void 0;
|
|
2653
2704
|
}
|
|
2654
|
-
const
|
|
2705
|
+
const va = {
|
|
2655
2706
|
id: "button-name",
|
|
2656
2707
|
wcag: ["4.1.2"],
|
|
2657
2708
|
level: "A",
|
|
@@ -2661,21 +2712,21 @@ const ga = {
|
|
|
2661
2712
|
run(t) {
|
|
2662
2713
|
const a = [];
|
|
2663
2714
|
for (const e of t.querySelectorAll('button, [role="button"]')) {
|
|
2664
|
-
if (
|
|
2715
|
+
if (g(e) || T(e)) continue;
|
|
2665
2716
|
const i = e.getAttribute("role");
|
|
2666
2717
|
if ((i === "none" || i === "presentation") && !(e.matches('button:not([disabled]), [tabindex]:not([tabindex="-1"])') || e.tagName.toLowerCase() === "button" && !e.disabled) || e.getRootNode() instanceof ShadowRoot) continue;
|
|
2667
2718
|
v(e) || a.push({
|
|
2668
2719
|
ruleId: "button-name",
|
|
2669
2720
|
selector: m(e),
|
|
2670
|
-
html:
|
|
2721
|
+
html: d(e),
|
|
2671
2722
|
impact: "critical",
|
|
2672
2723
|
message: "Button has no discernible text.",
|
|
2673
|
-
context:
|
|
2724
|
+
context: fa(e)
|
|
2674
2725
|
});
|
|
2675
2726
|
}
|
|
2676
2727
|
return a;
|
|
2677
2728
|
}
|
|
2678
|
-
},
|
|
2729
|
+
}, ya = {
|
|
2679
2730
|
alert: /* @__PURE__ */ new Set(["aria-atomic", "aria-busy", "aria-live", "aria-relevant"]),
|
|
2680
2731
|
alertdialog: /* @__PURE__ */ new Set(["aria-describedby", "aria-modal"]),
|
|
2681
2732
|
application: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-expanded", "aria-haspopup", "aria-invalid"]),
|
|
@@ -2747,7 +2798,7 @@ const ga = {
|
|
|
2747
2798
|
tree: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-required"]),
|
|
2748
2799
|
treegrid: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-colcount", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-readonly", "aria-required", "aria-rowcount"]),
|
|
2749
2800
|
treeitem: /* @__PURE__ */ new Set(["aria-checked", "aria-disabled", "aria-expanded", "aria-haspopup", "aria-level", "aria-posinset", "aria-selected", "aria-setsize"])
|
|
2750
|
-
},
|
|
2801
|
+
}, wa = /* @__PURE__ */ new Set([
|
|
2751
2802
|
"aria-atomic",
|
|
2752
2803
|
"aria-busy",
|
|
2753
2804
|
"aria-controls",
|
|
@@ -2771,7 +2822,7 @@ const ga = {
|
|
|
2771
2822
|
"aria-roledescription",
|
|
2772
2823
|
"aria-braillelabel",
|
|
2773
2824
|
"aria-brailleroledescription"
|
|
2774
|
-
]),
|
|
2825
|
+
]), Aa = {
|
|
2775
2826
|
id: "aria-allowed-attr",
|
|
2776
2827
|
wcag: ["4.1.2"],
|
|
2777
2828
|
level: "A",
|
|
@@ -2781,18 +2832,18 @@ const ga = {
|
|
|
2781
2832
|
run(t) {
|
|
2782
2833
|
const a = [];
|
|
2783
2834
|
for (const e of t.querySelectorAll("[role], [aria-*]")) {
|
|
2784
|
-
if (
|
|
2785
|
-
const i =
|
|
2835
|
+
if (g(e)) continue;
|
|
2836
|
+
const i = q(e);
|
|
2786
2837
|
if (!i) continue;
|
|
2787
|
-
const n =
|
|
2838
|
+
const n = ya[i];
|
|
2788
2839
|
if (n)
|
|
2789
2840
|
for (const r of e.attributes) {
|
|
2790
|
-
if (!r.name.startsWith("aria-") ||
|
|
2841
|
+
if (!r.name.startsWith("aria-") || wa.has(r.name) || n.has(r.name)) continue;
|
|
2791
2842
|
const o = n.size > 0 ? [...n].join(", ") : "none (only global ARIA attributes)";
|
|
2792
2843
|
a.push({
|
|
2793
2844
|
ruleId: "aria-allowed-attr",
|
|
2794
2845
|
selector: m(e),
|
|
2795
|
-
html:
|
|
2846
|
+
html: d(e),
|
|
2796
2847
|
impact: "critical",
|
|
2797
2848
|
message: `ARIA attribute "${r.name}" is not allowed on role "${i}".`,
|
|
2798
2849
|
context: `Attribute: ${r.name}="${r.value}", role: ${i}, allowed role-specific attributes: ${o}`
|
|
@@ -2801,7 +2852,7 @@ const ga = {
|
|
|
2801
2852
|
}
|
|
2802
2853
|
return a;
|
|
2803
2854
|
}
|
|
2804
|
-
},
|
|
2855
|
+
}, xa = /* @__PURE__ */ new Set([
|
|
2805
2856
|
"base",
|
|
2806
2857
|
"col",
|
|
2807
2858
|
"colgroup",
|
|
@@ -2816,7 +2867,7 @@ const ga = {
|
|
|
2816
2867
|
"template",
|
|
2817
2868
|
"title",
|
|
2818
2869
|
"track"
|
|
2819
|
-
]),
|
|
2870
|
+
]), E = {
|
|
2820
2871
|
a: /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem", "link"]),
|
|
2821
2872
|
"a[href]": /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem"]),
|
|
2822
2873
|
abbr: "any",
|
|
@@ -2923,22 +2974,22 @@ const ga = {
|
|
|
2923
2974
|
video: /* @__PURE__ */ new Set(["application"]),
|
|
2924
2975
|
wbr: /* @__PURE__ */ new Set(["none", "presentation"])
|
|
2925
2976
|
};
|
|
2926
|
-
function
|
|
2977
|
+
function Sa(t) {
|
|
2927
2978
|
var e;
|
|
2928
2979
|
const a = t.tagName.toLowerCase();
|
|
2929
|
-
if (
|
|
2980
|
+
if (xa.has(a))
|
|
2930
2981
|
return "none";
|
|
2931
2982
|
if (a === "a" && t.hasAttribute("href"))
|
|
2932
|
-
return
|
|
2983
|
+
return E["a[href]"];
|
|
2933
2984
|
if (a === "img" && t.getAttribute("alt") === "")
|
|
2934
|
-
return
|
|
2985
|
+
return E["img[alt='']"];
|
|
2935
2986
|
if (a === "input") {
|
|
2936
2987
|
const n = `input[type=${((e = t.getAttribute("type")) == null ? void 0 : e.toLowerCase()) || "text"}]`;
|
|
2937
|
-
return n in
|
|
2988
|
+
return n in E ? E[n] : "none";
|
|
2938
2989
|
}
|
|
2939
|
-
return
|
|
2990
|
+
return E[a] || "any";
|
|
2940
2991
|
}
|
|
2941
|
-
const
|
|
2992
|
+
const ka = {
|
|
2942
2993
|
id: "aria-allowed-role",
|
|
2943
2994
|
wcag: ["4.1.2"],
|
|
2944
2995
|
level: "A",
|
|
@@ -2949,29 +3000,29 @@ const Aa = {
|
|
|
2949
3000
|
var e;
|
|
2950
3001
|
const a = [];
|
|
2951
3002
|
for (const i of t.querySelectorAll("[role]")) {
|
|
2952
|
-
if (
|
|
3003
|
+
if (g(i)) continue;
|
|
2953
3004
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
2954
3005
|
if (!n) continue;
|
|
2955
|
-
const r =
|
|
3006
|
+
const r = de(i);
|
|
2956
3007
|
if (r && n === r) continue;
|
|
2957
|
-
const o =
|
|
3008
|
+
const o = Sa(i);
|
|
2958
3009
|
o === "none" ? a.push({
|
|
2959
3010
|
ruleId: "aria-allowed-role",
|
|
2960
3011
|
selector: m(i),
|
|
2961
|
-
html:
|
|
3012
|
+
html: d(i),
|
|
2962
3013
|
impact: "minor",
|
|
2963
3014
|
message: `Element <${i.tagName.toLowerCase()}> should not have an explicit role.`
|
|
2964
3015
|
}) : o !== "any" && !o.has(n) && a.push({
|
|
2965
3016
|
ruleId: "aria-allowed-role",
|
|
2966
3017
|
selector: m(i),
|
|
2967
|
-
html:
|
|
3018
|
+
html: d(i),
|
|
2968
3019
|
impact: "minor",
|
|
2969
3020
|
message: `Role "${n}" is not allowed on element <${i.tagName.toLowerCase()}>.`
|
|
2970
3021
|
});
|
|
2971
3022
|
}
|
|
2972
3023
|
return a;
|
|
2973
3024
|
}
|
|
2974
|
-
},
|
|
3025
|
+
}, ie = {
|
|
2975
3026
|
// Each array is an OR group - at least one of each inner array must be present
|
|
2976
3027
|
combobox: [["listbox", "tree", "grid", "dialog", "textbox"]],
|
|
2977
3028
|
// Must own/contain one of these
|
|
@@ -2988,7 +3039,7 @@ const Aa = {
|
|
|
2988
3039
|
tablist: [["tab"]],
|
|
2989
3040
|
tree: [["treeitem", "group"]],
|
|
2990
3041
|
treegrid: [["row", "rowgroup"]]
|
|
2991
|
-
},
|
|
3042
|
+
}, ne = {
|
|
2992
3043
|
caption: ["figure", "table", "grid", "treegrid"],
|
|
2993
3044
|
// cell/gridcell/columnheader/rowheader must be in a row
|
|
2994
3045
|
// but we skip checking native td/th since they're handled by HTML semantics
|
|
@@ -3002,27 +3053,27 @@ const Aa = {
|
|
|
3002
3053
|
tab: ["tablist"],
|
|
3003
3054
|
treeitem: ["tree", "group"]
|
|
3004
3055
|
};
|
|
3005
|
-
function
|
|
3056
|
+
function Ia(t, a) {
|
|
3006
3057
|
var r;
|
|
3007
3058
|
const e = ((r = t.getAttribute("aria-owns")) == null ? void 0 : r.split(/\s+/)) || [], i = t.ownerDocument, n = /* @__PURE__ */ new Set();
|
|
3008
3059
|
for (const o of t.querySelectorAll("*")) {
|
|
3009
|
-
const s =
|
|
3010
|
-
s && !
|
|
3060
|
+
const s = q(o);
|
|
3061
|
+
s && !g(o) && n.add(s);
|
|
3011
3062
|
}
|
|
3012
3063
|
for (const o of e) {
|
|
3013
3064
|
const s = i.getElementById(o);
|
|
3014
3065
|
if (s) {
|
|
3015
|
-
const l =
|
|
3016
|
-
l && !
|
|
3066
|
+
const l = q(s);
|
|
3067
|
+
l && !g(s) && n.add(l);
|
|
3017
3068
|
}
|
|
3018
3069
|
}
|
|
3019
3070
|
for (const o of a)
|
|
3020
3071
|
if (!o.some((l) => n.has(l))) return !1;
|
|
3021
3072
|
return !0;
|
|
3022
3073
|
}
|
|
3023
|
-
const
|
|
3074
|
+
const Ta = {
|
|
3024
3075
|
id: "aria-required-children",
|
|
3025
|
-
wcag: ["
|
|
3076
|
+
wcag: ["1.3.1"],
|
|
3026
3077
|
level: "A",
|
|
3027
3078
|
description: "Certain ARIA roles require specific child roles to be present.",
|
|
3028
3079
|
guidance: "Some ARIA roles represent containers that must contain specific child roles for proper semantics. For example, a list must contain listitems, a menu must contain menuitems. Add the required child elements with appropriate roles, or use native HTML elements that provide these semantics implicitly (e.g., <ul> with <li>).",
|
|
@@ -3031,16 +3082,16 @@ const Sa = {
|
|
|
3031
3082
|
var e;
|
|
3032
3083
|
const a = [];
|
|
3033
3084
|
for (const i of t.querySelectorAll("[role]")) {
|
|
3034
|
-
if (
|
|
3085
|
+
if (g(i)) continue;
|
|
3035
3086
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
3036
|
-
if (!n || !(n in
|
|
3037
|
-
const r =
|
|
3038
|
-
if (!
|
|
3087
|
+
if (!n || !(n in ie)) continue;
|
|
3088
|
+
const r = ie[n];
|
|
3089
|
+
if (!Ia(i, r)) {
|
|
3039
3090
|
const o = r.map((s) => s.join(" or ")).join(", ");
|
|
3040
3091
|
a.push({
|
|
3041
3092
|
ruleId: "aria-required-children",
|
|
3042
3093
|
selector: m(i),
|
|
3043
|
-
html:
|
|
3094
|
+
html: d(i),
|
|
3044
3095
|
impact: "critical",
|
|
3045
3096
|
message: `Role "${n}" requires children with role: ${o}.`
|
|
3046
3097
|
});
|
|
@@ -3048,9 +3099,9 @@ const Sa = {
|
|
|
3048
3099
|
}
|
|
3049
3100
|
return a;
|
|
3050
3101
|
}
|
|
3051
|
-
},
|
|
3102
|
+
}, Ea = {
|
|
3052
3103
|
id: "aria-required-parent",
|
|
3053
|
-
wcag: ["
|
|
3104
|
+
wcag: ["1.3.1"],
|
|
3054
3105
|
level: "A",
|
|
3055
3106
|
description: "Certain ARIA roles must be contained within specific parent roles.",
|
|
3056
3107
|
guidance: "Some ARIA roles represent items that must exist within specific container roles. For example, a listitem must be within a list, a tab must be within a tablist. Wrap the element in the appropriate parent, or use native HTML elements that provide this structure (e.g., <li> inside <ul>).",
|
|
@@ -3059,13 +3110,13 @@ const Sa = {
|
|
|
3059
3110
|
var e;
|
|
3060
3111
|
const a = [];
|
|
3061
3112
|
for (const i of t.querySelectorAll("[role]")) {
|
|
3062
|
-
if (
|
|
3113
|
+
if (g(i)) continue;
|
|
3063
3114
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
3064
|
-
if (!n || !(n in
|
|
3065
|
-
const r =
|
|
3115
|
+
if (!n || !(n in ne)) continue;
|
|
3116
|
+
const r = ne[n];
|
|
3066
3117
|
let o = i.parentElement, s = !1;
|
|
3067
3118
|
for (; o && o !== t.documentElement; ) {
|
|
3068
|
-
const l =
|
|
3119
|
+
const l = q(o);
|
|
3069
3120
|
if (l && r.includes(l)) {
|
|
3070
3121
|
s = !0;
|
|
3071
3122
|
break;
|
|
@@ -3075,14 +3126,14 @@ const Sa = {
|
|
|
3075
3126
|
s || a.push({
|
|
3076
3127
|
ruleId: "aria-required-parent",
|
|
3077
3128
|
selector: m(i),
|
|
3078
|
-
html:
|
|
3129
|
+
html: d(i),
|
|
3079
3130
|
impact: "critical",
|
|
3080
3131
|
message: `Role "${n}" must be contained within: ${r.join(", ")}.`
|
|
3081
3132
|
});
|
|
3082
3133
|
}
|
|
3083
3134
|
return a;
|
|
3084
3135
|
}
|
|
3085
|
-
},
|
|
3136
|
+
}, re = [
|
|
3086
3137
|
"a[href]",
|
|
3087
3138
|
"button:not([disabled])",
|
|
3088
3139
|
'input:not([disabled]):not([type="hidden"])',
|
|
@@ -3098,7 +3149,7 @@ const Sa = {
|
|
|
3098
3149
|
"embed",
|
|
3099
3150
|
"area[href]"
|
|
3100
3151
|
].join(", ");
|
|
3101
|
-
function
|
|
3152
|
+
function Ca(t) {
|
|
3102
3153
|
let a = t;
|
|
3103
3154
|
const e = t.ownerDocument, i = e.defaultView;
|
|
3104
3155
|
for (; a && a !== e.body; ) {
|
|
@@ -3111,7 +3162,7 @@ function Ia(t) {
|
|
|
3111
3162
|
}
|
|
3112
3163
|
return !0;
|
|
3113
3164
|
}
|
|
3114
|
-
const
|
|
3165
|
+
const La = {
|
|
3115
3166
|
id: "aria-hidden-body",
|
|
3116
3167
|
selector: 'body[aria-hidden="true"]',
|
|
3117
3168
|
check: { type: "selector-exists" },
|
|
@@ -3123,7 +3174,7 @@ const Ta = {
|
|
|
3123
3174
|
guidance: "Setting aria-hidden='true' on the body element hides all page content from assistive technologies, making the page completely inaccessible to screen reader users. Remove aria-hidden from the body element. If you need to hide content temporarily (e.g., behind a modal), use aria-hidden on specific sections instead.",
|
|
3124
3175
|
prompt: "Instruct to remove aria-hidden='true' from the body element.",
|
|
3125
3176
|
skipAriaHidden: !1
|
|
3126
|
-
},
|
|
3177
|
+
}, qa = k(La), Ra = {
|
|
3127
3178
|
id: "aria-hidden-focus",
|
|
3128
3179
|
wcag: ["4.1.2"],
|
|
3129
3180
|
level: "A",
|
|
@@ -3134,12 +3185,12 @@ const Ta = {
|
|
|
3134
3185
|
const a = [];
|
|
3135
3186
|
for (const e of t.querySelectorAll('[aria-hidden="true"]')) {
|
|
3136
3187
|
if (e === t.body) continue;
|
|
3137
|
-
const i = [...e.querySelectorAll(
|
|
3138
|
-
e.matches(
|
|
3188
|
+
const i = [...e.querySelectorAll(re)];
|
|
3189
|
+
e.matches(re) && i.push(e);
|
|
3139
3190
|
for (const n of i)
|
|
3140
3191
|
if (n instanceof HTMLElement) {
|
|
3141
3192
|
const r = n.getAttribute("tabindex");
|
|
3142
|
-
if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !
|
|
3193
|
+
if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ca(n)) continue;
|
|
3143
3194
|
const o = n.tagName.toLowerCase();
|
|
3144
3195
|
let s;
|
|
3145
3196
|
r !== null ? s = `has tabindex="${r}"` : o === "a" && n.hasAttribute("href") ? s = "is a link with href" : o === "button" ? s = "is a <button>" : o === "input" ? s = `is an <input type="${n.type}">` : o === "select" ? s = "is a <select>" : o === "textarea" ? s = "is a <textarea>" : o === "iframe" ? s = "is an <iframe>" : s = `is a natively focusable <${o}>`;
|
|
@@ -3147,16 +3198,16 @@ const Ta = {
|
|
|
3147
3198
|
a.push({
|
|
3148
3199
|
ruleId: "aria-hidden-focus",
|
|
3149
3200
|
selector: m(n),
|
|
3150
|
-
html:
|
|
3201
|
+
html: d(n),
|
|
3151
3202
|
impact: "serious",
|
|
3152
3203
|
message: "Focusable element is inside an aria-hidden region.",
|
|
3153
|
-
context: `Focusable because: ${s}. aria-hidden ancestor: ${l ?
|
|
3204
|
+
context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? d(l) : "unknown"}`
|
|
3154
3205
|
});
|
|
3155
3206
|
}
|
|
3156
3207
|
}
|
|
3157
3208
|
return a;
|
|
3158
3209
|
}
|
|
3159
|
-
},
|
|
3210
|
+
}, Na = {
|
|
3160
3211
|
id: "aria-command-name",
|
|
3161
3212
|
wcag: ["4.1.2"],
|
|
3162
3213
|
level: "A",
|
|
@@ -3167,14 +3218,14 @@ const Ta = {
|
|
|
3167
3218
|
var e;
|
|
3168
3219
|
const a = [];
|
|
3169
3220
|
for (const i of t.querySelectorAll('[role="button"], [role="link"], [role="menuitem"]')) {
|
|
3170
|
-
if (
|
|
3221
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
|
|
3171
3222
|
if (!v(i)) {
|
|
3172
3223
|
const r = i.querySelector("img[alt]");
|
|
3173
3224
|
if ((e = r == null ? void 0 : r.getAttribute("alt")) != null && e.trim()) continue;
|
|
3174
3225
|
a.push({
|
|
3175
3226
|
ruleId: "aria-command-name",
|
|
3176
3227
|
selector: m(i),
|
|
3177
|
-
html:
|
|
3228
|
+
html: d(i),
|
|
3178
3229
|
impact: "serious",
|
|
3179
3230
|
message: "ARIA command has no accessible name."
|
|
3180
3231
|
});
|
|
@@ -3182,7 +3233,7 @@ const Ta = {
|
|
|
3182
3233
|
}
|
|
3183
3234
|
return a;
|
|
3184
3235
|
}
|
|
3185
|
-
},
|
|
3236
|
+
}, $a = {
|
|
3186
3237
|
id: "aria-input-field-name",
|
|
3187
3238
|
wcag: ["4.1.2"],
|
|
3188
3239
|
level: "A",
|
|
@@ -3192,18 +3243,18 @@ const Ta = {
|
|
|
3192
3243
|
run(t) {
|
|
3193
3244
|
const a = [], e = '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]';
|
|
3194
3245
|
for (const i of t.querySelectorAll(e)) {
|
|
3195
|
-
if (
|
|
3246
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches("input, select, textarea")) continue;
|
|
3196
3247
|
v(i) || a.push({
|
|
3197
3248
|
ruleId: "aria-input-field-name",
|
|
3198
3249
|
selector: m(i),
|
|
3199
|
-
html:
|
|
3250
|
+
html: d(i),
|
|
3200
3251
|
impact: "serious",
|
|
3201
3252
|
message: "ARIA input field has no accessible name."
|
|
3202
3253
|
});
|
|
3203
3254
|
}
|
|
3204
3255
|
return a;
|
|
3205
3256
|
}
|
|
3206
|
-
},
|
|
3257
|
+
}, Ma = {
|
|
3207
3258
|
id: "aria-toggle-field-name",
|
|
3208
3259
|
wcag: ["4.1.2"],
|
|
3209
3260
|
level: "A",
|
|
@@ -3213,18 +3264,18 @@ const Ta = {
|
|
|
3213
3264
|
run(t) {
|
|
3214
3265
|
const a = [], e = '[role="checkbox"], [role="switch"], [role="radio"], [role="menuitemcheckbox"], [role="menuitemradio"]';
|
|
3215
3266
|
for (const i of t.querySelectorAll(e)) {
|
|
3216
|
-
if (
|
|
3267
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
|
|
3217
3268
|
v(i) || a.push({
|
|
3218
3269
|
ruleId: "aria-toggle-field-name",
|
|
3219
3270
|
selector: m(i),
|
|
3220
|
-
html:
|
|
3271
|
+
html: d(i),
|
|
3221
3272
|
impact: "serious",
|
|
3222
3273
|
message: "ARIA toggle field has no accessible name."
|
|
3223
3274
|
});
|
|
3224
3275
|
}
|
|
3225
3276
|
return a;
|
|
3226
3277
|
}
|
|
3227
|
-
},
|
|
3278
|
+
}, Ha = {
|
|
3228
3279
|
id: "aria-meter-name",
|
|
3229
3280
|
wcag: ["4.1.2"],
|
|
3230
3281
|
level: "A",
|
|
@@ -3234,18 +3285,18 @@ const Ta = {
|
|
|
3234
3285
|
run(t) {
|
|
3235
3286
|
const a = [];
|
|
3236
3287
|
for (const e of t.querySelectorAll('[role="meter"], meter')) {
|
|
3237
|
-
if (
|
|
3288
|
+
if (g(e)) continue;
|
|
3238
3289
|
v(e) || a.push({
|
|
3239
3290
|
ruleId: "aria-meter-name",
|
|
3240
3291
|
selector: m(e),
|
|
3241
|
-
html:
|
|
3292
|
+
html: d(e),
|
|
3242
3293
|
impact: "serious",
|
|
3243
3294
|
message: "Meter has no accessible name."
|
|
3244
3295
|
});
|
|
3245
3296
|
}
|
|
3246
3297
|
return a;
|
|
3247
3298
|
}
|
|
3248
|
-
},
|
|
3299
|
+
}, Da = {
|
|
3249
3300
|
id: "aria-progressbar-name",
|
|
3250
3301
|
wcag: ["4.1.2"],
|
|
3251
3302
|
level: "A",
|
|
@@ -3255,18 +3306,18 @@ const Ta = {
|
|
|
3255
3306
|
run(t) {
|
|
3256
3307
|
const a = [];
|
|
3257
3308
|
for (const e of t.querySelectorAll('[role="progressbar"], progress')) {
|
|
3258
|
-
if (
|
|
3309
|
+
if (g(e)) continue;
|
|
3259
3310
|
v(e) || a.push({
|
|
3260
3311
|
ruleId: "aria-progressbar-name",
|
|
3261
3312
|
selector: m(e),
|
|
3262
|
-
html:
|
|
3313
|
+
html: d(e),
|
|
3263
3314
|
impact: "serious",
|
|
3264
3315
|
message: "Progressbar has no accessible name."
|
|
3265
3316
|
});
|
|
3266
3317
|
}
|
|
3267
3318
|
return a;
|
|
3268
3319
|
}
|
|
3269
|
-
},
|
|
3320
|
+
}, Oa = {
|
|
3270
3321
|
id: "aria-dialog-name",
|
|
3271
3322
|
wcag: ["4.1.2"],
|
|
3272
3323
|
level: "A",
|
|
@@ -3276,18 +3327,18 @@ const Ta = {
|
|
|
3276
3327
|
run(t) {
|
|
3277
3328
|
const a = [];
|
|
3278
3329
|
for (const e of t.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog')) {
|
|
3279
|
-
if (
|
|
3330
|
+
if (g(e)) continue;
|
|
3280
3331
|
v(e) || a.push({
|
|
3281
3332
|
ruleId: "aria-dialog-name",
|
|
3282
3333
|
selector: m(e),
|
|
3283
|
-
html:
|
|
3334
|
+
html: d(e),
|
|
3284
3335
|
impact: "serious",
|
|
3285
3336
|
message: "Dialog has no accessible name."
|
|
3286
3337
|
});
|
|
3287
3338
|
}
|
|
3288
3339
|
return a;
|
|
3289
3340
|
}
|
|
3290
|
-
},
|
|
3341
|
+
}, Ba = {
|
|
3291
3342
|
id: "aria-tooltip-name",
|
|
3292
3343
|
wcag: ["4.1.2"],
|
|
3293
3344
|
level: "A",
|
|
@@ -3297,18 +3348,18 @@ const Ta = {
|
|
|
3297
3348
|
run(t) {
|
|
3298
3349
|
const a = [];
|
|
3299
3350
|
for (const e of t.querySelectorAll('[role="tooltip"]')) {
|
|
3300
|
-
if (
|
|
3351
|
+
if (g(e)) continue;
|
|
3301
3352
|
v(e) || a.push({
|
|
3302
3353
|
ruleId: "aria-tooltip-name",
|
|
3303
3354
|
selector: m(e),
|
|
3304
|
-
html:
|
|
3355
|
+
html: d(e),
|
|
3305
3356
|
impact: "serious",
|
|
3306
3357
|
message: "Tooltip has no accessible name."
|
|
3307
3358
|
});
|
|
3308
3359
|
}
|
|
3309
3360
|
return a;
|
|
3310
3361
|
}
|
|
3311
|
-
},
|
|
3362
|
+
}, Fa = {
|
|
3312
3363
|
id: "aria-treeitem-name",
|
|
3313
3364
|
wcag: ["4.1.2"],
|
|
3314
3365
|
level: "A",
|
|
@@ -3318,18 +3369,18 @@ const Ta = {
|
|
|
3318
3369
|
run(t) {
|
|
3319
3370
|
const a = [];
|
|
3320
3371
|
for (const e of t.querySelectorAll('[role="treeitem"]')) {
|
|
3321
|
-
if (
|
|
3372
|
+
if (g(e)) continue;
|
|
3322
3373
|
v(e) || a.push({
|
|
3323
3374
|
ruleId: "aria-treeitem-name",
|
|
3324
3375
|
selector: m(e),
|
|
3325
|
-
html:
|
|
3376
|
+
html: d(e),
|
|
3326
3377
|
impact: "serious",
|
|
3327
3378
|
message: "Treeitem has no accessible name."
|
|
3328
3379
|
});
|
|
3329
3380
|
}
|
|
3330
3381
|
return a;
|
|
3331
3382
|
}
|
|
3332
|
-
},
|
|
3383
|
+
}, Wa = {
|
|
3333
3384
|
id: "aria-prohibited-attr",
|
|
3334
3385
|
wcag: ["4.1.2"],
|
|
3335
3386
|
level: "A",
|
|
@@ -3337,16 +3388,16 @@ const Ta = {
|
|
|
3337
3388
|
guidance: "Some ARIA roles prohibit certain attributes. For example, roles like 'none', 'presentation', 'generic', and text-level roles (code, emphasis, strong) prohibit aria-label and aria-labelledby because naming is not supported for these roles. Remove the prohibited attributes or change the role.",
|
|
3338
3389
|
prompt: "Identify the prohibited attribute and recommend removing it from this element.",
|
|
3339
3390
|
run(t) {
|
|
3340
|
-
return
|
|
3391
|
+
return U(t).prohibitedAttr;
|
|
3341
3392
|
}
|
|
3342
|
-
},
|
|
3393
|
+
}, _a = [
|
|
3343
3394
|
"a[href]",
|
|
3344
3395
|
"button:not([disabled])",
|
|
3345
3396
|
'input:not([disabled]):not([type="hidden"])',
|
|
3346
3397
|
"select:not([disabled])",
|
|
3347
3398
|
"textarea:not([disabled])",
|
|
3348
3399
|
'[tabindex]:not([tabindex="-1"])'
|
|
3349
|
-
].join(", "),
|
|
3400
|
+
].join(", "), Pa = [
|
|
3350
3401
|
"aria-atomic",
|
|
3351
3402
|
"aria-busy",
|
|
3352
3403
|
"aria-controls",
|
|
@@ -3361,17 +3412,17 @@ const Ta = {
|
|
|
3361
3412
|
"aria-owns",
|
|
3362
3413
|
"aria-relevant"
|
|
3363
3414
|
];
|
|
3364
|
-
function
|
|
3415
|
+
function oe(t) {
|
|
3365
3416
|
const a = [];
|
|
3366
|
-
t.matches(
|
|
3367
|
-
for (const e of
|
|
3417
|
+
t.matches(_a) && a.push("element is focusable");
|
|
3418
|
+
for (const e of Pa)
|
|
3368
3419
|
if (t.hasAttribute(e)) {
|
|
3369
3420
|
a.push(`has ${e}`);
|
|
3370
3421
|
break;
|
|
3371
3422
|
}
|
|
3372
3423
|
return (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && a.push("has accessible name"), a;
|
|
3373
3424
|
}
|
|
3374
|
-
const
|
|
3425
|
+
const ja = {
|
|
3375
3426
|
id: "presentation-role-conflict",
|
|
3376
3427
|
wcag: ["4.1.2"],
|
|
3377
3428
|
level: "A",
|
|
@@ -3381,30 +3432,30 @@ const Wa = {
|
|
|
3381
3432
|
run(t) {
|
|
3382
3433
|
const a = [];
|
|
3383
3434
|
for (const e of t.querySelectorAll('[role="presentation"], [role="none"]')) {
|
|
3384
|
-
if (
|
|
3385
|
-
const i =
|
|
3435
|
+
if (g(e)) continue;
|
|
3436
|
+
const i = oe(e);
|
|
3386
3437
|
i.length > 0 && a.push({
|
|
3387
3438
|
ruleId: "presentation-role-conflict",
|
|
3388
3439
|
selector: m(e),
|
|
3389
|
-
html:
|
|
3440
|
+
html: d(e),
|
|
3390
3441
|
impact: "serious",
|
|
3391
3442
|
message: `Presentation role conflicts with: ${i.join(", ")}. The role will be ignored.`
|
|
3392
3443
|
});
|
|
3393
3444
|
}
|
|
3394
3445
|
for (const e of t.querySelectorAll('img[alt=""]')) {
|
|
3395
|
-
if (
|
|
3396
|
-
const i =
|
|
3446
|
+
if (g(e) || e.hasAttribute("role")) continue;
|
|
3447
|
+
const i = oe(e);
|
|
3397
3448
|
i.length > 0 && a.push({
|
|
3398
3449
|
ruleId: "presentation-role-conflict",
|
|
3399
3450
|
selector: m(e),
|
|
3400
|
-
html:
|
|
3451
|
+
html: d(e),
|
|
3401
3452
|
impact: "serious",
|
|
3402
3453
|
message: `Element with implicit presentation role (alt="") conflicts with: ${i.join(", ")}. The decorative role will be ignored.`
|
|
3403
3454
|
});
|
|
3404
3455
|
}
|
|
3405
3456
|
return a;
|
|
3406
3457
|
}
|
|
3407
|
-
},
|
|
3458
|
+
}, Va = {
|
|
3408
3459
|
id: "summary-name",
|
|
3409
3460
|
wcag: ["4.1.2"],
|
|
3410
3461
|
level: "A",
|
|
@@ -3414,11 +3465,11 @@ const Wa = {
|
|
|
3414
3465
|
run(t) {
|
|
3415
3466
|
const a = [];
|
|
3416
3467
|
for (const e of t.querySelectorAll("details > summary:first-of-type")) {
|
|
3417
|
-
if (
|
|
3468
|
+
if (g(e)) continue;
|
|
3418
3469
|
v(e) || a.push({
|
|
3419
3470
|
ruleId: "summary-name",
|
|
3420
3471
|
selector: m(e),
|
|
3421
|
-
html:
|
|
3472
|
+
html: d(e),
|
|
3422
3473
|
impact: "serious",
|
|
3423
3474
|
message: "<summary> element has no accessible name. Add descriptive text."
|
|
3424
3475
|
});
|
|
@@ -3426,7 +3477,7 @@ const Wa = {
|
|
|
3426
3477
|
return a;
|
|
3427
3478
|
}
|
|
3428
3479
|
};
|
|
3429
|
-
function
|
|
3480
|
+
function za(t) {
|
|
3430
3481
|
var n, r;
|
|
3431
3482
|
const a = [], e = t.getAttribute("href");
|
|
3432
3483
|
e && a.push(`href: ${e}`);
|
|
@@ -3443,7 +3494,7 @@ function Pa(t) {
|
|
|
3443
3494
|
return a.length > 0 ? a.join(`
|
|
3444
3495
|
`) : void 0;
|
|
3445
3496
|
}
|
|
3446
|
-
const
|
|
3497
|
+
const Ua = {
|
|
3447
3498
|
id: "link-name",
|
|
3448
3499
|
wcag: ["2.4.4", "4.1.2"],
|
|
3449
3500
|
level: "A",
|
|
@@ -3453,19 +3504,19 @@ const ja = {
|
|
|
3453
3504
|
run(t) {
|
|
3454
3505
|
const a = [];
|
|
3455
3506
|
for (const e of t.querySelectorAll('a[href], area[href], [role="link"]')) {
|
|
3456
|
-
if (
|
|
3507
|
+
if (g(e) || T(e) || e.getRootNode() instanceof ShadowRoot) continue;
|
|
3457
3508
|
v(e) || a.push({
|
|
3458
3509
|
ruleId: "link-name",
|
|
3459
3510
|
selector: m(e),
|
|
3460
|
-
html:
|
|
3511
|
+
html: d(e),
|
|
3461
3512
|
impact: "serious",
|
|
3462
3513
|
message: "Link has no discernible text.",
|
|
3463
|
-
context:
|
|
3514
|
+
context: za(e)
|
|
3464
3515
|
});
|
|
3465
3516
|
}
|
|
3466
3517
|
return a;
|
|
3467
3518
|
}
|
|
3468
|
-
},
|
|
3519
|
+
}, Ga = {
|
|
3469
3520
|
id: "skip-link",
|
|
3470
3521
|
wcag: ["2.4.1"],
|
|
3471
3522
|
level: "A",
|
|
@@ -3478,20 +3529,20 @@ const ja = {
|
|
|
3478
3529
|
for (const i of e) {
|
|
3479
3530
|
const n = i.getAttribute("href");
|
|
3480
3531
|
if (!n || n === "#") continue;
|
|
3481
|
-
const r =
|
|
3532
|
+
const r = A(i).toLowerCase();
|
|
3482
3533
|
if (!(r.includes("skip") || r.includes("jump") || r.includes("main content") || r.includes("navigation"))) continue;
|
|
3483
3534
|
const s = n.slice(1);
|
|
3484
3535
|
t.getElementById(s) || a.push({
|
|
3485
3536
|
ruleId: "skip-link",
|
|
3486
3537
|
selector: m(i),
|
|
3487
|
-
html:
|
|
3538
|
+
html: d(i),
|
|
3488
3539
|
impact: "moderate",
|
|
3489
3540
|
message: `Skip link points to "#${s}" which does not exist on the page.`
|
|
3490
3541
|
});
|
|
3491
3542
|
}
|
|
3492
3543
|
return a;
|
|
3493
3544
|
}
|
|
3494
|
-
},
|
|
3545
|
+
}, Ya = /* @__PURE__ */ new Set([
|
|
3495
3546
|
"block",
|
|
3496
3547
|
"flex",
|
|
3497
3548
|
"grid",
|
|
@@ -3499,23 +3550,23 @@ const ja = {
|
|
|
3499
3550
|
"table-cell",
|
|
3500
3551
|
"list-item",
|
|
3501
3552
|
"flow-root"
|
|
3502
|
-
]),
|
|
3553
|
+
]), Xa = /* @__PURE__ */ new Set([
|
|
3503
3554
|
"inline",
|
|
3504
3555
|
"inline-block",
|
|
3505
3556
|
"inline-flex",
|
|
3506
3557
|
"inline-grid"
|
|
3507
3558
|
]);
|
|
3508
|
-
function
|
|
3559
|
+
function Ka(t) {
|
|
3509
3560
|
let a = t.parentElement;
|
|
3510
3561
|
for (; a; ) {
|
|
3511
|
-
const e =
|
|
3512
|
-
if (
|
|
3513
|
-
return
|
|
3562
|
+
const e = w(a).display;
|
|
3563
|
+
if (Ya.has(e))
|
|
3564
|
+
return Ja(a) ? a : null;
|
|
3514
3565
|
a = a.parentElement;
|
|
3515
3566
|
}
|
|
3516
3567
|
return null;
|
|
3517
3568
|
}
|
|
3518
|
-
function
|
|
3569
|
+
function Ja(t) {
|
|
3519
3570
|
const a = t.ownerDocument.createTreeWalker(
|
|
3520
3571
|
t,
|
|
3521
3572
|
NodeFilter.SHOW_TEXT
|
|
@@ -3535,7 +3586,7 @@ function Xa(t) {
|
|
|
3535
3586
|
}
|
|
3536
3587
|
return /[a-zA-Z\u00C0-\u024F]{2,}/.test(e);
|
|
3537
3588
|
}
|
|
3538
|
-
function
|
|
3589
|
+
function Qa(t, a) {
|
|
3539
3590
|
const e = t.ownerDocument.createTreeWalker(
|
|
3540
3591
|
t,
|
|
3541
3592
|
NodeFilter.SHOW_TEXT
|
|
@@ -3552,11 +3603,11 @@ function Ya(t, a) {
|
|
|
3552
3603
|
o = o.parentElement;
|
|
3553
3604
|
}
|
|
3554
3605
|
if (!r && n)
|
|
3555
|
-
return
|
|
3606
|
+
return N(w(n).color);
|
|
3556
3607
|
}
|
|
3557
3608
|
return null;
|
|
3558
3609
|
}
|
|
3559
|
-
function
|
|
3610
|
+
function Za(t, a) {
|
|
3560
3611
|
const e = t.textDecorationLine || t.textDecoration || "", i = a.textDecorationLine || a.textDecoration || "";
|
|
3561
3612
|
if ((e.includes("underline") || e.includes("line-through")) && e !== i)
|
|
3562
3613
|
return !0;
|
|
@@ -3569,19 +3620,19 @@ function Ka(t, a) {
|
|
|
3569
3620
|
const l = t.backgroundImage || "";
|
|
3570
3621
|
if (l && l !== "none" && l !== "initial")
|
|
3571
3622
|
return !0;
|
|
3572
|
-
const h =
|
|
3623
|
+
const h = se(t.fontWeight), c = se(a.fontWeight);
|
|
3573
3624
|
if (Math.abs(h - c) >= 300 || t.fontStyle !== a.fontStyle)
|
|
3574
3625
|
return !0;
|
|
3575
|
-
const
|
|
3576
|
-
return
|
|
3626
|
+
const u = parseFloat(t.fontSize) || 16, p = parseFloat(a.fontSize) || 16;
|
|
3627
|
+
return p > 0 && u / p >= 1.2;
|
|
3577
3628
|
}
|
|
3578
|
-
function
|
|
3629
|
+
function se(t) {
|
|
3579
3630
|
return t === "bold" ? 700 : t === "normal" ? 400 : parseInt(t) || 400;
|
|
3580
3631
|
}
|
|
3581
|
-
function
|
|
3632
|
+
function le(t, a, e) {
|
|
3582
3633
|
return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
3583
3634
|
}
|
|
3584
|
-
const
|
|
3635
|
+
const ei = {
|
|
3585
3636
|
id: "link-in-text-block",
|
|
3586
3637
|
wcag: ["1.4.1"],
|
|
3587
3638
|
level: "A",
|
|
@@ -3591,22 +3642,22 @@ const Ja = {
|
|
|
3591
3642
|
run(t) {
|
|
3592
3643
|
const a = [];
|
|
3593
3644
|
for (const e of t.querySelectorAll("a[href]")) {
|
|
3594
|
-
if (
|
|
3595
|
-
const i =
|
|
3596
|
-
if (!
|
|
3597
|
-
const r =
|
|
3645
|
+
if (g(e) || !A(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
|
|
3646
|
+
const i = w(e), n = i.display || "inline";
|
|
3647
|
+
if (!Xa.has(n)) continue;
|
|
3648
|
+
const r = Ka(e);
|
|
3598
3649
|
if (!r) continue;
|
|
3599
|
-
const o =
|
|
3600
|
-
if (
|
|
3601
|
-
const s =
|
|
3650
|
+
const o = w(r);
|
|
3651
|
+
if (Za(i, o)) continue;
|
|
3652
|
+
const s = N(i.color), l = Qa(r);
|
|
3602
3653
|
if (!s || !l) continue;
|
|
3603
|
-
const h =
|
|
3604
|
-
if (
|
|
3605
|
-
const
|
|
3654
|
+
const h = R(...s), c = R(...l), u = me(h, c);
|
|
3655
|
+
if (u >= 3) continue;
|
|
3656
|
+
const p = le(...s), b = le(...l), f = `link color: ${p} rgb(${s.join(", ")}), surrounding text: ${b} rgb(${l.join(", ")}), ratio: ${u.toFixed(2)}:1`;
|
|
3606
3657
|
a.push({
|
|
3607
3658
|
ruleId: "link-in-text-block",
|
|
3608
3659
|
selector: m(e),
|
|
3609
|
-
html:
|
|
3660
|
+
html: d(e),
|
|
3610
3661
|
impact: "serious",
|
|
3611
3662
|
message: "Link in text block is not visually distinguishable from surrounding text. Add an underline, border, or ensure 3:1 color contrast with surrounding text.",
|
|
3612
3663
|
context: f
|
|
@@ -3614,7 +3665,7 @@ const Ja = {
|
|
|
3614
3665
|
}
|
|
3615
3666
|
return a;
|
|
3616
3667
|
}
|
|
3617
|
-
},
|
|
3668
|
+
}, ti = {
|
|
3618
3669
|
id: "html-has-lang",
|
|
3619
3670
|
wcag: ["3.1.1"],
|
|
3620
3671
|
level: "A",
|
|
@@ -3640,7 +3691,7 @@ const Ja = {
|
|
|
3640
3691
|
return [{
|
|
3641
3692
|
ruleId: "html-has-lang",
|
|
3642
3693
|
selector: m(a),
|
|
3643
|
-
html:
|
|
3694
|
+
html: d(a),
|
|
3644
3695
|
impact: "serious",
|
|
3645
3696
|
message: "<html> element missing lang attribute.",
|
|
3646
3697
|
context: n ? `Page text sample: "${n}"` : void 0
|
|
@@ -3648,17 +3699,17 @@ const Ja = {
|
|
|
3648
3699
|
}
|
|
3649
3700
|
return [];
|
|
3650
3701
|
}
|
|
3651
|
-
},
|
|
3702
|
+
}, ai = new Set(
|
|
3652
3703
|
"aa ab ae af ak am an ar as av ay az ba be bg bh bi bm bn bo br bs ca ce ch co cr cs cu cv cy da de dv dz ee el en eo es et eu fa ff fi fj fo fr fy ga gd gl gn gu gv ha he hi ho hr ht hu hy hz ia id ie ig ii ik io is it iu ja jv ka kg ki kj kk kl km kn ko kr ks ku kv kw ky la lb lg li ln lo lt lu lv mg mh mi mk ml mn mr ms mt my na nb nd ne ng nl nn no nr nv ny oc oj om or os pa pi pl ps pt qu rm rn ro ru rw sa sc sd se sg si sk sl sm sn so sq sr ss st su sv sw ta te tg th ti tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa wo xh yi yo za zh zu".split(" ")
|
|
3653
|
-
),
|
|
3704
|
+
), ii = new Set(
|
|
3654
3705
|
"aar abk afr aka amh ara arg asm ava ave aym aze bak bam bel ben bih bis bod bos bre bul cat ces cha che chu chv cor cos cre cym dan deu div dzo ell eng epo est eus ewe fao fas fij fin fra fry ful gla gle glg glv grn guj hat hau hbs heb her hin hmo hrv hun hye ibo iii iku ile ina ind ipk isl ita jav jpn kal kan kas kat kau kaz khm kik kin kir kom kon kor kua kur lao lat lav lim lin lit ltz lub lug mah mal mar mkd mlg mlt mon mri msa mya nau nav nbl nde ndo nep nld nno nob nor nya oci oji ori orm oss pan pli pol por pus que roh ron run rus sag san sin slk slv sme smo sna snd som sot spa sqi srd srp ssw sun swa swe tah tam tat tel tgk tgl tha tir ton tsn tso tuk tur twi uig ukr urd uzb ven vie vol wln wol xho yid yor zha zho zul".split(" ")
|
|
3655
|
-
),
|
|
3656
|
-
function
|
|
3657
|
-
if (!
|
|
3706
|
+
), ni = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
|
|
3707
|
+
function pe(t) {
|
|
3708
|
+
if (!ni.test(t)) return !1;
|
|
3658
3709
|
const a = t.split("-")[0].toLowerCase();
|
|
3659
|
-
return a.length === 2 ?
|
|
3710
|
+
return a.length === 2 ? ai.has(a) : a.length === 3 ? !ii.has(a) : !1;
|
|
3660
3711
|
}
|
|
3661
|
-
const
|
|
3712
|
+
const ri = {
|
|
3662
3713
|
id: "html-lang-valid",
|
|
3663
3714
|
wcag: ["3.1.1"],
|
|
3664
3715
|
level: "A",
|
|
@@ -3668,16 +3719,16 @@ const ai = {
|
|
|
3668
3719
|
run(t) {
|
|
3669
3720
|
var e;
|
|
3670
3721
|
const a = (e = t.documentElement.getAttribute("lang")) == null ? void 0 : e.trim();
|
|
3671
|
-
return a && !
|
|
3722
|
+
return a && !pe(a) ? [{
|
|
3672
3723
|
ruleId: "html-lang-valid",
|
|
3673
3724
|
selector: "html",
|
|
3674
|
-
html:
|
|
3725
|
+
html: d(t.documentElement),
|
|
3675
3726
|
impact: "serious",
|
|
3676
3727
|
message: `Invalid lang attribute value "${a}".`
|
|
3677
3728
|
}] : [];
|
|
3678
3729
|
}
|
|
3679
3730
|
};
|
|
3680
|
-
function
|
|
3731
|
+
function ce(t) {
|
|
3681
3732
|
var i;
|
|
3682
3733
|
const a = t.ownerDocument.createTreeWalker(t, NodeFilter.SHOW_TEXT);
|
|
3683
3734
|
let e;
|
|
@@ -3709,7 +3760,7 @@ function le(t) {
|
|
|
3709
3760
|
}
|
|
3710
3761
|
return !1;
|
|
3711
3762
|
}
|
|
3712
|
-
const
|
|
3763
|
+
const oi = {
|
|
3713
3764
|
id: "valid-lang",
|
|
3714
3765
|
wcag: ["3.1.2"],
|
|
3715
3766
|
level: "AA",
|
|
@@ -3719,29 +3770,29 @@ const ii = {
|
|
|
3719
3770
|
run(t) {
|
|
3720
3771
|
const a = [];
|
|
3721
3772
|
for (const e of t.querySelectorAll("[lang]")) {
|
|
3722
|
-
if (
|
|
3773
|
+
if (g(e) || e === t.documentElement) continue;
|
|
3723
3774
|
const i = e.getAttribute("lang"), n = i == null ? void 0 : i.trim();
|
|
3724
3775
|
if (i && !n) {
|
|
3725
|
-
|
|
3776
|
+
ce(e) && a.push({
|
|
3726
3777
|
ruleId: "valid-lang",
|
|
3727
3778
|
selector: m(e),
|
|
3728
|
-
html:
|
|
3779
|
+
html: d(e),
|
|
3729
3780
|
impact: "serious",
|
|
3730
3781
|
message: "Empty lang attribute value."
|
|
3731
3782
|
});
|
|
3732
3783
|
continue;
|
|
3733
3784
|
}
|
|
3734
|
-
n &&
|
|
3785
|
+
n && ce(e) && (pe(n) || a.push({
|
|
3735
3786
|
ruleId: "valid-lang",
|
|
3736
3787
|
selector: m(e),
|
|
3737
|
-
html:
|
|
3788
|
+
html: d(e),
|
|
3738
3789
|
impact: "serious",
|
|
3739
3790
|
message: `Invalid lang attribute value "${n}".`
|
|
3740
3791
|
}));
|
|
3741
3792
|
}
|
|
3742
3793
|
return a;
|
|
3743
3794
|
}
|
|
3744
|
-
},
|
|
3795
|
+
}, si = {
|
|
3745
3796
|
id: "html-xml-lang-mismatch",
|
|
3746
3797
|
wcag: ["3.1.1"],
|
|
3747
3798
|
level: "A",
|
|
@@ -3757,14 +3808,14 @@ const ii = {
|
|
|
3757
3808
|
return [{
|
|
3758
3809
|
ruleId: "html-xml-lang-mismatch",
|
|
3759
3810
|
selector: "html",
|
|
3760
|
-
html:
|
|
3811
|
+
html: d(a),
|
|
3761
3812
|
impact: "moderate",
|
|
3762
3813
|
message: `lang="${e}" and xml:lang="${i}" do not match.`
|
|
3763
3814
|
}];
|
|
3764
3815
|
}
|
|
3765
3816
|
return [];
|
|
3766
3817
|
}
|
|
3767
|
-
},
|
|
3818
|
+
}, li = {
|
|
3768
3819
|
id: "td-headers-attr",
|
|
3769
3820
|
wcag: ["1.3.1"],
|
|
3770
3821
|
level: "A",
|
|
@@ -3774,7 +3825,7 @@ const ii = {
|
|
|
3774
3825
|
run(t) {
|
|
3775
3826
|
const a = [];
|
|
3776
3827
|
for (const e of t.querySelectorAll("td[headers]")) {
|
|
3777
|
-
if (
|
|
3828
|
+
if (g(e)) continue;
|
|
3778
3829
|
const i = e.closest("table");
|
|
3779
3830
|
if (!i) continue;
|
|
3780
3831
|
const n = e.getAttribute("id"), r = e.getAttribute("headers").split(/\s+/);
|
|
@@ -3783,7 +3834,7 @@ const ii = {
|
|
|
3783
3834
|
a.push({
|
|
3784
3835
|
ruleId: "td-headers-attr",
|
|
3785
3836
|
selector: m(e),
|
|
3786
|
-
html:
|
|
3837
|
+
html: d(e),
|
|
3787
3838
|
impact: "serious",
|
|
3788
3839
|
message: `Headers attribute references the cell itself ("${o}").`
|
|
3789
3840
|
});
|
|
@@ -3793,7 +3844,7 @@ const ii = {
|
|
|
3793
3844
|
a.push({
|
|
3794
3845
|
ruleId: "td-headers-attr",
|
|
3795
3846
|
selector: m(e),
|
|
3796
|
-
html:
|
|
3847
|
+
html: d(e),
|
|
3797
3848
|
impact: "serious",
|
|
3798
3849
|
message: `Headers attribute references non-existent ID "${o}".`
|
|
3799
3850
|
});
|
|
@@ -3803,7 +3854,7 @@ const ii = {
|
|
|
3803
3854
|
}
|
|
3804
3855
|
return a;
|
|
3805
3856
|
}
|
|
3806
|
-
},
|
|
3857
|
+
}, ci = {
|
|
3807
3858
|
id: "th-has-data-cells",
|
|
3808
3859
|
wcag: ["1.3.1"],
|
|
3809
3860
|
level: "A",
|
|
@@ -3813,19 +3864,19 @@ const ii = {
|
|
|
3813
3864
|
run(t) {
|
|
3814
3865
|
const a = [];
|
|
3815
3866
|
for (const e of t.querySelectorAll("table")) {
|
|
3816
|
-
if (
|
|
3867
|
+
if (g(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
|
|
3817
3868
|
const i = e.querySelectorAll("th"), n = e.querySelectorAll("td");
|
|
3818
3869
|
i.length > 0 && n.length === 0 && a.push({
|
|
3819
3870
|
ruleId: "th-has-data-cells",
|
|
3820
3871
|
selector: m(e),
|
|
3821
|
-
html:
|
|
3872
|
+
html: d(e),
|
|
3822
3873
|
impact: "serious",
|
|
3823
3874
|
message: "Table has header cells but no data cells."
|
|
3824
3875
|
});
|
|
3825
3876
|
}
|
|
3826
3877
|
return a;
|
|
3827
3878
|
}
|
|
3828
|
-
},
|
|
3879
|
+
}, ui = {
|
|
3829
3880
|
id: "td-has-header",
|
|
3830
3881
|
wcag: ["1.3.1"],
|
|
3831
3882
|
level: "A",
|
|
@@ -3836,24 +3887,24 @@ const ii = {
|
|
|
3836
3887
|
var e, i;
|
|
3837
3888
|
const a = [];
|
|
3838
3889
|
for (const n of t.querySelectorAll("table")) {
|
|
3839
|
-
if (
|
|
3890
|
+
if (g(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
|
|
3840
3891
|
const r = n.querySelectorAll("tr"), o = r.length;
|
|
3841
3892
|
let s = 0;
|
|
3842
|
-
for (const
|
|
3843
|
-
const
|
|
3893
|
+
for (const u of r) {
|
|
3894
|
+
const p = u.querySelectorAll("td, th");
|
|
3844
3895
|
let b = 0;
|
|
3845
|
-
for (const f of
|
|
3896
|
+
for (const f of p)
|
|
3846
3897
|
b += parseInt(f.getAttribute("colspan") || "1", 10);
|
|
3847
3898
|
s = Math.max(s, b);
|
|
3848
3899
|
}
|
|
3849
3900
|
if (o <= 3 && s <= 3) continue;
|
|
3850
3901
|
const l = n.querySelector("th") !== null, h = n.querySelector("th[scope]") !== null, c = n.querySelector("td[headers]") !== null;
|
|
3851
3902
|
if (l)
|
|
3852
|
-
for (const
|
|
3853
|
-
if (
|
|
3854
|
-
const
|
|
3855
|
-
if (!
|
|
3856
|
-
const b =
|
|
3903
|
+
for (const u of n.querySelectorAll("td")) {
|
|
3904
|
+
if (g(u) || u.hasAttribute("headers")) continue;
|
|
3905
|
+
const p = u.closest("tr");
|
|
3906
|
+
if (!p) continue;
|
|
3907
|
+
const b = p.querySelector("th") !== null, f = Array.from(p.children).indexOf(u);
|
|
3857
3908
|
let y = !1;
|
|
3858
3909
|
const I = n.querySelector("thead");
|
|
3859
3910
|
if (I) {
|
|
@@ -3867,8 +3918,8 @@ const ii = {
|
|
|
3867
3918
|
if (!b && !y && !h && !c) {
|
|
3868
3919
|
a.push({
|
|
3869
3920
|
ruleId: "td-has-header",
|
|
3870
|
-
selector: m(
|
|
3871
|
-
html: u
|
|
3921
|
+
selector: m(u),
|
|
3922
|
+
html: d(u),
|
|
3872
3923
|
impact: "serious",
|
|
3873
3924
|
message: "Data cell has no associated header. Add th elements with scope, or headers attribute."
|
|
3874
3925
|
});
|
|
@@ -3878,7 +3929,7 @@ const ii = {
|
|
|
3878
3929
|
}
|
|
3879
3930
|
return a;
|
|
3880
3931
|
}
|
|
3881
|
-
},
|
|
3932
|
+
}, di = {
|
|
3882
3933
|
id: "scope-attr-valid",
|
|
3883
3934
|
wcag: ["1.3.1"],
|
|
3884
3935
|
level: "A",
|
|
@@ -3889,19 +3940,19 @@ const ii = {
|
|
|
3889
3940
|
var i;
|
|
3890
3941
|
const a = [], e = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
3891
3942
|
for (const n of t.querySelectorAll("th[scope]")) {
|
|
3892
|
-
if (
|
|
3943
|
+
if (g(n)) continue;
|
|
3893
3944
|
const r = (i = n.getAttribute("scope")) == null ? void 0 : i.toLowerCase();
|
|
3894
3945
|
r && !e.has(r) && a.push({
|
|
3895
3946
|
ruleId: "scope-attr-valid",
|
|
3896
3947
|
selector: m(n),
|
|
3897
|
-
html:
|
|
3948
|
+
html: d(n),
|
|
3898
3949
|
impact: "moderate",
|
|
3899
3950
|
message: `Invalid scope value "${r}". Use row, col, rowgroup, or colgroup.`
|
|
3900
3951
|
});
|
|
3901
3952
|
}
|
|
3902
3953
|
return a;
|
|
3903
3954
|
}
|
|
3904
|
-
},
|
|
3955
|
+
}, mi = {
|
|
3905
3956
|
id: "empty-table-header",
|
|
3906
3957
|
wcag: [],
|
|
3907
3958
|
level: "A",
|
|
@@ -3912,19 +3963,19 @@ const ii = {
|
|
|
3912
3963
|
run(t) {
|
|
3913
3964
|
const a = [];
|
|
3914
3965
|
for (const e of t.querySelectorAll("th")) {
|
|
3915
|
-
if (
|
|
3966
|
+
if (g(e)) continue;
|
|
3916
3967
|
const i = e.closest("table");
|
|
3917
3968
|
(i == null ? void 0 : i.getAttribute("role")) === "presentation" || (i == null ? void 0 : i.getAttribute("role")) === "none" || v(e) || a.push({
|
|
3918
3969
|
ruleId: "empty-table-header",
|
|
3919
3970
|
selector: m(e),
|
|
3920
|
-
html:
|
|
3971
|
+
html: d(e),
|
|
3921
3972
|
impact: "minor",
|
|
3922
3973
|
message: "Table header cell is empty. Add text or use aria-label."
|
|
3923
3974
|
});
|
|
3924
3975
|
}
|
|
3925
3976
|
return a;
|
|
3926
3977
|
}
|
|
3927
|
-
},
|
|
3978
|
+
}, O = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], hi = {
|
|
3928
3979
|
id: "duplicate-id-aria",
|
|
3929
3980
|
wcag: ["4.1.2"],
|
|
3930
3981
|
level: "A",
|
|
@@ -3934,7 +3985,7 @@ const ii = {
|
|
|
3934
3985
|
run(t) {
|
|
3935
3986
|
const a = [], e = /* @__PURE__ */ new Set();
|
|
3936
3987
|
for (const n of t.querySelectorAll("[aria-labelledby], [aria-describedby], [aria-controls], [aria-owns], [aria-flowto]"))
|
|
3937
|
-
for (const r of
|
|
3988
|
+
for (const r of O) {
|
|
3938
3989
|
const o = n.getAttribute(r);
|
|
3939
3990
|
o && o.split(/\s+/).forEach((s) => e.add(s));
|
|
3940
3991
|
}
|
|
@@ -3948,14 +3999,14 @@ const ii = {
|
|
|
3948
3999
|
for (const [n, r] of i) {
|
|
3949
4000
|
if (r <= 1) continue;
|
|
3950
4001
|
const o = t.querySelectorAll(`#${CSS.escape(n)}`), s = t.querySelector(
|
|
3951
|
-
|
|
4002
|
+
O.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
|
|
3952
4003
|
), l = t.querySelector(`label[for="${CSS.escape(n)}"]`);
|
|
3953
4004
|
let h;
|
|
3954
4005
|
if (s) {
|
|
3955
|
-
const c =
|
|
3956
|
-
(
|
|
3957
|
-
var
|
|
3958
|
-
return (
|
|
4006
|
+
const c = O.find(
|
|
4007
|
+
(u) => {
|
|
4008
|
+
var p;
|
|
4009
|
+
return (p = s.getAttribute(u)) == null ? void 0 : p.split(/\s+/).includes(n);
|
|
3959
4010
|
}
|
|
3960
4011
|
);
|
|
3961
4012
|
c && (h = c);
|
|
@@ -3963,16 +4014,16 @@ const ii = {
|
|
|
3963
4014
|
a.push({
|
|
3964
4015
|
ruleId: "duplicate-id-aria",
|
|
3965
4016
|
selector: m(o[1]),
|
|
3966
|
-
html:
|
|
4017
|
+
html: d(o[1]),
|
|
3967
4018
|
impact: "critical",
|
|
3968
4019
|
message: `Duplicate ID "${n}" referenced by ${h ?? "an accessibility attribute"}.`,
|
|
3969
|
-
context: `First element: ${
|
|
4020
|
+
context: `First element: ${d(o[0])}${h ? `
|
|
3970
4021
|
Referenced by: ${h}` : ""}`
|
|
3971
4022
|
});
|
|
3972
4023
|
}
|
|
3973
4024
|
return a;
|
|
3974
4025
|
}
|
|
3975
|
-
},
|
|
4026
|
+
}, pi = {
|
|
3976
4027
|
id: "video-caption",
|
|
3977
4028
|
wcag: ["1.2.2"],
|
|
3978
4029
|
level: "A",
|
|
@@ -3982,18 +4033,18 @@ Referenced by: ${h}` : ""}`
|
|
|
3982
4033
|
run(t) {
|
|
3983
4034
|
const a = [];
|
|
3984
4035
|
for (const e of t.querySelectorAll("video")) {
|
|
3985
|
-
if (
|
|
4036
|
+
if (g(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
|
|
3986
4037
|
e.querySelector('track[kind="captions"], track[kind="subtitles"]') || a.push({
|
|
3987
4038
|
ruleId: "video-caption",
|
|
3988
4039
|
selector: m(e),
|
|
3989
|
-
html:
|
|
4040
|
+
html: d(e),
|
|
3990
4041
|
impact: "critical",
|
|
3991
4042
|
message: "Video element has no captions track."
|
|
3992
4043
|
});
|
|
3993
4044
|
}
|
|
3994
4045
|
return a;
|
|
3995
4046
|
}
|
|
3996
|
-
},
|
|
4047
|
+
}, gi = {
|
|
3997
4048
|
id: "audio-caption",
|
|
3998
4049
|
wcag: ["1.2.1"],
|
|
3999
4050
|
level: "A",
|
|
@@ -4003,19 +4054,19 @@ Referenced by: ${h}` : ""}`
|
|
|
4003
4054
|
run(t) {
|
|
4004
4055
|
const a = [];
|
|
4005
4056
|
for (const e of t.querySelectorAll("audio")) {
|
|
4006
|
-
if (
|
|
4057
|
+
if (g(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
|
|
4007
4058
|
const n = e.parentElement;
|
|
4008
4059
|
n && n.querySelector('a[href*="transcript"], a[href*="text"]') || a.push({
|
|
4009
4060
|
ruleId: "audio-caption",
|
|
4010
4061
|
selector: m(e),
|
|
4011
|
-
html:
|
|
4062
|
+
html: d(e),
|
|
4012
4063
|
impact: "critical",
|
|
4013
4064
|
message: "Audio element has no transcript or text alternative. Add a transcript or track element."
|
|
4014
4065
|
});
|
|
4015
4066
|
}
|
|
4016
4067
|
return a;
|
|
4017
4068
|
}
|
|
4018
|
-
},
|
|
4069
|
+
}, bi = /* @__PURE__ */ new Set([
|
|
4019
4070
|
"SCRIPT",
|
|
4020
4071
|
"STYLE",
|
|
4021
4072
|
"NOSCRIPT",
|
|
@@ -4031,13 +4082,13 @@ Referenced by: ${h}` : ""}`
|
|
|
4031
4082
|
"BR",
|
|
4032
4083
|
"HR"
|
|
4033
4084
|
]);
|
|
4034
|
-
function
|
|
4085
|
+
function ue([t, a, e]) {
|
|
4035
4086
|
return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
4036
4087
|
}
|
|
4037
|
-
function
|
|
4088
|
+
function fi(t) {
|
|
4038
4089
|
return t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement || t instanceof HTMLButtonElement ? t.disabled : !!(t.closest("fieldset[disabled]") || t.getAttribute("aria-disabled") === "true");
|
|
4039
4090
|
}
|
|
4040
|
-
function
|
|
4091
|
+
function vi(t, a) {
|
|
4041
4092
|
if (t.tagName !== "LABEL") return !1;
|
|
4042
4093
|
const e = t, i = e.htmlFor;
|
|
4043
4094
|
if (i) {
|
|
@@ -4049,7 +4100,7 @@ function gi(t, a) {
|
|
|
4049
4100
|
const r = e.id;
|
|
4050
4101
|
return !!(r && a.querySelector(`[aria-labelledby~="${r}"][aria-disabled="true"]`));
|
|
4051
4102
|
}
|
|
4052
|
-
function
|
|
4103
|
+
function yi(t) {
|
|
4053
4104
|
const a = t.clip;
|
|
4054
4105
|
if (a && a.startsWith("rect(")) {
|
|
4055
4106
|
const i = a.match(/[\d.]+/g);
|
|
@@ -4063,17 +4114,41 @@ function bi(t) {
|
|
|
4063
4114
|
}
|
|
4064
4115
|
return !1;
|
|
4065
4116
|
}
|
|
4066
|
-
function
|
|
4067
|
-
if (
|
|
4117
|
+
function wi(t) {
|
|
4118
|
+
if (g(t)) return !0;
|
|
4119
|
+
let a = t;
|
|
4120
|
+
for (; a; ) {
|
|
4121
|
+
const e = w(a);
|
|
4122
|
+
if (e.display === "none" || e.visibility === "hidden" || yi(e)) return !0;
|
|
4123
|
+
a = a.parentElement;
|
|
4124
|
+
}
|
|
4125
|
+
return !1;
|
|
4126
|
+
}
|
|
4127
|
+
function Ai(t) {
|
|
4128
|
+
let a = 1, e = t;
|
|
4129
|
+
for (; e; ) {
|
|
4130
|
+
const i = w(e), n = parseFloat(i.opacity);
|
|
4131
|
+
isNaN(n) || (a *= n), e = e.parentElement;
|
|
4132
|
+
}
|
|
4133
|
+
return a;
|
|
4134
|
+
}
|
|
4135
|
+
function xi(t) {
|
|
4068
4136
|
let a = t;
|
|
4069
4137
|
for (; a; ) {
|
|
4070
|
-
const e =
|
|
4071
|
-
if (
|
|
4138
|
+
const e = w(a), i = e.filter;
|
|
4139
|
+
if (i && i !== "none" && i !== "initial") return !0;
|
|
4140
|
+
const n = e.mixBlendMode;
|
|
4141
|
+
if (n && n !== "normal" && n !== "initial") return !0;
|
|
4142
|
+
const r = e.backdropFilter;
|
|
4143
|
+
if (r && r !== "none" && r !== "initial") return !0;
|
|
4072
4144
|
a = a.parentElement;
|
|
4073
4145
|
}
|
|
4074
4146
|
return !1;
|
|
4075
4147
|
}
|
|
4076
|
-
|
|
4148
|
+
function Si(t) {
|
|
4149
|
+
return t.closest("select") !== null;
|
|
4150
|
+
}
|
|
4151
|
+
const ki = {
|
|
4077
4152
|
id: "color-contrast",
|
|
4078
4153
|
wcag: ["1.4.3"],
|
|
4079
4154
|
level: "AA",
|
|
@@ -4088,96 +4163,96 @@ const vi = {
|
|
|
4088
4163
|
for (; r = i.nextNode(); ) {
|
|
4089
4164
|
if (!r.textContent || !r.textContent.trim()) continue;
|
|
4090
4165
|
const o = r.parentElement;
|
|
4091
|
-
if (!o || n.has(o) || (n.add(o),
|
|
4092
|
-
const s =
|
|
4093
|
-
if (
|
|
4094
|
-
const l =
|
|
4095
|
-
if (l
|
|
4096
|
-
const h =
|
|
4097
|
-
if (
|
|
4098
|
-
const c =
|
|
4099
|
-
if (c
|
|
4100
|
-
const
|
|
4101
|
-
if (
|
|
4102
|
-
const
|
|
4103
|
-
if (
|
|
4104
|
-
|
|
4166
|
+
if (!o || n.has(o) || (n.add(o), bi.has(o.tagName))) continue;
|
|
4167
|
+
const s = o.tagName;
|
|
4168
|
+
if (s === "BODY" || s === "HTML" || Si(o) || fi(o) || vi(o, t) || wi(o)) continue;
|
|
4169
|
+
const l = w(o);
|
|
4170
|
+
if (parseFloat(l.opacity) === 0 || Ai(o) < 0.1) continue;
|
|
4171
|
+
const h = l.textShadow;
|
|
4172
|
+
if (h && h !== "none" && h !== "initial" || xi(o)) continue;
|
|
4173
|
+
const c = N(l.color);
|
|
4174
|
+
if (!c) continue;
|
|
4175
|
+
const u = l.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || l.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
|
|
4176
|
+
if (u && (u[1].endsWith("%") ? parseFloat(u[1]) / 100 : parseFloat(u[1])) === 0 || _e(o)) continue;
|
|
4177
|
+
const p = Be(o);
|
|
4178
|
+
if (!p) continue;
|
|
4179
|
+
const b = R(c[0], c[1], c[2]), f = R(p[0], p[1], p[2]), y = me(b, f), I = Ve(o) ? 3 : 4.5;
|
|
4180
|
+
if (y < I) {
|
|
4181
|
+
const x = Math.round(y * 100) / 100, M = ue(c), ye = ue(p);
|
|
4105
4182
|
a.push({
|
|
4106
4183
|
ruleId: "color-contrast",
|
|
4107
4184
|
selector: m(o),
|
|
4108
|
-
html:
|
|
4185
|
+
html: d(o),
|
|
4109
4186
|
impact: "serious",
|
|
4110
|
-
message: `Insufficient color contrast ratio of ${
|
|
4111
|
-
context: `foreground: ${
|
|
4187
|
+
message: `Insufficient color contrast ratio of ${x}:1 (required ${I}:1).`,
|
|
4188
|
+
context: `foreground: ${M} rgb(${c.join(", ")}), background: ${ye} rgb(${p.join(", ")}), ratio: ${x}:1, required: ${I}:1`
|
|
4112
4189
|
});
|
|
4113
4190
|
}
|
|
4114
4191
|
}
|
|
4115
4192
|
return a;
|
|
4116
4193
|
}
|
|
4117
|
-
},
|
|
4194
|
+
}, ge = [
|
|
4118
4195
|
// Document Structure
|
|
4119
|
-
Kt,
|
|
4120
|
-
Jt,
|
|
4121
|
-
Qt,
|
|
4122
4196
|
Zt,
|
|
4123
4197
|
ea,
|
|
4198
|
+
ta,
|
|
4124
4199
|
aa,
|
|
4125
4200
|
ia,
|
|
4126
4201
|
ra,
|
|
4127
|
-
|
|
4202
|
+
oa,
|
|
4203
|
+
la,
|
|
4204
|
+
ua,
|
|
4128
4205
|
// Images
|
|
4129
|
-
je,
|
|
4130
4206
|
ze,
|
|
4131
|
-
Ue,
|
|
4132
4207
|
Ge,
|
|
4133
4208
|
Ye,
|
|
4134
|
-
|
|
4209
|
+
Xe,
|
|
4210
|
+
Je,
|
|
4135
4211
|
Qe,
|
|
4136
|
-
|
|
4137
|
-
|
|
4212
|
+
et,
|
|
4213
|
+
tt,
|
|
4214
|
+
rt,
|
|
4138
4215
|
// Forms
|
|
4139
|
-
lt,
|
|
4140
|
-
ct,
|
|
4141
4216
|
ut,
|
|
4142
4217
|
dt,
|
|
4143
|
-
|
|
4144
|
-
|
|
4218
|
+
mt,
|
|
4219
|
+
ht,
|
|
4145
4220
|
wt,
|
|
4146
|
-
|
|
4221
|
+
At,
|
|
4147
4222
|
xt,
|
|
4223
|
+
// Keyboard
|
|
4148
4224
|
kt,
|
|
4149
|
-
|
|
4150
|
-
Nt,
|
|
4225
|
+
Tt,
|
|
4151
4226
|
$t,
|
|
4152
|
-
// Structure
|
|
4153
4227
|
Mt,
|
|
4154
|
-
ta,
|
|
4155
|
-
la,
|
|
4156
4228
|
Ht,
|
|
4229
|
+
// Structure
|
|
4157
4230
|
Dt,
|
|
4231
|
+
na,
|
|
4232
|
+
da,
|
|
4158
4233
|
Ot,
|
|
4159
|
-
Ft,
|
|
4160
4234
|
Bt,
|
|
4235
|
+
Ft,
|
|
4161
4236
|
Wt,
|
|
4162
4237
|
_t,
|
|
4163
4238
|
Pt,
|
|
4164
4239
|
jt,
|
|
4165
4240
|
Vt,
|
|
4241
|
+
zt,
|
|
4166
4242
|
Ut,
|
|
4167
|
-
Gt,
|
|
4168
4243
|
Yt,
|
|
4244
|
+
Qt,
|
|
4245
|
+
Xt,
|
|
4246
|
+
Jt,
|
|
4169
4247
|
// ARIA
|
|
4170
|
-
|
|
4171
|
-
ua,
|
|
4172
|
-
da,
|
|
4248
|
+
ma,
|
|
4173
4249
|
ha,
|
|
4174
|
-
|
|
4250
|
+
pa,
|
|
4251
|
+
ba,
|
|
4175
4252
|
Aa,
|
|
4176
|
-
Sa,
|
|
4177
4253
|
ka,
|
|
4254
|
+
Ta,
|
|
4178
4255
|
Ea,
|
|
4179
|
-
Ca,
|
|
4180
|
-
La,
|
|
4181
4256
|
qa,
|
|
4182
4257
|
Ra,
|
|
4183
4258
|
Na,
|
|
@@ -4186,42 +4261,45 @@ const vi = {
|
|
|
4186
4261
|
Ha,
|
|
4187
4262
|
Da,
|
|
4188
4263
|
Oa,
|
|
4264
|
+
Ba,
|
|
4265
|
+
Fa,
|
|
4189
4266
|
Wa,
|
|
4190
|
-
ga,
|
|
4191
|
-
_a,
|
|
4192
|
-
// Links
|
|
4193
4267
|
ja,
|
|
4268
|
+
va,
|
|
4194
4269
|
Va,
|
|
4195
|
-
|
|
4270
|
+
// Links
|
|
4271
|
+
Ua,
|
|
4272
|
+
Ga,
|
|
4273
|
+
ei,
|
|
4196
4274
|
// Language
|
|
4197
|
-
|
|
4198
|
-
ai,
|
|
4199
|
-
ii,
|
|
4200
|
-
ni,
|
|
4201
|
-
// Tables
|
|
4275
|
+
ti,
|
|
4202
4276
|
ri,
|
|
4203
4277
|
oi,
|
|
4204
4278
|
si,
|
|
4279
|
+
// Tables
|
|
4205
4280
|
li,
|
|
4206
4281
|
ci,
|
|
4207
|
-
// Parsing
|
|
4208
4282
|
ui,
|
|
4209
|
-
// Media
|
|
4210
4283
|
di,
|
|
4211
4284
|
mi,
|
|
4285
|
+
// Parsing
|
|
4286
|
+
hi,
|
|
4287
|
+
// Media
|
|
4288
|
+
pi,
|
|
4289
|
+
gi,
|
|
4212
4290
|
// Color
|
|
4213
|
-
|
|
4291
|
+
ki
|
|
4214
4292
|
];
|
|
4215
|
-
let
|
|
4216
|
-
function
|
|
4217
|
-
t.additionalRules && (
|
|
4293
|
+
let G = [], be = /* @__PURE__ */ new Set();
|
|
4294
|
+
function Ci(t) {
|
|
4295
|
+
t.additionalRules && (G = t.additionalRules), t.disabledRules && (be = new Set(t.disabledRules));
|
|
4218
4296
|
}
|
|
4219
|
-
function
|
|
4220
|
-
return
|
|
4297
|
+
function fe() {
|
|
4298
|
+
return ge.filter((a) => !be.has(a.id)).concat(G);
|
|
4221
4299
|
}
|
|
4222
|
-
function
|
|
4223
|
-
|
|
4224
|
-
const a =
|
|
4300
|
+
function Li(t) {
|
|
4301
|
+
ve();
|
|
4302
|
+
const a = fe(), e = [];
|
|
4225
4303
|
let i = 0;
|
|
4226
4304
|
return {
|
|
4227
4305
|
processChunk(n) {
|
|
@@ -4240,13 +4318,13 @@ function Si(t) {
|
|
|
4240
4318
|
}
|
|
4241
4319
|
};
|
|
4242
4320
|
}
|
|
4243
|
-
function
|
|
4244
|
-
|
|
4321
|
+
function ve() {
|
|
4322
|
+
Ie(), we(), Ae(), Oe(), De(), Ee();
|
|
4245
4323
|
}
|
|
4246
|
-
function
|
|
4324
|
+
function qi(t) {
|
|
4247
4325
|
var i;
|
|
4248
|
-
|
|
4249
|
-
const a =
|
|
4326
|
+
ve();
|
|
4327
|
+
const a = fe(), e = [];
|
|
4250
4328
|
for (const n of a)
|
|
4251
4329
|
try {
|
|
4252
4330
|
e.push(...n.run(t));
|
|
@@ -4259,32 +4337,32 @@ function ki(t) {
|
|
|
4259
4337
|
ruleCount: a.length
|
|
4260
4338
|
};
|
|
4261
4339
|
}
|
|
4262
|
-
const
|
|
4263
|
-
function
|
|
4264
|
-
const a =
|
|
4265
|
-
return a ||
|
|
4340
|
+
const Ii = new Map(ge.map((t) => [t.id, t]));
|
|
4341
|
+
function Ri(t) {
|
|
4342
|
+
const a = Ii.get(t);
|
|
4343
|
+
return a || G.find((e) => e.id === t);
|
|
4266
4344
|
}
|
|
4267
4345
|
export {
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4346
|
+
ve as clearAllCaches,
|
|
4347
|
+
De as clearAriaAttrAuditCache,
|
|
4348
|
+
Ie as clearAriaHiddenCache,
|
|
4349
|
+
Oe as clearColorCaches,
|
|
4350
|
+
we as clearComputedRoleCache,
|
|
4273
4351
|
k as compileDeclarativeRule,
|
|
4274
|
-
|
|
4275
|
-
|
|
4352
|
+
Ci as configureRules,
|
|
4353
|
+
Li as createChunkedAudit,
|
|
4276
4354
|
v as getAccessibleName,
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4355
|
+
A as getAccessibleTextContent,
|
|
4356
|
+
fe as getActiveRules,
|
|
4357
|
+
q as getComputedRole,
|
|
4358
|
+
d as getHtmlSnippet,
|
|
4359
|
+
de as getImplicitRole,
|
|
4360
|
+
Ri as getRuleById,
|
|
4283
4361
|
m as getSelector,
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4362
|
+
g as isAriaHidden,
|
|
4363
|
+
ke as isValidRole,
|
|
4364
|
+
Ti as querySelectorShadowAware,
|
|
4365
|
+
ge as rules,
|
|
4366
|
+
qi as runAudit,
|
|
4367
|
+
Ei as validateDeclarativeRule
|
|
4290
4368
|
};
|