@surea11y/core 1.4.1 → 1.5.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 +47 -7
- package/README.md +19 -3
- package/docs/API_STABILITY.md +2 -2
- package/docs/ENGINE_OPTIONS.md +14 -10
- package/docs/I18N.md +176 -20
- package/docs/INTEGRATION.md +28 -6
- package/docs/LIMITATIONS.md +1 -1
- package/docs/OUTPUT_SCHEMA.md +13 -3
- package/docs/REPORT.md +2 -0
- package/docs/RULE_AUTHORING.md +53 -0
- package/docs/TROUBLESHOOTING.md +2 -2
- package/package.json +6 -1
- package/src/checks/automatic/aria-allowed-attr.js +27 -30
- package/src/checks/automatic/aria-allowed-role.js +14 -16
- package/src/checks/automatic/aria-braille-equivalent.js +17 -19
- package/src/checks/automatic/aria-conditional-attr.js +17 -19
- package/src/checks/automatic/aria-deprecated-role.js +62 -49
- package/src/checks/automatic/aria-hidden-body.js +2 -9
- package/src/checks/automatic/aria-hidden-focus.js +99 -18
- package/src/checks/automatic/aria-prohibited-attr.js +54 -55
- package/src/checks/automatic/aria-prohibited-children.js +26 -26
- package/src/checks/automatic/aria-required-attr.js +14 -17
- package/src/checks/automatic/aria-required-children.js +17 -20
- package/src/checks/automatic/aria-required-parent.js +17 -20
- package/src/checks/automatic/aria-roles-valid.js +37 -23
- package/src/checks/automatic/aria-valid-attr-value.js +18 -21
- package/src/checks/automatic/aria-valid-attr.js +14 -17
- package/src/checks/automatic/autocomplete-valid.js +15 -17
- package/src/checks/automatic/avoid-inline-spacing.js +14 -16
- package/src/checks/automatic/binary-control-name-present.js +19 -21
- package/src/checks/automatic/button-name-present.js +23 -28
- package/src/checks/automatic/combobox-name-present.js +15 -17
- package/src/checks/automatic/css-orientation-lock.js +22 -22
- package/src/checks/automatic/definition-list-children-valid.js +18 -21
- package/src/checks/automatic/deprecated-elements-not-used.js +14 -16
- package/src/checks/automatic/dialog-name-present.js +16 -18
- package/src/checks/automatic/dlitem-parent-valid.js +15 -17
- package/src/checks/automatic/duplicate-id-aria.js +45 -37
- package/src/checks/automatic/form-control-single-label.js +38 -40
- package/src/checks/automatic/html-xml-lang-mismatch.js +2 -9
- package/src/checks/automatic/iframe-focusable-content.js +29 -31
- package/src/checks/automatic/iframe-name-present.js +15 -17
- package/src/checks/automatic/iframe-title-unique.js +18 -23
- package/src/checks/automatic/label-in-name.js +31 -36
- package/src/checks/automatic/link-in-text-block.js +19 -21
- package/src/checks/automatic/link-name-present.js +25 -30
- package/src/checks/automatic/list-children-valid.js +15 -17
- package/src/checks/automatic/listbox-name-present.js +15 -17
- package/src/checks/automatic/listitem-parent-valid.js +14 -17
- package/src/checks/automatic/menuitem-name-present.js +16 -18
- package/src/checks/automatic/meta-refresh-no-exceptions.js +15 -18
- package/src/checks/automatic/meta-refresh-timing-absent.js +14 -17
- package/src/checks/automatic/meta-viewport-zoom-enabled.js +14 -17
- package/src/checks/automatic/meter-name-present.js +16 -18
- package/src/checks/automatic/nested-interactive-controls-absent.js +17 -19
- package/src/checks/automatic/option-name-present.js +16 -18
- package/src/checks/automatic/progressbar-name-present.js +19 -21
- package/src/checks/automatic/searchbox-name-present.js +19 -17
- package/src/checks/automatic/server-side-image-map-absent.js +15 -18
- package/src/checks/automatic/slider-name-present.js +15 -17
- package/src/checks/automatic/spinbutton-name-present.js +19 -17
- package/src/checks/automatic/summary-name-present.js +16 -18
- package/src/checks/automatic/tab-name-present.js +16 -18
- package/src/checks/automatic/table-headers-attr-valid.js +15 -17
- package/src/checks/automatic/table-th-has-data-cells.js +15 -19
- package/src/checks/automatic/target-size-minimum.js +104 -81
- package/src/checks/automatic/td-has-header.js +15 -20
- package/src/checks/automatic/textbox-name-present.js +15 -17
- package/src/checks/automatic/tooltip-name-present.js +16 -18
- package/src/checks/automatic/treeitem-name-present.js +16 -18
- package/src/checks/automatic/valid-lang.js +15 -17
- package/src/checks/manual/accesskeys-manual.js +18 -19
- package/src/checks/manual/aria-checked-state-mismatch-manual.js +19 -22
- package/src/checks/manual/bypass-blocks-present-manual.js +4 -12
- package/src/checks/manual/empty-heading-manual.js +15 -17
- package/src/checks/manual/empty-table-header-manual.js +27 -30
- package/src/checks/manual/form-control-programmatic-label-quality-manual.js +2 -9
- package/src/checks/manual/heading-order-manual.js +17 -22
- package/src/checks/manual/image-redundant-alt-manual.js +14 -17
- package/src/checks/manual/label-title-only-manual.js +15 -17
- package/src/checks/manual/landmark-banner-is-top-level-manual.js +14 -17
- package/src/checks/manual/landmark-contentinfo-is-top-level-manual.js +14 -17
- package/src/checks/manual/landmark-main-is-top-level-manual.js +14 -17
- package/src/checks/manual/landmark-no-duplicate-banner-manual.js +2 -7
- package/src/checks/manual/landmark-no-duplicate-contentinfo-manual.js +2 -7
- package/src/checks/manual/landmark-no-duplicate-main-manual.js +2 -7
- package/src/checks/manual/landmark-one-main-manual.js +2 -9
- package/src/checks/manual/landmark-unique-manual.js +22 -27
- package/src/checks/manual/link-name-quality-manual.js +15 -17
- package/src/checks/manual/meta-viewport-large-manual.js +14 -17
- package/src/checks/manual/mouse-only-event-handlers-manual.js +17 -19
- package/src/checks/manual/page-has-heading-one-manual.js +2 -9
- package/src/checks/manual/presentation-role-conflict-manual.js +19 -21
- package/src/checks/manual/region-manual.js +13 -6
- package/src/checks/manual/scope-attr-valid-manual.js +14 -17
- package/src/checks/manual/skip-link-manual.js +39 -47
- package/src/checks/manual/tabindex-manual.js +14 -17
- package/src/checks/manual/table-duplicate-name-manual.js +14 -17
- package/src/core.js +4203 -3604
- package/src/report.js +14 -0
- package/surea11y.browser.js +1960 -3671
- package/surea11y.i18n.de.js +22 -0
- package/surea11y.i18n.es.js +22 -0
- package/surea11y.i18n.fr.js +22 -0
|
@@ -150,24 +150,22 @@ function runInPage(ctx) {
|
|
|
150
150
|
}
|
|
151
151
|
})()
|
|
152
152
|
: null;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
});
|
|
153
|
+
|
|
154
|
+
occurrences.push(
|
|
155
|
+
helpers.reportOccurrence(el, {
|
|
156
|
+
summary: 'This menu item has no accessible name.',
|
|
157
|
+
hint: 'Provide visible text that is not hidden from assistive technologies, or provide aria-label or aria-labelledby.',
|
|
158
|
+
i18n: {
|
|
159
|
+
summaryKey: 'menuitemNamePresent_summary_fail',
|
|
160
|
+
hintKey: 'menuitemNamePresent_hint_fail',
|
|
161
|
+
params: { role }
|
|
162
|
+
},
|
|
163
|
+
data: {
|
|
164
|
+
details: { reasonCode: 'name_missing', controlType: role, methodTried: res.method },
|
|
165
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
);
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
if (applicableCount === 0) {
|
|
@@ -126,24 +126,21 @@ function runInPage(ctx) {
|
|
|
126
126
|
|
|
127
127
|
applicableCount += 1;
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
details: { reasonCode: 'META_REFRESH_PRESENT' }
|
|
145
|
-
}
|
|
146
|
-
});
|
|
129
|
+
occurrences.push(
|
|
130
|
+
helpers.reportOccurrence(el, {
|
|
131
|
+
summary:
|
|
132
|
+
'This page uses a meta refresh, which is an automatic context change not initiated by the user.',
|
|
133
|
+
hint: 'Remove the meta refresh; trigger the redirect/refresh only in response to a user action instead.',
|
|
134
|
+
i18n: {
|
|
135
|
+
summaryKey: 'metaRefreshNoExceptions_summary_fail',
|
|
136
|
+
hintKey: 'metaRefreshNoExceptions_hint_fail',
|
|
137
|
+
params: {}
|
|
138
|
+
},
|
|
139
|
+
data: {
|
|
140
|
+
details: { reasonCode: 'META_REFRESH_PRESENT' }
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
);
|
|
147
144
|
}
|
|
148
145
|
|
|
149
146
|
if (applicableCount === 0) {
|
|
@@ -121,23 +121,20 @@ function runInPage(ctx) {
|
|
|
121
121
|
if (!(delay > 0)) continue;
|
|
122
122
|
if (delay > EXEMPT_DELAY_SECONDS) continue; // WCAG 2.2.1 Exception 3 (>20 hours)
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
details: { reasonCode: 'META_REFRESH_DELAYED', delay }
|
|
139
|
-
}
|
|
140
|
-
});
|
|
124
|
+
occurrences.push(
|
|
125
|
+
helpers.reportOccurrence(el, {
|
|
126
|
+
summary: 'This page refreshes itself automatically after a delay.',
|
|
127
|
+
hint: 'Remove the timed meta refresh, or provide a way for users to turn it off, extend it, or pause it before it triggers.',
|
|
128
|
+
i18n: {
|
|
129
|
+
summaryKey: 'metaRefreshTimingAbsent_summary_fail',
|
|
130
|
+
hintKey: 'metaRefreshTimingAbsent_hint_fail',
|
|
131
|
+
params: { delay: String(delay) }
|
|
132
|
+
},
|
|
133
|
+
data: {
|
|
134
|
+
details: { reasonCode: 'META_REFRESH_DELAYED', delay }
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
);
|
|
141
138
|
}
|
|
142
139
|
|
|
143
140
|
if (applicableCount === 0) {
|
|
@@ -131,23 +131,20 @@ function runInPage(ctx) {
|
|
|
131
131
|
|
|
132
132
|
if (!reasons.length) continue;
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
details: { reasonCode: 'VIEWPORT_ZOOM_RESTRICTED', reasons }
|
|
149
|
-
}
|
|
150
|
-
});
|
|
134
|
+
occurrences.push(
|
|
135
|
+
helpers.reportOccurrence(el, {
|
|
136
|
+
summary: 'This viewport meta tag restricts the user’s ability to zoom.',
|
|
137
|
+
hint: 'Remove user-scalable=no and any maximum-scale below 2 from the viewport meta content.',
|
|
138
|
+
i18n: {
|
|
139
|
+
summaryKey: 'metaViewportZoomEnabled_summary_fail',
|
|
140
|
+
hintKey: 'metaViewportZoomEnabled_hint_fail',
|
|
141
|
+
params: { reasons: reasons.join(', ') }
|
|
142
|
+
},
|
|
143
|
+
data: {
|
|
144
|
+
details: { reasonCode: 'VIEWPORT_ZOOM_RESTRICTED', reasons }
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
);
|
|
151
148
|
}
|
|
152
149
|
|
|
153
150
|
if (applicableCount === 0) {
|
|
@@ -133,24 +133,22 @@ function runInPage(ctx) {
|
|
|
133
133
|
}
|
|
134
134
|
})()
|
|
135
135
|
: null;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
});
|
|
136
|
+
|
|
137
|
+
occurrences.push(
|
|
138
|
+
helpers.reportOccurrence(el, {
|
|
139
|
+
summary: 'This meter has no accessible name.',
|
|
140
|
+
hint: "Provide aria-label, aria-labelledby, or a title attribute — visible text content is not exposed as this meter's accessible name.",
|
|
141
|
+
i18n: {
|
|
142
|
+
summaryKey: 'meterNamePresent_summary_fail',
|
|
143
|
+
hintKey: 'meterNamePresent_hint_fail',
|
|
144
|
+
params: {}
|
|
145
|
+
},
|
|
146
|
+
data: {
|
|
147
|
+
details: { reasonCode: 'name_missing', controlType: 'meter', methodTried: res.method },
|
|
148
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
);
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
if (applicableCount === 0) {
|
|
@@ -267,27 +267,25 @@ function runInPage(ctx) {
|
|
|
267
267
|
const dedupedNestedTags = [...new Set(nestedTags)];
|
|
268
268
|
|
|
269
269
|
const tag = el.tagName.toLowerCase();
|
|
270
|
-
const stableSelector = helpers.buildSelector ? helpers.buildSelector(el) : 'html';
|
|
271
|
-
const html = helpers.getOuterHtmlSnippet ? helpers.getOuterHtmlSnippet(el) : el.outerHTML || '';
|
|
272
270
|
|
|
273
|
-
occurrences.push(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
271
|
+
occurrences.push(
|
|
272
|
+
helpers.reportOccurrence(el, {
|
|
273
|
+
summary: 'This interactive control contains one or more other interactive controls.',
|
|
274
|
+
hint: 'Move the nested interactive control(s) outside this element; nested interactive controls are not reliably operable via assistive technology.',
|
|
275
|
+
i18n: {
|
|
276
|
+
summaryKey: 'nestedInteractiveControlsAbsent_summary_fail',
|
|
277
|
+
hintKey: 'nestedInteractiveControlsAbsent_hint_fail',
|
|
278
|
+
params: { element: tag, nestedElements: dedupedNestedTags.join(', ') }
|
|
279
|
+
},
|
|
280
|
+
data: {
|
|
281
|
+
details: {
|
|
282
|
+
reasonCode: 'NESTED_INTERACTIVE_CONTROL',
|
|
283
|
+
element: tag,
|
|
284
|
+
nestedElements: nestedTags
|
|
285
|
+
}
|
|
288
286
|
}
|
|
289
|
-
}
|
|
290
|
-
|
|
287
|
+
})
|
|
288
|
+
);
|
|
291
289
|
}
|
|
292
290
|
|
|
293
291
|
if (applicableCount === 0) {
|
|
@@ -145,24 +145,22 @@ function runInPage(ctx) {
|
|
|
145
145
|
}
|
|
146
146
|
})()
|
|
147
147
|
: null;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
});
|
|
148
|
+
|
|
149
|
+
occurrences.push(
|
|
150
|
+
helpers.reportOccurrence(el, {
|
|
151
|
+
summary: 'This element has no accessible name.',
|
|
152
|
+
hint: 'Provide aria-label or aria-labelledby (preferred), or provide visible text that is not hidden from assistive technologies.',
|
|
153
|
+
i18n: {
|
|
154
|
+
summaryKey: 'optionNamePresent_summary_fail',
|
|
155
|
+
hintKey: 'optionNamePresent_hint_fail',
|
|
156
|
+
params: { controlType: 'option' }
|
|
157
|
+
},
|
|
158
|
+
data: {
|
|
159
|
+
details: { reasonCode: 'name_missing', controlType: 'option', methodTried: res.method },
|
|
160
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
);
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
if (applicableCount === 0) {
|
|
@@ -135,28 +135,26 @@ function runInPage(ctx) {
|
|
|
135
135
|
}
|
|
136
136
|
})()
|
|
137
137
|
: null;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
summaryKey: 'progressbarNamePresent_summary_fail',
|
|
148
|
-
hintKey: 'progressbarNamePresent_hint_fail',
|
|
149
|
-
params: {}
|
|
150
|
-
},
|
|
151
|
-
data: {
|
|
152
|
-
details: {
|
|
153
|
-
reasonCode: 'name_missing',
|
|
154
|
-
controlType: 'progressbar',
|
|
155
|
-
methodTried: res.method
|
|
138
|
+
|
|
139
|
+
occurrences.push(
|
|
140
|
+
helpers.reportOccurrence(el, {
|
|
141
|
+
summary: 'This progress bar has no accessible name.',
|
|
142
|
+
hint: "Provide aria-label, aria-labelledby, or a title attribute — visible text content is not exposed as this progress bar's accessible name.",
|
|
143
|
+
i18n: {
|
|
144
|
+
summaryKey: 'progressbarNamePresent_summary_fail',
|
|
145
|
+
hintKey: 'progressbarNamePresent_hint_fail',
|
|
146
|
+
params: {}
|
|
156
147
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
148
|
+
data: {
|
|
149
|
+
details: {
|
|
150
|
+
reasonCode: 'name_missing',
|
|
151
|
+
controlType: 'progressbar',
|
|
152
|
+
methodTried: res.method
|
|
153
|
+
},
|
|
154
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
);
|
|
160
158
|
}
|
|
161
159
|
|
|
162
160
|
if (applicableCount === 0) {
|
|
@@ -227,24 +227,26 @@ function runInPage(ctx) {
|
|
|
227
227
|
}
|
|
228
228
|
})()
|
|
229
229
|
: null;
|
|
230
|
-
const stableSelector = helpers.buildSelector ? helpers.buildSelector(el) : 'html';
|
|
231
|
-
const html = helpers.getOuterHtmlSnippet ? helpers.getOuterHtmlSnippet(el) : el.outerHTML || '';
|
|
232
230
|
|
|
233
|
-
occurrences.push(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
231
|
+
occurrences.push(
|
|
232
|
+
helpers.reportOccurrence(el, {
|
|
233
|
+
summary: 'This element has no accessible name.',
|
|
234
|
+
hint: "Provide aria-label, aria-labelledby, or a title attribute — visible text content is not exposed as this searchbox's accessible name.",
|
|
235
|
+
i18n: {
|
|
236
|
+
summaryKey: 'searchboxNamePresent_summary_fail',
|
|
237
|
+
hintKey: 'searchboxNamePresent_hint_fail',
|
|
238
|
+
params: { controlType: 'searchbox' }
|
|
239
|
+
},
|
|
240
|
+
data: {
|
|
241
|
+
details: {
|
|
242
|
+
reasonCode: 'name_missing',
|
|
243
|
+
controlType: 'searchbox',
|
|
244
|
+
methodTried: res.method
|
|
245
|
+
},
|
|
246
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
);
|
|
248
250
|
}
|
|
249
251
|
|
|
250
252
|
if (applicableCount === 0) {
|
|
@@ -66,24 +66,21 @@ function runInPage(ctx) {
|
|
|
66
66
|
|
|
67
67
|
applicableCount += 1;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
details: { reasonCode: 'SERVER_SIDE_IMAGE_MAP' }
|
|
85
|
-
}
|
|
86
|
-
});
|
|
69
|
+
occurrences.push(
|
|
70
|
+
helpers.reportOccurrence(el, {
|
|
71
|
+
summary:
|
|
72
|
+
'This image uses a server-side image map, which has no keyboard-operable equivalent.',
|
|
73
|
+
hint: 'Replace the server-side image map (ismap) with a client-side image map (<map>/<area>) or separate accessible links/buttons.',
|
|
74
|
+
i18n: {
|
|
75
|
+
summaryKey: 'serverSideImageMapAbsent_summary_fail',
|
|
76
|
+
hintKey: 'serverSideImageMapAbsent_hint_fail',
|
|
77
|
+
params: {}
|
|
78
|
+
},
|
|
79
|
+
data: {
|
|
80
|
+
details: { reasonCode: 'SERVER_SIDE_IMAGE_MAP' }
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
if (applicableCount === 0) {
|
|
@@ -242,24 +242,22 @@ function runInPage(ctx) {
|
|
|
242
242
|
}
|
|
243
243
|
})()
|
|
244
244
|
: null;
|
|
245
|
-
const stableSelector = helpers.buildSelector ? helpers.buildSelector(el) : 'html';
|
|
246
|
-
const html = helpers.getOuterHtmlSnippet ? helpers.getOuterHtmlSnippet(el) : el.outerHTML || '';
|
|
247
245
|
|
|
248
|
-
occurrences.push(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
246
|
+
occurrences.push(
|
|
247
|
+
helpers.reportOccurrence(el, {
|
|
248
|
+
summary: 'This slider has no accessible name.',
|
|
249
|
+
hint: 'Provide a label, aria-label, or aria-labelledby so assistive technologies can identify the slider.',
|
|
250
|
+
i18n: {
|
|
251
|
+
summaryKey: 'sliderNamePresent_summary_fail',
|
|
252
|
+
hintKey: 'sliderNamePresent_hint_fail',
|
|
253
|
+
params: { kind }
|
|
254
|
+
},
|
|
255
|
+
data: {
|
|
256
|
+
details: { reasonCode: 'name_missing', controlType: kind, methodTried: res.method },
|
|
257
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
);
|
|
263
261
|
}
|
|
264
262
|
|
|
265
263
|
if (applicableCount === 0) {
|
|
@@ -227,24 +227,26 @@ function runInPage(ctx) {
|
|
|
227
227
|
}
|
|
228
228
|
})()
|
|
229
229
|
: null;
|
|
230
|
-
const stableSelector = helpers.buildSelector ? helpers.buildSelector(el) : 'html';
|
|
231
|
-
const html = helpers.getOuterHtmlSnippet ? helpers.getOuterHtmlSnippet(el) : el.outerHTML || '';
|
|
232
230
|
|
|
233
|
-
occurrences.push(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
231
|
+
occurrences.push(
|
|
232
|
+
helpers.reportOccurrence(el, {
|
|
233
|
+
summary: 'This element has no accessible name.',
|
|
234
|
+
hint: "Provide aria-label, aria-labelledby, or a title attribute — visible text content is not exposed as this spinbutton's accessible name.",
|
|
235
|
+
i18n: {
|
|
236
|
+
summaryKey: 'spinbuttonNamePresent_summary_fail',
|
|
237
|
+
hintKey: 'spinbuttonNamePresent_hint_fail',
|
|
238
|
+
params: { controlType: 'spinbutton' }
|
|
239
|
+
},
|
|
240
|
+
data: {
|
|
241
|
+
details: {
|
|
242
|
+
reasonCode: 'name_missing',
|
|
243
|
+
controlType: 'spinbutton',
|
|
244
|
+
methodTried: res.method
|
|
245
|
+
},
|
|
246
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
);
|
|
248
250
|
}
|
|
249
251
|
|
|
250
252
|
if (applicableCount === 0) {
|
|
@@ -144,24 +144,22 @@ function runInPage(ctx) {
|
|
|
144
144
|
}
|
|
145
145
|
})()
|
|
146
146
|
: null;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
});
|
|
147
|
+
|
|
148
|
+
occurrences.push(
|
|
149
|
+
helpers.reportOccurrence(el, {
|
|
150
|
+
summary: 'This summary has no accessible name.',
|
|
151
|
+
hint: 'Provide summary text that is not hidden from assistive technologies, or provide aria-label or aria-labelledby.',
|
|
152
|
+
i18n: {
|
|
153
|
+
summaryKey: 'summaryNamePresent_summary_fail',
|
|
154
|
+
hintKey: 'summaryNamePresent_hint_fail',
|
|
155
|
+
params: {}
|
|
156
|
+
},
|
|
157
|
+
data: {
|
|
158
|
+
details: { reasonCode: 'name_missing', controlType: 'summary', methodTried: res.method },
|
|
159
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
);
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
if (applicableCount === 0) {
|
|
@@ -148,24 +148,22 @@ function runInPage(ctx) {
|
|
|
148
148
|
}
|
|
149
149
|
})()
|
|
150
150
|
: null;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
});
|
|
151
|
+
|
|
152
|
+
occurrences.push(
|
|
153
|
+
helpers.reportOccurrence(el, {
|
|
154
|
+
summary: 'This tab has no accessible name.',
|
|
155
|
+
hint: 'Provide tab text that is not hidden from assistive technologies, or provide aria-label or aria-labelledby.',
|
|
156
|
+
i18n: {
|
|
157
|
+
summaryKey: 'tabNamePresent_summary_fail',
|
|
158
|
+
hintKey: 'tabNamePresent_hint_fail',
|
|
159
|
+
params: {}
|
|
160
|
+
},
|
|
161
|
+
data: {
|
|
162
|
+
details: { reasonCode: 'name_missing', controlType: 'tab', methodTried: res.method },
|
|
163
|
+
visibilityFilter: eligInfo || { targetSet: 'acc', accEligible: null, reasons: [] }
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
);
|
|
169
167
|
}
|
|
170
168
|
|
|
171
169
|
if (applicableCount === 0) {
|
|
@@ -104,23 +104,21 @@ function runInPage(ctx) {
|
|
|
104
104
|
const dedupedInvalidIds = [...new Set(invalid.map((i) => i.id))];
|
|
105
105
|
|
|
106
106
|
const tag = el.tagName.toLowerCase();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
});
|
|
107
|
+
|
|
108
|
+
occurrences.push(
|
|
109
|
+
helpers.reportOccurrence(el, {
|
|
110
|
+
summary: 'This cell’s headers attribute references one or more invalid header cells.',
|
|
111
|
+
hint: 'Update the headers attribute so every id refers to a <th> element within the same table.',
|
|
112
|
+
i18n: {
|
|
113
|
+
summaryKey: 'tableHeadersAttrValid_summary_fail',
|
|
114
|
+
hintKey: 'tableHeadersAttrValid_hint_fail',
|
|
115
|
+
params: { element: tag, invalidIds: dedupedInvalidIds.join(', ') }
|
|
116
|
+
},
|
|
117
|
+
data: {
|
|
118
|
+
details: { reasonCode: 'TABLE_HEADERS_ATTR_INVALID', element: tag, invalid }
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
);
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
if (applicableCount === 0) {
|