WebKit Bugzilla
Attachment 340954 Details for
Bug 185858
: [LFC] Implement positioning for non-replaced out-of-flow elements.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185858-20180521221017.patch (text/plain), 10.53 KB, created by
zalan
on 2018-05-21 22:10:18 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
zalan
Created:
2018-05-21 22:10:18 PDT
Size:
10.53 KB
patch
obsolete
>Subversion Revision: 231958 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9bf9345096d71de059c60de0ab1827c87a58e7df..6c7931b62573c766be46944c66442a1970e34d1d 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,20 @@ >+2018-05-21 Zalan Bujtas <zalan@apple.com> >+ >+ [LFC] Implement positioning for non-replaced out-of-flow elements. >+ https://bugs.webkit.org/show_bug.cgi?id=185858 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ In certain cases, the out-of-flow element's final position depends on the element's size. >+ Call computeOutOfFlowPosition() after width/height are resolved. >+ >+ * layout/FormattingContext.cpp: >+ (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const): >+ (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const): >+ (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedPosition const): >+ (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedPosition const): >+ * layout/FormattingContext.h: >+ > 2018-05-18 Zalan Bujtas <zalan@apple.com> > > [LFC] Implement height computation for non-replaced floating elements. >diff --git a/Source/WebCore/layout/FormattingContext.cpp b/Source/WebCore/layout/FormattingContext.cpp >index b197ea56318e4ae450bbb403c42620054ad5cb4b..d0a5f85a655130ebec33b323a702b06663651854 100644 >--- a/Source/WebCore/layout/FormattingContext.cpp >+++ b/Source/WebCore/layout/FormattingContext.cpp >@@ -56,8 +56,13 @@ void FormattingContext::computeInFlowPositionedPosition(const Box&, Display::Box > { > } > >-void FormattingContext::computeOutOfFlowPosition(const Box&, Display::Box&) const >+void FormattingContext::computeOutOfFlowPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const > { >+ if (!layoutBox.replaced()) { >+ computeOutOfFlowNonReplacedPosition(layoutContext, layoutBox, displayBox); >+ return; >+ } >+ computeOutOfFlowReplacedPosition(layoutContext, layoutBox, displayBox); > } > > void FormattingContext::computeWidth(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >@@ -146,7 +151,11 @@ void FormattingContext::layoutOutOfFlowDescendants(LayoutContext& layoutContext) > auto& layoutBox = *outOfFlowBox; > auto& displayBox = layoutContext.createDisplayBox(layoutBox); > >- computeOutOfFlowPosition(layoutBox, displayBox); >+ // 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); > computeOutOfFlowWidth(layoutContext, layoutBox, displayBox); > > ASSERT(layoutBox.establishesFormattingContext()); >@@ -154,6 +163,7 @@ void FormattingContext::layoutOutOfFlowDescendants(LayoutContext& layoutContext) > formattingContext->layout(layoutContext, layoutContext.establishedFormattingState(layoutBox, *formattingContext)); > > computeOutOfFlowHeight(layoutContext, layoutBox, displayBox); >+ computeOutOfFlowPosition(layoutContext, layoutBox, displayBox); > } > } > >@@ -442,6 +452,105 @@ LayoutUnit FormattingContext::shrinkToFitWidth(LayoutContext&, const Box&) const > return 0; > } > >+void FormattingContext::computeOutOfFlowNonReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const >+{ >+ // 10.3.7 Absolutely positioned, non-replaced elements (left/right) >+ // 10.6.4 Absolutely positioned, non-replaced elements (top/bottom) >+ >+ // At this point we've the size computed. >+ auto size = displayBox.size(); >+ auto& style = layoutBox.style(); >+ >+ // 10.6.4 Absolutely positioned, non-replaced elements >+ auto top = style.logicalTop(); >+ auto bottom = style.logicalBottom(); >+ auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height(); >+ >+ // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom' >+ // = height of containing block >+ // >+ // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7, >+ // set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' >+ // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for >+ // 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' >+ // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto' >+ // values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom' >+ // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top' >+ // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height' >+ // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom' >+ LayoutUnit computedTopValue; >+ if (top.isAuto() && !bottom.isAuto()) { >+ // #1 #4 >+ auto marginTop = displayBox.marginTop(); >+ auto marginBottom = displayBox.marginBottom(); >+ >+ auto paddingTop = displayBox.paddingTop(); >+ auto paddingBottom = displayBox.paddingBottom(); >+ >+ auto borderTop = displayBox.borderTop(); >+ auto borderBottom = displayBox.borderBottom(); >+ >+ computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value()); >+ } else if (top.isAuto() && bottom.isAuto()) { >+ // #2 >+ // Already computed as part of the computeStaticPosition(); >+ computedTopValue = displayBox.top(); >+ } else { >+ // #3 #5 #6 have top != auto >+ computedTopValue = valueForLength(top, containingBlockHeight); >+ } >+ >+ displayBox.setTop(computedTopValue); >+ >+ // 10.3.7 Absolutely positioned, non-replaced elements >+ auto left = style.logicalLeft(); >+ auto right = style.logicalRight(); >+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width(); >+ >+ // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' >+ // = width of containing block >+ // >+ // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0. >+ // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static >+ // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below. >+ >+ // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left' >+ // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position >+ // containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position. >+ // Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr'). >+ // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right' >+ // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left' >+ // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width' >+ // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right' >+ LayoutUnit computedLeftValue; >+ if (left.isAuto() && !right.isAuto()) { >+ // #1 #4 >+ auto marginLeft = displayBox.marginLeft(); >+ auto marginRight = displayBox.marginRight(); >+ >+ auto paddingLeft = displayBox.paddingLeft(); >+ auto paddingRight = displayBox.paddingRight(); >+ >+ auto borderLeft = displayBox.borderLeft(); >+ auto borderRight = displayBox.borderRight(); >+ >+ computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value()); >+ } else if (left.isAuto() && right.isAuto()) { >+ // #2 >+ // FIXME: rtl >+ computedLeftValue = displayBox.left(); >+ } else { >+ // #3 #5 #6 have left != auto >+ computedLeftValue = valueForLength(left, containingBlockWidth); >+ } >+ >+ displayBox.setLeft(computedLeftValue); >+} >+ >+void FormattingContext::computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const >+{ >+ >+} > } > } > #endif >diff --git a/Source/WebCore/layout/FormattingContext.h b/Source/WebCore/layout/FormattingContext.h >index ee0ed554b6b84f138fc904c47fd66959eb7137ca..ed8e87fe1cab962edb6c5aac16328211fd69564e 100644 >--- a/Source/WebCore/layout/FormattingContext.h >+++ b/Source/WebCore/layout/FormattingContext.h >@@ -66,7 +66,7 @@ protected: > > virtual void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const; > virtual void computeInFlowPositionedPosition(const Box&, Display::Box&) const; >- virtual void computeOutOfFlowPosition(const Box&, Display::Box&) const; >+ virtual void computeOutOfFlowPosition(LayoutContext&, const Box&, Display::Box&) const; > > virtual void computeWidth(LayoutContext&, const Box&, Display::Box&) const; > virtual void computeHeight(LayoutContext&, const Box&, Display::Box&) const; >@@ -96,6 +96,9 @@ private: > void computeOutOfFlowReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; > void computeOutOfFlowReplacedWidth(LayoutContext&, const Box&, Display::Box&) const; > >+ void computeOutOfFlowNonReplacedPosition(LayoutContext&, const Box&, Display::Box&) const; >+ void computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const; >+ > void computeFloatingNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const; > void computeFloatingNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const; >
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 185858
:
340954
|
340980