Bug 1263188 - fix event tree coalescence, part4, r=yzen
authorAlexander Surkov <surkov.alexander@gmail.com>
Thu, 14 Apr 2016 07:46:58 -0400
changeset 331131 6500ef91810315bd2a4103b0b9ada0207c2b3686
parent 331130 97c95a625a6fe8a160409ef3f603b783565c262c
child 331132 0eb8cf4e5b9283b3be5a5a6b3c5aab1ec927718a
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1263188
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 1263188 - fix event tree coalescence, part4, r=yzen
accessible/base/EventTree.cpp
accessible/tests/mochitest/events/test_coalescence.html
--- a/accessible/base/EventTree.cpp
+++ b/accessible/base/EventTree.cpp
@@ -180,17 +180,20 @@ TreeMutation::Done()
 ////////////////////////////////////////////////////////////////////////////////
 // EventTree
 
 void
 EventTree::Process()
 {
   EventTree* node = mFirst;
   while (node) {
-    node->Process();
+    // Skip a node and its subtree if its container is not in the document.
+    if (node->mContainer->IsInDocument()) {
+      node->Process();
+    }
     node = node->mNext;
   }
 
   MOZ_ASSERT(mContainer || mDependentEvents.IsEmpty(),
              "No container, no events");
   MOZ_ASSERT(!mContainer || !mContainer->IsDefunct(),
              "Processing events for defunct container");
 
@@ -332,17 +335,17 @@ EventTree::FindOrInsert(Accessible* aCon
   } while ((node = node->mNext));
 
   MOZ_ASSERT(prevNode, "Nowhere to insert");
   MOZ_ASSERT(!prevNode->mNext, "Taken by another node");
 
   // If 'this' node contains the given container accessible, then
   //   do not emit a reorder event for the container
   //   if a dependent show event target contains the given container then do not
-  //      emit show / hide events (to be done)
+  //   emit show / hide events (see Process() method)
 
   return prevNode->mNext = new EventTree(aContainer, mDependentEvents.IsEmpty());
 }
 
 void
 EventTree::Clear()
 {
   mFirst = nullptr;
--- a/accessible/tests/mochitest/events/test_coalescence.html
+++ b/accessible/tests/mochitest/events/test_coalescence.html
@@ -23,24 +23,21 @@
     ////////////////////////////////////////////////////////////////////////////
     // Invoker base classes
 
     const kRemoveElm = 1;
     const kHideElm = 2;
     const kAddElm = 3;
     const kShowElm = 4;
 
-    const kToDo = true;
-
     /**
      * Base class to test of mutation events coalescence.
      */
     function coalescenceBase(aChildAction, aParentAction,
-                             aPerformActionOnChildInTheFirstPlace,
-                             aIsChildsToDo)
+                             aPerformActionOnChildInTheFirstPlace)
     {
       // Invoker interface
 
       this.invoke = function coalescenceBase_invoke()
       {
         if (aPerformActionOnChildInTheFirstPlace) {
           this.invokeAction(this.childNode, aChildAction);
           this.invokeAction(this.parentNode, aParentAction);
@@ -58,23 +55,22 @@
         if (aPerformActionOnChildInTheFirstPlace)
           return childAction + " and then " + parentAction;
 
         return parentAction + " and then " + childAction;
       }
 
       this.finalCheck = function coalescenceBase_check()
       {
-        if (!aIsChildsToDo)
-          return;
-
-        var eventType = eventTypeToString(this.getEventType(aChildAction));
-        todo(false,
-             "Unexpected event " + eventType +
-             " for child in the test '" + this.getID() + "'");
+        if (this.getEventType(aChildAction) == EVENT_HIDE) {
+          testIsDefunct(this.child);
+        }
+        if (this.getEventType(aParentAction) == EVENT_HIDE) {
+          testIsDefunct(this.parent);
+        }
       }
 
       // Implementation details
 
       this.invokeAction = function coalescenceBase_invokeAction(aNode, aAction)
       {
         switch (aAction) {
           case kRemoveElm:
@@ -133,47 +129,39 @@
         var eventType = this.getEventType(aParentAction);
         this.eventSeq = [
           new invokerChecker(eventType, this.parentNode),
           new invokerChecker(EVENT_REORDER, this.hostNode)
         ];
 
         // unexpected events
         this.unexpectedEventSeq = [
+          new invokerChecker(this.getEventType(aChildAction), this.childNode),
           new invokerChecker(EVENT_REORDER, this.parentNode)
         ];
-
-        if (!aIsChildsToDo) {
-          var eventType = this.getEventType(aChildAction);
-          var checker = new invokerChecker(eventType, this.childNode);
-          this.unexpectedEventSeq.unshift(checker);
-        }
       }
     }
 
     /**
      * Remove or hide mutation events coalescence testing.
      */
     function removeOrHideCoalescenceBase(aChildID, aParentID,
                                          aChildAction, aParentAction,
-                                         aPerformActionOnChildInTheFirstPlace,
-                                         aIsChildsToDo)
+                                         aPerformActionOnChildInTheFirstPlace)
     {
       this.__proto__ = new coalescenceBase(aChildAction, aParentAction,
-                                           aPerformActionOnChildInTheFirstPlace,
-                                           aIsChildsToDo);
+                                           aPerformActionOnChildInTheFirstPlace);
 
       this.init = function removeOrHideCoalescenceBase_init()
       {
         this.childNode = getNode(aChildID);
         this.parentNode = getNode(aParentID);
+        this.child = getAccessible(this.childNode);
+        this.parent = getAccessible(this.parentNode);
         this.hostNode = this.parentNode.parentNode;
-
-        // ensure child accessible is created
-        getAccessible(this.childNode);
       }
 
       // Initalization
 
       this.init();
       this.initSequence();
     }
 
@@ -182,17 +170,17 @@
 
     /**
      * Remove child node and then its parent node from DOM tree.
      */
     function removeChildNParent(aChildID, aParentID)
     {
       this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
                                                        kRemoveElm, kRemoveElm,
-                                                       true, kToDo);
+                                                       true);
     }
 
     /**
      * Remove parent node and then its child node from DOM tree.
      */
     function removeParentNChild(aChildID, aParentID)
     {
       this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
@@ -230,33 +218,29 @@
                                                        true);
     }
 
     /**
      * Hide parent node and then remove its child node.
      */
     function hideParentNRemoveChild(aChildID, aParentID)
     {
-      // Because of async layout changes we handle remove child node change
-      // before than hide parent node change even we hide parent before we
-      // remove a child. Therefore mark this as todo until we have more smart
-      // events coalescence.
       this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
                                                        kRemoveElm, kHideElm,
-                                                       false, kToDo);
+                                                       false);
     }
 
     /**
      * Remove child node and then hide its parent node.
      */
     function removeChildNHideParent(aChildID, aParentID)
     {
       this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
                                                        kRemoveElm, kHideElm,
-                                                       true, kToDo);
+                                                       true);
     }
 
     /**
      * Remove parent node and then hide its child node.
      */
     function removeParentNHideChild(aChildID, aParentID)
     {
       this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,