WebKit Bugzilla
Attachment 342404 Details for
Bug 186475
: [LFC] Merge left, right, width and horizontal margin computation for out-of-flow replaced elements
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186475-20180610200830.patch (text/plain), 14.43 KB, created by
zalan
on 2018-06-10 20:08:31 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-06-10 20:08:31 PDT
Size:
14.43 KB
patch
obsolete
>Subversion Revision: 232661 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index e744f9b27e8f6051078c157cef823c5b8bfe23fa..aeec09009661e50ac91d4f8a9178143cad531aa3 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,27 @@ >+2018-06-10 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC] Merge left, right, width and horizontal margin computation for out-of-flow replaced elements >+ https://bugs.webkit.org/show_bug.cgi?id=186475 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Implement https://www.w3.org/TR/CSS22/visudet.html#abs-replaced-width >+ (10.3.8 Absolutely positioned, replaced elements) >+ >+ * layout/FormattingContext.cpp: >+ (WebCore::Layout::FormattingContext::computeOutOfFlowHorizontalGeometry const): >+ (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const): >+ (WebCore::Layout::FormattingContext::computeOutOfFlowWidthAndMargin const): Deleted. >+ * layout/FormattingContext.h: >+ * layout/FormattingContextGeometry.cpp: >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry): >+ (WebCore::Layout::computedValueIfNotAuto): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowHorizontalGeometry): >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedWidthAndMargin): Deleted. >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedWidthAndMargin): Deleted. >+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowWidthAndMargin): Deleted. >+ > 2018-06-09 Zalan Bujtas <zalan@apple.com> > > [LFC] MarginCollapse functions should be able to resolve non-fixed margin values >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index 51c2623b3c6c930f7c5c6f58805970eafb403960..b946dcd4afbdcfd5c419cae22a2eae2d6bdcb6c8 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -68,11 +68,13 @@ void FormattingContext::computeFloatingWidthAndMargin(LayoutContext& layoutConte > displayBox.setHorizontalMargin(widthAndMargin.margin); > } > >-void FormattingContext::computeOutOfFlowWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >+void FormattingContext::computeOutOfFlowHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { >- auto widthAndMargin = Geometry::outOfFlowWidthAndMargin(layoutContext, layoutBox); >- displayBox.setWidth(widthAndMargin.width); >- displayBox.setHorizontalMargin(widthAndMargin.margin); >+ auto horizontalGeometry = Geometry::outOfFlowHorizontalGeometry(layoutContext, layoutBox); >+ displayBox.setLeft(horizontalGeometry.left); >+ displayBox.setWidth(horizontalGeometry.width); >+ ASSERT(horizontalGeometry.left + horizontalGeometry.width == horizontalGeometry.right); >+ displayBox.setHorizontalMargin(horizontalGeometry.margin); > } > > void FormattingContext::computeOutOfFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >@@ -115,7 +117,7 @@ void FormattingContext::layoutOutOfFlowDescendants(LayoutContext& layoutContext) > // 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); >- computeOutOfFlowWidthAndMargin(layoutContext, layoutBox, displayBox); >+ computeOutOfFlowHorizontalGeometry(layoutContext, layoutBox, displayBox); > > ASSERT(layoutBox.establishesFormattingContext()); > auto formattingContext = layoutContext.formattingContext(layoutBox); >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index 9d230f21888d0b65aa4520e3ea1f6c7a3da5e03b..1c06045e639c4a98d5710f9a2085b6b9906ab2f0 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -91,8 +91,15 @@ protected: > Display::Box::VerticalEdges margin; > }; > >+ struct HorizontalGeometry { >+ LayoutUnit left; >+ LayoutUnit right; >+ LayoutUnit width; >+ Display::Box::HorizontalEdges margin; >+ }; >+ > static HeightAndMargin outOfFlowHeightAndMargin(LayoutContext&, const Box&); >- static WidthAndMargin outOfFlowWidthAndMargin(LayoutContext&, const Box&); >+ static HorizontalGeometry outOfFlowHorizontalGeometry(LayoutContext&, const Box&); > > static HeightAndMargin floatingHeightAndMargin(LayoutContext&, const Box&); > static WidthAndMargin floatingWidthAndMargin(LayoutContext&, const Box&); >@@ -111,10 +118,10 @@ protected: > > private: > static HeightAndMargin outOfFlowReplacedHeightAndMargin(LayoutContext&, const Box&); >- static WidthAndMargin outOfFlowReplacedWidthAndMargin(LayoutContext&, const Box&); >+ static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(LayoutContext&, const Box&); > > static HeightAndMargin outOfFlowNonReplacedHeightAndMargin(LayoutContext&, const Box&); >- static WidthAndMargin outOfFlowNonReplacedWidthAndMargin(LayoutContext&, const Box&); >+ static HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(LayoutContext&, const Box&); > > static HeightAndMargin floatingReplacedHeightAndMargin(LayoutContext&, const Box&); > static WidthAndMargin floatingReplacedWidthAndMargin(LayoutContext&, const Box&); >@@ -126,7 +133,7 @@ protected: > private: > void computeOutOfFlowPosition(LayoutContext&, const Box&, Display::Box&) const; > void computeOutOfFlowHeight(LayoutContext&, const Box&, Display::Box&) const; >- void computeOutOfFlowWidthAndMargin(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 a40c43d07b23aeadd755079fc1ac022c2f63efd0..2a09e2d641010b7fb028b95afdb74c92dcdf5307 100644 >--- a/Source/WebCore/layout/FormattingContextGeometry.cpp >+++ b/Source/WebCore/layout/FormattingContextGeometry.cpp >@@ -128,7 +128,7 @@ FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::outOfF > return { computedHeightValue, { } }; > } > >-FormattingContext::Geometry::WidthAndMargin FormattingContext::Geometry::outOfFlowNonReplacedWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox) >+FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox) > { > ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced()); > >@@ -183,7 +183,7 @@ FormattingContext::Geometry::WidthAndMargin FormattingContext::Geometry::outOfFl > ASSERT_NOT_REACHED(); > } > >- return WidthAndMargin { computedWidthValue, { } }; >+ return HorizontalGeometry { { }, { }, computedWidthValue, { } }; > } > > FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::outOfFlowReplacedHeightAndMargin(LayoutContext& layoutContext, const Box& layoutBox) >@@ -195,13 +195,103 @@ FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::outOfF > return inlineReplacedHeightAndMargin(layoutContext, layoutBox); > } > >-FormattingContext::Geometry::WidthAndMargin FormattingContext::Geometry::outOfFlowReplacedWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox) >+static std::optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth) >+{ >+ if (geometryProperty.isAuto()) >+ return std::nullopt; >+ return valueForLength(geometryProperty, containingBlockWidth); >+} >+ >+FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox) > { > ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced()); >- // 10.3.8 Absolutely positioned, replaced elements >+ // In this case, section 10.3.7 applies up through and including the constraint equation, but the rest of section 10.3.7 is replaced by the following rules: > // >- // The used value of 'width' is determined as for inline replaced elements. >- return inlineReplacedWidthAndMargin(layoutContext, layoutBox); >+ // The used value of 'width' is determined as for inline replaced elements. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below. >+ // 1. If both 'left' and 'right' have the value 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr', >+ // set 'left' to the static position; else if 'direction' is 'rtl', set 'right' to the static position. >+ // 2. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' or 'margin-right' with '0'. >+ // 3. If at this point both 'margin-left' and 'margin-right' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values, >+ // unless this would make them negative, in which case when the direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and >+ // solve for 'margin-right' ('margin-left'). >+ // 4. If at this point there is an 'auto' left, solve the equation for that value. >+ // 5. If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or >+ // 'right' (in case 'direction' is 'ltr') and solve for that value. >+ >+ auto& style = layoutBox.style(); >+ auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox); >+ auto& containingBlock = *layoutBox.containingBlock(); >+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock)->width(); >+ auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection(); >+ >+ auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth); >+ auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth); >+ auto marginLeft = computedValueIfNotAuto(style.marginLeft(), containingBlockWidth); >+ auto marginRight = computedValueIfNotAuto(style.marginRight(), containingBlockWidth); >+ auto width = inlineReplacedWidthAndMargin(layoutContext, layoutBox).width; >+ auto paddingLeft = displayBox.paddingLeft(); >+ auto paddingRight = displayBox.paddingRight(); >+ auto borderLeft = displayBox.borderLeft(); >+ auto borderRight = displayBox.borderRight(); >+ >+ if (!left && !right) { >+ // #1 >+ if (isLeftToRightDirection) >+ left = displayBox.left(); >+ else >+ right = displayBox.right(); >+ } >+ >+ if (!left || !right) { >+ // #2 >+ marginLeft = marginLeft.value_or(0); >+ marginRight = marginRight.value_or(0); >+ } >+ >+ if (!marginLeft && !marginRight) { >+ // #3 >+ auto marginLeftAndRight = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *right); >+ if (marginLeftAndRight >= 0) >+ marginLeft = marginRight = marginLeftAndRight / 2; >+ else { >+ if (isLeftToRightDirection) { >+ marginLeft = LayoutUnit { 0 }; >+ marginRight = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *right); >+ } else { >+ marginRight = LayoutUnit { 0 }; >+ marginLeft = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight + *right); >+ } >+ } >+ } >+ >+ // #4 >+ if (!left) >+ left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight + *right); >+ >+ if (!right) >+ right = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight); >+ >+ if (!marginLeft) >+ marginLeft = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight + *right); >+ >+ if (!marginRight) >+ marginRight = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *right); >+ >+ auto boxWidth = (*left + *marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight + *right); >+ if (boxWidth > containingBlockWidth) { >+ // #5 Over-constrained? >+ if (isLeftToRightDirection) >+ right = containingBlockWidth - (*left + *marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight); >+ else >+ left = containingBlockWidth - (*marginLeft + borderLeft + paddingLeft + width + paddingRight + borderRight + *marginRight + *right); >+ } >+ >+ ASSERT(left); >+ ASSERT(right); >+ ASSERT(marginLeft); >+ ASSERT(marginRight); >+ >+ return { *left, *right, width, { *marginLeft, *marginRight } }; > } > > FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::floatingNonReplacedHeightAndMargin(LayoutContext& layoutContext, const Box& layoutBox) >@@ -449,13 +539,13 @@ FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::outOfF > return outOfFlowReplacedHeightAndMargin(layoutContext, layoutBox); > } > >-FormattingContext::Geometry::WidthAndMargin FormattingContext::Geometry::outOfFlowWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox) >+FormattingContext::Geometry::HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox) > { > ASSERT(layoutBox.isOutOfFlowPositioned()); > > if (!layoutBox.replaced()) >- return outOfFlowNonReplacedWidthAndMargin(layoutContext, layoutBox); >- return outOfFlowReplacedWidthAndMargin(layoutContext, layoutBox); >+ return outOfFlowNonReplacedHorizontalGeometry(layoutContext, layoutBox); >+ return outOfFlowReplacedHorizontalGeometry(layoutContext, layoutBox); > } > > FormattingContext::Geometry::HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(LayoutContext& layoutContext, const Box& layoutBox)
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
Flags:
koivisto
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186475
: 342404