Bug 1547536 - Make PresShell QI-able for aware of do_QueryReferent() r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 30 Apr 2019 00:56:14 +0000
changeset 530676 d3399524b672da507007f90d6c0f849f81f3fdb9
parent 530675 39271a1d928832dec6a6418b1284bde5843c7b56
child 530677 e9a5f9d75b144d8927e75c6f3a610efd96c169a2
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
bugs1547536
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 1547536 - Make PresShell QI-able for aware of do_QueryReferent() r=smaug There is the following usage of nsIPresShell: ``` nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShellWeak); ``` So, for changing this to: ``` RefPtr<PresShell> presShell = do_QueryReferent(mPresShellWeak); ``` PresShell should have its own IID. Differential Revision: https://phabricator.services.mozilla.com/D29197
dom/base/nsGlobalWindowOuter.cpp
dom/html/nsTextEditorState.cpp
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsCaret.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsIFrame.h
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -4491,19 +4491,19 @@ void nsGlobalWindowOuter::FinishFullscre
   // and DOM fullscreen.
   FinishDOMFullscreenChange(mDoc, mFullscreen);
 
   // dispatch a "fullscreen" DOM event so that XUL apps can
   // respond visually if we are kicked into full screen mode
   DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
 
   if (!NS_WARN_IF(!IsChromeWindow())) {
-    if (nsCOMPtr<nsIPresShell> shell =
+    if (RefPtr<PresShell> presShell =
             do_QueryReferent(mChromeFields.mFullscreenPresShell)) {
-      if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
+      if (nsRefreshDriver* rd = presShell->GetRefreshDriver()) {
         rd->Thaw();
       }
       mChromeFields.mFullscreenPresShell = nullptr;
     }
   }
 
   if (!mWakeLock && mFullscreen) {
     RefPtr<power::PowerManagerService> pmService =
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -465,87 +465,95 @@ nsresult nsTextInputSelectionImpl::Repai
   if (!mFrameSelection) return NS_ERROR_FAILURE;
 
   RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
   return frameSelection->RepaintSelection(aSelectionType);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretEnabled(bool enabled) {
-  if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
-
-  nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak);
-  if (!shell) return NS_ERROR_FAILURE;
+  if (!mPresShellWeak) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  RefPtr<PresShell> presShell = do_QueryReferent(mPresShellWeak);
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
+  }
 
   // tell the pres shell to enable the caret, rather than settings its
   // visibility directly. this way the presShell's idea of caret visibility is
   // maintained.
-  nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(shell);
-  if (!selCon) return NS_ERROR_NO_INTERFACE;
-  selCon->SetCaretEnabled(enabled);
+  presShell->SetCaretEnabled(enabled);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretReadOnly(bool aReadOnly) {
-  if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
-  nsresult result;
-  nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
-  if (shell) {
-    RefPtr<nsCaret> caret = shell->GetCaret();
-    if (caret) {
-      Selection* selection =
-          mFrameSelection->GetSelection(SelectionType::eNormal);
-      if (selection) {
-        caret->SetCaretReadOnly(aReadOnly);
-      }
-      return NS_OK;
-    }
+  if (!mPresShellWeak) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  nsresult rv;
+  RefPtr<PresShell> presShell = do_QueryReferent(mPresShellWeak, &rv);
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
   }
-  return NS_ERROR_FAILURE;
+  RefPtr<nsCaret> caret = presShell->GetCaret();
+  if (!caret) {
+    return NS_ERROR_FAILURE;
+  }
+  Selection* selection = mFrameSelection->GetSelection(SelectionType::eNormal);
+  if (selection) {
+    caret->SetCaretReadOnly(aReadOnly);
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::GetCaretEnabled(bool* _retval) {
   return GetCaretVisible(_retval);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::GetCaretVisible(bool* _retval) {
-  if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
-  nsresult result;
-  nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
-  if (shell) {
-    RefPtr<nsCaret> caret = shell->GetCaret();
-    if (caret) {
-      *_retval = caret->IsVisible();
-      return NS_OK;
-    }
+  if (!mPresShellWeak) {
+    return NS_ERROR_NOT_INITIALIZED;
   }
-  return NS_ERROR_FAILURE;
+  nsresult rv;
+  RefPtr<PresShell> presShell = do_QueryReferent(mPresShellWeak, &rv);
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
+  }
+  RefPtr<nsCaret> caret = presShell->GetCaret();
+  if (!caret) {
+    return NS_ERROR_FAILURE;
+  }
+  *_retval = caret->IsVisible();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretVisibilityDuringSelection(bool aVisibility) {
-  if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
-  nsresult result;
-  nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
-  if (shell) {
-    RefPtr<nsCaret> caret = shell->GetCaret();
-    if (caret) {
-      Selection* selection =
-          mFrameSelection->GetSelection(SelectionType::eNormal);
-      if (selection) {
-        caret->SetVisibilityDuringSelection(aVisibility);
-      }
-      return NS_OK;
-    }
+  if (!mPresShellWeak) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  nsresult rv;
+  RefPtr<PresShell> presShell = do_QueryReferent(mPresShellWeak, &rv);
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
   }
-  return NS_ERROR_FAILURE;
+  RefPtr<nsCaret> caret = presShell->GetCaret();
+  if (!caret) {
+    return NS_ERROR_FAILURE;
+  }
+  Selection* selection = mFrameSelection->GetSelection(SelectionType::eNormal);
+  if (selection) {
+    caret->SetVisibilityDuringSelection(aVisibility);
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::PhysicalMove(int16_t aDirection, int16_t aAmount,
                                        bool aExtend) {
   if (mFrameSelection) {
     RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
     return frameSelection->PhysicalMove(aDirection, aAmount, aExtend);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -864,19 +864,36 @@ PresShell::PresShell()
   }
   PointerEventHandler::Initialize();
   mPaintingIsFrozen = false;
   mHasCSSBackgroundColor = true;
   mIsLastChromeOnlyEscapeKeyConsumed = false;
   mHasReceivedPaintMessage = false;
 }
 
-NS_IMPL_ISUPPORTS(PresShell, nsIPresShell, nsIDocumentObserver,
-                  nsISelectionController, nsISelectionDisplay, nsIObserver,
-                  nsISupportsWeakReference, nsIMutationObserver)
+NS_INTERFACE_TABLE_HEAD(PresShell)
+  NS_INTERFACE_TABLE_BEGIN
+    // In most cases, PresShell should be treated as concrete class, but need to
+    // QI for weak reference.  Therefore, the case needed by do_QueryReferent()
+    // should be tested first.
+    NS_INTERFACE_TABLE_ENTRY(PresShell, PresShell)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsIPresShell)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsIDocumentObserver)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsISelectionController)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsISelectionDisplay)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsIObserver)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsISupportsWeakReference)
+    NS_INTERFACE_TABLE_ENTRY(PresShell, nsIMutationObserver)
+    NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(PresShell, nsISupports, nsIObserver)
+  NS_INTERFACE_TABLE_END
+  NS_INTERFACE_TABLE_TO_MAP_SEGUE
+NS_INTERFACE_MAP_END
+
+NS_IMPL_ADDREF(PresShell)
+NS_IMPL_RELEASE(PresShell)
 
 PresShell::~PresShell() {
   MOZ_RELEASE_ASSERT(!mForbiddenToFlush,
                      "Flag should only be set temporarily, while doing things "
                      "that shouldn't cause destruction");
   MOZ_LOG(gLog, LogLevel::Debug, ("PresShell::~PresShell this=%p", this));
 
   if (!mHaveShutDown) {
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -49,16 +49,24 @@ namespace dom {
 class Element;
 class Selection;
 }  // namespace dom
 
 class EventDispatchingCallback;
 class GeckoMVMContext;
 class OverflowChangedTracker;
 
+// 039d8ffc-fa55-42d7-a53a-388cb129b052
+#define NS_PRESSHELL_IID                             \
+  {                                                  \
+    0x039d8ffc, 0xfa55, 0x42d7, {                    \
+      0xa5, 0x3a, 0x38, 0x8c, 0xb1, 0x29, 0xb0, 0x52 \
+    }                                                \
+  }
+
 class PresShell final : public nsIPresShell,
                         public nsISelectionController,
                         public nsIObserver,
                         public nsSupportsWeakReference {
   typedef layers::FocusTarget FocusTarget;
   typedef dom::Element Element;
 
   // A set type for tracking visible frames, for use by the visibility code in
@@ -66,16 +74,18 @@ class PresShell final : public nsIPresSh
   typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
 
  public:
   PresShell();
 
   // nsISupports
   NS_DECL_ISUPPORTS
 
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_PRESSHELL_IID)
+
   static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
 
   /**
    * Return the active content currently capturing the mouse if any.
    */
   static nsIContent* GetCapturingContent() {
     return sCapturingContentInfo.mContent;
   }
@@ -1642,11 +1652,13 @@ class PresShell final : public nsIPresSh
   };
   static CapturingContentInfo sCapturingContentInfo;
 
   static bool sDisableNonTestMouseEvents;
 
   static bool sProcessInteractable;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(PresShell, NS_PRESSHELL_IID)
+
 }  // namespace mozilla
 
 #endif  // mozilla_PresShell_h
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -577,17 +577,17 @@ void nsCaret::ResetBlinking() {
     return;
   }
   mBlinkRate = blinkRate;
 
   if (mBlinkTimer) {
     mBlinkTimer->Cancel();
   } else {
     nsIEventTarget* target = nullptr;
-    if (nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell)) {
+    if (RefPtr<PresShell> presShell = do_QueryReferent(mPresShell)) {
       if (nsCOMPtr<Document> doc = presShell->GetDocument()) {
         target = doc->EventTargetFor(TaskCategory::Other);
       }
     }
 
     mBlinkTimer = NS_NewTimer(target);
     if (!mBlinkTimer) {
       return;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -6158,18 +6158,18 @@ void ScrollFrameHelper::LayoutScrollbars
   if (!mPostedReflowCallback) {
     aState.PresShell()->PostReflowCallback(this);
     mPostedReflowCallback = true;
   }
 }
 
 #if DEBUG
 static bool ShellIsAlive(nsWeakPtr& aWeakPtr) {
-  nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aWeakPtr));
-  return !!shell;
+  RefPtr<PresShell> presShell = do_QueryReferent(aWeakPtr);
+  return !!presShell;
 }
 #endif
 
 void ScrollFrameHelper::SetScrollbarEnabled(Element* aElement,
                                             nscoord aMaxPos) {
   DebugOnly<nsWeakPtr> weakShell(do_GetWeakReference(mOuter->PresShell()));
   if (aMaxPos) {
     aElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -3806,30 +3806,29 @@ class nsIFrame : public nsQueryFrame {
   }
 
   /**
    * Increment the paint count of all child PresShells that were painted during
    * the last repaint.
    */
   void UpdatePaintCountForPaintedPresShells() {
     for (nsWeakPtr& item : *PaintedPresShellList()) {
-      nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
-      if (shell) {
-        shell->IncrementPaintCount();
+      if (RefPtr<mozilla::PresShell> presShell = do_QueryReferent(item)) {
+        presShell->IncrementPaintCount();
       }
     }
   }
 
   /**
    * @return true if we painted @aPresShell during the last repaint.
    */
-  bool DidPaintPresShell(mozilla::PresShell* aShell) {
+  bool DidPaintPresShell(mozilla::PresShell* aPresShell) {
     for (nsWeakPtr& item : *PaintedPresShellList()) {
-      nsCOMPtr<nsIPresShell> shell = do_QueryReferent(item);
-      if (shell == aShell) {
+      RefPtr<mozilla::PresShell> presShell = do_QueryReferent(item);
+      if (presShell == aPresShell) {
         return true;
       }
     }
     return false;
   }
 
   /**
    * Accessors for the absolute containing block.
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
+++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -1371,20 +1371,20 @@ bool nsTypeAheadFind::IsRangeRendered(Pr
 
     frames.ClearAndRetainStorage();
   }
 
   return false;
 }
 
 already_AddRefed<PresShell> nsTypeAheadFind::GetPresShell() {
-  if (!mPresShell) return nullptr;
-
-  nsCOMPtr<nsIPresShell> iPresShell = do_QueryReferent(mPresShell);
-  if (iPresShell) {
-    nsPresContext* pc = iPresShell->GetPresContext();
+  if (!mPresShell) {
+    return nullptr;
+  }
+  RefPtr<PresShell> presShell = do_QueryReferent(mPresShell);
+  if (presShell) {
+    nsPresContext* pc = presShell->GetPresContext();
     if (!pc || !pc->GetContainerWeak()) {
       return nullptr;
     }
   }
-  RefPtr<PresShell> presShell = static_cast<PresShell*>(iPresShell.get());
   return presShell.forget();
 }