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 291074 9f60a89fb3407e9ba100c34ebe90ccaf16cdd67f
parent 291073 57a583c7c3107d396c1c5a51bc7a248c452f21a7
child 291075 6e3cc6cb10cb3933cd95a0decbc15370cef3fc18
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1255617
milestone48.0a1
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");
       }