diff options
Diffstat (limited to 'layout/generic/nsFrame.cpp')
-rw-r--r-- | layout/generic/nsFrame.cpp | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 5296126ac..5d05b7103 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -634,8 +634,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 || @@ -643,7 +642,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); } } @@ -8091,9 +8089,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) @@ -8106,7 +8103,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; } @@ -8936,6 +8933,8 @@ GetIBSplitSiblingForAnonymousBlock(const nsIFrame* aFrame) * * Also skip anonymous scrolled-content parents; inherit directly from the * outer scroll frame. + * + * Also skip NAC parents if the child frame is NAC. */ static nsIFrame* GetCorrectedParent(const nsIFrame* aFrame) @@ -8961,6 +8960,32 @@ GetCorrectedParent(const nsIFrame* aFrame) if (pseudo == nsCSSAnonBoxes::tableWrapper) { pseudo = aFrame->PrincipalChildList().FirstChild()->StyleContext()->GetPseudo(); } + + // Prevent NAC from inheriting NAC. This partially duplicates the logic + // implemented in nsCSSFrameConstructor::AddFCItemsForAnonymousContent, and is + // necessary so that restyle inherits style contexts in the same way as the + // initial styling performed in frame construction. + // + // It would be nice to put it in CorrectStyleParentFrame and therefore share + // it, but that would lose the information of whether the _child_ is NAC, + // since CorrectStyleParentFrame only knows about the prospective _parent_. + // This duplication and complexity will go away when we fully switch to the + // Servo style system, where all this can be handled much more naturally. + // + // We need to take special care not to disrupt the style inheritance of frames + // whose content is NAC but who implement a pseudo (like an anonymous + // box, or a non-NAC-backed pseudo like ::first-line) that does not match the + // one that the NAC implements, if any. + nsIContent* content = aFrame->GetContent(); + Element* element = + content && content->IsElement() ? content->AsElement() : nullptr; + if (element && element->IsNativeAnonymous() && !element->IsNativeScrollbarContent() && + element->GetPseudoElementType() == aFrame->StyleContext()->GetPseudoType()) { + while (parent->GetContent() && parent->GetContent()->IsNativeAnonymous()) { + parent = parent->GetInFlowParent(); + } + } + return nsFrame::CorrectStyleParentFrame(parent, pseudo); } @@ -9030,7 +9055,9 @@ 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. if (MOZ_LIKELY(mContent)) { nsIContent* parentContent = mContent->GetFlattenedTreeParent(); if (MOZ_LIKELY(parentContent)) { @@ -9044,6 +9071,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 +9108,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); @@ -9160,7 +9188,7 @@ nsIFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse) // will be enough to make them keyboard scrollable. nsIScrollableFrame *scrollFrame = do_QueryFrame(this); if (scrollFrame && - !scrollFrame->GetScrollbarStyles().IsHiddenInBothDirections() && + !scrollFrame->GetScrollStyles().IsHiddenInBothDirections() && !scrollFrame->GetScrollRange().IsEqualEdges(nsRect(0, 0, 0, 0))) { // Scroll bars will be used for overflow isFocusable = true; @@ -9995,19 +10023,16 @@ nsIFrame::IsPseudoStackingContextFromStyle() { Element* nsIFrame::GetPseudoElement(CSSPseudoElementType aType) { - nsIFrame* frame = nullptr; + if (!mContent) { + return nullptr; + } if (aType == CSSPseudoElementType::before) { - frame = nsLayoutUtils::GetBeforeFrame(this); - } else if (aType == CSSPseudoElementType::after) { - frame = nsLayoutUtils::GetAfterFrame(this); + return nsLayoutUtils::GetBeforePseudo(mContent); } - if (frame) { - nsIContent* content = frame->GetContent(); - if (content->IsElement()) { - return content->AsElement(); - } + if (aType == CSSPseudoElementType::after) { + return nsLayoutUtils::GetAfterPseudo(mContent); } return nullptr; |