tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 4b9ab67d81cc608a8029323433f5d1374ae8d319
parent eb132871cd06207600d97fc1408f6901259ef858
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date:   Tue,  4 Nov 2025 17:42:54 +0000

Bug 1998203 - Factor out some view code into a PresShell::GetInProcessEmbedderElement(). r=jwatt

No meaningful behavior change.

mViewManager needs to get cleared after frame destruction is done.

Differential Revision: https://phabricator.services.mozilla.com/D271246

Diffstat:
Mlayout/base/PresShell.cpp | 43++++++++++++++++++++++++++++++++-----------
Mlayout/base/PresShell.h | 4++++
Mlayout/base/nsLayoutUtils.cpp | 28+++++-----------------------
Mlayout/base/nsPresContext.cpp | 43++++++++-----------------------------------
4 files changed, 49 insertions(+), 69 deletions(-)

diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp @@ -1213,13 +1213,6 @@ void PresShell::Destroy() { mPendingScrollAnchorAdjustment.Clear(); mPendingScrollResnap.Clear(); - if (mViewManager) { - // Clear the view manager's weak pointer back to |this| in case it - // was leaked. - mViewManager->SetPresShell(nullptr); - mViewManager = nullptr; - } - // This shell must be removed from the document before the frame // hierarchy is torn down to avoid finding deleted frames through // this presshell while the frames are being torn down @@ -1261,6 +1254,13 @@ void PresShell::Destroy() { mAccessibleCaretEventHub = nullptr; } + if (mViewManager) { + // Clear the view manager's weak pointer back to |this| in case it + // was leaked. + mViewManager->SetPresShell(nullptr); + mViewManager = nullptr; + } + if (mPresContext) { // We hold a reference to the pres context, and it holds a weak link back // to us. To avoid the pres context having a dangling reference, set its @@ -5645,10 +5645,8 @@ nsIWidget* PresShell::GetNearestWidget() const { } } } - if (auto* el = mDocument->GetEmbedderElement()) { - if (auto* f = el->GetPrimaryFrame()) { - return f->GetNearestWidget(); - } + if (auto* embedder = GetInProcessEmbedderFrame()) { + return embedder->GetNearestWidget(); } return GetRootWidget(); } @@ -10355,6 +10353,29 @@ void PresShell::DidPaintWindow() { } } +nsSubDocumentFrame* PresShell::GetInProcessEmbedderFrame() const { + if (!mViewManager) { + return nullptr; + } + // We may not have a root frame yet, so use views. + nsView* view = mViewManager->GetRootView(); + if (!view) { + return nullptr; + } + view = view->GetParent(); // anonymous inner view + if (!view) { + return nullptr; + } + view = view->GetParent(); // subdocumentframe's view + if (!view) { + return nullptr; + } + + nsIFrame* f = view->GetFrame(); + MOZ_ASSERT_IF(f, f->IsSubDocumentFrame()); + return do_QueryFrame(f); +} + bool PresShell::IsVisible() const { return mIsActive && !IsUnderHiddenEmbedderElement(); } diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h @@ -76,6 +76,7 @@ class nsRange; class nsRefreshDriver; class nsRegion; class nsTextFrame; +class nsSubDocumentFrame; class nsView; class nsViewManager; class nsWindowSizes; @@ -460,6 +461,9 @@ class PresShell final : public nsStubDocumentObserver, // popup). nsIWidget* GetNearestWidget() const; + // Get the current frame of our embedder, if it's in our same process. + nsSubDocumentFrame* GetInProcessEmbedderFrame() const; + /** * Get root scroll container frame from the frame constructor. */ diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp @@ -1019,32 +1019,14 @@ nsIFrame* nsLayoutUtils::GetFloatFromPlaceholder(nsIFrame* aFrame) { // static nsIFrame* nsLayoutUtils::GetCrossDocParentFrameInProcess( const nsIFrame* aFrame, nsPoint* aCrossDocOffset) { - nsIFrame* p = aFrame->GetParent(); - if (p) { + if (nsIFrame* p = aFrame->GetParent()) { return p; } - - nsView* v = aFrame->GetView(); - if (!v) { - return nullptr; + auto* embedder = aFrame->PresShell()->GetInProcessEmbedderFrame(); + if (embedder && aCrossDocOffset) { + *aCrossDocOffset += embedder->GetExtraOffset(); } - v = v->GetParent(); // anonymous inner view - if (!v) { - return nullptr; - } - v = v->GetParent(); // subdocumentframe's view - if (!v) { - return nullptr; - } - - p = v->GetFrame(); - if (p && aCrossDocOffset) { - nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(p); - MOZ_ASSERT(subdocumentFrame); - *aCrossDocOffset += subdocumentFrame->GetExtraOffset(); - } - - return p; + return embedder; } // static diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp @@ -91,6 +91,7 @@ #include "nsPIDOMWindow.h" #include "nsPIWindowRoot.h" #include "nsRefreshDriver.h" +#include "nsSubDocumentFrame.h" #include "nsThreadUtils.h" #include "nsTransitionManager.h" #include "nsViewManager.h" @@ -1134,26 +1135,12 @@ void nsPresContext::UpdateCharSet(NotNull<const Encoding*> aCharSet) { } nsPresContext* nsPresContext::GetParentPresContext() const { - mozilla::PresShell* presShell = GetPresShell(); - if (presShell) { - nsViewManager* viewManager = presShell->GetViewManager(); - if (viewManager) { - nsView* view = viewManager->GetRootView(); - if (view) { - view = view->GetParent(); // anonymous inner view - if (view) { - view = view->GetParent(); // subdocumentframe's view - if (view) { - nsIFrame* f = view->GetFrame(); - if (f) { - return f->PresContext(); - } - } - } - } - } + mozilla::PresShell* ps = GetPresShell(); + if (!ps) { + return nullptr; } - return nullptr; + auto* embedder = ps->GetInProcessEmbedderFrame(); + return embedder ? embedder->PresContext() : nullptr; } nsPresContext* nsPresContext::GetInProcessRootContentDocumentPresContext() { @@ -2656,22 +2643,8 @@ bool nsPresContext::IsRootContentDocumentInProcess() const { if (IsChrome()) { return false; } - // We may not have a root frame, so use views. - nsView* view = PresShell()->GetViewManager()->GetRootView(); - if (!view) { - return false; - } - view = view->GetParent(); // anonymous inner view - if (!view) { - return true; - } - view = view->GetParent(); // subdocumentframe's view - if (!view) { - return true; - } - - nsIFrame* f = view->GetFrame(); - return (f && f->PresContext()->IsChrome()); + auto* embedder = PresShell()->GetInProcessEmbedderFrame(); + return !embedder || embedder->PresContext()->IsChrome(); } bool nsPresContext::IsRootContentDocumentCrossProcess() const {