From 41d127dd55f2e0134aa1b341ec80e3d67ec812b5 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Fri, 13 Oct 2023 18:45:48 -0500 Subject: [PATCH] initial rule #1674 --- .../v2/checker/accessibility/util/legacy.ts | 26 +++++++++++++++++++ .../src/v4/rules/target_spacing_sufficient.ts | 2 +- .../src/v4/util/CommonUtil.ts | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/accessibility-checker-engine/src/v2/checker/accessibility/util/legacy.ts b/accessibility-checker-engine/src/v2/checker/accessibility/util/legacy.ts index 9523e5bc8..9b78b05c0 100644 --- a/accessibility-checker-engine/src/v2/checker/accessibility/util/legacy.ts +++ b/accessibility-checker-engine/src/v2/checker/accessibility/util/legacy.ts @@ -419,6 +419,32 @@ export class RPTUtil { } } + /** + * a target is en element that accept a pointer action (click or touch) + */ + public static isTarget(element) { + if (!element) return false; + + 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; + + const parent = element.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; + } + public static tabIndexLEZero(elem) { if (RPTUtil.hasAttribute(elem, "tabindex")) { if (elem.getAttribute("tabindex").match(/^-?\d+$/)) { diff --git a/accessibility-checker-engine/src/v4/rules/target_spacing_sufficient.ts b/accessibility-checker-engine/src/v4/rules/target_spacing_sufficient.ts index 3b94a250b..4c8311f7f 100644 --- a/accessibility-checker-engine/src/v4/rules/target_spacing_sufficient.ts +++ b/accessibility-checker-engine/src/v4/rules/target_spacing_sufficient.ts @@ -119,7 +119,7 @@ if (bnds.top <= bounds.top && bnds.left <= bounds.left && bnds.top + bnds.height >= bounds.top + bounds.height && bnds.left + bnds.height >= bounds.left + bounds.width && (before ? parseInt(zindex) < parseInt(z_index): parseInt(zindex) <= parseInt(z_index))) - // if the target is entirely covered: handled by element_tabbable_unobscured + // if the target is entirely covered: tabbable target handled by element_tabbable_unobscured and tabindex=-1 ignored continue; if (bnds.height !== 0 && bnds.width !== 0 diff --git a/accessibility-checker-engine/src/v4/util/CommonUtil.ts b/accessibility-checker-engine/src/v4/util/CommonUtil.ts index c6b0e9ab5..7632f91bf 100644 --- a/accessibility-checker-engine/src/v4/util/CommonUtil.ts +++ b/accessibility-checker-engine/src/v4/util/CommonUtil.ts @@ -60,7 +60,7 @@ export function getInvalidRoles(ruleContext: Element) { let invalidRoles = []; - if (allowedRoles && allowedRoles.includes('any')) + if (allowedRoles.includes('any')) return []; for (let i = 0; i < domRoles.length; i++)