Bug 1897135 Part 3 - Change two APIs to ensure root frame is a ViewportFrame. r=dholbert

Move `SetRootFrame()` to nsFrameManager.cpp, because in order to compile
`mRootFrame = aRootFrame` the compiler requires the full definition of
`ViewportFrame` to know that `ViewportFrame` is a subclass of `nsIFrame`

Differential Revision: https://phabricator.services.mozilla.com/D210671
This commit is contained in:
Ting-Yu Lin 2024-05-17 21:37:02 +00:00
parent 7e4bee6f3b
commit b174442fac
6 changed files with 30 additions and 19 deletions

View File

@ -115,6 +115,7 @@
#include "mozilla/Try.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/ViewportUtils.h"
#include "nsAnimationManager.h"
#include "nsAutoLayoutPhase.h"
@ -1766,10 +1767,10 @@ nsresult PresShell::Initialize() {
// XXXbz it would be nice to move this somewhere else... like frame manager
// Init(), say. But we need to make sure our views are all set up by the
// time we do this!
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
NS_ASSERTION(!rootFrame, "How did that happen, exactly?");
if (!rootFrame) {
MOZ_ASSERT(!mFrameConstructor->GetRootFrame(),
"How did that happen, exactly?");
ViewportFrame* rootFrame;
{
nsAutoScriptBlocker scriptBlocker;
rootFrame = mFrameConstructor->ConstructRootFrame();
mFrameConstructor->SetRootFrame(rootFrame);
@ -2458,8 +2459,7 @@ nsIFrame* PresShell::GetRootScrollFrame() const {
return nullptr;
}
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
// Ensure root frame is a viewport frame
if (!rootFrame || !rootFrame->IsViewportFrame()) {
if (!rootFrame) {
return nullptr;
}
nsIFrame* theFrame = rootFrame->PrincipalChildList().FirstChild();

View File

@ -2635,7 +2635,7 @@ RestyleManager* nsCSSFrameConstructor::RestyleManager() const {
return mPresShell->GetPresContext()->RestyleManager();
}
nsIFrame* nsCSSFrameConstructor::ConstructRootFrame() {
ViewportFrame* nsCSSFrameConstructor::ConstructRootFrame() {
AUTO_PROFILER_LABEL_HOT("nsCSSFrameConstructor::ConstructRootFrame",
LAYOUT_FrameConstruction);
AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);

View File

@ -45,6 +45,7 @@ class ComputedStyle;
class PresShell;
class PrintedSheetFrame;
class RestyleManager;
class ViewportFrame;
namespace dom {
@ -96,7 +97,7 @@ class nsCSSFrameConstructor final : public nsFrameManager {
mozilla::RestyleManager* RestyleManager() const;
nsIFrame* ConstructRootFrame();
mozilla::ViewportFrame* ConstructRootFrame();
private:
enum Operation { CONTENTAPPEND, CONTENTINSERT };

View File

@ -16,6 +16,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresState.h"
#include "mozilla/ViewportFrame.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsCOMPtr.h"
#include "nsContainerFrame.h"
@ -37,6 +38,12 @@ nsFrameManager::~nsFrameManager() {
NS_ASSERTION(!mPresShell, "nsFrameManager::Destroy never called");
}
void nsFrameManager::SetRootFrame(ViewportFrame* aRootFrame) {
MOZ_ASSERT(aRootFrame, "The root frame should be valid!");
MOZ_ASSERT(!mRootFrame, "We should set a root frame only once!");
mRootFrame = aRootFrame;
}
void nsFrameManager::Destroy() {
NS_ASSERTION(mPresShell, "Frame manager already shut down.");

View File

@ -22,6 +22,7 @@ class nsWindowSizes;
namespace mozilla {
struct FrameDestroyContext;
class PresShell;
class ViewportFrame;
} // namespace mozilla
/**
@ -35,21 +36,18 @@ class nsFrameManager {
using DestroyContext = mozilla::FrameDestroyContext;
explicit nsFrameManager(mozilla::PresShell* aPresShell)
: mPresShell(aPresShell), mRootFrame(nullptr) {
: mPresShell(aPresShell) {
MOZ_ASSERT(mPresShell, "need a pres shell");
}
~nsFrameManager();
/*
* Gets and sets the root frame (typically the viewport). The lifetime of the
* Gets and sets the root frame (i.e. ViewportFrame). The lifetime of the
* root frame is controlled by the frame manager. When the frame manager is
* destroyed, it destroys the entire frame hierarchy.
*/
nsIFrame* GetRootFrame() const { return mRootFrame; }
void SetRootFrame(nsIFrame* aRootFrame) {
NS_ASSERTION(!mRootFrame, "already have a root frame");
mRootFrame = aRootFrame;
}
void SetRootFrame(mozilla::ViewportFrame* aRootFrame);
/*
* After Destroy is called, it is an error to call any FrameManager methods.
@ -94,7 +92,11 @@ class nsFrameManager {
protected:
// weak link, because the pres shell owns us
mozilla::PresShell* MOZ_NON_OWNING_REF mPresShell;
nsIFrame* mRootFrame;
// Note: We use nsIFrame* instead of ViewportFrame* for mRootFrame to avoid
// exposing ViewportFrame to the callers via GetRootFrame(), since they do not
// depend on any ViewportFrame-specific APIs or details.
nsIFrame* mRootFrame = nullptr;
};
#endif

View File

@ -6,7 +6,7 @@
/*
* rendering object that is the root of the frame tree, which contains
* the document's scrollbars and contains fixed-positioned elements
* contains fixed-positioned elements
*/
#ifndef mozilla_ViewportFrame_h
@ -23,9 +23,10 @@ class nsDisplayWrapList;
class ServoRestyleState;
/**
* ViewportFrame is the parent of a single child - the doc root frame or a
* scroll frame containing the doc root frame. ViewportFrame stores this child
* in its primary child list.
* ViewportFrame is the parent of a single child -- the root canvas frame or a
* scroll container frame containing the root canvas frame. See
* nsCSSFrameConstructor::SetUpDocElementContainingBlock() for the root frame
* hierarchy. ViewportFrame stores this child in its primary child list.
*/
class ViewportFrame : public nsContainerFrame {
public: