Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Integrate ARIA element reflection in the Accessibility Tree
https://bugs.webkit.org/show_bug.cgi?id=244972 Reviewed by Ryosuke Niwa. * LayoutTests/accessibility/element-reflection-ariaactivedescendant-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariaactivedescendant.html: Added. * LayoutTests/accessibility/element-reflection-ariacontrols-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariacontrols.html: Added. * LayoutTests/accessibility/element-reflection-ariadescribedby-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariadescribedby.html: Added. * LayoutTests/accessibility/element-reflection-ariadetails-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariadetails.html: Added. * LayoutTests/accessibility/element-reflection-ariaerrormessage-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariaerrormessage.html: Added. * LayoutTests/accessibility/element-reflection-ariaflowto-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariaflowto.html: Added. * LayoutTests/accessibility/element-reflection-arialabelledby-expected.txt: Added. * LayoutTests/accessibility/element-reflection-arialabelledby.html: Added. * LayoutTests/accessibility/element-reflection-ariaowns-expected.txt: Added. * LayoutTests/accessibility/element-reflection-ariaowns.html: Added. * LayoutTests/platform/mac-wk1/TestExpectations: Skip tests due to missing methods on WK1. * LayoutTests/platform/win/TestExpectations: Skip new tests on Windows. * Source/WebCore/accessibility/AXObjectCache.cpp: (WebCore::AXObjectCache::updateRelationsIfNeeded): Take into account element reflection information. * Source/WebCore/accessibility/AccessibilityObject.cpp: (WebCore:: const): Ditto. * Source/WebCore/dom/Element.cpp: (WebCore::Element::isElementReflectionAttribute): Expose method so it can be used from the a11y code. (WebCore::Element::isElementsArrayReflectionAttribute): Ditto. (WebCore::isElementReflectionAttribute): Deleted. (WebCore::isElementsArrayReflectionAttribute): Deleted. * Source/WebCore/dom/Element.h: Canonical link: https://commits.webkit.org/254985@main
- Loading branch information
Showing
22 changed files
with
838 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Checks that element reflection is exposed to the a11y tree for 'ariaActiveDescendantElement' | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS axTarget1.selectedChildrenCount is 1 | ||
PASS axTarget1.selectedChildAtIndex(0).isEqual(axDescendant1) is true | ||
PASS axTarget2.selectedChildrenCount is 1 | ||
PASS axTarget2.selectedChildAtIndex(0).isEqual(axDescendantFirstChild) is true | ||
PASS axTarget2.selectedChildrenCount is 1 | ||
PASS axTarget2.selectedChildAtIndex(0).isEqual(axDescendant2) is true | ||
PASS axTarget3.selectedChildrenCount is 1 | ||
PASS axTarget3.selectedChildAtIndex(0).isEqual(axDescendant3) is true | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<!DOCTYPE html> | ||
<script src="../resources/js-test.js"></script> | ||
<script src="../resources/accessibility-helper.js"></script> | ||
<ul id="target1" role="menubar"> | ||
<li id="descendant1"></li> | ||
</ul> | ||
<ul id="target2" role="menubar"> | ||
<li></li> | ||
<li id="descendant2"></li> | ||
</ul> | ||
<ul id="target3" role="menubar"> | ||
<li id="descendant3"></li> | ||
</ul> | ||
|
||
<script> | ||
description("Checks that element reflection is exposed to the a11y tree for 'ariaActiveDescendantElement'"); | ||
if (!window.accessibilityController) { | ||
debug("This test requires accessibilityController"); | ||
} else { | ||
target1.ariaActiveDescendantElement = descendant1; | ||
var axTarget1 = accessibilityController.accessibleElementById("target1"); | ||
var axDescendant1 = accessibilityController.accessibleElementById("descendant1"); | ||
shouldBe("axTarget1.selectedChildrenCount", "1"); | ||
shouldBeTrue("axTarget1.selectedChildAtIndex(0).isEqual(axDescendant1)"); | ||
|
||
target2.ariaActiveDescendantElement = target2.firstElementChild; | ||
var axTarget2 = accessibilityController.accessibleElementById("target2"); | ||
var axDescendant2 = accessibilityController.accessibleElementById("descendant2"); | ||
var axDescendantFirstChild = axTarget2.childAtIndex(0); | ||
shouldBe("axTarget2.selectedChildrenCount", "1"); | ||
shouldBeTrue("axTarget2.selectedChildAtIndex(0).isEqual(axDescendantFirstChild)"); | ||
target2.setAttribute("aria-activedescendant", "descendant2"); | ||
shouldBe("axTarget2.selectedChildrenCount", "1"); | ||
shouldBeTrue("axTarget2.selectedChildAtIndex(0).isEqual(axDescendant2)"); | ||
|
||
target3.ariaActiveDescendantElement = descendant3; | ||
descendant3.id = "descendant3-new"; | ||
var axTarget3 = accessibilityController.accessibleElementById("target3"); | ||
var axDescendant3 = accessibilityController.accessibleElementById("descendant3-new"); | ||
shouldBe("axTarget3.selectedChildrenCount", "1"); | ||
shouldBeTrue("axTarget3.selectedChildAtIndex(0).isEqual(axDescendant3)"); | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Checks that element reflection is exposed to the a11y tree for 'ariaControlsElements' | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS axTab1.ariaControlsElementAtIndex(0).isEqual(axPanel1) is true | ||
PASS axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel2) is true | ||
PASS axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel1) is true | ||
PASS axTab3.ariaControlsElementAtIndex(0).isEqual(axPanel3) is true | ||
PASS axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel1) is true | ||
PASS axTab2.ariaControlsElementAtIndex(1).isEqual(axPanel2) is true | ||
PASS axTab2.ariaControlsElementAtIndex(2).isEqual(axPanel3) is true | ||
PASS axTab4.ariaControlsElementAtIndex(0).isEqual(axPanel4) is true | ||
PASS axTab5.ariaControlsElementAtIndex(0).isEqual(axPanel5) is true | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
First panel | ||
Tab 1 | ||
Second panel | ||
Tab 2 | ||
Third panel | ||
Fourth panel | ||
Tab 4 | ||
Fifth panel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<!DOCTYPE html> | ||
<script src="../resources/js-test.js"></script> | ||
<script src="../resources/accessibility-helper.js"></script> | ||
<div id="panel1">First panel</div> | ||
<div id="tab1" role="tab">Tab 1</div> | ||
<div id="wrapper" tabindex="0"> | ||
<div class="panel">Second panel</div> | ||
</div> | ||
<div id="tab2" role="tab">Tab 2</div> | ||
<div id="panel3">Third panel</div> | ||
<x-tab></x-tab> | ||
<div id="panel4">Fourth panel</div> | ||
<div id="tab4" role="tab">Tab 4</div> | ||
<x-custom></x-custom> | ||
|
||
<script> | ||
class XTab extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let tab = document.createElement("div"); | ||
tab.id = "innertab"; | ||
tab.role = "tab"; | ||
tab.textContent = "Tab 3"; | ||
tab.ariaControlsElements = [panel3]; | ||
this.shadowRoot.appendChild(tab); | ||
} | ||
} | ||
customElements.define("x-tab", XTab); | ||
|
||
class XCustom extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let panel = document.createElement("div"); | ||
panel.id = "panel5"; | ||
panel.textContent = "Fifth panel"; | ||
let tab = document.createElement("div"); | ||
tab.id = "tab5"; | ||
tab.role = "tab"; | ||
tab.textContent = "Tab 5"; | ||
this.shadowRoot.appendChild(panel); | ||
this.shadowRoot.appendChild(tab); | ||
tab.ariaControlsElements = [panel]; | ||
document.body.appendChild(panel); | ||
} | ||
} | ||
customElements.define("x-custom", XCustom); | ||
|
||
description("Checks that element reflection is exposed to the a11y tree for 'ariaControlsElements'"); | ||
if (!window.accessibilityController) { | ||
debug("This test requires accessibilityController"); | ||
} else { | ||
tab1.ariaControlsElements = [panel1]; | ||
var axPanel1 = accessibilityController.accessibleElementById("panel1"); | ||
var axTab1 = accessibilityController.accessibleElementById("tab1"); | ||
shouldBeTrue("axTab1.ariaControlsElementAtIndex(0).isEqual(axPanel1)"); | ||
|
||
tab2.ariaControlsElements = [document.getElementsByClassName("panel")[0]]; | ||
var wrapper = accessibilityController.accessibleElementById("wrapper"); | ||
var axPanel2 = wrapper.childAtIndex(0); | ||
var axTab2 = accessibilityController.accessibleElementById("tab2"); | ||
shouldBeTrue("axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel2)"); | ||
tab2.setAttribute("aria-controls", "panel1"); | ||
shouldBeTrue("axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel1)"); | ||
|
||
var axPanel3 = accessibilityController.accessibleElementById("panel3"); | ||
var axTab3 = accessibilityController.accessibleElementById("innertab"); | ||
shouldBeTrue("axTab3.ariaControlsElementAtIndex(0).isEqual(axPanel3)"); | ||
|
||
tab2.ariaControlsElements = [panel1, document.getElementsByClassName("panel")[0], panel3]; | ||
shouldBeTrue("axTab2.ariaControlsElementAtIndex(0).isEqual(axPanel1)"); | ||
shouldBeTrue("axTab2.ariaControlsElementAtIndex(1).isEqual(axPanel2)"); | ||
shouldBeTrue("axTab2.ariaControlsElementAtIndex(2).isEqual(axPanel3)"); | ||
|
||
tab4.ariaControlsElements = [panel4]; | ||
panel4.id = "panel4-new"; | ||
var axPanel4 = accessibilityController.accessibleElementById("panel4-new"); | ||
var axTab4 = accessibilityController.accessibleElementById("tab4"); | ||
shouldBeTrue("axTab4.ariaControlsElementAtIndex(0).isEqual(axPanel4)"); | ||
|
||
var axPanel5 = accessibilityController.accessibleElementById("panel5"); | ||
var axTab5 = accessibilityController.accessibleElementById("tab5"); | ||
shouldBeTrue("axTab5.ariaControlsElementAtIndex(0).isEqual(axPanel5)"); | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Checks that element reflection is exposed to the a11y tree for 'ariaDescribedByElements' | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS axTarget1.helpText is "AXHelp: First description" | ||
PASS axTarget2.helpText is "AXHelp: Second description" | ||
PASS axTarget2.helpText is "AXHelp: First description" | ||
PASS axInnerTarget.helpText is "AXHelp: Third description" | ||
PASS axTarget2.helpText is "AXHelp: First description Second description Third description" | ||
PASS axTarget4.helpText is "AXHelp: Fourth description" | ||
PASS axTarget5.helpText is "AXHelp: Fifth description" | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
First description | ||
Target 1 | ||
Second description | ||
Target 2 | ||
Third description | ||
Fourth description | ||
Target 4 | ||
Fifth description |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<!DOCTYPE html> | ||
<script src="../resources/js-test.js"></script> | ||
<script src="../resources/accessibility-helper.js"></script> | ||
|
||
<div id="desc1">First description</div> | ||
<div id="target1">Target 1</div> | ||
<div class="desc">Second description</div> | ||
<div id="target2">Target 2</div> | ||
<div id="desc3">Third description</div> | ||
<x-target></x-target> | ||
<div id="desc4">Fourth description</div> | ||
<div id="target4">Target 4</div> | ||
<x-custom></x-custom> | ||
|
||
<script> | ||
class XTarget extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let target = document.createElement("div"); | ||
target.id = "innertarget"; | ||
target.textContent = "Target 3"; | ||
target.ariaDescribedByElements = [desc3]; | ||
this.shadowRoot.appendChild(target); | ||
} | ||
} | ||
customElements.define("x-target", XTarget); | ||
|
||
class XCustom extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let desc = document.createElement("div"); | ||
desc.id = "desc5"; | ||
desc.textContent = "Fifth description"; | ||
let target = document.createElement("div"); | ||
target.id = "target5"; | ||
target.textContent = "Target 5"; | ||
this.shadowRoot.appendChild(desc); | ||
this.shadowRoot.appendChild(target); | ||
target.ariaDescribedByElements = [desc]; | ||
document.body.appendChild(desc); | ||
} | ||
} | ||
customElements.define("x-custom", XCustom); | ||
|
||
description("Checks that element reflection is exposed to the a11y tree for 'ariaDescribedByElements'"); | ||
if (!window.accessibilityController) { | ||
debug("This test requires accessibilityController"); | ||
} else { | ||
target1.ariaDescribedByElements = [desc1]; | ||
var axTarget1 = accessibilityController.accessibleElementById("target1"); | ||
shouldBeEqualToString("axTarget1.helpText", "AXHelp: First description"); | ||
|
||
target2.ariaDescribedByElements = [document.getElementsByClassName("desc")[0]]; | ||
var axTarget2 = accessibilityController.accessibleElementById("target2"); | ||
shouldBeEqualToString("axTarget2.helpText", "AXHelp: Second description"); | ||
target2.setAttribute("aria-describedby", "desc1"); | ||
shouldBeEqualToString("axTarget2.helpText", "AXHelp: First description"); | ||
|
||
var axInnerTarget = accessibilityController.accessibleElementById("innertarget"); | ||
shouldBeEqualToString("axInnerTarget.helpText", "AXHelp: Third description"); | ||
|
||
target2.ariaDescribedByElements = [desc1, document.getElementsByClassName("desc")[0], desc3]; | ||
shouldBeEqualToString("axTarget2.helpText", "AXHelp: First description Second description Third description"); | ||
|
||
target4.ariaDescribedByElements = [desc4]; | ||
desc4.id = "desc4-new"; | ||
var axTarget4 = accessibilityController.accessibleElementById("target4"); | ||
shouldBeEqualToString("axTarget4.helpText", "AXHelp: Fourth description"); | ||
|
||
var axTarget5 = accessibilityController.accessibleElementById("target5"); | ||
shouldBeEqualToString("axTarget5.helpText", "AXHelp: Fifth description"); | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Checks that element reflection is exposed to the a11y tree for 'ariaDetailsElements' | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS axTarget1.ariaDetailsElementAtIndex(0).isEqual(axDetail1) is true | ||
PASS axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail2) is true | ||
PASS axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail1) is true | ||
PASS axInnerTarget.ariaDetailsElementAtIndex(0).isEqual(axDetail3) is true | ||
PASS axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail1) is true | ||
PASS axTarget2.ariaDetailsElementAtIndex(1).isEqual(axDetail2) is true | ||
PASS axTarget2.ariaDetailsElementAtIndex(2).isEqual(axDetail3) is true | ||
PASS axTarget4.ariaDetailsElementAtIndex(0).isEqual(axDetail4) is true | ||
PASS axTarget5.ariaDetailsElementAtIndex(0).isEqual(axDetail5) is true | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
First detail | ||
Target 1 | ||
Second detail | ||
Target 2 | ||
Third detail | ||
Fourth detail | ||
Target 4 | ||
Fifth detail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<!DOCTYPE html> | ||
<script src="../resources/js-test.js"></script> | ||
<script src="../resources/accessibility-helper.js"></script> | ||
<div id="detail1">First detail</div> | ||
<div id="target1">Target 1</div> | ||
<div id="wrapper" tabindex="0"> | ||
<div class="detail">Second detail</div> | ||
</div> | ||
<div id="target2">Target 2</div> | ||
<div id="detail3">Third detail</div> | ||
<x-target></x-target> | ||
<div id="detail4">Fourth detail</div> | ||
<div id="target4">Target 4</div> | ||
<x-custom></x-custom> | ||
|
||
<script> | ||
class XTarget extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let target = document.createElement("div"); | ||
target.id = "innertarget"; | ||
target.textContent = "Target 3"; | ||
target.ariaDetailsElements = [detail3]; | ||
this.shadowRoot.appendChild(target); | ||
} | ||
} | ||
customElements.define("x-target", XTarget); | ||
|
||
class XCustom extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: "open" }); | ||
let detail = document.createElement("div"); | ||
detail.id = "detail5"; | ||
detail.textContent = "Fifth detail"; | ||
let target = document.createElement("div"); | ||
target.id = "target5"; | ||
target.textContent = "Target 5"; | ||
this.shadowRoot.appendChild(detail); | ||
this.shadowRoot.appendChild(target); | ||
target.ariaDetailsElements = [detail]; | ||
document.body.appendChild(detail); | ||
} | ||
} | ||
customElements.define("x-custom", XCustom); | ||
|
||
description("Checks that element reflection is exposed to the a11y tree for 'ariaDetailsElements'"); | ||
if (!window.accessibilityController) { | ||
debug("This test requires accessibilityController"); | ||
} else { | ||
target1.ariaDetailsElements = [detail1]; | ||
var axDetail1 = accessibilityController.accessibleElementById("detail1"); | ||
var axTarget1 = accessibilityController.accessibleElementById("target1"); | ||
shouldBeTrue("axTarget1.ariaDetailsElementAtIndex(0).isEqual(axDetail1)"); | ||
|
||
target2.ariaDetailsElements = [document.getElementsByClassName("detail")[0]]; | ||
var wrapper = accessibilityController.accessibleElementById("wrapper"); | ||
var axDetail2 = wrapper.childAtIndex(0); | ||
var axTarget2 = accessibilityController.accessibleElementById("target2"); | ||
shouldBeTrue("axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail2)"); | ||
target2.setAttribute("aria-details", "detail1"); | ||
shouldBeTrue("axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail1)"); | ||
|
||
var axDetail3 = accessibilityController.accessibleElementById("detail3"); | ||
var axInnerTarget = accessibilityController.accessibleElementById("innertarget"); | ||
shouldBeTrue("axInnerTarget.ariaDetailsElementAtIndex(0).isEqual(axDetail3)"); | ||
|
||
target2.ariaDetailsElements = [detail1, document.getElementsByClassName("detail")[0], detail3]; | ||
shouldBeTrue("axTarget2.ariaDetailsElementAtIndex(0).isEqual(axDetail1)"); | ||
shouldBeTrue("axTarget2.ariaDetailsElementAtIndex(1).isEqual(axDetail2)"); | ||
shouldBeTrue("axTarget2.ariaDetailsElementAtIndex(2).isEqual(axDetail3)"); | ||
|
||
target4.ariaDetailsElements = [detail4]; | ||
detail4.id = "detail4-new"; | ||
var axDetail4 = accessibilityController.accessibleElementById("detail4-new"); | ||
var axTarget4 = accessibilityController.accessibleElementById("target4"); | ||
shouldBeTrue("axTarget4.ariaDetailsElementAtIndex(0).isEqual(axDetail4)"); | ||
|
||
var axDetail5 = accessibilityController.accessibleElementById("detail5"); | ||
var axTarget5 = accessibilityController.accessibleElementById("target5"); | ||
shouldBeTrue("axTarget5.ariaDetailsElementAtIndex(0).isEqual(axDetail5)"); | ||
} | ||
</script> |
Oops, something went wrong.