Changeset 228365 in webkit
- Timestamp:
- Feb 10, 2018 7:44:55 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r228352 r228365 1 2018-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 1 27 2018-02-08 Ryosuke Niwa <rniwa@webkit.org> 2 28 -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r228337 r228365 483 483 } 484 484 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 521 485 void RenderBlock::dropAnonymousBoxChild(RenderTreeBuilder& builder, RenderBlock& child) 522 486 { … … 533 497 RenderPtr<RenderObject> RenderBlock::takeChild(RenderTreeBuilder& builder, RenderObject& oldChild) 534 498 { 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); 620 500 } 621 501 -
trunk/Source/WebCore/rendering/RenderBlock.h
r228337 r228365 398 398 void addChildIgnoringContinuation(RenderTreeBuilder&, RenderPtr<RenderObject> newChild, RenderObject* beforeChild) override; 399 399 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); } 400 402 401 403 protected: … … 435 437 const char* renderName() const override; 436 438 437 // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow438 virtual void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder& builder, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion normalizeAfterInsertion) { moveAllChildrenTo(builder, &toBlock, normalizeAfterInsertion); }439 440 439 bool isSelfCollapsingBlock() const override; 441 440 virtual bool childrenPreventSelfCollapsing() const; -
trunk/Source/WebCore/rendering/RenderBlockFlow.h
r228337 r228365 465 465 // the flow thread child. 466 466 void layoutExcludedChildren(bool relayoutChildren) override; 467 467 void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder&, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion) override; 468 468 469 private: 469 470 bool recomputeLogicalWidthAndColumnWidth(); … … 477 478 void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) override; 478 479 479 void moveAllChildrenIncludingFloatsTo(RenderTreeBuilder&, RenderBlock& toBlock, RenderBoxModelObject::NormalizeAfterInsertion) override;480 480 void repaintOverhangingFloats(bool paintAllDescendants) final; 481 481 void clipOutFloatingObjects(RenderBlock&, const PaintInfo*, const LayoutPoint&, const LayoutSize&) override; -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp
r228345 r228365 486 486 } 487 487 488 RenderPtr<RenderObject> RenderTreeBuilder::takeChildFromRenderBlock(RenderBlock& parent, RenderObject& oldChild) 489 { 490 return blockBuilder().takeChild(parent, oldChild); 491 } 492 488 493 void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer) 489 494 { -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h
r228345 r228365 77 77 RenderPtr<RenderObject> takeChildFromRenderRubyAsBlock(RenderRubyAsBlock& parent, RenderObject& child); 78 78 RenderPtr<RenderObject> takeChildFromRenderRubyRun(RenderRubyRun& parent, RenderObject& child); 79 RenderPtr<RenderObject> takeChildFromRenderBlock(RenderBlock& parent, RenderObject& oldChild); 79 80 80 81 bool childRequiresTable(const RenderElement& parent, const RenderObject& child); -
trunk/Source/WebCore/rendering/updating/RenderTreeBuilderBlock.cpp
r228224 r228365 36 36 namespace WebCore { 37 37 38 static 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 47 static 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 38 74 static RenderBlock* continuationBefore(RenderBlock& parent, RenderObject* beforeChild) 39 75 { … … 229 265 } 230 266 231 } 267 RenderPtr<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 37 37 void insertChildIgnoringContinuation(RenderBlock& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild); 38 38 39 RenderPtr<RenderObject> takeChild(RenderBlock& parent, RenderObject& oldChild); 40 39 41 void childBecameNonInline(RenderBlock& parent, RenderElement& child); 40 42
Note: See TracChangeset
for help on using the changeset viewer.