Bug 1255614 - make ProcessInvalidationList to insert accessibles instead the recaching, r=yzen
authorAlexander Surkov <surkov.alexander@gmail.com>
Tue, 29 Mar 2016 09:20:43 -0400
changeset 290925 f0574554378bfa00569f243399bd14414592d9b2
parent 290924 187f53033554684b8f5cb00a548262d7fc46ed22
child 290926 e93f8207a0b8a7c285fcf315e2a45c3a27c021a0
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
bugs1255614
milestone48.0a1
Bug 1255614 - make ProcessInvalidationList to insert accessibles instead the recaching, r=yzen
accessible/generic/DocAccessible.cpp
accessible/generic/DocAccessible.h
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -1385,18 +1385,31 @@ 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)
-        UpdateTreeOnInsertion(container);
+      if (container) {
+        TreeWalker walker(container);
+        if (container->IsAcceptableChild(content) && walker.Seek(content)) {
+          Accessible* child =
+            GetAccService()->GetOrCreateAccessible(content, container);
+          if (child) {
+            AutoTreeMutation mMut(container);
+            RefPtr<AccReorderEvent> reorderEvent =
+              new AccReorderEvent(container);
+            container->InsertAfter(child, walker.Prev());
+            uint32_t flags = UpdateTreeInternal(child, true, reorderEvent);
+            FireEventsOnInsertion(container, reorderEvent, flags);
+          }
+        }
+      }
     }
   }
 
   mInvalidationList.Clear();
 }
 
 Accessible*
 DocAccessible::GetAccessibleEvenIfNotInMap(nsINode* aNode) const
@@ -1829,37 +1842,45 @@ DocAccessible::ProcessContentInserted(Ac
     MOZ_ASSERT_UNREACHABLE("accessible was rejected");
   }
 
 #ifdef A11Y_LOG
   logging::TreeInfo("children after insertion", logging::eVerbose,
                     aContainer);
 #endif
 
+  FireEventsOnInsertion(aContainer, reorderEvent, updateFlags);
+}
+
+void
+DocAccessible::FireEventsOnInsertion(Accessible* aContainer,
+                                     AccReorderEvent* aReorderEvent,
+                                     uint32_t aUpdateFlags)
+{
   // Content insertion did not cause an accessible tree change.
-  if (updateFlags == eNoAccessible) {
+  if (aUpdateFlags == eNoAccessible) {
     return;
   }
 
   // Check to see if change occurred inside an alert, and fire an EVENT_ALERT
   // if it did.
-  if (!(updateFlags & eAlertAccessible) &&
+  if (!(aUpdateFlags & eAlertAccessible) &&
       (aContainer->IsAlert() || aContainer->IsInsideAlert())) {
     Accessible* ancestor = aContainer;
     do {
       if (ancestor->IsAlert()) {
         FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor);
         break;
       }
     }
     while ((ancestor = ancestor->Parent()));
   }
 
   MaybeNotifyOfValueChange(aContainer);
-  FireDelayedEvent(reorderEvent);
+  FireDelayedEvent(aReorderEvent);
 }
 
 void
 DocAccessible::UpdateTreeOnInsertion(Accessible* aContainer)
 {
   for (uint32_t idx = 0; idx < aContainer->ContentChildCount(); idx++) {
     Accessible* child = aContainer->ContentChildAt(idx);
     child->SetSurvivingInUpdate(true);
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -182,16 +182,19 @@ public:
   DocAccessible* GetChildDocumentAt(uint32_t aIndex) const
     { return mChildDocuments.SafeElementAt(aIndex, nullptr); }
 
   /**
    * Fire accessible event asynchronously.
    */
   void FireDelayedEvent(AccEvent* aEvent);
   void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget);
+  void FireEventsOnInsertion(Accessible* aContainer,
+                             AccReorderEvent* aReorderEvent,
+                             uint32_t aUpdateFlags);
 
   /**
    * Fire value change event on the given accessible if applicable.
    */
   void MaybeNotifyOfValueChange(Accessible* aAccessible);
 
   /**
    * Get/set the anchor jump.