From 7457010aa75f555625b19f82c7734ca9a814d779 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 1 May 2019 23:53:47 +0200 Subject: [PATCH] Bug 1466358 part 11 - [css-grid-2] Update the frame's subgrid state when the style changes. r=dholbert Differential Revision: https://phabricator.services.mozilla.com/D29578 --HG-- extra : rebase_source : 49ffcf3927761705680522750306fabfaa126cb9 --- layout/generic/nsGridContainerFrame.cpp | 67 +++++++++++++++++++------ layout/generic/nsGridContainerFrame.h | 14 ++++++ 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 32f57e435ca8..1ae54e55f14f 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -46,6 +46,9 @@ typedef nsTHashtable> FrameHashtable; typedef mozilla::CSSAlignUtils::AlignJustifyFlags AlignJustifyFlags; typedef nsLayoutUtils::IntrinsicISizeType IntrinsicISizeType; +static const nsFrameState kIsSubgridBits = (NS_STATE_GRID_IS_COL_SUBGRID | + NS_STATE_GRID_IS_ROW_SUBGRID); + // https://drafts.csswg.org/css-sizing/#constraints enum class SizingConstraint { MinContent, // sizing under min-content constraint @@ -6944,8 +6947,12 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext, const nsStylePosition* stylePos = aReflowInput.mStylePosition; auto prevInFlow = static_cast(GetPrevInFlow()); - if (!prevInFlow) { + if (MOZ_LIKELY(!prevInFlow)) { InitImplicitNamedAreas(stylePos); + } else { + MOZ_ASSERT((prevInFlow->GetStateBits() & kIsSubgridBits) == + (GetStateBits() & kIsSubgridBits), + "continuations should have same kIsSubgridBits"); } GridReflowInput gridReflowInput(this, aReflowInput); if (gridReflowInput.mIter.ItemsAreAlreadyInOrder()) { @@ -7366,35 +7373,63 @@ void nsGridContainerFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } +void nsGridContainerFrame::UpdateSubgridFrameState() { + nsFrameState oldBits = GetStateBits() & kIsSubgridBits; + nsFrameState newBits = ComputeSelfSubgridBits(); + if (newBits != oldBits) { + RemoveStateBits(kIsSubgridBits); + if (!newBits) { + DeleteProperty(Subgrid::Prop()); + } else { + AddStateBits(newBits); + } + } +} + +nsFrameState nsGridContainerFrame::ComputeSelfSubgridBits() const { + // skip our scroll frame and such if we have it + auto* parent = GetParent(); + while (parent && parent->GetContent() == GetContent()) { + parent = parent->GetParent(); + } + nsFrameState bits = nsFrameState(0); + if (parent && parent->IsGridContainerFrame()) { + const auto* pos = StylePosition(); + if (pos->GridTemplateColumns().mIsSubgrid) { + bits |= NS_STATE_GRID_IS_COL_SUBGRID; + } + if (pos->GridTemplateRows().mIsSubgrid) { + bits |= NS_STATE_GRID_IS_ROW_SUBGRID; + } + } + return bits; +} + void nsGridContainerFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { nsContainerFrame::Init(aContent, aParent, aPrevInFlow); nsFrameState bits = nsFrameState(0); if (MOZ_LIKELY(!aPrevInFlow)) { - // skip our scroll frame and such if we have it - auto* parent = aParent; - while (parent && parent->GetContent() == aContent) { - parent = parent->GetParent(); - } - if (parent && parent->IsGridContainerFrame()) { - const auto* pos = StylePosition(); - if (pos->GridTemplateColumns().mIsSubgrid) { - bits |= NS_STATE_GRID_IS_COL_SUBGRID; - } - if (pos->GridTemplateRows().mIsSubgrid) { - bits |= NS_STATE_GRID_IS_ROW_SUBGRID; - } - } + bits = ComputeSelfSubgridBits(); } else { bits = aPrevInFlow->GetStateBits() & - (NS_STATE_GRID_IS_COL_SUBGRID | NS_STATE_GRID_IS_ROW_SUBGRID | + (kIsSubgridBits | NS_STATE_GRID_HAS_COL_SUBGRID_ITEM | NS_STATE_GRID_HAS_ROW_SUBGRID_ITEM); } AddStateBits(bits); } +void nsGridContainerFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) { + nsContainerFrame::DidSetComputedStyle(aOldStyle); + + if (!aOldStyle) { + return; // Init() already initialized the bits. + } + UpdateSubgridFrameState(); +} + nscoord nsGridContainerFrame::IntrinsicISize(gfxContext* aRenderingContext, IntrinsicISizeType aType) { // Calculate the sum of column sizes under intrinsic sizing. diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h index 05965863c13e..bcb7b7d0fb78 100644 --- a/layout/generic/nsGridContainerFrame.h +++ b/layout/generic/nsGridContainerFrame.h @@ -105,6 +105,7 @@ class nsGridContainerFrame final : public nsContainerFrame { nsReflowStatus& aStatus) override; void Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) override; + void DidSetComputedStyle(ComputedStyle* aOldStyle) override; nscoord GetMinISize(gfxContext* aRenderingContext) override; nscoord GetPrefISize(gfxContext* aRenderingContext) override; void MarkIntrinsicISizesDirty() override; @@ -414,6 +415,19 @@ class nsGridContainerFrame final : public nsContainerFrame { void SanityCheckGridItemsBeforeReflow() const; #endif // DEBUG + /** + * Update our NS_STATE_GRID_IS_COL/ROW_SUBGRID bits and related subgrid state + * on our entire continuation chain based on the current style. + * This is needed because grid-template-columns/rows style changes only + * trigger a reflow so we need to update this dynamically. + */ + void UpdateSubgridFrameState(); + + /** + * Return the NS_STATE_GRID_IS_COL/ROW_SUBGRID bits we ought to have. + */ + nsFrameState ComputeSelfSubgridBits() const; + private: // Helpers for ReflowChildren struct Fragmentainer {