Changeset 234083 in webkit


Ignore:
Timestamp:
Jul 21, 2018 8:00:30 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][BFC] Do not collapse top/bottom margin with first/last inflow child from a non-block formatting context.
https://bugs.webkit.org/show_bug.cgi?id=187867

Reviewed by Antti Koivisto.

The box's top/bottom margin never collapses with a non-block inflow child.

  • layout/blockformatting/BlockMarginCollapse.cpp:

(WebCore::Layout::isMarginTopCollapsedWithSibling):
(WebCore::Layout::isMarginBottomCollapsedWithSibling):
(WebCore::Layout::isMarginTopCollapsedWithParent):
(WebCore::Layout::isMarginBottomCollapsedThrough):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::collapsedMarginTopFromFirstChild):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::nonCollapsedMarginTop):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginTop):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginBottom):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginTop):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBottom):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::collapsedMarginBottomFromLastChild):
(WebCore::Layout::BlockFormattingContext::MarginCollapse::nonCollapsedMarginBottom):

  • layout/layouttree/LayoutBox.cpp:

(WebCore::Layout::Box::establishesBlockFormattingContextOnly const): <div style="overflow: hidden">foobar</div> establishes both inline and block formatting context (inline wins though).

  • layout/layouttree/LayoutBox.h: establishesBlockFormattingContext() does not need to be virtual since we can determine it by looking at the box's style. -while in case

of inline formatting context, it is about the content.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r234078 r234083  
     12018-07-21  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][BFC] Do not collapse top/bottom margin with first/last inflow child from a non-block formatting context.
     4        https://bugs.webkit.org/show_bug.cgi?id=187867
     5
     6        Reviewed by Antti Koivisto.
     7
     8        The box's top/bottom margin never collapses with a non-block inflow child.
     9
     10        * layout/blockformatting/BlockMarginCollapse.cpp:
     11        (WebCore::Layout::isMarginTopCollapsedWithSibling):
     12        (WebCore::Layout::isMarginBottomCollapsedWithSibling):
     13        (WebCore::Layout::isMarginTopCollapsedWithParent):
     14        (WebCore::Layout::isMarginBottomCollapsedThrough):
     15        (WebCore::Layout::BlockFormattingContext::MarginCollapse::collapsedMarginTopFromFirstChild):
     16        (WebCore::Layout::BlockFormattingContext::MarginCollapse::nonCollapsedMarginTop):
     17        (WebCore::Layout::BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginTop):
     18        (WebCore::Layout::BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginBottom):
     19        (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginTop):
     20        (WebCore::Layout::BlockFormattingContext::MarginCollapse::marginBottom):
     21        (WebCore::Layout::BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent):
     22        (WebCore::Layout::BlockFormattingContext::MarginCollapse::collapsedMarginBottomFromLastChild):
     23        (WebCore::Layout::BlockFormattingContext::MarginCollapse::nonCollapsedMarginBottom):
     24        * layout/layouttree/LayoutBox.cpp:
     25        (WebCore::Layout::Box::establishesBlockFormattingContextOnly const): <div style="overflow: hidden">foobar</div> establishes both inline and block formatting context (inline wins though).
     26        * layout/layouttree/LayoutBox.h: establishesBlockFormattingContext() does not need to be virtual since we can determine it by looking at the box's style. -while in case
     27        of inline formatting context, it is about the content.
     28
    1292018-07-20  Jer Noble  <jer.noble@apple.com>
    230
  • trunk/Source/WebCore/layout/blockformatting/BlockMarginCollapse.cpp

    r233398 r234083  
    5555static bool isMarginTopCollapsedWithSibling(const Box& layoutBox)
    5656{
     57    ASSERT(layoutBox.isBlockLevelBox());
     58
    5759    if (layoutBox.isFloatingPositioned())
    5860        return false;
     
    6870static bool isMarginBottomCollapsedWithSibling(const Box& layoutBox)
    6971{
     72    ASSERT(layoutBox.isBlockLevelBox());
     73
    7074    if (layoutBox.isFloatingPositioned())
    7175        return false;
     
    8589    if (layoutBox.isAnonymous())
    8690        return false;
     91
     92    ASSERT(layoutBox.isBlockLevelBox());
    8793
    8894    if (layoutBox.isFloatingOrOutOfFlowPositioned())
     
    115121static bool isMarginBottomCollapsedThrough(const LayoutContext& layoutContext, const Box& layoutBox)
    116122{
     123    ASSERT(layoutBox.isBlockLevelBox());
     124
    117125    // If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it.
    118126    auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
     
    139147LayoutUnit BlockFormattingContext::MarginCollapse::collapsedMarginTopFromFirstChild(const LayoutContext& layoutContext, const Box& layoutBox)
    140148{
     149    ASSERT(layoutBox.isBlockLevelBox());
     150
    141151    // Check if the first child collapses its margin top.
    142152    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
     153        return 0;
     154
     155    // Do not collapse margin with a box from a non-block formatting context <div><span>foobar</span></div>.
     156    if (layoutBox.establishesFormattingContext() && !layoutBox.establishesBlockFormattingContextOnly())
    143157        return 0;
    144158
     
    153167LayoutUnit BlockFormattingContext::MarginCollapse::nonCollapsedMarginTop(const LayoutContext& layoutContext, const Box& layoutBox)
    154168{
     169    ASSERT(layoutBox.isBlockLevelBox());
     170
    155171    // Non collapsed margin top includes collapsed margin from inflow first child.
    156172    return marginValue(computedNonCollapsedMarginTop(layoutContext, layoutBox), collapsedMarginTopFromFirstChild(layoutContext, layoutBox));
     
    173189LayoutUnit BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginTop(const LayoutContext& layoutContext, const Box& layoutBox)
    174190{
     191    ASSERT(layoutBox.isBlockLevelBox());
     192
    175193    return FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(layoutContext, layoutBox).top;
    176194}
     
    178196LayoutUnit BlockFormattingContext::MarginCollapse::computedNonCollapsedMarginBottom(const LayoutContext& layoutContext, const Box& layoutBox)
    179197{
     198    ASSERT(layoutBox.isBlockLevelBox());
     199
    180200    return FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(layoutContext, layoutBox).bottom;
    181201}
     
    185205    if (layoutBox.isAnonymous())
    186206        return 0;
     207
     208    ASSERT(layoutBox.isBlockLevelBox());
    187209
    188210    // TODO: take _hasAdjoiningMarginTopAndBottom() into account.
     
    215237        return 0;
    216238
     239    ASSERT(layoutBox.isBlockLevelBox());
     240
    217241    // TODO: take _hasAdjoiningMarginTopAndBottom() into account.
    218242    if (isMarginBottomCollapsedWithParent(layoutContext, layoutBox))
     
    239263    if (layoutBox.isAnonymous())
    240264        return false;
     265
     266    ASSERT(layoutBox.isBlockLevelBox());
    241267
    242268    if (layoutBox.isFloatingOrOutOfFlowPositioned())
     
    280306LayoutUnit BlockFormattingContext::MarginCollapse::collapsedMarginBottomFromLastChild(const LayoutContext& layoutContext, const Box& layoutBox)
    281307{
     308    ASSERT(layoutBox.isBlockLevelBox());
     309
    282310    // Check if the last child propagates its margin bottom.
    283311    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
     312        return 0;
     313
     314    // Do not collapse margin with a box from a non-block formatting context <div><span>foobar</span></div>.
     315    if (layoutBox.establishesFormattingContext() && !layoutBox.establishesBlockFormattingContextOnly())
    284316        return 0;
    285317
     
    295327LayoutUnit BlockFormattingContext::MarginCollapse::nonCollapsedMarginBottom(const LayoutContext& layoutContext, const Box& layoutBox)
    296328{
     329    ASSERT(layoutBox.isBlockLevelBox());
     330
    297331    // Non collapsed margin bottom includes collapsed margin from inflow last child.
    298332    return marginValue(computedNonCollapsedMarginBottom(layoutContext, layoutBox), collapsedMarginBottomFromLastChild(layoutContext, layoutBox));
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp

    r234048 r234083  
    7171}
    7272
     73bool Box::establishesBlockFormattingContextOnly() const
     74{
     75    return establishesBlockFormattingContext() && !establishesInlineFormattingContext();
     76}
     77
    7378bool Box::isRelativelyPositioned() const
    7479{
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.h

    r234048 r234083  
    4848
    4949    bool establishesFormattingContext() const;
    50     virtual bool establishesBlockFormattingContext() const;
     50    bool establishesBlockFormattingContext() const;
     51    bool establishesBlockFormattingContextOnly() const;
    5152    virtual bool establishesInlineFormattingContext() const { return false; }
    5253
Note: See TracChangeset for help on using the changeset viewer.