Bug 1305458 Part3: Add EventTargetChainItem::GetFirstEventTarget. r=smaug
authorStone Shih <sshih@mozilla.com>
Sat, 22 Oct 2016 09:21:40 +0800
changeset 323074 ec4c31d96593226bb42aad94b0d95aa24972ea8a
parent 323073 d6c53113dd779d7e2a6f66d4503bf5e6e33f8644
child 323075 fdf729308c4042a06e050da49de50c2ead150ca3
push id30967
push userphilringnalda@gmail.com
push dateFri, 18 Nov 2016 03:21:38 +0000
treeherdermozilla-central@8e476f8bd52d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1305458
milestone53.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 1305458 Part3: Add EventTargetChainItem::GetFirstEventTarget. r=smaug MozReview-Commit-ID: 7EuGKsG9maX
dom/events/EventDispatcher.cpp
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -161,16 +161,27 @@ public:
   static void DestroyLast(nsTArray<EventTargetChainItem>& aChain,
                           EventTargetChainItem* aItem)
   {
     uint32_t lastIndex = aChain.Length() - 1;
     MOZ_ASSERT(&aChain[lastIndex] == aItem);
     aChain.RemoveElementAt(lastIndex);
   }
 
+  static EventTargetChainItem* GetFirstEventTarget(
+                                 nsTArray<EventTargetChainItem>& aChain)
+  {
+    return &aChain[0];
+  }
+
+  static uint32_t GetFirstEventTargetIdx(nsTArray<EventTargetChainItem>& aChain)
+  {
+    return 0;
+  }
+
   bool IsValid()
   {
     NS_WARNING_ASSERTION(!!(mTarget), "Event target is not valid!");
     return !!(mTarget);
   }
 
   EventTarget* GetNewTarget()
   {
@@ -371,21 +382,23 @@ EventTargetChainItem::HandleEventTargetC
                         nsTArray<EventTargetChainItem>& aChain,
                         EventChainPostVisitor& aVisitor,
                         EventDispatchingCallback* aCallback,
                         ELMCreationDetector& aCd)
 {
   // Save the target so that it can be restored later.
   nsCOMPtr<EventTarget> firstTarget = aVisitor.mEvent->mTarget;
   uint32_t chainLength = aChain.Length();
+  uint32_t firstEventTargetIdx =
+    EventTargetChainItem::GetFirstEventTargetIdx(aChain);
 
   // Capture
   aVisitor.mEvent->mFlags.mInCapturePhase = true;
   aVisitor.mEvent->mFlags.mInBubblingPhase = false;
-  for (uint32_t i = chainLength - 1; i > 0; --i) {
+  for (uint32_t i = chainLength - 1; i > firstEventTargetIdx; --i) {
     EventTargetChainItem& item = aChain[i];
     if ((!aVisitor.mEvent->mFlags.mNoContentDispatch ||
          item.ForceContentDispatch()) &&
         !aVisitor.mEvent->PropagationStopped()) {
       item.HandleEvent(aVisitor, aCd);
     }
 
     if (item.GetNewTarget()) {
@@ -398,29 +411,29 @@ EventTargetChainItem::HandleEventTargetC
           break;
         }
       }
     }
   }
 
   // Target
   aVisitor.mEvent->mFlags.mInBubblingPhase = true;
-  EventTargetChainItem& targetItem = aChain[0];
+  EventTargetChainItem& targetItem = aChain[firstEventTargetIdx];
   if (!aVisitor.mEvent->PropagationStopped() &&
       (!aVisitor.mEvent->mFlags.mNoContentDispatch ||
        targetItem.ForceContentDispatch())) {
     targetItem.HandleEvent(aVisitor, aCd);
   }
   if (aVisitor.mEvent->mFlags.mInSystemGroup) {
     targetItem.PostHandleEvent(aVisitor);
   }
 
   // Bubble
   aVisitor.mEvent->mFlags.mInCapturePhase = false;
-  for (uint32_t i = 1; i < chainLength; ++i) {
+  for (uint32_t i = firstEventTargetIdx + 1; i < chainLength; ++i) {
     EventTargetChainItem& item = aChain[i];
     EventTarget* newTarget = item.GetNewTarget();
     if (newTarget) {
       // Item is at anonymous boundary. Need to retarget for the current item
       // and for parent items.
       aVisitor.mEvent->mTarget = newTarget;
     }
 
@@ -667,17 +680,16 @@ EventDispatcher::Dispatch(nsISupports* a
                                   isInAnon);
   targetEtci->GetEventTargetParent(preVisitor);
 
   if (!preVisitor.mCanHandle && preVisitor.mAutomaticChromeDispatch && content) {
     // Event target couldn't handle the event. Try to propagate to chrome.
     EventTargetChainItem::DestroyLast(chain, targetEtci);
     targetEtci = EventTargetChainItemForChromeTarget(chain, content);
     NS_ENSURE_STATE(targetEtci);
-    MOZ_ASSERT(&chain[0] == targetEtci);
     targetEtci->GetEventTargetParent(preVisitor);
   }
   if (preVisitor.mCanHandle) {
     // At least the original target can handle the event.
     // Setting the retarget to the |target| simplifies retargeting code.
     nsCOMPtr<EventTarget> t = do_QueryInterface(aEvent->mTarget);
     targetEtci->SetNewTarget(t);
     EventTargetChainItem* topEtci = targetEtci;
@@ -712,17 +724,17 @@ EventDispatcher::Dispatch(nsISupports* a
           nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
           if (disabledTarget) {
             parentEtci = EventTargetChainItemForChromeTarget(chain,
                                                              disabledTarget,
                                                              topEtci);
             if (parentEtci) {
               parentEtci->GetEventTargetParent(preVisitor);
               if (preVisitor.mCanHandle) {
-                chain[0].SetNewTarget(parentTarget);
+                EventTargetChainItem::GetFirstEventTarget(chain)->SetNewTarget(parentTarget);
                 topEtci = parentEtci;
                 continue;
               }
             }
           }
         }
         break;
       }