⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276549 in webkit


Ignore:
Timestamp:
Apr 24, 2021, 6:42:04 AM (5 years ago)
Author:
Alan Bujtas
Message:

[RenderTreeBuilder] Subtree moving should clear the floats on all the descendants
https://bugs.webkit.org/show_bug.cgi?id=224996
<rdar://76837320>

Reviewed by Antti Koivisto.

Source/WebCore:

While moving a subtree, we invalidate the floating object list so that we don't end up with incorrectly placed floats (they'll get regenerated during the subsequent layout).
A float can be "assigned" to more than one RenderBlockFlow (e.g intruding floats). It's very common that a set of descendant RenderBlockFlow
renderers "see" the same set of floats (each RenderBlockFlow has its own list of floating objects).
Now the invalidation is based on ancestor-to-descendant direction starting with finding the outer most containing block for a particular float (see outermostBlockContainingFloatingObject)
The invalidation logic also expects no gaps in the ancestor chain e.g.

RenderBlockFlow (A) -> float X

RenderBlockFlow (B) -> float X

RenderBlockFlow (C) -> float X

if float X is assigned to both A and C, then it must be assigned to B as well.

RenderBlockFlow::removeFloatingObjects() simply removes the float from the renderer. It does not invalidate the ancestor/descendant chain.
e.g. calling B.removeFloatingObjects() would just remove float X from RenderBlockFlow (B)

RenderBlockFlow (A) -> float X

RenderBlockFlow (B)

RenderBlockFlow (C) -> float X

and any subsequent invalidation attempt would fail to clear up A or C (depending on whether it is initiated on A or C).

Test: fast/multicol/floating-boxes-moved-under-multi-column.html

  • rendering/updating/RenderTreeBuilder.cpp:

(WebCore::RenderTreeBuilder::moveChildren):

LayoutTests:

  • fast/multicol/floating-boxes-moved-under-multi-column-expected.txt: Added.
  • fast/multicol/floating-boxes-moved-under-multi-column.html: Added.
Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r276547 r276549  
     12021-04-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        [RenderTreeBuilder] Subtree moving should clear the floats on all the descendants
     4        https://bugs.webkit.org/show_bug.cgi?id=224996
     5        <rdar://76837320>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        * fast/multicol/floating-boxes-moved-under-multi-column-expected.txt: Added.
     10        * fast/multicol/floating-boxes-moved-under-multi-column.html: Added.
     11
    1122021-04-24  Rob Buis  <rbuis@igalia.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r276548 r276549  
     12021-04-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        [RenderTreeBuilder] Subtree moving should clear the floats on all the descendants
     4        https://bugs.webkit.org/show_bug.cgi?id=224996
     5        <rdar://76837320>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        While moving a subtree, we invalidate the floating object list so that we don't end up with incorrectly placed floats (they'll get regenerated during the subsequent layout).
     10        A float can be "assigned" to more than one RenderBlockFlow (e.g intruding floats). It's very common that a set of descendant RenderBlockFlow
     11        renderers "see" the same set of floats (each RenderBlockFlow has its own list of floating objects).
     12        Now the invalidation is based on ancestor-to-descendant direction starting with finding the outer most containing block for a particular float (see outermostBlockContainingFloatingObject)
     13        The invalidation logic also expects no gaps in the ancestor chain e.g.
     14
     15           RenderBlockFlow (A) -> float X
     16             RenderBlockFlow (B) -> float X
     17               RenderBlockFlow (C) -> float X
     18           if float X is assigned to both A and C, then it must be assigned to B as well.
     19
     20        RenderBlockFlow::removeFloatingObjects() simply removes the float from the renderer. It does not invalidate the ancestor/descendant chain.
     21        e.g. calling B.removeFloatingObjects() would just remove float X from RenderBlockFlow (B)
     22
     23           RenderBlockFlow (A) -> float X
     24             RenderBlockFlow (B)
     25               RenderBlockFlow (C) -> float X
     26
     27        and any subsequent invalidation attempt would fail to clear up A or C (depending on whether it is initiated on A or C).
     28
     29        Test: fast/multicol/floating-boxes-moved-under-multi-column.html
     30
     31        * rendering/updating/RenderTreeBuilder.cpp:
     32        (WebCore::RenderTreeBuilder::moveChildren):
     33
    1342021-04-24  Zalan Bujtas  <zalan@apple.com>
    235
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp

    r276464 r276549  
    532532    if (normalizeAfterInsertion == NormalizeAfterInsertion::Yes && is<RenderBlock>(from)) {
    533533        downcast<RenderBlock>(from).removePositionedObjects(nullptr);
    534         if (is<RenderBlockFlow>(from))
    535             downcast<RenderBlockFlow>(from).removeFloatingObjects();
     534        auto removeFloatingObjectsIfApplicable = [&] {
     535            if (from.renderTreeBeingDestroyed())
     536                return;
     537            if (!is<RenderBlockFlow>(from))
     538                return;
     539            auto* floatingObjects = downcast<RenderBlockFlow>(from).floatingObjectSet();
     540            if (!floatingObjects)
     541                return;
     542            // Here we remove the floating objects from the descendants as well.
     543            auto copyOfFloatingObjects = WTF::map(*floatingObjects, [](auto& floatingObject) {
     544                return floatingObject.get();
     545            });
     546            for (auto* floatingObject : copyOfFloatingObjects)
     547                floatingObject->renderer().removeFloatingOrPositionedChildFromBlockLists();
     548        };
     549        removeFloatingObjectsIfApplicable();
    536550    }
    537551
Note: See TracChangeset for help on using the changeset viewer.