Changeset 232065 in webkit


Ignore:
Timestamp:
May 22, 2018 8:06:27 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC] Implement positioning for non-replaced out-of-flow elements.
https://bugs.webkit.org/show_bug.cgi?id=185858

Reviewed by Antti Koivisto.

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:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r232064 r232065  
     12018-05-22  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC] Implement positioning for non-replaced out-of-flow elements.
     4        https://bugs.webkit.org/show_bug.cgi?id=185858
     5
     6        Reviewed by Antti Koivisto.
     7
     8        In certain cases, the out-of-flow element's final position depends on the element's size.
     9        Call computeOutOfFlowPosition() after width/height are resolved.
     10
     11        * layout/FormattingContext.cpp:
     12        (WebCore::Layout::FormattingContext::computeOutOfFlowPosition const):
     13        (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):
     14        (WebCore::Layout::FormattingContext::computeOutOfFlowNonReplacedPosition const):
     15        (WebCore::Layout::FormattingContext::computeOutOfFlowReplacedPosition const):
     16        * layout/FormattingContext.h:
     17
    1182018-05-22  Olivier Blin  <olivier.blin@softathome.com>
    219
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r232042 r232065  
    5858}
    5959
    60 void FormattingContext::computeOutOfFlowPosition(const Box&, Display::Box&) const
    61 {
     60void FormattingContext::computeOutOfFlowPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
     61{
     62    if (!layoutBox.replaced()) {
     63        computeOutOfFlowNonReplacedPosition(layoutContext, layoutBox, displayBox);
     64        return;
     65    }
     66    computeOutOfFlowReplacedPosition(layoutContext, layoutBox, displayBox);
    6267}
    6368
     
    148153        auto& displayBox = layoutContext.createDisplayBox(layoutBox);
    149154
    150         computeOutOfFlowPosition(layoutBox, displayBox);
     155        // The term "static position" (of an element) refers, roughly, to the position an element would have had in the normal flow.
     156        // More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin edge
     157        // of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static' and
     158        // its specified 'float' had been 'none' and its specified 'clear' had been 'none'.
     159        computeStaticPosition(layoutContext, layoutBox, displayBox);
    151160        computeOutOfFlowWidth(layoutContext, layoutBox, displayBox);
    152161
     
    156165
    157166        computeOutOfFlowHeight(layoutContext, layoutBox, displayBox);
     167        computeOutOfFlowPosition(layoutContext, layoutBox, displayBox);
    158168    }
    159169}
     
    439449}
    440450
     451void FormattingContext::computeOutOfFlowNonReplacedPosition(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
     452{
     453    // 10.3.7 Absolutely positioned, non-replaced elements (left/right)
     454    // 10.6.4 Absolutely positioned, non-replaced elements (top/bottom)
     455
     456    // At this point we've the size computed.
     457    auto size = displayBox.size();
     458    auto& style = layoutBox.style();
     459
     460    // 10.6.4 Absolutely positioned, non-replaced elements
     461    auto top = style.logicalTop();
     462    auto bottom = style.logicalBottom();
     463    auto containingBlockHeight = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->height();
     464
     465    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
     466    // = height of containing block
     467    //
     468    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
     469    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
     470    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
     471    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
     472    // 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'
     473    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
     474    // 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'
     475    // 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'
     476    // 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'
     477    LayoutUnit computedTopValue;
     478    if (top.isAuto() && !bottom.isAuto()) {
     479        // #1 #4
     480        auto marginTop = displayBox.marginTop();
     481        auto marginBottom = displayBox.marginBottom();
     482   
     483        auto paddingTop = displayBox.paddingTop();
     484        auto paddingBottom = displayBox.paddingBottom();
     485
     486        auto borderTop = displayBox.borderTop();
     487        auto borderBottom = displayBox.borderBottom();
     488
     489        computedTopValue = containingBlockHeight - (marginTop + borderTop + paddingTop + size.height() + paddingBottom + borderBottom + marginBottom + bottom.value());
     490    } else if (top.isAuto() && bottom.isAuto()) {
     491        // #2
     492        // Already computed as part of the computeStaticPosition();
     493        computedTopValue = displayBox.top();
     494    } else {
     495        // #3 #5 #6 have top != auto
     496        computedTopValue = valueForLength(top, containingBlockHeight);
     497    }
     498
     499    displayBox.setTop(computedTopValue);
     500
     501    // 10.3.7 Absolutely positioned, non-replaced elements
     502    auto left = style.logicalLeft();
     503    auto right = style.logicalRight();
     504    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
     505
     506    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
     507    // = width of containing block
     508    //
     509    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
     510    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
     511    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
     512
     513    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
     514    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position
     515    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
     516    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
     517    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
     518    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
     519    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
     520    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
     521    LayoutUnit computedLeftValue;
     522    if (left.isAuto() && !right.isAuto()) {
     523        // #1 #4
     524        auto marginLeft = displayBox.marginLeft();
     525        auto marginRight = displayBox.marginRight();
     526   
     527        auto paddingLeft = displayBox.paddingLeft();
     528        auto paddingRight = displayBox.paddingRight();
     529
     530        auto borderLeft = displayBox.borderLeft();
     531        auto borderRight = displayBox.borderRight();
     532
     533        computedLeftValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + size.width() + paddingRight + borderRight + marginRight + right.value());
     534    } else if (left.isAuto() && right.isAuto()) {
     535        // #2
     536        // FIXME: rtl
     537        computedLeftValue = displayBox.left();
     538    } else {
     539        // #3 #5 #6 have left != auto
     540        computedLeftValue = valueForLength(left, containingBlockWidth);
     541    }
     542
     543    displayBox.setLeft(computedLeftValue);
     544}
     545
     546void FormattingContext::computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const
     547{
     548
     549}
     550
    441551LayoutUnit FormattingContext::shrinkToFitWidth(LayoutContext&, const Box&) const
    442552{
     
    477587}
    478588#endif
     589
    479590}
    480591}
  • trunk/Source/WebCore/layout/FormattingContext.h

    r232042 r232065  
    6767    virtual void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const;
    6868    virtual void computeInFlowPositionedPosition(const Box&, Display::Box&) const;
    69     virtual void computeOutOfFlowPosition(const Box&, Display::Box&) const;
     69    virtual void computeOutOfFlowPosition(LayoutContext&, const Box&, Display::Box&) const;
    7070
    7171    virtual void computeWidth(LayoutContext&, const Box&, Display::Box&) const;
     
    101101    void computeOutOfFlowReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
    102102
     103    void computeOutOfFlowNonReplacedPosition(LayoutContext&, const Box&, Display::Box&) const;
     104    void computeOutOfFlowReplacedPosition(LayoutContext&, const Box&, Display::Box&) const;
     105
    103106    void computeFloatingNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
    104107    void computeFloatingNonReplacedWidth(LayoutContext&, const Box&, Display::Box&) const;
Note: See TracChangeset for help on using the changeset viewer.