@surea11y/core 1.1.0 → 1.1.2
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/CHANGELOG.md +25 -2
- package/docs/ENGINE_OPTIONS.md +2 -0
- package/docs/LIMITATIONS.md +1 -1
- package/package.json +1 -1
- package/src/checks/automatic/aria-allowed-attr.js +5 -4
- package/src/checks/automatic/aria-allowed-role.js +5 -4
- package/src/checks/automatic/aria-braille-equivalent.js +3 -4
- package/src/checks/automatic/aria-conditional-attr.js +3 -4
- package/src/checks/automatic/aria-deprecated-role.js +2 -3
- package/src/checks/automatic/aria-prohibited-attr.js +5 -4
- package/src/checks/automatic/aria-prohibited-children.js +2 -3
- package/src/checks/automatic/aria-required-attr.js +2 -3
- package/src/checks/automatic/aria-required-children.js +2 -3
- package/src/checks/automatic/aria-required-parent.js +3 -4
- package/src/checks/automatic/aria-roles-valid.js +2 -3
- package/src/checks/automatic/aria-valid-attr-value.js +5 -4
- package/src/checks/automatic/aria-valid-attr.js +5 -4
- package/src/checks/automatic/autocomplete-valid.js +2 -3
- package/src/checks/automatic/avoid-inline-spacing.js +2 -3
- package/src/checks/automatic/binary-control-name-present.js +2 -3
- package/src/checks/automatic/button-name-present.js +14 -4
- package/src/checks/automatic/bypass-blocks-present.js +35 -7
- package/src/checks/automatic/combobox-name-present.js +2 -3
- package/src/checks/automatic/definition-list-children-valid.js +2 -3
- package/src/checks/automatic/deprecated-elements-not-used.js +5 -4
- package/src/checks/automatic/dialog-name-present.js +2 -3
- package/src/checks/automatic/dlitem-parent-valid.js +2 -3
- package/src/checks/automatic/form-control-single-label.js +2 -3
- package/src/checks/automatic/iframe-focusable-content.js +2 -3
- package/src/checks/automatic/iframe-name-present.js +2 -3
- package/src/checks/automatic/iframe-title-unique.js +5 -5
- package/src/checks/automatic/label-in-name.js +7 -8
- package/src/checks/automatic/link-in-text-block.js +2 -3
- package/src/checks/automatic/link-name-present.js +16 -4
- package/src/checks/automatic/list-children-valid.js +2 -3
- package/src/checks/automatic/listbox-name-present.js +2 -3
- package/src/checks/automatic/listitem-parent-valid.js +2 -3
- package/src/checks/automatic/menuitem-name-present.js +2 -3
- package/src/checks/automatic/meter-name-present.js +2 -3
- package/src/checks/automatic/nested-interactive-controls-absent.js +2 -3
- package/src/checks/automatic/option-name-present.js +2 -3
- package/src/checks/automatic/progressbar-name-present.js +2 -3
- package/src/checks/automatic/searchbox-name-present.js +2 -3
- package/src/checks/automatic/server-side-image-map-absent.js +2 -3
- package/src/checks/automatic/slider-name-present.js +2 -3
- package/src/checks/automatic/spinbutton-name-present.js +2 -3
- package/src/checks/automatic/summary-name-present.js +2 -3
- package/src/checks/automatic/tab-name-present.js +2 -3
- package/src/checks/automatic/table-headers-attr-valid.js +5 -4
- package/src/checks/automatic/table-th-has-data-cells.js +5 -4
- package/src/checks/automatic/td-has-header.js +2 -3
- package/src/checks/automatic/textbox-name-present.js +2 -3
- package/src/checks/automatic/tooltip-name-present.js +2 -3
- package/src/checks/automatic/treeitem-name-present.js +2 -3
- package/src/checks/automatic/valid-lang.js +2 -3
- package/src/checks/manual/accesskeys-manual.js +1 -7
- package/src/checks/manual/aria-checked-state-mismatch-manual.js +7 -6
- package/src/checks/manual/aria-text-manual.js +2 -3
- package/src/checks/manual/focus-order-semantics-manual.js +2 -3
- package/src/checks/manual/identical-links-same-purpose-manual.js +2 -3
- package/src/checks/manual/image-redundant-alt-manual.js +2 -3
- package/src/checks/manual/label-title-only-manual.js +2 -3
- package/src/checks/manual/link-name-quality-manual.js +2 -3
- package/src/checks/manual/mouse-only-event-handlers-manual.js +2 -3
- package/src/checks/manual/no-autoplay-audio-manual.js +2 -3
- package/src/checks/manual/p-as-heading-manual.js +2 -3
- package/src/checks/manual/page-has-heading-one-manual.js +31 -2
- package/src/checks/manual/presentation-role-conflict-manual.js +3 -4
- package/src/checks/manual/scrollable-region-focusable-manual.js +2 -3
- package/src/checks/manual/skip-link-manual.js +91 -9
- package/src/checks/manual/table-duplicate-name-manual.js +2 -3
- package/src/checks/manual/table-fake-caption-manual.js +2 -3
- package/src/checks/manual/video-caption-manual.js +2 -3
- package/src/core/dom-helpers.js +89 -3
- package/src/core/dom-runner.js +19 -0
- package/src/core.js +962 -481
- package/src/i18n/en.js +4 -2
- package/src/i18n/fr.js +4 -2
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
* rule has no partial-pass case, matching a widely-used reference engine's `blink`/`marquee`
|
|
18
18
|
* rules (which report only when the element is found).
|
|
19
19
|
* @implementation-notes
|
|
20
|
-
* - Not gated on isAccTreeEligible: presence in markup is itself the
|
|
20
|
+
* - Not rule-gated on isAccTreeEligible: presence in markup is itself the
|
|
21
21
|
* violation, independent of visibility (moving/blinking content inside a
|
|
22
22
|
* hidden ancestor could still become visible later without a code
|
|
23
23
|
* change, so hiding it today does not remove the underlying defect).
|
|
24
|
+
* Engine-level hidden-subtree filtering still applies unless
|
|
25
|
+
* engineOptions.includeHiddenElements is true.
|
|
24
26
|
*/
|
|
25
27
|
|
|
26
28
|
const id = 'deprecated-elements-not-used';
|
|
@@ -46,10 +48,9 @@ const meta = {
|
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
function runInPage(ctx) {
|
|
49
|
-
const { document,
|
|
50
|
-
const safeRoot = root || document;
|
|
51
|
+
const { document, helpers, rule } = ctx;
|
|
51
52
|
|
|
52
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('blink, marquee'
|
|
53
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('blink, marquee') : helpers.queryAll('blink, marquee');
|
|
53
54
|
|
|
54
55
|
const occurrences = [];
|
|
55
56
|
let applicableCount = 0;
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -141,7 +140,7 @@ function runInPage(ctx) {
|
|
|
141
140
|
let applicableCount = 0;
|
|
142
141
|
|
|
143
142
|
const selector = '[role="dialog"],[role="alertdialog"]';
|
|
144
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
143
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
145
144
|
|
|
146
145
|
|
|
147
146
|
function evaluate(el) {
|
|
@@ -42,10 +42,9 @@ const meta = {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
function runInPage(ctx) {
|
|
45
|
-
const { document,
|
|
46
|
-
const safeRoot = root || document;
|
|
45
|
+
const { document, helpers, rule } = ctx;
|
|
47
46
|
|
|
48
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('dt, dd'
|
|
47
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('dt, dd') : helpers.queryAll('dt, dd');
|
|
49
48
|
|
|
50
49
|
const occurrences = [];
|
|
51
50
|
let applicableCount = 0;
|
|
@@ -46,11 +46,10 @@ const meta = {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
function runInPage(ctx) {
|
|
49
|
-
const { document,
|
|
50
|
-
const safeRoot = root || document;
|
|
49
|
+
const { document, helpers, rule } = ctx;
|
|
51
50
|
|
|
52
51
|
const selector = 'input:not([type="hidden"]):not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="image"]),select,textarea';
|
|
53
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
52
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
54
53
|
|
|
55
54
|
// Build a for-value -> label[] map once (avoids per-control dynamic
|
|
56
55
|
// attribute-selector construction / CSS.escape, which is not guaranteed
|
|
@@ -55,8 +55,7 @@ const meta = {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
function runInPage(ctx) {
|
|
58
|
-
const { document,
|
|
59
|
-
const safeRoot = root || document;
|
|
58
|
+
const { document, helpers, rule } = ctx;
|
|
60
59
|
|
|
61
60
|
function hasFocusableCandidate(doc) {
|
|
62
61
|
if (!doc || !doc.querySelectorAll) return false;
|
|
@@ -88,7 +87,7 @@ function runInPage(ctx) {
|
|
|
88
87
|
return !Number.isNaN(n) && n < 0;
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame'
|
|
90
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame') : helpers.queryAll('iframe, frame');
|
|
92
91
|
|
|
93
92
|
const occurrences = [];
|
|
94
93
|
let applicableCount = 0;
|
|
@@ -44,10 +44,9 @@ const meta = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function runInPage(ctx) {
|
|
47
|
-
const { document,
|
|
48
|
-
const safeRoot = root || document;
|
|
47
|
+
const { document, helpers, rule } = ctx;
|
|
49
48
|
|
|
50
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame'
|
|
49
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame') : helpers.queryAll('iframe, frame');
|
|
51
50
|
|
|
52
51
|
const occurrences = [];
|
|
53
52
|
let applicableCount = 0;
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
* - Compares the title ATTRIBUTE specifically, not the full computed
|
|
20
20
|
* accessible name (aria-label could legitimately differ in wording even
|
|
21
21
|
* when title happens to collide) — matches a widely-used reference engine's frame-title-unique.
|
|
22
|
-
* - Not gated on isAccTreeEligible:
|
|
23
|
-
* property
|
|
22
|
+
* - Not rule-gated on isAccTreeEligible: duplicate titles are a static
|
|
23
|
+
* markup property. Engine-level hidden-subtree filtering still applies
|
|
24
|
+
* unless engineOptions.includeHiddenElements is true.
|
|
24
25
|
*/
|
|
25
26
|
|
|
26
27
|
const id = 'iframe-title-unique';
|
|
@@ -46,10 +47,9 @@ const meta = {
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
function runInPage(ctx) {
|
|
49
|
-
const { document,
|
|
50
|
-
const safeRoot = root || document;
|
|
50
|
+
const { document, helpers, rule } = ctx;
|
|
51
51
|
|
|
52
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame'
|
|
52
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame') : helpers.queryAll('iframe, frame');
|
|
53
53
|
|
|
54
54
|
const groups = new Map(); // trimmed title -> elements[]
|
|
55
55
|
let applicableCount = 0;
|
|
@@ -30,8 +30,7 @@ const meta = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
function runInPage(ctx) {
|
|
33
|
-
const { document,
|
|
34
|
-
const safeRoot = root || document;
|
|
33
|
+
const { document, helpers, rule } = ctx;
|
|
35
34
|
|
|
36
35
|
const occurrences = [];
|
|
37
36
|
let applicableCount = 0;
|
|
@@ -40,7 +39,7 @@ function runInPage(ctx) {
|
|
|
40
39
|
// NOTE: aria-hidden is intentionally NOT excluded here; it does not affect visual rendering.
|
|
41
40
|
const selector = ':is(button, a[href], summary, input:not([type="hidden"]), textarea, select, [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="searchbox"], [role="tab"], [role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="option"], [role="treeitem"], [role="gridcell"]):not([hidden]):not([disabled]):not([aria-disabled="true"]):is([aria-label], [aria-labelledby])';
|
|
42
41
|
|
|
43
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
42
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
44
43
|
|
|
45
44
|
function norm(s) {
|
|
46
45
|
const v = (s == null ? '' : String(s));
|
|
@@ -178,11 +177,11 @@ function runInPage(ctx) {
|
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
// Fallback: label[for=id]. Uses `document` directly rather than
|
|
181
|
-
// ctx.root
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
//
|
|
180
|
+
// ctx.root -- label[for] association is a document-wide relationship
|
|
181
|
+
// (IDs are document-unique), not bounded by whatever contextSelector
|
|
182
|
+
// region happens to be scanned, and ctx.root is an array (multi-region
|
|
183
|
+
// contextSelector support), not a single element with its own
|
|
184
|
+
// .querySelector to call directly.
|
|
186
185
|
try {
|
|
187
186
|
const idAttribute = control && control.getAttribute ? (control.getAttribute('id') || '') : '';
|
|
188
187
|
const key = String(idAttribute || '').trim();
|
|
@@ -68,8 +68,7 @@ const meta = {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
function runInPage(ctx) {
|
|
71
|
-
const { document,
|
|
72
|
-
const safeRoot = root || document;
|
|
71
|
+
const { document, helpers, rule, engineOptions } = ctx;
|
|
73
72
|
|
|
74
73
|
function safeComputedStyle(el) {
|
|
75
74
|
try {
|
|
@@ -115,7 +114,7 @@ function runInPage(ctx) {
|
|
|
115
114
|
const c = helpers && helpers.contrast ? helpers.contrast : null;
|
|
116
115
|
|
|
117
116
|
const selector = 'a[href]';
|
|
118
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
117
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
119
118
|
|
|
120
119
|
const occurrences = [];
|
|
121
120
|
let applicableCount = 0;
|
|
@@ -24,8 +24,7 @@ const meta = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
function runInPage(ctx) {
|
|
27
|
-
const { document,
|
|
28
|
-
const safeRoot = root || document;
|
|
27
|
+
const { document, helpers, rule } = ctx;
|
|
29
28
|
|
|
30
29
|
const occurrences = [];
|
|
31
30
|
let applicableCount = 0;
|
|
@@ -46,7 +45,7 @@ function runInPage(ctx) {
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
const selector = 'a[href], area[href], [role="link"]';
|
|
49
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
48
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
50
49
|
|
|
51
50
|
for (const el of nodes) {
|
|
52
51
|
// isAccTreeEligible returns { eligible, reasons }, not a boolean.
|
|
@@ -59,7 +58,20 @@ function runInPage(ctx) {
|
|
|
59
58
|
const nameInfo = helpers.getAccessibleNameInfo ? helpers.getAccessibleNameInfo(el, ctx) : null;
|
|
60
59
|
const programmaticName = (nameInfo && typeof nameInfo.value === 'string') ? nameInfo.value : '';
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
// A native <a href>/<area href> (or [role="link"]) whose role has been
|
|
62
|
+
// overridden to one of these roles is no longer semantically a link —
|
|
63
|
+
// per the WAI-ARIA Accessible Name and Description Computation spec
|
|
64
|
+
// these roles are name-from-author-only, and their rendered content
|
|
65
|
+
// represents a VALUE, not a NAME (mirrors axe-core's controlValueRoles,
|
|
66
|
+
// verified against its source; see button-name-present.js's identical
|
|
67
|
+
// fix for a real-world example — <button role="combobox">List</button> —
|
|
68
|
+
// of the same class of bug on a different host tag).
|
|
69
|
+
const role = el.getAttribute ? el.getAttribute('role') : null;
|
|
70
|
+
const roleNorm = String(role || '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
71
|
+
const VALUE_ROLES = ['textbox', 'progressbar', 'scrollbar', 'slider', 'spinbutton', 'combobox', 'listbox'];
|
|
72
|
+
const isContentNameCandidate = !VALUE_ROLES.includes(roleNorm);
|
|
73
|
+
|
|
74
|
+
const contentName = (programmaticName.trim().length === 0 && isContentNameCandidate) ? getConservativeSubtreeText(el) : '';
|
|
63
75
|
const finalName = (programmaticName.trim().length ? programmaticName : contentName).trim();
|
|
64
76
|
|
|
65
77
|
if (finalName.length === 0) {
|
|
@@ -71,14 +71,13 @@ const meta = {
|
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
function runInPage(ctx) {
|
|
74
|
-
const { document,
|
|
75
|
-
const safeRoot = root || document;
|
|
74
|
+
const { document, helpers, rule } = ctx;
|
|
76
75
|
|
|
77
76
|
// Declared inside runInPage — see scripts/build-core.js header
|
|
78
77
|
// ("runInPage MUST be self-contained").
|
|
79
78
|
const ALLOWED_CHILD_TAGS = new Set(['li', 'script', 'template']);
|
|
80
79
|
|
|
81
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('ul, ol'
|
|
80
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('ul, ol') : helpers.queryAll('ul, ol');
|
|
82
81
|
|
|
83
82
|
const isAccTreeEligible = helpers && typeof helpers.isAccTreeEligible === 'function' ? helpers.isAccTreeEligible : null;
|
|
84
83
|
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -132,7 +131,7 @@ function runInPage(ctx) {
|
|
|
132
131
|
let applicableCount = 0;
|
|
133
132
|
|
|
134
133
|
const selector = "[role=\"listbox\"]";
|
|
135
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
134
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
136
135
|
|
|
137
136
|
// Precompute label[for] map for listbox elements that are labelable
|
|
138
137
|
// native form controls (e.g. <select multiple role="listbox">).
|
|
@@ -56,10 +56,9 @@ const meta = {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
function runInPage(ctx) {
|
|
59
|
-
const { document,
|
|
60
|
-
const safeRoot = root || document;
|
|
59
|
+
const { document, helpers, rule } = ctx;
|
|
61
60
|
|
|
62
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('li'
|
|
61
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('li') : helpers.queryAll('li');
|
|
63
62
|
|
|
64
63
|
const occurrences = [];
|
|
65
64
|
let applicableCount = 0;
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -133,7 +132,7 @@ function runInPage(ctx) {
|
|
|
133
132
|
let applicableCount = 0;
|
|
134
133
|
|
|
135
134
|
const selector = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]';
|
|
136
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
135
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
137
136
|
|
|
138
137
|
|
|
139
138
|
function evaluate(el) {
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -91,7 +90,7 @@ function runInPage(ctx) {
|
|
|
91
90
|
let applicableCount = 0;
|
|
92
91
|
|
|
93
92
|
const selector = '[role="meter"]';
|
|
94
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
93
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
function evaluate(el) {
|
|
@@ -53,8 +53,7 @@ const meta = {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
function runInPage(ctx) {
|
|
56
|
-
const { document,
|
|
57
|
-
const safeRoot = root || document;
|
|
56
|
+
const { document, helpers, rule } = ctx;
|
|
58
57
|
|
|
59
58
|
// Declared inside runInPage — see scripts/build-core.js header
|
|
60
59
|
// ("runInPage MUST be self-contained").
|
|
@@ -83,7 +82,7 @@ function runInPage(ctx) {
|
|
|
83
82
|
'[role="treeitem"]'
|
|
84
83
|
].join(', ');
|
|
85
84
|
|
|
86
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(INTERACTIVE_SELECTOR
|
|
85
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(INTERACTIVE_SELECTOR) : helpers.queryAll(INTERACTIVE_SELECTOR);
|
|
87
86
|
|
|
88
87
|
const occurrences = [];
|
|
89
88
|
let applicableCount = 0;
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -91,7 +90,7 @@ function runInPage(ctx) {
|
|
|
91
90
|
let applicableCount = 0;
|
|
92
91
|
|
|
93
92
|
const selector = "[role=\"option\"]";
|
|
94
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
93
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
function hasName(el) {
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -91,7 +90,7 @@ function runInPage(ctx) {
|
|
|
91
90
|
let applicableCount = 0;
|
|
92
91
|
|
|
93
92
|
const selector = '[role="progressbar"]';
|
|
94
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
93
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
function evaluate(el) {
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -132,7 +131,7 @@ function runInPage(ctx) {
|
|
|
132
131
|
let applicableCount = 0;
|
|
133
132
|
|
|
134
133
|
const selector = "[role=\"searchbox\"]";
|
|
135
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
134
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
136
135
|
|
|
137
136
|
// Precompute label[for] map for searchbox elements that are labelable
|
|
138
137
|
// native form controls (e.g. <input role="searchbox">).
|
|
@@ -44,10 +44,9 @@ const meta = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function runInPage(ctx) {
|
|
47
|
-
const { document,
|
|
48
|
-
const safeRoot = root || document;
|
|
47
|
+
const { document, helpers, rule } = ctx;
|
|
49
48
|
|
|
50
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('img[ismap]'
|
|
49
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('img[ismap]') : helpers.queryAll('img[ismap]');
|
|
51
50
|
|
|
52
51
|
const occurrences = [];
|
|
53
52
|
let applicableCount = 0;
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -159,7 +158,7 @@ function runInPage(ctx) {
|
|
|
159
158
|
let applicableCount = 0;
|
|
160
159
|
|
|
161
160
|
const selector = 'input[type="range"], [role="slider"]';
|
|
162
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
161
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
163
162
|
|
|
164
163
|
|
|
165
164
|
// Precompute label[for] map for native range inputs.
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -132,7 +131,7 @@ function runInPage(ctx) {
|
|
|
132
131
|
let applicableCount = 0;
|
|
133
132
|
|
|
134
133
|
const selector = "[role=\"spinbutton\"]";
|
|
135
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
134
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
136
135
|
|
|
137
136
|
// Precompute label[for] map for spinbutton elements that are labelable
|
|
138
137
|
// native form controls (e.g. <input role="spinbutton">).
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -90,7 +89,7 @@ function runInPage(ctx) {
|
|
|
90
89
|
const occurrences = [];
|
|
91
90
|
let applicableCount = 0;
|
|
92
91
|
|
|
93
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('summary'
|
|
92
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('summary') : helpers.queryAll('summary');
|
|
94
93
|
|
|
95
94
|
function evaluate(el) {
|
|
96
95
|
const ariaLabel = getAttr(el, 'aria-label');
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -133,7 +132,7 @@ function runInPage(ctx) {
|
|
|
133
132
|
let applicableCount = 0;
|
|
134
133
|
|
|
135
134
|
const selector = '[role="tab"]';
|
|
136
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
135
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
137
136
|
|
|
138
137
|
|
|
139
138
|
function evaluate(el) {
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
* - One occurrence per offending cell (not per bad token), listing every
|
|
17
17
|
* invalid reference — matches a widely-used reference engine's
|
|
18
18
|
* td-headers-attr reporting granularity.
|
|
19
|
-
* - Not gated on isAccTreeEligible: this
|
|
19
|
+
* - Not rule-gated on isAccTreeEligible: this remains a static-markup
|
|
20
|
+
* property, while engine-level hidden-subtree filtering still applies
|
|
21
|
+
* unless engineOptions.includeHiddenElements is true.
|
|
20
22
|
*/
|
|
21
23
|
|
|
22
24
|
const id = 'table-headers-attr-valid';
|
|
@@ -42,10 +44,9 @@ const meta = {
|
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
function runInPage(ctx) {
|
|
45
|
-
const { document,
|
|
46
|
-
const safeRoot = root || document;
|
|
47
|
+
const { document, helpers, rule } = ctx;
|
|
47
48
|
|
|
48
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('td[headers], th[headers]'
|
|
49
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('td[headers], th[headers]') : helpers.queryAll('td[headers], th[headers]');
|
|
49
50
|
|
|
50
51
|
const occurrences = [];
|
|
51
52
|
let applicableCount = 0;
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
* if some particular <th> in it doesn't actually describe any cell
|
|
29
29
|
* (false negative, not a false positive — acceptable under this
|
|
30
30
|
* engine's philosophy).
|
|
31
|
-
* - Not gated on isAccTreeEligible: this
|
|
31
|
+
* - Not rule-gated on isAccTreeEligible: this remains a static-markup
|
|
32
|
+
* property, while engine-level hidden-subtree filtering still applies
|
|
33
|
+
* unless engineOptions.includeHiddenElements is true.
|
|
32
34
|
*/
|
|
33
35
|
|
|
34
36
|
const id = 'table-th-has-data-cells';
|
|
@@ -54,10 +56,9 @@ const meta = {
|
|
|
54
56
|
};
|
|
55
57
|
|
|
56
58
|
function runInPage(ctx) {
|
|
57
|
-
const { document,
|
|
58
|
-
const safeRoot = root || document;
|
|
59
|
+
const { document, helpers, rule } = ctx;
|
|
59
60
|
|
|
60
|
-
const tables = helpers.queryAllSmart ? helpers.queryAllSmart('table'
|
|
61
|
+
const tables = helpers.queryAllSmart ? helpers.queryAllSmart('table') : helpers.queryAll('table');
|
|
61
62
|
|
|
62
63
|
const occurrences = [];
|
|
63
64
|
let applicableCount = 0;
|
|
@@ -55,14 +55,13 @@ const meta = {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
function runInPage(ctx) {
|
|
58
|
-
const { document,
|
|
59
|
-
const safeRoot = root || document;
|
|
58
|
+
const { document, helpers, rule } = ctx;
|
|
60
59
|
|
|
61
60
|
const MIN_SIZE = 4;
|
|
62
61
|
|
|
63
62
|
function trim(v) { return (v == null ? '' : String(v)).trim(); }
|
|
64
63
|
|
|
65
|
-
const tables = helpers.queryAllSmart ? helpers.queryAllSmart('table'
|
|
64
|
+
const tables = helpers.queryAllSmart ? helpers.queryAllSmart('table') : helpers.queryAll('table');
|
|
66
65
|
|
|
67
66
|
const occurrences = [];
|
|
68
67
|
let applicableCount = 0;
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -132,7 +131,7 @@ function runInPage(ctx) {
|
|
|
132
131
|
let applicableCount = 0;
|
|
133
132
|
|
|
134
133
|
const selector = "[role=\"textbox\"]";
|
|
135
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
134
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
136
135
|
|
|
137
136
|
// Precompute label[for] map for textbox elements that are labelable
|
|
138
137
|
// native form controls (e.g. <input role="textbox">).
|
|
@@ -23,11 +23,10 @@ const meta = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
function runInPage(ctx) {
|
|
26
|
-
const { document,
|
|
26
|
+
const { document, helpers, rule } = ctx;
|
|
27
27
|
const getEligibilityInfo = helpers && typeof helpers.getEligibilityInfo === 'function'
|
|
28
28
|
? helpers.getEligibilityInfo
|
|
29
29
|
: null;
|
|
30
|
-
const safeRoot = root || document;
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
function normalizeWs(s) {
|
|
@@ -91,7 +90,7 @@ function runInPage(ctx) {
|
|
|
91
90
|
let applicableCount = 0;
|
|
92
91
|
|
|
93
92
|
const selector = '[role="tooltip"]';
|
|
94
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector
|
|
93
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart(selector) : helpers.queryAll(selector);
|
|
95
94
|
|
|
96
95
|
|
|
97
96
|
function evaluate(el) {
|