Changes to aria-hidden don't change VO navigation
authorcfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Sep 2011 21:42:02 +0000 (21:42 +0000)
committercfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Sep 2011 21:42:02 +0000 (21:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67722

Reviewed by Darin Adler.

Source/WebCore:

When altering aria-hidden, WebCore needs to update the children caches of
affected elements. However, for elements that were children, but ignored, their
caches did not get updated, and stale information would be propagated.

The fix is to always clearChildren() when a parent is asking for children. This
ensures information is always up to date when the parent itself is asking for new data.

Test: accessibility/aria-hidden-updates-alldescendants.html

* accessibility/AccessibilityObject.h:
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::ariaIsHidden):
(WebCore::AccessibilityRenderObject::childrenChanged):
(WebCore::AccessibilityRenderObject::addChildren):

LayoutTests:

* accessibility/aria-hidden-updates-alldescendants-expected.txt: Added.
* accessibility/aria-hidden-updates-alldescendants.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/accessibility/aria-hidden-updates-alldescendants-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/aria-hidden-updates-alldescendants.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/AccessibilityRenderObject.cpp

index d3f014c..e03649b 100644 (file)
@@ -1,3 +1,13 @@
+2011-09-07  Chris Fleizach  <cfleizach@apple.com>
+
+        Changes to aria-hidden don't change VO navigation
+        https://bugs.webkit.org/show_bug.cgi?id=67722
+
+        Reviewed by Darin Adler.
+
+        * accessibility/aria-hidden-updates-alldescendants-expected.txt: Added.
+        * accessibility/aria-hidden-updates-alldescendants.html: Added.
+
 2011-09-07  Nate Chapin  <japhet@chromium.org>
 
         Unreviewed, upstream some chromium expected failure after skia roll,
diff --git a/LayoutTests/accessibility/aria-hidden-updates-alldescendants-expected.txt b/LayoutTests/accessibility/aria-hidden-updates-alldescendants-expected.txt
new file mode 100644 (file)
index 0000000..a2fd5b9
--- /dev/null
@@ -0,0 +1,18 @@
+Steps
+
+test
+Step 1: Do something
+Step 2: Do another thing
+Step 3: Do one last thing
+This tests that if aria-hidden changes on an element, all it's existing children will update their children caches
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS main.childrenCount is 1
+PASS main.childrenCount is 2
+PASS main.childAtIndex(1).childrenCount is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/aria-hidden-updates-alldescendants.html b/LayoutTests/accessibility/aria-hidden-updates-alldescendants.html
new file mode 100644 (file)
index 0000000..064057d
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
+<script>
+var successfullyParsed = false;
+</script>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<div>
+        <h1 id="heading">Steps</h1>
+
+        <main id="main" tabindex=0>
+         test
+                <div tabindex="-1" class="step-one" aria-hidden="true"><span>Step 1: Do something</span></div>
+                <div tabindex="-1" class="step-two" aria-hidden="true"><span>Step 2: Do another thing</span></div>
+                <div tabindex="-1" class="step-three" aria-hidden="true"><span>Step 3: Do one last thing</span></div>
+        </main>
+
+</div>
+
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that if aria-hidden changes on an element, all it's existing children will update their children caches");
+
+    if (window.accessibilityController) {
+          document.getElementById("main").focus();
+          
+          var main = accessibilityController.focusedElement;
+          // Access the element so the children cache is generated.
+          main.childAtIndex(0);
+          main.childAtIndex(1);
+          shouldBe("main.childrenCount", "1");
+
+          var group = document.getElementsByTagName('main')[0];
+          var items = group.getElementsByTagName('div');          
+          items[0].removeAttribute('aria-hidden');
+
+          // After removing aria-hidden, the new count should be 2.
+          shouldBe("main.childrenCount", "2");          
+          
+          // And most importantly, the DIV that was made non-hidden should have one child now.
+          shouldBe("main.childAtIndex(1).childrenCount", "1");
+    }
+
+    successfullyParsed = true;
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index d85f726..1447463 100644 (file)
@@ -1,3 +1,25 @@
+2011-09-07  Chris Fleizach  <cfleizach@apple.com>
+
+        Changes to aria-hidden don't change VO navigation
+        https://bugs.webkit.org/show_bug.cgi?id=67722
+
+        Reviewed by Darin Adler.
+
+        When altering aria-hidden, WebCore needs to update the children caches of 
+        affected elements. However, for elements that were children, but ignored, their
+        caches did not get updated, and stale information would be propagated.
+
+        The fix is to always clearChildren() when a parent is asking for children. This 
+        ensures information is always up to date when the parent itself is asking for new data.
+
+        Test: accessibility/aria-hidden-updates-alldescendants.html
+
+        * accessibility/AccessibilityObject.h:
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::ariaIsHidden):
+        (WebCore::AccessibilityRenderObject::childrenChanged):
+        (WebCore::AccessibilityRenderObject::addChildren):
+
 2011-09-07  Tim Horton  <timothy_horton@apple.com>
 
         Text rendered with a simple (i.e. 0px blur) shadow inside a transparency layer has a double shadow
index 5998ba2..d114fe9 100644 (file)
@@ -550,6 +550,8 @@ public:
     virtual bool canHaveChildren() const { return true; }
     virtual bool hasChildren() const { return m_haveChildren; }
     virtual void updateChildrenIfNecessary();
+    virtual void clearChildren();
+
     virtual void selectedChildren(AccessibilityChildrenVector&) { }
     virtual void visibleChildren(AccessibilityChildrenVector&) { }
     virtual void tabChildren(AccessibilityChildrenVector&) { }
@@ -670,7 +672,6 @@ protected:
     mutable bool m_haveChildren;
     AccessibilityRole m_role;
     
-    virtual void clearChildren();
     virtual bool isDetached() const { return true; }
     
 #if PLATFORM(GTK)
index 85303f6..5bf3caf 100644 (file)
@@ -1702,7 +1702,7 @@ bool AccessibilityRenderObject::ariaIsHidden() const
     // aria-hidden hides this object and any children
     AccessibilityObject* object = parentObject();
     while (object) {
-        if (object->isAccessibilityRenderObject() && equalIgnoringCase(static_cast<AccessibilityRenderObject*>(object)->getAttribute(aria_hiddenAttr), "true"))
+        if (equalIgnoringCase(object->getAttribute(aria_hiddenAttr), "true"))
             return true;
         object = object->parentObject();
     }
@@ -3374,7 +3374,7 @@ void AccessibilityRenderObject::childrenChanged()
         if (!parent->isAccessibilityRenderObject())
             continue;
         
-        AccessibilityRenderObject* axParent = static_cast<AccessibilityRenderObject*>(parent);
+        AccessibilityRenderObject* axParent = toAccessibilityRenderObject(parent);
         
         // Send the children changed notification on the first accessibility render object ancestor.
         if (!sentChildrenChanged) {
@@ -3456,7 +3456,12 @@ void AccessibilityRenderObject::addChildren()
     // add all unignored acc children
     for (RefPtr<AccessibilityObject> obj = firstChild(); obj; obj = obj->nextSibling()) {
         if (obj->accessibilityIsIgnored()) {
-            obj->updateChildrenIfNecessary();
+
+            // If the parent is asking for this child's children, then either it's the first time (and clearing is a no-op), 
+            // or its visibility has changed. In the latter case, this child may have a stale child cached. 
+            // This can prevent aria-hidden changes from working correctly. Hence, whenever a parent is getting children, ensure data is not stale.
+            obj->clearChildren();
+            
             AccessibilityChildrenVector children = obj->children();
             unsigned length = children.size();
             for (unsigned i = 0; i < length; ++i)