Bug 1547418 - Make CapturingContentInfo a private struct of PresShell and move APIs for it from nsIPresShell to PresShell r=smaug a=reland
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 30 Apr 2019 00:26:57 +0000
changeset 530674 596be5bff8b9ec986de13a5a5812f04672f89d08
parent 530673 2258dc01bcd175ce0d2f31ae69a88fadfbecdb12
child 530700 ee0dd3b092d03d28da65f5ee686db942b9ce8ec0
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, reland
bugs1547418
milestone68.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 1547418 - Make CapturingContentInfo a private struct of PresShell and move APIs for it from nsIPresShell to PresShell r=smaug a=reland `CapturingContentInfo` struct is used only in `PresShell.cpp` so that we can make it a private struct of `PresShell` if we move all users of them, i.e., API to access them, from `nsIPresShell` to `PresShell`. Differential Revision: https://phabricator.services.mozilla.com/D29111
dom/base/Document.cpp
dom/base/Element.h
dom/base/Selection.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/events/EventStateManager.cpp
dom/html/HTMLInputElement.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsIPresShell.h
layout/forms/nsListControlFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSelection.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsImageFrame.cpp
layout/generic/nsPluginFrame.cpp
layout/style/ServoBindings.toml
layout/xul/nsDeckFrame.cpp
layout/xul/nsSliderFrame.cpp
view/nsView.cpp
widget/nsBaseDragService.cpp
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -3671,17 +3671,17 @@ Element* Document::GetActiveElement() {
 Element* Document::GetCurrentScript() {
   nsCOMPtr<Element> el(do_QueryInterface(ScriptLoader()->GetCurrentScript()));
   return el;
 }
 
 void Document::ReleaseCapture() const {
   // only release the capture if the caller can access it. This prevents a
   // page from stopping a scrollbar grab for example.
-  nsCOMPtr<nsINode> node = nsIPresShell::GetCapturingContent();
+  nsCOMPtr<nsINode> node = PresShell::GetCapturingContent();
   if (node && nsContentUtils::CanCallerAccess(node)) {
     PresShell::ReleaseCapturingContent();
   }
 }
 
 already_AddRefed<nsIURI> Document::GetBaseURI(bool aTryUseXHRDocBaseURI) const {
   nsCOMPtr<nsIURI> uri;
   if (aTryUseXHRDocBaseURI && mChromeXHRDocBaseURI) {
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1170,34 +1170,34 @@ class Element : public FragmentOrElement
       return true;
     }
     return false;
   }
   void SetCapture(bool aRetargetToElement) {
     // If there is already an active capture, ignore this request. This would
     // occur if a splitter, frame resizer, etc had already captured and we don't
     // want to override those.
-    if (!nsIPresShell::GetCapturingContent()) {
+    if (!PresShell::GetCapturingContent()) {
       PresShell::SetCapturingContent(
           this, CaptureFlags::PreventDragStart |
                     (aRetargetToElement ? CaptureFlags::RetargetToElement
                                         : CaptureFlags::None));
     }
   }
 
   void SetCaptureAlways(bool aRetargetToElement) {
     PresShell::SetCapturingContent(
         this, CaptureFlags::PreventDragStart |
                   CaptureFlags::IgnoreAllowedState |
                   (aRetargetToElement ? CaptureFlags::RetargetToElement
                                       : CaptureFlags::None));
   }
 
   void ReleaseCapture() {
-    if (nsIPresShell::GetCapturingContent() == this) {
+    if (PresShell::GetCapturingContent() == this) {
       PresShell::ReleaseCapturingContent();
     }
   }
 
   already_AddRefed<Promise> RequestFullscreen(CallerType, ErrorResult&);
   void RequestPointerLock(CallerType aCallerType);
   Attr* GetAttributeNode(const nsAString& aName);
   already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr, ErrorResult& aError);
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -158,17 +158,17 @@ class nsAutoScrollTimer final : public n
   // aPoint is relative to aPresContext's root frame
   nsresult Start(nsPresContext* aPresContext, nsPoint& aPoint) {
     mPoint = aPoint;
 
     // Store the presentation context. The timer will be
     // stopped by the selection if the prescontext is destroyed.
     mPresContext = aPresContext;
 
-    mContent = nsIPresShell::GetCapturingContent();
+    mContent = PresShell::GetCapturingContent();
 
     if (!mTimer) {
       mTimer = NS_NewTimer(
           mPresContext->Document()->EventTargetFor(TaskCategory::Other));
 
       if (!mTimer) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -6331,17 +6331,17 @@ void nsGlobalWindowOuter::EnterModalStat
   if (ds) {
     ds->EndDragSession(true, 0);
   }
 
   // Clear the capturing content if it is under topDoc.
   // Usually the activeESM check above does that, but there are cases when
   // we don't have activeESM, or it is for different document.
   Document* topDoc = topWin->GetExtantDoc();
-  nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
+  nsIContent* capturingContent = PresShell::GetCapturingContent();
   if (capturingContent && topDoc &&
       nsContentUtils::ContentIsCrossDocDescendantOf(capturingContent, topDoc)) {
     PresShell::ReleaseCapturingContent();
   }
 
   if (topWin->mModalStateDepth == 0) {
     NS_ASSERTION(!topWin->mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1752,17 +1752,17 @@ void EventStateManager::GenerateDragGest
       RefPtr<nsFrameSelection> frameSel = mCurrentTarget->GetFrameSelection();
       if (frameSel && frameSel->GetDragState()) {
         StopTrackingDragGesture();
         return;
       }
     }
 
     // If non-native code is capturing the mouse don't start a drag.
-    if (nsIPresShell::IsMouseCapturePreventingDrag()) {
+    if (PresShell::IsMouseCapturePreventingDrag()) {
       StopTrackingDragGesture();
       return;
     }
 
     if (IsEventOutsideDragThreshold(aEvent)) {
       if (Prefs::ClickHoldContextMenu()) {
         // stop the click-hold before we fire off the drag gesture, in case
         // it takes a long time
@@ -3030,17 +3030,17 @@ nsresult EventStateManager::PostHandleEv
         break;
       }
 
       // For remote content, capture the event in the parent process at the
       // <xul:browser remote> element. This will ensure that subsequent
       // mousemove/mouseup events will continue to be dispatched to this element
       // and therefore forwarded to the child.
       if (aEvent->HasBeenPostedToRemoteProcess() &&
-          !nsIPresShell::GetCapturingContent()) {
+          !PresShell::GetCapturingContent()) {
         if (nsIContent* content =
                 mCurrentTarget ? mCurrentTarget->GetContent() : nullptr) {
           PresShell::SetCapturingContent(content, CaptureFlags::None);
         } else {
           PresShell::ReleaseCapturingContent();
         }
       }
 
@@ -6285,17 +6285,17 @@ AutoHandlingUserInputStatePusher::AutoHa
 }
 
 AutoHandlingUserInputStatePusher::~AutoHandlingUserInputStatePusher() {
   if (!mIsHandlingUserInput) {
     return;
   }
   EventStateManager::StopHandlingUserInput(mMessage);
   if (mMessage == eMouseDown) {
-    nsIPresShell::AllowMouseCapture(false);
+    PresShell::AllowMouseCapture(false);
   }
   if (NeedsToResetFocusManagerMouseButtonHandlingState()) {
     nsFocusManager* fm = nsFocusManager::GetFocusManager();
     NS_ENSURE_TRUE_VOID(fm);
     nsCOMPtr<Document> handlingDocument =
         fm->SetMouseButtonHandlingDocument(mMouseButtonEventHandlingDocument);
   }
 }
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -3423,32 +3423,32 @@ void HTMLInputElement::StartRangeThumbDr
   GetValue(mFocusedValue, CallerType::System);
 
   SetValueOfRangeForUserEvent(rangeFrame->GetValueAtEventPoint(aEvent));
 }
 
 void HTMLInputElement::FinishRangeThumbDrag(WidgetGUIEvent* aEvent) {
   MOZ_ASSERT(mIsDraggingRange);
 
-  if (nsIPresShell::GetCapturingContent() == this) {
+  if (PresShell::GetCapturingContent() == this) {
     PresShell::ReleaseCapturingContent();
   }
   if (aEvent) {
     nsRangeFrame* rangeFrame = do_QueryFrame(GetPrimaryFrame());
     SetValueOfRangeForUserEvent(rangeFrame->GetValueAtEventPoint(aEvent));
   }
   mIsDraggingRange = false;
   FireChangeEventIfNeeded();
 }
 
 void HTMLInputElement::CancelRangeThumbDrag(bool aIsForUserEvent) {
   MOZ_ASSERT(mIsDraggingRange);
 
   mIsDraggingRange = false;
-  if (nsIPresShell::GetCapturingContent() == this) {
+  if (PresShell::GetCapturingContent() == this) {
     PresShell::ReleaseCapturingContent();
   }
   if (aIsForUserEvent) {
     SetValueOfRangeForUserEvent(mRangeThumbDragStartValue);
   } else {
     // Don't dispatch an 'input' event - at least not using
     // DispatchTrustedEvent.
     // TODO: decide what we should do here - bug 851782.
@@ -3507,17 +3507,17 @@ void HTMLInputElement::StartNumberContro
   nsNumberControlFrame* numberControlFrame = do_QueryFrame(GetPrimaryFrame());
   if (numberControlFrame) {
     numberControlFrame->SpinnerStateChanged();
   }
 }
 
 void HTMLInputElement::StopNumberControlSpinnerSpin(SpinnerStopState aState) {
   if (mNumberControlSpinnerIsSpinning) {
-    if (nsIPresShell::GetCapturingContent() == this) {
+    if (PresShell::GetCapturingContent() == this) {
       PresShell::ReleaseCapturingContent();
     }
 
     nsRepeatService::GetInstance()->Stop(HandleNumberControlSpin, this);
 
     mNumberControlSpinnerIsSpinning = false;
 
     if (aState == eAllowDispatchingEvents) {
@@ -4178,17 +4178,17 @@ void HTMLInputElement::PostHandleEventFo
   }
 
   switch (aVisitor.mEvent->mMessage) {
     case eMouseDown:
     case eTouchStart: {
       if (mIsDraggingRange) {
         break;
       }
-      if (nsIPresShell::GetCapturingContent()) {
+      if (PresShell::GetCapturingContent()) {
         break;  // don't start drag if someone else is already capturing
       }
       WidgetInputEvent* inputEvent = aVisitor.mEvent->AsInputEvent();
       if (IgnoreInputEventWithModifier(inputEvent, true)) {
         break;  // ignore
       }
       if (aVisitor.mEvent->mMessage == eMouseDown) {
         if (aVisitor.mEvent->AsMouseEvent()->mButtons ==
@@ -4207,17 +4207,17 @@ void HTMLInputElement::PostHandleEventFo
       aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
     } break;
 
     case eMouseMove:
     case eTouchMove:
       if (!mIsDraggingRange) {
         break;
       }
-      if (nsIPresShell::GetCapturingContent() != this) {
+      if (PresShell::GetCapturingContent() != this) {
         // Someone else grabbed capture.
         CancelRangeThumbDrag();
         break;
       }
       SetValueOfRangeForUserEvent(
           rangeFrame->GetValueAtEventPoint(aVisitor.mEvent->AsInputEvent()));
       aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
       break;
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -1804,17 +1804,17 @@ static NPCocoaEventType CocoaEventTypeFo
     case eMouseOver:
       return NPCocoaEventMouseEntered;
     case eMouseOut:
       return NPCocoaEventMouseExited;
     case eMouseMove: {
       // We don't know via information on events from the widget code whether or
       // not we're dragging. The widget code just generates mouse move events
       // from native drag events. If anybody is capturing, this is a drag event.
-      if (nsIPresShell::GetCapturingContent()) {
+      if (PresShell::GetCapturingContent()) {
         return NPCocoaEventMouseDragged;
       }
 
       return NPCocoaEventMouseMoved;
     }
     case eMouseDown:
       return NPCocoaEventMouseDown;
     case eMouseUp:
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -207,19 +207,17 @@ using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 using namespace mozilla::layout;
 using PaintFrameFlags = nsLayoutUtils::PaintFrameFlags;
 typedef ScrollableLayerGuid::ViewID ViewID;
 
-CapturingContentInfo nsIPresShell::gCaptureInfo = {
-    false /* mAllowed */, false /* mPointerLock */,
-    false /* mRetargetToElement */, false /* mPreventDrag */};
+PresShell::CapturingContentInfo PresShell::sCapturingContentInfo;
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
   RefPtr<nsRange> mRange;
   nsDisplayListBuilder mBuilder;
   nsDisplayList mList;
 
   // offset of builder's reference frame to the root frame
@@ -2437,17 +2435,18 @@ void PresShell::RestoreRootScrollPositio
   }
 }
 
 void PresShell::MaybeReleaseCapturingContent() {
   RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (frameSelection) {
     frameSelection->SetDragState(false);
   }
-  if (gCaptureInfo.mContent && gCaptureInfo.mContent->OwnerDoc() == mDocument) {
+  if (sCapturingContentInfo.mContent &&
+      sCapturingContentInfo.mContent->OwnerDoc() == mDocument) {
     PresShell::ReleaseCapturingContent();
   }
 }
 
 void PresShell::BeginLoad(Document* aDocument) {
   mDocumentLoading = true;
 
   gfxTextPerfMetrics* tp = nullptr;
@@ -3696,75 +3695,75 @@ void nsIPresShell::DispatchSynthMouseMov
   nsEventStatus status = nsEventStatus_eIgnore;
   nsView* targetView = nsView::GetViewFor(aEvent->mWidget);
   if (!targetView) return;
   RefPtr<nsViewManager> viewManager = targetView->GetViewManager();
   viewManager->DispatchEvent(aEvent, targetView, &status);
 }
 
 void PresShell::ClearMouseCaptureOnView(nsView* aView) {
-  if (gCaptureInfo.mContent) {
+  if (sCapturingContentInfo.mContent) {
     if (aView) {
       // if a view was specified, ensure that the captured content is within
       // this view.
-      nsIFrame* frame = gCaptureInfo.mContent->GetPrimaryFrame();
+      nsIFrame* frame = sCapturingContentInfo.mContent->GetPrimaryFrame();
       if (frame) {
         nsView* view = frame->GetClosestView();
         // if there is no view, capturing won't be handled any more, so
         // just release the capture.
         if (view) {
           do {
             if (view == aView) {
-              gCaptureInfo.mContent = nullptr;
+              sCapturingContentInfo.mContent = nullptr;
               // the view containing the captured content likely disappeared so
               // disable capture for now.
-              gCaptureInfo.mAllowed = false;
+              sCapturingContentInfo.mAllowed = false;
               break;
             }
 
             view = view->GetParent();
           } while (view);
           // return if the view wasn't found
           return;
         }
       }
     }
 
-    gCaptureInfo.mContent = nullptr;
+    sCapturingContentInfo.mContent = nullptr;
   }
 
   // disable mouse capture until the next mousedown as a dialog has opened
   // or a drag has started. Otherwise, someone could start capture during
   // the modal dialog or drag.
-  gCaptureInfo.mAllowed = false;
-}
-
-void nsIPresShell::ClearMouseCapture(nsIFrame* aFrame) {
-  if (!gCaptureInfo.mContent) {
-    gCaptureInfo.mAllowed = false;
+  sCapturingContentInfo.mAllowed = false;
+}
+
+void PresShell::ClearMouseCapture(nsIFrame* aFrame) {
+  if (!sCapturingContentInfo.mContent) {
+    sCapturingContentInfo.mAllowed = false;
     return;
   }
 
   // null frame argument means clear the capture
   if (!aFrame) {
-    gCaptureInfo.mContent = nullptr;
-    gCaptureInfo.mAllowed = false;
+    sCapturingContentInfo.mContent = nullptr;
+    sCapturingContentInfo.mAllowed = false;
     return;
   }
 
-  nsIFrame* capturingFrame = gCaptureInfo.mContent->GetPrimaryFrame();
+  nsIFrame* capturingFrame = sCapturingContentInfo.mContent->GetPrimaryFrame();
   if (!capturingFrame) {
-    gCaptureInfo.mContent = nullptr;
-    gCaptureInfo.mAllowed = false;
+    sCapturingContentInfo.mContent = nullptr;
+    sCapturingContentInfo.mAllowed = false;
     return;
   }
 
   if (nsLayoutUtils::IsAncestorFrameCrossDoc(aFrame, capturingFrame)) {
-    gCaptureInfo.mContent = nullptr;
-    gCaptureInfo.mAllowed = false;
+    sCapturingContentInfo.mContent = nullptr;
+    sCapturingContentInfo.mAllowed = false;
   }
 }
 
 nsresult PresShell::CaptureHistoryState(nsILayoutHistoryState** aState) {
   MOZ_ASSERT(nullptr != aState, "null state pointer");
 
   // We actually have to mess with the docshell here, since we want to
   // store the state back in it.
@@ -6119,37 +6118,38 @@ void PresShell::Paint(nsView* aViewToPai
                                    ? LayerManager::END_DEFAULT
                                    : LayerManager::END_NO_COMPOSITE);
 }
 
 // static
 void PresShell::SetCapturingContent(nsIContent* aContent, CaptureFlags aFlags) {
   // If capture was set for pointer lock, don't unlock unless we are coming
   // out of pointer lock explicitly.
-  if (!aContent && gCaptureInfo.mPointerLock &&
+  if (!aContent && sCapturingContentInfo.mPointerLock &&
       !(aFlags & CaptureFlags::PointerLock)) {
     return;
   }
 
-  gCaptureInfo.mContent = nullptr;
+  sCapturingContentInfo.mContent = nullptr;
 
   // only set capturing content if allowed or the
   // CaptureFlags::IgnoreAllowedState or CaptureFlags::PointerLock are used.
-  if ((aFlags & CaptureFlags::IgnoreAllowedState) || gCaptureInfo.mAllowed ||
-      (aFlags & CaptureFlags::PointerLock)) {
+  if ((aFlags & CaptureFlags::IgnoreAllowedState) ||
+      sCapturingContentInfo.mAllowed || (aFlags & CaptureFlags::PointerLock)) {
     if (aContent) {
-      gCaptureInfo.mContent = aContent;
+      sCapturingContentInfo.mContent = aContent;
     }
     // CaptureFlags::PointerLock is the same as
     // CaptureFlags::RetargetToElement & CaptureFlags::IgnoreAllowedState.
-    gCaptureInfo.mRetargetToElement =
+    sCapturingContentInfo.mRetargetToElement =
         !!(aFlags & CaptureFlags::RetargetToElement) ||
         !!(aFlags & CaptureFlags::PointerLock);
-    gCaptureInfo.mPreventDrag = !!(aFlags & CaptureFlags::PreventDragStart);
-    gCaptureInfo.mPointerLock = !!(aFlags & CaptureFlags::PointerLock);
+    sCapturingContentInfo.mPreventDrag =
+        !!(aFlags & CaptureFlags::PreventDragStart);
+    sCapturingContentInfo.mPointerLock = !!(aFlags & CaptureFlags::PointerLock);
   }
 }
 
 nsIContent* nsIPresShell::GetCurrentEventContent() {
   if (mCurrentEventContent &&
       mCurrentEventContent->GetComposedDoc() != mDocument) {
     mCurrentEventContent = nullptr;
     mCurrentEventFrame = nullptr;
@@ -6660,17 +6660,17 @@ nsresult PresShell::EventHandler::Handle
     }
   }
 
   // if a node is capturing the mouse, check if the event needs to be
   // retargeted at the capturing content instead. This will be the case when
   // capture retargeting is being used, no frame was found or the frame's
   // content is not a descendant of the capturing content.
   if (capturingContent && !pointerCapturingContent &&
-      (gCaptureInfo.mRetargetToElement ||
+      (PresShell::sCapturingContentInfo.mRetargetToElement ||
        !eventTargetData.mFrame->GetContent() ||
        !nsContentUtils::ContentIsCrossDocDescendantOf(
            eventTargetData.mFrame->GetContent(), capturingContent))) {
     // A check was already done above to ensure that capturingContent is
     // in this presshell.
     NS_ASSERTION(capturingContent->GetComposedDoc() == GetDocument(),
                  "Unexpected document");
     nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame();
@@ -6999,17 +6999,17 @@ bool PresShell::EventHandler::MaybeDisca
 }
 
 // static
 nsIContent* PresShell::EventHandler::GetCapturingContentFor(
     WidgetGUIEvent* aGUIEvent) {
   return (aGUIEvent->mClass == ePointerEventClass ||
           aGUIEvent->mClass == eWheelEventClass ||
           aGUIEvent->HasMouseEventMessage())
-             ? nsIPresShell::GetCapturingContent()
+             ? PresShell::GetCapturingContent()
              : nullptr;
 }
 
 bool PresShell::EventHandler::GetRetargetEventDocument(
     WidgetGUIEvent* aGUIEvent, Document** aRetargetEventDocument) {
   MOZ_ASSERT(aGUIEvent);
   MOZ_ASSERT(aRetargetEventDocument);
 
@@ -7364,17 +7364,17 @@ PresShell::EventHandler::ComputeRootFram
   bool isBaseWindowVisible = false;
   nsresult rv = baseWindow->GetVisibility(&isBaseWindowVisible);
   if (NS_FAILED(rv) || !isBaseWindowVisible) {
     ClearMouseCapture(nullptr);
     *aIsCapturingContentIgnored = true;
     return aRootFrameToHandleEvent;
   }
 
-  if (gCaptureInfo.mRetargetToElement) {
+  if (PresShell::sCapturingContentInfo.mRetargetToElement) {
     *aIsCaptureRetargeted = true;
     return aRootFrameToHandleEvent;
   }
 
   // A check was already done above to ensure that aCapturingContent is
   // in this presshell.
   NS_ASSERTION(aCapturingContent->GetComposedDoc() == GetDocument(),
                "Unexpected document");
@@ -7833,17 +7833,17 @@ bool PresShell::EventHandler::PrepareToD
       *aIsUserInteraction = true;
       return true;
 
     case eMouseMove: {
       bool allowCapture = EventStateManager::GetActiveEventStateManager() &&
                           GetPresContext() &&
                           GetPresContext()->EventStateManager() ==
                               EventStateManager::GetActiveEventStateManager();
-      nsIPresShell::AllowMouseCapture(allowCapture);
+      PresShell::AllowMouseCapture(allowCapture);
       *aIsUserInteraction = false;
       return true;
     }
     case eDrop: {
       nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
       if (session) {
         bool onlyChromeDrop = false;
         session->GetOnlyChromeDrop(&onlyChromeDrop);
@@ -7910,17 +7910,17 @@ void PresShell::EventHandler::FinalizeHa
       }
       return;
     }
     case eMouseUp:
       // reset the capturing content now that the mouse button is up
       PresShell::ReleaseCapturingContent();
       return;
     case eMouseMove:
-      nsIPresShell::AllowMouseCapture(false);
+      PresShell::AllowMouseCapture(false);
       return;
     case eDrag:
     case eDragEnd:
     case eDragEnter:
     case eDragExit:
     case eDragLeave:
     case eDragOver:
     case eDrop: {
@@ -8249,17 +8249,17 @@ void PresShell::EventHandler::DispatchTo
 
     nsCOMPtr<EventTarget> targetPtr = touch->mTarget;
     nsCOMPtr<nsIContent> content = do_QueryInterface(targetPtr);
     if (!content) {
       continue;
     }
 
     Document* doc = content->OwnerDoc();
-    nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
+    nsIContent* capturingContent = PresShell::GetCapturingContent();
     if (capturingContent) {
       if (capturingContent->OwnerDoc() != doc) {
         // Wrong document, don't dispatch anything.
         continue;
       }
       content = capturingContent;
     }
     // copy the event
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -68,16 +68,44 @@ class PresShell final : public nsIPresSh
  public:
   PresShell();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
   static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
 
+  /**
+   * Return the active content currently capturing the mouse if any.
+   */
+  static nsIContent* GetCapturingContent() {
+    return sCapturingContentInfo.mContent;
+  }
+
+  /**
+   * Allow or disallow mouse capturing.
+   */
+  static void AllowMouseCapture(bool aAllowed) {
+    sCapturingContentInfo.mAllowed = aAllowed;
+  }
+
+  /**
+   * Returns true if there is an active mouse capture that wants to prevent
+   * drags.
+   */
+  static bool IsMouseCapturePreventingDrag() {
+    return sCapturingContentInfo.mPreventDrag && sCapturingContentInfo.mContent;
+  }
+
+  static void ClearMouseCaptureOnView(nsView* aView);
+
+  // If a frame in the subtree rooted at aFrame is capturing the mouse then
+  // clears that capture.
+  static void ClearMouseCapture(nsIFrame* aFrame);
+
   void Init(Document*, nsPresContext*, nsViewManager*);
   void Destroy() override;
 
   NS_IMETHOD GetSelectionFromScript(RawSelectionType aRawSelectionType,
                                     dom::Selection** aSelection) override;
   dom::Selection* GetSelection(RawSelectionType aRawSelectionType) override;
 
   dom::Selection* GetCurrentSelection(SelectionType aSelectionType) override;
@@ -233,17 +261,16 @@ class PresShell final : public nsIPresSh
    * manager flush on the next tick.
    *
    * @param aType PaintType::DelayedCompress : Schedule a paint to be executed
    * after a delay, and put FrameLayerBuilder in 'compressed' mode that avoids
    * short cut optimizations.
    */
   void ScheduleViewManagerFlush(PaintType aType = PaintType::Default);
 
-  void ClearMouseCaptureOnView(nsView* aView) override;
   bool IsVisible() override;
   void SuppressDisplayport(bool aEnabled) override;
   void RespectDisplayportSuppression(bool aEnabled) override;
   bool IsDisplayportSuppressed() override;
 
   // caret handling
   NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
   NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
@@ -1545,16 +1572,18 @@ class PresShell final : public nsIPresSh
 
   // Information needed to properly handle scrolling content into view if the
   // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is non-null
   // between the initial scroll attempt and the first time we finish processing
   // all our dirty roots.  mContentToScrollTo has a content property storing the
   // details for the scroll operation, see ScrollIntoViewData above.
   nsCOMPtr<nsIContent> mContentToScrollTo;
 
+  TimeStamp mLastOSWake;
+
   // The focus sequence number of the last processed input event
   uint64_t mAPZFocusSequenceNumber;
   // The focus information needed for async keyboard scrolling
   FocusTarget mAPZFocusTarget;
 
   nscoord mLastAnchorScrollPositionY = 0;
 
   int32_t mActiveSuppressDisplayport;
@@ -1592,18 +1621,32 @@ class PresShell final : public nsIPresSh
   // mForceUseLegacyKeyCodeAndCharCodeValues are initialized.
   bool mInitializedWithKeyPressEventDispatchingBlacklist : 1;
 
   // Whether we should dispatch click events for non-primary mouse buttons.
   bool mForceUseLegacyNonPrimaryDispatch : 1;
   // Whether mForceUseLegacyNonPrimaryDispatch is initialised.
   bool mInitializedWithClickEventDispatchingBlacklist : 1;
 
-  static bool sDisableNonTestMouseEvents;
+  struct CapturingContentInfo final {
+    CapturingContentInfo()
+        : mAllowed(false),
+          mPointerLock(false),
+          mRetargetToElement(false),
+          mPreventDrag(false) {}
 
-  TimeStamp mLastOSWake;
+    // capture should only be allowed during a mousedown event
+    StaticRefPtr<nsIContent> mContent;
+    bool mAllowed;
+    bool mPointerLock;
+    bool mRetargetToElement;
+    bool mPreventDrag;
+  };
+  static CapturingContentInfo sCapturingContentInfo;
+
+  static bool sDisableNonTestMouseEvents;
 
   static bool sProcessInteractable;
 };
 
 }  // namespace mozilla
 
 #endif  // mozilla_PresShell_h
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -13,17 +13,16 @@
 
 #include "mozilla/ArenaObjectID.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/FlushType.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ScrollTypes.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/ServoStyleConsts.h"
-#include "mozilla/StaticPtr.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/WeakPtr.h"
 #include "FrameMetrics.h"
 #include "GeckoProfiler.h"
 #include "gfxPoint.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsTHashtable.h"
@@ -123,25 +122,16 @@ namespace layers {
 class LayerManager;
 }  // namespace layers
 
 namespace gfx {
 class SourceSurface;
 }  // namespace gfx
 }  // namespace mozilla
 
-struct CapturingContentInfo final {
-  // capture should only be allowed during a mousedown event
-  bool mAllowed;
-  bool mPointerLock;
-  bool mRetargetToElement;
-  bool mPreventDrag;
-  mozilla::StaticRefPtr<nsIContent> mContent;
-};
-
 // b7b89561-4f03-44b3-9afa-b47e7f313ffb
 #define NS_IPRESSHELL_IID                            \
   {                                                  \
     0xb7b89561, 0x4f03, 0x44b3, {                    \
       0x9a, 0xfa, 0xb4, 0x7e, 0x7f, 0x31, 0x3f, 0xfb \
     }                                                \
   }
 
@@ -1052,39 +1042,16 @@ class nsIPresShell : public nsStubDocume
   bool ObservesNativeAnonMutationsForPrint() {
     return mObservesMutationsForPrint;
   }
 
   virtual nsresult SetIsActive(bool aIsActive) = 0;
 
   bool IsActive() { return mIsActive; }
 
-  // mouse capturing
-  static CapturingContentInfo gCaptureInfo;
-
-  /**
-   * Return the active content currently capturing the mouse if any.
-   */
-  static nsIContent* GetCapturingContent() { return gCaptureInfo.mContent; }
-
-  /**
-   * Allow or disallow mouse capturing.
-   */
-  static void AllowMouseCapture(bool aAllowed) {
-    gCaptureInfo.mAllowed = aAllowed;
-  }
-
-  /**
-   * Returns true if there is an active mouse capture that wants to prevent
-   * drags.
-   */
-  static bool IsMouseCapturePreventingDrag() {
-    return gCaptureInfo.mPreventDrag && gCaptureInfo.mContent;
-  }
-
   /**
    * Keep track of how many times this presshell has been rendered to
    * a window.
    */
   uint64_t GetPaintCount() { return mPaintCount; }
   void IncrementPaintCount() { ++mPaintCount; }
 
   /**
@@ -1195,17 +1162,16 @@ class nsIPresShell : public nsStubDocume
   virtual void WillPaintWindow() = 0;
   /**
    * Notify that we called Paint with PaintFlags::PaintComposite.
    * Fires on the presshell for the painted widget.
    * This is issued at a time when it's safe to modify widget geometry.
    */
   virtual void DidPaintWindow() = 0;
 
-  virtual void ClearMouseCaptureOnView(nsView* aView) = 0;
   virtual bool IsVisible() = 0;
   MOZ_CAN_RUN_SCRIPT
   void DispatchSynthMouseMove(mozilla::WidgetGUIEvent* aEvent);
 
   /* Temporarily ignore the Displayport for better paint performance. We
    * trigger a repaint once suppression is disabled. Without that
    * the displayport may get left at the suppressed size for an extended
    * period of time and result in unnecessary checkerboarding (see bug
@@ -1357,20 +1323,16 @@ class nsIPresShell : public nsStubDocume
   bool AddRefreshObserver(nsARefreshObserver* aObserver,
                           mozilla::FlushType aFlushType);
   bool RemoveRefreshObserver(nsARefreshObserver* aObserver,
                              mozilla::FlushType aFlushType);
 
   bool AddPostRefreshObserver(nsAPostRefreshObserver* aObserver);
   bool RemovePostRefreshObserver(nsAPostRefreshObserver* aObserver);
 
-  // If a frame in the subtree rooted at aFrame is capturing the mouse then
-  // clears that capture.
-  static void ClearMouseCapture(nsIFrame* aFrame);
-
   void SetVisualViewportSize(nscoord aWidth, nscoord aHeight);
   void ResetVisualViewportSize();
   bool IsVisualViewportSizeSet() { return mVisualViewportSizeSet; }
   nsSize GetVisualViewportSize() {
     NS_ASSERTION(mVisualViewportSizeSet,
                  "asking for visual viewport size when its not set?");
     return mVisualViewportSize;
   }
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -819,17 +819,17 @@ void nsListControlFrame::CaptureMouseEve
   // capture requested via other code paths, if any exist).
   if (aGrabMouseEvents && IsInDropDownMode() &&
       nsComboboxControlFrame::ToolkitHasNativePopup())
     return;
 
   if (aGrabMouseEvents) {
     PresShell::SetCapturingContent(mContent, CaptureFlags::IgnoreAllowedState);
   } else {
-    nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
+    nsIContent* capturingContent = PresShell::GetCapturingContent();
 
     bool dropDownIsHidden = false;
     if (IsInDropDownMode()) {
       dropDownIsHidden = !mComboboxFrame->IsDroppedDown();
     }
     if (capturingContent == mContent || dropDownIsHidden) {
       // only clear the capturing content if *we* are the ones doing the
       // capturing (or if the dropdown is hidden, in which case NO-ONE should
@@ -1601,17 +1601,17 @@ void nsListControlFrame::FireMenuItemAct
   FireDOMEvent(NS_LITERAL_STRING("DOMMenuItemActive"), optionContent);
 }
 #endif
 
 nsresult nsListControlFrame::GetIndexFromDOMEvent(dom::Event* aMouseEvent,
                                                   int32_t& aCurIndex) {
   if (IgnoreMouseEventForSelection(aMouseEvent)) return NS_ERROR_FAILURE;
 
-  if (nsIPresShell::GetCapturingContent() != mContent) {
+  if (PresShell::GetCapturingContent() != mContent) {
     // If we're not capturing, then ignore movement in the border
     nsPoint pt =
         nsLayoutUtils::GetDOMEventCoordinatesRelativeTo(aMouseEvent, this);
     nsRect borderInnerEdge = GetScrollPortRect();
     if (!borderInnerEdge.Contains(pt)) {
       return NS_ERROR_FAILURE;
     }
   }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2129,17 +2129,17 @@ void nsIFrame::OnVisibilityChange(Visibi
                                   const Maybe<OnNonvisible>& aNonvisibleAction
                                   /* = Nothing() */) {
   // XXX(seth): In bug 1218990 we'll implement visibility tracking for CSS
   // images here.
 }
 
 static nsIFrame* GetActiveSelectionFrame(nsPresContext* aPresContext,
                                          nsIFrame* aFrame) {
-  nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
+  nsIContent* capturingContent = PresShell::GetCapturingContent();
   if (capturingContent) {
     nsIFrame* activeFrame = aPresContext->GetPrimaryFrameFor(capturingContent);
     return activeFrame ? activeFrame : aFrame;
   }
 
   return aFrame;
 }
 
@@ -4263,17 +4263,17 @@ nsFrame::HandlePress(nsPresContext* aPre
 
   bool useFrameSelection = (selectStyle == StyleUserSelect::Text);
 
   // If the mouse is dragged outside the nearest enclosing scrollable area
   // while making a selection, the area will be scrolled. To do this, capture
   // the mouse on the nearest scrollable frame. If there isn't a scrollable
   // frame, or something else is already capturing the mouse, there's no
   // reason to capture.
-  if (!nsIPresShell::GetCapturingContent()) {
+  if (!PresShell::GetCapturingContent()) {
     nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetNearestScrollableFrame(
         this, nsLayoutUtils::SCROLLABLE_SAME_DOC |
                   nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
     if (scrollFrame) {
       nsIFrame* capturingFrame = do_QueryFrame(scrollFrame);
       PresShell::SetCapturingContent(capturingFrame->GetContent(),
                                      CaptureFlags::IgnoreAllowedState);
     }
@@ -4668,17 +4668,17 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
                                      WidgetGUIEvent* aEvent,
                                      nsEventStatus* aEventStatus) {
   if (aEvent->mClass != eMouseEventClass) {
     return NS_OK;
   }
 
   nsIFrame* activeFrame = GetActiveSelectionFrame(aPresContext, this);
 
-  nsCOMPtr<nsIContent> captureContent = nsIPresShell::GetCapturingContent();
+  nsCOMPtr<nsIContent> captureContent = PresShell::GetCapturingContent();
 
   // We can unconditionally stop capturing because
   // we should never be capturing when the mouse button is up
   PresShell::ReleaseCapturingContent();
 
   bool selectionOff =
       (DisplaySelection(aPresContext) == nsISelectionController::SELECTION_OFF);
 
--- a/layout/generic/nsFrameSelection.cpp
+++ b/layout/generic/nsFrameSelection.cpp
@@ -441,17 +441,17 @@ nsresult nsFrameSelection::ConstrainFram
 
   if (content) {
     nsIContent* contentRoot = content->GetSelectionRootContent(mPresShell);
     NS_ENSURE_TRUE(contentRoot, NS_ERROR_UNEXPECTED);
 
     if (anchorRoot == contentRoot) {
       // If the aFrame's content isn't the capturing content, it should be
       // a descendant.  At this time, we can return simply.
-      nsIContent* capturedContent = nsIPresShell::GetCapturingContent();
+      nsIContent* capturedContent = PresShell::GetCapturingContent();
       if (capturedContent != content) {
         return NS_OK;
       }
 
       // Find the frame under the mouse cursor with the root frame.
       // At this time, don't use the anchor's frame because it may not have
       // fixed positioned frames.
       nsIFrame* rootFrame = mPresShell->GetRootFrame();
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -1182,17 +1182,17 @@ void nsHTMLFramesetFrame::StartMouseDrag
   }
 
   gDragInProgress = true;
 }
 
 void nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext,
                                     WidgetGUIEvent* aEvent) {
   // if the capture ended, reset the drag state
-  if (nsIPresShell::GetCapturingContent() != GetContent()) {
+  if (PresShell::GetCapturingContent() != GetContent()) {
     mDragger = nullptr;
     gDragInProgress = false;
     return;
   }
 
   int32_t change;  // measured positive from left-to-right or top-to-bottom
   AutoWeakFrame weakFrame(this);
   if (mDragger->mVertical) {
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2226,17 +2226,17 @@ nsresult nsImageFrame::GetContentForEven
   nsIFrame* f = nsLayoutUtils::GetNonGeneratedAncestor(this);
   if (f != this) {
     return f->GetContentForEvent(aEvent, aContent);
   }
 
   // XXX We need to make this special check for area element's capturing the
   // mouse due to bug 135040. Remove it once that's fixed.
   nsIContent* capturingContent = aEvent->HasMouseEventMessage()
-                                     ? nsIPresShell::GetCapturingContent()
+                                     ? PresShell::GetCapturingContent()
                                      : nullptr;
   if (capturingContent && capturingContent->GetPrimaryFrame() == this) {
     *aContent = capturingContent;
     NS_IF_ADDREF(*aContent);
     return NS_OK;
   }
 
   if (nsImageMap* map = GetImageMap()) {
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -1509,17 +1509,17 @@ nsresult nsPluginFrame::HandleEvent(nsPr
        anEvent->mMessage == eWheel) &&
       mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
     // Due to plugin code reentering Gecko, this frame may be dead at this
     // point.
     return rv;
   }
 
-  // These two calls to nsIPresShell::SetCapturingContext() (on mouse-down
+  // These two calls to PresShell::SetCapturingContent() (on mouse-down
   // and mouse-up) are needed to make the routing of mouse events while
   // dragging conform to standard OS X practice, and to the Cocoa NPAPI spec.
   // See bug 525078 and bug 909678.
   if (anEvent->mMessage == eMouseDown) {
     PresShell::SetCapturingContent(GetContent(),
                                    CaptureFlags::IgnoreAllowedState);
   }
 #endif
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -207,17 +207,16 @@ whitelist-types = [
     "mozilla::gfx::Float",
     "mozilla::gfx::FontVariation",
     "mozilla::StyleImageLayerAttachment",
     "gfxFontFeature",
     "gfxFontVariation",
     ".*ThreadSafe.*Holder",
     "AnonymousContent",
     "AudioContext",
-    "CapturingContentInfo",
     "DefaultDelete",
     "DOMIntersectionObserverEntry",
     "Element",
     "FontFamilyList",
     "FontFamilyName",
     "mozilla::FontSizePrefs",
     "FragmentOrURL",
     "FrameRequestCallback",
--- a/layout/xul/nsDeckFrame.cpp
+++ b/layout/xul/nsDeckFrame.cpp
@@ -72,17 +72,17 @@ void nsDeckFrame::Init(nsIContent* aCont
   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
 
   mIndex = GetSelectedIndex();
 }
 
 void nsDeckFrame::ShowBox(nsIFrame* aBox) { Animate(aBox, true); }
 
 void nsDeckFrame::HideBox(nsIFrame* aBox) {
-  nsIPresShell::ClearMouseCapture(aBox);
+  mozilla::PresShell::ClearMouseCapture(aBox);
   Animate(aBox, false);
 }
 
 void nsDeckFrame::IndexChanged() {
   // did the index change?
   int32_t index = GetSelectedIndex();
 
   if (index == mIndex) return;
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -1146,17 +1146,17 @@ void nsSliderFrame::DragThumb(bool aGrab
     PresShell::SetCapturingContent(GetContent(),
                                    CaptureFlags::IgnoreAllowedState);
   } else {
     PresShell::ReleaseCapturingContent();
   }
 }
 
 bool nsSliderFrame::isDraggingThumb() const {
-  return (nsIPresShell::GetCapturingContent() == GetContent());
+  return PresShell::GetCapturingContent() == GetContent();
 }
 
 void nsSliderFrame::AddListener() {
   if (!mMediator) {
     mMediator = new nsSliderMediator(this);
   }
 
   nsIFrame* thumbFrame = mFrames.FirstChild();
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -52,18 +52,18 @@ nsView::nsView(nsViewManager* aViewManag
   if (!sShowPreviousPageInitialized) {
     Preferences::AddBoolVarCache(&sShowPreviousPage,
                                  "layout.show_previous_page", true);
     sShowPreviousPageInitialized = true;
   }
 }
 
 void nsView::DropMouseGrabbing() {
-  if (PresShell* presShell = mViewManager->GetPresShell()) {
-    presShell->ClearMouseCaptureOnView(this);
+  if (mViewManager->GetPresShell()) {
+    PresShell::ClearMouseCaptureOnView(this);
   }
 }
 
 nsView::~nsView() {
   MOZ_COUNT_DTOR(nsView);
 
   while (GetFirstChild()) {
     nsView* child = GetFirstChild();
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -231,17 +231,17 @@ nsBaseDragService::InvokeDragSession(
   mSourceNode = aDOMNode;
   mContentPolicyType = aContentPolicyType;
   mEndDragPoint = LayoutDeviceIntPoint(0, 0);
 
   // When the mouse goes down, the selection code starts a mouse
   // capture. However, this gets in the way of determining drag
   // feedback for things like trees because the event coordinates
   // are in the wrong coord system, so turn off mouse capture.
-  nsIPresShell::ClearMouseCapture(nullptr);
+  PresShell::ClearMouseCapture(nullptr);
 
   uint32_t length = 0;
   mozilla::Unused << aTransferableArray->GetLength(&length);
   for (uint32_t i = 0; i < length; ++i) {
     nsCOMPtr<nsITransferable> trans = do_QueryElementAt(aTransferableArray, i);
     if (trans) {
       // Set the requestingPrincipal on the transferable.
       trans->SetRequestingPrincipal(mSourceNode->NodePrincipal());