Changeset 238077 in webkit


Ignore:
Timestamp:
Nov 11, 2018 1:29:12 PM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][BFC] In-flow positioned logic is really formatting context dependent.
https://bugs.webkit.org/show_bug.cgi?id=191512

Reviewed by Simon Fraser.

Move block formatting context specific code from FormattingContext to BlockFormattingContext.

  • layout/FormattingContext.cpp:

(WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const): Deleted.

  • layout/FormattingContext.h:
  • layout/FormattingContextGeometry.cpp:

(WebCore::Layout::FormattingContext::Geometry::inFlowPositionedPositionOffset):

  • layout/blockformatting/BlockFormattingContext.cpp:

(WebCore::Layout::BlockFormattingContext::placeInFlowPositionedChildren const):
(WebCore::Layout::BlockFormattingContext::computeInFlowPositionedPosition const): Deleted.

  • layout/blockformatting/BlockFormattingContext.h:
  • layout/blockformatting/BlockFormattingContextGeometry.cpp:

(WebCore::Layout::BlockFormattingContext::Geometry::inFlowPositionedPosition): Deleted.

  • layout/inlineformatting/InlineFormattingContext.cpp:

(WebCore::Layout::InlineFormattingContext::computeInFlowPositionedPosition const): Deleted.

  • layout/inlineformatting/InlineFormattingContext.h:
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238075 r238077  
     12018-11-11  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][BFC] In-flow positioned logic is really formatting context dependent.
     4        https://bugs.webkit.org/show_bug.cgi?id=191512
     5
     6        Reviewed by Simon Fraser.
     7
     8        Move block formatting context specific code from FormattingContext to BlockFormattingContext.
     9
     10        * layout/FormattingContext.cpp:
     11        (WebCore::Layout::FormattingContext::placeInFlowPositionedChildren const): Deleted.
     12        * layout/FormattingContext.h:
     13        * layout/FormattingContextGeometry.cpp:
     14        (WebCore::Layout::FormattingContext::Geometry::inFlowPositionedPositionOffset):
     15        * layout/blockformatting/BlockFormattingContext.cpp:
     16        (WebCore::Layout::BlockFormattingContext::placeInFlowPositionedChildren const):
     17        (WebCore::Layout::BlockFormattingContext::computeInFlowPositionedPosition const): Deleted.
     18        * layout/blockformatting/BlockFormattingContext.h:
     19        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
     20        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowPositionedPosition): Deleted.
     21        * layout/inlineformatting/InlineFormattingContext.cpp:
     22        (WebCore::Layout::InlineFormattingContext::computeInFlowPositionedPosition const): Deleted.
     23        * layout/inlineformatting/InlineFormattingContext.h:
     24
    1252018-11-11  Myles C. Maxfield  <mmaxfield@apple.com>
    226
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r237729 r238077  
    131131}
    132132
    133 void FormattingContext::placeInFlowPositionedChildren(const Container& container) const
    134 {
    135     // If this container also establishes a formatting context, then positioning already has happend in that the formatting context.
    136     if (container.establishesFormattingContext() && &container != &root())
    137         return;
    138 
    139     LOG_WITH_STREAM(FormattingContextLayout, stream << "Start: move in-flow positioned children -> parent: " << &container);
    140     for (auto& layoutBox : childrenOfType<Box>(container)) {
    141         if (!layoutBox.isInFlowPositioned())
    142             continue;
    143         computeInFlowPositionedPosition(layoutBox);
    144     }
    145     LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> parent: " << &container);
    146 }
    147 
    148133void FormattingContext::layoutOutOfFlowDescendants(const Box& layoutBox) const
    149134{
  • trunk/Source/WebCore/layout/FormattingContext.h

    r237782 r238077  
    7171
    7272    virtual void computeStaticPosition(const Box&) const = 0;
    73     virtual void computeInFlowPositionedPosition(const Box&) const = 0;
    7473
    7574    void computeBorderAndPadding(const Box&) const;
    76 
    77     void placeInFlowPositionedChildren(const Container&) const;
    7875
    7976#ifndef NDEBUG
     
    9390        static WidthAndMargin inlineReplacedWidthAndMargin(const LayoutState&, const Box&, std::optional<LayoutUnit> usedWidth = { },
    9491            std::optional<LayoutUnit> precomputedMarginLeft = { }, std::optional<LayoutUnit> precomputedMarginRight = { });
     92
     93        static LayoutSize inFlowPositionedPositionOffset(const LayoutState&, const Box&);
    9594
    9695        static HeightAndMargin complicatedCases(const LayoutState&, const Box&, std::optional<LayoutUnit> usedHeight = { });
  • trunk/Source/WebCore/layout/FormattingContextGeometry.cpp

    r237783 r238077  
    948948}
    949949
     950LayoutSize FormattingContext::Geometry::inFlowPositionedPositionOffset(const LayoutState& layoutState, const Box& layoutBox)
     951{
     952    ASSERT(layoutBox.isInFlowPositioned());
     953
     954    // 9.4.3 Relative positioning
     955    //
     956    // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size.
     957    // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom.
     958    //
     959    // 1. If both are 'auto', their used values are both '0'.
     960    // 2. If one of them is 'auto', it becomes the negative of the other.
     961    // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').
     962
     963    auto& style = layoutBox.style();
     964    auto& containingBlock = *layoutBox.containingBlock();
     965    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
     966
     967    auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     968    auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
     969
     970    if (!top && !bottom) {
     971        // #1
     972        top = bottom = { 0 };
     973    } else if (!top) {
     974        // #2
     975        top = -*bottom;
     976    } else if (!bottom) {
     977        // #3
     978        bottom = -*top;
     979    } else {
     980        // #4
     981        bottom = std::nullopt;
     982    }
     983
     984    // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size.
     985    // 'Left' moves the boxes to the right, and 'right' moves them to the left.
     986    // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.
     987    //
     988    // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).
     989    // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').
     990    // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'.
     991    // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored.
     992    //    If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'.
     993    //    If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.
     994
     995    auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
     996    auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);
     997
     998    if (!left && !right) {
     999        // #1
     1000        left = right = { 0 };
     1001    } else if (!left) {
     1002        // #2
     1003        left = -*right;
     1004    } else if (!right) {
     1005        // #3
     1006        right = -*left;
     1007    } else {
     1008        // #4
     1009        auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
     1010        if (isLeftToRightDirection)
     1011            right = -*left;
     1012        else
     1013            left = std::nullopt;
     1014    }
     1015
     1016    ASSERT(!bottom || *top == -*bottom);
     1017    ASSERT(!left || *left == -*right);
     1018
     1019    auto topPositionOffset = *top;
     1020    auto leftPositionOffset = left.value_or(-*right);
     1021
     1022    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top offset(" << topPositionOffset << "px) left offset(" << leftPositionOffset << "px) layoutBox(" << &layoutBox << ")");
     1023    return { leftPositionOffset, topPositionOffset };
     1024}
     1025
    9501026Edges FormattingContext::Geometry::computedBorder(const LayoutState&, const Box& layoutBox)
    9511027{
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp

    r237730 r238077  
    155155}
    156156
     157void BlockFormattingContext::placeInFlowPositionedChildren(const Container& container) const
     158{
     159    LOG_WITH_STREAM(FormattingContextLayout, stream << "Start: move in-flow positioned children -> parent: " << &container);
     160    for (auto& layoutBox : childrenOfType<Box>(container)) {
     161        if (!layoutBox.isInFlowPositioned())
     162            continue;
     163
     164        auto computeInFlowPositionedPosition = [&](auto& layoutBox) {
     165            auto& layoutState = this->layoutState();
     166            auto positionOffset = Geometry::inFlowPositionedPositionOffset(layoutState, layoutBox);
     167
     168            auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     169            auto topLeft = displayBox.topLeft();
     170
     171            topLeft.move(positionOffset);
     172
     173            displayBox.setTopLeft(topLeft);
     174        };
     175
     176        computeInFlowPositionedPosition(layoutBox);
     177    }
     178    LOG_WITH_STREAM(FormattingContextLayout, stream << "End: move in-flow positioned children -> parent: " << &container);
     179}
     180
    157181void BlockFormattingContext::computeStaticPosition(const Box& layoutBox) const
    158182{
     
    275299}
    276300
    277 void BlockFormattingContext::computeInFlowPositionedPosition(const Box& layoutBox) const
    278 {
    279     auto& layoutState = this->layoutState();
    280     layoutState.displayBoxForLayoutBox(layoutBox).setTopLeft(Geometry::inFlowPositionedPosition(layoutState, layoutBox));
    281 }
    282 
    283301void BlockFormattingContext::computeWidthAndMargin(const Box& layoutBox) const
    284302{
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h

    r237729 r238077  
    5252private:
    5353    void layoutFormattingContextRoot(FloatingContext&, const Box&) const;
     54    void placeInFlowPositionedChildren(const Container&) const;
    5455
    5556    void computeWidthAndMargin(const Box&) const;
     
    6162    void computeVerticalPositionForFloatClear(const FloatingContext&, const Box&) const;
    6263
    63     void computeInFlowPositionedPosition(const Box&) const override;
    6464    void computeEstimatedMarginTopForAncestors(const Box&) const;
    6565    void computeEstimatedMarginTop(const Box&) const;
     
    7676
    7777        static Position staticPosition(const LayoutState&, const Box&);
    78         static Position inFlowPositionedPosition(const LayoutState&, const Box&);
    7978
    8079        static bool instrinsicWidthConstraintsNeedChildrenWidth(const Box&);
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp

    r237782 r238077  
    288288}
    289289
    290 Position BlockFormattingContext::Geometry::inFlowPositionedPosition(const LayoutState& layoutState, const Box& layoutBox)
    291 {
    292     ASSERT(layoutBox.isInFlowPositioned());
    293 
    294     // 9.4.3 Relative positioning
    295     //
    296     // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size.
    297     // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom.
    298     //
    299     // 1. If both are 'auto', their used values are both '0'.
    300     // 2. If one of them is 'auto', it becomes the negative of the other.
    301     // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').
    302 
    303     auto& style = layoutBox.style();
    304     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
    305     auto& containingBlock = *layoutBox.containingBlock();
    306     auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
    307 
    308     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
    309     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
    310 
    311     if (!top && !bottom) {
    312         // #1
    313         top = bottom = { 0 };
    314     } else if (!top) {
    315         // #2
    316         top = -*bottom;
    317     } else if (!bottom) {
    318         // #3
    319         bottom = -*top;
    320     } else {
    321         // #4
    322         bottom = std::nullopt;
    323     }
    324 
    325     // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size.
    326     // 'Left' moves the boxes to the right, and 'right' moves them to the left.
    327     // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.
    328     //
    329     // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).
    330     // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').
    331     // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'.
    332     // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored.
    333     //    If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'.
    334     //    If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.
    335 
    336     auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
    337     auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);
    338 
    339     if (!left && !right) {
    340         // #1
    341         left = right = { 0 };
    342     } else if (!left) {
    343         // #2
    344         left = -*right;
    345     } else if (!right) {
    346         // #3
    347         right = -*left;
    348     } else {
    349         // #4
    350         auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
    351         if (isLeftToRightDirection)
    352             right = -*left;
    353         else
    354             left = std::nullopt;
    355     }
    356 
    357     ASSERT(!bottom || *top == -*bottom);
    358     ASSERT(!left || *left == -*right);
    359 
    360     auto newTopPosition = displayBox.top() + *top;
    361     auto newLeftPosition = displayBox.left() + left.value_or(-*right);
    362 
    363     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top(" << newTopPosition << "px) left(" << newLeftPosition << "px) layoutBox(" << &layoutBox << ")");
    364     return { newLeftPosition, newTopPosition };
    365 }
    366 
    367290HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutState& layoutState, const Box& layoutBox, std::optional<LayoutUnit> usedHeight)
    368291{
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

    r238028 r238077  
    285285}
    286286
    287 void InlineFormattingContext::computeInFlowPositionedPosition(const Box&) const
    288 {
    289 }
    290 
    291287void InlineFormattingContext::collectInlineContent(InlineRunProvider& inlineRunProvider) const
    292288{
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

    r238028 r238077  
    119119    void computeFloatPosition(const FloatingContext&, Line&, const Box&) const;
    120120    void computeStaticPosition(const Box&) const override;
    121     void computeInFlowPositionedPosition(const Box&) const override;
    122121
    123122    void collectInlineContent(InlineRunProvider&) const;
Note: See TracChangeset for help on using the changeset viewer.