summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt A. Tobin <email@mattatobin.com>2020-04-17 06:07:51 -0400
committerMatt A. Tobin <email@mattatobin.com>2020-04-17 06:07:51 -0400
commit0c99ad16fbb5c3b90ee140235159f9a0ee72397b (patch)
treea8ac891f2d7dd3864bd461feaebafd06988e21e3
parent2bcd8923f776e1c7bc716bd42c7e7912c4fe8709 (diff)
downloaduxp-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.tar.gz
Bug 1368547 - Remove nsFrameManagerBase::mPlaceholderMap and instead store the placeholder on a frame property on the out-of-flow
Tag #1375
-rw-r--r--layout/base/nsCSSFrameConstructor.cpp25
-rw-r--r--layout/base/nsFrameManager.cpp80
-rw-r--r--layout/base/nsFrameManager.h11
-rw-r--r--layout/base/nsFrameManagerBase.h1
-rw-r--r--layout/base/nsFrameTraversal.cpp3
-rw-r--r--layout/base/nsIPresShell.h6
-rw-r--r--layout/base/nsLayoutUtils.cpp3
-rw-r--r--layout/base/nsPresShell.cpp6
-rw-r--r--layout/base/nsPresShell.h1
-rw-r--r--layout/generic/ReflowInput.cpp3
-rw-r--r--layout/generic/nsAbsoluteContainingBlock.cpp21
-rw-r--r--layout/generic/nsBlockFrame.cpp15
-rw-r--r--layout/generic/nsFirstLetterFrame.cpp3
-rw-r--r--layout/generic/nsFrame.cpp15
-rw-r--r--layout/generic/nsIFrame.h13
-rw-r--r--layout/generic/nsIFrameInlines.h4
-rw-r--r--layout/generic/nsPlaceholderFrame.cpp5
-rw-r--r--layout/generic/nsTextFrame.cpp3
18 files changed, 52 insertions, 166 deletions
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index bee9ed6299..57410a55a5 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -692,10 +692,9 @@ nsAbsoluteItems::nsAbsoluteItems(nsContainerFrame* aContainingBlock)
void
nsAbsoluteItems::AddChild(nsIFrame* aChild)
{
- NS_ASSERTION(aChild->PresContext()->FrameManager()->
- GetPlaceholderFrameFor(aChild),
- "Child without placeholder being added to nsAbsoluteItems?");
aChild->AddStateBits(NS_FRAME_OUT_OF_FLOW);
+ NS_ASSERTION(aChild->GetPlaceholderFrame(),
+ "Child without placeholder being added to nsAbsoluteItems?");
nsFrameItems::AddChild(aChild);
}
@@ -3032,14 +3031,12 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
placeholderFrame->Init(aContent, aParentFrame, aPrevInFlow);
- // The placeholder frame has a pointer back to the out-of-flow frame
+ // Associate the placeholder/out-of-flow with each other.
placeholderFrame->SetOutOfFlowFrame(aFrame);
+ aFrame->SetProperty(nsIFrame::PlaceholderFrameProperty(), placeholderFrame);
aFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW);
- // Add mapping from absolutely positioned frame to its placeholder frame
- aPresShell->FrameManager()->RegisterPlaceholderFrame(placeholderFrame);
-
return placeholderFrame;
}
@@ -6702,7 +6699,7 @@ nsCSSFrameConstructor::FindFrameForContentSibling(nsIContent* aContent,
// If the frame is out-of-flow, GetPrimaryFrame() will have returned the
// out-of-flow frame; we want the placeholder.
if (sibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
- nsIFrame* placeholderFrame = GetPlaceholderFrameFor(sibling);
+ nsIFrame* placeholderFrame = sibling->GetPlaceholderFrame();
NS_ASSERTION(placeholderFrame, "no placeholder for out-of-flow frame");
sibling = placeholderFrame;
}
@@ -7968,7 +7965,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// the placeholder frame.
if (insertion.mParentFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
nsPlaceholderFrame* placeholderFrame =
- GetPlaceholderFrameFor(insertion.mParentFrame);
+ insertion.mParentFrame->GetPlaceholderFrame();
NS_ASSERTION(placeholderFrame, "No placeholder for out-of-flow?");
insertion.mParentFrame = placeholderFrame->GetParent();
} else {
@@ -8456,7 +8453,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// :first-letter style applies.
nsIFrame* inflowChild = childFrame;
if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
- inflowChild = GetPlaceholderFrameFor(childFrame);
+ inflowChild = childFrame->GetPlaceholderFrame();
NS_ASSERTION(inflowChild, "No placeholder for out-of-flow?");
}
nsContainerFrame* containingBlock =
@@ -8512,7 +8509,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// Notify the parent frame that it should delete the frame
if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
- childFrame = GetPlaceholderFrameFor(childFrame);
+ childFrame = childFrame->GetPlaceholderFrame();
NS_ASSERTION(childFrame, "Missing placeholder frame for out of flow.");
parentFrame = childFrame->GetParent();
}
@@ -9153,7 +9150,7 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
// are within fixed frames, because that would cause duplicates on the new
// page - bug 389619)
for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
- nsIFrame* prevPlaceholder = GetPlaceholderFrameFor(fixed);
+ nsIFrame* prevPlaceholder = fixed->GetPlaceholderFrame();
if (prevPlaceholder &&
nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
// We want to use the same style as the primary style frame for
@@ -9417,7 +9414,7 @@ nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
// Now check for possibly needing to reconstruct due to a pseudo parent
nsIFrame* inFlowFrame =
(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) ?
- GetPlaceholderFrameFor(aFrame) : aFrame;
+ aFrame->GetPlaceholderFrame() : aFrame;
MOZ_ASSERT(inFlowFrame, "How did that happen?");
MOZ_ASSERT(inFlowFrame == inFlowFrame->FirstContinuation(),
"placeholder for primary frame has previous continuations?");
@@ -11594,7 +11591,7 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
}
// Discover the placeholder frame for the letter frame
- nsPlaceholderFrame* placeholderFrame = GetPlaceholderFrameFor(floatFrame);
+ nsPlaceholderFrame* placeholderFrame = floatFrame->GetPlaceholderFrame();
if (!placeholderFrame) {
// Somethings really wrong
return;
diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp
index 83bcd61ec0..d703537fa5 100644
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -46,34 +46,9 @@ using namespace mozilla::dom;
//----------------------------------------------------------------------
-struct PlaceholderMapEntry : public PLDHashEntryHdr {
- // key (the out of flow frame) can be obtained through placeholder frame
- nsPlaceholderFrame *placeholderFrame;
-};
-
-static bool
-PlaceholderMapMatchEntry(const PLDHashEntryHdr *hdr, const void *key)
-{
- const PlaceholderMapEntry *entry =
- static_cast<const PlaceholderMapEntry*>(hdr);
- NS_ASSERTION(entry->placeholderFrame->GetOutOfFlowFrame() !=
- (void*)0xdddddddd,
- "Dead placeholder in placeholder map");
- return entry->placeholderFrame->GetOutOfFlowFrame() == key;
-}
-
-static const PLDHashTableOps PlaceholderMapOps = {
- PLDHashTable::HashVoidPtrKeyStub,
- PlaceholderMapMatchEntry,
- PLDHashTable::MoveEntryStub,
- PLDHashTable::ClearEntryStub,
- nullptr
-};
-
nsFrameManagerBase::nsFrameManagerBase()
: mPresShell(nullptr)
, mRootFrame(nullptr)
- , mPlaceholderMap(&PlaceholderMapOps, sizeof(PlaceholderMapEntry))
, mUndisplayedMap(nullptr)
, mDisplayContentsMap(nullptr)
, mIsDestroyingFrames(false)
@@ -142,9 +117,6 @@ nsFrameManager::Destroy()
// Destroy the frame hierarchy.
mPresShell->SetIgnoreFrameDestruction(true);
- // Unregister all placeholders before tearing down the frame tree
- nsFrameManager::ClearPlaceholderFrameMap();
-
if (mRootFrame) {
mRootFrame->Destroy();
mRootFrame = nullptr;
@@ -159,56 +131,6 @@ nsFrameManager::Destroy()
//----------------------------------------------------------------------
-// Placeholder frame functions
-nsPlaceholderFrame*
-nsFrameManager::GetPlaceholderFrameFor(const nsIFrame* aFrame)
-{
- NS_PRECONDITION(aFrame, "null param unexpected");
-
- auto entry = static_cast<PlaceholderMapEntry*>
- (const_cast<PLDHashTable*>(&mPlaceholderMap)->Search(aFrame));
- if (entry) {
- return entry->placeholderFrame;
- }
-
- return nullptr;
-}
-
-void
-nsFrameManager::RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame)
-{
- MOZ_ASSERT(aPlaceholderFrame, "null param unexpected");
- MOZ_ASSERT(nsGkAtoms::placeholderFrame == aPlaceholderFrame->GetType(),
- "unexpected frame type");
- auto entry = static_cast<PlaceholderMapEntry*>
- (mPlaceholderMap.Add(aPlaceholderFrame->GetOutOfFlowFrame()));
- MOZ_ASSERT(!entry->placeholderFrame,
- "Registering a placeholder for a frame that already has a placeholder!");
- entry->placeholderFrame = aPlaceholderFrame;
-}
-
-void
-nsFrameManager::UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame)
-{
- NS_PRECONDITION(aPlaceholderFrame, "null param unexpected");
- NS_PRECONDITION(nsGkAtoms::placeholderFrame == aPlaceholderFrame->GetType(),
- "unexpected frame type");
-
- mPlaceholderMap.Remove(aPlaceholderFrame->GetOutOfFlowFrame());
-}
-
-void
-nsFrameManager::ClearPlaceholderFrameMap()
-{
- for (auto iter = mPlaceholderMap.Iter(); !iter.Done(); iter.Next()) {
- auto entry = static_cast<PlaceholderMapEntry*>(iter.Get());
- entry->placeholderFrame->SetOutOfFlowFrame(nullptr);
- }
- mPlaceholderMap.Clear();
-}
-
-//----------------------------------------------------------------------
-
/* static */ nsStyleContext*
nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent)
{
@@ -497,7 +419,7 @@ nsFrameManager::RemoveFrame(ChildListID aListID,
aOldFrame->GetType() == nsGkAtoms::textFrame,
"Must remove first continuation.");
NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
- GetPlaceholderFrameFor(aOldFrame)),
+ aOldFrame->GetPlaceholderFrame()),
"Must call RemoveFrame on placeholder for out-of-flows.");
nsContainerFrame* parentFrame = aOldFrame->GetParent();
if (parentFrame->IsAbsoluteContainer() &&
diff --git a/layout/base/nsFrameManager.h b/layout/base/nsFrameManager.h
index bca4a581ad..84d2c93e7f 100644
--- a/layout/base/nsFrameManager.h
+++ b/layout/base/nsFrameManager.h
@@ -51,9 +51,7 @@ struct UndisplayedNode : public LinkedListElement<UndisplayedNode>
} // namespace mozilla
/**
- * Frame manager interface. The frame manager serves two purposes:
- * <li>provides a service for mapping from content to frame and from
- * out-of-flow frame to placeholder frame.
+ * Frame manager interface. The frame manager serves one purpose:
* <li>handles structural modifications to the frame model. If the frame model
* lock can be acquired, then the changes are processed immediately; otherwise,
* they're queued and processed later.
@@ -81,13 +79,6 @@ public:
*/
void Destroy();
- // Placeholder frame functions
- nsPlaceholderFrame* GetPlaceholderFrameFor(const nsIFrame* aFrame);
- void RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
- void UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
-
- void ClearPlaceholderFrameMap();
-
// Mapping undisplayed content
nsStyleContext* GetUndisplayedContent(nsIContent* aContent)
{
diff --git a/layout/base/nsFrameManagerBase.h b/layout/base/nsFrameManagerBase.h
index 757dce7e5c..bb192b64f4 100644
--- a/layout/base/nsFrameManagerBase.h
+++ b/layout/base/nsFrameManagerBase.h
@@ -53,7 +53,6 @@ protected:
// weak link, because the pres shell owns us
nsIPresShell* MOZ_NON_OWNING_REF mPresShell;
nsIFrame* mRootFrame;
- PLDHashTable mPlaceholderMap;
UndisplayedMap* mUndisplayedMap;
UndisplayedMap* mDisplayContentsMap;
bool mIsDestroyingFrames; // The frame manager is destroying some frame(s).
diff --git a/layout/base/nsFrameTraversal.cpp b/layout/base/nsFrameTraversal.cpp
index 9ea6349f44..76dd40af1a 100644
--- a/layout/base/nsFrameTraversal.cpp
+++ b/layout/base/nsFrameTraversal.cpp
@@ -493,8 +493,7 @@ nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame)
if (MOZ_LIKELY(!aFrame || !aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW))) {
return aFrame;
}
- nsIFrame* placeholder =
- aFrame->PresContext()->PresShell()->GetPlaceholderFrameFor(aFrame);
+ nsIFrame* placeholder = aFrame->GetPlaceholderFrame();
return placeholder ? placeholder : aFrame;
}
diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h
index f89639b3e1..0a5f9e6e73 100644
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -486,12 +486,6 @@ public:
virtual nsCanvasFrame* GetCanvasFrame() const = 0;
/**
- * Gets the placeholder frame associated with the specified frame. This is
- * a helper frame that forwards the request to the frame manager.
- */
- virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const = 0;
-
- /**
* Tell the pres shell that a frame needs to be marked dirty and needs
* Reflow. It's OK if this is an ancestor of the frame needing reflow as
* long as the ancestor chain between them doesn't cross a reflow root.
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index de34822460..2c44499947 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4348,8 +4348,7 @@ nsLayoutUtils::GetParentOrPlaceholderFor(nsIFrame* aFrame)
{
if ((aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
&& !aFrame->GetPrevInFlow()) {
- return aFrame->PresContext()->PresShell()->FrameManager()->
- GetPlaceholderFrameFor(aFrame);
+ return aFrame->GetProperty(nsIFrame::PlaceholderFrameProperty());
}
return aFrame->GetParent();
}
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp
index b190622c7c..2407db6505 100644
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4596,12 +4596,6 @@ PresShell::StyleRuleRemoved(StyleSheet* aStyleSheet)
RecordStyleSheetChange(aStyleSheet);
}
-nsIFrame*
-PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame) const
-{
- return mFrameConstructor->GetPlaceholderFrameFor(aFrame);
-}
-
nsresult
PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
nscolor aBackgroundColor,
diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h
index f276273fa3..c25d07e662 100644
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -130,7 +130,6 @@ public:
virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
virtual nsCanvasFrame* GetCanvasFrame() const override;
- virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const override;
virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd,
ReflowRootHandling aRootHandling =
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 78eca8c6cb..9f7b4368c3 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -1564,8 +1564,7 @@ ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
// have been if it had been in the flow
nsHypotheticalPosition hypotheticalPos;
if ((iStartIsAuto && iEndIsAuto) || (bStartIsAuto && bEndIsAuto)) {
- nsIFrame* placeholderFrame =
- aPresContext->PresShell()->GetPlaceholderFrameFor(mFrame);
+ nsPlaceholderFrame* placeholderFrame = mFrame->GetPlaceholderFrame();
NS_ASSERTION(placeholderFrame, "no placeholder frame");
if (placeholderFrame->HasAnyStateBits(
diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp
index e3c847d01b..a92a2062d5 100644
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -338,17 +338,9 @@ nsAbsoluteContainingBlock::DoMarkFramesDirty(bool aMarkAllDirty)
// Given an out-of-flow frame, this method returns the parent frame of
// its placeholder frame, if that parent is a nsContainerFrame.
static nsContainerFrame*
-GetPlaceholderContainer(nsPresContext* aPresContext,
- nsIFrame* aPositionedFrame)
+GetPlaceholderContainer(nsIFrame* aPositionedFrame)
{
- MOZ_ASSERT(aPositionedFrame, "need non-null frame");
- MOZ_ASSERT(aPositionedFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW),
- "expecting abspos frame");
- MOZ_ASSERT(aPresContext && aPresContext == aPositionedFrame->PresContext(),
- "need non-null pres context which matches our frame");
-
- nsIFrame* placeholder =
- aPresContext->PresShell()->GetPlaceholderFrameFor(aPositionedFrame);
+ nsIFrame* placeholder = aPositionedFrame->GetPlaceholderFrame();
if (!placeholder) {
return nullptr;
@@ -557,8 +549,7 @@ nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) -
aKidSize.ISize(outerWM);
} else if (aKidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
- placeholderContainer = GetPlaceholderContainer(aPresContext,
- aKidReflowInput.mFrame);
+ placeholderContainer = GetPlaceholderContainer(aKidReflowInput.mFrame);
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
logicalCBSizeOuterWM,
placeholderContainer,
@@ -579,8 +570,7 @@ nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
aKidSize.BSize(outerWM);
} else if (aKidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
if (!placeholderContainer) {
- placeholderContainer = GetPlaceholderContainer(aPresContext,
- aKidReflowInput.mFrame);
+ placeholderContainer = GetPlaceholderContainer(aKidReflowInput.mFrame);
}
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
logicalCBSizeOuterWM,
@@ -655,8 +645,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// due to the multiple coordinate spaces in play, we use a convenience flag
// to simply have the child's ReflowInput give it a static position at its
// abs.pos. CB origin, and then we'll align & offset it from there.
- nsIFrame* placeholder =
- aPresContext->PresShell()->GetPlaceholderFrameFor(aKidFrame);
+ nsIFrame* placeholder = aKidFrame->GetPlaceholderFrame();
if (placeholder && placeholder->GetParent() == aDelegatingFrame) {
rsFlags |= ReflowInput::STATIC_POS_IS_CB_ORIGIN;
}
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index a37bfc06bd..8fec6cd6a6 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -4336,8 +4336,7 @@ CheckPlaceholderInLine(nsIFrame* aBlock, nsLineBox* aLine, nsFloatCache* aFC)
"float in a line should never be a continuation");
NS_ASSERTION(!(aFC->mFloat->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
"float in a line should never be a pushed float");
- nsIFrame* ph = aBlock->PresContext()->FrameManager()->
- GetPlaceholderFrameFor(aFC->mFloat->FirstInFlow());
+ nsIFrame* ph = aFC->mFloat->FirstInFlow()->GetPlaceholderFrame();
for (nsIFrame* f = ph; f; f = f->GetParent()) {
if (f->GetParent() == aBlock)
return aLine->Contains(f);
@@ -4939,9 +4938,8 @@ nsBlockFrame::DrainSelfPushedFloats()
if (f->GetPrevContinuation()) {
// FIXME
} else {
- nsPlaceholderFrame *placeholder =
- presContext->FrameManager()->GetPlaceholderFrameFor(f);
- nsIFrame *floatOriginalParent = presContext->PresShell()->
+ nsPlaceholderFrame* placeholder = f->GetPlaceholderFrame();
+ nsIFrame* floatOriginalParent = presContext->PresShell()->
FrameConstructor()->GetFloatContainingBlock(placeholder);
if (floatOriginalParent != this) {
// This is a first continuation that was pushed from one of our
@@ -5565,7 +5563,7 @@ FindChildContaining(nsBlockFrame* aFrame, nsIFrame* aFindFrame)
return nullptr;
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
break;
- aFindFrame = aFrame->PresContext()->FrameManager()->GetPlaceholderFrameFor(child);
+ aFindFrame = child->GetPlaceholderFrame();
}
return child;
@@ -6847,9 +6845,8 @@ nsBlockFrame::ChildIsDirty(nsIFrame* aChild)
AddStateBits(NS_BLOCK_LOOK_FOR_DIRTY_FRAMES);
} else {
NS_ASSERTION(aChild->IsFloating(), "should be a float");
- nsIFrame *thisFC = FirstContinuation();
- nsIFrame *placeholderPath =
- PresContext()->FrameManager()->GetPlaceholderFrameFor(aChild);
+ nsIFrame* thisFC = FirstContinuation();
+ nsIFrame* placeholderPath = aChild->GetPlaceholderFrame();
// SVG code sometimes sends FrameNeedsReflow notifications during
// frame destruction, leading to null placeholders, but we're safe
// ignoring those.
diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp
index 980e1e9bed..5f561c7593 100644
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -320,8 +320,7 @@ nsFirstLetterFrame::CreateContinuationForFloatingParent(nsPresContext* aPresCont
*aContinuation = nullptr;
nsIPresShell* presShell = aPresContext->PresShell();
- nsPlaceholderFrame* placeholderFrame =
- presShell->FrameManager()->GetPlaceholderFrameFor(this);
+ nsPlaceholderFrame* placeholderFrame = GetPlaceholderFrame();
nsContainerFrame* parent = placeholderFrame->GetParent();
nsIFrame* continuation = presShell->FrameConstructor()->
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 25b685fb28..ea29c6945e 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -633,8 +633,7 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsIPresShell *shell = presContext->GetPresShell();
if (mState & NS_FRAME_OUT_OF_FLOW) {
- nsPlaceholderFrame* placeholder =
- shell->FrameManager()->GetPlaceholderFrameFor(this);
+ nsPlaceholderFrame* placeholder = GetPlaceholderFrame();
NS_ASSERTION(!placeholder || (aDestructRoot != this),
"Don't call Destroy() on OOFs, call Destroy() on the placeholder.");
NS_ASSERTION(!placeholder ||
@@ -642,7 +641,6 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
"Placeholder relationship should have been torn down already; "
"this might mean we have a stray placeholder in the tree.");
if (placeholder) {
- shell->FrameManager()->UnregisterPlaceholderFrame(placeholder);
placeholder->SetOutOfFlowFrame(nullptr);
}
}
@@ -8073,9 +8071,8 @@ int32_t
nsFrame::GetLineNumber(nsIFrame *aFrame, bool aLockScroll, nsIFrame** aContainingBlock)
{
NS_ASSERTION(aFrame, "null aFrame");
- nsFrameManager* frameManager = aFrame->PresContext()->FrameManager();
- nsIFrame *blockFrame = aFrame;
- nsIFrame *thisBlock;
+ nsIFrame* blockFrame = aFrame;
+ nsIFrame* thisBlock;
nsAutoLineIterator it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
@@ -8088,7 +8085,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, bool aLockScroll, nsIFrame** aContainin
// abspos continuations don't have placeholders, get the fif
thisBlock = thisBlock->FirstInFlow();
}
- thisBlock = frameManager->GetPlaceholderFrameFor(thisBlock);
+ thisBlock = thisBlock->GetPlaceholderFrame();
if (!thisBlock)
return -1;
}
@@ -9040,7 +9037,6 @@ nsStyleContext*
nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
{
*aProviderFrame = nullptr;
- nsFrameManager* fm = PresContext()->FrameManager();
// Handle display:contents and the root frame, when there's no parent frame
// to inherit from.
@@ -9057,6 +9053,7 @@ nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
/* if next is true then it's really a request for the table frame's
parent context, see nsTable[Outer]Frame::GetParentStyleContext. */
pseudo == nsCSSAnonBoxes::tableWrapper) {
+ nsFrameManager* fm = PresContext()->FrameManager();
nsStyleContext* sc = fm->GetDisplayContentsStyleFor(parentContent);
if (MOZ_UNLIKELY(sc)) {
return sc;
@@ -9093,7 +9090,7 @@ nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
// We're an out-of-flow frame. For out-of-flow frames, we must
// resolve underneath the placeholder's parent. The placeholder is
// reached from the first-in-flow.
- nsIFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow());
+ nsIFrame* placeholder = FirstInFlow()->GetPlaceholderFrame();
if (!placeholder) {
NS_NOTREACHED("no placeholder frame for out-of-flow frame");
*aProviderFrame = GetCorrectedParent(this);
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 9372b15a2a..e22dd690a8 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -82,6 +82,7 @@ class nsLineList_iterator;
class nsAbsoluteContainingBlock;
class nsIContent;
class nsContainerFrame;
+class nsPlaceholderFrame;
struct nsPeekOffsetStruct;
struct nsPoint;
@@ -729,6 +730,16 @@ public:
inline nsContainerFrame* GetInFlowParent();
/**
+ * Return the placeholder for this frame (which must be out-of-flow).
+ * @note this will only return non-null if |this| is the first-in-flow
+ * although we don't assert that here for legacy reasons.
+ */
+ inline nsPlaceholderFrame* GetPlaceholderFrame() const {
+ MOZ_ASSERT(HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
+ return GetProperty(PlaceholderFrameProperty());
+ }
+
+ /**
* Set this frame's parent to aParent.
* If the frame may have moved into or out of a scrollframe's
* frame subtree, StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary
@@ -1047,6 +1058,8 @@ public:
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData)
+ NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty, nsPlaceholderFrame)
+
mozilla::FrameBidiData GetBidiData()
{
return GetProperty(BidiDataProperty());
diff --git a/layout/generic/nsIFrameInlines.h b/layout/generic/nsIFrameInlines.h
index 3068c9f79d..a3da7ebca9 100644
--- a/layout/generic/nsIFrameInlines.h
+++ b/layout/generic/nsIFrameInlines.h
@@ -166,8 +166,8 @@ nsContainerFrame*
nsIFrame::GetInFlowParent()
{
if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
- nsFrameManager* fm = PresContext()->FrameManager();
- return fm->GetPlaceholderFrameFor(FirstContinuation())->GetParent();
+ nsIFrame* ph = FirstContinuation()->GetProperty(nsIFrame::PlaceholderFrameProperty());
+ return ph->GetParent();
}
return GetParent();
diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp
index bd380a2d98..62370a06a4 100644
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -156,16 +156,15 @@ nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
nsIFrame* oof = mOutOfFlowFrame;
if (oof) {
- // Unregister out-of-flow frame
- nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
- fm->UnregisterPlaceholderFrame(this);
mOutOfFlowFrame = nullptr;
+ oof->DeleteProperty(nsIFrame::PlaceholderFrameProperty());
// If aDestructRoot 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)
if ((GetStateBits() & PLACEHOLDER_FOR_POPUP) ||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) {
ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof);
+ nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
fm->RemoveFrame(listId, oof);
}
// else oof will be destroyed by its parent
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index 59ef020ce2..6875f33e88 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -1383,8 +1383,7 @@ BuildTextRuns(DrawTarget* aDrawTarget, nsTextFrame* aForFrame,
nsIFrame* lineContainerChild = aForFrame;
if (!aLineContainer) {
if (aForFrame->IsFloatingFirstLetterChild()) {
- lineContainerChild = aForFrame->PresContext()->PresShell()->
- GetPlaceholderFrameFor(aForFrame->GetParent());
+ lineContainerChild = aForFrame->GetParent()->GetPlaceholderFrame();
}
aLineContainer = FindLineContainer(lineContainerChild);
} else {