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

Changeset 238119 in webkit


Ignore:
Timestamp:
Nov 12, 2018, 6:38:06 PM (8 years ago)
Author:
Alan Bujtas
Message:

Do not collapse the soon-to-be-parent anon block when we shuffle around the marker item renderer.
https://bugs.webkit.org/show_bug.cgi?id=191554
<rdar://problem/45825265>

Reviewed by Antti Koivisto.

Source/WebCore:

While moving the marker item renderer to its correct subtree, we accidentally remove the soon-to-be parent anonymous block.
Moving a renderer is a 2 step process:

  1. Detach the renderer from its current parent
  2. Attach it to its new parent.

During step #1, we check if there is a chance to collapse anonymous blocks. In this case the soon-to-be-parent is a sibling anonymous block which, after detaching the marker sibling
is not needed anymore (except we use it as the new parent).

Test: fast/inline/marker-list-item-move-should-not-crash.html

  • rendering/updating/RenderTreeBuilder.cpp:

(WebCore::RenderTreeBuilder::detach):

  • rendering/updating/RenderTreeBuilder.h:
  • rendering/updating/RenderTreeBuilderBlock.cpp:

(WebCore::RenderTreeBuilder::Block::detach):

  • rendering/updating/RenderTreeBuilderBlock.h:
  • rendering/updating/RenderTreeBuilderList.cpp:

(WebCore::RenderTreeBuilder::List::updateItemMarker):

LayoutTests:

  • fast/inline/marker-list-item-move-should-not-crash-expected.txt: Added.
  • fast/inline/marker-list-item-move-should-not-crash.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r238112 r238119  
     12018-11-12  Zalan Bujtas  <zalan@apple.com>
     2
     3        Do not collapse the soon-to-be-parent anon block when we shuffle around the marker item renderer.
     4        https://bugs.webkit.org/show_bug.cgi?id=191554
     5        <rdar://problem/45825265>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        * fast/inline/marker-list-item-move-should-not-crash-expected.txt: Added.
     10        * fast/inline/marker-list-item-move-should-not-crash.html: Added.
     11
    1122018-11-12  Sihui Liu  <sihui_liu@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r238118 r238119  
     12018-11-12  Zalan Bujtas  <zalan@apple.com>
     2
     3        Do not collapse the soon-to-be-parent anon block when we shuffle around the marker item renderer.
     4        https://bugs.webkit.org/show_bug.cgi?id=191554
     5        <rdar://problem/45825265>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        While moving the marker item renderer to its correct subtree, we accidentally remove the soon-to-be parent anonymous block.
     10        Moving a renderer is a 2 step process:
     11        1. Detach the renderer from its current parent
     12        2. Attach it to its new parent.
     13        During step #1, we check if there is a chance to collapse anonymous blocks. In this case the soon-to-be-parent is a sibling anonymous block which, after detaching the marker sibling
     14        is not needed anymore (except we use it as the new parent).
     15
     16        Test: fast/inline/marker-list-item-move-should-not-crash.html
     17
     18        * rendering/updating/RenderTreeBuilder.cpp:
     19        (WebCore::RenderTreeBuilder::detach):
     20        * rendering/updating/RenderTreeBuilder.h:
     21        * rendering/updating/RenderTreeBuilderBlock.cpp:
     22        (WebCore::RenderTreeBuilder::Block::detach):
     23        * rendering/updating/RenderTreeBuilderBlock.h:
     24        * rendering/updating/RenderTreeBuilderList.cpp:
     25        (WebCore::RenderTreeBuilder::List::updateItemMarker):
     26
    1272018-11-12  Javier Fernandez  <jfernandez@igalia.com>
    228
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp

    r233056 r238119  
    318318}
    319319
    320 RenderPtr<RenderObject> RenderTreeBuilder::detach(RenderElement& parent, RenderObject& child)
     320RenderPtr<RenderObject> RenderTreeBuilder::detach(RenderElement& parent, RenderObject& child, CanCollapseAnonymousBlock canCollapseAnonymousBlock)
    321321{
    322322    if (is<RenderRubyAsInline>(parent))
     
    351351
    352352    if (is<RenderBlockFlow>(parent))
    353         return blockBuilder().detach(downcast<RenderBlockFlow>(parent), child);
     353        return blockBuilder().detach(downcast<RenderBlockFlow>(parent), child, canCollapseAnonymousBlock);
    354354
    355355    if (is<RenderBlock>(parent))
    356         return blockBuilder().detach(downcast<RenderBlock>(parent), child);
     356        return blockBuilder().detach(downcast<RenderBlock>(parent), child, canCollapseAnonymousBlock);
    357357
    358358    return detachFromRenderElement(parent, child);
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h

    r232064 r238119  
    4545    void attach(RenderElement& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
    4646
    47     RenderPtr<RenderObject> detach(RenderElement&, RenderObject&) WARN_UNUSED_RETURN;
     47    enum class CanCollapseAnonymousBlock { No, Yes };
     48    RenderPtr<RenderObject> detach(RenderElement&, RenderObject&, CanCollapseAnonymousBlock = CanCollapseAnonymousBlock::Yes) WARN_UNUSED_RETURN;
    4849
    4950    void destroy(RenderObject& renderer);
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp

    r235586 r238119  
    273273}
    274274
    275 RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlock& parent, RenderObject& oldChild)
     275RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlock& parent, RenderObject& oldChild, CanCollapseAnonymousBlock canCollapseAnonymousBlock)
    276276{
    277277    // No need to waste time in merging or removing empty anonymous blocks.
     
    330330    }
    331331
    332     RenderObject* child = prev ? prev.get() : next.get();
    333     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && parent.canDropAnonymousBlockChild()) {
    334         // The removal has knocked us down to containing only a single anonymous
    335         // box. We can pull the content right back up into our box.
    336         dropAnonymousBoxChild(parent, downcast<RenderBlock>(*child));
    337     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && parent.canDropAnonymousBlockChild()) {
    338         // It's possible that the removal has knocked us down to a single anonymous
    339         // block with floating siblings.
    340         RenderBlock& anonBlock = downcast<RenderBlock>((prev && prev->isAnonymousBlock()) ? *prev : *next);
    341         if (canDropAnonymousBlock(anonBlock)) {
    342             bool dropAnonymousBlock = true;
    343             for (auto& sibling : childrenOfType<RenderObject>(parent)) {
    344                 if (&sibling == &anonBlock)
    345                     continue;
    346                 if (!sibling.isFloating()) {
    347                     dropAnonymousBlock = false;
    348                     break;
     332    if (canCollapseAnonymousBlock == CanCollapseAnonymousBlock::Yes && parent.canDropAnonymousBlockChild()) {
     333        RenderObject* child = prev ? prev.get() : next.get();
     334        if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling()) {
     335            // The removal has knocked us down to containing only a single anonymous box. We can pull the content right back up into our box.
     336            dropAnonymousBoxChild(parent, downcast<RenderBlock>(*child));
     337        } else if ((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) {
     338            // It's possible that the removal has knocked us down to a single anonymous block with floating siblings.
     339            RenderBlock& anonBlock = downcast<RenderBlock>((prev && prev->isAnonymousBlock()) ? *prev : *next);
     340            if (canDropAnonymousBlock(anonBlock)) {
     341                bool dropAnonymousBlock = true;
     342                for (auto& sibling : childrenOfType<RenderObject>(parent)) {
     343                    if (&sibling == &anonBlock)
     344                        continue;
     345                    if (!sibling.isFloating()) {
     346                        dropAnonymousBlock = false;
     347                        break;
     348                    }
    349349                }
     350                if (dropAnonymousBlock)
     351                    dropAnonymousBoxChild(parent, anonBlock);
    350352            }
    351             if (dropAnonymousBlock)
    352                 dropAnonymousBoxChild(parent, anonBlock);
    353353        }
    354354    }
     
    374374}
    375375
    376 RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlockFlow& parent, RenderObject& child)
     376RenderPtr<RenderObject> RenderTreeBuilder::Block::detach(RenderBlockFlow& parent, RenderObject& child, CanCollapseAnonymousBlock canCollapseAnonymousBlock)
    377377{
    378378    if (!parent.renderTreeBeingDestroyed()) {
     
    381381            m_builder.multiColumnBuilder().multiColumnRelativeWillBeRemoved(*fragmentedFlow, child);
    382382    }
    383     return detach(static_cast<RenderBlock&>(parent), child);
    384 }
    385 
    386 }
     383    return detach(static_cast<RenderBlock&>(parent), child, canCollapseAnonymousBlock);
     384}
     385
     386}
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.h

    r228954 r238119  
    3838    void attachIgnoringContinuation(RenderBlock& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
    3939
    40     RenderPtr<RenderObject> detach(RenderBlock& parent, RenderObject& oldChild) WARN_UNUSED_RETURN;
    41     RenderPtr<RenderObject> detach(RenderBlockFlow& parent, RenderObject& child) WARN_UNUSED_RETURN;
     40    RenderPtr<RenderObject> detach(RenderBlock& parent, RenderObject& oldChild, CanCollapseAnonymousBlock = CanCollapseAnonymousBlock::Yes) WARN_UNUSED_RETURN;
     41    RenderPtr<RenderObject> detach(RenderBlockFlow& parent, RenderObject& child, CanCollapseAnonymousBlock = CanCollapseAnonymousBlock::Yes) WARN_UNUSED_RETURN;
    4242
    4343    void dropAnonymousBoxChild(RenderBlock& parent, RenderBlock& child);
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilderList.cpp

    r232178 r238119  
    116116
    117117    if (currentParent)
    118         m_builder.attach(*newParent, m_builder.detach(*currentParent, *markerRenderer), firstNonMarkerChild(*newParent));
     118        m_builder.attach(*newParent, m_builder.detach(*currentParent, *markerRenderer, RenderTreeBuilder::CanCollapseAnonymousBlock::No), firstNonMarkerChild(*newParent));
    119119    else
    120120        m_builder.attach(*newParent, WTFMove(newMarkerRenderer), firstNonMarkerChild(*newParent));
Note: See TracChangeset for help on using the changeset viewer.