Skip to content

Commit

Permalink
add utilities for target #1674
Browse files Browse the repository at this point in the history
  • Loading branch information
shunguoy committed Oct 16, 2023
1 parent 41d127d commit ee16f58
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,45 @@ export class RPTUtil {
if (!allowedRoles && allowedRoles.length === 0)
return false;

const parent = element.parentElement;
let parent = element.parentElement;
// datalist, fieldset, optgroup, etc. may be just used for grouping purpose, so go up to the parent
while (parent && roles.some(role => role === 'group'))
parent = parent.parentElement;

if (parent && (parent.hasAttribute("tabindex") || RPTUtil.isTabbable(parent))) {
const target_roles =["listitem", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "treeitem"];
if (allowedRoles.includes('any') || roles.some(role => target_roles.includes(role)))
return true;
}
return false;
}

/**
* an "inline" CSS display property tells the element to fit itself on the same line. An 'inline' element's width and height are ignored.
* some element has default inline property, such as <span>, <a>, <img>
* most formatting elements inherent inline property, such as <em>, <strong>, <i>, <small>
* an "inline-block" element still place element in the same line without breaking the line, but the element's width and height are applied.
*/
public static isInline(element) {
if (!element) return false;

const inline_elements = ["listitem", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "treeitem"];
if (element.hasAttribute("tabindex") || RPTUtil.isTabbable(element)) return true;

const roles = RPTUtil.getRoles(element, true);
if (!roles && roles.length === 0)
return false;

let tagProperty = RPTUtil.getElementAriaProperty(element);
let allowedRoles = RPTUtil.getAllowedAriaRoles(element, tagProperty);
if (!allowedRoles && allowedRoles.length === 0)
return false;

let parent = element.parentElement;
// datalist, fieldset, optgroup, etc. may be just used for grouping purpose, so go up to the parent
while (parent && roles.some(role => role === 'group'))
parent = parent.parentElement;

if (parent && (parent.hasAttribute("tabindex") || RPTUtil.isTabbable(parent))) {
const target_roles =["listitem", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "treeitem"];
if (allowedRoles.includes('any') || roles.some(role => target_roles.includes(role)))
Expand Down
1 change: 1 addition & 0 deletions accessibility-checker-engine/src/v4/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export * from "./table_layout_linearized"
export * from "./table_scope_valid"
export * from "./table_structure_misuse"
export * from "./table_summary_redundant"
export * from "./target_spacing_sufficient"
export * from "./text_block_heading"
export * from "./text_contrast_sufficient"
export * from "./text_quoted_correctly"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
act: [],
run: (context: RuleContext, options?: {}, contextHierarchies?: RuleContextHierarchy): RuleResult | RuleResult[] => {
const ruleContext = context["dom"].node as HTMLElement;
if (!VisUtil.isNodeVisible(ruleContext) || (!RPTUtil.isTabbable(ruleContext) && !ruleContext .hasAttribute("tabindex")))
if (!VisUtil.isNodeVisible(ruleContext) || (!RPTUtil.isTarget(ruleContext)))
return null;

const nodeName = ruleContext.nodeName.toLocaleLowerCase();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--
/******************************************************************************
Copyright:: 2020- IBM, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
-->

<html lang="en">

<head>
<title>RPT Test Suite</title>
<style>
a.link {
display: inline; /* the default for a */
width: 100px;
height: 100px;
padding: 5px;
}

button.btn {
display: inline;
width: 100px;
height: 100px;
padding: 5px;
}

button.btn2 {
display: inline-block;
width: 100px;
height: 100px;
padding: 5px;
border: 1px solid blue;
background-color: yellow;
}

p {
display: block;
width: 100px;
height: 100px;
padding: 5px;
border: 1px solid blue;
background-color: yellow;
}
</style>
</head>

<body>

<h1>The display Property</h1>

<h2>display: inline</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat. <a class='link' href="google.com">Aliquam</a> <button class='btn' value='venenatis'></button> gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet. </div>

<h2>display: inline-block</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat. <span class="b">Aliquam</span> <span class="b">venenatis</span> gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet. </div>

<h2>display: block</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat. <span class="c">Aliquam</span> <span class="c">venenatis</span> gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet. </div>



<script>
UnitTest = {
ruleIds: ["element_tabbable_unobscured"],
results: [
{
"ruleId": "element_tabbable_unobscured",
"value": [
"INFORMATION",
"POTENTIAL"
],
"path": {
"dom": "/html[1]/body[1]/div[1]",
"aria": "/document[1]"
},
"reasonId": "potential_obscured",
"message": "Confirm that when the element receives focus, it is not covered or, if covered by user action, can be uncovered without moving focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
},
{
"ruleId": "element_tabbable_unobscured",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/div[2]",
"aria": "/document[1]"
},
"reasonId": "pass",
"message": "The element is not entirely covered by other content",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--
/******************************************************************************
Copyright:: 2020- IBM, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*****************************************************************************/
-->

<html lang="en">

<head>
<title>RPT Test Suite</title>
<style>
a.link {
display: inline; /* the default for a */
width: 100px;
height: 100px;
line-height: 100px;
padding: 5px;
}

button.btn {
display: inline;
/**width: 100px;
height: 100px;
padding: 5px;*/
}

button.btn2 {
display: inline-block;
width: 100px;
height: 100px;
padding: 5px;
border: 1px solid blue;
background-color: yellow;
}

p {
display: block;
width: 100px;
height: 100px;
padding: 5px;
border: 1px solid blue;
background-color: yellow;
}
</style>
</head>

<body>

<h1>The display Property</h1>

<h2>display: inline</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat.
<a class='link' href="google.com">Aliquam</a>
<button class='btn' value='venenatis'></button>
gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet.
</div>

<h2>display: inline-block</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat. <span class="b">Aliquam</span> <span class="b">venenatis</span> gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet. </div>

<h2>display: block</h2>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat scelerisque elit sit amet consequat. Aliquam erat volutpat. <span class="c">Aliquam</span> <span class="c">venenatis</span> gravida nisl sit amet facilisis. Nullam cursus fermentum velit sed laoreet. </div>



<script>
UnitTest = {
ruleIds: ["element_tabbable_unobscured"],
results: [
{
"ruleId": "element_tabbable_unobscured",
"value": [
"INFORMATION",
"POTENTIAL"
],
"path": {
"dom": "/html[1]/body[1]/div[1]",
"aria": "/document[1]"
},
"reasonId": "potential_obscured",
"message": "Confirm that when the element receives focus, it is not covered or, if covered by user action, can be uncovered without moving focus",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
},
{
"ruleId": "element_tabbable_unobscured",
"value": [
"INFORMATION",
"PASS"
],
"path": {
"dom": "/html[1]/body[1]/div[2]",
"aria": "/document[1]"
},
"reasonId": "pass",
"message": "The element is not entirely covered by other content",
"messageArgs": [],
"apiArgs": [],
"category": "Accessibility"
}
]
}
</script>
</body>

</html>

0 comments on commit ee16f58

Please sign in to comment.