Bug 1368547 - Remove nsFrameManagerBase::mPlaceholderMap and instead store the placeholder on a frame property on the out-of-flow

Tag #1375
This commit is contained in:
Matt A. Tobin 2020-04-17 06:07:51 -04:00 • committed by Roy Tam
commit 9b868f0298
18 changed files with 52 additions and 166 deletions

View file

@ -692,10 +692,9 @@ nsAbsoluteItems::nsAbsoluteItems(nsContainerFrame* aContainingBlock)
void void
nsAbsoluteItems::AddChild(nsIFrame* aChild) 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); aChild->AddStateBits(NS_FRAME_OUT_OF_FLOW);
NS_ASSERTION(aChild->GetPlaceholderFrame(),
"Child without placeholder being added to nsAbsoluteItems?");
nsFrameItems::AddChild(aChild); nsFrameItems::AddChild(aChild);
} }
@ -3032,14 +3031,12 @@ nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
placeholderFrame->Init(aContent, aParentFrame, aPrevInFlow); 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); placeholderFrame->SetOutOfFlowFrame(aFrame);
aFrame->SetProperty(nsIFrame::PlaceholderFrameProperty(), placeholderFrame);
aFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW); aFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW);
// Add mapping from absolutely positioned frame to its placeholder frame
aPresShell->FrameManager()->RegisterPlaceholderFrame(placeholderFrame);
return placeholderFrame; return placeholderFrame;
} }
@ -6702,7 +6699,7 @@ nsCSSFrameConstructor::FindFrameForContentSibling(nsIContent* aContent,
// If the frame is out-of-flow, GetPrimaryFrame() will have returned the // If the frame is out-of-flow, GetPrimaryFrame() will have returned the
// out-of-flow frame; we want the placeholder. // out-of-flow frame; we want the placeholder.
if (sibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { 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"); NS_ASSERTION(placeholderFrame, "no placeholder for out-of-flow frame");
sibling = placeholderFrame; sibling = placeholderFrame;
} }
@ -7968,7 +7965,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
// the placeholder frame. // the placeholder frame.
if (insertion.mParentFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { if (insertion.mParentFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
nsPlaceholderFrame* placeholderFrame = nsPlaceholderFrame* placeholderFrame =
GetPlaceholderFrameFor(insertion.mParentFrame); insertion.mParentFrame->GetPlaceholderFrame();
NS_ASSERTION(placeholderFrame, "No placeholder for out-of-flow?"); NS_ASSERTION(placeholderFrame, "No placeholder for out-of-flow?");
insertion.mParentFrame = placeholderFrame->GetParent(); insertion.mParentFrame = placeholderFrame->GetParent();
} else { } else {
@ -8456,7 +8453,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// :first-letter style applies. // :first-letter style applies.
nsIFrame* inflowChild = childFrame; nsIFrame* inflowChild = childFrame;
if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
inflowChild = GetPlaceholderFrameFor(childFrame); inflowChild = childFrame->GetPlaceholderFrame();
NS_ASSERTION(inflowChild, "No placeholder for out-of-flow?"); NS_ASSERTION(inflowChild, "No placeholder for out-of-flow?");
} }
nsContainerFrame* containingBlock = nsContainerFrame* containingBlock =
@ -8512,7 +8509,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
// Notify the parent frame that it should delete the frame // Notify the parent frame that it should delete the frame
if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { if (childFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
childFrame = GetPlaceholderFrameFor(childFrame); childFrame = childFrame->GetPlaceholderFrame();
NS_ASSERTION(childFrame, "Missing placeholder frame for out of flow."); NS_ASSERTION(childFrame, "Missing placeholder frame for out of flow.");
parentFrame = childFrame->GetParent(); parentFrame = childFrame->GetParent();
} }
@ -9153,7 +9150,7 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
// are within fixed frames, because that would cause duplicates on the new // are within fixed frames, because that would cause duplicates on the new
// page - bug 389619) // page - bug 389619)
for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) { for (nsIFrame* fixed = firstFixed; fixed; fixed = fixed->GetNextSibling()) {
nsIFrame* prevPlaceholder = GetPlaceholderFrameFor(fixed); nsIFrame* prevPlaceholder = fixed->GetPlaceholderFrame();
if (prevPlaceholder && if (prevPlaceholder &&
nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) { nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
// We want to use the same style as the primary style frame for // 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 // Now check for possibly needing to reconstruct due to a pseudo parent
nsIFrame* inFlowFrame = nsIFrame* inFlowFrame =
(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) ? (aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) ?
GetPlaceholderFrameFor(aFrame) : aFrame; aFrame->GetPlaceholderFrame() : aFrame;
MOZ_ASSERT(inFlowFrame, "How did that happen?"); MOZ_ASSERT(inFlowFrame, "How did that happen?");
MOZ_ASSERT(inFlowFrame == inFlowFrame->FirstContinuation(), MOZ_ASSERT(inFlowFrame == inFlowFrame->FirstContinuation(),
"placeholder for primary frame has previous continuations?"); "placeholder for primary frame has previous continuations?");
@ -11594,7 +11591,7 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
} }
// Discover the placeholder frame for the letter frame // Discover the placeholder frame for the letter frame
nsPlaceholderFrame* placeholderFrame = GetPlaceholderFrameFor(floatFrame); nsPlaceholderFrame* placeholderFrame = floatFrame->GetPlaceholderFrame();
if (!placeholderFrame) { if (!placeholderFrame) {
// Somethings really wrong // Somethings really wrong
return; return;

View file

@ -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() nsFrameManagerBase::nsFrameManagerBase()
: mPresShell(nullptr) : mPresShell(nullptr)
, mRootFrame(nullptr) , mRootFrame(nullptr)
, mPlaceholderMap(&PlaceholderMapOps, sizeof(PlaceholderMapEntry))
, mUndisplayedMap(nullptr) , mUndisplayedMap(nullptr)
, mDisplayContentsMap(nullptr) , mDisplayContentsMap(nullptr)
, mIsDestroyingFrames(false) , mIsDestroyingFrames(false)
@ -142,9 +117,6 @@ nsFrameManager::Destroy()
// Destroy the frame hierarchy. // Destroy the frame hierarchy.
mPresShell->SetIgnoreFrameDestruction(true); mPresShell->SetIgnoreFrameDestruction(true);
// Unregister all placeholders before tearing down the frame tree
nsFrameManager::ClearPlaceholderFrameMap();
if (mRootFrame) { if (mRootFrame) {
mRootFrame->Destroy(); mRootFrame->Destroy();
mRootFrame = nullptr; 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* /* static */ nsStyleContext*
nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent) nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent)
{ {
@ -497,7 +419,7 @@ nsFrameManager::RemoveFrame(ChildListID aListID,
aOldFrame->GetType() == nsGkAtoms::textFrame, aOldFrame->GetType() == nsGkAtoms::textFrame,
"Must remove first continuation."); "Must remove first continuation.");
NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW && NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
GetPlaceholderFrameFor(aOldFrame)), aOldFrame->GetPlaceholderFrame()),
"Must call RemoveFrame on placeholder for out-of-flows."); "Must call RemoveFrame on placeholder for out-of-flows.");
nsContainerFrame* parentFrame = aOldFrame->GetParent(); nsContainerFrame* parentFrame = aOldFrame->GetParent();
if (parentFrame->IsAbsoluteContainer() && if (parentFrame->IsAbsoluteContainer() &&

View file

@ -51,9 +51,7 @@ struct UndisplayedNode : public LinkedListElement<UndisplayedNode>
} // namespace mozilla } // namespace mozilla
/** /**
* Frame manager interface. The frame manager serves two purposes: * Frame manager interface. The frame manager serves one purpose:
* <li>provides a service for mapping from content to frame and from
* out-of-flow frame to placeholder frame.
* <li>handles structural modifications to the frame model. If the frame model * <li>handles structural modifications to the frame model. If the frame model
* lock can be acquired, then the changes are processed immediately; otherwise, * lock can be acquired, then the changes are processed immediately; otherwise,
* they're queued and processed later. * they're queued and processed later.
@ -81,13 +79,6 @@ public:
*/ */
void Destroy(); void Destroy();
// Placeholder frame functions
nsPlaceholderFrame* GetPlaceholderFrameFor(const nsIFrame* aFrame);
void RegisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
void UnregisterPlaceholderFrame(nsPlaceholderFrame* aPlaceholderFrame);
void ClearPlaceholderFrameMap();
// Mapping undisplayed content // Mapping undisplayed content
nsStyleContext* GetUndisplayedContent(nsIContent* aContent) nsStyleContext* GetUndisplayedContent(nsIContent* aContent)
{ {

View file

@ -53,7 +53,6 @@ protected:
// weak link, because the pres shell owns us // weak link, because the pres shell owns us
nsIPresShell* MOZ_NON_OWNING_REF mPresShell; nsIPresShell* MOZ_NON_OWNING_REF mPresShell;
nsIFrame* mRootFrame; nsIFrame* mRootFrame;
PLDHashTable mPlaceholderMap;
UndisplayedMap* mUndisplayedMap; UndisplayedMap* mUndisplayedMap;
UndisplayedMap* mDisplayContentsMap; UndisplayedMap* mDisplayContentsMap;
bool mIsDestroyingFrames; // The frame manager is destroying some frame(s). bool mIsDestroyingFrames; // The frame manager is destroying some frame(s).

View file

@ -493,8 +493,7 @@ nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame)
if (MOZ_LIKELY(!aFrame || !aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW))) { if (MOZ_LIKELY(!aFrame || !aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW))) {
return aFrame; return aFrame;
} }
nsIFrame* placeholder = nsIFrame* placeholder = aFrame->GetPlaceholderFrame();
aFrame->PresContext()->PresShell()->GetPlaceholderFrameFor(aFrame);
return placeholder ? placeholder : aFrame; return placeholder ? placeholder : aFrame;
} }

View file

@ -485,12 +485,6 @@ public:
*/ */
virtual nsCanvasFrame* GetCanvasFrame() const = 0; 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 * 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 * Reflow. It's OK if this is an ancestor of the frame needing reflow as

View file

@ -4348,8 +4348,7 @@ nsLayoutUtils::GetParentOrPlaceholderFor(nsIFrame* aFrame)
{ {
if ((aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) if ((aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
&& !aFrame->GetPrevInFlow()) { && !aFrame->GetPrevInFlow()) {
return aFrame->PresContext()->PresShell()->FrameManager()-> return aFrame->GetProperty(nsIFrame::PlaceholderFrameProperty());
GetPlaceholderFrameFor(aFrame);
} }
return aFrame->GetParent(); return aFrame->GetParent();
} }

View file

@ -4596,12 +4596,6 @@ PresShell::StyleRuleRemoved(StyleSheet* aStyleSheet)
RecordStyleSheetChange(aStyleSheet); RecordStyleSheetChange(aStyleSheet);
} }
nsIFrame*
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame) const
{
return mFrameConstructor->GetPlaceholderFrameFor(aFrame);
}
nsresult nsresult
PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags, PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
nscolor aBackgroundColor, nscolor aBackgroundColor,

View file

@ -130,7 +130,6 @@ public:
virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override; virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
virtual nsCanvasFrame* GetCanvasFrame() const override; virtual nsCanvasFrame* GetCanvasFrame() const override;
virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const override;
virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty, virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd, nsFrameState aBitToAdd,
ReflowRootHandling aRootHandling = ReflowRootHandling aRootHandling =

View file

@ -1564,8 +1564,7 @@ ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext,
// have been if it had been in the flow // have been if it had been in the flow
nsHypotheticalPosition hypotheticalPos; nsHypotheticalPosition hypotheticalPos;
if ((iStartIsAuto && iEndIsAuto) || (bStartIsAuto && bEndIsAuto)) { if ((iStartIsAuto && iEndIsAuto) || (bStartIsAuto && bEndIsAuto)) {
nsIFrame* placeholderFrame = nsPlaceholderFrame* placeholderFrame = mFrame->GetPlaceholderFrame();
aPresContext->PresShell()->GetPlaceholderFrameFor(mFrame);
NS_ASSERTION(placeholderFrame, "no placeholder frame"); NS_ASSERTION(placeholderFrame, "no placeholder frame");
if (placeholderFrame->HasAnyStateBits( if (placeholderFrame->HasAnyStateBits(

View file

@ -338,17 +338,9 @@ nsAbsoluteContainingBlock::DoMarkFramesDirty(bool aMarkAllDirty)
// Given an out-of-flow frame, this method returns the parent frame of // Given an out-of-flow frame, this method returns the parent frame of
// its placeholder frame, if that parent is a nsContainerFrame. // its placeholder frame, if that parent is a nsContainerFrame.
static nsContainerFrame* static nsContainerFrame*
GetPlaceholderContainer(nsPresContext* aPresContext, GetPlaceholderContainer(nsIFrame* aPositionedFrame)
nsIFrame* aPositionedFrame)
{ {
MOZ_ASSERT(aPositionedFrame, "need non-null frame"); nsIFrame* placeholder = aPositionedFrame->GetPlaceholderFrame();
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);
if (!placeholder) { if (!placeholder) {
return nullptr; return nullptr;
@ -557,8 +549,7 @@ nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) - aOffsets->IEnd(outerWM) - aMargin.IStartEnd(outerWM) -
aKidSize.ISize(outerWM); aKidSize.ISize(outerWM);
} else if (aKidReflowInput.mFlags.mIOffsetsNeedCSSAlign) { } else if (aKidReflowInput.mFlags.mIOffsetsNeedCSSAlign) {
placeholderContainer = GetPlaceholderContainer(aPresContext, placeholderContainer = GetPlaceholderContainer(aKidReflowInput.mFrame);
aKidReflowInput.mFrame);
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize, nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
logicalCBSizeOuterWM, logicalCBSizeOuterWM,
placeholderContainer, placeholderContainer,
@ -579,8 +570,7 @@ nsAbsoluteContainingBlock::ResolveSizeDependentOffsets(
aKidSize.BSize(outerWM); aKidSize.BSize(outerWM);
} else if (aKidReflowInput.mFlags.mBOffsetsNeedCSSAlign) { } else if (aKidReflowInput.mFlags.mBOffsetsNeedCSSAlign) {
if (!placeholderContainer) { if (!placeholderContainer) {
placeholderContainer = GetPlaceholderContainer(aPresContext, placeholderContainer = GetPlaceholderContainer(aKidReflowInput.mFrame);
aKidReflowInput.mFrame);
} }
nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize, nscoord offset = OffsetToAlignedStaticPos(aKidReflowInput, aKidSize,
logicalCBSizeOuterWM, logicalCBSizeOuterWM,
@ -655,8 +645,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// due to the multiple coordinate spaces in play, we use a convenience flag // 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 // 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. // abs.pos. CB origin, and then we'll align & offset it from there.
nsIFrame* placeholder = nsIFrame* placeholder = aKidFrame->GetPlaceholderFrame();
aPresContext->PresShell()->GetPlaceholderFrameFor(aKidFrame);
if (placeholder && placeholder->GetParent() == aDelegatingFrame) { if (placeholder && placeholder->GetParent() == aDelegatingFrame) {
rsFlags |= ReflowInput::STATIC_POS_IS_CB_ORIGIN; rsFlags |= ReflowInput::STATIC_POS_IS_CB_ORIGIN;
} }

View file

@ -4336,8 +4336,7 @@ CheckPlaceholderInLine(nsIFrame* aBlock, nsLineBox* aLine, nsFloatCache* aFC)
"float in a line should never be a continuation"); "float in a line should never be a continuation");
NS_ASSERTION(!(aFC->mFloat->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT), NS_ASSERTION(!(aFC->mFloat->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
"float in a line should never be a pushed float"); "float in a line should never be a pushed float");
nsIFrame* ph = aBlock->PresContext()->FrameManager()-> nsIFrame* ph = aFC->mFloat->FirstInFlow()->GetPlaceholderFrame();
GetPlaceholderFrameFor(aFC->mFloat->FirstInFlow());
for (nsIFrame* f = ph; f; f = f->GetParent()) { for (nsIFrame* f = ph; f; f = f->GetParent()) {
if (f->GetParent() == aBlock) if (f->GetParent() == aBlock)
return aLine->Contains(f); return aLine->Contains(f);
@ -4939,9 +4938,8 @@ nsBlockFrame::DrainSelfPushedFloats()
if (f->GetPrevContinuation()) { if (f->GetPrevContinuation()) {
// FIXME // FIXME
} else { } else {
nsPlaceholderFrame *placeholder = nsPlaceholderFrame* placeholder = f->GetPlaceholderFrame();
presContext->FrameManager()->GetPlaceholderFrameFor(f); nsIFrame* floatOriginalParent = presContext->PresShell()->
nsIFrame *floatOriginalParent = presContext->PresShell()->
FrameConstructor()->GetFloatContainingBlock(placeholder); FrameConstructor()->GetFloatContainingBlock(placeholder);
if (floatOriginalParent != this) { if (floatOriginalParent != this) {
// This is a first continuation that was pushed from one of our // This is a first continuation that was pushed from one of our
@ -5565,7 +5563,7 @@ FindChildContaining(nsBlockFrame* aFrame, nsIFrame* aFindFrame)
return nullptr; return nullptr;
if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
break; break;
aFindFrame = aFrame->PresContext()->FrameManager()->GetPlaceholderFrameFor(child); aFindFrame = child->GetPlaceholderFrame();
} }
return child; return child;
@ -6847,9 +6845,8 @@ nsBlockFrame::ChildIsDirty(nsIFrame* aChild)
AddStateBits(NS_BLOCK_LOOK_FOR_DIRTY_FRAMES); AddStateBits(NS_BLOCK_LOOK_FOR_DIRTY_FRAMES);
} else { } else {
NS_ASSERTION(aChild->IsFloating(), "should be a float"); NS_ASSERTION(aChild->IsFloating(), "should be a float");
nsIFrame *thisFC = FirstContinuation(); nsIFrame* thisFC = FirstContinuation();
nsIFrame *placeholderPath = nsIFrame* placeholderPath = aChild->GetPlaceholderFrame();
PresContext()->FrameManager()->GetPlaceholderFrameFor(aChild);
// SVG code sometimes sends FrameNeedsReflow notifications during // SVG code sometimes sends FrameNeedsReflow notifications during
// frame destruction, leading to null placeholders, but we're safe // frame destruction, leading to null placeholders, but we're safe
// ignoring those. // ignoring those.

View file

@ -320,8 +320,7 @@ nsFirstLetterFrame::CreateContinuationForFloatingParent(nsPresContext* aPresCont
*aContinuation = nullptr; *aContinuation = nullptr;
nsIPresShell* presShell = aPresContext->PresShell(); nsIPresShell* presShell = aPresContext->PresShell();
nsPlaceholderFrame* placeholderFrame = nsPlaceholderFrame* placeholderFrame = GetPlaceholderFrame();
presShell->FrameManager()->GetPlaceholderFrameFor(this);
nsContainerFrame* parent = placeholderFrame->GetParent(); nsContainerFrame* parent = placeholderFrame->GetParent();
nsIFrame* continuation = presShell->FrameConstructor()-> nsIFrame* continuation = presShell->FrameConstructor()->

View file

@ -633,8 +633,7 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsIPresShell *shell = presContext->GetPresShell(); nsIPresShell *shell = presContext->GetPresShell();
if (mState & NS_FRAME_OUT_OF_FLOW) { if (mState & NS_FRAME_OUT_OF_FLOW) {
nsPlaceholderFrame* placeholder = nsPlaceholderFrame* placeholder = GetPlaceholderFrame();
shell->FrameManager()->GetPlaceholderFrameFor(this);
NS_ASSERTION(!placeholder || (aDestructRoot != this), NS_ASSERTION(!placeholder || (aDestructRoot != this),
"Don't call Destroy() on OOFs, call Destroy() on the placeholder."); "Don't call Destroy() on OOFs, call Destroy() on the placeholder.");
NS_ASSERTION(!placeholder || NS_ASSERTION(!placeholder ||
@ -642,7 +641,6 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
"Placeholder relationship should have been torn down already; " "Placeholder relationship should have been torn down already; "
"this might mean we have a stray placeholder in the tree."); "this might mean we have a stray placeholder in the tree.");
if (placeholder) { if (placeholder) {
shell->FrameManager()->UnregisterPlaceholderFrame(placeholder);
placeholder->SetOutOfFlowFrame(nullptr); placeholder->SetOutOfFlowFrame(nullptr);
} }
} }
@ -8060,9 +8058,8 @@ int32_t
nsFrame::GetLineNumber(nsIFrame *aFrame, bool aLockScroll, nsIFrame** aContainingBlock) nsFrame::GetLineNumber(nsIFrame *aFrame, bool aLockScroll, nsIFrame** aContainingBlock)
{ {
NS_ASSERTION(aFrame, "null aFrame"); NS_ASSERTION(aFrame, "null aFrame");
nsFrameManager* frameManager = aFrame->PresContext()->FrameManager(); nsIFrame* blockFrame = aFrame;
nsIFrame *blockFrame = aFrame; nsIFrame* thisBlock;
nsIFrame *thisBlock;
nsAutoLineIterator it; nsAutoLineIterator it;
nsresult result = NS_ERROR_FAILURE; nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame) while (NS_FAILED(result) && blockFrame)
@ -8075,7 +8072,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, bool aLockScroll, nsIFrame** aContainin
// abspos continuations don't have placeholders, get the fif // abspos continuations don't have placeholders, get the fif
thisBlock = thisBlock->FirstInFlow(); thisBlock = thisBlock->FirstInFlow();
} }
thisBlock = frameManager->GetPlaceholderFrameFor(thisBlock); thisBlock = thisBlock->GetPlaceholderFrame();
if (!thisBlock) if (!thisBlock)
return -1; return -1;
} }
@ -9027,7 +9024,6 @@ nsStyleContext*
nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
{ {
*aProviderFrame = nullptr; *aProviderFrame = nullptr;
nsFrameManager* fm = PresContext()->FrameManager();
// Handle display:contents and the root frame, when there's no parent frame // Handle display:contents and the root frame, when there's no parent frame
// to inherit from. // to inherit from.
@ -9044,6 +9040,7 @@ nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
/* if next is true then it's really a request for the table frame's /* if next is true then it's really a request for the table frame's
parent context, see nsTable[Outer]Frame::GetParentStyleContext. */ parent context, see nsTable[Outer]Frame::GetParentStyleContext. */
pseudo == nsCSSAnonBoxes::tableWrapper) { pseudo == nsCSSAnonBoxes::tableWrapper) {
nsFrameManager* fm = PresContext()->FrameManager();
nsStyleContext* sc = fm->GetDisplayContentsStyleFor(parentContent); nsStyleContext* sc = fm->GetDisplayContentsStyleFor(parentContent);
if (MOZ_UNLIKELY(sc)) { if (MOZ_UNLIKELY(sc)) {
return sc; return sc;
@ -9080,7 +9077,7 @@ nsFrame::DoGetParentStyleContext(nsIFrame** aProviderFrame) const
// We're an out-of-flow frame. For out-of-flow frames, we must // We're an out-of-flow frame. For out-of-flow frames, we must
// resolve underneath the placeholder's parent. The placeholder is // resolve underneath the placeholder's parent. The placeholder is
// reached from the first-in-flow. // reached from the first-in-flow.
nsIFrame* placeholder = fm->GetPlaceholderFrameFor(FirstInFlow()); nsIFrame* placeholder = FirstInFlow()->GetPlaceholderFrame();
if (!placeholder) { if (!placeholder) {
NS_NOTREACHED("no placeholder frame for out-of-flow frame"); NS_NOTREACHED("no placeholder frame for out-of-flow frame");
*aProviderFrame = GetCorrectedParent(this); *aProviderFrame = GetCorrectedParent(this);

View file

@ -82,6 +82,7 @@ class nsLineList_iterator;
class nsAbsoluteContainingBlock; class nsAbsoluteContainingBlock;
class nsIContent; class nsIContent;
class nsContainerFrame; class nsContainerFrame;
class nsPlaceholderFrame;
struct nsPeekOffsetStruct; struct nsPeekOffsetStruct;
struct nsPoint; struct nsPoint;
@ -728,6 +729,16 @@ public:
*/ */
inline nsContainerFrame* GetInFlowParent(); 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. * Set this frame's parent to aParent.
* If the frame may have moved into or out of a scrollframe's * If the frame may have moved into or out of a scrollframe's
@ -1047,6 +1058,8 @@ public:
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData) NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData)
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty, nsPlaceholderFrame)
mozilla::FrameBidiData GetBidiData() mozilla::FrameBidiData GetBidiData()
{ {
return GetProperty(BidiDataProperty()); return GetProperty(BidiDataProperty());

View file

@ -166,8 +166,8 @@ nsContainerFrame*
nsIFrame::GetInFlowParent() nsIFrame::GetInFlowParent()
{ {
if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
nsFrameManager* fm = PresContext()->FrameManager(); nsIFrame* ph = FirstContinuation()->GetProperty(nsIFrame::PlaceholderFrameProperty());
return fm->GetPlaceholderFrameFor(FirstContinuation())->GetParent(); return ph->GetParent();
} }
return GetParent(); return GetParent();

View file

@ -156,16 +156,15 @@ nsPlaceholderFrame::DestroyFrom(nsIFrame* aDestructRoot)
{ {
nsIFrame* oof = mOutOfFlowFrame; nsIFrame* oof = mOutOfFlowFrame;
if (oof) { if (oof) {
// Unregister out-of-flow frame
nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
fm->UnregisterPlaceholderFrame(this);
mOutOfFlowFrame = nullptr; mOutOfFlowFrame = nullptr;
oof->DeleteProperty(nsIFrame::PlaceholderFrameProperty());
// If aDestructRoot is not an ancestor of the out-of-flow frame, // If aDestructRoot is not an ancestor of the out-of-flow frame,
// then call RemoveFrame on it here. // then call RemoveFrame on it here.
// Also destroy it here if it's a popup frame. (Bug 96291) // Also destroy it here if it's a popup frame. (Bug 96291)
if ((GetStateBits() & PLACEHOLDER_FOR_POPUP) || if ((GetStateBits() & PLACEHOLDER_FOR_POPUP) ||
!nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) { !nsLayoutUtils::IsProperAncestorFrame(aDestructRoot, oof)) {
ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof); ChildListID listId = nsLayoutUtils::GetChildListNameFor(oof);
nsFrameManager* fm = PresContext()->GetPresShell()->FrameManager();
fm->RemoveFrame(listId, oof); fm->RemoveFrame(listId, oof);
} }
// else oof will be destroyed by its parent // else oof will be destroyed by its parent

View file

@ -1383,8 +1383,7 @@ BuildTextRuns(DrawTarget* aDrawTarget, nsTextFrame* aForFrame,
nsIFrame* lineContainerChild = aForFrame; nsIFrame* lineContainerChild = aForFrame;
if (!aLineContainer) { if (!aLineContainer) {
if (aForFrame->IsFloatingFirstLetterChild()) { if (aForFrame->IsFloatingFirstLetterChild()) {
lineContainerChild = aForFrame->PresContext()->PresShell()-> lineContainerChild = aForFrame->GetParent()->GetPlaceholderFrame();
GetPlaceholderFrameFor(aForFrame->GetParent());
} }
aLineContainer = FindLineContainer(lineContainerChild); aLineContainer = FindLineContainer(lineContainerChild);
} else { } else {