From 1f5c67934f05d036de575c3d8172587fa6d398bc Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Thu, 16 Apr 2020 17:51:36 -0400 Subject: Bug 1343937 - Fix a crash in nsWrapperCache.h * Implement and use GetInFlowParent * Exempt scrollbar NAC from the new NAC semantics Tag #1375 --- dom/base/nsIContent.h | 8 ++++++++ layout/base/nsCSSFrameConstructor.cpp | 13 +++++++++++-- layout/generic/nsFrame.cpp | 4 ++-- layout/generic/nsIFrame.h | 7 +++++++ layout/generic/nsIFrameInlines.h | 13 +++++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index ff0c57e8c..edb0d69f3 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -950,6 +950,14 @@ public: return false; } + // Returns true if this element is native-anonymous scrollbar content. + bool IsNativeScrollbarContent() const { + return IsNativeAnonymous() && + IsAnyOfXULElements(nsGkAtoms::scrollbar, + nsGkAtoms::resizer, + nsGkAtoms::scrollcorner); + } + // Overloaded from nsINode virtual already_AddRefed GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a2dec55e1..e88b2d62c 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -10730,6 +10730,12 @@ nsCSSFrameConstructor::AddFCItemsForAnonymousContent( // first element that is not itself NAC (distinct from whether it happens // to be in a NAC subtree). // + // The one exception to all of this is scrollbar content, which we parent + // directly to the scrollframe. This is because the special-snowflake + // construction of scroll frames doesn't result in the placeholder frame + // being constructed until later, which means that GetInFlowParent() doesn't + // work right in the case of out-of-flow scrollframes. + // // To implement all this, we need to pass the correct parent style context // here because SetPrimaryFrame() may not have been called on the content // yet and thus ResolveStyleContext can't find it otherwise. @@ -10739,9 +10745,12 @@ nsCSSFrameConstructor::AddFCItemsForAnonymousContent( // to worry about anonymous boxes, which CorrectStyleParentFrame handles // for us. nsIFrame* inheritFrame = aFrame; - while (inheritFrame->GetContent()->IsNativeAnonymous()) { - inheritFrame = inheritFrame->GetParent(); + if (!content->IsNativeScrollbarContent()) { + while (inheritFrame->GetContent()->IsNativeAnonymous()) { + inheritFrame = inheritFrame->GetInFlowParent(); + } } + if (inheritFrame->GetType() == nsGkAtoms::canvasFrame) { // CorrectStyleParentFrame returns nullptr if the prospective parent is // the canvas frame, so avoid calling it in that situation. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 2b81ce83b..71f6172bd 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -8964,10 +8964,10 @@ GetCorrectedParent(const nsIFrame* aFrame) nsIContent* content = aFrame->GetContent(); Element* element = content && content->IsElement() ? content->AsElement() : nullptr; - if (element && element->IsNativeAnonymous() && + if (element && element->IsNativeAnonymous() && !element->IsNativeScrollbarContent() && element->GetPseudoElementType() == aFrame->StyleContext()->GetPseudoType()) { while (parent->GetContent() && parent->GetContent()->IsNativeAnonymous()) { - parent = parent->GetParent(); + parent = parent->GetInFlowParent(); } } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 93eb95099..3137aaee2 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -721,6 +721,13 @@ public: * Accessor functions for geometric parent. */ nsContainerFrame* GetParent() const { return mParent; } + + /** + * Gets the parent of a frame, using the parent of the placeholder for + * out-of-flow frames. + */ + inline nsContainerFrame* GetInFlowParent(); + /** * Set this frame's parent to aParent. * If the frame may have moved into or out of a scrollframe's diff --git a/layout/generic/nsIFrameInlines.h b/layout/generic/nsIFrameInlines.h index eb9a7202a..3068c9f79 100644 --- a/layout/generic/nsIFrameInlines.h +++ b/layout/generic/nsIFrameInlines.h @@ -8,8 +8,10 @@ #define nsIFrameInlines_h___ #include "nsContainerFrame.h" +#include "nsPlaceholderFrame.h" #include "nsStyleStructInlines.h" #include "nsCSSAnonBoxes.h" +#include "nsFrameManager.h" bool nsIFrame::IsFlexItem() const @@ -160,4 +162,15 @@ nsIFrame::BaselineBOffset(mozilla::WritingMode aWM, return SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); } +nsContainerFrame* +nsIFrame::GetInFlowParent() +{ + if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { + nsFrameManager* fm = PresContext()->FrameManager(); + return fm->GetPlaceholderFrameFor(FirstContinuation())->GetParent(); + } + + return GetParent(); +} + #endif -- cgit v1.2.3