Diff
Modified: trunk/LayoutTests/ChangeLog (224870 => 224871)
--- trunk/LayoutTests/ChangeLog 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/LayoutTests/ChangeLog 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1,3 +1,14 @@
+2017-11-14 Nan Wang <[email protected]>
+
+ AX: AOM: Implement AccessibleNode class and support label and role attributes
+ https://bugs.webkit.org/show_bug.cgi?id=179494
+
+ Reviewed by Ryosuke Niwa.
+
+ * accessibility/accessibility-object-model-expected.txt: Added.
+ * accessibility/accessibility-object-model.html: Added.
+ * js/dom/dom-static-property-for-in-iteration-expected.txt:
+
2017-11-14 Antti Koivisto <[email protected]>
Media query with :host inside a custom elements doesn't get updated on window resize
Added: trunk/LayoutTests/accessibility/accessibility-object-model-expected.txt (0 => 224871)
--- trunk/LayoutTests/accessibility/accessibility-object-model-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/accessibility-object-model-expected.txt 2017-11-15 07:56:04 UTC (rev 224871)
@@ -0,0 +1,42 @@
+Click Me
+This tests getting and setting Accessibility Object Model properties.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS button.accessibleNode == null is false
+
+Supported properties on an AccessibleNode are all null by default
+PASS button.accessibleNode.role is null
+PASS button.accessibleNode.label is null
+PASS button.accessibleNode.foo is undefined
+
+ARIA attributes should not be reflected into AOM properties.
+PASS axButton.role is 'AXRole: AXCheckBox'
+PASS axButton.description is 'AXDescription: label'
+PASS button.accessibleNode.role is null
+PASS button.accessibleNode.label is null
+
+Test setting AOM properties. And make sure AOM takes precedence.
+PASS button.accessibleNode.role is 'slider'
+PASS button.accessibleNode.label is 'AOM Label'
+PASS axButton.role is 'AXRole: AXSlider'
+PASS axButton.description is 'AXDescription: AOM Label'
+
+Setting some of the AOM properties should be able to make an element accessible.
+PASS axParagraph == null || axParagraph == undefined is true
+PASS axParagraph.isIgnored is false
+
+An invalid role should be ignored.
+PASS button.accessibleNode.role is null
+PASS axButton.role is 'AXRole: AXButton'
+PASS button.accessibleNode.role is 'badrole'
+PASS axButton.role is 'AXRole: AXButton'
+
+An AccessibleNode keeps its element alive.
+PASS aomRemovedButton.role is 'checkbox'
+PASS aomRemovedButton.role is 'checkbox'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/accessibility/accessibility-object-model.html (0 => 224871)
--- trunk/LayoutTests/accessibility/accessibility-object-model.html (rev 0)
+++ trunk/LayoutTests/accessibility/accessibility-object-model.html 2017-11-15 07:56:04 UTC (rev 224871)
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<button id="button">Click Me</button>
+<div id="container"><button id="button2">Button2</button></div>
+<p id="paragraph"></p>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+ description("This tests getting and setting Accessibility Object Model properties.");
+ if (window.accessibilityController) {
+ var button = document.getElementById("button");
+ var axButton = accessibilityController.accessibleElementById("button");
+ var aomRemovedButton;
+ var paragraph = document.getElementById("paragraph");
+ var axParagraph;
+
+ shouldBeFalse("button.accessibleNode == null");
+
+ testPropertiesDefault();
+ testNoReflection();
+ testSettingProperties();
+ testBecomeAccessible();
+ testInvalidRole();
+ testElementAlive();
+ }
+
+ function testPropertiesDefault() {
+ debug("\nSupported properties on an AccessibleNode are all null by default");
+ shouldBeNull("button.accessibleNode.role");
+ shouldBeNull("button.accessibleNode.label");
+ // Invalid property value should be undefined
+ shouldBe("button.accessibleNode.foo", "undefined");
+ }
+
+ function testNoReflection() {
+ debug("\nARIA attributes should not be reflected into AOM properties.");
+ button.setAttribute("role", "checkbox");
+ button.setAttribute("aria-label", "label");
+ shouldBe("axButton.role", "'AXRole: AXCheckBox'");
+ shouldBe("axButton.description", "'AXDescription: label'");
+
+ // AOM properties should be null even if we have set ARIA attributes.
+ shouldBeNull("button.accessibleNode.role");
+ shouldBeNull("button.accessibleNode.label");
+ }
+
+ function testSettingProperties() {
+ debug("\nTest setting AOM properties. And make sure AOM takes precedence.");
+
+ // Set the ARIA attributes on the element first.
+ button.setAttribute("role", "checkbox");
+ button.setAttribute("aria-label", "label");
+
+ // Then set the corresponding AOM properties to some different values.
+ button.accessibleNode.role = "slider";
+ shouldBe("button.accessibleNode.role", "'slider'");
+ button.accessibleNode.label = "AOM Label";
+ shouldBe("button.accessibleNode.label", "'AOM Label'");
+
+ // The AOM property values should override ARIA attributes.
+ shouldBe("axButton.role", "'AXRole: AXSlider'");
+ shouldBe("axButton.description", "'AXDescription: AOM Label'");
+ }
+
+ function testBecomeAccessible() {
+ debug("\nSetting some of the AOM properties should be able to make an element accessible.");
+ axParagraph = accessibilityController.accessibleElementById("paragraph");
+ shouldBeTrue("axParagraph == null || axParagraph == undefined");
+
+ // The element should be accessible if it has a label.
+ paragraph.accessibleNode.label = "test label";
+ axParagraph = accessibilityController.accessibleElementById("paragraph");
+ shouldBeFalse("axParagraph.isIgnored");
+ }
+
+ function testInvalidRole() {
+ debug("\nAn invalid role should be ignored.");
+
+ // Clear the ARIA attribute and AOM property value.
+ button.removeAttribute("role");
+ button.accessibleNode.role = null;
+ shouldBe("button.accessibleNode.role", "null");
+ shouldBe("axButton.role", "'AXRole: AXButton'");
+
+ // Accessibility should use the semantic role if an invalid role is provided.
+ button.accessibleNode.role = "badrole";
+ shouldBe("button.accessibleNode.role", "'badrole'");
+ shouldBe("axButton.role", "'AXRole: AXButton'");
+ }
+
+ function testElementAlive() {
+ debug("\nAn AccessibleNode keeps its element alive.");
+ // Get the button to be removed and access its accessibleNode.
+ (function() {
+ var button2 = document.getElementById("button2");
+ aomRemovedButton = button2.accessibleNode;
+ aomRemovedButton.role = "checkbox";
+ })();
+ shouldBe("aomRemovedButton.role", "'checkbox'");
+
+ // Remove the button make sure we are still able to access the accessibleNode.
+ (function() {
+ var button2 = document.getElementById("button2");
+ button2.parentElement.removeChild(button2);
+ })();
+ gc();
+ shouldBe("aomRemovedButton.role", "'checkbox'");
+ }
+
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt (224870 => 224871)
--- trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2017-11-15 07:56:04 UTC (rev 224871)
@@ -134,6 +134,7 @@
PASS a["clientHeight"] is 0
PASS a["innerHTML"] is nerget
PASS a["outerHTML"] is <a id="foo" href=""
+PASS a["accessibleNode"] is [object AccessibleNode]
PASS a["oncopy"] is null
PASS a["oncut"] is null
PASS a["onpaste"] is null
Modified: trunk/Source/WebCore/CMakeLists.txt (224870 => 224871)
--- trunk/Source/WebCore/CMakeLists.txt 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/CMakeLists.txt 2017-11-15 07:56:04 UTC (rev 224871)
@@ -419,6 +419,8 @@
Modules/webvr/VRPose.idl
Modules/webvr/VRStageParameters.idl
+ accessibility/AccessibleNode.idl
+
animation/Animatable.idl
animation/AnimationEffect.idl
animation/AnimationEffectTiming.idl
Modified: trunk/Source/WebCore/ChangeLog (224870 => 224871)
--- trunk/Source/WebCore/ChangeLog 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/ChangeLog 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1,3 +1,94 @@
+2017-11-14 Nan Wang <[email protected]>
+
+ AX: AOM: Implement AccessibleNode class and support label and role attributes
+ https://bugs.webkit.org/show_bug.cgi?id=179494
+
+ Reviewed by Ryosuke Niwa.
+
+ Accessibility Object Model
+ Explainer: https://wicg.github.io/aom/explainer.html
+ Spec: https://wicg.github.io/aom/spec/
+
+ This change adds an accessibleNode getter on Element, and implements
+ the role and label properties of AccessibleNode.
+
+ In existing accessibility code, places where we previously retrieve an
+ ARIA attribute are replaced with a new function that first checks the
+ AOM property and then checks the equivalent ARIA attribute.
+
+ Test: accessibility/accessibility-object-model.html
+
+ * CMakeLists.txt:
+ * DerivedSources.cpp:
+ * DerivedSources.make:
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::nodeHasRole):
+ (WebCore::AXObjectCache::handleLiveRegionCreated):
+ * accessibility/AccessibilityAllInOne.cpp:
+ * accessibility/AccessibilityImageMapLink.cpp:
+ (WebCore::AccessibilityImageMapLink::roleValue const):
+ (WebCore::AccessibilityImageMapLink::accessibilityDescription const):
+ * accessibility/AccessibilityListBoxOption.cpp:
+ (WebCore::AccessibilityListBoxOption::stringValue const):
+ * accessibility/AccessibilityNodeObject.cpp:
+ (WebCore::AccessibilityNodeObject::ariaAccessibilityDescription const):
+ (WebCore::siblingWithAriaRole):
+ (WebCore::AccessibilityNodeObject::textForLabelElement const):
+ (WebCore::AccessibilityNodeObject::alternativeText const):
+ (WebCore::AccessibilityNodeObject::alternativeTextForWebArea const):
+ (WebCore::AccessibilityNodeObject::stringValue const):
+ (WebCore::accessibleNameForNode):
+ (WebCore::AccessibilityNodeObject::determineAriaRoleAttribute const):
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::hasProperty const):
+ (WebCore::AccessibilityObject::stringValueForProperty const):
+ (WebCore::AccessibilityObject::supportsARIAAttributes const):
+ * accessibility/AccessibilityObject.h:
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::stringValue const):
+ (WebCore::AccessibilityRenderObject::exposesTitleUIElement const):
+ (WebCore::AccessibilityRenderObject::determineAccessibilityRole):
+ * accessibility/AccessibleNode.cpp: Added.
+ (WebCore::ariaAttributeMap):
+ (WebCore::isPropertyValueString):
+ (WebCore::AccessibleNode::hasProperty):
+ (WebCore::AccessibleNode::valueForProperty):
+ (WebCore::AccessibleNode::effectiveStringValueForElement):
+ (WebCore::AccessibleNode::stringValueForProperty):
+ (WebCore::AccessibleNode::setStringProperty):
+ (WebCore::AccessibleNode::role const):
+ (WebCore::AccessibleNode::setRole):
+ (WebCore::AccessibleNode::label const):
+ (WebCore::AccessibleNode::setLabel):
+ * accessibility/AccessibleNode.h: Added.
+ (WebCore::AXPropertyHashTraits::emptyValue):
+ (WebCore::AXPropertyHashTraits::constructDeletedValue):
+ (WebCore::AXPropertyHashTraits::isDeletedValue):
+ (WebCore::AccessibleNode::AccessibleNode):
+ (WebCore::AccessibleNode::ref):
+ (WebCore::AccessibleNode::deref):
+ * accessibility/AccessibleNode.idl: Added.
+ * bindings/js/WebCoreBuiltinNames.h:
+ * dom/Element.cpp:
+ (WebCore::Element::canContainRangeEndPoint const):
+ (WebCore::Element::accessibleNode):
+ (WebCore::Element::existingAccessibleNode const):
+ * dom/Element.h:
+ * dom/Element.idl:
+ * dom/ElementRareData.cpp:
+ * dom/ElementRareData.h:
+ (WebCore::ElementRareData::accessibleNode const):
+ (WebCore::ElementRareData::setAccessibleNode):
+ * editing/TextIterator.cpp:
+ (WebCore::isRendererReplacedElement):
+ * page/RuntimeEnabledFeatures.h:
+ (WebCore::RuntimeEnabledFeatures::setAccessibilityObjectModelEnabled):
+ (WebCore::RuntimeEnabledFeatures::accessibilityObjectModelEnabled const):
+ * rendering/RenderMenuList.cpp:
+ (RenderMenuList::itemAccessibilityText const):
+
2017-11-14 Zan Dobersek <[email protected]>
[Cairo] Add GraphicsContextImplCairo stub
Modified: trunk/Source/WebCore/DerivedSources.cpp (224870 => 224871)
--- trunk/Source/WebCore/DerivedSources.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/DerivedSources.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -36,6 +36,7 @@
#include "JSANGLEInstancedArrays.cpp"
#endif
#include "JSAbstractWorker.cpp"
+#include "JSAccessibleNode.cpp"
#include "JSAnimationEvent.cpp"
#include "JSAttr.cpp"
#include "JSBarProp.cpp"
Modified: trunk/Source/WebCore/DerivedSources.make (224870 => 224871)
--- trunk/Source/WebCore/DerivedSources.make 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/DerivedSources.make 2017-11-15 07:56:04 UTC (rev 224871)
@@ -57,6 +57,7 @@
$(WebCore)/Modules/webdriver \
$(WebCore)/Modules/websockets \
$(WebCore)/Modules/webvr \
+ $(WebCore)/accessibility \
$(WebCore)/animation \
$(WebCore)/bindings/js \
$(WebCore)/crypto \
@@ -343,6 +344,7 @@
$(WebCore)/Modules/webvr/VRLayerInit.idl \
$(WebCore)/Modules/webvr/VRPose.idl \
$(WebCore)/Modules/webvr/VRStageParameters.idl \
+ $(WebCore)/accessibility/AccessibleNode.idl \
$(WebCore)/animation/Animatable.idl \
$(WebCore)/animation/AnimationEffect.idl \
$(WebCore)/animation/AnimationEffectTiming.idl \
@@ -1395,6 +1397,7 @@
IDL_INCLUDES = \
$(WebCore)/Modules \
+ $(WebCore)/accessibility \
$(WebCore)/animation \
$(WebCore)/css \
$(WebCore)/crypto \
Modified: trunk/Source/WebCore/Sources.txt (224870 => 224871)
--- trunk/Source/WebCore/Sources.txt 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/Sources.txt 2017-11-15 07:56:04 UTC (rev 224871)
@@ -308,6 +308,7 @@
accessibility/AccessibilityTableRow.cpp
accessibility/AccessibilityTree.cpp
accessibility/AccessibilityTreeItem.cpp
+accessibility/AccessibleNode.cpp
animation/AnimationEffect.cpp
animation/AnimationEffectTiming.cpp
@@ -2258,6 +2259,7 @@
JSAbortController.cpp
JSAbortSignal.cpp
JSAbstractWorker.cpp
+JSAccessibleNode.cpp
JSAesCbcCfbParams.cpp
JSAesCtrParams.cpp
JSAesGcmParams.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (224870 => 224871)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-11-15 07:56:04 UTC (rev 224871)
@@ -11238,6 +11238,9 @@
A91C9FBD1B6586DE00AFFD54 /* AccessibilityTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTree.h; sourceTree = "<group>"; };
A91C9FC01B659A6700AFFD54 /* AccessibilityTreeItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityTreeItem.cpp; sourceTree = "<group>"; };
A91C9FC11B659A6700AFFD54 /* AccessibilityTreeItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityTreeItem.h; sourceTree = "<group>"; };
+ A941AE6B1FB62BE5000F6F71 /* AccessibleNode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibleNode.cpp; sourceTree = "<group>"; };
+ A941AE6D1FB62BE7000F6F71 /* AccessibleNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibleNode.h; sourceTree = "<group>"; };
+ A941AE6E1FB62BEC000F6F71 /* AccessibleNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = AccessibleNode.idl; sourceTree = "<group>"; };
A9787CB21F5F599200C551C6 /* AccessibilityMediaObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccessibilityMediaObject.h; sourceTree = "<group>"; };
A9787CB31F5F5C6500C551C6 /* AccessibilityMediaObject.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityMediaObject.cpp; sourceTree = "<group>"; };
A9C6E4E10D745E05006442E9 /* DOMMimeType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DOMMimeType.cpp; sourceTree = "<group>"; };
@@ -15842,6 +15845,9 @@
2981CAAF131822EC00D12F2A /* AXObjectCache.cpp */,
29A8121A0FBB9C1D00510293 /* AXObjectCache.h */,
91C9F2F81AE3BE240095B61C /* AXTextStateChangeIntent.h */,
+ A941AE6B1FB62BE5000F6F71 /* AccessibleNode.cpp */,
+ A941AE6D1FB62BE7000F6F71 /* AccessibleNode.h */,
+ A941AE6E1FB62BEC000F6F71 /* AccessibleNode.idl */,
);
path = accessibility;
sourceTree = "<group>";
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -62,6 +62,7 @@
#include "AccessibilityTableRow.h"
#include "AccessibilityTree.h"
#include "AccessibilityTreeItem.h"
+#include "AccessibleNode.h"
#include "Document.h"
#include "Editing.h"
#include "Editor.h"
@@ -408,7 +409,7 @@
if (!node || !is<Element>(node))
return false;
- auto& roleValue = downcast<Element>(*node).attributeWithoutSynchronization(roleAttr);
+ const auto& roleValue = AccessibleNode::effectiveStringValueForElement(downcast<Element>(*node), AXPropertyName::Role);
if (role.isNull())
return roleValue.isEmpty();
if (roleValue.isEmpty())
@@ -848,7 +849,7 @@
Element* element = downcast<Element>(node);
String liveRegionStatus = element->attributeWithoutSynchronization(aria_liveAttr);
if (liveRegionStatus.isEmpty()) {
- const AtomicString& ariaRole = element->attributeWithoutSynchronization(roleAttr);
+ const AtomicString& ariaRole = AccessibleNode::effectiveStringValueForElement(*element, AXPropertyName::Role);
if (!ariaRole.isEmpty())
liveRegionStatus = AccessibilityObject::defaultLiveRegionStatusForRole(AccessibilityObject::ariaRoleToWebCoreRole(ariaRole));
}
Modified: trunk/Source/WebCore/accessibility/AccessibilityAllInOne.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityAllInOne.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityAllInOne.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -58,3 +58,4 @@
#include "AccessibilityTableRow.cpp"
#include "AccessibilityTree.cpp"
#include "AccessibilityTreeItem.cpp"
+#include "AccessibleNode.cpp"
Modified: trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityImageMapLink.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -31,6 +31,7 @@
#include "AXObjectCache.h"
#include "AccessibilityRenderObject.h"
+#include "AccessibleNode.h"
#include "Document.h"
#include "HTMLNames.h"
#include "RenderBoxModelObject.h"
@@ -68,7 +69,7 @@
if (!m_areaElement)
return AccessibilityRole::WebCoreLink;
- const AtomicString& ariaRole = getAttribute(roleAttr);
+ const AtomicString& ariaRole = stringValueForProperty(AXPropertyName::Role);
if (!ariaRole.isEmpty())
return AccessibilityObject::ariaRoleToWebCoreRole(ariaRole);
@@ -110,7 +111,7 @@
String AccessibilityImageMapLink::accessibilityDescription() const
{
- const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
+ const AtomicString& ariaLabel = stringValueForProperty(AXPropertyName::Label);
if (!ariaLabel.isEmpty())
return ariaLabel;
const AtomicString& alt = getAttribute(altAttr);
Modified: trunk/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -31,6 +31,7 @@
#include "AXObjectCache.h"
#include "AccessibilityListBox.h"
+#include "AccessibleNode.h"
#include "Element.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
@@ -141,7 +142,7 @@
if (!m_optionElement)
return String();
- const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
+ const AtomicString& ariaLabel = stringValueForProperty(AXPropertyName::Label);
if (!ariaLabel.isNull())
return ariaLabel;
Modified: trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -35,6 +35,7 @@
#include "AccessibilityListBox.h"
#include "AccessibilitySpinButton.h"
#include "AccessibilityTable.h"
+#include "AccessibleNode.h"
#include "Editing.h"
#include "ElementIterator.h"
#include "EventNames.h"
@@ -1169,7 +1170,7 @@
if (!ariaLabeledBy.isEmpty())
return ariaLabeledBy;
- const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
+ const AtomicString& ariaLabel = stringValueForProperty(AXPropertyName::Label);
if (!ariaLabel.isEmpty())
return ariaLabel;
@@ -1185,7 +1186,7 @@
for (auto& sibling : childrenOfType<Element>(*parent)) {
// FIXME: Should skip sibling that is the same as the node.
- if (equalIgnoringASCIICase(sibling.attributeWithoutSynchronization(roleAttr), role))
+ if (equalIgnoringASCIICase(AccessibleNode::effectiveStringValueForElement(sibling, AXPropertyName::Role), role))
return &sibling;
}
@@ -1276,7 +1277,7 @@
// Then check for aria-label attribute.
if (result.isEmpty())
- result = label->attributeWithoutSynchronization(aria_labelAttr);
+ result = AccessibleNode::effectiveStringValueForElement(*label, AXPropertyName::Label);
return !result.isEmpty() ? result : label->innerText();
}
@@ -1315,7 +1316,7 @@
ariaLabeledByText(textOrder);
- const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
+ const AtomicString& ariaLabel = stringValueForProperty(AXPropertyName::Label);
if (!ariaLabel.isEmpty())
textOrder.append(AccessibilityText(ariaLabel, AccessibilityTextSource::Alternative));
@@ -1507,7 +1508,7 @@
// Check if the HTML element has an aria-label for the webpage.
if (Element* documentElement = document->documentElement()) {
- const AtomicString& ariaLabel = documentElement->attributeWithoutSynchronization(aria_labelAttr);
+ const AtomicString& ariaLabel = AccessibleNode::effectiveStringValueForElement(*documentElement, AXPropertyName::Label);
if (!ariaLabel.isEmpty())
return ariaLabel;
}
@@ -1878,7 +1879,7 @@
int selectedIndex = selectElement.selectedIndex();
const Vector<HTMLElement*>& listItems = selectElement.listItems();
if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
- const AtomicString& overriddenDescription = listItems[selectedIndex]->attributeWithoutSynchronization(aria_labelAttr);
+ const AtomicString& overriddenDescription = AccessibleNode::effectiveStringValueForElement(*listItems[selectedIndex], AXPropertyName::Label);
if (!overriddenDescription.isNull())
return overriddenDescription;
}
@@ -1931,7 +1932,7 @@
return String();
Element& element = downcast<Element>(*node);
- const AtomicString& ariaLabel = element.attributeWithoutSynchronization(aria_labelAttr);
+ const AtomicString& ariaLabel = AccessibleNode::effectiveStringValueForElement(element, AXPropertyName::Label);
if (!ariaLabel.isEmpty())
return ariaLabel;
@@ -2119,7 +2120,7 @@
AccessibilityRole AccessibilityNodeObject::determineAriaRoleAttribute() const
{
- const AtomicString& ariaRole = getAttribute(roleAttr);
+ const AtomicString& ariaRole = stringValueForProperty(AXPropertyName::Role);
if (ariaRole.isNull() || ariaRole.isEmpty())
return AccessibilityRole::Unknown;
@@ -2145,7 +2146,7 @@
// describes the purpose of the content in the region." The Core AAM states, "Special case:
// if the region does not have an accessible name, do not expose the element as a landmark.
// Use the native host language role of the element instead."
- if (role == AccessibilityRole::LandmarkRegion && !hasAttribute(aria_labelAttr) && !hasAttribute(aria_labelledbyAttr))
+ if (role == AccessibilityRole::LandmarkRegion && !hasProperty(AXPropertyName::Label) && !hasAttribute(aria_labelledbyAttr))
role = AccessibilityRole::Unknown;
if (static_cast<int>(role))
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -33,6 +33,7 @@
#include "AccessibilityRenderObject.h"
#include "AccessibilityScrollView.h"
#include "AccessibilityTable.h"
+#include "AccessibleNode.h"
#include "DOMTokenList.h"
#include "Editing.h"
#include "Editor.h"
@@ -2143,7 +2144,21 @@
return element->attributeWithoutSynchronization(attribute);
return nullAtom();
}
-
+
+bool AccessibilityObject::hasProperty(AXPropertyName propertyKey) const
+{
+ if (Element* element = this->element())
+ return AccessibleNode::hasProperty(*element, propertyKey);
+ return false;
+}
+
+const String AccessibilityObject::stringValueForProperty(AXPropertyName propertyKey) const
+{
+ if (Element* element = this->element())
+ return AccessibleNode::effectiveStringValueForElement(*element, propertyKey);
+ return nullAtom();
+}
+
// Lacking concrete evidence of orientation, horizontal means width > height. vertical is height > width;
AccessibilityOrientation AccessibilityObject::orientation() const
{
@@ -2519,7 +2534,7 @@
|| hasAttribute(aria_flowtoAttr)
|| hasAttribute(aria_haspopupAttr)
|| hasAttribute(aria_invalidAttr)
- || hasAttribute(aria_labelAttr)
+ || hasProperty(AXPropertyName::Label)
|| hasAttribute(aria_labelledbyAttr)
|| hasAttribute(aria_relevantAttr);
}
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -90,6 +90,8 @@
class ScrollView;
class Widget;
+enum class AXPropertyName;
+
typedef unsigned AXID;
enum class AccessibilityRole {
@@ -891,6 +893,9 @@
const AtomicString& getAttribute(const QualifiedName&) const;
bool hasTagName(const QualifiedName&) const;
+ bool hasProperty(AXPropertyName) const;
+ const String stringValueForProperty(AXPropertyName) const;
+
virtual VisiblePositionRange visiblePositionRange() const { return VisiblePositionRange(); }
virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const { return VisiblePositionRange(); }
Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (224870 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -749,7 +749,7 @@
int selectedIndex = selectElement.selectedIndex();
const Vector<HTMLElement*>& listItems = selectElement.listItems();
if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
- const AtomicString& overriddenDescription = listItems[selectedIndex]->attributeWithoutSynchronization(aria_labelAttr);
+ const AtomicString& overriddenDescription = AccessibleNode::effectiveStringValueForElement(*listItems[selectedIndex], AXPropertyName::Label);
if (!overriddenDescription.isNull())
return overriddenDescription;
}
@@ -1059,7 +1059,7 @@
// titleUIElement, otherwise its inner text will be announced by a screenreader.
if (isLabelable()) {
if (HTMLLabelElement* label = labelForElement(downcast<Element>(node()))) {
- if (!label->attributeWithoutSynchronization(aria_labelAttr).isEmpty())
+ if (!AccessibleNode::effectiveStringValueForElement(*label, AXPropertyName::Label).isEmpty())
return false;
if (AccessibilityObject* labelObject = axObjectCache()->getOrCreate(label)) {
if (!labelObject->ariaLabeledByAttribute().isEmpty())
@@ -2768,7 +2768,7 @@
// The HTML AAM spec says it is "strongly recommended" that ATs only convey and provide navigation
// for section elements which have names.
if (node && node->hasTagName(sectionTag))
- return hasAttribute(aria_labelAttr) || hasAttribute(aria_labelledbyAttr) ? AccessibilityRole::LandmarkRegion : AccessibilityRole::TextGroup;
+ return hasProperty(AXPropertyName::Label) || hasAttribute(aria_labelledbyAttr) ? AccessibilityRole::LandmarkRegion : AccessibilityRole::TextGroup;
if (node && node->hasTagName(addressTag))
return AccessibilityRole::LandmarkContentInfo;
Added: trunk/Source/WebCore/accessibility/AccessibleNode.cpp (0 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibleNode.cpp (rev 0)
+++ trunk/Source/WebCore/accessibility/AccessibleNode.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AccessibleNode.h"
+
+#include "AXObjectCache.h"
+#include "HTMLNames.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+using ARIAAttributeMap = HashMap<AXPropertyName, QualifiedName, WTF::IntHash<AXPropertyName>, AXPropertyHashTraits>;
+
+static ARIAAttributeMap& ariaAttributeMap()
+{
+ static NeverDestroyed<ARIAAttributeMap> ariaAttributeMap = [] {
+ const struct AttributeEntry {
+ AXPropertyName name;
+ QualifiedName ariaAttribute;
+ } attributes[] = {
+ { AXPropertyName::Label, aria_labelAttr },
+ { AXPropertyName::Role, roleAttr }
+ };
+ ARIAAttributeMap map;
+ for (auto& attribute : attributes)
+ map.set(attribute.name, attribute.ariaAttribute);
+ return map;
+ }();
+ return ariaAttributeMap;
+}
+
+static bool isPropertyValueString(AXPropertyName propertyName)
+{
+ switch (propertyName) {
+ case AXPropertyName::Label:
+ case AXPropertyName::Role:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool AccessibleNode::hasProperty(Element& element, AXPropertyName propertyName)
+{
+ if (auto* accessibleNode = element.existingAccessibleNode()) {
+ if (accessibleNode->m_propertyMap.contains(propertyName))
+ return true;
+ }
+
+ if (ariaAttributeMap().contains(propertyName))
+ return element.hasAttributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
+
+ return false;
+}
+
+const PropertyValueVariant AccessibleNode::valueForProperty(Element& element, AXPropertyName propertyName)
+{
+ if (auto* accessibleNode = element.existingAccessibleNode()) {
+ if (accessibleNode->m_propertyMap.contains(propertyName))
+ return accessibleNode->m_propertyMap.get(propertyName);
+ }
+
+ return nullptr;
+}
+
+const String AccessibleNode::effectiveStringValueForElement(Element& element, AXPropertyName propertyName)
+{
+ const String& value = stringValueForProperty(element, propertyName);
+ if (!value.isEmpty())
+ return value;
+
+ if (ariaAttributeMap().contains(propertyName) && isPropertyValueString(propertyName))
+ return element.attributeWithoutSynchronization(ariaAttributeMap().get(propertyName));
+
+ return nullAtom();
+}
+
+const String AccessibleNode::stringValueForProperty(Element& element, AXPropertyName propertyName)
+{
+ const PropertyValueVariant&& variant = AccessibleNode::valueForProperty(element, propertyName);
+ if (WTF::holds_alternative<String>(variant))
+ return WTF::get<String>(variant);
+ return nullAtom();
+}
+
+void AccessibleNode::setStringProperty(const String& value, AXPropertyName propertyName)
+{
+ if (value.isEmpty()) {
+ m_propertyMap.remove(propertyName);
+ return;
+ }
+ m_propertyMap.set(propertyName, value);
+}
+
+String AccessibleNode::role() const
+{
+ return stringValueForProperty(m_ownerElement, AXPropertyName::Role);
+}
+
+void AccessibleNode::setRole(const String& role)
+{
+ setStringProperty(role, AXPropertyName::Role);
+ if (AXObjectCache* cache = m_ownerElement.document().axObjectCache())
+ cache->handleAttributeChanged(roleAttr, &m_ownerElement);
+}
+
+String AccessibleNode::label() const
+{
+ return stringValueForProperty(m_ownerElement, AXPropertyName::Label);
+}
+
+void AccessibleNode::setLabel(const String& label)
+{
+ setStringProperty(label, AXPropertyName::Label);
+ if (AXObjectCache* cache = m_ownerElement.document().axObjectCache())
+ cache->handleAttributeChanged(aria_labelAttr, &m_ownerElement);
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/accessibility/AccessibleNode.h (0 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibleNode.h (rev 0)
+++ trunk/Source/WebCore/accessibility/AccessibleNode.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Element.h"
+#include "ScriptWrappable.h"
+#include <wtf/HashMap.h>
+#include <wtf/Variant.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+typedef Variant<String, bool, int> PropertyValueVariant;
+
+enum class AXPropertyName {
+ None,
+ Role,
+ Label
+};
+
+struct AXPropertyHashTraits : WTF::GenericHashTraits<AXPropertyName> {
+ static const bool emptyValueIsZero = false;
+ static AXPropertyName emptyValue() { return AXPropertyName::None; };
+ static void constructDeletedValue(AXPropertyName& slot)
+ {
+ slot = AXPropertyName::None;
+ }
+ static bool isDeletedValue(AXPropertyName value)
+ {
+ return value == AXPropertyName::None;
+ }
+};
+
+class AccessibleNode : public ScriptWrappable {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit AccessibleNode(Element& element)
+ : m_ownerElement(element)
+ {
+ }
+
+ void ref() { m_ownerElement.ref(); }
+ void deref() { m_ownerElement.deref(); }
+
+ static const String effectiveStringValueForElement(Element&, AXPropertyName);
+ static bool hasProperty(Element&, AXPropertyName);
+
+ String role() const;
+ void setRole(const String&);
+
+ String label() const;
+ void setLabel(const String&);
+
+private:
+ static const PropertyValueVariant valueForProperty(Element&, AXPropertyName);
+ static const String stringValueForProperty(Element&, AXPropertyName);
+ void setStringProperty(const String&, AXPropertyName);
+
+ Element& m_ownerElement;
+
+ HashMap<AXPropertyName, PropertyValueVariant, WTF::IntHash<AXPropertyName>, AXPropertyHashTraits> m_propertyMap;
+};
+
+} // namespace WebCore
+
Added: trunk/Source/WebCore/accessibility/AccessibleNode.idl (0 => 224871)
--- trunk/Source/WebCore/accessibility/AccessibleNode.idl (rev 0)
+++ trunk/Source/WebCore/accessibility/AccessibleNode.idl 2017-11-15 07:56:04 UTC (rev 224871)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ SkipVTableValidation,
+ EnabledAtRuntime=AccessibilityObjectModel,
+] interface AccessibleNode {
+ attribute DOMString? role;
+ attribute DOMString? label;
+};
Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (224870 => 224871)
--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -31,6 +31,7 @@
namespace WebCore {
#define WEBCORE_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
+ macro(AccessibleNode) \
macro(Animation) \
macro(AnimationEffect) \
macro(AnimationEffectTiming) \
Modified: trunk/Source/WebCore/dom/Element.cpp (224870 => 224871)
--- trunk/Source/WebCore/dom/Element.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/dom/Element.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -27,6 +27,7 @@
#include "Element.h"
#include "AXObjectCache.h"
+#include "AccessibleNode.h"
#include "Attr.h"
#include "AttributeChangeInvalidation.h"
#include "CSSAnimationController.h"
@@ -85,6 +86,7 @@
#include "RenderTreeUpdater.h"
#include "RenderView.h"
#include "RenderWidget.h"
+#include "RuntimeEnabledFeatures.h"
#include "SVGDocumentExtensions.h"
#include "SVGElement.h"
#include "SVGNames.h"
@@ -3553,7 +3555,7 @@
bool Element::canContainRangeEndPoint() const
{
- return !equalLettersIgnoringASCIICase(attributeWithoutSynchronization(roleAttr), "img");
+ return !equalLettersIgnoringASCIICase(AccessibleNode::effectiveStringValueForElement(const_cast<Element&>(*this), AXPropertyName::Role), "img");
}
String Element::completeURLsInAttributeValue(const URL& base, const Attribute& attribute) const
@@ -3707,4 +3709,25 @@
return document().timeline().animationsForElement(*this);
}
+AccessibleNode* Element::accessibleNode()
+{
+ if (!RuntimeEnabledFeatures::sharedFeatures().accessibilityObjectModelEnabled())
+ return nullptr;
+
+ ElementRareData& data = ""
+ if (!data.accessibleNode())
+ data.setAccessibleNode(std::make_unique<AccessibleNode>(*this));
+ return data.accessibleNode();
+}
+
+AccessibleNode* Element::existingAccessibleNode() const
+{
+ if (!RuntimeEnabledFeatures::sharedFeatures().accessibilityObjectModelEnabled())
+ return nullptr;
+
+ if (!hasRareData())
+ return nullptr;
+ return elementRareData()->accessibleNode();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Element.h (224870 => 224871)
--- trunk/Source/WebCore/dom/Element.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/dom/Element.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -36,6 +36,7 @@
namespace WebCore {
+class AccessibleNode;
class CustomElementReactionQueue;
class DatasetDOMStringMap;
class DOMRect;
@@ -552,6 +553,9 @@
Element* findAnchorElementForLink(String& outAnchorName);
+ AccessibleNode* existingAccessibleNode() const;
+ AccessibleNode* accessibleNode();
+
Vector<RefPtr<WebAnimation>> getAnimations();
protected:
Modified: trunk/Source/WebCore/dom/Element.idl (224870 => 224871)
--- trunk/Source/WebCore/dom/Element.idl 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/dom/Element.idl 2017-11-15 07:56:04 UTC (rev 224871)
@@ -103,6 +103,8 @@
// Non standard API (https://www.w3.org/Bugs/Public/show_bug.cgi?id=17152).
void scrollIntoViewIfNeeded(optional boolean centerIfNeeded = true);
+ [EnabledAtRuntime=AccessibilityObjectModel, SameObject] readonly attribute AccessibleNode? accessibleNode;
+
// Event handler from Selection API (http://w3c.github.io/selection-api/#extensions-to-globaleventhandlers).
// FIXME: Should be moved to GlobalEventHandlers.
[NotEnumerable] attribute EventHandler onselectstart; // FIXME: Should be enumerable.
Modified: trunk/Source/WebCore/dom/ElementRareData.cpp (224870 => 224871)
--- trunk/Source/WebCore/dom/ElementRareData.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/dom/ElementRareData.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -43,7 +43,7 @@
#endif
LayoutSize sizeForResizing;
IntPoint savedLayerScrollPosition;
- void* pointers[8];
+ void* pointers[9];
};
static_assert(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), "ElementRareData should stay small");
Modified: trunk/Source/WebCore/dom/ElementRareData.h (224870 => 224871)
--- trunk/Source/WebCore/dom/ElementRareData.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/dom/ElementRareData.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -21,6 +21,7 @@
#pragma once
+#include "AccessibleNode.h"
#include "CustomElementReactionQueue.h"
#include "DOMTokenList.h"
#include "DatasetDOMStringMap.h"
@@ -110,6 +111,9 @@
bool hasCSSAnimation() const { return m_hasCSSAnimation; }
void setHasCSSAnimation(bool value) { m_hasCSSAnimation = value; }
+ AccessibleNode* accessibleNode() const { return m_accessibleNode.get(); }
+ void setAccessibleNode(std::unique_ptr<AccessibleNode> accessibleNode) { m_accessibleNode = WTFMove(accessibleNode); }
+
private:
int m_tabIndex;
unsigned short m_childIndex;
@@ -144,6 +148,8 @@
RefPtr<PseudoElement> m_beforePseudoElement;
RefPtr<PseudoElement> m_afterPseudoElement;
+ std::unique_ptr<AccessibleNode> m_accessibleNode;
+
void releasePseudoElement(PseudoElement*);
};
Modified: trunk/Source/WebCore/editing/TextIterator.cpp (224870 => 224871)
--- trunk/Source/WebCore/editing/TextIterator.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/editing/TextIterator.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -27,6 +27,7 @@
#include "config.h"
#include "TextIterator.h"
+#include "AccessibleNode.h"
#include "Document.h"
#include "Editing.h"
#include "FontCascade.h"
@@ -284,7 +285,7 @@
Element& element = downcast<Element>(*renderer->node());
if (is<HTMLFormControlElement>(element) || is<HTMLLegendElement>(element) || is<HTMLProgressElement>(element) || element.hasTagName(meterTag))
return true;
- if (equalLettersIgnoringASCIICase(element.attributeWithoutSynchronization(roleAttr), "img"))
+ if (equalLettersIgnoringASCIICase(AccessibleNode::effectiveStringValueForElement(element, AXPropertyName::Role), "img"))
return true;
}
Modified: trunk/Source/WebCore/page/RuntimeEnabledFeatures.h (224870 => 224871)
--- trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/page/RuntimeEnabledFeatures.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -225,6 +225,9 @@
void setWebVREnabled(bool isEnabled) { m_webVREnabled = isEnabled; }
bool webVREnabled() const { return m_webVREnabled; }
+ void setAccessibilityObjectModelEnabled(bool isEnabled) { m_accessibilityObjectModelEnabled = isEnabled; }
+ bool accessibilityObjectModelEnabled() const { return m_accessibilityObjectModelEnabled; }
+
WEBCORE_EXPORT static RuntimeEnabledFeatures& sharedFeatures();
private:
@@ -345,6 +348,8 @@
bool m_inspectorAdditionsEnabled { false };
bool m_webVREnabled { false };
+ bool m_accessibilityObjectModelEnabled { false };
+
friend class WTF::NeverDestroyed<RuntimeEnabledFeatures>;
};
Modified: trunk/Source/WebCore/rendering/RenderMenuList.cpp (224870 => 224871)
--- trunk/Source/WebCore/rendering/RenderMenuList.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebCore/rendering/RenderMenuList.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -27,6 +27,7 @@
#include "AXObjectCache.h"
#include "AccessibilityMenuList.h"
+#include "AccessibleNode.h"
#include "CSSFontSelector.h"
#include "Chrome.h"
#include "Frame.h"
@@ -476,7 +477,7 @@
const Vector<HTMLElement*>& listItems = selectElement().listItems();
if (listIndex >= listItems.size())
return String();
- return listItems[listIndex]->attributeWithoutSynchronization(aria_labelAttr);
+ return AccessibleNode::effectiveStringValueForElement(*listItems[listIndex], AXPropertyName::Label);
}
String RenderMenuList::itemToolTip(unsigned listIndex) const
Modified: trunk/Source/WebKit/ChangeLog (224870 => 224871)
--- trunk/Source/WebKit/ChangeLog 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKit/ChangeLog 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1,3 +1,16 @@
+2017-11-14 Nan Wang <[email protected]>
+
+ AX: AOM: Implement AccessibleNode class and support label and role attributes
+ https://bugs.webkit.org/show_bug.cgi?id=179494
+
+ Reviewed by Ryosuke Niwa.
+
+ * Shared/WebPreferences.yaml:
+ * UIProcess/API/C/WKPreferences.cpp:
+ (WKPreferencesSetAccessibilityObjectModelEnabled):
+ (WKPreferencesGetAccessibilityObjectModelEnabled):
+ * UIProcess/API/C/WKPreferencesRefPrivate.h:
+
2017-11-14 Carlos Garcia Campos <[email protected]>
Move JSONValues to WTF and convert uses of InspectorValues.h to JSONValues.h
Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (224870 => 224871)
--- trunk/Source/WebKit/Shared/WebPreferences.yaml 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1147,3 +1147,11 @@
category: experimental
webcoreBinding: RuntimeEnabledFeatures
condition: ENABLE(WEBGPU)
+
+AccessibilityObjectModelEnabled:
+ type: bool
+ defaultValue: false
+ humanReadableName: "Accessibility Object Model"
+ humanReadableDescription: "Accessibility Object Model support"
+ category: experimental
+ webcoreBinding: RuntimeEnabledFeatures
Modified: trunk/Source/WebKit/UIProcess/API/C/WKPreferences.cpp (224870 => 224871)
--- trunk/Source/WebKit/UIProcess/API/C/WKPreferences.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPreferences.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1909,3 +1909,13 @@
{
return toImpl(preferencesRef)->storageAccessAPIEnabled();
}
+
+void WKPreferencesSetAccessibilityObjectModelEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+ toImpl(preferencesRef)->setAccessibilityObjectModelEnabled(flag);
+}
+
+bool WKPreferencesGetAccessibilityObjectModelEnabled(WKPreferencesRef preferencesRef)
+{
+ return toImpl(preferencesRef)->accessibilityObjectModelEnabled();
+}
Modified: trunk/Source/WebKit/UIProcess/API/C/WKPreferencesRefPrivate.h (224870 => 224871)
--- trunk/Source/WebKit/UIProcess/API/C/WKPreferencesRefPrivate.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKit/UIProcess/API/C/WKPreferencesRefPrivate.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -540,6 +540,10 @@
// Defaults to false.
WK_EXPORT void WKPreferencesSetStorageAccessAPIEnabled(WKPreferencesRef, bool flag);
WK_EXPORT bool WKPreferencesGetStorageAccessAPIEnabled(WKPreferencesRef);
+
+// Defaults to false
+WK_EXPORT void WKPreferencesSetAccessibilityObjectModelEnabled(WKPreferencesRef, bool flag);
+WK_EXPORT bool WKPreferencesGetAccessibilityObjectModelEnabled(WKPreferencesRef);
#ifdef __cplusplus
}
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (224870 => 224871)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1,3 +1,19 @@
+2017-11-14 Nan Wang <[email protected]>
+
+ AX: AOM: Implement AccessibleNode class and support label and role attributes
+ https://bugs.webkit.org/show_bug.cgi?id=179494
+
+ Reviewed by Ryosuke Niwa.
+
+ * WebView/WebPreferenceKeysPrivate.h:
+ * WebView/WebPreferences.mm:
+ (+[WebPreferences initialize]):
+ (-[WebPreferences accessibilityObjectModelEnabled]):
+ (-[WebPreferences setAccessibilityObjectModelEnabled:]):
+ * WebView/WebPreferencesPrivate.h:
+ * WebView/WebView.mm:
+ (-[WebView _preferencesChanged:]):
+
2017-11-14 Alex Christensen <[email protected]>
Remove Cocoa CFURLConnection loading code
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h (224870 => 224871)
--- trunk/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -252,3 +252,4 @@
#define WebKitEncryptedMediaAPIEnabledKey @"WebKitEncryptedMediaAPIEnabled"
#define WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey @"WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallback"
#define WebKitInspectorAdditionsEnabledPreferenceKey @"WebKitInspectorAdditionsEnabled"
+#define WebKitAccessibilityObjectModelEnabledPreferenceKey @"WebKitAccessibilityObjectModelEnabled"
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm (224870 => 224871)
--- trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPreferences.mm 2017-11-15 07:56:04 UTC (rev 224871)
@@ -680,6 +680,7 @@
@YES, WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey,
@NO, WebKitInspectorAdditionsEnabledPreferenceKey,
(NSString *)Settings::defaultMediaContentTypesRequiringHardwareSupport(), WebKitMediaContentTypesRequiringHardwareSupportPreferenceKey,
+ @NO, WebKitAccessibilityObjectModelEnabledPreferenceKey,
nil];
#if !PLATFORM(IOS)
@@ -3256,6 +3257,17 @@
[self _setBoolValue:flag forKey:WebKitInspectorAdditionsEnabledPreferenceKey];
}
+- (BOOL)accessibilityObjectModelEnabled
+{
+ return [self _boolValueForKey:WebKitAccessibilityObjectModelEnabledPreferenceKey];
+}
+
+- (void)setAccessibilityObjectModelEnabled:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitAccessibilityObjectModelEnabledPreferenceKey];
+}
+
+
@end
@implementation WebPreferences (WebInternal)
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h (224870 => 224871)
--- trunk/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h 2017-11-15 07:56:04 UTC (rev 224871)
@@ -595,6 +595,7 @@
@property (nonatomic) BOOL constantPropertiesEnabled;
@property (nonatomic) BOOL inspectorAdditionsEnabled;
@property (nonatomic) BOOL allowMediaContentTypesRequiringHardwareSupportAsFallback;
+@property (nonatomic) BOOL accessibilityObjectModelEnabled;
#if TARGET_OS_IPHONE
@property (nonatomic) BOOL quickLookDocumentSavingEnabled;
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebView.mm (224870 => 224871)
--- trunk/Source/WebKitLegacy/mac/WebView/WebView.mm 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebView.mm 2017-11-15 07:56:04 UTC (rev 224871)
@@ -3039,6 +3039,7 @@
RuntimeEnabledFeatures::sharedFeatures().setIsSecureContextAttributeEnabled(preferences.isSecureContextAttributeEnabled);
RuntimeEnabledFeatures::sharedFeatures().setDirectoryUploadEnabled([preferences directoryUploadEnabled]);
RuntimeEnabledFeatures::sharedFeatures().setMenuItemElementEnabled([preferences menuItemElementEnabled]);
+ RuntimeEnabledFeatures::sharedFeatures().setAccessibilityObjectModelEnabled([preferences accessibilityObjectModelEnabled]);
#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
RuntimeEnabledFeatures::sharedFeatures().setLegacyEncryptedMediaAPIEnabled(preferences.legacyEncryptedMediaAPIEnabled);
Modified: trunk/Tools/ChangeLog (224870 => 224871)
--- trunk/Tools/ChangeLog 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Tools/ChangeLog 2017-11-15 07:56:04 UTC (rev 224871)
@@ -1,3 +1,15 @@
+2017-11-14 Nan Wang <[email protected]>
+
+ AX: AOM: Implement AccessibleNode class and support label and role attributes
+ https://bugs.webkit.org/show_bug.cgi?id=179494
+
+ Reviewed by Ryosuke Niwa.
+
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (enableExperimentalFeatures):
+ * WebKitTestRunner/TestController.cpp:
+ (WTR::TestController::resetPreferencesToConsistentValues):
+
2017-11-14 Basuke Suzuki <[email protected]>
[Windows] Fix error while launching subprocess on Windows Python
Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (224870 => 224871)
--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm 2017-11-15 07:56:04 UTC (rev 224871)
@@ -855,6 +855,7 @@
[preferences setReadableByteStreamAPIEnabled:YES];
[preferences setWritableStreamAPIEnabled:YES];
preferences.encryptedMediaAPIEnabled = YES;
+ [preferences setAccessibilityObjectModelEnabled:YES];
}
// Called before each test.
Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (224870 => 224871)
--- trunk/Tools/WebKitTestRunner/TestController.cpp 2017-11-15 06:08:44 UTC (rev 224870)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp 2017-11-15 07:56:04 UTC (rev 224871)
@@ -741,6 +741,8 @@
WKPreferencesSetInspectorAdditionsEnabled(preferences, options.enableInspectorAdditions);
WKPreferencesSetStorageAccessAPIEnabled(preferences, true);
+
+ WKPreferencesSetAccessibilityObjectModelEnabled(preferences, true);
platformResetPreferencesToConsistentValues();
}