Skip to content

Commit

Permalink
Merge pull request #1964 from IBMa/dev-1911
Browse files Browse the repository at this point in the history
fixrule(`element_scrollable_tabbable`, `label_name_visible`): fix issues related to off-screen and scrollable content
  • Loading branch information
ErickRenteria authored Aug 14, 2024
2 parents 19e1121 + d4c0adb commit 50c6dfc
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 5 deletions.
4 changes: 3 additions & 1 deletion accessibility-checker-engine/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
// { pattern: 'test/v2/checker/accessibility/rules/WCAG20_Table_CapSummRedundant_ruleunit/*.html', watched: true },

// { pattern: 'test/v2/checker/accessibility/rules/Rpt_Aria_RequiredParent_Native_Host_Sematics_ruleunit/ACT_ff89c9_pass4.html', watched: true },
// { pattern: 'test/v2/checker/accessibility/rules/IBMA_Color_Contrast_WCAG2AA_ruleunit/Color-hidden.html', watched: true },
//{ pattern: 'test/v2/checker/accessibility/rules/label_name_visible_ruleunit/label_offscreen.html', watched: true },
//{ pattern: 'test/v2/checker/accessibility/rules/aria_role_valid_ruleunit/td_attribute_invalid_copy.html', watched: true },
//{ pattern: 'test/v2/checker/accessibility/rules/label_name_visible_ruleunit/label_multiple_offscreen.html', watched: true },


{ pattern: 'test/**/*_ruleunit/*.html', watched: true },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ export class RPTUtil {
}

public static normalizeSpacing(s) {
if (!s) return '';
return s.trim().replace(/\s+/g, ' ');
};

Expand Down Expand Up @@ -2686,6 +2687,39 @@ export class RPTUtil {
return retVal;
}

/**
* return onscreen innerText.
* This function should return the same result as innerText if no offscreen content exists
*
* @parm {element} node The node which should be checked it has inner text or not.
* @return {null | string} null if element has empty inner text, text otherwise
*
* @memberOf RPTUtil
*/
public static getOnScreenInnerText(element) {
if (!element) return null;
if (element.nodeType === 3) return element.nodeValue();

let text = "";
let nw = new NodeWalker(element);

// Loop over all the childrens of the element to get the text
while (nw.nextNode() && nw.node !== element && nw.node !== element.parentNode) {
if ((nw.node.nodeType === 1 && (VisUtil.hiddenByDefaultElements.includes(nw.node.nodeName.toLowerCase())) || !VisUtil.isNodeVisible(nw.node) || VisUtil.isElementOffscreen(nw.node))) {
if (nw.node.nextSibling) {
if (nw.node.nextSibling.nodeType === 3 && nw.node.nextSibling.nodeValue !== null)
text += nw.node.nextSibling.nodeValue;
nw.node = nw.node.nextSibling;
continue;
} else
break;
}
if (nw.node.nodeType === 3 && nw.node.nodeValue !== null)
text += nw.node.nodeValue;
}
return text.trim();
}

/** Return the text content of the given node
* this is different than innerText or textContent that return text content of a node and its descendants
*/
Expand Down
20 changes: 20 additions & 0 deletions accessibility-checker-engine/src/v2/dom/VisUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { getCache, setCache } from "../../v4/util/CacheUtil";
import { DOMUtil } from "./DOMUtil";
import { DOMWalker } from "./DOMWalker";
import { DOMMapper } from "../../v2/dom/DOMMapper";

export class VisUtil {
// This list contains a list of element tags which can not be hidden, when hidden is
Expand Down Expand Up @@ -248,6 +249,25 @@ export class VisUtil {
return true;
}

/**
* return true if the node is offscreen by CSS position
* @param node
*/
public static isElementOffscreen(node: Node) : boolean {
if (!node) return false;

const mapper : DOMMapper = new DOMMapper();
const bounds = mapper.getUnadjustedBounds(node);;

if (!bounds)
return false;

if (bounds['height'] === 0 || bounds['width'] === 0 || bounds['top'] < 0 || bounds['left'] < 0)
return true;

return false;
}

/**
* return true if the node or its ancestor is natively hidden or aria-hidden = 'true'
* @param node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ export let element_scrollable_tabbable: Rule = {
&& ruleContext.scrollHeight - ruleContext.clientHeight < 1+ padding_y)
return null;

// pass iframe element has a tabindex attribute value that is not negative
if (ruleContext.hasAttribute("tabindex") && parseInt(ruleContext.getAttribute("tabindex")) >= 0)
// pass if element is tabbable
if (RPTUtil.isTabbable(ruleContext))
return RulePass("pass_tabbable");

// check if element content is tabbable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ export let label_name_visible: Rule = {
if (!labelElem && elementsToSkipContentCheck.indexOf(nodeName) !== -1) {
text = ""; // skip content check for some elements
} else {
// get the visible text
text = RPTUtil.getInnerText(element);
// get the visible text only
text = RPTUtil.getOnScreenInnerText(element);
}

/* Note: Disable this alt check in images for now until we get confirmation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>test case</title>
</head>
<body>
<textarea style="height: 100px; width: 500px; overflow-y: scroll">
<h1>WCAG Abstract</h1>
<p>
Web Content Accessibility Guidelines (WCAG) covers a wide range of recommendations for making Web content more
accessible. Following these guidelines will make content more accessible to a wider range of people with
disabilities, including accommodations for blindness and low vision, deafness and hearing loss, limited movement,
speech disabilities, photosensitivity, and combinations of these, and some accommodation for learning disabilities
and cognitive limitations; but will not address every user need for people with these disabilities. These guidelines
address accessibility of web content on desktops, laptops, tablets, and mobile devices. Following these guidelines
will also often make Web content more usable to users in general.
</p>
</textarea>

<script>
UnitTest = {
ruleIds: ["element_scrollable_tabbable"],
results: [
{
"ruleId": "element_scrollable_tabbable",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/textarea[1]",
"aria": "/document[1]/textbox[1]"
},
"reasonId": "pass_tabbable",
"message": "The scrollable element is tabbable",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>test case</title>
</head>
<body>
<textarea id="story" name="story" rows="1" cols="33">
It was a dark and stormy night...
It was a dark and stormy night...
It was a dark and stormy night...
It was a dark and stormy night...
</textarea>

<script>
UnitTest = {
ruleIds: ["element_scrollable_tabbable"],
results: [
{
"ruleId": "element_scrollable_tabbable",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/textarea[1]",
"aria": "/document[1]/textbox[1]"
},
"reasonId": "pass_tabbable",
"message": "The scrollable element is tabbable",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>test case</title>
</head>
<body>
<div role="button" id='button1' aria-label="Visible label">
<span style="position:absolute;left:-1000px">1st label</span>
2nd label
<span style="position:absolute;left:-1000px">3rd label</span>
4th label
<span>5th label</span>6th label
<span style="position:absolute;left:-1000px">7th label</span>
8th label
</div>

<div> another line </div>
<script>
UnitTest = {
ruleIds: ["label_name_visible"],
results: [
{
"ruleId": "label_name_visible",
"value": [
"INFORMATION",
"FAIL"
],
"path": {
"dom": "/html[1]/body[1]/div[1]",
"aria": "/document[1]/button[1]"
},
"reasonId": "Fail_1",
"message": "Accessible name does not match or contain the visible label text",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>test case</title>
</head>
<body>
<button id='button1' aria-label="Visible label">
<span style="position:absolute;left:-1000px">Offscreen content</span>
Visible label
</button>

<button id='button2' aria-label="Another visible label">
<span> Another Offscreen content</span>
Another Visible label
</button>
<div> another line </div>
<script>
UnitTest = {
ruleIds: ["label_name_visible"],
results: [
{
"ruleId": "label_name_visible",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/button[1]",
"aria": "/document[1]/button[1]"
},
"reasonId": "Pass_0",
"message": "Accessible name matches or contains the visible label text",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
},
{
"ruleId": "label_name_visible",
"value": [
"INFORMATION",
"FAIL"
],
"path": {
"dom": "/html[1]/body[1]/button[2]",
"aria": "/document[1]/button[2]"
},
"reasonId": "Fail_1",
"message": "Accessible name does not match or contain the visible label text",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>

0 comments on commit 50c6dfc

Please sign in to comment.