@surea11y/core 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +3 -0
- package/bin/core.js +107 -3
- package/docs/API_STABILITY.md +61 -0
- package/docs/BASELINE.md +66 -0
- package/docs/CLI.md +26 -0
- package/docs/ENGINE_OPTIONS.md +2 -0
- package/docs/INTEGRATION.md +1 -1
- package/docs/OUTPUT_SCHEMA.md +1 -1
- package/docs/REPORT.md +33 -0
- package/docs/RULE_AUTHORING.md +31 -0
- package/package.json +1 -1
- package/src/baseline.js +0 -0
- package/src/checks/automatic/aria-allowed-attr.js +2 -3
- package/src/checks/automatic/aria-allowed-role.js +2 -3
- 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-hidden-body.js +9 -1
- package/src/checks/automatic/aria-prohibited-attr.js +2 -3
- package/src/checks/automatic/aria-prohibited-children.js +73 -17
- 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 +2 -3
- package/src/checks/automatic/aria-valid-attr.js +2 -3
- 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 +44 -8
- package/src/checks/automatic/combobox-name-present.js +2 -3
- package/src/checks/automatic/css-orientation-lock.js +9 -1
- package/src/checks/automatic/definition-list-children-valid.js +2 -3
- package/src/checks/automatic/deprecated-elements-not-used.js +2 -3
- 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/html-xml-lang-mismatch.js +9 -1
- 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 +2 -3
- package/src/checks/automatic/label-in-name.js +7 -8
- package/src/checks/automatic/language-page-present.js +9 -1
- 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/meta-refresh-no-exceptions.js +9 -1
- package/src/checks/automatic/meta-refresh-timing-absent.js +9 -1
- package/src/checks/automatic/meta-viewport-zoom-enabled.js +9 -1
- 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/page-title-present.js +9 -1
- 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 +2 -3
- package/src/checks/automatic/table-th-has-data-cells.js +2 -3
- 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 +3 -4
- package/src/checks/manual/aria-text-manual.js +2 -3
- package/src/checks/manual/empty-heading-manual.js +1 -6
- package/src/checks/manual/empty-table-header-manual.js +5 -9
- package/src/checks/manual/focus-order-semantics-manual.js +2 -3
- package/src/checks/manual/heading-order-manual.js +1 -6
- 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/landmark-banner-is-top-level-manual.js +30 -14
- package/src/checks/manual/landmark-contentinfo-is-top-level-manual.js +30 -14
- package/src/checks/manual/landmark-main-is-top-level-manual.js +30 -14
- package/src/checks/manual/landmark-no-duplicate-banner-manual.js +25 -13
- package/src/checks/manual/landmark-no-duplicate-contentinfo-manual.js +25 -13
- package/src/checks/manual/landmark-one-main-manual.js +9 -1
- package/src/checks/manual/landmark-unique-manual.js +32 -30
- package/src/checks/manual/link-name-quality-manual.js +2 -3
- package/src/checks/manual/meta-viewport-large-manual.js +9 -1
- 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 +40 -3
- package/src/checks/manual/page-title-patterns-manual.js +9 -1
- package/src/checks/manual/presentation-role-conflict-manual.js +3 -4
- package/src/checks/manual/region-manual.js +34 -14
- package/src/checks/manual/scope-attr-valid-manual.js +2 -7
- 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/tabindex-manual.js +2 -7
- 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/aria-helpers.js +82 -18
- package/src/core/dom-helpers.js +88 -3
- package/src/core/dom-runner.js +23 -0
- package/src/core/rule-meta.js +19 -0
- package/src/core.js +2632 -885
- package/src/i18n/en.js +6 -2
- package/src/i18n/fr.js +6 -2
- package/src/report.js +482 -0
|
@@ -45,6 +45,14 @@ const meta = {
|
|
|
45
45
|
coverage: { facetsBySc: { '3.1.1': ['html-xml-lang-mismatch'] } }
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
49
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
50
|
+
// scoped this run narrower than the whole document, or when
|
|
51
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
52
|
+
function applicability(ctx) {
|
|
53
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
function runInPage(ctx) {
|
|
49
57
|
const { document, helpers, rule } = ctx;
|
|
50
58
|
|
|
@@ -88,4 +96,4 @@ function runInPage(ctx) {
|
|
|
88
96
|
return { ruleId: rule.ruleId, outcome: 'fail', severity: rule.defaultSeverity || 'serious', occurrences };
|
|
89
97
|
}
|
|
90
98
|
|
|
91
|
-
module.exports = { id, meta, runInPage };
|
|
99
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -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;
|
|
@@ -47,10 +47,9 @@ const meta = {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
function runInPage(ctx) {
|
|
50
|
-
const { document,
|
|
51
|
-
const safeRoot = root || document;
|
|
50
|
+
const { document, helpers, rule } = ctx;
|
|
52
51
|
|
|
53
|
-
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame'
|
|
52
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('iframe, frame') : helpers.queryAll('iframe, frame');
|
|
54
53
|
|
|
55
54
|
const groups = new Map(); // trimmed title -> elements[]
|
|
56
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();
|
|
@@ -63,6 +63,14 @@ const meta = {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
67
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
68
|
+
// scoped this run narrower than the whole document, or when
|
|
69
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
70
|
+
function applicability(ctx) {
|
|
71
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
function runInPage(ctx) {
|
|
67
75
|
const { document, rule, helpers } = ctx;
|
|
68
76
|
const html = document && document.documentElement;
|
|
@@ -156,4 +164,4 @@ function runInPage(ctx) {
|
|
|
156
164
|
};
|
|
157
165
|
}
|
|
158
166
|
|
|
159
|
-
module.exports = { id, meta, runInPage };
|
|
167
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -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) {
|
|
@@ -58,6 +58,14 @@ const meta = {
|
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
62
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
63
|
+
// scoped this run narrower than the whole document, or when
|
|
64
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
65
|
+
function applicability(ctx) {
|
|
66
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
function runInPage(ctx) {
|
|
62
70
|
const { document, helpers, rule } = ctx;
|
|
63
71
|
|
|
@@ -102,4 +110,4 @@ function runInPage(ctx) {
|
|
|
102
110
|
return { ruleId: rule.ruleId, outcome: 'pass', severity: 'minor', occurrences: [] };
|
|
103
111
|
}
|
|
104
112
|
|
|
105
|
-
module.exports = { id, meta, runInPage };
|
|
113
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -49,6 +49,14 @@ const meta = {
|
|
|
49
49
|
coverage: { facetsBySc: { '2.2.1': ['meta-refresh-timing-absent'] } }
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
53
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
54
|
+
// scoped this run narrower than the whole document, or when
|
|
55
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
56
|
+
function applicability(ctx) {
|
|
57
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
function runInPage(ctx) {
|
|
53
61
|
const { document, helpers, rule } = ctx;
|
|
54
62
|
|
|
@@ -104,4 +112,4 @@ function runInPage(ctx) {
|
|
|
104
112
|
return { ruleId: rule.ruleId, outcome: 'pass', severity: 'minor', occurrences: [] };
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
module.exports = { id, meta, runInPage };
|
|
115
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -42,6 +42,14 @@ const meta = {
|
|
|
42
42
|
coverage: { facetsBySc: { '1.4.4': ['meta-viewport-zoom-enabled'] } }
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
46
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
47
|
+
// scoped this run narrower than the whole document, or when
|
|
48
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
49
|
+
function applicability(ctx) {
|
|
50
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
function runInPage(ctx) {
|
|
46
54
|
const { document, helpers, rule } = ctx;
|
|
47
55
|
|
|
@@ -115,4 +123,4 @@ function runInPage(ctx) {
|
|
|
115
123
|
return { ruleId: rule.ruleId, outcome: 'pass', severity: 'minor', occurrences: [] };
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
module.exports = { id, meta, runInPage };
|
|
126
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -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) {
|
|
@@ -22,6 +22,14 @@ const meta = {
|
|
|
22
22
|
coverage: { facetsBySc: { '2.4.2': ['page-title-present'] } }
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
// This check is inherently whole-document (does the PAGE have this
|
|
26
|
+
// property?), not evaluable per-subtree -- notApplicable when contextSelector
|
|
27
|
+
// scoped this run narrower than the whole document, or when
|
|
28
|
+
// engineOptions.fragment:true was set (see helpers.isWholeDocumentScope).
|
|
29
|
+
function applicability(ctx) {
|
|
30
|
+
return ctx.helpers.isWholeDocumentScope ? ctx.helpers.isWholeDocumentScope() : true;
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
function runInPage(ctx) {
|
|
26
34
|
const { document, helpers, rule } = ctx;
|
|
27
35
|
|
|
@@ -83,4 +91,4 @@ function runInPage(ctx) {
|
|
|
83
91
|
return { ruleId: rule.ruleId, outcome: 'pass', severity: 'minor', occurrences: [] };
|
|
84
92
|
}
|
|
85
93
|
|
|
86
|
-
module.exports = { id, meta, runInPage };
|
|
94
|
+
module.exports = { id, meta, runInPage, applicability };
|
|
@@ -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) {
|
|
@@ -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('td[headers], th[headers]'
|
|
49
|
+
const nodes = helpers.queryAllSmart ? helpers.queryAllSmart('td[headers], th[headers]') : helpers.queryAll('td[headers], th[headers]');
|
|
51
50
|
|
|
52
51
|
const occurrences = [];
|
|
53
52
|
let applicableCount = 0;
|
|
@@ -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 tables = helpers.queryAllSmart ? helpers.queryAllSmart('table'
|
|
61
|
+
const tables = helpers.queryAllSmart ? helpers.queryAllSmart('table') : helpers.queryAll('table');
|
|
63
62
|
|
|
64
63
|
const occurrences = [];
|
|
65
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">).
|