Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve aria-hidden warning rule to cover some valid use cases for adding it to elements #523

Merged
merged 18 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ff9bc6c
Add a test class and some initial test data for aria-hidden rule
pattonwebz Mar 7, 2024
7f57cde
Add helpers prep and pass markup to the aria-hidden test rule
pattonwebz Mar 7, 2024
70133ba
Add tests that cover the current functionality of aria-hidden rule
pattonwebz Mar 7, 2024
a04700f
Add tests to cover newly requested functionality from #448
pattonwebz Mar 7, 2024
f3258bc
Make aria-hidden rule handle elements that are hidden but presentational
pattonwebz Mar 7, 2024
6aa59e7
Make aria-hidden not flag elements if their parent has a non-empty label
pattonwebz Mar 7, 2024
b47607a
Add some handling for sibling nodes are are likely screen reader elem…
pattonwebz Mar 12, 2024
e80da13
Remove test case for visible text checking in aria-hidden rules
pattonwebz Mar 12, 2024
36bd601
Add `@ since` tags for new functions added
pattonwebz Mar 12, 2024
6cde56f
Avoid single user vars in test helper function
pattonwebz Mar 12, 2024
5c194ab
Use dataProvider for passing and some failing screen-reader classes o…
pattonwebz Mar 12, 2024
5b8b577
Do exact match on screen-reader classes rather than contains checks t…
pattonwebz Mar 12, 2024
3089283
Ensure that parent elements that are NOT buttons or links don't have …
pattonwebz Mar 15, 2024
24a1eb0
Remove unnecessary line space
pattonwebz Mar 15, 2024
a233cf0
Try detect visible text by stripping tags from parent if there is mor…
pattonwebz Mar 15, 2024
48ba4e7
Add test for visible text type markups
pattonwebz Mar 15, 2024
023c510
Try make conditions more readable
pattonwebz Mar 15, 2024
f75ce37
Use a more strait-forward condition check for readability
pattonwebz Mar 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 117 additions & 2 deletions includes/rules/aria_hidden.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,50 @@ function edac_rule_aria_hidden( $content, $post ) { // phpcs:ignore -- $post is
$errors = array();
$elements = $dom->find( '[aria-hidden="true"]' );

$attributes_that_make_this_valid_hidden_use = array(
'class' => 'wp-block-spacer',
'role' => 'presentation',
);

if ( $elements ) {
foreach ( $elements as $element ) {

if ( stristr( $element->getAttribute( 'class' ), 'wp-block-spacer' ) ) {
continue;
foreach ( $attributes_that_make_this_valid_hidden_use as $attribute => $value ) {
if ( stristr( $element->getAttribute( $attribute ), $value ) ) {
continue 2;
}
}

$parent_node = $element->parent();
if (
$parent_node &&
(
strtolower( $parent_node->tag ) === 'button' ||
strtolower( $parent_node->tag ) === 'a'
)
) {
if ( edac_rule_aria_hidden_valid_parentnode_condition_check( $parent_node, $element ) ) {
continue;
}

$siblings = $parent_node->children();

// if there's only 1 sibling then it's the element itself, and
// we can assume it's neither screen reader text nor visible.
if ( ! $siblings || 1 === $siblings ) {
$errors[] = $element;
continue;
}

if ( edac_rule_aria_hidden_siblings_are_screen_reader_text_elements( $siblings ) ) {
continue;
}

// if the parent node has any text after stripping the tags then
// assume it's visible text making the aria-hidden="true" valid.
if ( ! empty( edac_rule_aria_hidden_strip_markup_and_return_text( $parent_node ) ) ) {
continue;
}
}

$errors[] = $element;
Expand All @@ -31,3 +70,79 @@ function edac_rule_aria_hidden( $content, $post ) { // phpcs:ignore -- $post is

return $errors;
}

/**
* Check if the siblings are screen reader text elements.
*
* @since 1.10.0
*
* @param array $siblings Array of siblings.
* @return bool
*/
function edac_rule_aria_hidden_siblings_are_screen_reader_text_elements( array $siblings ): bool {
$common_screen_reader_classes = array(
'screen-reader-text',
'sr-only',
'show-for-sr',
'visuallyhidden',
'visually-hidden',
'hidden-visually',
'invisible',
'accessibly-hidden',
'hide',
'hidden',
);

foreach ( $siblings as $sibling ) {
foreach ( $common_screen_reader_classes as $class ) {
if ( strtolower( $sibling->getAttribute( 'class' ) ) === $class ) {
return true;
}
}
}
return false;
}

/**
* Check if the parent has a valid situation to avoid flagging aria-hidden="true" warning.
*
* @since 1.10.0
*
* @param object $parent_node The parent element.
* @param object $element The element.
*
* @return bool
*/
function edac_rule_aria_hidden_valid_parentnode_condition_check( object $parent_node, object $element ): bool {
// bail early if we don't have a parent node or an element node.
if (
! $parent_node ||
! $element
) {
return false;
}

// parent node with a non-empty aria-label makes the aria-hidden="true" likely valid.
if ( ! empty( $parent_node->getAttribute( 'aria-label' ) ) ) {
return true;
}

return false;
}

/**
* Strip the markup and return the text if there is any leftover.
*
* @since 1.10.0
*
* @param object $parent_node A simple_html_dom_node of a parent container.
*
* @return string empty string for invalid parent node, string of text if some
* is leftover running through tag stripping.
*/
function edac_rule_aria_hidden_strip_markup_and_return_text( object $parent_node ): string {
if ( ! ( $parent_node instanceof simple_html_dom_node ) ) {
return '';
}
return trim( wp_strip_all_tags( $parent_node->innertext() ) );
}
Loading
Loading