Bug 1296420: Don't add node to DocAccessible's invalidation list if it's a target of aria-owns. r=surkov draft
authorMichael Li <michael.li11702@gmail.com>
Wed, 24 Aug 2016 16:54:54 -0400
changeset 405147 2a63b325ee269213a79227d10eb6df46ca287690
parent 403970 194fe275b4e60ded2af6b25173eec421f0dba8ad
child 529373 44937b5fccc1fa7735bf39b99822951dbe3b4e69
push id27412
push userbmo:mili@mozilla.com
push dateWed, 24 Aug 2016 22:49:42 +0000
reviewerssurkov
bugs1296420
milestone51.0a1
Bug 1296420: Don't add node to DocAccessible's invalidation list if it's a target of aria-owns. r=surkov MozReview-Commit-ID: tOCjCud8b0
accessible/generic/DocAccessible.cpp
accessible/tests/mochitest/events/a11y.ini
accessible/tests/mochitest/events/test_aria_owns.html
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1371,17 +1371,33 @@ DocAccessible::ProcessInvalidationList()
   // Invalidate children of container accessible for each element in
   // invalidation list. Allow invalidation list insertions while container
   // children are recached.
   for (uint32_t idx = 0; idx < mInvalidationList.Length(); idx++) {
     nsIContent* content = mInvalidationList[idx];
     if (!HasAccessible(content)) {
       Accessible* container = GetContainerAccessible(content);
       if (container) {
-        ProcessContentInserted(container, content);
+        // Check if the node is a target of aria-owns, and if so, don't process
+        // it here and let DoARIAOwnsRelocation process it.
+        AttrRelProviderArray* list =
+          mDependentIDsHash.Get(nsDependentAtomString(content->GetID()));
+        bool shouldProcess = !!list;
+        if (shouldProcess) {
+          for (uint32_t idx = 0; idx < list->Length(); idx++) {
+            if (list->ElementAt(idx)->mRelAttr == nsGkAtoms::aria_owns) {
+              shouldProcess = false;
+              break;
+            }
+          }
+
+          if (shouldProcess) {
+            ProcessContentInserted(container, content);
+          }
+        }
       }
     }
   }
 
   mInvalidationList.Clear();
 }
 
 Accessible*
--- a/accessible/tests/mochitest/events/a11y.ini
+++ b/accessible/tests/mochitest/events/a11y.ini
@@ -4,16 +4,17 @@ support-files =
   focus.html
   scroll.html
   !/accessible/tests/mochitest/*.js
   !/accessible/tests/mochitest/letters.gif
 
 [test_aria_alert.html]
 [test_aria_menu.html]
 [test_aria_objattr.html]
+[test_aria_owns.html]
 [test_aria_statechange.html]
 [test_attrs.html]
 [test_caretmove.html]
 [test_caretmove.xul]
 [test_coalescence.html]
 [test_contextmenu.html]
 [test_descrchange.html]
 [test_docload.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/test_aria_owns.html
@@ -0,0 +1,129 @@
+<html>
+
+<head>
+  <title>Aria-owns targets shouldn't be on invalidation list so shouldn't have
+         show/hide events</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Do tests.
+
+    //gA11yEventDumpToConsole = true; // debug stuff
+    //enableLogging("tree,eventTree,verbose");
+
+    /**
+     * Aria-owns target shouldn't have a show event.
+     * Markup:
+     * <div id="t1_fc" aria-owns="t1_owns"></div>
+     * <span id="t1_owns"></div>
+     */
+    function testAriaOwns()
+    {
+      this.parent = getNode("t1");
+      this.fc = document.createElement("div");
+      this.fc.setAttribute("id", "t1_fc");
+      this.owns = document.createElement("span");
+      this.owns.setAttribute("id", "t1_owns");
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, this.fc),
+        new unexpectedInvokerChecker(EVENT_SHOW, this.owns)
+      ];
+
+      this.invoke = function testAriaOwns_invoke()
+      {
+        getNode("t1").appendChild(this.fc);
+        getNode("t1").appendChild(this.owns);
+        getNode("t1_fc").setAttribute("aria-owns", "t1_owns");
+      };
+
+      this.getID = function testAriaOwns_getID() {
+        return "Aria-owns target shouldn't have show event";
+      };
+    }
+
+    /**
+     * Target of both aria-owns and other aria attribute like aria-labelledby
+     * shouldn't have a show event.
+     * Markup:
+     * <div id="t2_fc" aria-owns="t1_owns"></div>
+     * <div id="t2_sc" aria-labelledby="t2_owns"></div>
+     * <span id="t2_owns"></div>
+     */
+    function testAriaOwnsAndLabelledBy()
+    {
+      this.parent = getNode("t2");
+      this.fc = document.createElement("div");
+      this.fc.setAttribute("id", "t2_fc");
+      this.sc = document.createElement("div");
+      this.sc.setAttribute("id", "t2_sc");
+      this.owns = document.createElement("span");
+      this.owns.setAttribute("id", "t2_owns");
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, this.fc),
+        new invokerChecker(EVENT_SHOW, this.sc),
+        new unexpectedInvokerChecker(EVENT_SHOW, this.owns)
+      ];
+
+      this.invoke = function testAriaOwns_invoke()
+      {
+        getNode("t2").appendChild(this.fc);
+        getNode("t2").appendChild(this.sc);
+        getNode("t2").appendChild(this.owns);
+        getNode("t2_fc").setAttribute("aria-owns", "t2_owns");
+        getNode("t2_sc").setAttribute("aria-labelledby", "t2_owns");
+      };
+
+      this.getID = function testAriaOwns_getID() {
+        return "Aria-owns and aria-labelledby target shouldn't have show event";
+      };
+    }
+
+    var gQueue = null;
+    function doTests()
+    {
+      gQueue = new eventQueue();
+      gQueue.push(new testAriaOwns());
+      gQueue.push(new testAriaOwnsAndLabelledBy());
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=1296420"
+     title="Aria-owns targets shouldn't be on invalidation list so shouldn't
+            have show/hide events">
+    Mozilla Bug 1296420
+  </a><br>
+
+  <div id="testContainer">
+    <div id="t1"></div>
+
+    <div id="t2"></div>
+  </div>
+
+</body>
+</html>