Bug 906684, make sure to access the right EventTargetChainItem when forwarding events to chrome, r=jst
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 20 Aug 2013 00:12:56 +0300
changeset 156043 bb025b6949e88dc58b47bd614b49d1e5f20141d3
parent 156042 e2c977148d7ab6d6f14432f0890cc856e256f280
child 156044 339c0e4de6f7dcb13e22667a7e3f0e50121ab23b
child 156094 c98aa0d00ade8beee2b98b9b664cda44c16b0360
child 156108 cfa0c423b1d77755b206f194799a250263a75dac
child 156474 9d9eab84d2e7b1a067fa4613ee5c949056c2d44a
child 170232 1de256e3ce917a787e207e68d0e39d9e903750d8
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs906684
milestone26.0a1
first release with
nightly linux32
bb025b6949e8 / 26.0a1 / 20130820030206 / files
nightly linux64
bb025b6949e8 / 26.0a1 / 20130820030206 / files
nightly mac
bb025b6949e8 / 26.0a1 / 20130820030206 / files
nightly win32
bb025b6949e8 / 26.0a1 / 20130820030206 / files
nightly win64
bb025b6949e8 / 26.0a1 / 20130820030206 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 906684, make sure to access the right EventTargetChainItem when forwarding events to chrome, r=jst
content/events/src/nsEventDispatcher.cpp
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -456,16 +456,17 @@ nsEventDispatcher::Dispatch(nsISupports*
   // event dispatching is finished.
   nsRefPtr<nsPresContext> kungFuDeathGrip(aPresContext);
 
   nsTArray<nsEventTargetChainItem> chain(128);
 
   // Create the event target chain item for the event target.
   nsEventTargetChainItem* targetEtci =
     nsEventTargetChainItem::Create(chain, target->GetTargetForEventTargetChain());
+  MOZ_ASSERT(&chain[0] == targetEtci);
   if (!targetEtci->IsValid()) {
     nsEventTargetChainItem::DestroyLast(chain, targetEtci);
     return NS_ERROR_FAILURE;
   }
 
   // Make sure that nsIDOMEvent::target and nsIDOMEvent::originalTarget
   // point to the last item in the chain.
   if (!aEvent->target) {
@@ -503,24 +504,26 @@ nsEventDispatcher::Dispatch(nsISupports*
                                     isInAnon);
   targetEtci->PreHandleEvent(preVisitor);
 
   if (!preVisitor.mCanHandle && preVisitor.mAutomaticChromeDispatch && content) {
     // Event target couldn't handle the event. Try to propagate to chrome.
     nsEventTargetChainItem::DestroyLast(chain, targetEtci);
     targetEtci = EventTargetChainItemForChromeTarget(chain, content);
     NS_ENSURE_STATE(targetEtci);
+    MOZ_ASSERT(&chain[0] == targetEtci);
     targetEtci->PreHandleEvent(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->target);
     targetEtci->SetNewTarget(t);
     nsEventTargetChainItem* topEtci = targetEtci;
+    targetEtci = nullptr;
     while (preVisitor.mParentTarget) {
       EventTarget* parentTarget = preVisitor.mParentTarget;
       nsEventTargetChainItem* parentEtci =
         nsEventTargetChainItem::Create(chain, preVisitor.mParentTarget, topEtci);
       if (!parentEtci->IsValid()) {
         nsEventTargetChainItem::DestroyLast(chain, parentEtci);
         rv = NS_ERROR_FAILURE;
         break;
@@ -546,17 +549,17 @@ nsEventDispatcher::Dispatch(nsISupports*
           nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
           if (disabledTarget) {
             parentEtci = EventTargetChainItemForChromeTarget(chain,
                                                              disabledTarget,
                                                              topEtci);
             if (parentEtci) {
               parentEtci->PreHandleEvent(preVisitor);
               if (preVisitor.mCanHandle) {
-                targetEtci->SetNewTarget(parentTarget);
+                chain[0].SetNewTarget(parentTarget);
                 topEtci = parentEtci;
                 continue;
               }
             }
           }
         }
         break;
       }
@@ -586,18 +589,16 @@ nsEventDispatcher::Dispatch(nsISupports*
         }
       }
     }
   }
 
   // Note, nsEventTargetChainItem objects are deleted when the chain goes out of
   // the scope.
 
-  targetEtci = nullptr;
-
   aEvent->mFlags.mIsBeingDispatched = false;
   aEvent->mFlags.mDispatchedAtLeastOnce = true;
 
   if (!externalDOMEvent && preVisitor.mDOMEvent) {
     // An nsDOMEvent was created while dispatching the event.
     // Duplicate private data if someone holds a pointer to it.
     nsrefcnt rc = 0;
     NS_RELEASE2(preVisitor.mDOMEvent, rc);