diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 06:07:51 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 06:07:51 -0400 |
commit | 0c99ad16fbb5c3b90ee140235159f9a0ee72397b (patch) | |
tree | a8ac891f2d7dd3864bd461feaebafd06988e21e3 | |
parent | 2bcd8923f776e1c7bc716bd42c7e7912c4fe8709 (diff) | |
download | UXP-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.tar UXP-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.tar.gz UXP-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.tar.lz UXP-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.tar.xz UXP-0c99ad16fbb5c3b90ee140235159f9a0ee72397b.zip |
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.cpp | 25 | ||||
-rw-r--r-- | layout/base/nsFrameManager.cpp | 80 | ||||
-rw-r--r-- | layout/base/nsFrameManager.h | 11 | ||||
-rw-r--r-- | layout/base/nsFrameManagerBase.h | 1 | ||||
-rw-r--r-- | layout/base/nsFrameTraversal.cpp | 3 | ||||
-rw-r--r-- | layout/base/nsIPresShell.h | 6 | ||||
-rw-r--r-- | layout/base/nsLayoutUtils.cpp | 3 | ||||
-rw-r--r-- | layout/base/nsPresShell.cpp | 6 | ||||
-rw-r--r-- | layout/base/nsPresShell.h | 1 | ||||
-rw-r--r-- | layout/generic/ReflowInput.cpp | 3 | ||||
-rw-r--r-- | layout/generic/nsAbsoluteContainingBlock.cpp | 21 | ||||
-rw-r--r-- | layout/generic/nsBlockFrame.cpp | 15 | ||||
-rw-r--r-- | layout/generic/nsFirstLetterFrame.cpp | 3 | ||||
-rw-r--r-- | layout/generic/nsFrame.cpp | 15 | ||||
-rw-r--r-- | layout/generic/nsIFrame.h | 13 | ||||
-rw-r--r-- | layout/generic/nsIFrameInlines.h | 4 | ||||
-rw-r--r-- | layout/generic/nsPlaceholderFrame.cpp | 5 | ||||
-rw-r--r-- | layout/generic/nsTextFrame.cpp | 3 |
18 files changed, 52 insertions, 166 deletions
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index bee9ed629..57410a55a 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 83bcd61ec..d703537fa 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 bca4a581a..84d2c93e7 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 757dce7e5..bb192b64f 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 9ea6349f4..76dd40af1 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 f89639b3e..0a5f9e6e7 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 de3482246..2c4449994 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 b190622c7..2407db650 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 f276273fa..c25d07e66 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 78eca8c6c..9f7b4368c 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 e3c847d01..a92a2062d 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 a37bfc06b..8fec6cd6a 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 980e1e9be..5f561c759 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 25b685fb2..ea29c6945 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 9372b15a2..e22dd690a 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 3068c9f79..a3da7ebca 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 bd380a2d9..62370a06a 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 59ef020ce..6875f33e8 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 { |