Bug 541474 - make events coalescing smarter, r=ginn, davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Wed, 27 Jan 2010 19:45:32 +0800
changeset 37540 0c9bf70733adae2b6fdacaf5a0c10405855e0c43
parent 37539 202a07f8110bba0174a10c4ad5896bfd93858696
child 37542 51caa47ea5bd9d657af20e7eb5cd32df375b588a
push id11366
push usersurkov.alexander@gmail.com
push dateWed, 27 Jan 2010 11:47:36 +0000
treeherdermozilla-central@0c9bf70733ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersginn, davidb
bugs541474
milestone1.9.3a1pre
Bug 541474 - make events coalescing smarter, r=ginn, davidb
accessible/src/base/nsEventShell.cpp
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -248,51 +248,87 @@ nsAccEventQueue::CoalesceEvents()
             CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
             continue;
           }
 
           // Dupe
           thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
           continue;
         }
-        if (nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
-          // thisDOMNode is a descendant of tailDOMNode
+
+        // More older show event target (thisNode) can't be contained by recent
+        // show event target (tailNode), i.e be a descendant of tailNode.
+        // XXX: target of older show event caused by DOM node appending can be
+        // contained by target of recent show event caused by style change.
+        // XXX: target of older show event caused by style change can be
+        // contained by target of recent show event caused by style change.
+        PRBool thisCanBeDescendantOfTail =
+          tailEvent->mEventType != nsIAccessibleEvent::EVENT_SHOW ||
+          tailEvent->mIsAsync;
+
+        if (thisCanBeDescendantOfTail &&
+            nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
+          // thisNode is a descendant of tailNode.
+
           if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
             CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
             continue;
           }
 
-          // Do not emit thisEvent, also apply this result to sibling
-          // nodes of thisDOMNode.
+          // Do not emit thisEvent, also apply this result to sibling nodes of
+          // thisNode.
           thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
           ApplyToSiblings(0, index, thisEvent->mEventType,
                           thisEvent->mNode, nsAccEvent::eDoNotEmit);
           continue;
         }
-        if (nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
-          // tailDOMNode is a descendant of thisDOMNode
+
+#ifdef DEBUG
+        if (!thisCanBeDescendantOfTail &&
+            nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
+          NS_NOTREACHED("Older event target is a descendant of recent event target!");
+        }
+#endif
+
+        // More older hide event target (thisNode) can't contain recent hide
+        // event target (tailNode), i.e. be ancestor of tailNode.
+        if (tailEvent->mEventType != nsIAccessibleEvent::EVENT_HIDE &&
+            nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
+          // tailNode is a descendant of thisNode
+
           if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
             CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
             continue;
           }
 
-          // Do not emit tailEvent, also apply this result to sibling
-          // nodes of tailDOMNode.
+          // Do not emit tailEvent, also apply this result to sibling nodes of
+          // tailNode.
           tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
           ApplyToSiblings(0, tail, tailEvent->mEventType,
                           tailEvent->mNode, nsAccEvent::eDoNotEmit);
           break;
         }
+
+#ifdef DEBUG
+        if (tailEvent->mEventType == nsIAccessibleEvent::EVENT_HIDE &&
+            nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
+          NS_NOTREACHED("More older hide event target is an ancestor of recent hide event target!");
+        }
+#endif
+
       } // for (index)
 
       if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
-        // Not in another event node's subtree, and no other event is in
-        // this event node's subtree.
-        // This event should be emitted
-        // Apply this result to sibling nodes of tailDOMNode
+        // Not in another event node's subtree, and no other event is in this
+        // event node's subtree. This event should be emitted. Apply this result
+        // to sibling nodes of tailNode.
+
+        // We should do this in all cases even when tailEvent is hide event and
+        // it's caused by DOM node removal because the rule can applied for
+        // sibling event targets caused by style changes.
         ApplyToSiblings(0, tail, tailEvent->mEventType,
                         tailEvent->mNode, nsAccEvent::eAllowDupes);
       }
     } break; // case eCoalesceFromSameSubtree
 
     case nsAccEvent::eRemoveDupes:
     {
       // Check for repeat events.