Changeset 247198 in webkit


Ignore:
Timestamp:
Jul 7, 2019 6:47:26 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC] Fix formatting context root for inflow positioned inline containers
https://bugs.webkit.org/show_bug.cgi?id=199551
<rdar://problem/52728868>

Reviewed by Antti Koivisto.

Relatively positioned (inflow) inline container lives in the formatting context where its parent lives unless
the parent establishes a formatting context. This is slightly different from the usual behavior which is containing block driven.

div id=outer style="position: absolute">><div id=inner><span style="position: relative">content</span></div></div>

While the relatively positioned inline container (span) is placed relative to its containing block "outer", it lives in the inline formatting context established by "inner".

  • layout/FormattingContext.cpp:

(WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):

  • layout/layouttree/LayoutBox.cpp:

(WebCore::Layout::Box::formattingContextRoot const):

  • layout/layouttree/LayoutBox.h:
  • layout/layouttree/LayoutInlineContainer.cpp:

(WebCore::Layout::InlineContainer::formattingContextRoot const):

  • layout/layouttree/LayoutInlineContainer.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r247195 r247198  
     12019-07-07  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC] Fix formatting context root for inflow positioned inline containers
     4        https://bugs.webkit.org/show_bug.cgi?id=199551
     5        <rdar://problem/52728868>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Relatively positioned (inflow) inline container lives in the formatting context where its parent lives unless
     10        the parent establishes a formatting context. This is slightly different from the usual behavior which is containing block driven.
     11
     12        div id=outer style="position: absolute">><div id=inner><span style="position: relative">content</span></div></div>
     13
     14        While the relatively positioned inline container (span) is placed relative to its containing block "outer", it lives in the inline formatting context established by "inner".
     15
     16        * layout/FormattingContext.cpp:
     17        (WebCore::Layout::FormattingContext::layoutOutOfFlowDescendants const):
     18        * layout/layouttree/LayoutBox.cpp:
     19        (WebCore::Layout::Box::formattingContextRoot const):
     20        * layout/layouttree/LayoutBox.h:
     21        * layout/layouttree/LayoutInlineContainer.cpp:
     22        (WebCore::Layout::InlineContainer::formattingContextRoot const):
     23        * layout/layouttree/LayoutInlineContainer.h:
     24
    1252019-07-06  Simon Fraser  <simon.fraser@apple.com>
    226
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r246483 r247198  
    136136void FormattingContext::layoutOutOfFlowDescendants(const Box& layoutBox) const
    137137{
    138     // Initial containing block by definition is a containing block.
    139     if (!layoutBox.isPositioned() && !layoutBox.isInitialContainingBlock())
    140         return;
    141 
    142138    if (!is<Container>(layoutBox))
    143139        return;
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp

    r246479 r247198  
    175175const Container& Box::formattingContextRoot() const
    176176{
    177     for (auto* ancestor = containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
    178         if (ancestor->establishesFormattingContext())
    179             return *ancestor;
    180     }
    181 
    182     // Initial containing block always establishes a formatting context.
    183     if (isInitialContainingBlock())
    184         return downcast<Container>(*this);
    185 
    186     RELEASE_ASSERT_NOT_REACHED();
     177    // We should never need to ask this question on the ICB.
     178    ASSERT(!isInitialContainingBlock());
     179    // A box lives in the same formatting context as its containing block unless the containing block establishes a formatting context.
     180    auto& containingBlock = *this->containingBlock();
     181    if (containingBlock.establishesFormattingContext())
     182        return containingBlock;
     183    return containingBlock.formattingContextRoot();
    187184}
    188185
  • trunk/Source/WebCore/layout/layouttree/LayoutBox.h

    r246479 r247198  
    9898
    9999    const Container* containingBlock() const;
    100     const Container& formattingContextRoot() const;
     100    virtual const Container& formattingContextRoot() const;
    101101    const Container& initialContainingBlock() const;
    102102
  • trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.cpp

    r239427 r247198  
    5555}
    5656
     57const Container& InlineContainer::formattingContextRoot() const
     58{
     59    // Relatively positioned (inflow) inline container lives in the formatting context where its parent lives unless
     60    // the parent establishes a formatting context. This is slightly different from the usual behavior which is containing block driven.
     61    //
     62    // <div id=outer style="position: absolute">><div id=inner><span style="position: relative">content</span></div></div>
     63    // While the relatively positioned inline container (span) is placed relative to its containing block "outer", it lives in the inline
     64    // formatting context established by "inner".
     65    auto& ancestor = isInFlowPositioned() ? *parent() : *containingBlock();
     66    if (ancestor.establishesFormattingContext())
     67        return ancestor;
     68    return ancestor.formattingContextRoot();
     69}
     70
    5771}
    5872}
  • trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.h

    r239427 r247198  
    4343
    4444    bool establishesInlineFormattingContext() const final;
     45    const Container& formattingContextRoot() const final;
    4546};
    4647
Note: See TracChangeset for help on using the changeset viewer.