@accesslint/core 0.3.8 → 0.3.10
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 +773 -722
- 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/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/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 Ii(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 Ti(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,36 @@ 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
|
+
if (i.scrollHeight <= i.clientHeight && i.scrollWidth <= i.clientWidth || i.clientWidth < 64 && i.clientHeight < 64) continue;
|
|
1908
1932
|
} else {
|
|
1909
|
-
const
|
|
1910
|
-
if (!
|
|
1933
|
+
const b = o.height !== "" || o.maxHeight !== "", f = ((e = i.textContent) == null ? void 0 : e.trim().length) ?? 0;
|
|
1934
|
+
if (!b || f <= 50) continue;
|
|
1911
1935
|
}
|
|
1912
|
-
const
|
|
1913
|
-
|
|
1936
|
+
const u = i.getAttribute("tabindex");
|
|
1937
|
+
u !== null && u !== "-1" || i.querySelector(
|
|
1914
1938
|
'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
1915
1939
|
) || a.push({
|
|
1916
1940
|
ruleId: "scrollable-region-focusable",
|
|
1917
|
-
selector: m(
|
|
1918
|
-
html:
|
|
1941
|
+
selector: m(i),
|
|
1942
|
+
html: d(i),
|
|
1919
1943
|
impact: "serious",
|
|
1920
1944
|
message: "Scrollable region is not keyboard accessible. Add tabindex='0' or include focusable elements."
|
|
1921
1945
|
});
|
|
1922
1946
|
}
|
|
1923
1947
|
return a;
|
|
1924
1948
|
}
|
|
1925
|
-
},
|
|
1949
|
+
}, Ht = {
|
|
1926
1950
|
id: "accesskeys",
|
|
1927
1951
|
wcag: [],
|
|
1928
1952
|
level: "A",
|
|
@@ -1934,7 +1958,7 @@ const Rt = {
|
|
|
1934
1958
|
var i;
|
|
1935
1959
|
const a = [], e = /* @__PURE__ */ new Map();
|
|
1936
1960
|
for (const n of t.querySelectorAll("[accesskey]")) {
|
|
1937
|
-
if (
|
|
1961
|
+
if (g(n)) continue;
|
|
1938
1962
|
const r = (i = n.getAttribute("accesskey")) == null ? void 0 : i.trim().toLowerCase();
|
|
1939
1963
|
if (!r) continue;
|
|
1940
1964
|
const o = e.get(r) || [];
|
|
@@ -1946,13 +1970,13 @@ const Rt = {
|
|
|
1946
1970
|
a.push({
|
|
1947
1971
|
ruleId: "accesskeys",
|
|
1948
1972
|
selector: m(o),
|
|
1949
|
-
html:
|
|
1973
|
+
html: d(o),
|
|
1950
1974
|
impact: "serious",
|
|
1951
1975
|
message: `Duplicate accesskey "${n}". Each accesskey must be unique.`
|
|
1952
1976
|
});
|
|
1953
1977
|
return a;
|
|
1954
1978
|
}
|
|
1955
|
-
},
|
|
1979
|
+
}, Dt = {
|
|
1956
1980
|
id: "heading-order",
|
|
1957
1981
|
wcag: [],
|
|
1958
1982
|
level: "A",
|
|
@@ -1964,20 +1988,20 @@ const Rt = {
|
|
|
1964
1988
|
const a = [], e = t.querySelectorAll("h1, h2, h3, h4, h5, h6, [role='heading']");
|
|
1965
1989
|
let i = 0, n = null;
|
|
1966
1990
|
for (const r of e) {
|
|
1967
|
-
if (
|
|
1991
|
+
if (g(r)) continue;
|
|
1968
1992
|
let o;
|
|
1969
1993
|
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
1994
|
ruleId: "heading-order",
|
|
1971
1995
|
selector: m(r),
|
|
1972
|
-
html:
|
|
1996
|
+
html: d(r),
|
|
1973
1997
|
impact: "moderate",
|
|
1974
1998
|
message: `Heading level ${o} skipped from level ${i}.`,
|
|
1975
|
-
context: n ? `Previous heading: ${
|
|
1999
|
+
context: n ? `Previous heading: ${d(n)}` : void 0
|
|
1976
2000
|
}), i = o, n = r;
|
|
1977
2001
|
}
|
|
1978
2002
|
return a;
|
|
1979
2003
|
}
|
|
1980
|
-
},
|
|
2004
|
+
}, $ = '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
2005
|
id: "landmark-one-main",
|
|
1982
2006
|
wcag: [],
|
|
1983
2007
|
level: "A",
|
|
@@ -1996,12 +2020,12 @@ const Rt = {
|
|
|
1996
2020
|
}] : a.length > 1 ? Array.from(a).slice(1).map((e) => ({
|
|
1997
2021
|
ruleId: "landmark-one-main",
|
|
1998
2022
|
selector: m(e),
|
|
1999
|
-
html:
|
|
2023
|
+
html: d(e),
|
|
2000
2024
|
impact: "moderate",
|
|
2001
2025
|
message: "Page has multiple main landmarks."
|
|
2002
2026
|
})) : [];
|
|
2003
2027
|
}
|
|
2004
|
-
},
|
|
2028
|
+
}, Bt = {
|
|
2005
2029
|
id: "landmark-no-duplicate-banner",
|
|
2006
2030
|
wcag: [],
|
|
2007
2031
|
level: "A",
|
|
@@ -2010,18 +2034,18 @@ const Rt = {
|
|
|
2010
2034
|
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
2035
|
prompt: "Explain whether to remove this duplicate banner or nest it inside a sectioning element.",
|
|
2012
2036
|
run(t) {
|
|
2013
|
-
const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest(
|
|
2037
|
+
const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest($));
|
|
2014
2038
|
return i.length > 1 && i.slice(1).forEach(
|
|
2015
2039
|
(n) => a.push({
|
|
2016
2040
|
ruleId: "landmark-no-duplicate-banner",
|
|
2017
2041
|
selector: m(n),
|
|
2018
|
-
html:
|
|
2042
|
+
html: d(n),
|
|
2019
2043
|
impact: "moderate",
|
|
2020
2044
|
message: "Page has multiple banner landmarks."
|
|
2021
2045
|
})
|
|
2022
2046
|
), a;
|
|
2023
2047
|
}
|
|
2024
|
-
},
|
|
2048
|
+
}, Ft = {
|
|
2025
2049
|
id: "landmark-no-duplicate-contentinfo",
|
|
2026
2050
|
wcag: [],
|
|
2027
2051
|
level: "A",
|
|
@@ -2030,18 +2054,18 @@ const Rt = {
|
|
|
2030
2054
|
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
2055
|
prompt: "Explain whether to remove this duplicate footer or nest it inside a sectioning element.",
|
|
2032
2056
|
run(t) {
|
|
2033
|
-
const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest(
|
|
2057
|
+
const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest($));
|
|
2034
2058
|
return i.length > 1 && i.slice(1).forEach(
|
|
2035
2059
|
(n) => a.push({
|
|
2036
2060
|
ruleId: "landmark-no-duplicate-contentinfo",
|
|
2037
2061
|
selector: m(n),
|
|
2038
|
-
html:
|
|
2062
|
+
html: d(n),
|
|
2039
2063
|
impact: "moderate",
|
|
2040
2064
|
message: "Page has multiple contentinfo landmarks."
|
|
2041
2065
|
})
|
|
2042
2066
|
), a;
|
|
2043
2067
|
}
|
|
2044
|
-
},
|
|
2068
|
+
}, Wt = {
|
|
2045
2069
|
id: "landmark-no-duplicate-main",
|
|
2046
2070
|
wcag: [],
|
|
2047
2071
|
level: "A",
|
|
@@ -2055,13 +2079,13 @@ const Rt = {
|
|
|
2055
2079
|
(i) => a.push({
|
|
2056
2080
|
ruleId: "landmark-no-duplicate-main",
|
|
2057
2081
|
selector: m(i),
|
|
2058
|
-
html:
|
|
2082
|
+
html: d(i),
|
|
2059
2083
|
impact: "moderate",
|
|
2060
2084
|
message: "Page has multiple main landmarks."
|
|
2061
2085
|
})
|
|
2062
2086
|
), a;
|
|
2063
2087
|
}
|
|
2064
|
-
},
|
|
2088
|
+
}, _t = {
|
|
2065
2089
|
id: "landmark-banner-is-top-level",
|
|
2066
2090
|
wcag: [],
|
|
2067
2091
|
level: "A",
|
|
@@ -2072,16 +2096,16 @@ const Rt = {
|
|
|
2072
2096
|
run(t) {
|
|
2073
2097
|
const a = [], e = t.querySelectorAll('[role="banner"]');
|
|
2074
2098
|
for (const i of e)
|
|
2075
|
-
i.closest(
|
|
2099
|
+
i.closest($) && a.push({
|
|
2076
2100
|
ruleId: "landmark-banner-is-top-level",
|
|
2077
2101
|
selector: m(i),
|
|
2078
|
-
html:
|
|
2102
|
+
html: d(i),
|
|
2079
2103
|
impact: "moderate",
|
|
2080
2104
|
message: "Banner landmark is nested within another landmark."
|
|
2081
2105
|
});
|
|
2082
2106
|
return a;
|
|
2083
2107
|
}
|
|
2084
|
-
},
|
|
2108
|
+
}, Pt = {
|
|
2085
2109
|
id: "landmark-contentinfo-is-top-level",
|
|
2086
2110
|
wcag: [],
|
|
2087
2111
|
level: "A",
|
|
@@ -2092,16 +2116,16 @@ const Rt = {
|
|
|
2092
2116
|
run(t) {
|
|
2093
2117
|
const a = [], e = t.querySelectorAll('[role="contentinfo"]');
|
|
2094
2118
|
for (const i of e)
|
|
2095
|
-
i.closest(
|
|
2119
|
+
i.closest($) && a.push({
|
|
2096
2120
|
ruleId: "landmark-contentinfo-is-top-level",
|
|
2097
2121
|
selector: m(i),
|
|
2098
|
-
html:
|
|
2122
|
+
html: d(i),
|
|
2099
2123
|
impact: "moderate",
|
|
2100
2124
|
message: "Contentinfo landmark is nested within another landmark."
|
|
2101
2125
|
});
|
|
2102
2126
|
return a;
|
|
2103
2127
|
}
|
|
2104
|
-
},
|
|
2128
|
+
}, jt = {
|
|
2105
2129
|
id: "landmark-main-is-top-level",
|
|
2106
2130
|
wcag: [],
|
|
2107
2131
|
level: "A",
|
|
@@ -2116,14 +2140,14 @@ const Rt = {
|
|
|
2116
2140
|
n != null && n.closest('article, aside, nav, section, [role="article"], [role="complementary"], [role="navigation"], [role="region"]') && a.push({
|
|
2117
2141
|
ruleId: "landmark-main-is-top-level",
|
|
2118
2142
|
selector: m(i),
|
|
2119
|
-
html:
|
|
2143
|
+
html: d(i),
|
|
2120
2144
|
impact: "moderate",
|
|
2121
2145
|
message: "Main landmark is nested within another landmark."
|
|
2122
2146
|
});
|
|
2123
2147
|
}
|
|
2124
2148
|
return a;
|
|
2125
2149
|
}
|
|
2126
|
-
},
|
|
2150
|
+
}, Vt = {
|
|
2127
2151
|
id: "landmark-complementary-is-top-level",
|
|
2128
2152
|
wcag: [],
|
|
2129
2153
|
level: "A",
|
|
@@ -2138,14 +2162,14 @@ const Rt = {
|
|
|
2138
2162
|
n && !n.matches('body, main, [role="main"]') && i.closest('article, nav, section, [role="article"], [role="navigation"], [role="region"]') && a.push({
|
|
2139
2163
|
ruleId: "landmark-complementary-is-top-level",
|
|
2140
2164
|
selector: m(i),
|
|
2141
|
-
html:
|
|
2165
|
+
html: d(i),
|
|
2142
2166
|
impact: "moderate",
|
|
2143
2167
|
message: "Complementary landmark should be top-level."
|
|
2144
2168
|
});
|
|
2145
2169
|
}
|
|
2146
2170
|
return a;
|
|
2147
2171
|
}
|
|
2148
|
-
},
|
|
2172
|
+
}, zt = {
|
|
2149
2173
|
id: "landmark-unique",
|
|
2150
2174
|
wcag: [],
|
|
2151
2175
|
level: "A",
|
|
@@ -2161,7 +2185,7 @@ const Rt = {
|
|
|
2161
2185
|
{ selector: 'form[aria-label], form[aria-labelledby], [role="form"], [role="search"]', type: "form" }
|
|
2162
2186
|
];
|
|
2163
2187
|
for (const { selector: i, type: n } of e) {
|
|
2164
|
-
const r = Array.from(t.querySelectorAll(i)).filter((s) => !
|
|
2188
|
+
const r = Array.from(t.querySelectorAll(i)).filter((s) => !g(s));
|
|
2165
2189
|
if (r.length <= 1) continue;
|
|
2166
2190
|
const o = /* @__PURE__ */ new Map();
|
|
2167
2191
|
for (const s of r) {
|
|
@@ -2174,14 +2198,14 @@ const Rt = {
|
|
|
2174
2198
|
a.push({
|
|
2175
2199
|
ruleId: "landmark-unique",
|
|
2176
2200
|
selector: m(h),
|
|
2177
|
-
html:
|
|
2201
|
+
html: d(h),
|
|
2178
2202
|
impact: "moderate",
|
|
2179
2203
|
message: s ? `Multiple ${n} landmarks have the same label "${s}".` : `Multiple ${n} landmarks have no label. Add unique aria-label attributes.`
|
|
2180
2204
|
});
|
|
2181
2205
|
}
|
|
2182
2206
|
return a;
|
|
2183
2207
|
}
|
|
2184
|
-
},
|
|
2208
|
+
}, Ut = {
|
|
2185
2209
|
id: "region",
|
|
2186
2210
|
wcag: [],
|
|
2187
2211
|
level: "A",
|
|
@@ -2194,22 +2218,22 @@ const Rt = {
|
|
|
2194
2218
|
const a = [], e = t.body;
|
|
2195
2219
|
if (!e) return [];
|
|
2196
2220
|
for (const n of e.children) {
|
|
2197
|
-
if (
|
|
2198
|
-
const r = n.matches(
|
|
2199
|
-
!r && o && (n.querySelector(
|
|
2221
|
+
if (g(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
|
|
2222
|
+
const r = n.matches(ae), o = (i = n.textContent) == null ? void 0 : i.trim();
|
|
2223
|
+
!r && o && (n.querySelector(ae) || a.push({
|
|
2200
2224
|
ruleId: "region",
|
|
2201
2225
|
selector: m(n),
|
|
2202
|
-
html:
|
|
2226
|
+
html: d(n),
|
|
2203
2227
|
impact: "moderate",
|
|
2204
2228
|
message: "Content is not contained within a landmark region."
|
|
2205
2229
|
}));
|
|
2206
2230
|
}
|
|
2207
2231
|
return a;
|
|
2208
2232
|
}
|
|
2209
|
-
},
|
|
2233
|
+
}, Gt = {
|
|
2210
2234
|
id: "list",
|
|
2211
2235
|
selector: "ul, ol",
|
|
2212
|
-
check: { type: "child-invalid", allowedChildren: ["li", "script", "template"] },
|
|
2236
|
+
check: { type: "child-invalid", allowedChildren: ["li", "script", "template"], allowedChildRoles: ["listitem"] },
|
|
2213
2237
|
impact: "serious",
|
|
2214
2238
|
message: "List contains non-<li> child <{{tag}}>.",
|
|
2215
2239
|
description: "<ul> and <ol> must only contain <li>, <script>, or <template> as direct children.",
|
|
@@ -2217,7 +2241,7 @@ const Rt = {
|
|
|
2217
2241
|
level: "A",
|
|
2218
2242
|
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
2243
|
prompt: "Explain how to restructure this element within the list properly."
|
|
2220
|
-
},
|
|
2244
|
+
}, Yt = k(Gt), Xt = {
|
|
2221
2245
|
id: "dlitem",
|
|
2222
2246
|
wcag: ["1.3.1"],
|
|
2223
2247
|
level: "A",
|
|
@@ -2230,13 +2254,13 @@ const Rt = {
|
|
|
2230
2254
|
(!e.parentElement || e.parentElement.tagName.toLowerCase() !== "dl") && a.push({
|
|
2231
2255
|
ruleId: "dlitem",
|
|
2232
2256
|
selector: m(e),
|
|
2233
|
-
html:
|
|
2257
|
+
html: d(e),
|
|
2234
2258
|
impact: "serious",
|
|
2235
2259
|
message: `<${e.tagName.toLowerCase()}> is not contained in a <dl>.`
|
|
2236
2260
|
});
|
|
2237
2261
|
return a;
|
|
2238
2262
|
}
|
|
2239
|
-
},
|
|
2263
|
+
}, Kt = {
|
|
2240
2264
|
id: "definition-list",
|
|
2241
2265
|
selector: "dl",
|
|
2242
2266
|
check: { type: "child-invalid", allowedChildren: ["dt", "dd", "div", "script", "template"] },
|
|
@@ -2247,7 +2271,7 @@ const Rt = {
|
|
|
2247
2271
|
level: "A",
|
|
2248
2272
|
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
2273
|
prompt: "Explain whether to move this element outside the <dl> or convert it to dt/dd."
|
|
2250
|
-
},
|
|
2274
|
+
}, Jt = k(Kt), Qt = {
|
|
2251
2275
|
id: "document-title",
|
|
2252
2276
|
wcag: ["2.4.2"],
|
|
2253
2277
|
level: "A",
|
|
@@ -2277,10 +2301,11 @@ const Rt = {
|
|
|
2277
2301
|
}
|
|
2278
2302
|
return [];
|
|
2279
2303
|
}
|
|
2280
|
-
},
|
|
2304
|
+
}, Zt = {
|
|
2281
2305
|
id: "bypass",
|
|
2282
|
-
wcag: [
|
|
2306
|
+
wcag: [],
|
|
2283
2307
|
level: "A",
|
|
2308
|
+
tags: ["best-practice"],
|
|
2284
2309
|
description: "Page must have a mechanism to bypass repeated blocks of content.",
|
|
2285
2310
|
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
2311
|
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 +2332,7 @@ const Rt = {
|
|
|
2307
2332
|
context: `Missing: ${n.join(", ")}`
|
|
2308
2333
|
}];
|
|
2309
2334
|
}
|
|
2310
|
-
},
|
|
2335
|
+
}, ea = {
|
|
2311
2336
|
id: "page-has-heading-one",
|
|
2312
2337
|
wcag: [],
|
|
2313
2338
|
level: "A",
|
|
@@ -2339,13 +2364,13 @@ const Rt = {
|
|
|
2339
2364
|
}];
|
|
2340
2365
|
}
|
|
2341
2366
|
};
|
|
2342
|
-
function
|
|
2367
|
+
function he(t) {
|
|
2343
2368
|
if (!(t instanceof HTMLElement)) return !1;
|
|
2344
2369
|
if (t.style.display === "none" || t.style.visibility === "hidden") return !0;
|
|
2345
2370
|
const a = t.getAttribute("width"), e = t.getAttribute("height");
|
|
2346
2371
|
return (a === "0" || a === "1") && (e === "0" || e === "1");
|
|
2347
2372
|
}
|
|
2348
|
-
const
|
|
2373
|
+
const ta = {
|
|
2349
2374
|
id: "frame-title",
|
|
2350
2375
|
wcag: ["4.1.2"],
|
|
2351
2376
|
level: "A",
|
|
@@ -2355,13 +2380,13 @@ const Zt = {
|
|
|
2355
2380
|
run(t) {
|
|
2356
2381
|
const a = [];
|
|
2357
2382
|
for (const e of t.querySelectorAll("iframe, frame")) {
|
|
2358
|
-
if (
|
|
2383
|
+
if (g(e) || he(e)) continue;
|
|
2359
2384
|
if (!v(e)) {
|
|
2360
2385
|
const n = e.getAttribute("src");
|
|
2361
2386
|
a.push({
|
|
2362
2387
|
ruleId: "frame-title",
|
|
2363
2388
|
selector: m(e),
|
|
2364
|
-
html:
|
|
2389
|
+
html: d(e),
|
|
2365
2390
|
impact: "serious",
|
|
2366
2391
|
message: "Frame is missing an accessible name. Add a title attribute.",
|
|
2367
2392
|
context: n ? `src: "${n}"` : void 0
|
|
@@ -2370,7 +2395,7 @@ const Zt = {
|
|
|
2370
2395
|
}
|
|
2371
2396
|
return a;
|
|
2372
2397
|
}
|
|
2373
|
-
},
|
|
2398
|
+
}, aa = {
|
|
2374
2399
|
id: "frame-title-unique",
|
|
2375
2400
|
wcag: ["4.1.2"],
|
|
2376
2401
|
level: "A",
|
|
@@ -2382,7 +2407,7 @@ const Zt = {
|
|
|
2382
2407
|
var n;
|
|
2383
2408
|
const a = [], e = Array.from(t.querySelectorAll("iframe[title], frame[title]")), i = /* @__PURE__ */ new Map();
|
|
2384
2409
|
for (const r of e) {
|
|
2385
|
-
if (
|
|
2410
|
+
if (g(r) || he(r)) continue;
|
|
2386
2411
|
const o = (n = r.getAttribute("title")) == null ? void 0 : n.trim().toLowerCase();
|
|
2387
2412
|
if (o) {
|
|
2388
2413
|
const s = i.get(o) || [];
|
|
@@ -2395,13 +2420,13 @@ const Zt = {
|
|
|
2395
2420
|
a.push({
|
|
2396
2421
|
ruleId: "frame-title-unique",
|
|
2397
2422
|
selector: m(o),
|
|
2398
|
-
html:
|
|
2423
|
+
html: d(o),
|
|
2399
2424
|
impact: "moderate",
|
|
2400
2425
|
message: "Frame title is not unique. Use a distinct title for each frame."
|
|
2401
2426
|
});
|
|
2402
2427
|
return a;
|
|
2403
2428
|
}
|
|
2404
|
-
},
|
|
2429
|
+
}, ia = {
|
|
2405
2430
|
id: "empty-heading",
|
|
2406
2431
|
wcag: [],
|
|
2407
2432
|
level: "A",
|
|
@@ -2413,7 +2438,7 @@ const Zt = {
|
|
|
2413
2438
|
var i;
|
|
2414
2439
|
const a = [], e = t.querySelectorAll('h1, h2, h3, h4, h5, h6, [role="heading"]');
|
|
2415
2440
|
for (const n of e)
|
|
2416
|
-
if (!
|
|
2441
|
+
if (!g(n) && !v(n)) {
|
|
2417
2442
|
let r;
|
|
2418
2443
|
const o = n.nextElementSibling;
|
|
2419
2444
|
if (o) {
|
|
@@ -2423,7 +2448,7 @@ const Zt = {
|
|
|
2423
2448
|
a.push({
|
|
2424
2449
|
ruleId: "empty-heading",
|
|
2425
2450
|
selector: m(n),
|
|
2426
|
-
html:
|
|
2451
|
+
html: d(n),
|
|
2427
2452
|
impact: "minor",
|
|
2428
2453
|
message: "Heading is empty. Add text content or remove the heading element.",
|
|
2429
2454
|
context: r ? `Following content: "${r}"` : void 0
|
|
@@ -2431,7 +2456,7 @@ const Zt = {
|
|
|
2431
2456
|
}
|
|
2432
2457
|
return a;
|
|
2433
2458
|
}
|
|
2434
|
-
},
|
|
2459
|
+
}, na = {
|
|
2435
2460
|
id: "meta-viewport",
|
|
2436
2461
|
wcag: ["1.4.4"],
|
|
2437
2462
|
level: "AA",
|
|
@@ -2445,7 +2470,7 @@ const Zt = {
|
|
|
2445
2470
|
(/user-scalable\s*=\s*no/i.test(n) || /user-scalable\s*=\s*0/i.test(n)) && a.push({
|
|
2446
2471
|
ruleId: "meta-viewport",
|
|
2447
2472
|
selector: m(e),
|
|
2448
|
-
html:
|
|
2473
|
+
html: d(e),
|
|
2449
2474
|
impact: "critical",
|
|
2450
2475
|
message: "Viewport disables user scaling. Remove user-scalable=no.",
|
|
2451
2476
|
context: `content: "${i}"`
|
|
@@ -2456,7 +2481,7 @@ const Zt = {
|
|
|
2456
2481
|
s < 2 && a.push({
|
|
2457
2482
|
ruleId: "meta-viewport",
|
|
2458
2483
|
selector: m(e),
|
|
2459
|
-
html:
|
|
2484
|
+
html: d(e),
|
|
2460
2485
|
impact: "critical",
|
|
2461
2486
|
message: `Viewport maximum-scale=${s} restricts zooming. Set to at least 2 or remove.`,
|
|
2462
2487
|
context: `content: "${i}"`
|
|
@@ -2464,7 +2489,7 @@ const Zt = {
|
|
|
2464
2489
|
}
|
|
2465
2490
|
return a;
|
|
2466
2491
|
}
|
|
2467
|
-
},
|
|
2492
|
+
}, ra = {
|
|
2468
2493
|
id: "meta-refresh",
|
|
2469
2494
|
wcag: ["2.2.1", "2.2.4", "3.2.5"],
|
|
2470
2495
|
level: "A",
|
|
@@ -2480,7 +2505,7 @@ const Zt = {
|
|
|
2480
2505
|
return n > 0 && n <= 72e3 ? [{
|
|
2481
2506
|
ruleId: "meta-refresh",
|
|
2482
2507
|
selector: m(a),
|
|
2483
|
-
html:
|
|
2508
|
+
html: d(a),
|
|
2484
2509
|
impact: "critical",
|
|
2485
2510
|
message: `Page redirects after ${n} seconds without warning. Use server-side redirect.`
|
|
2486
2511
|
}] : [];
|
|
@@ -2488,14 +2513,14 @@ const Zt = {
|
|
|
2488
2513
|
return [{
|
|
2489
2514
|
ruleId: "meta-refresh",
|
|
2490
2515
|
selector: m(a),
|
|
2491
|
-
html:
|
|
2516
|
+
html: d(a),
|
|
2492
2517
|
impact: "critical",
|
|
2493
2518
|
message: `Page auto-refreshes after ${n} seconds. Provide user control over refresh.`
|
|
2494
2519
|
}];
|
|
2495
2520
|
}
|
|
2496
2521
|
return [];
|
|
2497
2522
|
}
|
|
2498
|
-
},
|
|
2523
|
+
}, oa = {
|
|
2499
2524
|
id: "blink",
|
|
2500
2525
|
selector: "blink",
|
|
2501
2526
|
check: { type: "selector-exists" },
|
|
@@ -2506,7 +2531,7 @@ const Zt = {
|
|
|
2506
2531
|
level: "A",
|
|
2507
2532
|
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
2533
|
prompt: "Suggest static alternatives to the blinking effect."
|
|
2509
|
-
},
|
|
2534
|
+
}, sa = k(oa), la = {
|
|
2510
2535
|
id: "marquee",
|
|
2511
2536
|
selector: "marquee",
|
|
2512
2537
|
check: { type: "selector-exists" },
|
|
@@ -2517,7 +2542,7 @@ const Zt = {
|
|
|
2517
2542
|
level: "A",
|
|
2518
2543
|
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
2544
|
prompt: "Suggest static alternatives or accessible carousel patterns."
|
|
2520
|
-
},
|
|
2545
|
+
}, ca = k(la), ua = {
|
|
2521
2546
|
id: "p-as-heading",
|
|
2522
2547
|
wcag: [],
|
|
2523
2548
|
level: "A",
|
|
@@ -2529,14 +2554,14 @@ const Zt = {
|
|
|
2529
2554
|
var e, i;
|
|
2530
2555
|
const a = [];
|
|
2531
2556
|
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) &&
|
|
2557
|
+
if (g(n)) continue;
|
|
2558
|
+
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(/[.!?,;:]$/);
|
|
2559
|
+
if ((o && s || o && h) && u && p) {
|
|
2535
2560
|
const y = n.nextElementSibling;
|
|
2536
2561
|
y && (y.tagName === "P" || y.tagName === "DIV" || y.tagName === "UL") && a.push({
|
|
2537
2562
|
ruleId: "p-as-heading",
|
|
2538
2563
|
selector: m(n),
|
|
2539
|
-
html:
|
|
2564
|
+
html: d(n),
|
|
2540
2565
|
impact: "serious",
|
|
2541
2566
|
message: "Paragraph appears to be styled as a heading. Use an h1-h6 element instead."
|
|
2542
2567
|
});
|
|
@@ -2544,7 +2569,7 @@ const Zt = {
|
|
|
2544
2569
|
}
|
|
2545
2570
|
return a;
|
|
2546
2571
|
}
|
|
2547
|
-
},
|
|
2572
|
+
}, da = {
|
|
2548
2573
|
id: "aria-roles",
|
|
2549
2574
|
wcag: ["4.1.2"],
|
|
2550
2575
|
level: "A",
|
|
@@ -2555,17 +2580,17 @@ const Zt = {
|
|
|
2555
2580
|
const a = [];
|
|
2556
2581
|
for (const e of t.querySelectorAll("[role]")) {
|
|
2557
2582
|
const r = e.getAttribute("role").replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "").split(/\s+/).filter(Boolean);
|
|
2558
|
-
!r.some((s) =>
|
|
2583
|
+
!r.some((s) => ke(s)) && r.length > 0 && a.push({
|
|
2559
2584
|
ruleId: "aria-roles",
|
|
2560
2585
|
selector: m(e),
|
|
2561
|
-
html:
|
|
2586
|
+
html: d(e),
|
|
2562
2587
|
impact: "critical",
|
|
2563
2588
|
message: `Invalid ARIA role "${r[0]}".`
|
|
2564
2589
|
});
|
|
2565
2590
|
}
|
|
2566
2591
|
return a;
|
|
2567
2592
|
}
|
|
2568
|
-
},
|
|
2593
|
+
}, ma = {
|
|
2569
2594
|
id: "aria-valid-attr",
|
|
2570
2595
|
wcag: ["4.1.2"],
|
|
2571
2596
|
level: "A",
|
|
@@ -2573,9 +2598,9 @@ const Zt = {
|
|
|
2573
2598
|
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
2599
|
prompt: "Identify the misspelled attribute and provide the correct spelling.",
|
|
2575
2600
|
run(t) {
|
|
2576
|
-
return
|
|
2601
|
+
return U(t).validAttr;
|
|
2577
2602
|
}
|
|
2578
|
-
},
|
|
2603
|
+
}, ha = {
|
|
2579
2604
|
id: "aria-valid-attr-value",
|
|
2580
2605
|
wcag: ["4.1.2"],
|
|
2581
2606
|
level: "A",
|
|
@@ -2583,9 +2608,9 @@ const Zt = {
|
|
|
2583
2608
|
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
2609
|
prompt: "Show the invalid value and list the valid values for this specific attribute.",
|
|
2585
2610
|
run(t) {
|
|
2586
|
-
return
|
|
2611
|
+
return U(t).validAttrValue;
|
|
2587
2612
|
}
|
|
2588
|
-
},
|
|
2613
|
+
}, pa = {
|
|
2589
2614
|
checkbox: ["aria-checked"],
|
|
2590
2615
|
combobox: ["aria-expanded"],
|
|
2591
2616
|
heading: ["aria-level"],
|
|
@@ -2599,7 +2624,7 @@ const Zt = {
|
|
|
2599
2624
|
slider: ["aria-valuenow"],
|
|
2600
2625
|
spinbutton: ["aria-valuenow"],
|
|
2601
2626
|
switch: ["aria-checked"]
|
|
2602
|
-
},
|
|
2627
|
+
}, ga = {
|
|
2603
2628
|
id: "aria-required-attr",
|
|
2604
2629
|
wcag: ["4.1.2"],
|
|
2605
2630
|
level: "A",
|
|
@@ -2609,8 +2634,8 @@ const Zt = {
|
|
|
2609
2634
|
run(t) {
|
|
2610
2635
|
const a = [];
|
|
2611
2636
|
for (const e of t.querySelectorAll("[role]")) {
|
|
2612
|
-
if (
|
|
2613
|
-
const i = e.getAttribute("role").trim().toLowerCase(), n =
|
|
2637
|
+
if (g(e) || e instanceof HTMLElement && e.style.display === "none") continue;
|
|
2638
|
+
const i = e.getAttribute("role").trim().toLowerCase(), n = pa[i];
|
|
2614
2639
|
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
2640
|
if (i === "separator") {
|
|
2616
2641
|
const r = e.getAttribute("tabindex");
|
|
@@ -2622,7 +2647,7 @@ const Zt = {
|
|
|
2622
2647
|
a.push({
|
|
2623
2648
|
ruleId: "aria-required-attr",
|
|
2624
2649
|
selector: m(e),
|
|
2625
|
-
html:
|
|
2650
|
+
html: d(e),
|
|
2626
2651
|
impact: "critical",
|
|
2627
2652
|
message: `Role "${i}" requires attribute "${r}".`
|
|
2628
2653
|
});
|
|
@@ -2634,7 +2659,7 @@ const Zt = {
|
|
|
2634
2659
|
return a;
|
|
2635
2660
|
}
|
|
2636
2661
|
};
|
|
2637
|
-
function
|
|
2662
|
+
function ba(t) {
|
|
2638
2663
|
var r, o, s;
|
|
2639
2664
|
const a = [], e = t.className;
|
|
2640
2665
|
e && typeof e == "string" && e.trim() && a.push(`Classes: ${e.trim().slice(0, 100)}`);
|
|
@@ -2651,7 +2676,7 @@ function pa(t) {
|
|
|
2651
2676
|
return a.length > 0 ? a.join(`
|
|
2652
2677
|
`) : void 0;
|
|
2653
2678
|
}
|
|
2654
|
-
const
|
|
2679
|
+
const fa = {
|
|
2655
2680
|
id: "button-name",
|
|
2656
2681
|
wcag: ["4.1.2"],
|
|
2657
2682
|
level: "A",
|
|
@@ -2661,21 +2686,21 @@ const ga = {
|
|
|
2661
2686
|
run(t) {
|
|
2662
2687
|
const a = [];
|
|
2663
2688
|
for (const e of t.querySelectorAll('button, [role="button"]')) {
|
|
2664
|
-
if (
|
|
2689
|
+
if (g(e) || T(e)) continue;
|
|
2665
2690
|
const i = e.getAttribute("role");
|
|
2666
2691
|
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
2692
|
v(e) || a.push({
|
|
2668
2693
|
ruleId: "button-name",
|
|
2669
2694
|
selector: m(e),
|
|
2670
|
-
html:
|
|
2695
|
+
html: d(e),
|
|
2671
2696
|
impact: "critical",
|
|
2672
2697
|
message: "Button has no discernible text.",
|
|
2673
|
-
context:
|
|
2698
|
+
context: ba(e)
|
|
2674
2699
|
});
|
|
2675
2700
|
}
|
|
2676
2701
|
return a;
|
|
2677
2702
|
}
|
|
2678
|
-
},
|
|
2703
|
+
}, va = {
|
|
2679
2704
|
alert: /* @__PURE__ */ new Set(["aria-atomic", "aria-busy", "aria-live", "aria-relevant"]),
|
|
2680
2705
|
alertdialog: /* @__PURE__ */ new Set(["aria-describedby", "aria-modal"]),
|
|
2681
2706
|
application: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-expanded", "aria-haspopup", "aria-invalid"]),
|
|
@@ -2747,7 +2772,7 @@ const ga = {
|
|
|
2747
2772
|
tree: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-required"]),
|
|
2748
2773
|
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
2774
|
treeitem: /* @__PURE__ */ new Set(["aria-checked", "aria-disabled", "aria-expanded", "aria-haspopup", "aria-level", "aria-posinset", "aria-selected", "aria-setsize"])
|
|
2750
|
-
},
|
|
2775
|
+
}, ya = /* @__PURE__ */ new Set([
|
|
2751
2776
|
"aria-atomic",
|
|
2752
2777
|
"aria-busy",
|
|
2753
2778
|
"aria-controls",
|
|
@@ -2771,7 +2796,7 @@ const ga = {
|
|
|
2771
2796
|
"aria-roledescription",
|
|
2772
2797
|
"aria-braillelabel",
|
|
2773
2798
|
"aria-brailleroledescription"
|
|
2774
|
-
]),
|
|
2799
|
+
]), wa = {
|
|
2775
2800
|
id: "aria-allowed-attr",
|
|
2776
2801
|
wcag: ["4.1.2"],
|
|
2777
2802
|
level: "A",
|
|
@@ -2781,18 +2806,18 @@ const ga = {
|
|
|
2781
2806
|
run(t) {
|
|
2782
2807
|
const a = [];
|
|
2783
2808
|
for (const e of t.querySelectorAll("[role], [aria-*]")) {
|
|
2784
|
-
if (
|
|
2785
|
-
const i =
|
|
2809
|
+
if (g(e)) continue;
|
|
2810
|
+
const i = q(e);
|
|
2786
2811
|
if (!i) continue;
|
|
2787
|
-
const n =
|
|
2812
|
+
const n = va[i];
|
|
2788
2813
|
if (n)
|
|
2789
2814
|
for (const r of e.attributes) {
|
|
2790
|
-
if (!r.name.startsWith("aria-") ||
|
|
2815
|
+
if (!r.name.startsWith("aria-") || ya.has(r.name) || n.has(r.name)) continue;
|
|
2791
2816
|
const o = n.size > 0 ? [...n].join(", ") : "none (only global ARIA attributes)";
|
|
2792
2817
|
a.push({
|
|
2793
2818
|
ruleId: "aria-allowed-attr",
|
|
2794
2819
|
selector: m(e),
|
|
2795
|
-
html:
|
|
2820
|
+
html: d(e),
|
|
2796
2821
|
impact: "critical",
|
|
2797
2822
|
message: `ARIA attribute "${r.name}" is not allowed on role "${i}".`,
|
|
2798
2823
|
context: `Attribute: ${r.name}="${r.value}", role: ${i}, allowed role-specific attributes: ${o}`
|
|
@@ -2801,7 +2826,7 @@ const ga = {
|
|
|
2801
2826
|
}
|
|
2802
2827
|
return a;
|
|
2803
2828
|
}
|
|
2804
|
-
},
|
|
2829
|
+
}, Aa = /* @__PURE__ */ new Set([
|
|
2805
2830
|
"base",
|
|
2806
2831
|
"col",
|
|
2807
2832
|
"colgroup",
|
|
@@ -2816,7 +2841,7 @@ const ga = {
|
|
|
2816
2841
|
"template",
|
|
2817
2842
|
"title",
|
|
2818
2843
|
"track"
|
|
2819
|
-
]),
|
|
2844
|
+
]), E = {
|
|
2820
2845
|
a: /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem", "link"]),
|
|
2821
2846
|
"a[href]": /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem"]),
|
|
2822
2847
|
abbr: "any",
|
|
@@ -2923,22 +2948,22 @@ const ga = {
|
|
|
2923
2948
|
video: /* @__PURE__ */ new Set(["application"]),
|
|
2924
2949
|
wbr: /* @__PURE__ */ new Set(["none", "presentation"])
|
|
2925
2950
|
};
|
|
2926
|
-
function
|
|
2951
|
+
function xa(t) {
|
|
2927
2952
|
var e;
|
|
2928
2953
|
const a = t.tagName.toLowerCase();
|
|
2929
|
-
if (
|
|
2954
|
+
if (Aa.has(a))
|
|
2930
2955
|
return "none";
|
|
2931
2956
|
if (a === "a" && t.hasAttribute("href"))
|
|
2932
|
-
return
|
|
2957
|
+
return E["a[href]"];
|
|
2933
2958
|
if (a === "img" && t.getAttribute("alt") === "")
|
|
2934
|
-
return
|
|
2959
|
+
return E["img[alt='']"];
|
|
2935
2960
|
if (a === "input") {
|
|
2936
2961
|
const n = `input[type=${((e = t.getAttribute("type")) == null ? void 0 : e.toLowerCase()) || "text"}]`;
|
|
2937
|
-
return n in
|
|
2962
|
+
return n in E ? E[n] : "none";
|
|
2938
2963
|
}
|
|
2939
|
-
return
|
|
2964
|
+
return E[a] || "any";
|
|
2940
2965
|
}
|
|
2941
|
-
const
|
|
2966
|
+
const Sa = {
|
|
2942
2967
|
id: "aria-allowed-role",
|
|
2943
2968
|
wcag: ["4.1.2"],
|
|
2944
2969
|
level: "A",
|
|
@@ -2949,29 +2974,29 @@ const Aa = {
|
|
|
2949
2974
|
var e;
|
|
2950
2975
|
const a = [];
|
|
2951
2976
|
for (const i of t.querySelectorAll("[role]")) {
|
|
2952
|
-
if (
|
|
2977
|
+
if (g(i)) continue;
|
|
2953
2978
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
2954
2979
|
if (!n) continue;
|
|
2955
|
-
const r =
|
|
2980
|
+
const r = de(i);
|
|
2956
2981
|
if (r && n === r) continue;
|
|
2957
|
-
const o =
|
|
2982
|
+
const o = xa(i);
|
|
2958
2983
|
o === "none" ? a.push({
|
|
2959
2984
|
ruleId: "aria-allowed-role",
|
|
2960
2985
|
selector: m(i),
|
|
2961
|
-
html:
|
|
2986
|
+
html: d(i),
|
|
2962
2987
|
impact: "minor",
|
|
2963
2988
|
message: `Element <${i.tagName.toLowerCase()}> should not have an explicit role.`
|
|
2964
2989
|
}) : o !== "any" && !o.has(n) && a.push({
|
|
2965
2990
|
ruleId: "aria-allowed-role",
|
|
2966
2991
|
selector: m(i),
|
|
2967
|
-
html:
|
|
2992
|
+
html: d(i),
|
|
2968
2993
|
impact: "minor",
|
|
2969
2994
|
message: `Role "${n}" is not allowed on element <${i.tagName.toLowerCase()}>.`
|
|
2970
2995
|
});
|
|
2971
2996
|
}
|
|
2972
2997
|
return a;
|
|
2973
2998
|
}
|
|
2974
|
-
},
|
|
2999
|
+
}, ie = {
|
|
2975
3000
|
// Each array is an OR group - at least one of each inner array must be present
|
|
2976
3001
|
combobox: [["listbox", "tree", "grid", "dialog", "textbox"]],
|
|
2977
3002
|
// Must own/contain one of these
|
|
@@ -2988,7 +3013,7 @@ const Aa = {
|
|
|
2988
3013
|
tablist: [["tab"]],
|
|
2989
3014
|
tree: [["treeitem", "group"]],
|
|
2990
3015
|
treegrid: [["row", "rowgroup"]]
|
|
2991
|
-
},
|
|
3016
|
+
}, ne = {
|
|
2992
3017
|
caption: ["figure", "table", "grid", "treegrid"],
|
|
2993
3018
|
// cell/gridcell/columnheader/rowheader must be in a row
|
|
2994
3019
|
// but we skip checking native td/th since they're handled by HTML semantics
|
|
@@ -3002,25 +3027,25 @@ const Aa = {
|
|
|
3002
3027
|
tab: ["tablist"],
|
|
3003
3028
|
treeitem: ["tree", "group"]
|
|
3004
3029
|
};
|
|
3005
|
-
function
|
|
3030
|
+
function ka(t, a) {
|
|
3006
3031
|
var r;
|
|
3007
3032
|
const e = ((r = t.getAttribute("aria-owns")) == null ? void 0 : r.split(/\s+/)) || [], i = t.ownerDocument, n = /* @__PURE__ */ new Set();
|
|
3008
3033
|
for (const o of t.querySelectorAll("*")) {
|
|
3009
|
-
const s =
|
|
3010
|
-
s && !
|
|
3034
|
+
const s = q(o);
|
|
3035
|
+
s && !g(o) && n.add(s);
|
|
3011
3036
|
}
|
|
3012
3037
|
for (const o of e) {
|
|
3013
3038
|
const s = i.getElementById(o);
|
|
3014
3039
|
if (s) {
|
|
3015
|
-
const l =
|
|
3016
|
-
l && !
|
|
3040
|
+
const l = q(s);
|
|
3041
|
+
l && !g(s) && n.add(l);
|
|
3017
3042
|
}
|
|
3018
3043
|
}
|
|
3019
3044
|
for (const o of a)
|
|
3020
3045
|
if (!o.some((l) => n.has(l))) return !1;
|
|
3021
3046
|
return !0;
|
|
3022
3047
|
}
|
|
3023
|
-
const
|
|
3048
|
+
const Ia = {
|
|
3024
3049
|
id: "aria-required-children",
|
|
3025
3050
|
wcag: ["4.1.2"],
|
|
3026
3051
|
level: "A",
|
|
@@ -3031,16 +3056,16 @@ const Sa = {
|
|
|
3031
3056
|
var e;
|
|
3032
3057
|
const a = [];
|
|
3033
3058
|
for (const i of t.querySelectorAll("[role]")) {
|
|
3034
|
-
if (
|
|
3059
|
+
if (g(i)) continue;
|
|
3035
3060
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
3036
|
-
if (!n || !(n in
|
|
3037
|
-
const r =
|
|
3038
|
-
if (!
|
|
3061
|
+
if (!n || !(n in ie)) continue;
|
|
3062
|
+
const r = ie[n];
|
|
3063
|
+
if (!ka(i, r)) {
|
|
3039
3064
|
const o = r.map((s) => s.join(" or ")).join(", ");
|
|
3040
3065
|
a.push({
|
|
3041
3066
|
ruleId: "aria-required-children",
|
|
3042
3067
|
selector: m(i),
|
|
3043
|
-
html:
|
|
3068
|
+
html: d(i),
|
|
3044
3069
|
impact: "critical",
|
|
3045
3070
|
message: `Role "${n}" requires children with role: ${o}.`
|
|
3046
3071
|
});
|
|
@@ -3048,7 +3073,7 @@ const Sa = {
|
|
|
3048
3073
|
}
|
|
3049
3074
|
return a;
|
|
3050
3075
|
}
|
|
3051
|
-
},
|
|
3076
|
+
}, Ta = {
|
|
3052
3077
|
id: "aria-required-parent",
|
|
3053
3078
|
wcag: ["4.1.2"],
|
|
3054
3079
|
level: "A",
|
|
@@ -3059,13 +3084,13 @@ const Sa = {
|
|
|
3059
3084
|
var e;
|
|
3060
3085
|
const a = [];
|
|
3061
3086
|
for (const i of t.querySelectorAll("[role]")) {
|
|
3062
|
-
if (
|
|
3087
|
+
if (g(i)) continue;
|
|
3063
3088
|
const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
|
|
3064
|
-
if (!n || !(n in
|
|
3065
|
-
const r =
|
|
3089
|
+
if (!n || !(n in ne)) continue;
|
|
3090
|
+
const r = ne[n];
|
|
3066
3091
|
let o = i.parentElement, s = !1;
|
|
3067
3092
|
for (; o && o !== t.documentElement; ) {
|
|
3068
|
-
const l =
|
|
3093
|
+
const l = q(o);
|
|
3069
3094
|
if (l && r.includes(l)) {
|
|
3070
3095
|
s = !0;
|
|
3071
3096
|
break;
|
|
@@ -3075,14 +3100,14 @@ const Sa = {
|
|
|
3075
3100
|
s || a.push({
|
|
3076
3101
|
ruleId: "aria-required-parent",
|
|
3077
3102
|
selector: m(i),
|
|
3078
|
-
html:
|
|
3103
|
+
html: d(i),
|
|
3079
3104
|
impact: "critical",
|
|
3080
3105
|
message: `Role "${n}" must be contained within: ${r.join(", ")}.`
|
|
3081
3106
|
});
|
|
3082
3107
|
}
|
|
3083
3108
|
return a;
|
|
3084
3109
|
}
|
|
3085
|
-
},
|
|
3110
|
+
}, re = [
|
|
3086
3111
|
"a[href]",
|
|
3087
3112
|
"button:not([disabled])",
|
|
3088
3113
|
'input:not([disabled]):not([type="hidden"])',
|
|
@@ -3098,7 +3123,7 @@ const Sa = {
|
|
|
3098
3123
|
"embed",
|
|
3099
3124
|
"area[href]"
|
|
3100
3125
|
].join(", ");
|
|
3101
|
-
function
|
|
3126
|
+
function Ea(t) {
|
|
3102
3127
|
let a = t;
|
|
3103
3128
|
const e = t.ownerDocument, i = e.defaultView;
|
|
3104
3129
|
for (; a && a !== e.body; ) {
|
|
@@ -3111,7 +3136,7 @@ function Ia(t) {
|
|
|
3111
3136
|
}
|
|
3112
3137
|
return !0;
|
|
3113
3138
|
}
|
|
3114
|
-
const
|
|
3139
|
+
const Ca = {
|
|
3115
3140
|
id: "aria-hidden-body",
|
|
3116
3141
|
selector: 'body[aria-hidden="true"]',
|
|
3117
3142
|
check: { type: "selector-exists" },
|
|
@@ -3123,7 +3148,7 @@ const Ta = {
|
|
|
3123
3148
|
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
3149
|
prompt: "Instruct to remove aria-hidden='true' from the body element.",
|
|
3125
3150
|
skipAriaHidden: !1
|
|
3126
|
-
},
|
|
3151
|
+
}, La = k(Ca), qa = {
|
|
3127
3152
|
id: "aria-hidden-focus",
|
|
3128
3153
|
wcag: ["4.1.2"],
|
|
3129
3154
|
level: "A",
|
|
@@ -3134,12 +3159,12 @@ const Ta = {
|
|
|
3134
3159
|
const a = [];
|
|
3135
3160
|
for (const e of t.querySelectorAll('[aria-hidden="true"]')) {
|
|
3136
3161
|
if (e === t.body) continue;
|
|
3137
|
-
const i = [...e.querySelectorAll(
|
|
3138
|
-
e.matches(
|
|
3162
|
+
const i = [...e.querySelectorAll(re)];
|
|
3163
|
+
e.matches(re) && i.push(e);
|
|
3139
3164
|
for (const n of i)
|
|
3140
3165
|
if (n instanceof HTMLElement) {
|
|
3141
3166
|
const r = n.getAttribute("tabindex");
|
|
3142
|
-
if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !
|
|
3167
|
+
if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ea(n)) continue;
|
|
3143
3168
|
const o = n.tagName.toLowerCase();
|
|
3144
3169
|
let s;
|
|
3145
3170
|
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 +3172,16 @@ const Ta = {
|
|
|
3147
3172
|
a.push({
|
|
3148
3173
|
ruleId: "aria-hidden-focus",
|
|
3149
3174
|
selector: m(n),
|
|
3150
|
-
html:
|
|
3175
|
+
html: d(n),
|
|
3151
3176
|
impact: "serious",
|
|
3152
3177
|
message: "Focusable element is inside an aria-hidden region.",
|
|
3153
|
-
context: `Focusable because: ${s}. aria-hidden ancestor: ${l ?
|
|
3178
|
+
context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? d(l) : "unknown"}`
|
|
3154
3179
|
});
|
|
3155
3180
|
}
|
|
3156
3181
|
}
|
|
3157
3182
|
return a;
|
|
3158
3183
|
}
|
|
3159
|
-
},
|
|
3184
|
+
}, Ra = {
|
|
3160
3185
|
id: "aria-command-name",
|
|
3161
3186
|
wcag: ["4.1.2"],
|
|
3162
3187
|
level: "A",
|
|
@@ -3167,14 +3192,14 @@ const Ta = {
|
|
|
3167
3192
|
var e;
|
|
3168
3193
|
const a = [];
|
|
3169
3194
|
for (const i of t.querySelectorAll('[role="button"], [role="link"], [role="menuitem"]')) {
|
|
3170
|
-
if (
|
|
3195
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
|
|
3171
3196
|
if (!v(i)) {
|
|
3172
3197
|
const r = i.querySelector("img[alt]");
|
|
3173
3198
|
if ((e = r == null ? void 0 : r.getAttribute("alt")) != null && e.trim()) continue;
|
|
3174
3199
|
a.push({
|
|
3175
3200
|
ruleId: "aria-command-name",
|
|
3176
3201
|
selector: m(i),
|
|
3177
|
-
html:
|
|
3202
|
+
html: d(i),
|
|
3178
3203
|
impact: "serious",
|
|
3179
3204
|
message: "ARIA command has no accessible name."
|
|
3180
3205
|
});
|
|
@@ -3182,7 +3207,7 @@ const Ta = {
|
|
|
3182
3207
|
}
|
|
3183
3208
|
return a;
|
|
3184
3209
|
}
|
|
3185
|
-
},
|
|
3210
|
+
}, Na = {
|
|
3186
3211
|
id: "aria-input-field-name",
|
|
3187
3212
|
wcag: ["4.1.2"],
|
|
3188
3213
|
level: "A",
|
|
@@ -3192,18 +3217,18 @@ const Ta = {
|
|
|
3192
3217
|
run(t) {
|
|
3193
3218
|
const a = [], e = '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]';
|
|
3194
3219
|
for (const i of t.querySelectorAll(e)) {
|
|
3195
|
-
if (
|
|
3220
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches("input, select, textarea")) continue;
|
|
3196
3221
|
v(i) || a.push({
|
|
3197
3222
|
ruleId: "aria-input-field-name",
|
|
3198
3223
|
selector: m(i),
|
|
3199
|
-
html:
|
|
3224
|
+
html: d(i),
|
|
3200
3225
|
impact: "serious",
|
|
3201
3226
|
message: "ARIA input field has no accessible name."
|
|
3202
3227
|
});
|
|
3203
3228
|
}
|
|
3204
3229
|
return a;
|
|
3205
3230
|
}
|
|
3206
|
-
},
|
|
3231
|
+
}, $a = {
|
|
3207
3232
|
id: "aria-toggle-field-name",
|
|
3208
3233
|
wcag: ["4.1.2"],
|
|
3209
3234
|
level: "A",
|
|
@@ -3213,18 +3238,18 @@ const Ta = {
|
|
|
3213
3238
|
run(t) {
|
|
3214
3239
|
const a = [], e = '[role="checkbox"], [role="switch"], [role="radio"], [role="menuitemcheckbox"], [role="menuitemradio"]';
|
|
3215
3240
|
for (const i of t.querySelectorAll(e)) {
|
|
3216
|
-
if (
|
|
3241
|
+
if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
|
|
3217
3242
|
v(i) || a.push({
|
|
3218
3243
|
ruleId: "aria-toggle-field-name",
|
|
3219
3244
|
selector: m(i),
|
|
3220
|
-
html:
|
|
3245
|
+
html: d(i),
|
|
3221
3246
|
impact: "serious",
|
|
3222
3247
|
message: "ARIA toggle field has no accessible name."
|
|
3223
3248
|
});
|
|
3224
3249
|
}
|
|
3225
3250
|
return a;
|
|
3226
3251
|
}
|
|
3227
|
-
},
|
|
3252
|
+
}, Ma = {
|
|
3228
3253
|
id: "aria-meter-name",
|
|
3229
3254
|
wcag: ["4.1.2"],
|
|
3230
3255
|
level: "A",
|
|
@@ -3234,18 +3259,18 @@ const Ta = {
|
|
|
3234
3259
|
run(t) {
|
|
3235
3260
|
const a = [];
|
|
3236
3261
|
for (const e of t.querySelectorAll('[role="meter"], meter')) {
|
|
3237
|
-
if (
|
|
3262
|
+
if (g(e)) continue;
|
|
3238
3263
|
v(e) || a.push({
|
|
3239
3264
|
ruleId: "aria-meter-name",
|
|
3240
3265
|
selector: m(e),
|
|
3241
|
-
html:
|
|
3266
|
+
html: d(e),
|
|
3242
3267
|
impact: "serious",
|
|
3243
3268
|
message: "Meter has no accessible name."
|
|
3244
3269
|
});
|
|
3245
3270
|
}
|
|
3246
3271
|
return a;
|
|
3247
3272
|
}
|
|
3248
|
-
},
|
|
3273
|
+
}, Ha = {
|
|
3249
3274
|
id: "aria-progressbar-name",
|
|
3250
3275
|
wcag: ["4.1.2"],
|
|
3251
3276
|
level: "A",
|
|
@@ -3255,18 +3280,18 @@ const Ta = {
|
|
|
3255
3280
|
run(t) {
|
|
3256
3281
|
const a = [];
|
|
3257
3282
|
for (const e of t.querySelectorAll('[role="progressbar"], progress')) {
|
|
3258
|
-
if (
|
|
3283
|
+
if (g(e)) continue;
|
|
3259
3284
|
v(e) || a.push({
|
|
3260
3285
|
ruleId: "aria-progressbar-name",
|
|
3261
3286
|
selector: m(e),
|
|
3262
|
-
html:
|
|
3287
|
+
html: d(e),
|
|
3263
3288
|
impact: "serious",
|
|
3264
3289
|
message: "Progressbar has no accessible name."
|
|
3265
3290
|
});
|
|
3266
3291
|
}
|
|
3267
3292
|
return a;
|
|
3268
3293
|
}
|
|
3269
|
-
},
|
|
3294
|
+
}, Da = {
|
|
3270
3295
|
id: "aria-dialog-name",
|
|
3271
3296
|
wcag: ["4.1.2"],
|
|
3272
3297
|
level: "A",
|
|
@@ -3276,18 +3301,18 @@ const Ta = {
|
|
|
3276
3301
|
run(t) {
|
|
3277
3302
|
const a = [];
|
|
3278
3303
|
for (const e of t.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog')) {
|
|
3279
|
-
if (
|
|
3304
|
+
if (g(e)) continue;
|
|
3280
3305
|
v(e) || a.push({
|
|
3281
3306
|
ruleId: "aria-dialog-name",
|
|
3282
3307
|
selector: m(e),
|
|
3283
|
-
html:
|
|
3308
|
+
html: d(e),
|
|
3284
3309
|
impact: "serious",
|
|
3285
3310
|
message: "Dialog has no accessible name."
|
|
3286
3311
|
});
|
|
3287
3312
|
}
|
|
3288
3313
|
return a;
|
|
3289
3314
|
}
|
|
3290
|
-
},
|
|
3315
|
+
}, Oa = {
|
|
3291
3316
|
id: "aria-tooltip-name",
|
|
3292
3317
|
wcag: ["4.1.2"],
|
|
3293
3318
|
level: "A",
|
|
@@ -3297,18 +3322,18 @@ const Ta = {
|
|
|
3297
3322
|
run(t) {
|
|
3298
3323
|
const a = [];
|
|
3299
3324
|
for (const e of t.querySelectorAll('[role="tooltip"]')) {
|
|
3300
|
-
if (
|
|
3325
|
+
if (g(e)) continue;
|
|
3301
3326
|
v(e) || a.push({
|
|
3302
3327
|
ruleId: "aria-tooltip-name",
|
|
3303
3328
|
selector: m(e),
|
|
3304
|
-
html:
|
|
3329
|
+
html: d(e),
|
|
3305
3330
|
impact: "serious",
|
|
3306
3331
|
message: "Tooltip has no accessible name."
|
|
3307
3332
|
});
|
|
3308
3333
|
}
|
|
3309
3334
|
return a;
|
|
3310
3335
|
}
|
|
3311
|
-
},
|
|
3336
|
+
}, Ba = {
|
|
3312
3337
|
id: "aria-treeitem-name",
|
|
3313
3338
|
wcag: ["4.1.2"],
|
|
3314
3339
|
level: "A",
|
|
@@ -3318,18 +3343,18 @@ const Ta = {
|
|
|
3318
3343
|
run(t) {
|
|
3319
3344
|
const a = [];
|
|
3320
3345
|
for (const e of t.querySelectorAll('[role="treeitem"]')) {
|
|
3321
|
-
if (
|
|
3346
|
+
if (g(e)) continue;
|
|
3322
3347
|
v(e) || a.push({
|
|
3323
3348
|
ruleId: "aria-treeitem-name",
|
|
3324
3349
|
selector: m(e),
|
|
3325
|
-
html:
|
|
3350
|
+
html: d(e),
|
|
3326
3351
|
impact: "serious",
|
|
3327
3352
|
message: "Treeitem has no accessible name."
|
|
3328
3353
|
});
|
|
3329
3354
|
}
|
|
3330
3355
|
return a;
|
|
3331
3356
|
}
|
|
3332
|
-
},
|
|
3357
|
+
}, Fa = {
|
|
3333
3358
|
id: "aria-prohibited-attr",
|
|
3334
3359
|
wcag: ["4.1.2"],
|
|
3335
3360
|
level: "A",
|
|
@@ -3337,16 +3362,16 @@ const Ta = {
|
|
|
3337
3362
|
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
3363
|
prompt: "Identify the prohibited attribute and recommend removing it from this element.",
|
|
3339
3364
|
run(t) {
|
|
3340
|
-
return
|
|
3365
|
+
return U(t).prohibitedAttr;
|
|
3341
3366
|
}
|
|
3342
|
-
},
|
|
3367
|
+
}, Wa = [
|
|
3343
3368
|
"a[href]",
|
|
3344
3369
|
"button:not([disabled])",
|
|
3345
3370
|
'input:not([disabled]):not([type="hidden"])',
|
|
3346
3371
|
"select:not([disabled])",
|
|
3347
3372
|
"textarea:not([disabled])",
|
|
3348
3373
|
'[tabindex]:not([tabindex="-1"])'
|
|
3349
|
-
].join(", "),
|
|
3374
|
+
].join(", "), _a = [
|
|
3350
3375
|
"aria-atomic",
|
|
3351
3376
|
"aria-busy",
|
|
3352
3377
|
"aria-controls",
|
|
@@ -3361,17 +3386,17 @@ const Ta = {
|
|
|
3361
3386
|
"aria-owns",
|
|
3362
3387
|
"aria-relevant"
|
|
3363
3388
|
];
|
|
3364
|
-
function
|
|
3389
|
+
function oe(t) {
|
|
3365
3390
|
const a = [];
|
|
3366
|
-
t.matches(
|
|
3367
|
-
for (const e of
|
|
3391
|
+
t.matches(Wa) && a.push("element is focusable");
|
|
3392
|
+
for (const e of _a)
|
|
3368
3393
|
if (t.hasAttribute(e)) {
|
|
3369
3394
|
a.push(`has ${e}`);
|
|
3370
3395
|
break;
|
|
3371
3396
|
}
|
|
3372
3397
|
return (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && a.push("has accessible name"), a;
|
|
3373
3398
|
}
|
|
3374
|
-
const
|
|
3399
|
+
const Pa = {
|
|
3375
3400
|
id: "presentation-role-conflict",
|
|
3376
3401
|
wcag: ["4.1.2"],
|
|
3377
3402
|
level: "A",
|
|
@@ -3381,30 +3406,30 @@ const Wa = {
|
|
|
3381
3406
|
run(t) {
|
|
3382
3407
|
const a = [];
|
|
3383
3408
|
for (const e of t.querySelectorAll('[role="presentation"], [role="none"]')) {
|
|
3384
|
-
if (
|
|
3385
|
-
const i =
|
|
3409
|
+
if (g(e)) continue;
|
|
3410
|
+
const i = oe(e);
|
|
3386
3411
|
i.length > 0 && a.push({
|
|
3387
3412
|
ruleId: "presentation-role-conflict",
|
|
3388
3413
|
selector: m(e),
|
|
3389
|
-
html:
|
|
3414
|
+
html: d(e),
|
|
3390
3415
|
impact: "serious",
|
|
3391
3416
|
message: `Presentation role conflicts with: ${i.join(", ")}. The role will be ignored.`
|
|
3392
3417
|
});
|
|
3393
3418
|
}
|
|
3394
3419
|
for (const e of t.querySelectorAll('img[alt=""]')) {
|
|
3395
|
-
if (
|
|
3396
|
-
const i =
|
|
3420
|
+
if (g(e) || e.hasAttribute("role")) continue;
|
|
3421
|
+
const i = oe(e);
|
|
3397
3422
|
i.length > 0 && a.push({
|
|
3398
3423
|
ruleId: "presentation-role-conflict",
|
|
3399
3424
|
selector: m(e),
|
|
3400
|
-
html:
|
|
3425
|
+
html: d(e),
|
|
3401
3426
|
impact: "serious",
|
|
3402
3427
|
message: `Element with implicit presentation role (alt="") conflicts with: ${i.join(", ")}. The decorative role will be ignored.`
|
|
3403
3428
|
});
|
|
3404
3429
|
}
|
|
3405
3430
|
return a;
|
|
3406
3431
|
}
|
|
3407
|
-
},
|
|
3432
|
+
}, ja = {
|
|
3408
3433
|
id: "summary-name",
|
|
3409
3434
|
wcag: ["4.1.2"],
|
|
3410
3435
|
level: "A",
|
|
@@ -3414,11 +3439,11 @@ const Wa = {
|
|
|
3414
3439
|
run(t) {
|
|
3415
3440
|
const a = [];
|
|
3416
3441
|
for (const e of t.querySelectorAll("details > summary:first-of-type")) {
|
|
3417
|
-
if (
|
|
3442
|
+
if (g(e)) continue;
|
|
3418
3443
|
v(e) || a.push({
|
|
3419
3444
|
ruleId: "summary-name",
|
|
3420
3445
|
selector: m(e),
|
|
3421
|
-
html:
|
|
3446
|
+
html: d(e),
|
|
3422
3447
|
impact: "serious",
|
|
3423
3448
|
message: "<summary> element has no accessible name. Add descriptive text."
|
|
3424
3449
|
});
|
|
@@ -3426,7 +3451,7 @@ const Wa = {
|
|
|
3426
3451
|
return a;
|
|
3427
3452
|
}
|
|
3428
3453
|
};
|
|
3429
|
-
function
|
|
3454
|
+
function Va(t) {
|
|
3430
3455
|
var n, r;
|
|
3431
3456
|
const a = [], e = t.getAttribute("href");
|
|
3432
3457
|
e && a.push(`href: ${e}`);
|
|
@@ -3443,7 +3468,7 @@ function Pa(t) {
|
|
|
3443
3468
|
return a.length > 0 ? a.join(`
|
|
3444
3469
|
`) : void 0;
|
|
3445
3470
|
}
|
|
3446
|
-
const
|
|
3471
|
+
const za = {
|
|
3447
3472
|
id: "link-name",
|
|
3448
3473
|
wcag: ["2.4.4", "4.1.2"],
|
|
3449
3474
|
level: "A",
|
|
@@ -3453,19 +3478,19 @@ const ja = {
|
|
|
3453
3478
|
run(t) {
|
|
3454
3479
|
const a = [];
|
|
3455
3480
|
for (const e of t.querySelectorAll('a[href], area[href], [role="link"]')) {
|
|
3456
|
-
if (
|
|
3481
|
+
if (g(e) || T(e) || e.getRootNode() instanceof ShadowRoot) continue;
|
|
3457
3482
|
v(e) || a.push({
|
|
3458
3483
|
ruleId: "link-name",
|
|
3459
3484
|
selector: m(e),
|
|
3460
|
-
html:
|
|
3485
|
+
html: d(e),
|
|
3461
3486
|
impact: "serious",
|
|
3462
3487
|
message: "Link has no discernible text.",
|
|
3463
|
-
context:
|
|
3488
|
+
context: Va(e)
|
|
3464
3489
|
});
|
|
3465
3490
|
}
|
|
3466
3491
|
return a;
|
|
3467
3492
|
}
|
|
3468
|
-
},
|
|
3493
|
+
}, Ua = {
|
|
3469
3494
|
id: "skip-link",
|
|
3470
3495
|
wcag: ["2.4.1"],
|
|
3471
3496
|
level: "A",
|
|
@@ -3478,20 +3503,20 @@ const ja = {
|
|
|
3478
3503
|
for (const i of e) {
|
|
3479
3504
|
const n = i.getAttribute("href");
|
|
3480
3505
|
if (!n || n === "#") continue;
|
|
3481
|
-
const r =
|
|
3506
|
+
const r = A(i).toLowerCase();
|
|
3482
3507
|
if (!(r.includes("skip") || r.includes("jump") || r.includes("main content") || r.includes("navigation"))) continue;
|
|
3483
3508
|
const s = n.slice(1);
|
|
3484
3509
|
t.getElementById(s) || a.push({
|
|
3485
3510
|
ruleId: "skip-link",
|
|
3486
3511
|
selector: m(i),
|
|
3487
|
-
html:
|
|
3512
|
+
html: d(i),
|
|
3488
3513
|
impact: "moderate",
|
|
3489
3514
|
message: `Skip link points to "#${s}" which does not exist on the page.`
|
|
3490
3515
|
});
|
|
3491
3516
|
}
|
|
3492
3517
|
return a;
|
|
3493
3518
|
}
|
|
3494
|
-
},
|
|
3519
|
+
}, Ga = /* @__PURE__ */ new Set([
|
|
3495
3520
|
"block",
|
|
3496
3521
|
"flex",
|
|
3497
3522
|
"grid",
|
|
@@ -3499,23 +3524,23 @@ const ja = {
|
|
|
3499
3524
|
"table-cell",
|
|
3500
3525
|
"list-item",
|
|
3501
3526
|
"flow-root"
|
|
3502
|
-
]),
|
|
3527
|
+
]), Ya = /* @__PURE__ */ new Set([
|
|
3503
3528
|
"inline",
|
|
3504
3529
|
"inline-block",
|
|
3505
3530
|
"inline-flex",
|
|
3506
3531
|
"inline-grid"
|
|
3507
3532
|
]);
|
|
3508
|
-
function
|
|
3533
|
+
function Xa(t) {
|
|
3509
3534
|
let a = t.parentElement;
|
|
3510
3535
|
for (; a; ) {
|
|
3511
|
-
const e =
|
|
3512
|
-
if (
|
|
3513
|
-
return
|
|
3536
|
+
const e = w(a).display;
|
|
3537
|
+
if (Ga.has(e))
|
|
3538
|
+
return Ka(a) ? a : null;
|
|
3514
3539
|
a = a.parentElement;
|
|
3515
3540
|
}
|
|
3516
3541
|
return null;
|
|
3517
3542
|
}
|
|
3518
|
-
function
|
|
3543
|
+
function Ka(t) {
|
|
3519
3544
|
const a = t.ownerDocument.createTreeWalker(
|
|
3520
3545
|
t,
|
|
3521
3546
|
NodeFilter.SHOW_TEXT
|
|
@@ -3535,7 +3560,7 @@ function Xa(t) {
|
|
|
3535
3560
|
}
|
|
3536
3561
|
return /[a-zA-Z\u00C0-\u024F]{2,}/.test(e);
|
|
3537
3562
|
}
|
|
3538
|
-
function
|
|
3563
|
+
function Ja(t, a) {
|
|
3539
3564
|
const e = t.ownerDocument.createTreeWalker(
|
|
3540
3565
|
t,
|
|
3541
3566
|
NodeFilter.SHOW_TEXT
|
|
@@ -3552,11 +3577,11 @@ function Ya(t, a) {
|
|
|
3552
3577
|
o = o.parentElement;
|
|
3553
3578
|
}
|
|
3554
3579
|
if (!r && n)
|
|
3555
|
-
return
|
|
3580
|
+
return N(w(n).color);
|
|
3556
3581
|
}
|
|
3557
3582
|
return null;
|
|
3558
3583
|
}
|
|
3559
|
-
function
|
|
3584
|
+
function Qa(t, a) {
|
|
3560
3585
|
const e = t.textDecorationLine || t.textDecoration || "", i = a.textDecorationLine || a.textDecoration || "";
|
|
3561
3586
|
if ((e.includes("underline") || e.includes("line-through")) && e !== i)
|
|
3562
3587
|
return !0;
|
|
@@ -3569,19 +3594,19 @@ function Ka(t, a) {
|
|
|
3569
3594
|
const l = t.backgroundImage || "";
|
|
3570
3595
|
if (l && l !== "none" && l !== "initial")
|
|
3571
3596
|
return !0;
|
|
3572
|
-
const h =
|
|
3597
|
+
const h = se(t.fontWeight), c = se(a.fontWeight);
|
|
3573
3598
|
if (Math.abs(h - c) >= 300 || t.fontStyle !== a.fontStyle)
|
|
3574
3599
|
return !0;
|
|
3575
|
-
const
|
|
3576
|
-
return
|
|
3600
|
+
const u = parseFloat(t.fontSize) || 16, p = parseFloat(a.fontSize) || 16;
|
|
3601
|
+
return p > 0 && u / p >= 1.2;
|
|
3577
3602
|
}
|
|
3578
|
-
function
|
|
3603
|
+
function se(t) {
|
|
3579
3604
|
return t === "bold" ? 700 : t === "normal" ? 400 : parseInt(t) || 400;
|
|
3580
3605
|
}
|
|
3581
|
-
function
|
|
3606
|
+
function le(t, a, e) {
|
|
3582
3607
|
return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
3583
3608
|
}
|
|
3584
|
-
const
|
|
3609
|
+
const Za = {
|
|
3585
3610
|
id: "link-in-text-block",
|
|
3586
3611
|
wcag: ["1.4.1"],
|
|
3587
3612
|
level: "A",
|
|
@@ -3591,22 +3616,22 @@ const Ja = {
|
|
|
3591
3616
|
run(t) {
|
|
3592
3617
|
const a = [];
|
|
3593
3618
|
for (const e of t.querySelectorAll("a[href]")) {
|
|
3594
|
-
if (
|
|
3595
|
-
const i =
|
|
3596
|
-
if (!
|
|
3597
|
-
const r =
|
|
3619
|
+
if (g(e) || !A(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
|
|
3620
|
+
const i = w(e), n = i.display || "inline";
|
|
3621
|
+
if (!Ya.has(n)) continue;
|
|
3622
|
+
const r = Xa(e);
|
|
3598
3623
|
if (!r) continue;
|
|
3599
|
-
const o =
|
|
3600
|
-
if (
|
|
3601
|
-
const s =
|
|
3624
|
+
const o = w(r);
|
|
3625
|
+
if (Qa(i, o)) continue;
|
|
3626
|
+
const s = N(i.color), l = Ja(r);
|
|
3602
3627
|
if (!s || !l) continue;
|
|
3603
|
-
const h =
|
|
3604
|
-
if (
|
|
3605
|
-
const
|
|
3628
|
+
const h = R(...s), c = R(...l), u = me(h, c);
|
|
3629
|
+
if (u >= 3) continue;
|
|
3630
|
+
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
3631
|
a.push({
|
|
3607
3632
|
ruleId: "link-in-text-block",
|
|
3608
3633
|
selector: m(e),
|
|
3609
|
-
html:
|
|
3634
|
+
html: d(e),
|
|
3610
3635
|
impact: "serious",
|
|
3611
3636
|
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
3637
|
context: f
|
|
@@ -3614,7 +3639,7 @@ const Ja = {
|
|
|
3614
3639
|
}
|
|
3615
3640
|
return a;
|
|
3616
3641
|
}
|
|
3617
|
-
},
|
|
3642
|
+
}, ei = {
|
|
3618
3643
|
id: "html-has-lang",
|
|
3619
3644
|
wcag: ["3.1.1"],
|
|
3620
3645
|
level: "A",
|
|
@@ -3640,7 +3665,7 @@ const Ja = {
|
|
|
3640
3665
|
return [{
|
|
3641
3666
|
ruleId: "html-has-lang",
|
|
3642
3667
|
selector: m(a),
|
|
3643
|
-
html:
|
|
3668
|
+
html: d(a),
|
|
3644
3669
|
impact: "serious",
|
|
3645
3670
|
message: "<html> element missing lang attribute.",
|
|
3646
3671
|
context: n ? `Page text sample: "${n}"` : void 0
|
|
@@ -3648,17 +3673,17 @@ const Ja = {
|
|
|
3648
3673
|
}
|
|
3649
3674
|
return [];
|
|
3650
3675
|
}
|
|
3651
|
-
},
|
|
3676
|
+
}, ti = new Set(
|
|
3652
3677
|
"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
|
-
),
|
|
3678
|
+
), ai = new Set(
|
|
3654
3679
|
"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 (!
|
|
3680
|
+
), ii = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
|
|
3681
|
+
function pe(t) {
|
|
3682
|
+
if (!ii.test(t)) return !1;
|
|
3658
3683
|
const a = t.split("-")[0].toLowerCase();
|
|
3659
|
-
return a.length === 2 ?
|
|
3684
|
+
return a.length === 2 ? ti.has(a) : a.length === 3 ? !ai.has(a) : !1;
|
|
3660
3685
|
}
|
|
3661
|
-
const
|
|
3686
|
+
const ni = {
|
|
3662
3687
|
id: "html-lang-valid",
|
|
3663
3688
|
wcag: ["3.1.1"],
|
|
3664
3689
|
level: "A",
|
|
@@ -3668,16 +3693,16 @@ const ai = {
|
|
|
3668
3693
|
run(t) {
|
|
3669
3694
|
var e;
|
|
3670
3695
|
const a = (e = t.documentElement.getAttribute("lang")) == null ? void 0 : e.trim();
|
|
3671
|
-
return a && !
|
|
3696
|
+
return a && !pe(a) ? [{
|
|
3672
3697
|
ruleId: "html-lang-valid",
|
|
3673
3698
|
selector: "html",
|
|
3674
|
-
html:
|
|
3699
|
+
html: d(t.documentElement),
|
|
3675
3700
|
impact: "serious",
|
|
3676
3701
|
message: `Invalid lang attribute value "${a}".`
|
|
3677
3702
|
}] : [];
|
|
3678
3703
|
}
|
|
3679
3704
|
};
|
|
3680
|
-
function
|
|
3705
|
+
function ce(t) {
|
|
3681
3706
|
var i;
|
|
3682
3707
|
const a = t.ownerDocument.createTreeWalker(t, NodeFilter.SHOW_TEXT);
|
|
3683
3708
|
let e;
|
|
@@ -3709,7 +3734,7 @@ function le(t) {
|
|
|
3709
3734
|
}
|
|
3710
3735
|
return !1;
|
|
3711
3736
|
}
|
|
3712
|
-
const
|
|
3737
|
+
const ri = {
|
|
3713
3738
|
id: "valid-lang",
|
|
3714
3739
|
wcag: ["3.1.2"],
|
|
3715
3740
|
level: "AA",
|
|
@@ -3719,29 +3744,29 @@ const ii = {
|
|
|
3719
3744
|
run(t) {
|
|
3720
3745
|
const a = [];
|
|
3721
3746
|
for (const e of t.querySelectorAll("[lang]")) {
|
|
3722
|
-
if (
|
|
3747
|
+
if (g(e) || e === t.documentElement) continue;
|
|
3723
3748
|
const i = e.getAttribute("lang"), n = i == null ? void 0 : i.trim();
|
|
3724
3749
|
if (i && !n) {
|
|
3725
|
-
|
|
3750
|
+
ce(e) && a.push({
|
|
3726
3751
|
ruleId: "valid-lang",
|
|
3727
3752
|
selector: m(e),
|
|
3728
|
-
html:
|
|
3753
|
+
html: d(e),
|
|
3729
3754
|
impact: "serious",
|
|
3730
3755
|
message: "Empty lang attribute value."
|
|
3731
3756
|
});
|
|
3732
3757
|
continue;
|
|
3733
3758
|
}
|
|
3734
|
-
n &&
|
|
3759
|
+
n && ce(e) && (pe(n) || a.push({
|
|
3735
3760
|
ruleId: "valid-lang",
|
|
3736
3761
|
selector: m(e),
|
|
3737
|
-
html:
|
|
3762
|
+
html: d(e),
|
|
3738
3763
|
impact: "serious",
|
|
3739
3764
|
message: `Invalid lang attribute value "${n}".`
|
|
3740
3765
|
}));
|
|
3741
3766
|
}
|
|
3742
3767
|
return a;
|
|
3743
3768
|
}
|
|
3744
|
-
},
|
|
3769
|
+
}, oi = {
|
|
3745
3770
|
id: "html-xml-lang-mismatch",
|
|
3746
3771
|
wcag: ["3.1.1"],
|
|
3747
3772
|
level: "A",
|
|
@@ -3757,14 +3782,14 @@ const ii = {
|
|
|
3757
3782
|
return [{
|
|
3758
3783
|
ruleId: "html-xml-lang-mismatch",
|
|
3759
3784
|
selector: "html",
|
|
3760
|
-
html:
|
|
3785
|
+
html: d(a),
|
|
3761
3786
|
impact: "moderate",
|
|
3762
3787
|
message: `lang="${e}" and xml:lang="${i}" do not match.`
|
|
3763
3788
|
}];
|
|
3764
3789
|
}
|
|
3765
3790
|
return [];
|
|
3766
3791
|
}
|
|
3767
|
-
},
|
|
3792
|
+
}, si = {
|
|
3768
3793
|
id: "td-headers-attr",
|
|
3769
3794
|
wcag: ["1.3.1"],
|
|
3770
3795
|
level: "A",
|
|
@@ -3774,7 +3799,7 @@ const ii = {
|
|
|
3774
3799
|
run(t) {
|
|
3775
3800
|
const a = [];
|
|
3776
3801
|
for (const e of t.querySelectorAll("td[headers]")) {
|
|
3777
|
-
if (
|
|
3802
|
+
if (g(e)) continue;
|
|
3778
3803
|
const i = e.closest("table");
|
|
3779
3804
|
if (!i) continue;
|
|
3780
3805
|
const n = e.getAttribute("id"), r = e.getAttribute("headers").split(/\s+/);
|
|
@@ -3783,7 +3808,7 @@ const ii = {
|
|
|
3783
3808
|
a.push({
|
|
3784
3809
|
ruleId: "td-headers-attr",
|
|
3785
3810
|
selector: m(e),
|
|
3786
|
-
html:
|
|
3811
|
+
html: d(e),
|
|
3787
3812
|
impact: "serious",
|
|
3788
3813
|
message: `Headers attribute references the cell itself ("${o}").`
|
|
3789
3814
|
});
|
|
@@ -3793,7 +3818,7 @@ const ii = {
|
|
|
3793
3818
|
a.push({
|
|
3794
3819
|
ruleId: "td-headers-attr",
|
|
3795
3820
|
selector: m(e),
|
|
3796
|
-
html:
|
|
3821
|
+
html: d(e),
|
|
3797
3822
|
impact: "serious",
|
|
3798
3823
|
message: `Headers attribute references non-existent ID "${o}".`
|
|
3799
3824
|
});
|
|
@@ -3803,7 +3828,7 @@ const ii = {
|
|
|
3803
3828
|
}
|
|
3804
3829
|
return a;
|
|
3805
3830
|
}
|
|
3806
|
-
},
|
|
3831
|
+
}, li = {
|
|
3807
3832
|
id: "th-has-data-cells",
|
|
3808
3833
|
wcag: ["1.3.1"],
|
|
3809
3834
|
level: "A",
|
|
@@ -3813,19 +3838,19 @@ const ii = {
|
|
|
3813
3838
|
run(t) {
|
|
3814
3839
|
const a = [];
|
|
3815
3840
|
for (const e of t.querySelectorAll("table")) {
|
|
3816
|
-
if (
|
|
3841
|
+
if (g(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
|
|
3817
3842
|
const i = e.querySelectorAll("th"), n = e.querySelectorAll("td");
|
|
3818
3843
|
i.length > 0 && n.length === 0 && a.push({
|
|
3819
3844
|
ruleId: "th-has-data-cells",
|
|
3820
3845
|
selector: m(e),
|
|
3821
|
-
html:
|
|
3846
|
+
html: d(e),
|
|
3822
3847
|
impact: "serious",
|
|
3823
3848
|
message: "Table has header cells but no data cells."
|
|
3824
3849
|
});
|
|
3825
3850
|
}
|
|
3826
3851
|
return a;
|
|
3827
3852
|
}
|
|
3828
|
-
},
|
|
3853
|
+
}, ci = {
|
|
3829
3854
|
id: "td-has-header",
|
|
3830
3855
|
wcag: ["1.3.1"],
|
|
3831
3856
|
level: "A",
|
|
@@ -3836,24 +3861,24 @@ const ii = {
|
|
|
3836
3861
|
var e, i;
|
|
3837
3862
|
const a = [];
|
|
3838
3863
|
for (const n of t.querySelectorAll("table")) {
|
|
3839
|
-
if (
|
|
3864
|
+
if (g(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
|
|
3840
3865
|
const r = n.querySelectorAll("tr"), o = r.length;
|
|
3841
3866
|
let s = 0;
|
|
3842
|
-
for (const
|
|
3843
|
-
const
|
|
3867
|
+
for (const u of r) {
|
|
3868
|
+
const p = u.querySelectorAll("td, th");
|
|
3844
3869
|
let b = 0;
|
|
3845
|
-
for (const f of
|
|
3870
|
+
for (const f of p)
|
|
3846
3871
|
b += parseInt(f.getAttribute("colspan") || "1", 10);
|
|
3847
3872
|
s = Math.max(s, b);
|
|
3848
3873
|
}
|
|
3849
3874
|
if (o <= 3 && s <= 3) continue;
|
|
3850
3875
|
const l = n.querySelector("th") !== null, h = n.querySelector("th[scope]") !== null, c = n.querySelector("td[headers]") !== null;
|
|
3851
3876
|
if (l)
|
|
3852
|
-
for (const
|
|
3853
|
-
if (
|
|
3854
|
-
const
|
|
3855
|
-
if (!
|
|
3856
|
-
const b =
|
|
3877
|
+
for (const u of n.querySelectorAll("td")) {
|
|
3878
|
+
if (g(u) || u.hasAttribute("headers")) continue;
|
|
3879
|
+
const p = u.closest("tr");
|
|
3880
|
+
if (!p) continue;
|
|
3881
|
+
const b = p.querySelector("th") !== null, f = Array.from(p.children).indexOf(u);
|
|
3857
3882
|
let y = !1;
|
|
3858
3883
|
const I = n.querySelector("thead");
|
|
3859
3884
|
if (I) {
|
|
@@ -3867,8 +3892,8 @@ const ii = {
|
|
|
3867
3892
|
if (!b && !y && !h && !c) {
|
|
3868
3893
|
a.push({
|
|
3869
3894
|
ruleId: "td-has-header",
|
|
3870
|
-
selector: m(
|
|
3871
|
-
html: u
|
|
3895
|
+
selector: m(u),
|
|
3896
|
+
html: d(u),
|
|
3872
3897
|
impact: "serious",
|
|
3873
3898
|
message: "Data cell has no associated header. Add th elements with scope, or headers attribute."
|
|
3874
3899
|
});
|
|
@@ -3878,7 +3903,7 @@ const ii = {
|
|
|
3878
3903
|
}
|
|
3879
3904
|
return a;
|
|
3880
3905
|
}
|
|
3881
|
-
},
|
|
3906
|
+
}, ui = {
|
|
3882
3907
|
id: "scope-attr-valid",
|
|
3883
3908
|
wcag: ["1.3.1"],
|
|
3884
3909
|
level: "A",
|
|
@@ -3889,19 +3914,19 @@ const ii = {
|
|
|
3889
3914
|
var i;
|
|
3890
3915
|
const a = [], e = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
|
|
3891
3916
|
for (const n of t.querySelectorAll("th[scope]")) {
|
|
3892
|
-
if (
|
|
3917
|
+
if (g(n)) continue;
|
|
3893
3918
|
const r = (i = n.getAttribute("scope")) == null ? void 0 : i.toLowerCase();
|
|
3894
3919
|
r && !e.has(r) && a.push({
|
|
3895
3920
|
ruleId: "scope-attr-valid",
|
|
3896
3921
|
selector: m(n),
|
|
3897
|
-
html:
|
|
3922
|
+
html: d(n),
|
|
3898
3923
|
impact: "moderate",
|
|
3899
3924
|
message: `Invalid scope value "${r}". Use row, col, rowgroup, or colgroup.`
|
|
3900
3925
|
});
|
|
3901
3926
|
}
|
|
3902
3927
|
return a;
|
|
3903
3928
|
}
|
|
3904
|
-
},
|
|
3929
|
+
}, di = {
|
|
3905
3930
|
id: "empty-table-header",
|
|
3906
3931
|
wcag: [],
|
|
3907
3932
|
level: "A",
|
|
@@ -3912,19 +3937,19 @@ const ii = {
|
|
|
3912
3937
|
run(t) {
|
|
3913
3938
|
const a = [];
|
|
3914
3939
|
for (const e of t.querySelectorAll("th")) {
|
|
3915
|
-
if (
|
|
3940
|
+
if (g(e)) continue;
|
|
3916
3941
|
const i = e.closest("table");
|
|
3917
3942
|
(i == null ? void 0 : i.getAttribute("role")) === "presentation" || (i == null ? void 0 : i.getAttribute("role")) === "none" || v(e) || a.push({
|
|
3918
3943
|
ruleId: "empty-table-header",
|
|
3919
3944
|
selector: m(e),
|
|
3920
|
-
html:
|
|
3945
|
+
html: d(e),
|
|
3921
3946
|
impact: "minor",
|
|
3922
3947
|
message: "Table header cell is empty. Add text or use aria-label."
|
|
3923
3948
|
});
|
|
3924
3949
|
}
|
|
3925
3950
|
return a;
|
|
3926
3951
|
}
|
|
3927
|
-
},
|
|
3952
|
+
}, O = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], mi = {
|
|
3928
3953
|
id: "duplicate-id-aria",
|
|
3929
3954
|
wcag: ["4.1.2"],
|
|
3930
3955
|
level: "A",
|
|
@@ -3934,7 +3959,7 @@ const ii = {
|
|
|
3934
3959
|
run(t) {
|
|
3935
3960
|
const a = [], e = /* @__PURE__ */ new Set();
|
|
3936
3961
|
for (const n of t.querySelectorAll("[aria-labelledby], [aria-describedby], [aria-controls], [aria-owns], [aria-flowto]"))
|
|
3937
|
-
for (const r of
|
|
3962
|
+
for (const r of O) {
|
|
3938
3963
|
const o = n.getAttribute(r);
|
|
3939
3964
|
o && o.split(/\s+/).forEach((s) => e.add(s));
|
|
3940
3965
|
}
|
|
@@ -3948,14 +3973,14 @@ const ii = {
|
|
|
3948
3973
|
for (const [n, r] of i) {
|
|
3949
3974
|
if (r <= 1) continue;
|
|
3950
3975
|
const o = t.querySelectorAll(`#${CSS.escape(n)}`), s = t.querySelector(
|
|
3951
|
-
|
|
3976
|
+
O.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
|
|
3952
3977
|
), l = t.querySelector(`label[for="${CSS.escape(n)}"]`);
|
|
3953
3978
|
let h;
|
|
3954
3979
|
if (s) {
|
|
3955
|
-
const c =
|
|
3956
|
-
(
|
|
3957
|
-
var
|
|
3958
|
-
return (
|
|
3980
|
+
const c = O.find(
|
|
3981
|
+
(u) => {
|
|
3982
|
+
var p;
|
|
3983
|
+
return (p = s.getAttribute(u)) == null ? void 0 : p.split(/\s+/).includes(n);
|
|
3959
3984
|
}
|
|
3960
3985
|
);
|
|
3961
3986
|
c && (h = c);
|
|
@@ -3963,16 +3988,16 @@ const ii = {
|
|
|
3963
3988
|
a.push({
|
|
3964
3989
|
ruleId: "duplicate-id-aria",
|
|
3965
3990
|
selector: m(o[1]),
|
|
3966
|
-
html:
|
|
3991
|
+
html: d(o[1]),
|
|
3967
3992
|
impact: "critical",
|
|
3968
3993
|
message: `Duplicate ID "${n}" referenced by ${h ?? "an accessibility attribute"}.`,
|
|
3969
|
-
context: `First element: ${
|
|
3994
|
+
context: `First element: ${d(o[0])}${h ? `
|
|
3970
3995
|
Referenced by: ${h}` : ""}`
|
|
3971
3996
|
});
|
|
3972
3997
|
}
|
|
3973
3998
|
return a;
|
|
3974
3999
|
}
|
|
3975
|
-
},
|
|
4000
|
+
}, hi = {
|
|
3976
4001
|
id: "video-caption",
|
|
3977
4002
|
wcag: ["1.2.2"],
|
|
3978
4003
|
level: "A",
|
|
@@ -3982,18 +4007,18 @@ Referenced by: ${h}` : ""}`
|
|
|
3982
4007
|
run(t) {
|
|
3983
4008
|
const a = [];
|
|
3984
4009
|
for (const e of t.querySelectorAll("video")) {
|
|
3985
|
-
if (
|
|
4010
|
+
if (g(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
|
|
3986
4011
|
e.querySelector('track[kind="captions"], track[kind="subtitles"]') || a.push({
|
|
3987
4012
|
ruleId: "video-caption",
|
|
3988
4013
|
selector: m(e),
|
|
3989
|
-
html:
|
|
4014
|
+
html: d(e),
|
|
3990
4015
|
impact: "critical",
|
|
3991
4016
|
message: "Video element has no captions track."
|
|
3992
4017
|
});
|
|
3993
4018
|
}
|
|
3994
4019
|
return a;
|
|
3995
4020
|
}
|
|
3996
|
-
},
|
|
4021
|
+
}, pi = {
|
|
3997
4022
|
id: "audio-caption",
|
|
3998
4023
|
wcag: ["1.2.1"],
|
|
3999
4024
|
level: "A",
|
|
@@ -4003,19 +4028,19 @@ Referenced by: ${h}` : ""}`
|
|
|
4003
4028
|
run(t) {
|
|
4004
4029
|
const a = [];
|
|
4005
4030
|
for (const e of t.querySelectorAll("audio")) {
|
|
4006
|
-
if (
|
|
4031
|
+
if (g(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
|
|
4007
4032
|
const n = e.parentElement;
|
|
4008
4033
|
n && n.querySelector('a[href*="transcript"], a[href*="text"]') || a.push({
|
|
4009
4034
|
ruleId: "audio-caption",
|
|
4010
4035
|
selector: m(e),
|
|
4011
|
-
html:
|
|
4036
|
+
html: d(e),
|
|
4012
4037
|
impact: "critical",
|
|
4013
4038
|
message: "Audio element has no transcript or text alternative. Add a transcript or track element."
|
|
4014
4039
|
});
|
|
4015
4040
|
}
|
|
4016
4041
|
return a;
|
|
4017
4042
|
}
|
|
4018
|
-
},
|
|
4043
|
+
}, gi = /* @__PURE__ */ new Set([
|
|
4019
4044
|
"SCRIPT",
|
|
4020
4045
|
"STYLE",
|
|
4021
4046
|
"NOSCRIPT",
|
|
@@ -4031,13 +4056,13 @@ Referenced by: ${h}` : ""}`
|
|
|
4031
4056
|
"BR",
|
|
4032
4057
|
"HR"
|
|
4033
4058
|
]);
|
|
4034
|
-
function
|
|
4059
|
+
function ue([t, a, e]) {
|
|
4035
4060
|
return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
4036
4061
|
}
|
|
4037
|
-
function
|
|
4062
|
+
function bi(t) {
|
|
4038
4063
|
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
4064
|
}
|
|
4040
|
-
function
|
|
4065
|
+
function fi(t, a) {
|
|
4041
4066
|
if (t.tagName !== "LABEL") return !1;
|
|
4042
4067
|
const e = t, i = e.htmlFor;
|
|
4043
4068
|
if (i) {
|
|
@@ -4049,7 +4074,7 @@ function gi(t, a) {
|
|
|
4049
4074
|
const r = e.id;
|
|
4050
4075
|
return !!(r && a.querySelector(`[aria-labelledby~="${r}"][aria-disabled="true"]`));
|
|
4051
4076
|
}
|
|
4052
|
-
function
|
|
4077
|
+
function vi(t) {
|
|
4053
4078
|
const a = t.clip;
|
|
4054
4079
|
if (a && a.startsWith("rect(")) {
|
|
4055
4080
|
const i = a.match(/[\d.]+/g);
|
|
@@ -4063,17 +4088,41 @@ function bi(t) {
|
|
|
4063
4088
|
}
|
|
4064
4089
|
return !1;
|
|
4065
4090
|
}
|
|
4066
|
-
function
|
|
4067
|
-
if (
|
|
4091
|
+
function yi(t) {
|
|
4092
|
+
if (g(t)) return !0;
|
|
4093
|
+
let a = t;
|
|
4094
|
+
for (; a; ) {
|
|
4095
|
+
const e = w(a);
|
|
4096
|
+
if (e.display === "none" || e.visibility === "hidden" || vi(e)) return !0;
|
|
4097
|
+
a = a.parentElement;
|
|
4098
|
+
}
|
|
4099
|
+
return !1;
|
|
4100
|
+
}
|
|
4101
|
+
function wi(t) {
|
|
4102
|
+
let a = 1, e = t;
|
|
4103
|
+
for (; e; ) {
|
|
4104
|
+
const i = w(e), n = parseFloat(i.opacity);
|
|
4105
|
+
isNaN(n) || (a *= n), e = e.parentElement;
|
|
4106
|
+
}
|
|
4107
|
+
return a;
|
|
4108
|
+
}
|
|
4109
|
+
function Ai(t) {
|
|
4068
4110
|
let a = t;
|
|
4069
4111
|
for (; a; ) {
|
|
4070
|
-
const e =
|
|
4071
|
-
if (
|
|
4112
|
+
const e = w(a), i = e.filter;
|
|
4113
|
+
if (i && i !== "none" && i !== "initial") return !0;
|
|
4114
|
+
const n = e.mixBlendMode;
|
|
4115
|
+
if (n && n !== "normal" && n !== "initial") return !0;
|
|
4116
|
+
const r = e.backdropFilter;
|
|
4117
|
+
if (r && r !== "none" && r !== "initial") return !0;
|
|
4072
4118
|
a = a.parentElement;
|
|
4073
4119
|
}
|
|
4074
4120
|
return !1;
|
|
4075
4121
|
}
|
|
4076
|
-
|
|
4122
|
+
function xi(t) {
|
|
4123
|
+
return t.closest("select") !== null;
|
|
4124
|
+
}
|
|
4125
|
+
const Si = {
|
|
4077
4126
|
id: "color-contrast",
|
|
4078
4127
|
wcag: ["1.4.3"],
|
|
4079
4128
|
level: "AA",
|
|
@@ -4088,95 +4137,95 @@ const vi = {
|
|
|
4088
4137
|
for (; r = i.nextNode(); ) {
|
|
4089
4138
|
if (!r.textContent || !r.textContent.trim()) continue;
|
|
4090
4139
|
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
|
-
|
|
4140
|
+
if (!o || n.has(o) || (n.add(o), gi.has(o.tagName))) continue;
|
|
4141
|
+
const s = o.tagName;
|
|
4142
|
+
if (s === "BODY" || s === "HTML" || xi(o) || bi(o) || fi(o, t) || yi(o)) continue;
|
|
4143
|
+
const l = w(o);
|
|
4144
|
+
if (parseFloat(l.opacity) === 0 || wi(o) < 0.1) continue;
|
|
4145
|
+
const h = l.textShadow;
|
|
4146
|
+
if (h && h !== "none" && h !== "initial" || Ai(o)) continue;
|
|
4147
|
+
const c = N(l.color);
|
|
4148
|
+
if (!c) continue;
|
|
4149
|
+
const u = l.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || l.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
|
|
4150
|
+
if (u && (u[1].endsWith("%") ? parseFloat(u[1]) / 100 : parseFloat(u[1])) === 0 || _e(o)) continue;
|
|
4151
|
+
const p = Be(o);
|
|
4152
|
+
if (!p) continue;
|
|
4153
|
+
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;
|
|
4154
|
+
if (y < I) {
|
|
4155
|
+
const x = Math.round(y * 100) / 100, M = ue(c), ye = ue(p);
|
|
4105
4156
|
a.push({
|
|
4106
4157
|
ruleId: "color-contrast",
|
|
4107
4158
|
selector: m(o),
|
|
4108
|
-
html:
|
|
4159
|
+
html: d(o),
|
|
4109
4160
|
impact: "serious",
|
|
4110
|
-
message: `Insufficient color contrast ratio of ${
|
|
4111
|
-
context: `foreground: ${
|
|
4161
|
+
message: `Insufficient color contrast ratio of ${x}:1 (required ${I}:1).`,
|
|
4162
|
+
context: `foreground: ${M} rgb(${c.join(", ")}), background: ${ye} rgb(${p.join(", ")}), ratio: ${x}:1, required: ${I}:1`
|
|
4112
4163
|
});
|
|
4113
4164
|
}
|
|
4114
4165
|
}
|
|
4115
4166
|
return a;
|
|
4116
4167
|
}
|
|
4117
|
-
},
|
|
4168
|
+
}, ge = [
|
|
4118
4169
|
// Document Structure
|
|
4119
|
-
Kt,
|
|
4120
|
-
Jt,
|
|
4121
4170
|
Qt,
|
|
4122
4171
|
Zt,
|
|
4123
4172
|
ea,
|
|
4173
|
+
ta,
|
|
4124
4174
|
aa,
|
|
4125
|
-
|
|
4175
|
+
na,
|
|
4126
4176
|
ra,
|
|
4127
4177
|
sa,
|
|
4178
|
+
ca,
|
|
4128
4179
|
// Images
|
|
4129
|
-
je,
|
|
4130
4180
|
ze,
|
|
4131
|
-
Ue,
|
|
4132
4181
|
Ge,
|
|
4133
4182
|
Ye,
|
|
4134
|
-
|
|
4183
|
+
Xe,
|
|
4184
|
+
Je,
|
|
4135
4185
|
Qe,
|
|
4136
|
-
|
|
4137
|
-
|
|
4186
|
+
et,
|
|
4187
|
+
tt,
|
|
4188
|
+
rt,
|
|
4138
4189
|
// Forms
|
|
4139
|
-
lt,
|
|
4140
|
-
ct,
|
|
4141
4190
|
ut,
|
|
4142
4191
|
dt,
|
|
4143
|
-
|
|
4144
|
-
|
|
4192
|
+
mt,
|
|
4193
|
+
ht,
|
|
4145
4194
|
wt,
|
|
4146
|
-
|
|
4195
|
+
At,
|
|
4147
4196
|
xt,
|
|
4197
|
+
// Keyboard
|
|
4148
4198
|
kt,
|
|
4149
|
-
|
|
4150
|
-
Nt,
|
|
4199
|
+
Tt,
|
|
4151
4200
|
$t,
|
|
4152
|
-
// Structure
|
|
4153
4201
|
Mt,
|
|
4154
|
-
ta,
|
|
4155
|
-
la,
|
|
4156
4202
|
Ht,
|
|
4203
|
+
// Structure
|
|
4157
4204
|
Dt,
|
|
4205
|
+
ia,
|
|
4206
|
+
ua,
|
|
4158
4207
|
Ot,
|
|
4159
|
-
Ft,
|
|
4160
4208
|
Bt,
|
|
4209
|
+
Ft,
|
|
4161
4210
|
Wt,
|
|
4162
4211
|
_t,
|
|
4163
4212
|
Pt,
|
|
4164
4213
|
jt,
|
|
4165
4214
|
Vt,
|
|
4215
|
+
zt,
|
|
4166
4216
|
Ut,
|
|
4167
|
-
Gt,
|
|
4168
4217
|
Yt,
|
|
4218
|
+
Xt,
|
|
4219
|
+
Jt,
|
|
4169
4220
|
// ARIA
|
|
4170
|
-
ca,
|
|
4171
|
-
ua,
|
|
4172
4221
|
da,
|
|
4222
|
+
ma,
|
|
4173
4223
|
ha,
|
|
4174
|
-
|
|
4175
|
-
|
|
4224
|
+
ga,
|
|
4225
|
+
wa,
|
|
4176
4226
|
Sa,
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
Ca,
|
|
4227
|
+
Ia,
|
|
4228
|
+
Ta,
|
|
4180
4229
|
La,
|
|
4181
4230
|
qa,
|
|
4182
4231
|
Ra,
|
|
@@ -4186,42 +4235,44 @@ const vi = {
|
|
|
4186
4235
|
Ha,
|
|
4187
4236
|
Da,
|
|
4188
4237
|
Oa,
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4238
|
+
Ba,
|
|
4239
|
+
Fa,
|
|
4240
|
+
Pa,
|
|
4241
|
+
fa,
|
|
4193
4242
|
ja,
|
|
4194
|
-
|
|
4195
|
-
|
|
4243
|
+
// Links
|
|
4244
|
+
za,
|
|
4245
|
+
Ua,
|
|
4246
|
+
Za,
|
|
4196
4247
|
// Language
|
|
4197
|
-
|
|
4198
|
-
ai,
|
|
4199
|
-
ii,
|
|
4248
|
+
ei,
|
|
4200
4249
|
ni,
|
|
4201
|
-
// Tables
|
|
4202
4250
|
ri,
|
|
4203
4251
|
oi,
|
|
4252
|
+
// Tables
|
|
4204
4253
|
si,
|
|
4205
4254
|
li,
|
|
4206
4255
|
ci,
|
|
4207
|
-
// Parsing
|
|
4208
4256
|
ui,
|
|
4209
|
-
// Media
|
|
4210
4257
|
di,
|
|
4258
|
+
// Parsing
|
|
4211
4259
|
mi,
|
|
4260
|
+
// Media
|
|
4261
|
+
hi,
|
|
4262
|
+
pi,
|
|
4212
4263
|
// Color
|
|
4213
|
-
|
|
4264
|
+
Si
|
|
4214
4265
|
];
|
|
4215
|
-
let
|
|
4216
|
-
function
|
|
4217
|
-
t.additionalRules && (
|
|
4266
|
+
let G = [], be = /* @__PURE__ */ new Set();
|
|
4267
|
+
function Ei(t) {
|
|
4268
|
+
t.additionalRules && (G = t.additionalRules), t.disabledRules && (be = new Set(t.disabledRules));
|
|
4218
4269
|
}
|
|
4219
|
-
function
|
|
4220
|
-
return
|
|
4270
|
+
function fe() {
|
|
4271
|
+
return ge.filter((a) => !be.has(a.id)).concat(G);
|
|
4221
4272
|
}
|
|
4222
|
-
function
|
|
4223
|
-
|
|
4224
|
-
const a =
|
|
4273
|
+
function Ci(t) {
|
|
4274
|
+
ve();
|
|
4275
|
+
const a = fe(), e = [];
|
|
4225
4276
|
let i = 0;
|
|
4226
4277
|
return {
|
|
4227
4278
|
processChunk(n) {
|
|
@@ -4240,13 +4291,13 @@ function Si(t) {
|
|
|
4240
4291
|
}
|
|
4241
4292
|
};
|
|
4242
4293
|
}
|
|
4243
|
-
function
|
|
4244
|
-
|
|
4294
|
+
function ve() {
|
|
4295
|
+
Ie(), we(), Ae(), Oe(), De(), Ee();
|
|
4245
4296
|
}
|
|
4246
|
-
function
|
|
4297
|
+
function Li(t) {
|
|
4247
4298
|
var i;
|
|
4248
|
-
|
|
4249
|
-
const a =
|
|
4299
|
+
ve();
|
|
4300
|
+
const a = fe(), e = [];
|
|
4250
4301
|
for (const n of a)
|
|
4251
4302
|
try {
|
|
4252
4303
|
e.push(...n.run(t));
|
|
@@ -4259,32 +4310,32 @@ function ki(t) {
|
|
|
4259
4310
|
ruleCount: a.length
|
|
4260
4311
|
};
|
|
4261
4312
|
}
|
|
4262
|
-
const
|
|
4263
|
-
function
|
|
4264
|
-
const a =
|
|
4265
|
-
return a ||
|
|
4313
|
+
const ki = new Map(ge.map((t) => [t.id, t]));
|
|
4314
|
+
function qi(t) {
|
|
4315
|
+
const a = ki.get(t);
|
|
4316
|
+
return a || G.find((e) => e.id === t);
|
|
4266
4317
|
}
|
|
4267
4318
|
export {
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4319
|
+
ve as clearAllCaches,
|
|
4320
|
+
De as clearAriaAttrAuditCache,
|
|
4321
|
+
Ie as clearAriaHiddenCache,
|
|
4322
|
+
Oe as clearColorCaches,
|
|
4323
|
+
we as clearComputedRoleCache,
|
|
4273
4324
|
k as compileDeclarativeRule,
|
|
4274
|
-
|
|
4275
|
-
|
|
4325
|
+
Ei as configureRules,
|
|
4326
|
+
Ci as createChunkedAudit,
|
|
4276
4327
|
v as getAccessibleName,
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4328
|
+
A as getAccessibleTextContent,
|
|
4329
|
+
fe as getActiveRules,
|
|
4330
|
+
q as getComputedRole,
|
|
4331
|
+
d as getHtmlSnippet,
|
|
4332
|
+
de as getImplicitRole,
|
|
4333
|
+
qi as getRuleById,
|
|
4283
4334
|
m as getSelector,
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4335
|
+
g as isAriaHidden,
|
|
4336
|
+
ke as isValidRole,
|
|
4337
|
+
Ii as querySelectorShadowAware,
|
|
4338
|
+
ge as rules,
|
|
4339
|
+
Li as runAudit,
|
|
4340
|
+
Ti as validateDeclarativeRule
|
|
4290
4341
|
};
|