feat(rules): support ARIA element internals properties#5168
Conversation
Updates autocomplete-matches.js to use getAriaValue for aria-readonly and aria-disabled checks so that values set via ElementInternals are also respected.
- aria-hidden-focus-matches: shouldMatchElement used el.getAttribute('aria-hidden')
directly on a DOM node; convert to getAriaValue via getNodeFromTree with
fallback to getAttribute when the node is not in the axe virtual tree
- color-contrast-matches: control.getAttribute('aria-labelledby') used to
check which controls reference an ancestor; convert to vNode.attr() for the
HTML attribute case, and getResolvedRefs for the property/internals case
(where the attribute string is absent but element refs are set)
…nternals Adds a full integration test verifying that a focusable element inside a [aria-hidden=true] container whose ancestor has aria-hidden=true set via elementInternals is excluded from the rule — no violations.
…on/rules Add a testutils-element with aria-hidden via elementInternals containing a focusable [aria-hidden=true] div. With the fix the inner element is excluded by the matches function (ancestor internals aria-hidden detected) so no new violation appears. Without the fix it would be a violation, causing 'should not return other results' to fail.
WilcoFiers
left a comment
There was a problem hiding this comment.
LGTM, just needs to be updated to 5177
| // the composed parent could or could not be included in the tree so we'll need to handle either case | ||
| const ariaHidden = vNode | ||
| ? getAriaValue(vNode, 'aria-hidden', { lowercase: true })?.value | ||
| : el.getAttribute('aria-hidden'); |
There was a problem hiding this comment.
Assume we can drop this with https://github.com/dequelabs/axe-core/pull/5177/changes#r3435735513
|
Heads up: the audit report in the PR description looks out of sync with the actual diff. The description lists
…and doesn't touch (Also updated the issue trailer — this is the |
Updates the
rulesdirectory to use the newgetAriaValuefunction where it makes sense. Only the JS match files were reviewed; JSON rule definitions have no ARIA attr access.Here's a report of the full directory (JS files only):
rules/autocomplete-matches- aria-readonly and aria-disabled → getAriaValue with{ lowercase: true }(both are boolean type); removed the now-redundant.toLowerCase()calls on the comparisonrules/aria-allowed-attr-matches- iterates overattrNames, no direct.attr('aria-*')callrules/aria-has-attr-matches- checks for presence of any aria attr viaattrNames, not a value lookuprules/bypass-matches- checks for links and headings, no ARIA attr accessrules/color-contrast-matches- checks visibility, no ARIA attr accessrules/identical-links-same-purpose-matches- computes accessible names, no ARIA attr accessrules/inserted-into-focus-order-matches- checks tabindex, not an ARIA proprules/label-matches- checks element type and role, no direct aria attr value accessrules/landmark-has-body-context-matches- checks role, not an ARIA proprules/no-autoplay-audio-matches- checks media attributes, no ARIA attr accessrules/no-empty-role-matches- checks role attr, not an ARIA proprules/no-negative-tabindex-matches- checks tabindex, not an ARIA proprules/no-role-matches- checks role attr, not an ARIA propCloses: #5150