| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 || oldStyle.paddingLeft() != newStyle.paddingLeft() | 244 || oldStyle.paddingLeft() != newStyle.paddingLeft() |
| 245 || oldStyle.paddingRight() != newStyle.paddingRight(); | 245 || oldStyle.paddingRight() != newStyle.paddingRight(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 return oldStyle.borderTopWidth() != newStyle.borderTopWidth() | 248 return oldStyle.borderTopWidth() != newStyle.borderTopWidth() |
| 249 || oldStyle.borderBottomWidth() != newStyle.borderBottomWidth() | 249 || oldStyle.borderBottomWidth() != newStyle.borderBottomWidth() |
| 250 || oldStyle.paddingTop() != newStyle.paddingTop() | 250 || oldStyle.paddingTop() != newStyle.paddingTop() |
| 251 || oldStyle.paddingBottom() != newStyle.paddingBottom(); | 251 || oldStyle.paddingBottom() != newStyle.paddingBottom(); |
| 252 } | 252 } |
| 253 | 253 |
| 254 static bool canMergeContiguousAnonymousBlocks(LayoutObject* prev, LayoutObject*
next) |
| 255 { |
| 256 if ((prev && (!prev->isAnonymousBlock() || toLayoutBlock(prev)->continuation
() || toLayoutBlock(prev)->beingDestroyed())) |
| 257 || (next && (!next->isAnonymousBlock() || toLayoutBlock(next)->continuat
ion() || toLayoutBlock(next)->beingDestroyed()))) |
| 258 return false; |
| 259 |
| 260 if ((prev && (prev->isRubyRun() || prev->isRubyBase())) |
| 261 || (next && (next->isRubyRun() || next->isRubyBase()))) |
| 262 return false; |
| 263 |
| 264 return true; |
| 265 } |
| 266 |
| 267 static bool mergeContiguousAnonymousBlocks(LayoutObject* prev, LayoutObject*& ne
xt) |
| 268 { |
| 269 if (!prev || !next || !canMergeContiguousAnonymousBlocks(prev, next)) |
| 270 return false; |
| 271 |
| 272 prev->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvali
dationReason::AnonymousBlockChange); |
| 273 LayoutBlockFlow* nextBlock = toLayoutBlockFlow(next); |
| 274 LayoutBlockFlow* prevBlock = toLayoutBlockFlow(prev); |
| 275 |
| 276 // If the inlineness of children of the two block don't match, we'd need spe
cial code here |
| 277 // (but there should be no need for it). |
| 278 ASSERT(nextBlock->childrenInline() == prevBlock->childrenInline()); |
| 279 // Take all the children out of the |next| block and put them in |
| 280 // the |prev| block. |
| 281 nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer()
|| prevBlock->hasLayer()); |
| 282 // Delete the now-empty block's lines and nuke it. |
| 283 nextBlock->deleteLineBoxTree(); |
| 284 nextBlock->destroy(); |
| 285 next = nullptr; |
| 286 return true; |
| 287 } |
| 288 |
| 254 static void addNextFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block) | 289 static void addNextFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block) |
| 255 { | 290 { |
| 256 if (!block->parent() || !block->parent()->isLayoutBlockFlow()) | 291 if (!block->parent() || !block->parent()->isLayoutBlockFlow()) |
| 257 return; | 292 return; |
| 258 if (block->beingDestroyed() || block->documentBeingDestroyed()) | 293 if (block->beingDestroyed() || block->documentBeingDestroyed()) |
| 259 return; | 294 return; |
| 260 | 295 |
| 261 LayoutObject* child = block->nextSibling(); | 296 LayoutObject* child = block->nextSibling(); |
| 262 while (child && child->isFloatingOrOutOfFlowPositioned()) { | 297 while (child && child->isFloatingOrOutOfFlowPositioned()) { |
| 263 LayoutObject* sibling = child->nextSibling(); | 298 LayoutObject* sibling = child->nextSibling(); |
| 264 toLayoutBlock(block->parent())->moveChildTo(block, child, nullptr, false
); | 299 toLayoutBlock(block->parent())->moveChildTo(block, child, nullptr, false
); |
| 265 child = sibling; | 300 child = sibling; |
| 266 } | 301 } |
| 302 |
| 303 LayoutObject* next = block->nextSibling(); |
| 304 mergeContiguousAnonymousBlocks(block, next); |
| 267 } | 305 } |
| 268 | 306 |
| 269 static void addPreviousFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block) | 307 static void addPreviousFloatingOrOutOfFlowSiblingsToBlock(LayoutBlock* block) |
| 270 { | 308 { |
| 271 if (!block->parent() || !block->parent()->isLayoutBlockFlow()) | 309 if (!block->parent() || !block->parent()->isLayoutBlockFlow()) |
| 272 return; | 310 return; |
| 273 if (block->beingDestroyed() || block->documentBeingDestroyed()) | 311 if (block->beingDestroyed() || block->documentBeingDestroyed()) |
| 274 return; | 312 return; |
| 275 | 313 |
| 276 LayoutObject* child = block->previousSibling(); | 314 LayoutObject* child = block->previousSibling(); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 if (child->parent()->isLayoutGrid()) | 651 if (child->parent()->isLayoutGrid()) |
| 614 toLayoutGrid(child->parent())->dirtyGrid(); | 652 toLayoutGrid(child->parent())->dirtyGrid(); |
| 615 | 653 |
| 616 // Now remove the leftover anonymous block from the tree, and destroy it. We
'll rip it out | 654 // Now remove the leftover anonymous block from the tree, and destroy it. We
'll rip it out |
| 617 // manually from the tree before destroying it, because we don't want to tri
gger any tree | 655 // manually from the tree before destroying it, because we don't want to tri
gger any tree |
| 618 // adjustments with regards to anonymous blocks (or any other kind of undesi
red chain-reaction). | 656 // adjustments with regards to anonymous blocks (or any other kind of undesi
red chain-reaction). |
| 619 children()->removeChildNode(this, child, false); | 657 children()->removeChildNode(this, child, false); |
| 620 child->destroy(); | 658 child->destroy(); |
| 621 } | 659 } |
| 622 | 660 |
| 623 static bool canMergeContiguousAnonymousBlocks(LayoutObject* oldChild, LayoutObje
ct* prev, LayoutObject* next) | |
| 624 { | |
| 625 if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->
virtualContinuation()) | |
| 626 return false; | |
| 627 | |
| 628 if ((prev && (!prev->isAnonymousBlock() || toLayoutBlock(prev)->continuation
() || toLayoutBlock(prev)->beingDestroyed())) | |
| 629 || (next && (!next->isAnonymousBlock() || toLayoutBlock(next)->continuat
ion() || toLayoutBlock(next)->beingDestroyed()))) | |
| 630 return false; | |
| 631 | |
| 632 if ((prev && (prev->isRubyRun() || prev->isRubyBase())) | |
| 633 || (next && (next->isRubyRun() || next->isRubyBase()))) | |
| 634 return false; | |
| 635 | |
| 636 return true; | |
| 637 } | |
| 638 | |
| 639 void LayoutBlock::makeChildrenInlineIfPossible() | 661 void LayoutBlock::makeChildrenInlineIfPossible() |
| 640 { | 662 { |
| 641 ASSERT(isLayoutBlockFlow()); | 663 ASSERT(isLayoutBlockFlow()); |
| 642 // Collapsing away anonymous wrappers isn't relevant for the children of ano
nymous blocks, unless they are ruby bases. | 664 // Collapsing away anonymous wrappers isn't relevant for the children of ano
nymous blocks, unless they are ruby bases. |
| 643 if (isAnonymousBlock() && !isRubyBase()) | 665 if (isAnonymousBlock() && !isRubyBase()) |
| 644 return; | 666 return; |
| 645 | 667 |
| 646 Vector<LayoutBlock*, 3> blocksToRemove; | 668 Vector<LayoutBlock*, 3> blocksToRemove; |
| 647 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { | 669 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
| 648 if (child->isFloating()) | 670 if (child->isFloating()) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 675 // now - they will be rebuilt at layout. | 697 // now - they will be rebuilt at layout. |
| 676 toLayoutBlockFlow(this)->removeFloatingObjectsFromDescendants(); | 698 toLayoutBlockFlow(this)->removeFloatingObjectsFromDescendants(); |
| 677 | 699 |
| 678 for (size_t i = 0; i < blocksToRemove.size(); i++) | 700 for (size_t i = 0; i < blocksToRemove.size(); i++) |
| 679 collapseAnonymousBlockChild(this, blocksToRemove[i]); | 701 collapseAnonymousBlockChild(this, blocksToRemove[i]); |
| 680 setChildrenInline(true); | 702 setChildrenInline(true); |
| 681 } | 703 } |
| 682 | 704 |
| 683 void LayoutBlock::collapseAnonymousBlockChild(LayoutBlock* parent, LayoutBlock*
child) | 705 void LayoutBlock::collapseAnonymousBlockChild(LayoutBlock* parent, LayoutBlock*
child) |
| 684 { | 706 { |
| 707 if (!parent->canCollapseAnonymousBlockChild()) |
| 708 return; |
| 685 // It's possible that this block's destruction may have been triggered by th
e | 709 // It's possible that this block's destruction may have been triggered by th
e |
| 686 // child's removal. Just bail if the anonymous child block is already being | 710 // child's removal. Just bail if the anonymous child block is already being |
| 687 // destroyed. See crbug.com/282088 | 711 // destroyed. See crbug.com/282088 |
| 688 if (child->beingDestroyed()) | 712 if (child->beingDestroyed()) |
| 689 return; | 713 return; |
| 690 if (child->continuation()) | 714 if (child->continuation()) |
| 691 return; | 715 return; |
| 692 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by desi
gn, so we don't remove them. | 716 // Ruby elements use anonymous wrappers for ruby runs and ruby bases by desi
gn, so we don't remove them. |
| 693 if (child->isRubyRun() || child->isRubyBase()) | 717 if (child->isRubyRun() || child->isRubyBase()) |
| 694 return; | 718 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 708 if (documentBeingDestroyed()) { | 732 if (documentBeingDestroyed()) { |
| 709 LayoutBox::removeChild(oldChild); | 733 LayoutBox::removeChild(oldChild); |
| 710 return; | 734 return; |
| 711 } | 735 } |
| 712 | 736 |
| 713 // If this child is a block, and if our previous and next siblings are | 737 // If this child is a block, and if our previous and next siblings are |
| 714 // both anonymous blocks with inline content, then we can go ahead and | 738 // both anonymous blocks with inline content, then we can go ahead and |
| 715 // fold the inline content back together. | 739 // fold the inline content back together. |
| 716 LayoutObject* prev = oldChild->previousSibling(); | 740 LayoutObject* prev = oldChild->previousSibling(); |
| 717 LayoutObject* next = oldChild->nextSibling(); | 741 LayoutObject* next = oldChild->nextSibling(); |
| 718 bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, p
rev, next); | 742 bool mergedAnonymousBlocks = !oldChild->documentBeingDestroyed() && !oldChil
d->isInline() && !oldChild->virtualContinuation() && mergeContiguousAnonymousBlo
cks(prev, next); |
| 719 if (canMergeAnonymousBlocks && prev && next) { | |
| 720 prev->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutIn
validationReason::AnonymousBlockChange); | |
| 721 LayoutBlockFlow* nextBlock = toLayoutBlockFlow(next); | |
| 722 LayoutBlockFlow* prevBlock = toLayoutBlockFlow(prev); | |
| 723 | |
| 724 // If the inlineness of children of the two block don't match, we'd need
special code here | |
| 725 // (but there should be no need for it). | |
| 726 ASSERT(nextBlock->childrenInline() == prevBlock->childrenInline()); | |
| 727 | |
| 728 // Take all the children out of the |next| block and put them in | |
| 729 // the |prev| block. | |
| 730 nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLay
er() || prevBlock->hasLayer()); | |
| 731 | |
| 732 // Delete the now-empty block's lines and nuke it. | |
| 733 nextBlock->deleteLineBoxTree(); | |
| 734 nextBlock->destroy(); | |
| 735 next = nullptr; | |
| 736 } | |
| 737 | 743 |
| 738 LayoutBox::removeChild(oldChild); | 744 LayoutBox::removeChild(oldChild); |
| 739 | 745 |
| 740 LayoutObject* child = prev ? prev : next; | 746 LayoutObject* child = prev ? prev : next; |
| 741 if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child-
>nextSibling() && canCollapseAnonymousBlockChild()) { | 747 if (mergedAnonymousBlocks && child && !child->previousSibling() && !child->n
extSibling()) { |
| 742 // The removal has knocked us down to containing only a single anonymous | 748 // The removal has knocked us down to containing only a single anonymous |
| 743 // box. We can go ahead and pull the content right back up into our | 749 // box. We can go ahead and pull the content right back up into our |
| 744 // box. | 750 // box. |
| 745 collapseAnonymousBlockChild(this, toLayoutBlock(child)); | 751 collapseAnonymousBlockChild(this, toLayoutBlock(child)); |
| 746 } | 752 } |
| 747 | 753 |
| 748 if (!firstChild()) { | 754 if (!firstChild()) { |
| 749 // If this was our last child be sure to clear out our line boxes. | 755 // If this was our last child be sure to clear out our line boxes. |
| 750 if (childrenInline()) | 756 if (childrenInline()) |
| 751 deleteLineBoxTree(); | 757 deleteLineBoxTree(); |
| (...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2855 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout
Object* obj) const | 2861 void LayoutBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m
arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Layout
Object* obj) const |
| 2856 { | 2862 { |
| 2857 showLayoutObject(); | 2863 showLayoutObject(); |
| 2858 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) | 2864 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot
Box()) |
| 2859 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); | 2865 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa
bel2, obj, 1); |
| 2860 } | 2866 } |
| 2861 | 2867 |
| 2862 #endif | 2868 #endif |
| 2863 | 2869 |
| 2864 } // namespace blink | 2870 } // namespace blink |
| OLD | NEW |