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
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;

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()
: 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() &&

View file

@ -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)
{

View file

@ -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).

View file

@ -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;
}

View file

@ -485,12 +485,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

View file

@ -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();
}

View file

@ -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,

View file

@ -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 =

View file

@ -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(

View file

@ -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;
}

View file

@ -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.

View file

@ -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()->

View file

@ -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);
}
}
@ -8060,9 +8058,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)
@ -8075,7 +8072,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;
}
@ -9027,7 +9024,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.
@ -9044,6 +9040,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;
@ -9080,7 +9077,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);

View file

@ -82,6 +82,7 @@ class nsLineList_iterator;
class nsAbsoluteContainingBlock;
class nsIContent;
class nsContainerFrame;
class nsPlaceholderFrame;
struct nsPeekOffsetStruct;
struct nsPoint;
@ -728,6 +729,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
@ -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());

View file

@ -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();

View file

@ -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

View file

@ -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 {