Bug 1466208 - part 31: Create a PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell() overload r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 05 Mar 2019 06:09:02 +0000
changeset 520415 5b5c05af88e26abb051604aa0ff4256ce980f588
parent 520414 7f51bc3757d9d196730d75d719199b29c21fbe0b
child 520416 5edf9199407cff51e09fda265ed3fe4f1386e1cb
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1466208
milestone67.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 1466208 - part 31: Create a PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell() overload r=smaug If focused element is in another document, `PresShell::EventHandler::HandleEvent()` needs to retarget the event to another `PresShell`. This patch moves the case into new overload method, `MaybeHandleEventWithAnotherPresShell()`. Additionally, removes `PresShell::HandleRetargetedEvent()` and makes `EventHandler::HandleRetargetedEvent()` non-public because the new method is the only user of them. Differential Revision: https://phabricator.services.mozilla.com/D21196
layout/base/PresShell.cpp
layout/base/PresShell.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6535,50 +6535,44 @@ nsresult PresShell::EventHandler::Handle
       // Keypress events in new blank tabs should not be completely thrown away.
       // Retarget them -- the parent chrome shell might make use of them.
       return RetargetEventToParent(aGUIEvent, aEventStatus);
     }
 
     return NS_OK;
   }
 
-  nsresult rv = NS_OK;
-
   AutoCurrentEventInfoSetter eventInfoSetter(*this);
 
   if (aGUIEvent->IsTargetedAtFocusedContent()) {
     mPresShell->mCurrentEventContent = nullptr;
 
     RefPtr<Element> eventTargetElement =
         ComputeFocusedEventTargetElement(aGUIEvent);
 
     mPresShell->mCurrentEventFrame = nullptr;
-    Document* targetDoc =
-        eventTargetElement ? eventTargetElement->OwnerDoc() : nullptr;
-    if (targetDoc && targetDoc != GetDocument()) {
-      nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell();
-      if (shell) {
-        rv = static_cast<PresShell*>(shell.get())
-                 ->HandleRetargetedEvent(aGUIEvent, aEventStatus,
-                                         eventTargetElement);
-      }
-      return rv;
-    } else {
-      mPresShell->mCurrentEventContent = eventTargetElement;
-    }
+    if (eventTargetElement) {
+      nsresult rv = NS_OK;
+      if (MaybeHandleEventWithAnotherPresShell(eventTargetElement, aGUIEvent,
+                                               aEventStatus, &rv)) {
+        return rv;
+      }
+    }
+    mPresShell->mCurrentEventContent = eventTargetElement;
 
     if (!mPresShell->GetCurrentEventContent() ||
         !mPresShell->GetCurrentEventFrame() ||
         InZombieDocument(mPresShell->mCurrentEventContent)) {
-      rv = RetargetEventToParent(aGUIEvent, aEventStatus);
-      return rv;
+      return RetargetEventToParent(aGUIEvent, aEventStatus);
     }
   } else {
     mPresShell->mCurrentEventFrame = aFrame;
   }
+
+  nsresult rv = NS_OK;
   if (mPresShell->GetCurrentEventFrame()) {
     nsCOMPtr<nsIContent> overrideClickTarget;  // Required due to bug  1506439
     rv =
         HandleEventInternal(aGUIEvent, aEventStatus, true, overrideClickTarget);
   }
 
 #ifdef DEBUG
   mPresShell->ShowEventTargetDebug();
@@ -7507,16 +7501,44 @@ Element* PresShell::EventHandler::Comput
         sLastKeyDownEventTargetElement = nullptr;
       }
       MOZ_FALLTHROUGH;
     default:
       return eventTargetElement;
   }
 }
 
+bool PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell(
+    Element* aEventTargetElement, WidgetGUIEvent* aGUIEvent,
+    nsEventStatus* aEventStatus, nsresult* aRv) {
+  MOZ_ASSERT(aEventTargetElement);
+  MOZ_ASSERT(aGUIEvent);
+  MOZ_ASSERT(!aGUIEvent->IsUsingCoordinates());
+  MOZ_ASSERT(aEventStatus);
+  MOZ_ASSERT(aRv);
+
+  Document* eventTargetDocument = aEventTargetElement->OwnerDoc();
+  if (!eventTargetDocument || eventTargetDocument == GetDocument()) {
+    *aRv = NS_OK;
+    return false;
+  }
+
+  RefPtr<PresShell> eventTargetPresShell =
+      static_cast<PresShell*>(eventTargetDocument->GetShell());
+  if (!eventTargetPresShell) {
+    *aRv = NS_OK;
+    return true;  // No PresShell can handle the event.
+  }
+
+  EventHandler eventHandler(std::move(eventTargetPresShell));
+  *aRv = eventHandler.HandleRetargetedEvent(aGUIEvent, aEventStatus,
+                                            aEventTargetElement);
+  return true;
+}
+
 Document* PresShell::GetPrimaryContentDocument() {
   nsPresContext* context = GetPresContext();
   if (!context || !context->IsRoot()) {
     return nullptr;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem = context->GetDocShell();
   if (!shellAsTreeItem) {
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -520,38 +520,16 @@ class PresShell final : public nsIPresSh
      *                                  different PresShell.
      * @param aEventStatus              [in/out] EventStatus of aGUIEvent.
      */
     MOZ_CAN_RUN_SCRIPT
     nsresult HandleEvent(nsIFrame* aFrame, WidgetGUIEvent* aGUIEvent,
                          bool aDontRetargetEvents, nsEventStatus* aEventStatus);
 
     /**
-     * HandleRetargetedEvent() dispatches aGUIEvent on the PresShell without
-     * retargetting.  This should be used only when caller computes final
-     * target of aGUIEvent.
-     *
-     * @param aGUIEvent         Event to be dispatched.
-     * @param aEventStatus      [in/out] EventStatus of aGUIEvent.
-     * @param aTarget           The final target of aGUIEvent.
-     */
-    MOZ_CAN_RUN_SCRIPT
-    nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
-                                   nsEventStatus* aEventStatus,
-                                   nsIContent* aTarget) {
-      AutoCurrentEventInfoSetter eventInfoSetter(*this, nullptr, aTarget);
-      if (!mPresShell->GetCurrentEventFrame()) {
-        return NS_OK;
-      }
-      nsCOMPtr<nsIContent> overrideClickTarget;
-      return HandleEventInternal(aGUIEvent, aEventStatus, true,
-                                 overrideClickTarget);
-    }
-
-    /**
      * HandleEventWithTarget() tries to dispatch aEvent on aContent after
      * setting current event target content to aNewEventContent and current
      * event frame to aNewEventFrame temporarily.  Note that this supports
      * WidgetEvent, not WidgetGUIEvent.  So, you can dispatch a simple event
      * with this.
      *
      * @param aEvent                    Event to be dispatched.
      * @param aNewEventFrame            Temporal new event frame.
@@ -982,16 +960,59 @@ class PresShell final : public nsIPresSh
      *
      * @param aGUIEvent                 The handling event.
      * @return                          The element which should be the event
      *                                  target of aGUIEvent.
      */
     Element* ComputeFocusedEventTargetElement(WidgetGUIEvent* aGUIEvent);
 
     /**
+     * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another
+     * PresShell.
+     *
+     * @param aEventTargetElement       The event target element of aGUIEvent.
+     * @param aGUIEvent                 Handling event.
+     * @param aEventStatus              [in/out] EventStatus of aGUIEvent.
+     * @param aRv                       [out] Returns error if this gets an
+     *                                  error handling the event.
+     * @return                          false if caller needs to keep handling
+     *                                  the event by itself.
+     *                                  true if caller shouldn't keep handling
+     *                                  the event.  Note that when no PresShell
+     *                                  can handle the event, this returns true.
+     */
+    MOZ_CAN_RUN_SCRIPT
+    bool MaybeHandleEventWithAnotherPresShell(Element* aEventTargetElement,
+                                              WidgetGUIEvent* aGUIEvent,
+                                              nsEventStatus* aEventStatus,
+                                              nsresult* aRv);
+
+    /**
+     * HandleRetargetedEvent() dispatches aGUIEvent on the PresShell without
+     * retargetting.  This should be used only when caller computes final
+     * target of aGUIEvent.
+     *
+     * @param aGUIEvent         Event to be dispatched.
+     * @param aEventStatus      [in/out] EventStatus of aGUIEvent.
+     * @param aTarget           The final target of aGUIEvent.
+     */
+    MOZ_CAN_RUN_SCRIPT
+    nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
+                                   nsEventStatus* aEventStatus,
+                                   nsIContent* aTarget) {
+      AutoCurrentEventInfoSetter eventInfoSetter(*this, nullptr, aTarget);
+      if (!mPresShell->GetCurrentEventFrame()) {
+        return NS_OK;
+      }
+      nsCOMPtr<nsIContent> overrideClickTarget;
+      return HandleEventInternal(aGUIEvent, aEventStatus, true,
+                                 overrideClickTarget);
+    }
+
+    /**
      * XXX Needs better name.
      * HandleEventInternal() dispatches aEvent into the DOM tree and
      * notify EventStateManager of that.
      *
      * @param aEvent                    Event to be dispatched.
      * @param aEventStatus              [in/out] EventStatus of aEvent.
      * @param aIsHandlingNativeEvent    true if aGUIEvent represents a native
      *                                  event.
@@ -1121,32 +1142,16 @@ class PresShell final : public nsIPresSh
 
     OwningNonNull<PresShell> mPresShell;
     AutoCurrentEventInfoSetter* mCurrentEventInfoSetter;
     static TimeStamp sLastInputCreated;
     static TimeStamp sLastInputProcessed;
     static StaticRefPtr<Element> sLastKeyDownEventTargetElement;
   };
 
-  /**
-   * Helper method of EventHandler::HandleEvent().  This is called when the
-   * event is dispatched without ref-point and dispatched by
-   * EventHandler::HandleEvent().
-   *
-   * See EventHandler::HandleRetargetedEvent() for the detail of the arguments.
-   */
-  MOZ_CAN_RUN_SCRIPT
-  nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
-                                 nsEventStatus* aEventStatus,
-                                 nsIContent* aTarget) {
-    MOZ_ASSERT(aGUIEvent);
-    EventHandler eventHandler(*this);
-    return eventHandler.HandleRetargetedEvent(aGUIEvent, aEventStatus, aTarget);
-  }
-
   void SynthesizeMouseMove(bool aFromScroll) override;
 
   PresShell* GetRootPresShell();
 
   nscolor GetDefaultBackgroundColorToDraw();
 
   // The callback for the mPaintSuppressionTimer timer.
   static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);