Bug 1255617 - make PutChildrenBack to insert accessibles instead the recaching, r=yzen
authorAlexander Surkov <surkov.alexander@gmail.com>
Wed, 30 Mar 2016 10:47:36 -0400
changeset 290897 9f60a89fb3407e9ba100c34ebe90ccaf16cdd67f
parent 290896 57a583c7c3107d396c1c5a51bc7a248c452f21a7
child 290898 6e3cc6cb10cb3933cd95a0decbc15370cef3fc18
push id74418
push usersurkov.alexander@gmail.com
push dateWed, 30 Mar 2016 14:47:46 +0000
treeherdermozilla-inbound@9f60a89fb340 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1255617
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1255617 - make PutChildrenBack to insert accessibles instead the recaching, r=yzen
accessible/generic/DocAccessible.cpp
accessible/tests/mochitest/treeupdate/test_ariaowns.html
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -2277,55 +2277,78 @@ DocAccessible::MoveChild(Accessible* aCh
 
 void
 DocAccessible::PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren,
                                uint32_t aStartIdx)
 {
   nsTArray<RefPtr<Accessible> > containers;
   for (auto idx = aStartIdx; idx < aChildren->Length(); idx++) {
     Accessible* child = aChildren->ElementAt(idx);
+    if (!child->IsInDocument()) {
+      continue;
+    }
 
-    // If the child is in the tree then remove it from the owner.
-    if (child->IsInDocument()) {
-      Accessible* owner = child->Parent();
-      if (!owner) {
-        NS_ERROR("Cannot put the child back. No parent, a broken tree.");
-        continue;
-      }
-      RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
-      RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(child, false);
-      reorderEvent->AddSubMutationEvent(hideEvent);
-      FireDelayedEvent(hideEvent);
+    // Remove the child from the owner
+    Accessible* owner = child->Parent();
+    if (!owner) {
+      NS_ERROR("Cannot put the child back. No parent, a broken tree.");
+      continue;
+    }
 
-      {
-        AutoTreeMutation mut(owner);
-        owner->RemoveChild(child);
-        child->SetRelocated(false);
-      }
+#ifdef A11Y_LOG
+    logging::TreeInfo("aria owns put child back", 0,
+                      "old parent", owner, "child", child, nullptr);
+#endif
 
-      MaybeNotifyOfValueChange(owner);
-      FireDelayedEvent(reorderEvent);
+    RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
+    RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(child, false);
+    reorderEvent->AddSubMutationEvent(hideEvent);
+    FireDelayedEvent(hideEvent);
+
+    {
+      AutoTreeMutation mut(owner);
+      owner->RemoveChild(child);
+      child->SetRelocated(false);
     }
 
-    Accessible* container = GetContainerAccessible(child->GetContent());
-    if (container &&
-        containers.IndexOf(container) == nsTArray<Accessible*>::NoIndex) {
-      containers.AppendElement(container);
+    MaybeNotifyOfValueChange(owner);
+    FireDelayedEvent(reorderEvent);
+
+#ifdef A11Y_LOG
+    logging::TreeInfo("aria owns put child back: old parent tree after",
+                      logging::eVerbose, owner);
+#endif
+
+    // and put it back where it belongs to.
+    Accessible* origContainer = GetContainerAccessible(child->GetContent());
+    if (origContainer) {
+      TreeWalker walker(origContainer);
+      if (walker.Seek(child->GetContent())) {
+        Accessible* prevChild = walker.Prev();
+        {
+          AutoTreeMutation mut(origContainer);
+          origContainer->InsertAfter(child, prevChild);
+        }
+
+        RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(origContainer);
+        RefPtr<AccMutationEvent> showEvent = new AccShowEvent(child);
+        reorderEvent->AddSubMutationEvent(showEvent);
+        FireDelayedEvent(showEvent);
+        MaybeNotifyOfValueChange(origContainer);
+        FireDelayedEvent(reorderEvent);
+
+#ifdef A11Y_LOG
+        logging::TreeInfo("aria owns put child back: new parent tree after",
+                          logging::eVerbose, origContainer);
+#endif
+      }
     }
   }
 
-  // And put it back where it belongs to.
   aChildren->RemoveElementsAt(aStartIdx, aChildren->Length() - aStartIdx);
-  for (uint32_t idx = 0; idx < containers.Length(); idx++) {
-    NS_ASSERTION(containers[idx]->IsInDocument(),
-                 "A container has been destroyed.");
-    if (containers[idx]->IsInDocument()) {
-      UpdateTreeOnInsertion(containers[idx]);
-    }
-  }
 }
 
 void
 DocAccessible::CacheChildrenInSubtree(Accessible* aRoot,
                                       Accessible** aFocusedAcc)
 {
   // If the accessible is focused then report a focus event after all related
   // mutation events.
--- a/accessible/tests/mochitest/treeupdate/test_ariaowns.html
+++ b/accessible/tests/mochitest/treeupdate/test_ariaowns.html
@@ -69,18 +69,18 @@
         return "Change @aria-owns attribute";
       }
     }
 
     function removeARIAOwns()
     {
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, getNode("t1_button")),
+        new invokerChecker(EVENT_SHOW, getNode("t1_button")),
         new invokerChecker(EVENT_HIDE, getNode("t1_subdiv")),
-        new invokerChecker(EVENT_SHOW, getNode("t1_button")),
         new invokerChecker(EVENT_SHOW, getNode("t1_subdiv")),
         new invokerChecker(EVENT_REORDER, getNode("t1_container"))
       ];
 
       this.invoke = function removeARIAOwns_invoke()
       {
         getNode("t1_container").removeAttribute("aria-owns");
       }