WebKit Bugzilla
Attachment 343688 Details for
Bug 187082
: [LFC] Out-of-flow positioned element's height depends on its containing block's height.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-187082-20180626220149.patch (text/plain), 29.52 KB, created by
zalan
on 2018-06-26 22:01:50 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-06-26 22:01:50 PDT
Size:
29.52 KB
patch
obsolete
>Subversion Revision: 233202 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 976923bbc04115d6bb3b0f1230a050ab6aae15e6..4001722132e397c7753d0a567d6e42431eca4f34 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,39 @@ >+2018-06-26 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC] Out-of-flow positioned element's height depends on its containing block's height. >+ https://bugs.webkit.org/show_bug.cgi?id=187082 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We can't really compute the final height of an out-of-flow element until after its containing block's height is computed. >+ >+ * layout/FormattingContext.cpp: >+ (WebCore::Layout::FormattingContext::computeVerticalGeometryForOutOfFlowDescendants const): >+ (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const): Deleted. >+ * layout/FormattingContext.h: >+ * layout/FormattingContextGeometry.cpp: >+ (WebCore::Layout::staticHorizontalPositionForOutOfFlowPositioned): >+ (WebCore::Layout::staticVerticalPositionForOutOfFlowPositioned): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry): >+ * layout/LayoutContext.cpp: >+ (WebCore::Layout::LayoutContext::updateLayout): >+ (WebCore::Layout::LayoutContext::layoutFormattingContextSubtree): >+ * layout/LayoutContext.h: >+ * layout/blockformatting/BlockFormattingContext.cpp: >+ (WebCore::Layout::BlockFormattingContext::layout const): >+ (WebCore::Layout::BlockFormattingContext::layoutFormattingContextRoot const): >+ (WebCore::Layout::BlockFormattingContext::computeHorizontalGeometry const): >+ (WebCore::Layout::BlockFormattingContext::computeVerticalGeometry const): >+ (WebCore::Layout::BlockFormattingContext::computeWidthAndMargin const): Deleted. >+ (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const): Deleted. >+ * layout/blockformatting/BlockFormattingContext.h: >+ * layout/blockformatting/BlockFormattingContextGeometry.cpp: >+ (WebCore::Layout::BlockFormattingContext::Geometry::staticPosition): >+ (WebCore::Layout::BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned): Deleted. >+ > 2018-06-26 Thibault Saunier <tsaunier@igalia.com> > > [GStreamer] Do not forget to set stream on track switching >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index 1acb1a1d8910f65d9f0100501e1f33f1afc9a65a..01a9edd1d0696ee8bc5af8c41f79ec37238b861a 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -105,31 +105,16 @@ void FormattingContext::placeInFlowPositionedChildren(LayoutContext& layoutConte > LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> context: " << &layoutContext << " parent: " << &container); > } > >-void FormattingContext::layoutOutOfFlowDescendants(LayoutContext& layoutContext) const >+void FormattingContext::computeVerticalGeometryForOutOfFlowDescendants(LayoutContext& layoutContext, FormattingState&) const > { > if (!is<Container>(m_root.get())) > return; > > LOG_WITH_STREAM(FormattingContextLayout, stream << "Start: layout out-of-flow descendants -> context: " << &layoutContext << " root: " << &root()); > >- for (auto& outOfFlowBox : downcast<Container>(*m_root).outOfFlowDescendants()) { >- auto& layoutBox = *outOfFlowBox; >- auto& displayBox = layoutContext.createDisplayBox(layoutBox); >+ for (auto& outOfFlowBox : downcast<Container>(*m_root).outOfFlowDescendants()) >+ computeOutOfFlowVerticalGeometry(layoutContext, *outOfFlowBox, *layoutContext.displayBoxForLayoutBox(*outOfFlowBox)); > >- // The term "static position" (of an element) refers, roughly, to the position an element would have had in the normal flow. >- // More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge >- // of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static' and >- // its specified 'float' had been 'none' and its specified 'clear' had been 'none'. >- computeStaticPosition(layoutContext, layoutBox, displayBox); >- computeBorderAndPadding(layoutContext, layoutBox, displayBox); >- computeOutOfFlowHorizontalGeometry(layoutContext, layoutBox, displayBox); >- >- ASSERT(layoutBox.establishesFormattingContext()); >- auto formattingContext = layoutContext.formattingContext(layoutBox); >- formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext)); >- >- computeOutOfFlowVerticalGeometry(layoutContext, layoutBox, displayBox); >- } > LOG_WITH_STREAM(FormattingContextLayout, stream << "End: layout out-of-flow descendants -> context: " << &layoutContext << " root: " << &root()); > } > >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index 52bba414d82d26b83e69a0189bd64673fb3afde3..4c7b1ae7028b2abaecfd624bf927057d62bacc0a 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -51,6 +51,11 @@ public: > virtual ~FormattingContext(); > > virtual void layout(LayoutContext&, FormattingState&) const = 0; >+ void computeVerticalGeometryForOutOfFlowDescendants(LayoutContext&s, FormattingState&) const; >+#ifndef NDEBUG >+ virtual void validateGeometryConstraintsAfterLayout(const LayoutContext&) const; >+#endif >+ > virtual std::unique_ptr<FormattingState> createFormattingState(Ref<FloatingState>&&) const = 0; > virtual Ref<FloatingState> createOrFindFloatingState(LayoutContext&) const = 0; > >@@ -72,11 +77,9 @@ protected: > void computeBorderAndPadding(LayoutContext&, const Box&, Display::Box&) const; > > void placeInFlowPositionedChildren(LayoutContext&, const Container&) const; >- void layoutOutOfFlowDescendants(LayoutContext&s) const; > >-#ifndef NDEBUG >- virtual void validateGeometryConstraintsAfterLayout(const LayoutContext&) const; >-#endif >+ void computeOutOfFlowVerticalGeometry(LayoutContext&, const Box&, Display::Box&) const; >+ void computeOutOfFlowHorizontalGeometry(LayoutContext&, const Box&, Display::Box&) const; > > // This class implements generic positioning and sizing. > class Geometry { >@@ -143,9 +146,6 @@ protected: > }; > > private: >- void computeOutOfFlowVerticalGeometry(LayoutContext&, const Box&, Display::Box&) const; >- void computeOutOfFlowHorizontalGeometry(LayoutContext&, const Box&, Display::Box&) const; >- > WeakPtr<Box> m_root; > }; > >diff --git a/Source/WebCore/layout/FormattingContextGeometry.cpp b/Source/WebCore/layout/FormattingContextGeometry.cpp >index f5fa05c791433f083f00db18ce62d0171ca04b6d..a854a53eaa8c2b185970785278ecf296deee59b3 100644 >--- a/Source/WebCore/layout/FormattingContextGeometry.cpp >+++ b/Source/WebCore/layout/FormattingContextGeometry.cpp >@@ -75,6 +75,44 @@ std::optional<LayoutUnit> FormattingContext::Geometry::computedValueIfNotAuto(co > return valueForLength(geometryProperty, containingBlockWidth); > } > >+static LayoutUnit staticHorizontalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox) >+{ >+ ASSERT(layoutBox.isOutOfFlowPositioned()); >+ >+ LayoutUnit left; >+ // Resolve left all the way up to the containing block. >+ auto* containingBlock = layoutBox.containingBlock(); >+ for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) { >+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent); >+ left += (displayBox.left() + displayBox.contentBoxLeft()); >+ if (parent == containingBlock) >+ break; >+ } >+ return left; >+} >+ >+static LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox) >+{ >+ ASSERT(layoutBox.isOutOfFlowPositioned()); >+ >+ LayoutUnit top; >+ // Resolve top all the way up to the containing block. >+ auto* containingBlock = layoutBox.containingBlock(); >+ for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) { >+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent); >+ top += (displayBox.top() + displayBox.contentBoxTop()); >+ if (parent == containingBlock) >+ break; >+ } >+ // Add sibling offset >+ if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) { >+ auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling); >+ top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom(); >+ } >+ >+ return top; >+} >+ > FormattingContext::Geometry::VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(LayoutContext& layoutContext, const Box& layoutBox) > { > ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced()); >@@ -120,7 +158,7 @@ FormattingContext::Geometry::VerticalGeometry FormattingContext::Geometry::outOf > auto borderBottom = displayBox.borderBottom(); > > if (!top && !height && !bottom) >- top = displayBox.top(); >+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > > if (top && height && bottom) { > if (!marginTop && !marginBottom) { >@@ -146,7 +184,7 @@ FormattingContext::Geometry::VerticalGeometry FormattingContext::Geometry::outOf > > if (!top && !bottom && height) { > // #2 >- top = displayBox.top(); >+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > marginTop = marginTop.value_or(0); > marginBottom = marginBottom.value_or(0); > bottom = containingBlockHeight - (*top + *marginTop + borderTop + paddingTop + *height + paddingBottom + borderBottom + *marginBottom); >@@ -244,10 +282,11 @@ FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::out > marginLeft = marginLeft.value_or(0); > marginRight = marginRight.value_or(0); > >+ auto hoztizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > if (isLeftToRightDirection) >- left = displayBox.left(); >+ left = hoztizontalPosition; > else >- right = displayBox.right(); >+ right = hoztizontalPosition; > } else if (left && width && right) { > // If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values, > // unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and >@@ -301,11 +340,12 @@ FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::out > left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight + *right); > } else if (!left && !right && width) { > // #2 >+ auto hoztizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > if (isLeftToRightDirection) { >- left = displayBox.left(); >+ left = hoztizontalPosition; > right = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight); > } else { >- right = displayBox.right(); >+ right = hoztizontalPosition; > left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + *width + paddingRight + borderRight + *marginRight + *right); > } > } else if (!width && !right && left) { >@@ -365,7 +405,7 @@ FormattingContext::Geometry::VerticalGeometry FormattingContext::Geometry::outOf > > if (!top && !bottom) { > // #1 >- top = displayBox.top(); >+ top = staticVerticalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > } > > if (!bottom) { >@@ -438,10 +478,11 @@ FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::out > > if (!left && !right) { > // #1 >+ auto hoztizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutContext, layoutBox); > if (isLeftToRightDirection) >- left = displayBox.left(); >+ left = hoztizontalPosition; > else >- right = displayBox.right(); >+ right = hoztizontalPosition; > } > > if (!left || !right) { >diff --git a/Source/WebCore/layout/LayoutContext.cpp b/Source/WebCore/layout/LayoutContext.cpp >index 97379982447753a8e02f67102fb6ad2273dd7fe6..bfcdc0f047185ca36a22279299ff340d8c260f82 100644 >--- a/Source/WebCore/layout/LayoutContext.cpp >+++ b/Source/WebCore/layout/LayoutContext.cpp >@@ -71,15 +71,24 @@ void LayoutContext::initializeRoot(const Container& root, const LayoutSize& cont > void LayoutContext::updateLayout() > { > ASSERT(!m_formattingContextRootListForLayout.isEmpty()); >- for (auto* layoutRoot : m_formattingContextRootListForLayout) { >- RELEASE_ASSERT(layoutRoot->establishesFormattingContext()); >- auto context = formattingContext(*layoutRoot); >- auto& state = establishedFormattingState(*layoutRoot, *context); >- context->layout(*this, state); >- } >+ for (auto* layoutRoot : m_formattingContextRootListForLayout) >+ layoutFormattingContextSubtree(*layoutRoot); > m_formattingContextRootListForLayout.clear(); > } > >+void LayoutContext::layoutFormattingContextSubtree(const Box& layoutRoot) >+{ >+ // We don't layout the root itself here, only the boxes that participate in its formatting context. >+ RELEASE_ASSERT(layoutRoot.establishesFormattingContext()); >+ auto formattingContext = this->formattingContext(layoutRoot); >+ auto& formattingState = establishedFormattingState(layoutRoot, *formattingContext); >+ formattingContext->layout(*this, formattingState); >+ formattingContext->computeVerticalGeometryForOutOfFlowDescendants(*this, formattingState); >+#ifndef NDEBUG >+ formattingContext->validateGeometryConstraintsAfterLayout(*this); >+#endif >+} >+ > Display::Box& LayoutContext::createDisplayBox(const Box& layoutBox) > { > std::unique_ptr<Display::Box> displayBox(new Display::Box(layoutBox.style())); >diff --git a/Source/WebCore/layout/LayoutContext.h b/Source/WebCore/layout/LayoutContext.h >index d83bc08aa407fca4b1696f36c734a26b0304c0eb..1f84ac6c38a4515e5e3726c340a292da14c0c599 100644 >--- a/Source/WebCore/layout/LayoutContext.h >+++ b/Source/WebCore/layout/LayoutContext.h >@@ -86,6 +86,8 @@ public: > void verifyAndOutputMismatchingLayoutTree(const RenderView&) const; > > private: >+ void layoutFormattingContextSubtree(const Box&); >+ > WeakPtr<Container> m_root; > HashSet<const Container*> m_formattingContextRootListForLayout; > HashMap<const Box*, std::unique_ptr<FormattingState>> m_formattingStates; >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >index 3125f241431d36148da1f60820a54250f59b9b0c..8826e9e3433ab3459bcfb2ae882b6f78d67e47b3 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp >@@ -55,7 +55,7 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > // In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. > // The vertical distance between two sibling boxes is determined by the 'margin' properties. > // Vertical margins between adjacent block-level boxes in a block formatting context collapse. >- if (!is<Container>(root())) >+ if (!is<Container>(root()) || !downcast<Container>(root()).firstChild()) > return; > > LOG_WITH_STREAM(FormattingContextLayout, stream << "[Start] -> block formatting context -> layout context(" << &layoutContext << ") formatting root(" << &root() << ")"); >@@ -65,8 +65,8 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > FloatingContext floatingContext(formattingState.floatingState()); > // This is a post-order tree traversal layout. > // The root container layout is done in the formatting context it lives in, not that one it creates, so let's start with the first child. >- if (auto* firstChild = formattingRoot.firstInFlowOrFloatingChild()) >- layoutQueue.append(std::make_unique<LayoutPair>(LayoutPair {*firstChild, layoutContext.createDisplayBox(*firstChild)})); >+ auto& firstChild = *formattingRoot.firstChild(); >+ layoutQueue.append(std::make_unique<LayoutPair>(LayoutPair { firstChild, layoutContext.createDisplayBox(firstChild) })); > // 1. Go all the way down to the leaf node > // 2. Compute static position and width as we traverse down > // 3. As we climb back on the tree, compute height and finialize position >@@ -78,18 +78,19 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > auto& layoutBox = layoutPair.layoutBox; > auto& displayBox = layoutPair.displayBox; > >- LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Position][Border][Padding][Width][Margin] -> for layoutBox(" << &layoutBox << ")"); >- computeStaticPosition(layoutContext, layoutBox, displayBox); >- computeBorderAndPadding(layoutContext, layoutBox, displayBox); >- computeWidthAndMargin(layoutContext, layoutBox, displayBox); > if (layoutBox.establishesFormattingContext()) { >- auto formattingContext = layoutContext.formattingContext(layoutBox); >- formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext)); >+ layoutFormattingContextRoot(layoutContext, formattingState, layoutBox, displayBox); >+ layoutQueue.removeLast(); > break; > } >- if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild()) >+ >+ LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Position][Border][Padding][Width][Margin] -> for layoutBox(" << &layoutBox << ")"); >+ computeStaticPosition(layoutContext, layoutBox, displayBox); >+ computeBorderAndPadding(layoutContext, layoutBox, displayBox); >+ computeHorizontalGeometry(layoutContext, layoutBox, displayBox); >+ if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).firstChild()) > break; >- auto& firstChild = *downcast<Container>(layoutBox).firstInFlowOrFloatingChild(); >+ auto& firstChild = *downcast<Container>(layoutBox).firstChild(); > layoutQueue.append(std::make_unique<LayoutPair>(LayoutPair {firstChild, layoutContext.createDisplayBox(firstChild)})); > } > >@@ -99,9 +100,12 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > auto layoutPair = layoutQueue.takeLast(); > auto& layoutBox = layoutPair->layoutBox; > auto& displayBox = layoutPair->displayBox; >- LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Height][Margin] -> for layoutBox(" << &layoutBox << ")"); > >- computeHeightAndMargin(layoutContext, layoutBox, displayBox); >+ // Formatting root boxes are special-cased and they don't come here. >+ ASSERT(!layoutBox.establishesFormattingContext()); >+ >+ LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Height][Margin] -> for layoutBox(" << &layoutBox << ")"); >+ computeVerticalGeometry(layoutContext, layoutBox, displayBox); > // Adjust position now that we have all the previous floats placed in this context -if needed. > floatingContext.computePosition(layoutBox, displayBox); > if (!is<Container>(layoutBox)) >@@ -109,7 +113,7 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > auto& container = downcast<Container>(layoutBox); > // Move in-flow positioned children to their final position. > placeInFlowPositionedChildren(layoutContext, container); >- if (auto* nextSibling = container.nextInFlowOrFloatingSibling()) { >+ if (auto* nextSibling = container.nextSibling()) { > layoutQueue.append(std::make_unique<LayoutPair>(LayoutPair {*nextSibling, layoutContext.createDisplayBox(*nextSibling)})); > break; > } >@@ -117,14 +121,33 @@ void BlockFormattingContext::layout(LayoutContext& layoutContext, FormattingStat > } > // Place the inflow positioned children. > placeInFlowPositionedChildren(layoutContext, formattingRoot); >- // And take care of out-of-flow boxes as the final step. >- layoutOutOfFlowDescendants(layoutContext); >-#ifndef NDEBUG >- validateGeometryConstraintsAfterLayout(layoutContext); >-#endif > LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> block formatting context -> layout context(" << &layoutContext << ") formatting root(" << &root() << ")"); > } > >+void BlockFormattingContext::layoutFormattingContextRoot(LayoutContext& layoutContext, FormattingState& formattingState, const Box& layoutBox, Display::Box& displayBox) const >+{ >+ // Start laying out this formatting root in the formatting contenxt it lives in. >+ LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Position][Border][Padding][Width][Margin] -> for layoutBox(" << &layoutBox << ")"); >+ computeStaticPosition(layoutContext, layoutBox, displayBox); >+ computeBorderAndPadding(layoutContext, layoutBox, displayBox); >+ computeHorizontalGeometry(layoutContext, layoutBox, displayBox); >+ >+ // Swich over to the new formatting context (the one that the root creates). >+ auto formattingContext = layoutContext.formattingContext(layoutBox); >+ auto& establishedFormattingState = layoutContext.establishedFormattingState(layoutBox, *formattingContext); >+ formattingContext->layout(layoutContext, establishedFormattingState); >+ >+ // Come back and finalize the root's geometry. >+ FloatingContext(formattingState.floatingState()).computePosition(layoutBox, displayBox); >+ LOG_WITH_STREAM(FormattingContextLayout, stream << "[Compute] -> [Height][Margin] -> for layoutBox(" << &layoutBox << ")"); >+ // The out-of-flow element's vertical geometry is computed latter as the last step while finishing its formatting root's layout. >+ if (!layoutBox.isOutOfFlowPositioned()) { >+ computeVerticalGeometry(layoutContext, layoutBox, displayBox); >+ // And soon after the root's height is computed, we can go ahead and size the out-of-flow descendants. >+ formattingContext->computeVerticalGeometryForOutOfFlowDescendants(layoutContext, establishedFormattingState); >+ } >+} >+ > std::unique_ptr<FormattingState> BlockFormattingContext::createFormattingState(Ref<FloatingState>&& floatingState) const > { > return std::make_unique<BlockFormattingState>(WTFMove(floatingState)); >@@ -146,7 +169,7 @@ void BlockFormattingContext::computeInFlowPositionedPosition(LayoutContext& layo > displayBox.setTopLeft(Geometry::inFlowPositionedPosition(layoutContext, layoutBox)); > } > >-void BlockFormattingContext::computeWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >+void BlockFormattingContext::computeHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { > if (layoutBox.isInFlow()) > return computeInFlowWidthAndMargin(layoutContext, layoutBox, displayBox); >@@ -154,10 +177,13 @@ void BlockFormattingContext::computeWidthAndMargin(LayoutContext& layoutContext, > if (layoutBox.isFloatingPositioned()) > return computeFloatingWidthAndMargin(layoutContext, layoutBox, displayBox); > >+ if (layoutBox.isOutOfFlowPositioned()) >+ return computeOutOfFlowHorizontalGeometry(layoutContext, layoutBox, displayBox); >+ > ASSERT_NOT_REACHED(); > } > >-void BlockFormattingContext::computeHeightAndMargin(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >+void BlockFormattingContext::computeVerticalGeometry(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { > if (layoutBox.isInFlow()) > return computeInFlowHeightAndMargin(layoutContext, layoutBox, displayBox); >@@ -165,6 +191,9 @@ void BlockFormattingContext::computeHeightAndMargin(LayoutContext& layoutContext > if (layoutBox.isFloatingPositioned()) > return computeFloatingHeightAndMargin(layoutContext, layoutBox, displayBox); > >+ if (layoutBox.isOutOfFlowPositioned()) >+ return computeOutOfFlowVerticalGeometry(layoutContext, layoutBox, displayBox); >+ > ASSERT_NOT_REACHED(); > } > >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >index 311b22908c7a9d303bdb30dcfc49594d56e98368..553928318a811b7d41818062f75642493fb97ee9 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContext.h >@@ -51,8 +51,10 @@ public: > Ref<FloatingState> createOrFindFloatingState(LayoutContext&) const override; > > private: >- void computeWidthAndMargin(LayoutContext&, const Box&, Display::Box&) const; >- void computeHeightAndMargin(LayoutContext&, const Box&, Display::Box&) const; >+ void layoutFormattingContextRoot(LayoutContext&, FormattingState&, const Box&, Display::Box&) const; >+ >+ void computeHorizontalGeometry(LayoutContext&, const Box&, Display::Box&) const; >+ void computeVerticalGeometry(LayoutContext&, const Box&, Display::Box&) const; > > void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override; > void computeInFlowPositionedPosition(LayoutContext&, const Box&, Display::Box&) const override; >@@ -72,7 +74,6 @@ private: > static FormattingContext::Geometry::HeightAndMargin inFlowNonReplacedHeightAndMargin(LayoutContext&, const Box&); > static FormattingContext::Geometry::WidthAndMargin inFlowNonReplacedWidthAndMargin(LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = std::nullopt); > static FormattingContext::Geometry::WidthAndMargin inFlowReplacedWidthAndMargin(LayoutContext&, const Box&); >- static FormattingContext::Geometry::Position staticPositionForOutOfFlowPositioned(const LayoutContext&, const Box&); > }; > > // This class implements margin collapsing for block formatting context. >diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp >index ba65b7edb4ddc0162e5757790ccf453eef527eb8..de5eb8995a077b6d6e9bbbce8d7ea802556e7276 100644 >--- a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp >+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp >@@ -265,31 +265,6 @@ FormattingContext::Geometry::WidthAndMargin BlockFormattingContext::Geometry::in > return { width, margin }; > } > >-FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox) >-{ >- // FIXME: This is certainly only really needed when top/bottom left/right are auto. >- ASSERT(layoutBox.isOutOfFlowPositioned()); >- LayoutUnit top; >- LayoutUnit left; >- // Resolve top/left all the way up to the containing block. >- auto* containingBlock = layoutBox.containingBlock(); >- for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) { >- auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent); >- top += (displayBox.top() + displayBox.contentBoxTop()); >- left += (displayBox.left() + displayBox.contentBoxLeft()); >- if (parent == containingBlock) >- break; >- } >- // Add sibling offset >- if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) { >- auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling); >- top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom(); >- } >- >- LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> out-of-flow -> static -> top(" << top << "px) left(" << left << "px) layoutBox(" << &layoutBox << ")"); >- return { left, top }; >-} >- > FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox) > { > // https://www.w3.org/TR/CSS22/visuren.html#block-formatting >@@ -297,10 +272,6 @@ FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPo > // The vertical distance between two sibling boxes is determined by the 'margin' properties. > // Vertical margins between adjacent block-level boxes in a block formatting context collapse. > // In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). >- >- if (layoutBox.isOutOfFlowPositioned()) >- return staticPositionForOutOfFlowPositioned(layoutContext, layoutBox); >- > LayoutUnit top; > auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()); > if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 187082
:
343688
|
343725