Changeset 228365 in webkit


Ignore:
Timestamp:
Feb 10, 2018 7:44:55 AM (6 years ago)
Author:
Alan Bujtas
Message:

[RenderTreeBuilder] Move RenderBlock::takeChild mutation to a RenderTreeBuilder
https://bugs.webkit.org/show_bug.cgi?id=182662
<rdar://problem/37408571>

Reviewed by Simon Fraser.

No change in functionality.

  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::takeChild):
(WebCore::canDropAnonymousBlock): Deleted.
(WebCore::canMergeContiguousAnonymousBlocks): Deleted.

  • rendering/RenderBlock.h:

(WebCore::RenderBlock::moveAllChildrenIncludingFloatsTo):

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

(WebCore::RenderTreeBuilder::takenChildFromRenderBlock):

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

(WebCore::canDropAnonymousBlock):
(WebCore::canMergeContiguousAnonymousBlocks):
(WebCore::RenderTreeBuilder::Block::takeChild):

  • rendering/updating/RenderTreeBuilderBlock.h:
Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r228352 r228365  
     12018-02-10  Zalan Bujtas  <zalan@apple.com>
     2
     3        [RenderTreeBuilder] Move RenderBlock::takeChild mutation to a RenderTreeBuilder
     4        https://bugs.webkit.org/show_bug.cgi?id=182662
     5        <rdar://problem/37408571>
     6
     7        Reviewed by Simon Fraser.
     8
     9        No change in functionality.
     10
     11        * rendering/RenderBlock.cpp:
     12        (WebCore::RenderBlock::takeChild):
     13        (WebCore::canDropAnonymousBlock): Deleted.
     14        (WebCore::canMergeContiguousAnonymousBlocks): Deleted.
     15        * rendering/RenderBlock.h:
     16        (WebCore::RenderBlock::moveAllChildrenIncludingFloatsTo):
     17        * rendering/RenderBlockFlow.h:
     18        * rendering/updating/RenderTreeBuilder.cpp:
     19        (WebCore::RenderTreeBuilder::takenChildFromRenderBlock):
     20        * rendering/updating/RenderTreeBuilder.h:
     21        * rendering/updating/RenderTreeBuilderBlock.cpp:
     22        (WebCore::canDropAnonymousBlock):
     23        (WebCore::canMergeContiguousAnonymousBlocks):
     24        (WebCore::RenderTreeBuilder::Block::takeChild):
     25        * rendering/updating/RenderTreeBuilderBlock.h:
     26
    1272018-02-08  Ryosuke Niwa  <rniwa@webkit.org>
    228
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r228337 r228365  
    483483}
    484484
    485 static bool canDropAnonymousBlock(const RenderBlock& anonymousBlock)
    486 {
    487     if (anonymousBlock.beingDestroyed() || anonymousBlock.continuation())
    488         return false;
    489     if (anonymousBlock.isRubyRun() || anonymousBlock.isRubyBase())
    490         return false;
    491     return true;
    492 }
    493 
    494 static bool canMergeContiguousAnonymousBlocks(RenderObject& oldChild, RenderObject* previous, RenderObject* next)
    495 {
    496     ASSERT(!oldChild.renderTreeBeingDestroyed());
    497 
    498     if (oldChild.isInline())
    499         return false;
    500 
    501     if (is<RenderBoxModelObject>(oldChild) && downcast<RenderBoxModelObject>(oldChild).continuation())
    502         return false;
    503 
    504     if (previous) {
    505         if (!previous->isAnonymousBlock())
    506             return false;
    507         RenderBlock& previousAnonymousBlock = downcast<RenderBlock>(*previous);
    508         if (!canDropAnonymousBlock(previousAnonymousBlock))
    509             return false;
    510     }
    511     if (next) {
    512         if (!next->isAnonymousBlock())
    513             return false;
    514         RenderBlock& nextAnonymousBlock = downcast<RenderBlock>(*next);
    515         if (!canDropAnonymousBlock(nextAnonymousBlock))
    516             return false;
    517     }
    518     return true;
    519 }
    520 
    521485void RenderBlock::dropAnonymousBoxChild(RenderTreeBuilder& builder, RenderBlock& child)
    522486{
     
    533497RenderPtr<RenderObject> RenderBlock::takeChild(RenderTreeBuilder& builder, RenderObject& oldChild)
    534498{
    535     // No need to waste time in merging or removing empty anonymous blocks.
    536     // We can just bail out if our document is getting destroyed.
    537     if (renderTreeBeingDestroyed())
    538         return RenderBox::takeChild(builder, oldChild);
    539 
    540     // If this child is a block, and if our previous and next siblings are both anonymous blocks
    541     // with inline content, then we can fold the inline content back together.
    542     RenderObject* prev = oldChild.previousSibling();
    543     RenderObject* next = oldChild.nextSibling();
    544     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
    545     if (canMergeAnonymousBlocks && prev && next) {
    546         prev->setNeedsLayoutAndPrefWidthsRecalc();
    547         RenderBlock& nextBlock = downcast<RenderBlock>(*next);
    548         RenderBlock& prevBlock = downcast<RenderBlock>(*prev);
    549        
    550         if (prev->childrenInline() != next->childrenInline()) {
    551             RenderBlock& inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
    552             RenderBlock& blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
    553            
    554             // Place the inline children block inside of the block children block instead of deleting it.
    555             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
    556             // to clear out inherited column properties by just making a new style, and to also clear the
    557             // column span flag if it is set.
    558             ASSERT(!inlineChildrenBlock.continuation());
    559             // Cache this value as it might get changed in setStyle() call.
    560             inlineChildrenBlock.setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
    561             auto blockToMove = takeChildInternal(inlineChildrenBlock);
    562            
    563             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
    564             RenderObject* beforeChild = prev == &inlineChildrenBlock ? blockChildrenBlock.firstChild() : nullptr;
    565             blockChildrenBlock.insertChildInternal(WTFMove(blockToMove), beforeChild);
    566             next->setNeedsLayoutAndPrefWidthsRecalc();
    567            
    568             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
    569             // of "this". we null out prev or next so that is not used later in the function.
    570             if (&inlineChildrenBlock == &prevBlock)
    571                 prev = nullptr;
    572             else
    573                 next = nullptr;
    574         } else {
    575             // Take all the children out of the |next| block and put them in
    576             // the |prev| block.
    577             nextBlock.moveAllChildrenIncludingFloatsTo(builder, prevBlock, RenderBoxModelObject::NormalizeAfterInsertion::No);
    578            
    579             // Delete the now-empty block's lines and nuke it.
    580             nextBlock.deleteLines();
    581             nextBlock.removeFromParentAndDestroy(builder);
    582             next = nullptr;
    583         }
    584     }
    585 
    586     invalidateLineLayoutPath();
    587 
    588     auto takenChild = RenderBox::takeChild(builder, oldChild);
    589 
    590     RenderObject* child = prev ? prev : next;
    591     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canDropAnonymousBlockChild()) {
    592         // The removal has knocked us down to containing only a single anonymous
    593         // box. We can pull the content right back up into our box.
    594         dropAnonymousBoxChild(builder, downcast<RenderBlock>(*child));
    595     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canDropAnonymousBlockChild()) {
    596         // It's possible that the removal has knocked us down to a single anonymous
    597         // block with floating siblings.
    598         RenderBlock& anonBlock = downcast<RenderBlock>((prev && prev->isAnonymousBlock()) ? *prev : *next);
    599         if (canDropAnonymousBlock(anonBlock)) {
    600             bool dropAnonymousBlock = true;
    601             for (auto& sibling : childrenOfType<RenderObject>(*this)) {
    602                 if (&sibling == &anonBlock)
    603                     continue;
    604                 if (!sibling.isFloating()) {
    605                     dropAnonymousBlock = false;
    606                     break;
    607                 }
    608             }
    609             if (dropAnonymousBlock)
    610                 dropAnonymousBoxChild(builder, anonBlock);
    611         }
    612     }
    613 
    614     if (!firstChild()) {
    615         // If this was our last child be sure to clear out our line boxes.
    616         if (childrenInline())
    617             deleteLines();
    618     }
    619     return takenChild;
     499    return builder.takeChildFromRenderBlock(*this, oldChild);
    620500}
    621501
  • trunk/Source/WebCore/rendering/RenderBlock.h

    r228337 r228365  
    398398    void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) override;
    399399    bool isInlineBlockOrInlineTable() const final { return isInline() && isReplaced(); }
     400    // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     401    virtual void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder& builder, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion normalizeAfterInsertion) { moveAllChildrenTo(builder, &toBlock, normalizeAfterInsertion); }
    400402
    401403protected:
     
    435437    const char* renderName() const override;
    436438
    437     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
    438     virtual void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder& builder, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion normalizeAfterInsertion) { moveAllChildrenTo(builder, &toBlock, normalizeAfterInsertion); }
    439 
    440439    bool isSelfCollapsingBlock() const override;
    441440    virtual bool childrenPreventSelfCollapsing() const;
  • trunk/Source/WebCore/rendering/RenderBlockFlow.h

    r228337 r228365  
    465465    // the flow thread child.
    466466    void layoutExcludedChildren(bool relayoutChildren) override;
    467    
     467    void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder&, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion) override;
     468
    468469private:
    469470    bool recomputeLogicalWidthAndColumnWidth();
     
    477478    void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) override;
    478479
    479     void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder&, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion) override;
    480480    void repaintOverhangingFloats(bool paintAllDescendants) final;
    481481    void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) override;
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp

    r228345 r228365  
    486486}
    487487
     488RenderPtr<RenderObject> RenderTreeBuilder::takeChildFromRenderBlock(RenderBlock& parent, RenderObject& oldChild)
     489{
     490    return blockBuilder().takeChild(parent, oldChild);
     491}
     492
    488493void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer)
    489494{
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h

    r228345 r228365  
    7777    RenderPtr<RenderObject> takeChildFromRenderRubyAsBlock(RenderRubyAsBlock& parent, RenderObject& child);
    7878    RenderPtr<RenderObject> takeChildFromRenderRubyRun(RenderRubyRun& parent, RenderObject& child);
     79    RenderPtr<RenderObject> takeChildFromRenderBlock(RenderBlock& parent, RenderObject& oldChild);
    7980
    8081    bool childRequiresTable(const RenderElement& parent, const RenderObject& child);
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp

    r228224 r228365  
    3636namespace WebCore {
    3737
     38static bool canDropAnonymousBlock(const RenderBlock& anonymousBlock)
     39{
     40    if (anonymousBlock.beingDestroyed() || anonymousBlock.continuation())
     41        return false;
     42    if (anonymousBlock.isRubyRun() || anonymousBlock.isRubyBase())
     43        return false;
     44    return true;
     45}
     46
     47static bool canMergeContiguousAnonymousBlocks(RenderObject& oldChild, RenderObject* previous, RenderObject* next)
     48{
     49    ASSERT(!oldChild.renderTreeBeingDestroyed());
     50
     51    if (oldChild.isInline())
     52        return false;
     53
     54    if (is<RenderBoxModelObject>(oldChild) && downcast<RenderBoxModelObject>(oldChild).continuation())
     55        return false;
     56
     57    if (previous) {
     58        if (!previous->isAnonymousBlock())
     59            return false;
     60        RenderBlock& previousAnonymousBlock = downcast<RenderBlock>(*previous);
     61        if (!canDropAnonymousBlock(previousAnonymousBlock))
     62            return false;
     63    }
     64    if (next) {
     65        if (!next->isAnonymousBlock())
     66            return false;
     67        RenderBlock& nextAnonymousBlock = downcast<RenderBlock>(*next);
     68        if (!canDropAnonymousBlock(nextAnonymousBlock))
     69            return false;
     70    }
     71    return true;
     72}
     73
    3874static RenderBlock* continuationBefore(RenderBlock& parent, RenderObject* beforeChild)
    3975{
     
    229265}
    230266
    231 }
     267RenderPtr<RenderObject> RenderTreeBuilder::Block::takeChild(RenderBlock& parent, RenderObject& oldChild)
     268{
     269    // No need to waste time in merging or removing empty anonymous blocks.
     270    // We can just bail out if our document is getting destroyed.
     271    if (parent.renderTreeBeingDestroyed())
     272        return parent.RenderBox::takeChild(m_builder, oldChild);
     273
     274    // If this child is a block, and if our previous and next siblings are both anonymous blocks
     275    // with inline content, then we can fold the inline content back together.
     276    RenderObject* prev = oldChild.previousSibling();
     277    RenderObject* next = oldChild.nextSibling();
     278    bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
     279    if (canMergeAnonymousBlocks && prev && next) {
     280        prev->setNeedsLayoutAndPrefWidthsRecalc();
     281        RenderBlock& nextBlock = downcast<RenderBlock>(*next);
     282        RenderBlock& prevBlock = downcast<RenderBlock>(*prev);
     283
     284        if (prev->childrenInline() != next->childrenInline()) {
     285            RenderBlock& inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
     286            RenderBlock& blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
     287
     288            // Place the inline children block inside of the block children block instead of deleting it.
     289            // In order to reuse it, we have to reset it to just be a generic anonymous block. Make sure
     290            // to clear out inherited column properties by just making a new style, and to also clear the
     291            // column span flag if it is set.
     292            ASSERT(!inlineChildrenBlock.continuation());
     293            // Cache this value as it might get changed in setStyle() call.
     294            inlineChildrenBlock.setStyle(RenderStyle::createAnonymousStyleWithDisplay(parent.style(), BLOCK));
     295            auto blockToMove = parent.takeChildInternal(inlineChildrenBlock);
     296
     297            // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
     298            RenderObject* beforeChild = prev == &inlineChildrenBlock ? blockChildrenBlock.firstChild() : nullptr;
     299            blockChildrenBlock.insertChildInternal(WTFMove(blockToMove), beforeChild);
     300            next->setNeedsLayoutAndPrefWidthsRecalc();
     301
     302            // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
     303            // of "this". we null out prev or next so that is not used later in the function.
     304            if (&inlineChildrenBlock == &prevBlock)
     305                prev = nullptr;
     306            else
     307                next = nullptr;
     308        } else {
     309            // Take all the children out of the |next| block and put them in
     310            // the |prev| block.
     311            nextBlock.moveAllChildrenIncludingFloatsTo(m_builder, prevBlock, RenderBoxModelObject::NormalizeAfterInsertion::No);
     312
     313            // Delete the now-empty block's lines and nuke it.
     314            nextBlock.deleteLines();
     315            nextBlock.removeFromParentAndDestroy(m_builder);
     316            next = nullptr;
     317        }
     318    }
     319
     320    parent.invalidateLineLayoutPath();
     321
     322    auto takenChild = parent.RenderBox::takeChild(m_builder, oldChild);
     323
     324    RenderObject* child = prev ? prev : next;
     325    if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && parent.canDropAnonymousBlockChild()) {
     326        // The removal has knocked us down to containing only a single anonymous
     327        // box. We can pull the content right back up into our box.
     328        parent.dropAnonymousBoxChild(m_builder, downcast<RenderBlock>(*child));
     329    } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && parent.canDropAnonymousBlockChild()) {
     330        // It's possible that the removal has knocked us down to a single anonymous
     331        // block with floating siblings.
     332        RenderBlock& anonBlock = downcast<RenderBlock>((prev && prev->isAnonymousBlock()) ? *prev : *next);
     333        if (canDropAnonymousBlock(anonBlock)) {
     334            bool dropAnonymousBlock = true;
     335            for (auto& sibling : childrenOfType<RenderObject>(parent)) {
     336                if (&sibling == &anonBlock)
     337                    continue;
     338                if (!sibling.isFloating()) {
     339                    dropAnonymousBlock = false;
     340                    break;
     341                }
     342            }
     343            if (dropAnonymousBlock)
     344                parent.dropAnonymousBoxChild(m_builder, anonBlock);
     345        }
     346    }
     347
     348    if (!parent.firstChild()) {
     349        // If this was our last child be sure to clear out our line boxes.
     350        if (parent.childrenInline())
     351            parent.deleteLines();
     352    }
     353    return takenChild;
     354}
     355
     356}
  • trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.h

    r228224 r228365  
    3737    void insertChildIgnoringContinuation(RenderBlock& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild);
    3838
     39    RenderPtr<RenderObject> takeChild(RenderBlock& parent, RenderObject& oldChild);
     40
    3941    void childBecameNonInline(RenderBlock& parent, RenderElement& child);
    4042
Note: See TracChangeset for help on using the changeset viewer.