Bug 1851868 - Refactor nsIFrame::Destroy to pass a single DestroyContext parameter. r=dholbert

This shouldn't change behavior, but it packs the two arguments to
DestroyFrom into a single thing, and makes nsIFrame::Destroy not so easy
to call without a previous context.

This is a prerequisite to pass aDestroyContext to various things that
right now just mint one, which can cause badness, see bug 1851787 and
related bugs.

It's also a bit nicer to add things there if we need to in the future.

Differential Revision: https://phabricator.services.mozilla.com/D187578
This commit is contained in:
Emilio Cobos Álvarez 2023-09-06 22:34:35 +00:00
Родитель cde4937cc4
Коммит 59766eeba4
87 изменённых файлов: 311 добавлений и 409 удалений

Просмотреть файл

@ -50,7 +50,8 @@ void nsFrameManager::Destroy() {
mPresShell->SetIgnoreFrameDestruction(true);
if (mRootFrame) {
mRootFrame->Destroy();
FrameDestroyContext context(mRootFrame);
mRootFrame->Destroy(context);
mRootFrame = nullptr;
}

Просмотреть файл

@ -38,10 +38,9 @@ NS_QUERYFRAME_HEAD(nsColorControlFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame)
void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mColorContent.forget());
nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsColorControlFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mColorContent.forget());
nsHTMLButtonControlFrame::Destroy(aContext);
}
#ifdef DEBUG_FRAME_DUMP

Просмотреть файл

@ -27,8 +27,7 @@ class nsColorControlFrame final : public nsHTMLButtonControlFrame,
friend nsIFrame* NS_NewColorControlFrame(mozilla::PresShell* aPresShell,
ComputedStyle* aStyle);
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsColorControlFrame)

Просмотреть файл

@ -845,17 +845,16 @@ nsIFrame* nsComboboxControlFrame::CreateFrameForDisplayNode() {
return mDisplayFrame;
}
void nsComboboxControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsComboboxControlFrame::Destroy(DestroyContext& aContext) {
// Revoke any pending RedisplayTextEvent
mRedisplayTextEvent.Revoke();
mEventListener->Detach();
// Cleanup frames in popup child list
aPostDestroyData.AddAnonymousContent(mDisplayContent.forget());
aPostDestroyData.AddAnonymousContent(mButtonContent.forget());
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
aContext.AddAnonymousContent(mDisplayContent.forget());
aContext.AddAnonymousContent(mButtonContent.forget());
nsBlockFrame::Destroy(aContext);
}
const nsFrameList& nsComboboxControlFrame::GetChildList(

Просмотреть файл

@ -105,8 +105,8 @@ class nsComboboxControlFrame final : public nsBlockFrame,
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const final;
#endif
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) final;
void Destroy(DestroyContext&) final;
void SetInitialChildList(ChildListID aListID, nsFrameList&& aChildList) final;
const nsFrameList& GetChildList(ChildListID aListID) const final;
void GetChildLists(nsTArray<ChildList>* aLists) const final;

Просмотреть файл

@ -59,8 +59,7 @@ void nsFileControlFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
mMouseListener = new DnDListener(this);
}
void nsFileControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsFileControlFrame::Destroy(DestroyContext& aContext) {
NS_ENSURE_TRUE_VOID(mContent);
// Remove the events.
@ -69,11 +68,11 @@ void nsFileControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
mContent->RemoveSystemEventListener(u"dragover"_ns, mMouseListener, false);
}
aPostDestroyData.AddAnonymousContent(mTextContent.forget());
aPostDestroyData.AddAnonymousContent(mBrowseFilesOrDirs.forget());
aContext.AddAnonymousContent(mTextContent.forget());
aContext.AddAnonymousContent(mBrowseFilesOrDirs.forget());
mMouseListener->ForgetFrame();
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsBlockFrame::Destroy(aContext);
}
static already_AddRefed<Element> MakeAnonButton(

Просмотреть файл

@ -39,8 +39,7 @@ class nsFileControlFrame final : public nsBlockFrame,
nsresult SetFormProperty(nsAtom* aName, const nsAString& aValue) override;
void SetFocus(bool aOn, bool aRepaint) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const override;

Просмотреть файл

@ -26,10 +26,9 @@ nsContainerFrame* NS_NewGfxButtonControlFrame(PresShell* aPresShell,
NS_IMPL_FRAMEARENA_HELPERS(nsGfxButtonControlFrame)
void nsGfxButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mTextContent.forget());
nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsGfxButtonControlFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mTextContent.forget());
nsHTMLButtonControlFrame::Destroy(aContext);
}
#ifdef DEBUG_FRAME_DUMP

Просмотреть файл

@ -27,8 +27,7 @@ class nsGfxButtonControlFrame final : public nsHTMLButtonControlFrame,
explicit nsGfxButtonControlFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext);
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
virtual nsresult HandleEvent(nsPresContext* aPresContext,
mozilla::WidgetGUIEvent* aEvent,

Просмотреть файл

@ -77,8 +77,7 @@ Maybe<nscoord> nsListControlFrame::GetNaturalBaselineBOffset(
return Nothing{};
}
// for Bug 47302 (remove this comment later)
void nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsListControlFrame::Destroy(DestroyContext& aContext) {
// get the receiver interface from the browser button's content node
NS_ENSURE_TRUE_VOID(mContent);
@ -86,7 +85,7 @@ void nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
// event listener can outlive the frame.
mEventListener->Detach();
nsHTMLScrollFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsHTMLScrollFrame::Destroy(aContext);
}
void nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,

Просмотреть файл

@ -77,8 +77,7 @@ class nsListControlFrame final : public nsHTMLScrollFrame,
void DidReflow(nsPresContext* aPresContext,
const ReflowInput* aReflowInput) final;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) final;
void Destroy(DestroyContext&) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) final;

Просмотреть файл

@ -38,13 +38,12 @@ nsMeterFrame::nsMeterFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
nsMeterFrame::~nsMeterFrame() = default;
void nsMeterFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsMeterFrame::Destroy(DestroyContext& aContext) {
NS_ASSERTION(!GetPrevContinuation(),
"nsMeterFrame should not have continuations; if it does we "
"need to call RegUnregAccessKey only for the first.");
aPostDestroyData.AddAnonymousContent(mBarDiv.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
aContext.AddAnonymousContent(mBarDiv.forget());
nsContainerFrame::Destroy(aContext);
}
nsresult nsMeterFrame::CreateAnonymousContent(

Просмотреть файл

@ -26,8 +26,7 @@ class nsMeterFrame final : public nsContainerFrame,
explicit nsMeterFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
virtual ~nsMeterFrame();
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
virtual void Reflow(nsPresContext* aCX, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,

Просмотреть файл

@ -41,10 +41,9 @@ nsNumberControlFrame::nsNumberControlFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext)
: nsTextControlFrame(aStyle, aPresContext, kClassID) {}
void nsNumberControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mSpinBox.forget());
nsTextControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsNumberControlFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mSpinBox.forget());
nsTextControlFrame::Destroy(aContext);
}
nsresult nsNumberControlFrame::CreateAnonymousContent(

Просмотреть файл

@ -49,7 +49,7 @@ class nsNumberControlFrame final : public nsTextControlFrame {
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsNumberControlFrame)
void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData&) override;
void Destroy(DestroyContext&) override;
#ifdef ACCESSIBILITY
mozilla::a11y::AccType AccessibleType() override;

Просмотреть файл

@ -37,13 +37,12 @@ nsProgressFrame::nsProgressFrame(ComputedStyle* aStyle,
nsProgressFrame::~nsProgressFrame() = default;
void nsProgressFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsProgressFrame::Destroy(DestroyContext& aContext) {
NS_ASSERTION(!GetPrevContinuation(),
"nsProgressFrame should not have continuations; if it does we "
"need to call RegUnregAccessKey only for the first.");
aPostDestroyData.AddAnonymousContent(mBarDiv.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
aContext.AddAnonymousContent(mBarDiv.forget());
nsContainerFrame::Destroy(aContext);
}
nsresult nsProgressFrame::CreateAnonymousContent(

Просмотреть файл

@ -28,8 +28,7 @@ class nsProgressFrame final : public nsContainerFrame,
explicit nsProgressFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
virtual ~nsProgressFrame();
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;

Просмотреть файл

@ -69,8 +69,7 @@ NS_QUERYFRAME_HEAD(nsRangeFrame)
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
void nsRangeFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsRangeFrame::Destroy(DestroyContext& aContext) {
NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
"nsRangeFrame should not have continuations; if it does we "
"need to call RegUnregAccessKey only for the first.");
@ -78,10 +77,10 @@ void nsRangeFrame::DestroyFrom(nsIFrame* aDestructRoot,
if (mListMutationObserver) {
mListMutationObserver->Detach();
}
aPostDestroyData.AddAnonymousContent(mTrackDiv.forget());
aPostDestroyData.AddAnonymousContent(mProgressDiv.forget());
aPostDestroyData.AddAnonymousContent(mThumbDiv.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
aContext.AddAnonymousContent(mTrackDiv.forget());
aContext.AddAnonymousContent(mProgressDiv.forget());
aContext.AddAnonymousContent(mThumbDiv.forget());
nsContainerFrame::Destroy(aContext);
}
nsresult nsRangeFrame::MakeAnonymousDiv(Element** aResult,

Просмотреть файл

@ -48,8 +48,7 @@ class nsRangeFrame final : public nsContainerFrame,
NS_DECL_FRAMEARENA_HELPERS(nsRangeFrame)
// nsIFrame overrides
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;

Просмотреть файл

@ -39,10 +39,9 @@ nsSearchControlFrame::nsSearchControlFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext)
: nsTextControlFrame(aStyle, aPresContext, kClassID) {}
void nsSearchControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mClearButton.forget());
nsTextControlFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsSearchControlFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mClearButton.forget());
nsTextControlFrame::Destroy(aContext);
}
nsresult nsSearchControlFrame::CreateAnonymousContent(

Просмотреть файл

@ -40,8 +40,7 @@ class nsSearchControlFrame final : public nsTextControlFrame {
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsSearchControlFrame)
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
// nsIAnonymousContentCreator
nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;

Просмотреть файл

@ -126,8 +126,7 @@ nsIScrollableFrame* nsTextControlFrame::GetScrollTargetFrame() const {
return do_QueryFrame(mRootNode->GetPrimaryFrame());
}
void nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsTextControlFrame::Destroy(DestroyContext& aContext) {
RemoveProperty(TextControlInitializer());
// Unbind the text editor state object from the frame. The editor will live
@ -166,12 +165,12 @@ void nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot,
// If we're a subclass like nsNumberControlFrame, then it owns the root of the
// anonymous subtree where mRootNode is.
aPostDestroyData.AddAnonymousContent(mRootNode.forget());
aPostDestroyData.AddAnonymousContent(mPlaceholderDiv.forget());
aPostDestroyData.AddAnonymousContent(mPreviewDiv.forget());
aPostDestroyData.AddAnonymousContent(mRevealButton.forget());
aContext.AddAnonymousContent(mRootNode.forget());
aContext.AddAnonymousContent(mPlaceholderDiv.forget());
aContext.AddAnonymousContent(mPreviewDiv.forget());
aContext.AddAnonymousContent(mRevealButton.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
LogicalSize nsTextControlFrame::CalcIntrinsicSize(

Просмотреть файл

@ -49,16 +49,14 @@ class nsTextControlFrame : public nsContainerFrame,
virtual ~nsTextControlFrame();
/**
* DestroyFrom() causes preparing to destroy editor and that may cause
* running selection listeners of specllchecker selection and document
* state listeners. Not sure whether the former does something or not,
* but nobody should run content script. The latter is currently only
* FinderHighlighter to clean up its fields at destruction. Thus, the
* latter won't run content script too. Therefore, this won't run
* unsafe script.
* Destroy() causes preparing to destroy editor and that may cause running
* selection listeners of spellchecker selection and document state listeners.
* Not sure whether the former does something or not, but nobody should run
* content script. The latter is currently only FinderHighlighter to clean up
* its fields at destruction. Thus, the latter won't run content script too.
* Therefore, this won't run unsafe script.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData&) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Destroy(DestroyContext&) override;
nsIScrollableFrame* GetScrollTargetFrame() const override;

Просмотреть файл

@ -210,10 +210,9 @@ void MiddleCroppingBlockFrame::AppendAnonymousContentTo(
aContent.AppendElement(mTextNode);
}
void MiddleCroppingBlockFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mTextNode.forget());
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void MiddleCroppingBlockFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mTextNode.forget());
nsBlockFrame::Destroy(aContext);
}
} // namespace mozilla

Просмотреть файл

@ -53,8 +53,7 @@ class MiddleCroppingBlockFrame : public nsBlockFrame,
*/
void UpdateDisplayedValue(const nsAString& aValue, bool aIsCropped,
bool aNotify);
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
RefPtr<dom::Text> mTextNode;
bool mCropped = false;

Просмотреть файл

@ -396,10 +396,8 @@ bool nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
return false;
}
void nsAbsoluteContainingBlock::DestroyFrames(
nsIFrame* aDelegatingFrame, nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
mAbsoluteFrames.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
void nsAbsoluteContainingBlock::DestroyFrames(DestroyContext& aContext) {
mAbsoluteFrames.DestroyFrames(aContext);
}
void nsAbsoluteContainingBlock::MarkSizeDependentFramesDirty() {

Просмотреть файл

@ -95,9 +95,8 @@ class nsAbsoluteContainingBlock {
const nsRect& aContainingBlock, AbsPosReflowFlags aFlags,
mozilla::OverflowAreas* aOverflowAreas);
using PostDestroyData = nsIFrame::PostDestroyData;
void DestroyFrames(nsIFrame* aDelegatingFrame, nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData);
using DestroyContext = nsIFrame::DestroyContext;
void DestroyFrames(DestroyContext&);
bool HasAbsoluteFrames() const { return mAbsoluteFrames.NotEmpty(); }

Просмотреть файл

@ -472,43 +472,39 @@ void nsBlockFrame::AddSizeOfExcludingThisForTree(
}
}
void nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsBlockFrame::Destroy(DestroyContext& aContext) {
ClearLineCursors();
DestroyAbsoluteFrames(aDestructRoot, aPostDestroyData);
mFloats.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
DestroyAbsoluteFrames(aContext);
mFloats.DestroyFrames(aContext);
nsPresContext* presContext = PresContext();
mozilla::PresShell* presShell = presContext->PresShell();
nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot, &mFrames,
aPostDestroyData);
nsLineBox::DeleteLineList(presContext, mLines, &mFrames, aContext);
if (HasPushedFloats()) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
PushedFloatProperty());
SafelyDestroyFrameListProp(aContext, presShell, PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
}
// destroy overflow lines now
FrameLines* overflowLines = RemoveOverflowLines();
if (overflowLines) {
nsLineBox::DeleteLineList(presContext, overflowLines->mLines, aDestructRoot,
&overflowLines->mFrames, aPostDestroyData);
nsLineBox::DeleteLineList(presContext, overflowLines->mLines,
&overflowLines->mFrames, aContext);
delete overflowLines;
}
if (HasAnyStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS)) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
SafelyDestroyFrameListProp(aContext, presShell,
OverflowOutOfFlowsProperty());
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
if (HasOutsideMarker()) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
OutsideMarkerProperty());
SafelyDestroyFrameListProp(aContext, presShell, OutsideMarkerProperty());
RemoveStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_MARKER);
}
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
/* virtual */
@ -5856,9 +5852,10 @@ void nsBlockFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
printf("\n");
#endif
DestroyContext context(aOldFrame);
if (aListID == FrameChildListID::Principal) {
bool hasFloats = BlockHasAnyFloats(aOldFrame);
DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS, context);
if (hasFloats) {
MarkSameFloatManagerLinesDirty(this);
}
@ -5874,10 +5871,10 @@ void nsBlockFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
MarkSameFloatManagerLinesDirty(
static_cast<nsBlockFrame*>(f->GetParent()));
}
DoRemoveOutOfFlowFrame(aOldFrame);
DoRemoveOutOfFlowFrame(aOldFrame, context);
} else if (FrameChildListID::NoReflowPrincipal == aListID) {
// Skip the call to |FrameNeedsReflow| below by returning now.
DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS, context);
return;
} else {
MOZ_CRASH("unexpected child list");
@ -6131,7 +6128,8 @@ void nsBlockFrame::RemoveFloat(nsIFrame* aFloat) {
}
}
void nsBlockFrame::DoRemoveOutOfFlowFrame(nsIFrame* aFrame) {
void nsBlockFrame::DoRemoveOutOfFlowFrame(nsIFrame* aFrame,
DestroyContext& aContext) {
// The containing block is always the parent of aFrame.
nsBlockFrame* block = (nsBlockFrame*)aFrame->GetParent();
@ -6149,7 +6147,7 @@ void nsBlockFrame::DoRemoveOutOfFlowFrame(nsIFrame* aFrame) {
// Now remove aFrame from its child list and Destroy it.
block->RemoveFloatFromFloatCache(aFrame);
block->RemoveFloat(aFrame);
aFrame->Destroy();
aFrame->Destroy(aContext);
}
}
@ -6431,9 +6429,8 @@ bool nsBlockInFlowLineIterator::FindValidLine() {
// aDeletedFrame and remove aDeletedFrame from that line. But here we
// start by locating aDeletedFrame and then scanning from that point
// on looking for continuations.
void nsBlockFrame::DoRemoveFrameInternal(nsIFrame* aDeletedFrame,
uint32_t aFlags,
PostDestroyData& aPostDestroyData) {
void nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags,
DestroyContext& aContext) {
// Clear our line cursor, since our lines may change.
ClearLineCursors();
@ -6442,8 +6439,9 @@ void nsBlockFrame::DoRemoveFrameInternal(nsIFrame* aDeletedFrame,
if (!aDeletedFrame->GetPrevInFlow()) {
NS_ASSERTION(aDeletedFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW),
"Expected out-of-flow frame");
DoRemoveOutOfFlowFrame(aDeletedFrame);
DoRemoveOutOfFlowFrame(aDeletedFrame, aContext);
} else {
// FIXME(emilio): aContext is lost here, maybe it's not a big deal?
nsContainerFrame::DeleteNextInFlowChild(aDeletedFrame,
(aFlags & FRAMES_ARE_EMPTY) != 0);
}
@ -6559,7 +6557,7 @@ void nsBlockFrame::DoRemoveFrameInternal(nsIFrame* aDeletedFrame,
deletedNextContinuation = nullptr;
}
aDeletedFrame->DestroyFrom(aDeletedFrame, aPostDestroyData);
aDeletedFrame->Destroy(aContext);
aDeletedFrame = deletedNextContinuation;
bool haveAdvancedToNextLine = false;
@ -6666,7 +6664,7 @@ void nsBlockFrame::DoRemoveFrameInternal(nsIFrame* aDeletedFrame,
nsBlockFrame* nextBlock = do_QueryFrame(aDeletedFrame->GetParent());
NS_ASSERTION(nextBlock, "Our child's continuation's parent is not a block?");
uint32_t flags = (aFlags & REMOVE_FIXED_CONTINUATIONS);
nextBlock->DoRemoveFrameInternal(aDeletedFrame, flags, aPostDestroyData);
nextBlock->DoRemoveFrame(aDeletedFrame, flags, aContext);
}
static bool FindBlockLineFor(nsIFrame* aChild, nsLineList::iterator aBegin,
@ -6780,7 +6778,9 @@ void nsBlockFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
nsLayoutUtils::AssertTreeOnlyEmptyNextInFlows(aNextInFlow);
}
#endif
DoRemoveFrame(aNextInFlow, aDeletingEmptyFrames ? FRAMES_ARE_EMPTY : 0);
DestroyContext context(aNextInFlow);
DoRemoveFrame(aNextInFlow, aDeletingEmptyFrames ? FRAMES_ARE_EMPTY : 0,
context);
}
}

Просмотреть файл

@ -136,8 +136,8 @@ class nsBlockFrame : public nsContainerFrame {
mozilla::WritingMode aWM, BaselineSharingGroup aBaselineGroup,
BaselineExportContext aExportContext) const override;
nscoord GetCaretBaseline() const override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
bool IsFloatContainingBlock() const override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
@ -551,19 +551,14 @@ class nsBlockFrame : public nsContainerFrame {
* -- destroys all removed frames
*/
enum { REMOVE_FIXED_CONTINUATIONS = 0x02, FRAMES_ARE_EMPTY = 0x04 };
void DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags) {
AutoPostDestroyData data(PresContext());
DoRemoveFrameInternal(aDeletedFrame, aFlags, data.mData);
}
void DoRemoveFrame(nsIFrame* aDeletedFrame, uint32_t aFlags, DestroyContext&);
void ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
bool aReparentSiblings);
virtual bool ComputeCustomOverflow(
mozilla::OverflowAreas& aOverflowAreas) override;
bool ComputeCustomOverflow(mozilla::OverflowAreas&) override;
virtual void UnionChildOverflow(
mozilla::OverflowAreas& aOverflowAreas) override;
void UnionChildOverflow(mozilla::OverflowAreas&) override;
/**
* Load all of aFrame's floats into the float manager iff aFrame is not a
@ -601,10 +596,6 @@ class nsBlockFrame : public nsContainerFrame {
bool IsInLineClampContext() const;
protected:
/** @see DoRemoveFrame */
void DoRemoveFrameInternal(nsIFrame* aDeletedFrame, uint32_t aFlags,
PostDestroyData& data);
/** grab overflow lines from this block's prevInFlow, and make them
* part of this block's mLines list.
* @return true if any lines were drained.
@ -677,7 +668,7 @@ class nsBlockFrame : public nsContainerFrame {
bool aCollectFromSiblings);
// Remove a float, abs, rel positioned frame from the appropriate block's list
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame, DestroyContext&);
/** set up the conditions necessary for an resize reflow
* the primary task is to mark the minimumly sufficient lines dirty.

Просмотреть файл

@ -203,19 +203,18 @@ void nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
}
}
void nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsCanvasFrame::Destroy(DestroyContext& aContext) {
nsIScrollableFrame* sf =
PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
if (sf) {
sf->RemoveScrollPositionListener(this);
}
aPostDestroyData.AddAnonymousContent(mCustomContentContainer.forget());
aContext.AddAnonymousContent(mCustomContentContainer.forget());
if (mTooltipContent) {
aPostDestroyData.AddAnonymousContent(mTooltipContent.forget());
aContext.AddAnonymousContent(mTooltipContent.forget());
}
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
void nsCanvasFrame::ScrollPositionWillChange(nscoord aX, nscoord aY) {

Просмотреть файл

@ -46,8 +46,7 @@ class nsCanvasFrame final : public nsContainerFrame,
Element* GetDefaultTooltip() override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void SetInitialChildList(ChildListID aListID,
nsFrameList&& aChildList) override;

Просмотреть файл

@ -183,7 +183,8 @@ void nsContainerFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
// We really MUST use StealFrame() and nothing else here.
// @see nsInlineFrame::StealFrame for details.
parent->StealFrame(continuation);
continuation->Destroy();
DestroyContext context(continuation);
continuation->Destroy(context);
if (generateReflowCommand && parent != lastParent) {
presShell->FrameNeedsReflow(parent, IntrinsicDirty::FrameAndAncestors,
NS_FRAME_HAS_DIRTY_CHILDREN);
@ -192,25 +193,23 @@ void nsContainerFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
}
}
void nsContainerFrame::DestroyAbsoluteFrames(
nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) {
void nsContainerFrame::DestroyAbsoluteFrames(DestroyContext& aContext) {
if (IsAbsoluteContainer()) {
GetAbsoluteContainingBlock()->DestroyFrames(this, aDestructRoot,
aPostDestroyData);
GetAbsoluteContainingBlock()->DestroyFrames(aContext);
MarkAsNotAbsoluteContainingBlock();
}
}
void nsContainerFrame::SafelyDestroyFrameListProp(
nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData,
mozilla::PresShell* aPresShell, FrameListPropertyDescriptor aProp) {
DestroyContext& aContext, mozilla::PresShell* aPresShell,
FrameListPropertyDescriptor aProp) {
// Note that the last frame can be removed through another route and thus
// delete the property -- that's why we fetch the property again before
// removing each frame rather than fetching it once and iterating the list.
while (nsFrameList* frameList = GetProperty(aProp)) {
nsIFrame* frame = frameList->RemoveFirstChild();
if (MOZ_LIKELY(frame)) {
frame->DestroyFrom(aDestructRoot, aPostDestroyData);
frame->Destroy(aContext);
} else {
Unused << TakeProperty(aProp);
frameList->Delete(aPresShell);
@ -219,17 +218,16 @@ void nsContainerFrame::SafelyDestroyFrameListProp(
}
}
void nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsContainerFrame::Destroy(DestroyContext& aContext) {
// Prevent event dispatch during destruction.
if (HasView()) {
GetView()->SetFrame(nullptr);
}
DestroyAbsoluteFrames(aDestructRoot, aPostDestroyData);
DestroyAbsoluteFrames(aContext);
// Destroy frames on the principal child list.
mFrames.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
mFrames.DestroyFrames(aContext);
// If we have any IB split siblings, clear their references to us.
if (HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
@ -275,19 +273,18 @@ void nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot,
nsPresContext* pc = PresContext();
mozilla::PresShell* presShell = pc->PresShell();
if (hasO) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
OverflowProperty());
SafelyDestroyFrameListProp(aContext, presShell, OverflowProperty());
}
MOZ_ASSERT(
IsFrameOfType(eCanContainOverflowContainers) || !(hasOC || hasEOC),
"this type of frame shouldn't have overflow containers");
if (hasOC) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
SafelyDestroyFrameListProp(aContext, presShell,
OverflowContainersProperty());
}
if (hasEOC) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
SafelyDestroyFrameListProp(aContext, presShell,
ExcessOverflowContainersProperty());
}
@ -295,12 +292,11 @@ void nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot,
StyleDisplay()->mTopLayer != StyleTopLayer::None,
"only top layer frame may have backdrop");
if (hasBackdrop) {
SafelyDestroyFrameListProp(aDestructRoot, aPostDestroyData, presShell,
BackdropProperty());
SafelyDestroyFrameListProp(aContext, presShell, BackdropProperty());
}
}
nsSplittableFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsSplittableFrame::Destroy(aContext);
}
/////////////////////////////////////////////////////////////////////////////
@ -896,8 +892,7 @@ void nsContainerFrame::ReflowChild(
// but only if the NoDeleteNextInFlowChild flag isn't set.
if (!aStatus.IsInlineBreakBefore() && aStatus.IsFullyComplete() &&
!(aFlags & ReflowChildFlags::NoDeleteNextInFlowChild)) {
nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow();
if (kidNextInFlow) {
if (nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow()) {
// Remove all of the childs next-in-flows. Make sure that we ask
// the right parent to do the removal (it's possible that the
// parent is not this because we are executing pullup code)
@ -936,8 +931,7 @@ void nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
// but only if the NoDeleteNextInFlowChild flag isn't set.
if (aStatus.IsFullyComplete() &&
!(aFlags & ReflowChildFlags::NoDeleteNextInFlowChild)) {
nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow();
if (kidNextInFlow) {
if (nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow()) {
// Remove all of the childs next-in-flows. Make sure that we ask
// the right parent to do the removal (it's possible that the
// parent is not this because we are executing pullup code)
@ -1381,8 +1375,8 @@ void nsContainerFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
frames.AppendElement(f);
}
for (nsIFrame* delFrame : Reversed(frames)) {
delFrame->GetParent()->DeleteNextInFlowChild(delFrame,
aDeletingEmptyFrames);
nsContainerFrame* parent = delFrame->GetParent();
parent->DeleteNextInFlowChild(delFrame, aDeletingEmptyFrames);
}
}
@ -1397,7 +1391,8 @@ void nsContainerFrame::DeleteNextInFlowChild(nsIFrame* aNextInFlow,
// Delete the next-in-flow frame and its descendants. This will also
// remove it from its next-in-flow/prev-in-flow chain.
aNextInFlow->Destroy();
DestroyContext context(aNextInFlow);
aNextInFlow->Destroy(context);
MOZ_ASSERT(!prevInFlow->GetNextInFlow(), "non null next-in-flow");
}

Просмотреть файл

@ -46,19 +46,19 @@ class nsContainerFrame : public nsSplittableFrame {
NS_DECL_QUERYFRAME
// nsIFrame overrides
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
virtual nsContainerFrame* GetContentInsertionFrame() override { return this; }
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
nsContainerFrame* GetContentInsertionFrame() override { return this; }
virtual const nsFrameList& GetChildList(ChildListID aList) const override;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
virtual void ChildIsDirty(nsIFrame* aChild) override;
const nsFrameList& GetChildList(ChildListID aList) const override;
void GetChildLists(nsTArray<ChildList>* aLists) const override;
void Destroy(DestroyContext&) override;
virtual FrameSearchResult PeekOffsetNoAmount(bool aForward,
int32_t* aOffset) override;
virtual FrameSearchResult PeekOffsetCharacter(
void ChildIsDirty(nsIFrame* aChild) override;
FrameSearchResult PeekOffsetNoAmount(bool aForward,
int32_t* aOffset) override;
FrameSearchResult PeekOffsetCharacter(
bool aForward, int32_t* aOffset,
PeekOffsetCharacterOptions aOptions =
PeekOffsetCharacterOptions()) override;
@ -523,8 +523,7 @@ class nsContainerFrame : public nsSplittableFrame {
* Derived classes must do that too, if they destroy such frame lists.
* See nsBlockFrame::DestroyFrom for an example.
*/
void DestroyAbsoluteFrames(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData);
void DestroyAbsoluteFrames(DestroyContext&);
/**
* Helper for StealFrame. Returns true if aChild was removed from its list.
@ -852,8 +851,7 @@ class nsContainerFrame : public nsSplittableFrame {
* frame then remove the property and delete the frame list.
* Nothing happens if the property doesn't exist.
*/
void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData,
void SafelyDestroyFrameListProp(DestroyContext&,
mozilla::PresShell* aPresShell,
FrameListPropertyDescriptor aProp);

Просмотреть файл

@ -37,17 +37,15 @@ void nsFrameList::Delete(mozilla::PresShell* aPresShell) {
void nsFrameList::DestroyFrames() {
while (nsIFrame* frame = RemoveFirstChild()) {
frame->Destroy();
FrameDestroyContext context(frame);
frame->Destroy(context);
}
mLastChild = nullptr;
}
void nsFrameList::DestroyFramesFrom(nsIFrame* aDestructRoot,
PostFrameDestroyData& aPostDestroyData) {
MOZ_ASSERT(aDestructRoot, "Missing destruct root");
void nsFrameList::DestroyFrames(FrameDestroyContext& aContext) {
while (nsIFrame* frame = RemoveFirstChild()) {
frame->DestroyFrom(aDestructRoot, aPostDestroyData);
frame->Destroy(aContext);
}
mLastChild = nullptr;
}
@ -108,7 +106,8 @@ nsIFrame* nsFrameList::RemoveFirstChild() {
void nsFrameList::DestroyFrame(nsIFrame* aFrame) {
MOZ_ASSERT(aFrame, "null ptr");
RemoveFrame(aFrame);
aFrame->Destroy();
FrameDestroyContext context(aFrame);
aFrame->Destroy(context);
}
nsFrameList::Slice nsFrameList::InsertFrames(nsContainerFrame* aParent,

Просмотреть файл

@ -26,6 +26,9 @@ class nsIFrame;
class nsPresContext;
namespace mozilla {
struct FrameDestroyContext;
class PresShell;
class FrameChildList;
enum class FrameChildListID {
@ -49,17 +52,6 @@ enum class FrameChildListID {
NoReflowPrincipal,
};
// A helper class for nsIFrame::Destroy[From]. It's defined here because
// nsFrameList needs it and we can't use nsIFrame here.
struct PostFrameDestroyData {
PostFrameDestroyData(const PostFrameDestroyData&) = delete;
PostFrameDestroyData() = default;
AutoTArray<RefPtr<nsIContent>, 100> mAnonymousContent;
void AddAnonymousContent(already_AddRefed<nsIContent>&& aContent) {
mAnonymousContent.AppendElement(aContent);
}
};
} // namespace mozilla
// Uncomment this to enable expensive frame-list integrity checking
@ -141,10 +133,9 @@ class nsFrameList {
/**
* For each frame in this list: remove it from the list then call
* DestroyFrom(aDestructRoot, aPostDestroyData) on it.
* Destroy() on it with the passed context as an argument.
*/
void DestroyFramesFrom(nsIFrame* aDestructRoot,
mozilla::PostFrameDestroyData& aPostDestroyData);
void DestroyFrames(mozilla::FrameDestroyContext&);
void Clear() { mFirstChild = mLastChild = nullptr; }

Просмотреть файл

@ -315,9 +315,8 @@ void nsHTMLScrollFrame::ScrollbarActivityStopped() const {
}
}
void nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
DestroyAbsoluteFrames(aDestructRoot, aPostDestroyData);
void nsHTMLScrollFrame::Destroy(DestroyContext& aContext) {
DestroyAbsoluteFrames(aContext);
if (mIsRoot) {
PresShell()->ResetVisualViewportOffset();
}
@ -330,10 +329,10 @@ void nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot,
}
// Unbind the content created in CreateAnonymousContent later...
aPostDestroyData.AddAnonymousContent(mHScrollbarContent.forget());
aPostDestroyData.AddAnonymousContent(mVScrollbarContent.forget());
aPostDestroyData.AddAnonymousContent(mScrollCornerContent.forget());
aPostDestroyData.AddAnonymousContent(mResizerContent.forget());
aContext.AddAnonymousContent(mHScrollbarContent.forget());
aContext.AddAnonymousContent(mVScrollbarContent.forget());
aContext.AddAnonymousContent(mScrollCornerContent.forget());
aContext.AddAnonymousContent(mResizerContent.forget());
if (mPostedReflowCallback) {
PresShell()->CancelReflowCallback(this);
@ -362,7 +361,7 @@ void nsHTMLScrollFrame::DestroyFrom(nsIFrame* aDestructRoot,
if (mScrollEndEvent) {
mScrollEndEvent->Revoke();
}
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
void nsHTMLScrollFrame::SetInitialChildList(ChildListID aListID,

Просмотреть файл

@ -150,7 +150,7 @@ class nsHTMLScrollFrame : public nsContainerFrame,
void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) final;
void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData&) override;
void Destroy(DestroyContext&) override;
nsIScrollableFrame* GetScrollTargetFrame() const final {
return const_cast<nsHTMLScrollFrame*>(this);

Просмотреть файл

@ -346,12 +346,11 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
NS_IMPL_FRAMEARENA_HELPERS(nsHTMLCanvasFrame)
void nsHTMLCanvasFrame::DestroyFrom(nsIFrame* aDestroyRoot,
PostDestroyData& aPostDestroyData) {
void nsHTMLCanvasFrame::Destroy(DestroyContext& aContext) {
if (IsPrimaryFrame()) {
HTMLCanvasElement::FromNode(*mContent)->ResetPrintCallback();
}
nsContainerFrame::DestroyFrom(aDestroyRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
nsHTMLCanvasFrame::~nsHTMLCanvasFrame() = default;

Просмотреть файл

@ -43,7 +43,7 @@ class nsHTMLCanvasFrame final : public nsContainerFrame {
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
void DestroyFrom(nsIFrame*, PostDestroyData&) override;
void Destroy(DestroyContext&) override;
bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder,
WebRenderCanvasData* aCanvasData);

Просмотреть файл

@ -217,11 +217,10 @@ static void SetOrUpdateRectValuedProperty(
}
}
/* static */
void nsIFrame::DestroyAnonymousContent(
nsPresContext* aPresContext, already_AddRefed<nsIContent>&& aContent) {
if (nsCOMPtr<nsIContent> content = aContent) {
aPresContext->PresShell()->NativeAnonymousContentRemoved(content);
FrameDestroyContext::~FrameDestroyContext() {
auto* ps = mPresContext->PresShell();
for (auto& content : mozilla::Reversed(mAnonymousContent)) {
ps->NativeAnonymousContentRemoved(content);
content->UnbindFromTree();
}
}
@ -764,13 +763,12 @@ void nsIFrame::InitPrimaryFrame() {
HandleLastRememberedSize();
}
void nsIFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsIFrame::Destroy(DestroyContext& aContext) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"destroy called on frame while scripts not blocked");
NS_ASSERTION(!GetNextSibling() && !GetPrevSibling(),
"Frames should be removed before destruction.");
NS_ASSERTION(aDestructRoot, "Must specify destruct root");
NS_ASSERTION(aContext.DestructRoot(), "Must specify destruct root");
MOZ_ASSERT(!HasAbsolutelyPositionedChildren());
MOZ_ASSERT(!HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT),
"NS_FRAME_PART_OF_IBSPLIT set on non-nsContainerFrame?");
@ -796,10 +794,10 @@ void nsIFrame::DestroyFrom(nsIFrame* aDestructRoot,
if (HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
nsPlaceholderFrame* placeholder = GetPlaceholderFrame();
NS_ASSERTION(
!placeholder || (aDestructRoot != this),
!placeholder || aContext.DestructRoot() != this,
"Don't call Destroy() on OOFs, call Destroy() on the placeholder.");
NS_ASSERTION(!placeholder || nsLayoutUtils::IsProperAncestorFrame(
aDestructRoot, placeholder),
aContext.DestructRoot(), placeholder),
"Placeholder relationship should have been torn down already; "
"this might mean we have a stray placeholder in the tree.");
if (placeholder) {
@ -869,7 +867,7 @@ void nsIFrame::DestroyFrom(nsIFrame* aDestructRoot,
// aPostDestroyData to unbind it after frame destruction is done.
if (HasAnyStateBits(NS_FRAME_GENERATED_CONTENT) &&
mContent->IsRootOfNativeAnonymousSubtree()) {
aPostDestroyData.AddAnonymousContent(mContent.forget());
aContext.AddAnonymousContent(mContent.forget());
}
}

Просмотреть файл

@ -493,6 +493,37 @@ static void ReleaseValue(T* aPropertyValue) {
//----------------------------------------------------------------------
namespace mozilla {
// A simple class to group stuff that we need to keep around when tearing down
// a frame tree.
//
// Native anonymous content created by the frames need to get unbound _after_
// the frame has been destroyed, see bug 1400618.
//
// We destroy the anonymous content bottom-up (so, in reverse order), because
// it's a bit simpler, though we generally don't have that much nested anonymous
// content (except for scrollbars).
struct MOZ_RAII FrameDestroyContext {
explicit FrameDestroyContext(nsIFrame* aRoot);
nsIFrame* DestructRoot() const { return mDestructRoot; }
void AddAnonymousContent(already_AddRefed<nsIContent>&& aContent) {
if (RefPtr<nsIContent> content = aContent) {
mAnonymousContent.AppendElement(std::move(content));
}
}
~FrameDestroyContext();
private:
nsIFrame* const mDestructRoot;
nsPresContext* const mPresContext;
AutoTArray<RefPtr<nsIContent>, 100> mAnonymousContent;
};
} // namespace mozilla
/**
* A frame in the layout model. This interface is supported by all frame
* objects.
@ -631,31 +662,7 @@ class nsIFrame : public nsQueryFrame {
void* operator new(size_t, mozilla::PresShell*) MOZ_MUST_OVERRIDE;
using PostDestroyData = mozilla::PostFrameDestroyData;
struct MOZ_RAII AutoPostDestroyData {
explicit AutoPostDestroyData(nsPresContext* aPresContext)
: mPresContext(aPresContext) {}
~AutoPostDestroyData() {
for (auto& content : mozilla::Reversed(mData.mAnonymousContent)) {
nsIFrame::DestroyAnonymousContent(mPresContext, content.forget());
}
}
nsPresContext* mPresContext;
PostDestroyData mData;
};
/**
* Destroys this frame and each of its child frames (recursively calls
* Destroy() for each child). If this frame is a first-continuation, this
* also removes the frame from the primary frame map and clears undisplayed
* content for its content node.
* If the frame is a placeholder, it also ensures the out-of-flow frame's
* removal and destruction.
*/
void Destroy() {
AutoPostDestroyData data(PresContext());
DestroyFrom(this, data.mData);
// Note that |this| is deleted at this point.
}
using DestroyContext = mozilla::FrameDestroyContext;
/**
* Flags for PeekOffsetCharacter, PeekOffsetNoAmount, PeekOffsetWord return
@ -689,32 +696,19 @@ class nsIFrame : public nsQueryFrame {
: mRespectClusters(true), mIgnoreUserStyleAll(false) {}
};
protected:
friend class nsBlockFrame; // for access to DestroyFrom
virtual void Destroy(DestroyContext&);
protected:
/**
* Return true if the frame is part of a Selection.
* Helper method to implement the public IsSelected() API.
*/
virtual bool IsFrameSelected() const;
/**
* Implements Destroy(). Do not call this directly except from within a
* DestroyFrom() implementation.
*
* @note This will always be called, so it is not necessary to override
* Destroy() in subclasses of nsFrame, just DestroyFrom().
*
* @param aDestructRoot is the root of the subtree being destroyed
*/
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData);
friend class nsFrameList; // needed to pass aDestructRoot through to children
friend class nsLineBox; // needed to pass aDestructRoot through to children
friend class nsContainerFrame; // needed to pass aDestructRoot through to
// children
template <class Source>
friend class do_QueryFrameHelper; // to read mClass
friend class nsBlockFrame; // for GetCaretBaseline
friend class nsContainerFrame; // for ReparentFrameViewTo
virtual ~nsIFrame();
@ -4900,9 +4894,6 @@ class nsIFrame : public nsQueryFrame {
void HandleLastRememberedSize();
protected:
static void DestroyAnonymousContent(nsPresContext* aPresContext,
already_AddRefed<nsIContent>&& aContent);
/**
* Reparent this frame's view if it has one.
*/
@ -5624,4 +5615,13 @@ inline nsIFrame* nsFrameList::BackwardFrameTraversal::Prev(nsIFrame* aFrame) {
return aFrame->GetNextSibling();
}
namespace mozilla {
inline FrameDestroyContext::FrameDestroyContext(nsIFrame* aRoot)
: mDestructRoot(aRoot), mPresContext(aRoot->PresContext()) {
MOZ_ASSERT(mDestructRoot);
}
} // namespace mozilla
#endif /* nsIFrame_h___ */

Просмотреть файл

@ -485,8 +485,7 @@ void nsImageFrame::DisconnectMap() {
#endif
}
void nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsImageFrame::Destroy(DestroyContext& aContext) {
MaybeSendIntrinsicSizeAndRatioToEmbedder(Nothing(), Nothing());
if (mReflowCallbackPosted) {
@ -524,7 +523,7 @@ void nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
BrokenImageIcon::RemoveObserver(this);
}
nsAtomicContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsAtomicContainerFrame::Destroy(aContext);
}
void nsImageFrame::DeinitOwnedRequest() {

Просмотреть файл

@ -70,7 +70,7 @@ class nsImageFrame : public nsAtomicContainerFrame, public nsIReflowCallback {
NS_DECL_FRAMEARENA_HELPERS(nsImageFrame)
NS_DECL_QUERYFRAME
void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData&) override;
void Destroy(DestroyContext&) override;
void DidSetComputedStyle(ComputedStyle* aOldStyle) final;
void Init(nsIContent* aContent, nsContainerFrame* aParent,

Просмотреть файл

@ -166,8 +166,7 @@ nsIFrame::FrameSearchResult nsInlineFrame::PeekOffsetCharacter(
return CONTINUE;
}
void nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsInlineFrame::Destroy(DestroyContext& aContext) {
nsFrameList* overflowFrames = GetOverflowFrames();
if (overflowFrames) {
// Fixup the parent pointers for any child frames on the OverflowList.
@ -175,7 +174,7 @@ void nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot,
// container (an ancestor).
overflowFrames->ApplySetParent(this);
}
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
void nsInlineFrame::StealFrame(nsIFrame* aChild) {

Просмотреть файл

@ -68,8 +68,8 @@ class nsInlineFrame : public nsContainerFrame {
PeekOffsetCharacterOptions aOptions =
PeekOffsetCharacterOptions()) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void StealFrame(nsIFrame* aChild) override;
// nsIHTMLReflow overrides

Просмотреть файл

@ -348,8 +348,7 @@ bool nsLineBox::CachedIsEmpty() {
}
void nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines,
nsIFrame* aDestructRoot, nsFrameList* aFrames,
PostDestroyData& aPostDestroyData) {
nsFrameList* aFrames, DestroyContext& aContext) {
PresShell* presShell = aPresContext->PresShell();
// Keep our line list and frame list up to date as we
@ -366,7 +365,7 @@ void nsLineBox::DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines,
MOZ_DIAGNOSTIC_ASSERT(child == line->mFirstChild, "Lines out of sync");
line->mFirstChild = aFrames->FirstChild();
line->NoteFrameRemoved(child);
child->DestroyFrom(aDestructRoot, aPostDestroyData);
child->Destroy(aContext);
}
MOZ_DIAGNOSTIC_ASSERT(line == aLines.front(),
"destroying child frames messed up our lines!");

Просмотреть файл

@ -396,10 +396,9 @@ class nsLineBox final : public nsLineLink {
mBounds.BSize(mWritingMode) = 0;
}
using PostDestroyData = nsIFrame::PostDestroyData;
using DestroyContext = nsIFrame::DestroyContext;
static void DeleteLineList(nsPresContext* aPresContext, nsLineList& aLines,
nsIFrame* aDestructRoot, nsFrameList* aFrames,
PostDestroyData& aPostDestroyData);
nsFrameList* aFrames, DestroyContext&);
// search from end to beginning of [aBegin, aEnd)
// Returns true if it found the line and false if not.

Просмотреть файл

@ -146,19 +146,18 @@ static FrameChildListID ChildListIDForOutOfFlow(nsFrameState aPlaceholderState,
return FrameChildListID::Float;
}
void nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsPlaceholderFrame::Destroy(DestroyContext& aContext) {
nsIFrame* oof = mOutOfFlowFrame;
if (oof) {
mOutOfFlowFrame = nullptr;
oof->RemoveProperty(nsIFrame::PlaceholderFrameProperty());
// If aDestructRoot is not an ancestor of the out-of-flow frame,
// then call RemoveFrame on it here.
// If the destruct root is not an ancestor of the out-of-flow frame, then
// call RemoveFrame on it here.
// Also destroy it here if it's a popup frame. (Bug 96291)
// FIXME(emilio): Is the popup special-case still needed?
if (oof->IsMenuPopupFrame() ||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) {
!nsLayoutUtils::IsProperAncestorFrame(aContext.DestructRoot(), oof)) {
ChildListID listId = ChildListIDForOutOfFlow(GetStateBits(), oof);
nsFrameManager* fm = PresContext()->FrameConstructor();
fm->RemoveFrame(listId, oof);
@ -166,7 +165,7 @@ void nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot,
// else oof will be destroyed by its parent
}
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
/* virtual */

Просмотреть файл

@ -102,8 +102,7 @@ class nsPlaceholderFrame final : public nsIFrame {
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
#if defined(DEBUG) || (defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF))
void BuildDisplayList(nsDisplayListBuilder* aBuilder,

Просмотреть файл

@ -260,8 +260,7 @@ void nsRubyFrame::ReflowSegment(nsPresContext* aPresContext,
// line layout is not aware of the ruby text containers, hence
// it is necessary to remove them here.
for (uint32_t i = 0; i < rtcCount; i++) {
nsIFrame* nextRTC = textContainers[i]->GetNextInFlow();
if (nextRTC) {
if (nsIFrame* nextRTC = textContainers[i]->GetNextInFlow()) {
nextRTC->GetParent()->DeleteNextInFlowChild(nextRTC, true);
}
}

Просмотреть файл

@ -26,15 +26,14 @@ void nsSplittableFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame::Init(aContent, aParent, aPrevInFlow);
}
void nsSplittableFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsSplittableFrame::Destroy(DestroyContext& aContext) {
// Disconnect from the flow list
if (mPrevContinuation || mNextContinuation) {
RemoveFromFlow(this);
}
// Let the base class destroy the frame
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
nsIFrame* nsSplittableFrame::GetPrevContinuation() const {

Просмотреть файл

@ -23,8 +23,7 @@ class nsSplittableFrame : public nsIFrame {
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
/*
* Frame continuations can be either fluid or non-fluid.

Просмотреть файл

@ -937,8 +937,7 @@ class nsHideViewer : public Runnable {
static nsView* BeginSwapDocShellsForViews(nsView* aSibling);
void nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsSubDocumentFrame::Destroy(DestroyContext& aContext) {
PropagateIsUnderHiddenEmbedderElementToSubView(true);
if (mPostedReflowCallback) {
PresShell()->CancelReflowCallback(this);
@ -971,7 +970,7 @@ void nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot,
}
}
nsAtomicContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsAtomicContainerFrame::Destroy(aContext);
}
nsFrameLoader* nsSubDocumentFrame::FrameLoader() const {

Просмотреть файл

@ -53,8 +53,7 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
nscoord GetMinISize(gfxContext* aRenderingContext) override;
nscoord GetPrefISize(gfxContext* aRenderingContext) override;

Просмотреть файл

@ -3868,8 +3868,7 @@ void nsTextFrame::ClearFrameOffsetCache() {
}
}
void nsTextFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsTextFrame::Destroy(DestroyContext& aContext) {
ClearFrameOffsetCache();
// We might want to clear NS_CREATE_FRAME_IF_NON_WHITESPACE or
@ -3880,7 +3879,7 @@ void nsTextFrame::DestroyFrom(nsIFrame* aDestructRoot,
mNextContinuation->SetPrevInFlow(nullptr);
}
// Let the base class destroy the frame
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
nsTArray<nsTextFrame*>* nsTextFrame::GetContinuations() {
@ -3922,8 +3921,7 @@ class nsContinuingTextFrame final : public nsTextFrame {
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) final;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) final;
void Destroy(DestroyContext&) override;
nsTextFrame* GetPrevContinuation() const final { return mPrevContinuation; }
@ -4089,8 +4087,7 @@ void nsContinuingTextFrame::Init(nsIContent* aContent,
} // prev frame is bidi
}
void nsContinuingTextFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsContinuingTextFrame::Destroy(DestroyContext& aContext) {
ClearFrameOffsetCache();
// The text associated with this frame will become associated with our
@ -4113,7 +4110,7 @@ void nsContinuingTextFrame::DestroyFrom(nsIFrame* aDestructRoot,
}
nsSplittableFrame::RemoveFromFlow(this);
// Let the base class destroy the frame
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
nsIFrame* nsContinuingTextFrame::FirstInFlow() const {
@ -8896,7 +8893,8 @@ static void RemoveEmptyInFlows(nsTextFrame* aFrame,
// Manually call DoRemoveFrame so we can tell it that we're
// removing empty frames; this will keep it from blowing away
// text runs.
parentBlock->DoRemoveFrame(aFrame, nsBlockFrame::FRAMES_ARE_EMPTY);
nsIFrame::DestroyContext context(aFrame);
parentBlock->DoRemoveFrame(aFrame, nsBlockFrame::FRAMES_ARE_EMPTY, context);
} else {
// Just remove it normally; use FrameChildListID::NoReflowPrincipal to avoid
// posting new reflows.

Просмотреть файл

@ -222,8 +222,7 @@ class nsTextFrame : public nsIFrame {
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
mozilla::Maybe<Cursor> GetCursor(const nsPoint&) final;

Просмотреть файл

@ -147,14 +147,13 @@ nsIContent* nsVideoFrame::GetVideoControls() const {
return mContent->GetShadowRoot()->GetFirstChild();
}
void nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsVideoFrame::Destroy(DestroyContext& aContext) {
if (mReflowCallbackPosted) {
PresShell()->CancelReflowCallback(this);
}
aPostDestroyData.AddAnonymousContent(mCaptionDiv.forget());
aPostDestroyData.AddAnonymousContent(mPosterImage.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
aContext.AddAnonymousContent(mCaptionDiv.forget());
aContext.AddAnonymousContent(mPosterImage.forget());
nsContainerFrame::Destroy(aContext);
}
class DispatchResizeEvent : public Runnable {

Просмотреть файл

@ -58,8 +58,7 @@ class nsVideoFrame final : public nsContainerFrame,
mozilla::ComputeSizeFlags aFlags) override;
nscoord GetMinISize(gfxContext* aRenderingContext) override;
nscoord GetPrefISize(gfxContext* aRenderingContext) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,

Просмотреть файл

@ -75,12 +75,11 @@ nsMathMLmunderoverFrame::InheritAutomaticData(nsIFrame* aParent) {
return NS_OK;
}
void nsMathMLmunderoverFrame::DestroyFrom(nsIFrame* aDestroyRoot,
PostDestroyData& aPostDestroyData) {
void nsMathMLmunderoverFrame::Destroy(DestroyContext& aContext) {
if (!mPostReflowIncrementScriptLevelCommands.IsEmpty()) {
PresShell()->CancelReflowCallback(this);
}
nsMathMLContainerFrame::DestroyFrom(aDestroyRoot, aPostDestroyData);
nsMathMLContainerFrame::Destroy(aContext);
}
uint8_t nsMathMLmunderoverFrame::ScriptIncrement(nsIFrame* aFrame) {

Просмотреть файл

@ -37,7 +37,7 @@ class nsMathMLmunderoverFrame final : public nsMathMLContainerFrame,
NS_IMETHOD UpdatePresentationData(uint32_t aFlagsValues,
uint32_t aFlagsToUpdate) override;
void DestroyFrom(nsIFrame* aRoot, PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;

Просмотреть файл

@ -42,8 +42,7 @@ class SVGFEImageFrame final : public nsIFrame {
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
bool IsFrameOfType(uint32_t aFlags) const override {
if (aFlags & eSupportsContainLayoutAndPaint) {
@ -85,8 +84,7 @@ namespace mozilla {
NS_IMPL_FRAMEARENA_HELPERS(SVGFEImageFrame)
/* virtual */
void SVGFEImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void SVGFEImageFrame::Destroy(DestroyContext& aContext) {
DecApproximateVisibleCount();
nsCOMPtr<nsIImageLoadingContent> imageLoader =
@ -95,7 +93,7 @@ void SVGFEImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
imageLoader->FrameDestroyed(this);
}
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
void SVGFEImageFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,

Просмотреть файл

@ -121,8 +121,7 @@ void SVGImageFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
}
/* virtual */
void SVGImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void SVGImageFrame::Destroy(DestroyContext& aContext) {
if (HasAnyStateBits(NS_FRAME_IS_NONDISPLAY)) {
DecApproximateVisibleCount();
}
@ -139,7 +138,7 @@ void SVGImageFrame::DestroyFrom(nsIFrame* aDestructRoot,
imageLoader->FrameDestroyed(this);
}
nsIFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsIFrame::Destroy(aContext);
}
/* virtual */

Просмотреть файл

@ -89,8 +89,8 @@ class SVGImageFrame final : public nsIFrame,
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void DidSetComputedStyle(ComputedStyle* aOldStyle) final;
bool IsSVGTransformed(Matrix* aOwnTransforms = nullptr,

Просмотреть файл

@ -774,15 +774,14 @@ void SVGOuterSVGFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
}
}
void SVGOuterSVGFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void SVGOuterSVGFrame::Destroy(DestroyContext& aContext) {
// This handles both the case when the root <svg> element is made display:none
// (and thus loses its intrinsic size and aspect ratio), and when the frame
// is navigated elsewhere & we need to reset parent <object>/<embed>'s
// recorded intrinsic size/ratio values.
MaybeSendIntrinsicSizeAndRatioToEmbedder(Nothing(), Nothing());
SVGDisplayContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
SVGDisplayContainerFrame::Destroy(aContext);
}
} // namespace mozilla

Просмотреть файл

@ -88,8 +88,7 @@ class SVGOuterSVGFrame final : public SVGDisplayContainerFrame,
void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;

Просмотреть файл

@ -81,10 +81,10 @@ void nsTableCellFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
}
}
void nsTableCellFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this, aDestructRoot);
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsTableCellFrame::Destroy(DestroyContext& aContext) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this,
aContext.DestructRoot());
nsContainerFrame::Destroy(aContext);
}
// nsIPercentBSizeObserver methods

Просмотреть файл

@ -66,8 +66,7 @@ class nsTableCellFrame : public nsContainerFrame,
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
#ifdef ACCESSIBILITY
mozilla::a11y::AccType AccessibleType() override;

Просмотреть файл

@ -210,10 +210,9 @@ void nsTableFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
// the header only has forward declarations of them.
nsTableFrame::~nsTableFrame() = default;
void nsTableFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
mColGroups.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsTableFrame::Destroy(DestroyContext& aContext) {
mColGroups.DestroyFrames(aContext);
nsContainerFrame::Destroy(aContext);
}
// Make sure any views are positioned properly

Просмотреть файл

@ -197,8 +197,7 @@ class nsTableFrame : public nsContainerFrame {
void RowOrColSpanChanged(nsTableCellFrame* aCellFrame);
/** @see nsIFrame::DestroyFrom */
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
/** @see nsIFrame::DidSetComputedStyle */
virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;

Просмотреть файл

@ -154,10 +154,10 @@ void nsTableRowFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
}
}
void nsTableRowFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this, aDestructRoot);
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsTableRowFrame::Destroy(DestroyContext& aContext) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this,
aContext.DestructRoot());
nsContainerFrame::Destroy(aContext);
}
/* virtual */

Просмотреть файл

@ -39,8 +39,7 @@ class nsTableRowFrame : public nsContainerFrame {
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;

Просмотреть файл

@ -62,10 +62,10 @@ nsTableRowGroupFrame::nsTableRowGroupFrame(ComputedStyle* aStyle,
nsTableRowGroupFrame::~nsTableRowGroupFrame() = default;
void nsTableRowGroupFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this, aDestructRoot);
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsTableRowGroupFrame::Destroy(DestroyContext& aContext) {
nsTableFrame::MaybeUnregisterPositionedTablePart(this,
aContext.DestructRoot());
nsContainerFrame::Destroy(aContext);
}
NS_QUERYFRAME_HEAD(nsTableRowGroupFrame)

Просмотреть файл

@ -57,8 +57,7 @@ class nsTableRowGroupFrame final : public nsContainerFrame,
}
}
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
/** @see nsIFrame::DidSetComputedStyle */
void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;

Просмотреть файл

@ -82,11 +82,10 @@ a11y::AccType nsTableWrapperFrame::AccessibleType() {
}
#endif
void nsTableWrapperFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
DestroyAbsoluteFrames(aDestructRoot, aPostDestroyData);
mCaptionFrames.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsTableWrapperFrame::Destroy(DestroyContext& aContext) {
DestroyAbsoluteFrames(aContext);
mCaptionFrames.DestroyFrames(aContext);
nsContainerFrame::Destroy(aContext);
}
const nsFrameList& nsTableWrapperFrame::GetChildList(

Просмотреть файл

@ -36,8 +36,7 @@ class nsTableWrapperFrame : public nsContainerFrame {
// nsIFrame overrides - see there for a description
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
virtual const nsFrameList& GetChildList(ChildListID aListID) const override;
virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;

Просмотреть файл

@ -2159,8 +2159,7 @@ void nsMenuPopupFrame::MoveToAttributePosition() {
this, IntrinsicDirty::FrameAncestorsAndDescendants, NS_FRAME_IS_DIRTY);
}
void nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsMenuPopupFrame::Destroy(DestroyContext& aContext) {
// XXX: Currently we don't fire popuphidden for these popups, that seems wrong
// but alas, also pre-existing.
HidePopup(/* aDeselectMenu = */ false, ePopupClosed,
@ -2170,7 +2169,7 @@ void nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot,
pm->PopupDestroyed(this);
}
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsBlockFrame::Destroy(aContext);
}
nsMargin nsMenuPopupFrame::GetMargin() const {

Просмотреть файл

@ -195,8 +195,7 @@ class nsMenuPopupFrame final : public nsBlockFrame {
int32_t aModType) override;
// FIXME: This shouldn't run script (this can end up calling HidePopup).
MOZ_CAN_RUN_SCRIPT_BOUNDARY void DestroyFrom(
nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Destroy(DestroyContext&) override;
bool HasRemoteContent() const;

Просмотреть файл

@ -264,10 +264,9 @@ nsresult nsScrollbarButtonFrame::GetParentWithTag(nsAtom* toFind,
return NS_OK;
}
void nsScrollbarButtonFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsScrollbarButtonFrame::Destroy(DestroyContext& aContext) {
// Ensure our repeat service isn't going... it's possible that a scrollbar can
// disappear out from under you while you're in the process of scrolling.
StopRepeat();
SimpleXULLeafFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
SimpleXULLeafFrame::Destroy(aContext);
}

Просмотреть файл

@ -32,8 +32,7 @@ class nsScrollbarButtonFrame final : public mozilla::SimpleXULLeafFrame {
: mozilla::SimpleXULLeafFrame(aStyle, aPresContext, kClassID) {}
// Overrides
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
friend nsIFrame* NS_NewScrollbarButtonFrame(mozilla::PresShell* aPresShell,
ComputedStyle* aStyle);

Просмотреть файл

@ -58,14 +58,13 @@ void nsScrollbarFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
AddStateBits(NS_FRAME_REFLOW_ROOT);
}
void nsScrollbarFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
aPostDestroyData.AddAnonymousContent(mUpTopButton.forget());
aPostDestroyData.AddAnonymousContent(mDownTopButton.forget());
aPostDestroyData.AddAnonymousContent(mSlider.forget());
aPostDestroyData.AddAnonymousContent(mUpBottomButton.forget());
aPostDestroyData.AddAnonymousContent(mDownBottomButton.forget());
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
void nsScrollbarFrame::Destroy(DestroyContext& aContext) {
aContext.AddAnonymousContent(mUpTopButton.forget());
aContext.AddAnonymousContent(mDownTopButton.forget());
aContext.AddAnonymousContent(mSlider.forget());
aContext.AddAnonymousContent(mUpBottomButton.forget());
aContext.AddAnonymousContent(mDownBottomButton.forget());
nsContainerFrame::Destroy(aContext);
}
void nsScrollbarFrame::Reflow(nsPresContext* aPresContext,

Просмотреть файл

@ -83,8 +83,7 @@ class nsScrollbarFrame final : public nsContainerFrame,
nsSize ScrollbarMinSize() const;
bool IsHorizontal() const;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;

Просмотреть файл

@ -1437,8 +1437,7 @@ nsSliderFrame::HandleRelease(nsPresContext* aPresContext,
return NS_OK;
}
void nsSliderFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsSliderFrame::Destroy(DestroyContext& aContext) {
// tell our mediator if we have one we are gone.
if (mMediator) {
mMediator->SetSlider(nullptr);
@ -1447,7 +1446,7 @@ void nsSliderFrame::DestroyFrom(nsIFrame* aDestructRoot,
StopRepeat();
// call base class Destroy()
nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
nsContainerFrame::Destroy(aContext);
}
void nsSliderFrame::Notify() {

Просмотреть файл

@ -73,8 +73,7 @@ class nsSliderFrame final : public nsContainerFrame {
nsReflowStatus& aStatus) override;
// nsIFrame overrides
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;

Просмотреть файл

@ -216,14 +216,13 @@ nsSplitterFrame::nsSplitterFrame(ComputedStyle* aStyle,
nsPresContext* aPresContext)
: SimpleXULLeafFrame(aStyle, aPresContext, kClassID) {}
void nsSplitterFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsSplitterFrame::Destroy(DestroyContext& aContext) {
if (mInner) {
mInner->RemoveListener();
mInner->Disconnect();
mInner = nullptr;
}
SimpleXULLeafFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
SimpleXULLeafFrame::Destroy(aContext);
}
nsresult nsSplitterFrame::AttributeChanged(int32_t aNameSpaceID,

Просмотреть файл

@ -29,8 +29,7 @@ class nsSplitterFrame final : public mozilla::SimpleXULLeafFrame {
NS_DECL_FRAMEARENA_HELPERS(nsSplitterFrame)
explicit nsSplitterFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
#ifdef DEBUG_FRAME_DUMP
nsresult GetFrameName(nsAString& aResult) const override {

Просмотреть файл

@ -298,8 +298,7 @@ void nsTreeBodyFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
}
}
void nsTreeBodyFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
void nsTreeBodyFrame::Destroy(DestroyContext& aContext) {
if (mScrollbarActivity) {
mScrollbarActivity->Destroy();
mScrollbarActivity = nullptr;
@ -334,7 +333,7 @@ void nsTreeBodyFrame::DestroyFrom(nsIFrame* aDestructRoot,
mTree->BodyDestroyed(mTopRowIndex);
}
SimpleXULLeafFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
SimpleXULLeafFrame::Destroy(aContext);
}
void nsTreeBodyFrame::EnsureView() {

Просмотреть файл

@ -157,8 +157,7 @@ class nsTreeBodyFrame final : public mozilla::SimpleXULLeafFrame,
// Overridden from nsIFrame to cache our pres context.
void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
void Destroy(DestroyContext&) override;
mozilla::Maybe<Cursor> GetCursor(const nsPoint&) override;