Changeset 231642 in webkit


Ignore:
Timestamp:
May 10, 2018 9:46:54 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC] Implement height computation for non-replaced inflow elements.
https://bugs.webkit.org/show_bug.cgi?id=185474

Reviewed by Antti Koivisto.

Initial implementation. Does not cover all the cases.

  • layout/FormattingContext.cpp:

(WebCore::Layout::FormattingContext::computeHeight const):

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

(WebCore::Layout::BlockFormattingContext::layout const):
(WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
(WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const):

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

(WebCore::Layout::collapsedMarginBottomFromLastChild):
(WebCore::Layout::BlockMarginCollapse::isMarginBottomCollapsedWithParent):
(WebCore::Layout::BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom):
(WebCore::Layout::isMarginBottomCollapsedWithParent): Deleted.

  • layout/blockformatting/BlockMarginCollapse.h:
  • layout/inlineformatting/InlineFormattingContext.cpp:

(WebCore::Layout::InlineFormattingContext::computeInFlowHeight const):

  • layout/inlineformatting/InlineFormattingContext.h:
  • layout/layouttree/LayoutBox.cpp:

(WebCore::Layout::Box::isReplaced const):

  • layout/layouttree/LayoutBox.h:
Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r231638 r231642  
     12018-05-10  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC] Implement height computation for non-replaced inflow elements.
     4        https://bugs.webkit.org/show_bug.cgi?id=185474
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Initial implementation. Does not cover all the cases.
     9
     10        * layout/FormattingContext.cpp:
     11        (WebCore::Layout::FormattingContext::computeHeight const):
     12        * layout/FormattingContext.h:
     13        * layout/blockformatting/BlockFormattingContext.cpp:
     14        (WebCore::Layout::BlockFormattingContext::layout const):
     15        (WebCore::Layout::BlockFormattingContext::computeInFlowHeight const):
     16        (WebCore::Layout::BlockFormattingContext::computeInFlowNonReplacedHeight const):
     17        * layout/blockformatting/BlockFormattingContext.h:
     18        * layout/blockformatting/BlockMarginCollapse.cpp:
     19        (WebCore::Layout::collapsedMarginBottomFromLastChild):
     20        (WebCore::Layout::BlockMarginCollapse::isMarginBottomCollapsedWithParent):
     21        (WebCore::Layout::BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom):
     22        (WebCore::Layout::isMarginBottomCollapsedWithParent): Deleted.
     23        * layout/blockformatting/BlockMarginCollapse.h:
     24        * layout/inlineformatting/InlineFormattingContext.cpp:
     25        (WebCore::Layout::InlineFormattingContext::computeInFlowHeight const):
     26        * layout/inlineformatting/InlineFormattingContext.h:
     27        * layout/layouttree/LayoutBox.cpp:
     28        (WebCore::Layout::Box::isReplaced const):
     29        * layout/layouttree/LayoutBox.h:
     30
    1312018-05-10  Thibault Saunier  <tsaunier@igalia.com>
    232
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r231480 r231642  
    6969}
    7070
    71 void FormattingContext::computeHeight(const Box& layoutBox, Display::Box& displayBox) const
     71void FormattingContext::computeHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
    7272{
    7373    if (layoutBox.isOutOfFlowPositioned())
     
    7575    if (layoutBox.isFloatingPositioned())
    7676        return computeFloatingHeight(layoutBox, displayBox);
    77     return computeInFlowHeight(layoutBox, displayBox);
     77    return computeInFlowHeight(layoutContext, layoutBox, displayBox);
    7878}
    7979
  • trunk/Source/WebCore/layout/FormattingContext.h

    r231480 r231642  
    7070
    7171    virtual void computeWidth(const Box&, Display::Box&) const;
    72     virtual void computeHeight(const Box&, Display::Box&) const;
     72    virtual void computeHeight(LayoutContext&, const Box&, Display::Box&) const;
    7373
    7474    virtual void computeOutOfFlowWidth(const Box&, Display::Box&) const;
     
    7878    virtual void computeOutOfFlowHeight(const Box&, Display::Box&) const;
    7979    virtual void computeFloatingHeight(const Box&, Display::Box&) const;
    80     virtual void computeInFlowHeight(const Box&, Display::Box&) const = 0;
     80    virtual void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const = 0;
    8181
    8282    virtual LayoutUnit marginTop(const Box&) const;
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp

    r231487 r231642  
    9595            auto& displayBox = layoutPair->displayBox;
    9696
    97             computeHeight(layoutBox, displayBox);
     97            computeHeight(layoutContext, layoutBox, displayBox);
    9898            // Adjust position now that we have all the previous floats placed in this context -if needed.
    9999            floatingContext.computePosition(layoutBox, displayBox);
     
    148148}
    149149
    150 void BlockFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const
    151 {
     150void BlockFormattingContext::computeInFlowHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
     151{
     152    if (!layoutBox.isReplaced()) {
     153        computeInFlowNonReplacedHeight(layoutContext, layoutBox, displayBox);
     154        return;
     155    }
     156    ASSERT_NOT_REACHED();
    152157}
    153158
     
    162167}
    163168
     169void BlockFormattingContext::computeInFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox, Display::Box& displayBox) const
     170{
     171    // https://www.w3.org/TR/CSS22/visudet.html
     172    // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
     173    // The element's height is the distance from its top content edge to the first applicable of the following:
     174    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
     175    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
     176    //    does not collapse with the element's bottom margin
     177    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
     178    // 4. zero, otherwise
     179    // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
     180    // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
     181    if (!layoutBox.style().logicalHeight().isAuto()) {
     182        // FIXME: Only fixed values yet.
     183        displayBox.setHeight(layoutBox.style().logicalHeight().value());
     184        return;
     185    }
     186
     187    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild()) {
     188        displayBox.setHeight(0);
     189        return;
     190    }
     191
     192    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
     193    if (layoutBox.establishesInlineFormattingContext()) {
     194        // height = lastLineBox().bottom();
     195        displayBox.setHeight(0);
     196        return;
     197    }
     198
     199    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
     200    auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
     201    ASSERT(lastInFlowChild);
     202    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
     203        auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
     204        ASSERT(lastInFlowDisplayBox);
     205        displayBox.setHeight(lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom());
     206        return;
     207    }
     208
     209    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
     210    auto* inFlowChild = lastInFlowChild;
     211    while (inFlowChild && BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
     212        inFlowChild = inFlowChild->previousInFlowSibling();
     213    if (inFlowChild) {
     214        auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
     215        ASSERT(inFlowDisplayBox);
     216        displayBox.setHeight(inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height());
     217        return;
     218    }
     219
     220    // 4. zero, otherwise
     221    displayBox.setHeight(0);
     222}
     223
    164224}
    165225}
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h

    r231480 r231642  
    5050    Ref<FloatingState> createOrFindFloatingState(LayoutContext&) const override;
    5151
    52 protected:
     52private:
    5353    void computeStaticPosition(LayoutContext&, const Box&, Display::Box&) const override;
    5454    void computeInFlowWidth(const Box&, Display::Box&) const override;
    55     void computeInFlowHeight(const Box&, Display::Box&) const override;
     55    void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override;
     56    void computeInFlowNonReplacedHeight(LayoutContext&, const Box&, Display::Box&) const;
    5657
    5758    LayoutUnit marginTop(const Box&) const override;
  • trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp

    r231487 r231642  
    115115}
    116116
    117 static bool isMarginBottomCollapsedWithParent(const Box& layoutBox)
    118 {
    119     // last inflow box to parent.
    120     // https://www.w3.org/TR/CSS21/box.html#collapsing-margins
    121     if (layoutBox.isAnonymous())
    122         return false;
    123 
    124     if (layoutBox.isFloatingOrOutOfFlowPositioned())
    125         return false;
    126 
    127     // We never margin collapse the initial containing block.
    128     ASSERT(layoutBox.parent());
    129     auto& parent = *layoutBox.parent();
    130     // Is this the last inlflow child?
    131     if (parent.lastInFlowChild() != &layoutBox)
    132         return false;
    133 
    134     if (parent.establishesBlockFormattingContext())
    135         return false;
    136 
    137     // Margins of the root element's box do not collapse.
    138     if (parent.isInitialContainingBlock())
    139         return false;
    140 
    141     if (!parent.style().borderTop().nonZero())
    142         return false;
    143 
    144     if (!parent.style().paddingTop().isZero())
    145         return false;
    146 
    147     if (!parent.style().height().isAuto())
    148         return false;
    149 
    150     return true;
    151 }
    152 
    153117static LayoutUnit collapsedMarginTopFromFirstChild(const Box& layoutBox)
    154118{
     
    172136
    173137    auto& lastInFlowChild = *downcast<Container>(layoutBox).lastInFlowChild();
    174     if (!isMarginBottomCollapsedWithParent(lastInFlowChild))
     138    if (!BlockMarginCollapse::isMarginBottomCollapsedWithParent(lastInFlowChild))
    175139        return 0;
    176140
     
    250214}
    251215
     216bool BlockMarginCollapse::isMarginBottomCollapsedWithParent(const Box& layoutBox)
     217{
     218    // last inflow box to parent.
     219    // https://www.w3.org/TR/CSS21/box.html#collapsing-margins
     220    if (layoutBox.isAnonymous())
     221        return false;
     222
     223    if (layoutBox.isFloatingOrOutOfFlowPositioned())
     224        return false;
     225
     226    // We never margin collapse the initial containing block.
     227    ASSERT(layoutBox.parent());
     228    auto& parent = *layoutBox.parent();
     229    // Is this the last inlflow child?
     230    if (parent.lastInFlowChild() != &layoutBox)
     231        return false;
     232
     233    if (parent.establishesBlockFormattingContext())
     234        return false;
     235
     236    // Margins of the root element's box do not collapse.
     237    if (parent.isInitialContainingBlock())
     238        return false;
     239
     240    if (!parent.style().borderTop().nonZero())
     241        return false;
     242
     243    if (!parent.style().paddingTop().isZero())
     244        return false;
     245
     246    if (!parent.style().height().isAuto())
     247        return false;
     248
     249    return true;
     250}
     251
     252bool BlockMarginCollapse::isMarginTopCollapsedWithParentMarginBottom(const Box&)
     253{
     254    return false;
     255}
     256
    252257}
    253258}
  • trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.h

    r231487 r231642  
    4343    static LayoutUnit marginTop(const Box&);
    4444    static LayoutUnit marginBottom(const Box&);
     45
     46    static bool isMarginBottomCollapsedWithParent(const Box&);
     47    static bool isMarginTopCollapsedWithParentMarginBottom(const Box&);
    4548};
    4649
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

    r231480 r231642  
    7171}
    7272
    73 void InlineFormattingContext::computeInFlowHeight(const Box&, Display::Box&) const
     73void InlineFormattingContext::computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const
    7474{
    7575}
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

    r231480 r231642  
    5050private:
    5151    void computeInFlowWidth(const Box&, Display::Box&) const override;
    52     void computeInFlowHeight(const Box&, Display::Box&) const override;
     52    void computeInFlowHeight(LayoutContext&, const Box&, Display::Box&) const override;
    5353
    5454};
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp

    r231096 r231642  
    180180}
    181181
     182bool Box::isReplaced() const
     183{
     184    // HTMLAudioElement || HTMLCanvasElement || HTMLEmbedElement || HTMLIFrameElement || HTMLImageElement || HTMLInputElement || HTMLObjectElement || HTMLVideoElement
     185    return false;
     186}
     187
    182188const Box* Box::nextInFlowSibling() const
    183189{
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.h

    r231141 r231642  
    7373    bool isBlockContainerBox() const;
    7474    bool isInitialContainingBlock() const;
     75    bool isReplaced() const;
    7576
    7677    const Container* parent() const { return m_parent; }
Note: See TracChangeset for help on using the changeset viewer.