Bug 1466208 - part 20: Create PresShell::EventHandler::EventTargetData::MaybeRetargetToActiveDocument() r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 15 Feb 2019 02:06:31 +0000
changeset 459498 1bcbf6ebcd453f3ea6eaa944145704766aee8b49
parent 459497 6cec6714210566cd5a156c40b1759a3c46d9d69f
child 459499 3c9f0c796287636c7428d6a181a80632d397051a
push id111964
push usercsabou@mozilla.com
push dateFri, 15 Feb 2019 18:54:44 +0000
treeherdermozilla-inbound@db3c4f905082 [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 20: Create PresShell::EventHandler::EventTargetData::MaybeRetargetToActiveDocument() r=smaug Now, we can create methods to update event target into EventTargetData(). This moves a block in PresShell::EventHandler::HandleEvent() to retarget to active document into the new method. Differential Revision: https://phabricator.services.mozilla.com/D19318
layout/base/PresShell.cpp
layout/base/PresShell.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6624,45 +6624,22 @@ nsresult PresShell::EventHandler::Handle
 
     // Suppress mouse event if it's being targeted at an element inside
     // a document which needs events suppressed
     if (MaybeDiscardOrDelayMouseEvent(eventTargetData.mFrame, aGUIEvent)) {
       return NS_OK;
     }
 
     // Check if we have an active EventStateManager which isn't the
-    // EventStateManager of the current PresContext.
-    // If that is the case, and mouse is over some ancestor document,
-    // forward event handling to the active document.
-    // This way content can get mouse events even when
-    // mouse is over the chrome or outside the window.
-    //
-    // Note, currently for backwards compatibility we don't forward mouse events
-    // to the active document when mouse is over some subdocument.
-    if (EventStateManager* activeESM =
-            EventStateManager::GetActiveEventStateManager()) {
-      if (aGUIEvent->mClass == ePointerEventClass ||
-          aGUIEvent->HasMouseEventMessage()) {
-        if (activeESM != eventTargetData.GetEventStateManager()) {
-          if (nsPresContext* activeContext = activeESM->GetPresContext()) {
-            if (nsIPresShell* activeShell = activeContext->GetPresShell()) {
-              if (nsContentUtils::ContentIsCrossDocDescendantOf(
-                      activeShell->GetDocument(),
-                      eventTargetData.GetDocument())) {
-                eventTargetData.SetPresShellAndFrame(
-                    static_cast<PresShell*>(activeShell),
-                    activeShell->GetRootFrame());
-              }
-            }
-          }
-        }
-      }
-    }
-
-    if (NS_WARN_IF(!eventTargetData.mFrame)) {
+    // EventStateManager of the current PresContext.  If that is the case, and
+    // mouse is over some ancestor document, forward event handling to the
+    // active document.  This way content can get mouse events even when mouse
+    // is over the chrome or outside the window.
+    if (eventTargetData.MaybeRetargetToActiveDocument(aGUIEvent) &&
+        NS_WARN_IF(!eventTargetData.mFrame)) {
       return NS_OK;
     }
 
     eventTargetData.SetContentForEventFromFrame(aGUIEvent);
 
     // If there is no content for this frame, target it anyway.  Some
     // frames can be targeted but do not have content, particularly
     // windows with scrolling off.
@@ -10768,8 +10745,38 @@ void PresShell::EventHandler::EventTarge
   MOZ_ASSERT(mFrame);
   mContent = nullptr;
   mFrame->GetContentForEvent(aGUIEvent, getter_AddRefs(mContent));
 }
 
 nsIContent* PresShell::EventHandler::EventTargetData::GetFrameContent() const {
   return mFrame ? mFrame->GetContent() : nullptr;
 }
+
+bool PresShell::EventHandler::EventTargetData::MaybeRetargetToActiveDocument(
+    WidgetGUIEvent* aGUIEvent) {
+  MOZ_ASSERT(aGUIEvent);
+  MOZ_ASSERT(mFrame);
+  MOZ_ASSERT(mPresShell);
+  MOZ_ASSERT(!mContent, "Doesn't support to retarget the content");
+
+  // Note, currently for backwards compatibility we don't forward mouse events
+  // to the active document when mouse is over some subdocument.
+  if (EventStateManager* activeESM =
+          EventStateManager::GetActiveEventStateManager()) {
+    if (aGUIEvent->mClass == ePointerEventClass ||
+        aGUIEvent->HasMouseEventMessage()) {
+      if (activeESM != GetEventStateManager()) {
+        if (nsPresContext* activeContext = activeESM->GetPresContext()) {
+          if (nsIPresShell* activeShell = activeContext->GetPresShell()) {
+            if (nsContentUtils::ContentIsCrossDocDescendantOf(
+                    activeShell->GetDocument(), GetDocument())) {
+              SetPresShellAndFrame(static_cast<PresShell*>(activeShell),
+                                   activeShell->GetRootFrame());
+              return true;
+            }
+          }
+        }
+      }
+    }
+  }
+  return false;
+}
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -611,16 +611,26 @@ class PresShell final : public nsIPresSh
         nsPresContext* presContext = GetPresContext();
         return presContext ? presContext->EventStateManager() : nullptr;
       }
       Document* GetDocument() const {
         return mPresShell ? mPresShell->GetDocument() : nullptr;
       }
       nsIContent* GetFrameContent() const;
 
+      /**
+       * MaybeRetargetToActiveDocument() tries retarget aGUIEvent into
+       * active document if there is.  Note that this does not support to
+       * retarget mContent.  Make sure it is nullptr before calling this.
+       *
+       * @param aGUIEvent       The handling event.
+       * @return                true if retargetted.
+       */
+      bool MaybeRetargetToActiveDocument(WidgetGUIEvent* aGUIEvent);
+
       RefPtr<PresShell> mPresShell;
       nsIFrame* mFrame;
       nsCOMPtr<nsIContent> mContent;
     };
 
     /**
      * MaybeFlushPendingNotifications() maybe flush pending notifications if
      * aGUIEvent should be handled with the latest layout.