From 9e7cf414fb087f45e3745a7dba25f848526176a9 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Thu, 2 Nov 2023 16:07:56 -0500 Subject: [PATCH 01/11] initial rule creation #1675 --- .../en-US/element_draggable_alternative.html | 97 ++++++++++++++ .../v4/rules/element_draggable_alternative.ts | 123 ++++++++++++++++++ .../v4/rules/element_tabbable_unobscured.ts | 1 - .../src/v4/rulesets.ts | 1 + .../src/v4/sc-urls.json | 12 ++ 5 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html create mode 100644 accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts diff --git a/accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html b/accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html new file mode 100644 index 000000000..fa9d44e73 --- /dev/null +++ b/accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html @@ -0,0 +1,97 @@ + + + + + + + + + + + + + +
+
+
+ +

+ +
+ +

+
+
+
+
+ + + + +
+
+
+ + + +
+
+
+ + diff --git a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts new file mode 100644 index 000000000..565d923a3 --- /dev/null +++ b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts @@ -0,0 +1,123 @@ +/****************************************************************************** + Copyright:: 2022- 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. + *****************************************************************************/ + +import { RPTUtil } from "../../v2/checker/accessibility/util/legacy"; +import { Rule, RuleResult, RuleContext, RulePass, RuleContextHierarchy, RulePotential } from "../api/IRule"; +import { eRulePolicy, eToolkitLevel } from "../api/IRule"; +import { VisUtil } from "../../v2/dom/VisUtil"; +import { DOMMapper } from "../../v2/dom/DOMMapper"; + +export let element_draggable_alternative: Rule = { + id: "element_draggable_alternative", + context: "dom:*", + dependencies: [], + help: { + "en-US": { + "group": "element_draggable_alternative.html", + "pass": "element_draggable_alternative.html", + "potential_obscured": "element_draggable_alternative.html" + } + }, + messages: { + "en-US": { + "group": "When an element receives focus, it is not entirely covered by other content", + "pass": "The element is not entirely covered by other content", + "potential_obscured": "Confirm that when the element receives focus, it is not covered or, if covered by user action, can be uncovered without moving focus" + } + }, + rulesets: [{ + id: ["WCAG_2_2"], + num: ["2.5.7"], + level: eRulePolicy.VIOLATION, + toolkitLevel: eToolkitLevel.LEVEL_THREE + }], + act: [], + run: (context: RuleContext, options?: {}, contextHierarchies?: RuleContextHierarchy): RuleResult | RuleResult[] => { + const ruleContext = context["dom"].node as HTMLElement; + if (!VisUtil.isNodeVisible(ruleContext) || !RPTUtil.isTabbable(ruleContext)) + return null; + + const nodeName = ruleContext.nodeName.toLocaleLowerCase(); + + //ignore certain elements + if (RPTUtil.getAncestor(ruleContext, ["pre", "code", "script", "meta"]) !== null + || nodeName === "body" || nodeName === "html" ) + return null; + + const bounds = context["dom"].bounds; + + //in case the bounds not available + if (!bounds) return null; + + //ignore if offscreen + if (bounds['height'] === 0 || bounds['width'] === 0 ) + return null; + + const doc = ruleContext.ownerDocument; + if (!doc) { + return null; + } + const win = doc.defaultView; + if (!win) { + return null; + } + + const cStyle = win.getComputedStyle(ruleContext); + if (cStyle === null) + return null; + + let zindex = cStyle.zIndex; + if (!zindex || zindex === 'auto') + zindex = "0"; + + const elems = doc.querySelectorAll('body *:not(script)'); + if (!elems || elems.length == 0) + return; + + const mapper : DOMMapper = new DOMMapper(); + let violations = []; + let before = true; + elems.forEach(elem => { + /** + * the nodes returned from querySelectorAll is in document order + * if two elements overlap and z-index are not defined, then the node rendered earlier will be overlaid by the node rendered later + */ + if (ruleContext.contains(elem)) { + //the next node in elems will be after the target node (ruleContext). + before = false; + } else if (VisUtil.isNodeVisible(elem) && !elem.contains(ruleContext)) { + const bnds = mapper.getBounds(elem); + const zStyle = win.getComputedStyle(elem); + let z_index = '0'; + if (zStyle) { + z_index = zStyle.zIndex; + if (!z_index || isNaN(Number(z_index))) + z_index = "0"; + } + if (bnds.height !== 0 && bnds.width !== 0 + && 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))) + { + violations.push(elem); + } + } + }); + + if (violations.length > 0) { + return RulePotential("potential_obscured", []); + } + + return RulePass("pass"); + } +} diff --git a/accessibility-checker-engine/src/v4/rules/element_tabbable_unobscured.ts b/accessibility-checker-engine/src/v4/rules/element_tabbable_unobscured.ts index 7d6057c6b..d84272253 100644 --- a/accessibility-checker-engine/src/v4/rules/element_tabbable_unobscured.ts +++ b/accessibility-checker-engine/src/v4/rules/element_tabbable_unobscured.ts @@ -16,7 +16,6 @@ import { Rule, RuleResult, RuleContext, RulePass, RuleContextHierarchy, RulePote import { eRulePolicy, eToolkitLevel } from "../api/IRule"; import { VisUtil } from "../../v2/dom/VisUtil"; import { DOMMapper } from "../../v2/dom/DOMMapper"; -import { DOMUtil } from "../../v2/dom/DOMUtil"; export let element_tabbable_unobscured: Rule = { id: "element_tabbable_unobscured", diff --git a/accessibility-checker-engine/src/v4/rulesets.ts b/accessibility-checker-engine/src/v4/rulesets.ts index f5a4eea58..b46ec0a5c 100644 --- a/accessibility-checker-engine/src/v4/rulesets.ts +++ b/accessibility-checker-engine/src/v4/rulesets.ts @@ -61,6 +61,7 @@ const summaries = { "2.5.2": "For functionality that can be operated using a single pointer, completion of the function is on the up-event with an ability to abort, undo or reverse the outcome.", "2.5.3": "For user interface components with labels that include text or images of text, the accessible name contains the text that is presented visually.", "2.5.4": "Functionality that can be operated by motion can also be operated by user interface components, and the motion trigger can be disabled.", + "2.5.7": "All functionality that uses a dragging movement for operation can be achieved by a single pointer without dragging.", "3.1.1": "The default human language of Web pages, non-Web documents, or software can be programmatically determined.", "3.1.2": "The human language of each passage or phrase in the content can be programmatically determined.", "3.2.1": "When any component receives focus, it does not initiate a change of context.", diff --git a/accessibility-checker-engine/src/v4/sc-urls.json b/accessibility-checker-engine/src/v4/sc-urls.json index a84f4603c..93183bb16 100644 --- a/accessibility-checker-engine/src/v4/sc-urls.json +++ b/accessibility-checker-engine/src/v4/sc-urls.json @@ -707,6 +707,18 @@ "level": "AAA", "wcagType": "2.1" }, + "2.5.7": { + "num": "2.5.7", + "url": "https://www.w3.org/TR/WCAG22/#dragging-movements", + "scId": "WCAG2:dragging-movement", + "scAltId": ["dragging-movement"], + "test": "WCAG2:WCAG2:dragging-movement", + "howToMeetUrl": "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html", + "understandingUrl": "https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html", + "handle": "Dragging Movement", + "level": "AA", + "wcagType": "2.2" + }, "3.1.1": { "num": "3.1.1", "url": "https://www.w3.org/TR/WCAG21/#language-of-page", From 1f76df60759999f9e7e7fb3b97f6492db61e73e2 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Thu, 2 Nov 2023 16:35:23 -0500 Subject: [PATCH 02/11] update the context #1675 --- .../src/v4/rules/element_draggable_alternative.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts index 565d923a3..5629340c0 100644 --- a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts +++ b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts @@ -19,7 +19,7 @@ import { DOMMapper } from "../../v2/dom/DOMMapper"; export let element_draggable_alternative: Rule = { id: "element_draggable_alternative", - context: "dom:*", + context: "dom:*[draggable]", dependencies: [], help: { "en-US": { From aedb7c2204d4e747f39bbfda96734c6d750671a5 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Fri, 3 Nov 2023 10:26:22 -0500 Subject: [PATCH 03/11] initial rule #1675 --- .../v4/rules/element_draggable_alternative.ts | 72 +++---------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts index 5629340c0..96200dbe6 100644 --- a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts +++ b/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts @@ -15,7 +15,6 @@ import { RPTUtil } from "../../v2/checker/accessibility/util/legacy"; import { Rule, RuleResult, RuleContext, RulePass, RuleContextHierarchy, RulePotential } from "../api/IRule"; import { eRulePolicy, eToolkitLevel } from "../api/IRule"; import { VisUtil } from "../../v2/dom/VisUtil"; -import { DOMMapper } from "../../v2/dom/DOMMapper"; export let element_draggable_alternative: Rule = { id: "element_draggable_alternative", @@ -44,7 +43,7 @@ export let element_draggable_alternative: Rule = { act: [], run: (context: RuleContext, options?: {}, contextHierarchies?: RuleContextHierarchy): RuleResult | RuleResult[] => { const ruleContext = context["dom"].node as HTMLElement; - if (!VisUtil.isNodeVisible(ruleContext) || !RPTUtil.isTabbable(ruleContext)) + if (!VisUtil.isNodeVisible(ruleContext)) return null; const nodeName = ruleContext.nodeName.toLocaleLowerCase(); @@ -57,67 +56,16 @@ export let element_draggable_alternative: Rule = { const bounds = context["dom"].bounds; //in case the bounds not available - if (!bounds) return null; - - //ignore if offscreen - if (bounds['height'] === 0 || bounds['width'] === 0 ) - return null; + if (ruleContext.getAttribute("draggable") === 'true') + if (ruleContext.hasAttribute("ondragstart")) + return RulePotential("potential_alternative", [nodeName]); + else + return RulePotential("potential_draggable", [nodeName]); - const doc = ruleContext.ownerDocument; - if (!doc) { - return null; - } - const win = doc.defaultView; - if (!win) { - return null; - } - - const cStyle = win.getComputedStyle(ruleContext); - if (cStyle === null) + else if (ruleContext.getAttribute("draggable") === 'false') + return RulePass("pass_undraggable", [nodeName]); + + else return null; - - let zindex = cStyle.zIndex; - if (!zindex || zindex === 'auto') - zindex = "0"; - - const elems = doc.querySelectorAll('body *:not(script)'); - if (!elems || elems.length == 0) - return; - - const mapper : DOMMapper = new DOMMapper(); - let violations = []; - let before = true; - elems.forEach(elem => { - /** - * the nodes returned from querySelectorAll is in document order - * if two elements overlap and z-index are not defined, then the node rendered earlier will be overlaid by the node rendered later - */ - if (ruleContext.contains(elem)) { - //the next node in elems will be after the target node (ruleContext). - before = false; - } else if (VisUtil.isNodeVisible(elem) && !elem.contains(ruleContext)) { - const bnds = mapper.getBounds(elem); - const zStyle = win.getComputedStyle(elem); - let z_index = '0'; - if (zStyle) { - z_index = zStyle.zIndex; - if (!z_index || isNaN(Number(z_index))) - z_index = "0"; - } - if (bnds.height !== 0 && bnds.width !== 0 - && 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))) - { - violations.push(elem); - } - } - }); - - if (violations.length > 0) { - return RulePotential("potential_obscured", []); - } - - return RulePass("pass"); } } From c4cfab95ad5903db8218f664d44f030c4736246c Mon Sep 17 00:00:00 2001 From: Shunguo Date: Fri, 3 Nov 2023 12:02:09 -0500 Subject: [PATCH 04/11] change rule id #1675 --- ...html => draggable_alternative_exists.html} | 0 ...ive.ts => draggable_alternative_exists.ts} | 10 +- .../element_draggable.html | 79 ++++++ .../element_overlaid_hidden_zindex.html | 101 ++++++++ .../element_overlaid_visible_default.html | 99 +++++++ .../element_overlaid_visible_zindex.html | 101 ++++++++ .../element_unobscured.html | 242 ++++++++++++++++++ 7 files changed, 627 insertions(+), 5 deletions(-) rename accessibility-checker-engine/help-v4/en-US/{element_draggable_alternative.html => draggable_alternative_exists.html} (100%) rename accessibility-checker-engine/src/v4/rules/{element_draggable_alternative.ts => draggable_alternative_exists.ts} (91%) create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html diff --git a/accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html b/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html similarity index 100% rename from accessibility-checker-engine/help-v4/en-US/element_draggable_alternative.html rename to accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html diff --git a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts similarity index 91% rename from accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts rename to accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts index 96200dbe6..7565db2e7 100644 --- a/accessibility-checker-engine/src/v4/rules/element_draggable_alternative.ts +++ b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts @@ -16,15 +16,15 @@ import { Rule, RuleResult, RuleContext, RulePass, RuleContextHierarchy, RulePote import { eRulePolicy, eToolkitLevel } from "../api/IRule"; import { VisUtil } from "../../v2/dom/VisUtil"; -export let element_draggable_alternative: Rule = { - id: "element_draggable_alternative", +export let draggable_alternative_exists: Rule = { + id: "draggable_alternative_exists", context: "dom:*[draggable]", dependencies: [], help: { "en-US": { - "group": "element_draggable_alternative.html", - "pass": "element_draggable_alternative.html", - "potential_obscured": "element_draggable_alternative.html" + "group": "draggable_alternative_exists.html", + "pass": "draggable_alternative_exists.html", + "potential_obscured": "draggable_alternative_exists.html" } }, messages: { diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html new file mode 100755 index 000000000..c41aeee20 --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html @@ -0,0 +1,79 @@ + + + + + + + + RPT Test Suite + + + + + +

This text may be dragged.

+ + + + + diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html new file mode 100755 index 000000000..ac5812e05 --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html @@ -0,0 +1,101 @@ + + + + + + + + RPT Test Suite + + + + + +
1
+
2
+ + + + + diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html new file mode 100755 index 000000000..4bec86731 --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html @@ -0,0 +1,99 @@ + + + + + + + + RPT Test Suite + + + + + +
1
+
2
+ + + + + diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html new file mode 100755 index 000000000..f8dce5098 --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html @@ -0,0 +1,101 @@ + + + + + + + + RPT Test Suite + + + + + +
1
+
2
+ + + + + diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html new file mode 100755 index 000000000..4e626f5ae --- /dev/null +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html @@ -0,0 +1,242 @@ + + + + + + Using CSS margin and scroll-margin to un-obscure content + + + +
+

Fixed-Position Banner

+ +
+ +
+
+

Main Content

+
+

+ +

+ +

+ +

+ +

+ +

+

+ +

+ +
+ + +
+ + + + + From 92bcaffebac58bd3ef3de63076f6d891217f7962 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Fri, 3 Nov 2023 14:23:15 -0500 Subject: [PATCH 05/11] add test cases #1675 --- .../v4/rules/draggable_alternative_exists.ts | 14 +-- .../src/v4/rules/index.ts | 1 + .../element_draggable.html | 42 ++++--- .../element_dropstop.html | 105 ++++++++++++++++++ .../element_overlaid_hidden_zindex.html | 101 ----------------- 5 files changed, 138 insertions(+), 125 deletions(-) create mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_dropstop.html delete mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html diff --git a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts index 7565db2e7..a91ee918e 100644 --- a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts +++ b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts @@ -29,9 +29,10 @@ export let draggable_alternative_exists: Rule = { }, messages: { "en-US": { - "group": "When an element receives focus, it is not entirely covered by other content", - "pass": "The element is not entirely covered by other content", - "potential_obscured": "Confirm that when the element receives focus, it is not covered or, if covered by user action, can be uncovered without moving focus" + "group": "A draggable element must have a \"single pointer\" alternative", + "pass_alternative": "The draggable element \"{0}\" has a \"single pointer\" alternative", + "pass_undraggable": "The element \"{0}\" is not draggable", + "potential_alternative": "Ensure the draggable element \"{0}\" has a \"single pointer\" alternative" } }, rulesets: [{ @@ -57,14 +58,9 @@ export let draggable_alternative_exists: Rule = { //in case the bounds not available if (ruleContext.getAttribute("draggable") === 'true') - if (ruleContext.hasAttribute("ondragstart")) - return RulePotential("potential_alternative", [nodeName]); - else - return RulePotential("potential_draggable", [nodeName]); - + return RulePotential("potential_alternative", [nodeName]); else if (ruleContext.getAttribute("draggable") === 'false') return RulePass("pass_undraggable", [nodeName]); - else return null; } diff --git a/accessibility-checker-engine/src/v4/rules/index.ts b/accessibility-checker-engine/src/v4/rules/index.ts index f9430b5e7..2bb42749f 100644 --- a/accessibility-checker-engine/src/v4/rules/index.ts +++ b/accessibility-checker-engine/src/v4/rules/index.ts @@ -80,6 +80,7 @@ export * from "./debug_paths" export * from "./detector_tabbable" export * from "./dir_attribute_valid" export * from "./download_keyboard_controllable" +export * from "./draggable_alternative_exists" export * from "./element_accesskey_labelled" export * from "./element_accesskey_unique" export * from "./element_attribute_deprecated" diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html index c41aeee20..d1651bc4c 100755 --- a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html +++ b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_draggable.html @@ -33,41 +33,53 @@ -

This text may be dragged.

+

no draggable defined: This text may be dragged by selection.

+ +

draggable false: This text may be selected and dragged.

+ +

draggable undefined:This text may be selected and dragged.

+ +

draggable true: This text may be dragged.

+ + + + + + +

Drag or move the image into the rectangle:

+ +
+
+ +
+
+ + + + + diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html deleted file mode 100755 index ac5812e05..000000000 --- a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_hidden_zindex.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - RPT Test Suite - - - - - -
1
-
2
- - - - - From 17499890a50297b2607fa5df4277563f5437c6ac Mon Sep 17 00:00:00 2001 From: Phill Jenkins Date: Mon, 6 Nov 2023 10:26:03 -0600 Subject: [PATCH 06/11] Update Help Initial commit for Help content --- .../en-US/draggable_alternative_exists.html | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html b/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html index fa9d44e73..98f688510 100644 --- a/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html +++ b/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html @@ -45,22 +45,26 @@

### Why is this important? -When users cannot see the item with focus because it is covered (hidden) by another element, they may not know how to proceed, or may even think the system has become unresponsive. -The objective is to ensure that the element receiving focus is always partially visible to the user unless it is covered by the user’s action. -Knowing the current element with focus is critical for sighted people who rely on a keyboard (or technology that operates through the keyboard interface, such as a switch or voice input). -The element with focus signals the interaction point on the page. +Some people cannot use a mouse, pen, or touch to drag items. The design should not rely on dragging as the only means for the user’s actions. -However, content opened or controlled by the _user’s action_ may obscure the element receiving focus. -If the _user_ can uncover (re-reveal) the focused element without advancing the keyboard focus, such as by scrolling or closing the content that the _user_ opened, then the focused element is not considered obscured (covered) due to author-created content. -Where content can be repositioned by the _user’s action_, then only the initial positions of user-movable content are considered for testing and conformance. +- **_Draggable_**: an operation where the pointer (mouse, pen, or touch) engages with an element on the [down-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-down-event) and the element (or a representation of its position) follows the pointer until an [up-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-up-event). Examples of draggable elements include list items, text, and images. +- **_Single-pointer_**: pointer input with _one point of contact with the screen_, including single taps and clicks, double-taps and double-clicks, long presses, and non _path-based gestures_. +- **_Path-based gesture_**: involves a pointer interaction where not just the endpoints matter. +- Exceptions and additional terms are defined at [Understanding Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#key-terms) + +**Note**: This requirement is separate from keyboard accessibility. +However, providing a text input can be an acceptable _single-pointer_ alternative to dragging. +For example, a text input beside a slider could allow any user to enter a precise value for the slider. +In such a situation, the on-screen keyboard for touch users offers a _single-pointer_ means of entering an alphanumeric value.
### What to do -- Confirm that the element that had been originally covered by the _author_, but that now has focus, is now visible, otherwise adjust the design to allow elements with focus to be visible -- **Or**, if the element was originally visible, but is now covered due to the _user’s action_, confirm that the _user_ can uncover (re-reveal) the element with focus without moving the focus away from the element such as by scrolling or escaping to close the content that is covering the element with focus +For any action that involves dragging with a mouse, pen, or touch: +- Provide a _single-pointer_ alternative, such as including single taps and clicks, double-taps and double-clicks, and long presses as alternatives to the dragging +- **Or**, provide a text input alternative @@ -73,19 +77,15 @@

### About this requirement -- [WCAG 2.4.11 Focus Not Obscured (Minimum)](https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum) -- [WCAG technique C43: Using CSS margin and scroll-margin to un-obscure content](https://www.w3.org/WAI/WCAG22/Techniques/css/C43) -- [Common failure F110: Obscured due to a sticky footer or header completely hiding focused elements](https://www.w3.org/WAI/WCAG22/Techniques/failures/F110) +- [WCAG 2.5.7 Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html) +- [WCAG technique G219: Ensuring that an alternative is available for dragging movements that operate on content](https://www.w3.org/WAI/WCAG22/Techniques/general/G219) +- [WCAG Failure F108: Failure due to not providing a _single-pointer_ method for the user to operate a function that uses a dragging movement](https://www.w3.org/WAI/WCAG22/Techniques/failures/F108) ### Who does this affect? -- People with low vision who use screen magnification -- People who physically cannot use a pointing device -- People using a keyboard and alternate keyboards or input devices that act as keyboard emulators like speech input software and on-screen keyboards -- People with dexterity impairment using a keyboard-like switch device -- People with dexterity impairment using voice control -- People with tremors or other movement disorders using a keyboard-like device -- People with memory limitations in executive processes benefit by being able to discover where the focus is located +- People who struggle with performing dragging movements +- People with tremors or other movement disorders using a mouse, stylus, or touch input +- People using a device in environments where they are exposed to shaking such as public transportation - Many older adults From 281ed9d8b28af8d7dbb17849402166f7a1e9dd36 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Tue, 7 Nov 2023 13:35:45 -0600 Subject: [PATCH 07/11] remove wrong test cases #1675 --- .../element_overlaid_visible_default.html | 99 ------- .../element_overlaid_visible_zindex.html | 101 -------- .../element_unobscured.html | 242 ------------------ 3 files changed, 442 deletions(-) delete mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html delete mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html delete mode 100755 accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html deleted file mode 100755 index 4bec86731..000000000 --- a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_default.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - RPT Test Suite - - - - - -
1
-
2
- - - - - diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html deleted file mode 100755 index f8dce5098..000000000 --- a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_overlaid_visible_zindex.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - RPT Test Suite - - - - - -
1
-
2
- - - - - diff --git a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html b/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html deleted file mode 100755 index 4e626f5ae..000000000 --- a/accessibility-checker-engine/test/v2/checker/accessibility/rules/draggable_alternative_exists_ruleunit/element_unobscured.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - Using CSS margin and scroll-margin to un-obscure content - - - -
-

Fixed-Position Banner

- -
- -
-
-

Main Content

-
-

- -

- -

- -

- -

- -

-

- -

- -
- - -
- - - - - From bf07d5d279ac00e3d9de25070e8bc3f6afbf6b04 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Tue, 7 Nov 2023 13:47:45 -0600 Subject: [PATCH 08/11] update the hep references #1675 --- .../src/v4/rules/draggable_alternative_exists.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts index a91ee918e..547871a12 100644 --- a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts +++ b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts @@ -23,8 +23,9 @@ export let draggable_alternative_exists: Rule = { help: { "en-US": { "group": "draggable_alternative_exists.html", - "pass": "draggable_alternative_exists.html", - "potential_obscured": "draggable_alternative_exists.html" + "pass_alternative": "draggable_alternative_exists.html", + "pass_undraggable": "draggable_alternative_exists.html", + "potential_alternative": "draggable_alternative_exists.html" } }, messages: { From a60f9d4432f521117387f09620a62f4b30ca845a Mon Sep 17 00:00:00 2001 From: Shunguo Date: Tue, 7 Nov 2023 13:59:56 -0600 Subject: [PATCH 09/11] cleanup the code #1675 --- .../src/v4/rules/draggable_alternative_exists.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts index 547871a12..490c8d20d 100644 --- a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts +++ b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts @@ -55,8 +55,6 @@ export let draggable_alternative_exists: Rule = { || nodeName === "body" || nodeName === "html" ) return null; - const bounds = context["dom"].bounds; - //in case the bounds not available if (ruleContext.getAttribute("draggable") === 'true') return RulePotential("potential_alternative", [nodeName]); From 37432486e9f6379b505e9d4cc9756df3a69a8581 Mon Sep 17 00:00:00 2001 From: Phill Jenkins Date: Tue, 7 Nov 2023 20:28:56 -0600 Subject: [PATCH 10/11] Single pointer definition --- .../help-v4/en-US/draggable_alternative_exists.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html b/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html index 98f688510..46e09059d 100644 --- a/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html +++ b/accessibility-checker-engine/help-v4/en-US/draggable_alternative_exists.html @@ -45,12 +45,14 @@

### Why is this important? -Some people cannot use a mouse, pen, or touch to drag items. The design should not rely on dragging as the only means for the user’s actions. +Some people cannot use a mouse, pen, or touch to drag items. +Examples of draggable elements include list items, text, and images. +The design should not rely on dragging as the only means for the user’s actions. -- **_Draggable_**: an operation where the pointer (mouse, pen, or touch) engages with an element on the [down-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-down-event) and the element (or a representation of its position) follows the pointer until an [up-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-up-event). Examples of draggable elements include list items, text, and images. -- **_Single-pointer_**: pointer input with _one point of contact with the screen_, including single taps and clicks, double-taps and double-clicks, long presses, and non _path-based gestures_. +- **_Draggable_**: an operation where the pointer (mouse, pen, or touch) engages with an element on the [down-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-down-event) and the element (or a representation of its position) follows the pointer until an [up-event](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#dfn-up-event). +- **_Single-pointer_**: one or several pointer inputs that operate with _one point of contact with the screen_, including single taps and clicks, double-taps and double-clicks, and long presses. - **_Path-based gesture_**: involves a pointer interaction where not just the endpoints matter. -- Exceptions and additional terms are defined at [Understanding Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#key-terms) +- **_Exceptions and additional terms_**: are defined at [Understanding Dragging Movements](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html#key-terms). **Note**: This requirement is separate from keyboard accessibility. However, providing a text input can be an acceptable _single-pointer_ alternative to dragging. From a3e9e36a3c106e46d6a414e1c01edf1867a0c7d4 Mon Sep 17 00:00:00 2001 From: Shunguo Date: Wed, 8 Nov 2023 10:31:44 -0600 Subject: [PATCH 11/11] cleanup the code #1675 --- .../src/v4/rules/draggable_alternative_exists.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts index 490c8d20d..b209b5bf8 100644 --- a/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts +++ b/accessibility-checker-engine/src/v4/rules/draggable_alternative_exists.ts @@ -55,7 +55,6 @@ export let draggable_alternative_exists: Rule = { || nodeName === "body" || nodeName === "html" ) return null; - //in case the bounds not available if (ruleContext.getAttribute("draggable") === 'true') return RulePotential("potential_alternative", [nodeName]); else if (ruleContext.getAttribute("draggable") === 'false')