[ATK] Implement support for new ARIA 1.1 values of aria-haspopup
authorjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Apr 2017 19:30:08 +0000 (19:30 +0000)
committerjdiggs@igalia.com <jdiggs@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Apr 2017 19:30:08 +0000 (19:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171164

Reviewed by Chris Fleizach.

Source/WebCore:

In ARIA 1.1, aria-haspopup's value type changed from true/false to a token.
Values: true, false (default, unless it's a combobox), dialog, grid, listbox
(default for combobox), menu, and tree. Any value of aria-haspopup that is
not included in the list of allowed values, including an empty string, must
be treated as if the value false had been provided.

Add AccessibilityObject::ariaPopupValue() to validate the value, handle implicit
values, and give platform assistive technologies a means to access that value.

If there is a valid, non-false value of aria-haspopup, include ATK_STATE_HAS_POPUP
in the AtkStateSet. Lastly, expose the value (rather than true/false) via the "haspop"
AtkObject attribute.

Test: accessibility/gtk/aria-haspopup.html

* accessibility/AccessibilityObject.h:
(WebCore::AccessibilityObject::ariaPopupValue):
(WebCore::AccessibilityObject::supportsARIAHasPopup):
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::ariaHasPopup):
* accessibility/AccessibilityRenderObject.h:
* accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
(webkitAccessibleGetAttributes):
(setAtkStateSetFromCoreObject):

Tools:

hasPopup() should return whether or not ATK_STATE_HAS_POPUP is in the
AtkStateSet; not what is found in the AtkObject's attributes.

* WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp:
(WTR::AccessibilityUIElement::hasPopup):

LayoutTests:

In addition to the new test, update xml-roles-exposed.html's expectations
because the implicit value of aria-haspopup for the combobox role is now
listbox, and that value should be exposed via an AtkObject attribute.

* accessibility/gtk/aria-haspopup-expected.txt: Added.
* accessibility/gtk/aria-haspopup.html: Added.
* accessibility/gtk/xml-roles-exposed-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/accessibility/gtk/aria-haspopup-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/gtk/aria-haspopup.html [new file with mode: 0644]
LayoutTests/accessibility/gtk/xml-roles-exposed-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp

index 9069ff2..41ff07e 100644 (file)
@@ -1,3 +1,18 @@
+2017-04-26  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        [ATK] Implement support for new ARIA 1.1 values of aria-haspopup
+        https://bugs.webkit.org/show_bug.cgi?id=171164
+
+        Reviewed by Chris Fleizach.
+
+        In addition to the new test, update xml-roles-exposed.html's expectations
+        because the implicit value of aria-haspopup for the combobox role is now
+        listbox, and that value should be exposed via an AtkObject attribute.
+
+        * accessibility/gtk/aria-haspopup-expected.txt: Added.
+        * accessibility/gtk/aria-haspopup.html: Added.
+        * accessibility/gtk/xml-roles-exposed-expected.txt:
+
 2017-04-26  Simon Fraser  <simon.fraser@apple.com>
 
         http/tests/frame-throttling tests failing on iOS
diff --git a/LayoutTests/accessibility/gtk/aria-haspopup-expected.txt b/LayoutTests/accessibility/gtk/aria-haspopup-expected.txt
new file mode 100644 (file)
index 0000000..42d88c0
--- /dev/null
@@ -0,0 +1,69 @@
+This tests the exposure of aria-haspopup
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+test1 hasPopup: false
+AXPlatformAttributes: computed-role:button, xml-roles:button, html-id:test1, tag:div, toolkit:WebKitGtk
+
+test2 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:true, html-id:test2, tag:div, toolkit:WebKitGtk
+
+test3 hasPopup: false
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:false, html-id:test3, tag:div, toolkit:WebKitGtk
+
+test4 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:dialog, html-id:test4, tag:div, toolkit:WebKitGtk
+
+test5 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:grid, html-id:test5, tag:div, toolkit:WebKitGtk
+
+test6 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:listbox, html-id:test6, tag:div, toolkit:WebKitGtk
+
+test7 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:menu, html-id:test7, tag:div, toolkit:WebKitGtk
+
+test8 hasPopup: true
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:tree, html-id:test8, tag:div, toolkit:WebKitGtk
+
+test9 hasPopup: false
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:false, html-id:test9, tag:div, toolkit:WebKitGtk
+
+test10 hasPopup: false
+AXPlatformAttributes: computed-role:button, xml-roles:button, haspopup:false, html-id:test10, tag:div, toolkit:WebKitGtk
+
+test11 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:listbox, html-id:test11, tag:div, toolkit:WebKitGtk
+
+test12 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:true, html-id:test12, tag:div, toolkit:WebKitGtk
+
+test13 hasPopup: false
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:false, html-id:test13, tag:div, toolkit:WebKitGtk
+
+test14 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:dialog, html-id:test14, tag:div, toolkit:WebKitGtk
+
+test15 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:grid, html-id:test15, tag:div, toolkit:WebKitGtk
+
+test16 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:listbox, html-id:test16, tag:div, toolkit:WebKitGtk
+
+test17 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:menu, html-id:test17, tag:div, toolkit:WebKitGtk
+
+test18 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:tree, html-id:test18, tag:div, toolkit:WebKitGtk
+
+test19 hasPopup: false
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:false, html-id:test19, tag:div, toolkit:WebKitGtk
+
+test20 hasPopup: true
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:listbox, html-id:test20, tag:div, toolkit:WebKitGtk
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/gtk/aria-haspopup.html b/LayoutTests/accessibility/gtk/aria-haspopup.html
new file mode 100644 (file)
index 0000000..5b547ac
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+<div id="content">
+  <div id="test1" role="button">X</div>
+  <div id="test2" role="button" aria-haspopup="true">X</div>
+  <div id="test3" role="button" aria-haspopup="false">X</div>
+  <div id="test4" role="button" aria-haspopup="dialog">X</div>
+  <div id="test5" role="button" aria-haspopup="grid">X</div>
+  <div id="test6" role="button" aria-haspopup="listbox">X</div>
+  <div id="test7" role="button" aria-haspopup="menu">X</div>
+  <div id="test8" role="button" aria-haspopup="tree">X</div>
+  <div id="test9" role="button" aria-haspopup="foo">X</div>
+  <div id="test10" role="button" aria-haspopup="">X</div>
+  <div id="test11" role="combobox">X</div>
+  <div id="test12" role="combobox" aria-haspopup="true">X</div>
+  <div id="test13" role="combobox" aria-haspopup="false">X</div>
+  <div id="test14" role="combobox" aria-haspopup="dialog">X</div>
+  <div id="test15" role="combobox" aria-haspopup="grid">X</div>
+  <div id="test16" role="combobox" aria-haspopup="listbox">X</div>
+  <div id="test17" role="combobox" aria-haspopup="menu">X</div>
+  <div id="test18" role="combobox" aria-haspopup="tree">X</div>
+  <div id="test19" role="combobox" aria-haspopup="foo">X</div>
+  <div id="test20" role="combobox" aria-haspopup="">X</div>
+</div>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+    function platformAttributes(axElement) {
+        var allAttributes = axElement.allAttributes().split("\n");
+        var length = allAttributes.length;
+        for (var i = 0; i < length; i++) {
+            var string = allAttributes[i];
+            if (string.startsWith("AXPlatformAttributes"))
+                return string;
+        }
+        return "";
+    }
+
+    description("This tests the exposure of aria-haspopup");
+    if (window.accessibilityController) {
+        for (var i = 1; i <= 20; i++) {
+            var axElement = accessibilityController.accessibleElementById("test" + i);
+            debug("\ntest" + i + " hasPopup: " + axElement.hasPopup);
+            debug(platformAttributes(axElement));
+        }
+
+        document.getElementById("content").style.visibility = "hidden";
+    }
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
+
index c6ac269..24922a3 100644 (file)
@@ -154,7 +154,7 @@ AXEnabled: 1
 AXExpanded: 0
 AXRequired: 0
 AXChecked: 0
-AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, tag:div, toolkit:WebKitGtk
+AXPlatformAttributes: computed-role:combobox, xml-roles:combobox, readonly:false, haspopup:listbox, tag:div, toolkit:WebKitGtk
 ------------
 AXRole: AXLandmarkComplementary
 AXParent: AXWebArea
index dce492d..8158abf 100644 (file)
@@ -1,3 +1,35 @@
+2017-04-26  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        [ATK] Implement support for new ARIA 1.1 values of aria-haspopup
+        https://bugs.webkit.org/show_bug.cgi?id=171164
+
+        Reviewed by Chris Fleizach.
+
+        In ARIA 1.1, aria-haspopup's value type changed from true/false to a token.
+        Values: true, false (default, unless it's a combobox), dialog, grid, listbox
+        (default for combobox), menu, and tree. Any value of aria-haspopup that is
+        not included in the list of allowed values, including an empty string, must
+        be treated as if the value false had been provided.
+
+        Add AccessibilityObject::ariaPopupValue() to validate the value, handle implicit
+        values, and give platform assistive technologies a means to access that value.
+
+        If there is a valid, non-false value of aria-haspopup, include ATK_STATE_HAS_POPUP
+        in the AtkStateSet. Lastly, expose the value (rather than true/false) via the "haspop"
+        AtkObject attribute.
+
+        Test: accessibility/gtk/aria-haspopup.html
+
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilityObject::ariaPopupValue):
+        (WebCore::AccessibilityObject::supportsARIAHasPopup):
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::ariaHasPopup):
+        * accessibility/AccessibilityRenderObject.h:
+        * accessibility/atk/WebKitAccessibleWrapperAtk.cpp:
+        (webkitAccessibleGetAttributes):
+        (setAtkStateSetFromCoreObject):
+
 2017-04-26  Alex Christensen  <achristensen@webkit.org>
 
         Fix CMake build.
index 9ab1979..880466f 100644 (file)
@@ -2481,6 +2481,32 @@ bool AccessibilityObject::supportsRangeValue() const
         || isAttachmentElement();
 }
     
+bool AccessibilityObject::supportsARIAHasPopup() const
+{
+    return hasAttribute(aria_haspopupAttr) || isComboBox();
+}
+
+String AccessibilityObject::ariaPopupValue() const
+{
+    const AtomicString& hasPopup = getAttribute(aria_haspopupAttr);
+    if (equalLettersIgnoringASCIICase(hasPopup, "true")
+        || equalLettersIgnoringASCIICase(hasPopup, "dialog")
+        || equalLettersIgnoringASCIICase(hasPopup, "grid")
+        || equalLettersIgnoringASCIICase(hasPopup, "listbox")
+        || equalLettersIgnoringASCIICase(hasPopup, "menu")
+        || equalLettersIgnoringASCIICase(hasPopup, "tree"))
+        return hasPopup;
+
+    // In ARIA 1.1, the implicit value for combobox became "listbox."
+    if (isComboBox() && hasPopup.isEmpty())
+        return "listbox";
+
+    // The spec states that "User agents must treat any value of aria-haspopup that is not
+    // included in the list of allowed values, including an empty string, as if the value
+    // false had been provided."
+    return "false";
+}
+
 bool AccessibilityObject::supportsARIASetSize() const
 {
     return hasAttribute(aria_setsizeAttr);
index 159d5cc..c2c1bbc 100644 (file)
@@ -641,6 +641,8 @@ public:
     void ariaOwnsElements(AccessibilityChildrenVector&) const;
 
     virtual bool ariaHasPopup() const { return false; }
+    String ariaPopupValue() const;
+    bool supportsARIAHasPopup() const;
     bool ariaPressedIsPresent() const;
     bool ariaIsMultiline() const;
     String invalidStatus() const;
index c579858..aea1be5 100644 (file)
@@ -1010,7 +1010,7 @@ bool AccessibilityRenderObject::hasTextAlternative() const
     
 bool AccessibilityRenderObject::ariaHasPopup() const
 {
-    return elementAttributeValue(aria_haspopupAttr);
+    return !equalLettersIgnoringASCIICase(ariaPopupValue(), "false");
 }
 
 bool AccessibilityRenderObject::supportsARIADropping() const 
index e35247b..6df2587 100644 (file)
@@ -400,8 +400,8 @@ static AtkAttributeSet* webkitAccessibleGetAttributes(AtkObject* object)
     if (!placeholder.isEmpty())
         attributeSet = addToAtkAttributeSet(attributeSet, "placeholder-text", placeholder.utf8().data());
 
-    if (coreObject->ariaHasPopup())
-        attributeSet = addToAtkAttributeSet(attributeSet, "haspopup", "true");
+    if (coreObject->supportsARIAHasPopup())
+        attributeSet = addToAtkAttributeSet(attributeSet, "haspopup", coreObject->ariaPopupValue().utf8().data());
 
     AccessibilitySortDirection sortDirection = coreObject->sortDirection();
     if (sortDirection != SortDirectionNone) {
@@ -793,6 +793,9 @@ static void setAtkStateSetFromCoreObject(AccessibilityObject* coreObject, AtkSta
     else if (coreObject->orientation() == AccessibilityOrientationVertical)
         atk_state_set_add_state(stateSet, ATK_STATE_VERTICAL);
 
+    if (coreObject->ariaHasPopup())
+        atk_state_set_add_state(stateSet, ATK_STATE_HAS_POPUP);
+
     if (coreObject->isIndeterminate())
         atk_state_set_add_state(stateSet, ATK_STATE_INDETERMINATE);
 
index aa984c9..14701a7 100644 (file)
@@ -1,3 +1,16 @@
+2017-04-26  Joanmarie Diggs  <jdiggs@igalia.com>
+
+        [ATK] Implement support for new ARIA 1.1 values of aria-haspopup
+        https://bugs.webkit.org/show_bug.cgi?id=171164
+
+        Reviewed by Chris Fleizach.
+
+        hasPopup() should return whether or not ATK_STATE_HAS_POPUP is in the
+        AtkStateSet; not what is found in the AtkObject's attributes.
+
+        * WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp:
+        (WTR::AccessibilityUIElement::hasPopup):
+
 2017-04-25  Alex Christensen  <achristensen@webkit.org>
 
         Encoded filename should be decoded for WKContentExtension.identifier
index a417586..df4efba 100644 (file)
@@ -1987,11 +1987,7 @@ bool AccessibilityUIElement::isMultiLine() const
 
 bool AccessibilityUIElement::hasPopup() const
 {
-    if (!ATK_IS_OBJECT(m_element.get()))
-        return false;
-
-    String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "haspopup");
-    return equalLettersIgnoringASCIICase(hasPopupValue, "true");
+    return checkElementState(m_element.get(), ATK_STATE_HAS_POPUP);
 }
 
 void AccessibilityUIElement::takeFocus()