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
Implement ARIA id-ref reflection for ElementInternals
https://bugs.webkit.org/show_bug.cgi?id=245328 Reviewed by Manuel Rego Casasnovas. This patch adds the support for id-ref ARIA attributes to ElementInternals. * LayoutTests/accessibility/custom-elements/controls-expected.txt: Added. * LayoutTests/accessibility/custom-elements/controls.html: Added. * LayoutTests/accessibility/custom-elements/describedby-expected.txt: Added. * LayoutTests/accessibility/custom-elements/describedby.html: Added. * LayoutTests/accessibility/custom-elements/flowto-expected.txt: Added. * LayoutTests/accessibility/custom-elements/flowto.html: Added. * LayoutTests/accessibility/custom-elements/menuitem-expected.txt: * LayoutTests/accessibility/custom-elements/menuitem.html: * LayoutTests/imported/w3c/web-platform-tests/custom-elements/form-associated/ElementInternals-accessibility-expected.txt: * LayoutTests/platform/gtk/accessibility/custom-elements/describedby-expected.txt: Added. * LayoutTests/platform/mac-wk1/TestExpectations: * Source/WebCore/Sources.txt: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/accessibility/AXObjectCache.cpp: (WebCore::AXObjectCache::isModalElement const): (WebCore::nodeHasRole): (WebCore::AXObjectCache::updateRelationsIfNeeded): Add the support for defining relations via ElementInternals. * Source/WebCore/accessibility/AccessibilityObject.cpp: (WebCore::AccessibilityObject::getAttribute const): (WebCore::AccessibilityObject::elementsFromAttribute const): Ditto. * Source/WebCore/bindings/js/JSElementInternalsCustom.cpp: Added. (WebCore::getElementsArrayAttribute): Added. (WebCore::JSElementInternals::ariaControlsElements const): Added. (WebCore::JSElementInternals::ariaDescribedByElements const): Added. (WebCore::JSElementInternals::ariaDetailsElements const): Added. (WebCore::JSElementInternals::ariaErrorMessageElements const): (WebCore::JSElementInternals::ariaFlowToElements const): Added. (WebCore::JSElementInternals::ariaLabelledByElements const): Added. (WebCore::JSElementInternals::ariaOwnsElements const): Added. * Source/WebCore/dom/CustomElementDefaultARIA.cpp: (WebCore::isElementVisible): Added. (WebCore::CustomElementDefaultARIA::valueForAttribute const): Added the support for converting WeakPtr<Element> and Vector<WeakPtr<Element>> to ID strings. (WebCore::CustomElementDefaultARIA::elementForAttribute const): Added. (WebCore::CustomElementDefaultARIA::setElementForAttribute): Added. (WebCore::CustomElementDefaultARIA::elementsForAttribute const): Added. (WebCore::CustomElementDefaultARIA::setElementsForAttribute): Added. * Source/WebCore/dom/CustomElementDefaultARIA.h: * Source/WebCore/dom/ElementInternals.cpp: (WebCore::computeValueForAttribute): Extracted out of setAttributeWithoutSynchronization. (WebCore::ElementInternals::setAttributeWithoutSynchronization): (WebCore::ElementInternals::attributeWithoutSynchronization const): (WebCore::ElementInternals::getElementAttribute const): Added. (WebCore::ElementInternals::setElementAttribute): Added. (WebCore::ElementInternals::getElementsArrayAttribute const): Added. (WebCore::ElementInternals::setElementsArrayAttribute): Added. * Source/WebCore/dom/ElementInternals.h: * Source/WebCore/dom/ElementInternals.idl: Canonical link: https://commits.webkit.org/254709@main
- Loading branch information
Showing
21 changed files
with
567 additions
and
37 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,16 @@ | ||
This tests that aria fallback roles work correctly. | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS labelForControl(accessibilityController.accessibleElementById("custom-tab-1").ariaControlsElementAtIndex(0)) is "AXValue: Panel 1" | ||
PASS labelForControl(accessibilityController.accessibleElementById("custom-tab-1").ariaControlsElementAtIndex(1)) is "AXValue: Panel 2" | ||
PASS labelForControl(accessibilityController.accessibleElementById("custom-tab-2").ariaControlsElementAtIndex(0)) is "AXValue: Panel 3" | ||
PASS accessibilityController.accessibleElementById("custom-tab-2").ariaControlsElementAtIndex(1) is null | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
Panel 1 | ||
Panel 2 | ||
Panel 3 | ||
Panel 4 |
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,41 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<body> | ||
<script src="../../resources/js-test.js"></script> | ||
<script src="../../resources/accessibility-helper.js"></script> | ||
<custom-tab id="custom-tab-1"></custom-tab> | ||
<div class="control">Panel 1</div> | ||
<div class="control">Panel 2</div> | ||
<custom-tab id="custom-tab-2" aria-controls="panel3"></custom-tab> | ||
<div id="panel3" class="control">Panel 3</div> | ||
<div id="panel4" class="control">Panel 4</div> | ||
<script> | ||
|
||
customElements.define('custom-tab', class CustomElement extends HTMLElement { | ||
constructor() | ||
{ | ||
super(); | ||
const internals = this.attachInternals(); | ||
internals.role = 'tab'; | ||
internals.ariaControlsElements = Array.from(document.querySelectorAll('.control')); | ||
} | ||
}); | ||
|
||
description("This tests that aria fallback roles work correctly."); | ||
if (!window.accessibilityController) | ||
debug('This test requires accessibilityController'); | ||
else { | ||
function labelForControl(control) { | ||
if (accessibilityController.platformName == "mac") | ||
return control.childAtIndex(0).stringValue; | ||
return control.stringValue; | ||
} | ||
shouldBeEqualToString('labelForControl(accessibilityController.accessibleElementById("custom-tab-1").ariaControlsElementAtIndex(0))', 'AXValue: Panel 1'); | ||
shouldBeEqualToString('labelForControl(accessibilityController.accessibleElementById("custom-tab-1").ariaControlsElementAtIndex(1))', 'AXValue: Panel 2'); | ||
shouldBeEqualToString('labelForControl(accessibilityController.accessibleElementById("custom-tab-2").ariaControlsElementAtIndex(0))', 'AXValue: Panel 3'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-tab-2").ariaControlsElementAtIndex(1)', 'null'); | ||
} | ||
|
||
</script> | ||
</body> | ||
</html> |
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,28 @@ | ||
This tests that aria fallback roles work correctly. | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS accessibilityController.accessibleElementById("custom-1").role is "AXRole: AXCheckBox" | ||
PASS accessibilityController.accessibleElementById("custom-1").helpText is "AXHelp: some description other description" | ||
PASS accessibilityController.accessibleElementById("custom-1").detailsElements().length is 2 | ||
PASS accessibilityController.accessibleElementById("custom-1").detailsElements()[0].domIdentifier is "details1" | ||
PASS accessibilityController.accessibleElementById("custom-1").detailsElements()[1].domIdentifier is "details2" | ||
PASS accessibilityController.accessibleElementById("custom-1").errorMessageElements().length is 2 | ||
PASS accessibilityController.accessibleElementById("custom-1").errorMessageElements()[0].domIdentifier is "error1" | ||
PASS accessibilityController.accessibleElementById("custom-1").errorMessageElements()[1].domIdentifier is "error2" | ||
PASS accessibilityController.accessibleElementById("custom-2").role is "AXRole: AXCheckBox" | ||
PASS accessibilityController.accessibleElementById("custom-2").helpText is "AXHelp: some description" | ||
PASS accessibilityController.accessibleElementById("custom-2").detailsElements().length is 1 | ||
PASS accessibilityController.accessibleElementById("custom-2").detailsElements()[0].domIdentifier is "details2" | ||
PASS accessibilityController.accessibleElementById("custom-2").errorMessageElements().length is 1 | ||
PASS accessibilityController.accessibleElementById("custom-2").errorMessageElements()[0].domIdentifier is "error2" | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
some description | ||
other description | ||
some details | ||
other details | ||
some error | ||
other error |
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,50 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<body id="body"> | ||
<script src="../../resources/js-test.js"></script> | ||
<script src="../../resources/accessibility-helper.js"></script> | ||
<custom-element id="custom-1"></custom-element> | ||
<custom-element id="custom-2" aria-describedby="some" aria-details="details2" aria-errormessage="error2"></custom-element> | ||
<div id="some" class="note">some description</div> | ||
<div class="note">other description</div> | ||
<div id="details1" class="details">some details</div> | ||
<div id="details2" class="details">other details</div> | ||
<div id="error1" class="error">some error</div> | ||
<div id="error2" class="error">other error</div> | ||
<script> | ||
|
||
customElements.define('custom-element', class CustomElement extends HTMLElement { | ||
constructor() | ||
{ | ||
super(); | ||
const internals = this.attachInternals(); | ||
internals.role = 'checkbox'; | ||
internals.ariaDescribedByElements = Array.from(document.querySelectorAll('.note')); | ||
internals.ariaDetailsElements = Array.from(document.querySelectorAll('.details')); | ||
internals.ariaErrorMessageElements = Array.from(document.querySelectorAll('.error')); | ||
} | ||
}); | ||
|
||
description("This tests that aria fallback roles work correctly."); | ||
if (!window.accessibilityController) | ||
debug('This test requires accessibilityController'); | ||
else { | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").role', 'AXRole: AXCheckBox'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").helpText', 'AXHelp: some description other description'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-1").detailsElements().length', '2'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").detailsElements()[0].domIdentifier', 'details1'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").detailsElements()[1].domIdentifier', 'details2'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-1").errorMessageElements().length', '2'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").errorMessageElements()[0].domIdentifier', 'error1'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").errorMessageElements()[1].domIdentifier', 'error2'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").role', 'AXRole: AXCheckBox'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").helpText', 'AXHelp: some description'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-2").detailsElements().length', '1'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").detailsElements()[0].domIdentifier', 'details2'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-2").errorMessageElements().length', '1'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").errorMessageElements()[0].domIdentifier', 'error2'); | ||
} | ||
|
||
</script> | ||
</body> | ||
</html> |
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,24 @@ | ||
This tests that aria fallback roles work correctly. | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS accessibilityController.accessibleElementById("custom-1").role is "AXRole: AXCheckBox" | ||
PASS platformValueForW3CName(accessibilityController.accessibleElementById("custom-1")) is "label 1 label 2" | ||
PASS accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(0).role is "AXRole: AXButton" | ||
PASS accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(0).title is "AXTitle: FlowTo1" | ||
PASS accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(1).role is "AXRole: AXButton" | ||
PASS accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(1).title is "AXTitle: FlowTo2" | ||
PASS accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(2) is null | ||
PASS accessibilityController.accessibleElementById("custom-2").role is "AXRole: AXCheckBox" | ||
PASS platformValueForW3CName(accessibilityController.accessibleElementById("custom-2")) is "label 2" | ||
PASS accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(0).role is "AXRole: AXButton" | ||
PASS accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(0).title is "AXTitle: FlowTo2" | ||
PASS accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(1) is null | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
FlowTo1 | ||
FlowTo2 | ||
label 1 | ||
label 2 |
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,45 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<body id="body"> | ||
<script src="../../resources/js-test.js"></script> | ||
<script src="../../resources/accessibility-helper.js"></script> | ||
<custom-element id="custom-1"></custom-element> | ||
<custom-element id="custom-2" aria-flowto="flowto2" aria-labelledby="label2"></custom-element> | ||
<div role="button" class="flowto">FlowTo1</div> | ||
<div id="flowto2" role="button" class="flowto">FlowTo2</div> | ||
<div class="label">label 1</div> | ||
<div id="label2" class="label">label 2</div> | ||
<script> | ||
|
||
customElements.define('custom-element', class CustomElement extends HTMLElement { | ||
constructor() | ||
{ | ||
super(); | ||
const internals = this.attachInternals(); | ||
internals.role = 'checkbox'; | ||
internals.ariaFlowToElements = Array.from(document.querySelectorAll('.flowto')); | ||
internals.ariaLabelledByElements = Array.from(document.querySelectorAll('.label')); | ||
} | ||
}); | ||
|
||
description("This tests that aria fallback roles work correctly."); | ||
if (!window.accessibilityController) | ||
debug('This test requires accessibilityController'); | ||
else { | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").role', 'AXRole: AXCheckBox'); | ||
shouldBeEqualToString('platformValueForW3CName(accessibilityController.accessibleElementById("custom-1"))', 'label 1 label 2'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(0).role', 'AXRole: AXButton'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(0).title', 'AXTitle: FlowTo1'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(1).role', 'AXRole: AXButton'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(1).title', 'AXTitle: FlowTo2'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-1").ariaFlowToElementAtIndex(2)', 'null'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").role', 'AXRole: AXCheckBox'); | ||
shouldBeEqualToString('platformValueForW3CName(accessibilityController.accessibleElementById("custom-2"))', 'label 2'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(0).role', 'AXRole: AXButton'); | ||
shouldBeEqualToString('accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(0).title', 'AXTitle: FlowTo2'); | ||
shouldBe('accessibilityController.accessibleElementById("custom-2").ariaFlowToElementAtIndex(1)', 'null'); | ||
} | ||
|
||
</script> | ||
</body> | ||
</html> |
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
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
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
Oops, something went wrong.