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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 if (isPreviousBlockViable) | 474 if (isPreviousBlockViable) |
475 isPreviousBlockViable = !immediateChild->previousSibling(); | 475 isPreviousBlockViable = !immediateChild->previousSibling(); |
476 immediateChild = immediateChild->parent(); | 476 immediateChild = immediateChild->parent(); |
477 } | 477 } |
478 if (isPreviousBlockViable && immediateChild->previousSibling()) { | 478 if (isPreviousBlockViable && immediateChild->previousSibling()) { |
479 toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonym
ousColumnBlocks(newChild, 0); // Treat like an append. | 479 toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonym
ousColumnBlocks(newChild, 0); // Treat like an append. |
480 return; | 480 return; |
481 } | 481 } |
482 | 482 |
483 // Split our anonymous blocks. | 483 // Split our anonymous blocks. |
484 RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild); | 484 RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild); |
| 485 |
485 | 486 |
486 // Create a new anonymous box of the appropriate type. | 487 // Create a new anonymous box of the appropriate type. |
487 RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock
() : createAnonymousColumnsBlock(); | 488 RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock
() : createAnonymousColumnsBlock(); |
488 children()->insertChildNode(this, newBox, newBeforeChild); | 489 children()->insertChildNode(this, newBox, newBeforeChild); |
489 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); | 490 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0); |
490 return; | 491 return; |
491 } | 492 } |
492 | 493 |
493 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock) | 494 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock) |
494 { | 495 { |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 newBlockBox->addChild(newChild); | 675 newBlockBox->addChild(newChild); |
675 | 676 |
676 // Always just do a full layout in order to ensure that line boxes (especial
ly wrappers for images) | 677 // Always just do a full layout in order to ensure that line boxes (especial
ly wrappers for images) |
677 // get deleted properly. Because objects moves from the pre block into the
post block, we want to | 678 // get deleted properly. Because objects moves from the pre block into the
post block, we want to |
678 // make new line boxes instead of leaving the old line boxes around. | 679 // make new line boxes instead of leaving the old line boxes around. |
679 pre->setNeedsLayoutAndPrefWidthsRecalc(); | 680 pre->setNeedsLayoutAndPrefWidthsRecalc(); |
680 block->setNeedsLayoutAndPrefWidthsRecalc(); | 681 block->setNeedsLayoutAndPrefWidthsRecalc(); |
681 post->setNeedsLayoutAndPrefWidthsRecalc(); | 682 post->setNeedsLayoutAndPrefWidthsRecalc(); |
682 } | 683 } |
683 | 684 |
684 RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeC
hild) | |
685 { | |
686 if (beforeChild->isTablePart()) | |
687 beforeChild = splitTablePartsAroundChild(beforeChild); | |
688 | |
689 while (beforeChild->parent() != this) { | |
690 RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent()); | |
691 if (blockToSplit->firstChild() != beforeChild) { | |
692 // We have to split the parentBlock into two blocks. | |
693 RenderBlock* post = toRenderBlock(blockToSplit->createAnonymousBoxWi
thSameTypeAs(this)); | |
694 post->setChildrenInline(blockToSplit->childrenInline()); | |
695 RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent()); | |
696 parentBlock->children()->insertChildNode(parentBlock, post, blockToS
plit->nextSibling()); | |
697 blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->has
Layer()); | |
698 post->setNeedsLayoutAndPrefWidthsRecalc(); | |
699 blockToSplit->setNeedsLayoutAndPrefWidthsRecalc(); | |
700 beforeChild = post; | |
701 } else | |
702 beforeChild = blockToSplit; | |
703 } | |
704 return beforeChild; | |
705 } | |
706 | |
707 static void markTableForSectionAndCellRecalculation(RenderObject* child) | |
708 { | |
709 RenderObject* curr = child; | |
710 while (!curr->isTable()) { | |
711 if (curr->isTableSection()) | |
712 toRenderTableSection(curr)->setNeedsCellRecalc(); | |
713 curr = curr->parent(); | |
714 } | |
715 | |
716 RenderTable* table = toRenderTable(curr); | |
717 table->setNeedsSectionRecalc(); | |
718 table->setNeedsLayoutAndPrefWidthsRecalc(); | |
719 } | |
720 | |
721 static void moveAllTableChildrenTo(RenderObject* fromTablePart, RenderTable* toT
able, RenderObject* startChild) | |
722 { | |
723 for (RenderObject* curr = startChild; curr;) { | |
724 // Need to store next sibling as we won't have access to it | |
725 // after we are removed from table. | |
726 RenderObject* next = curr->nextSibling(); | |
727 fromTablePart->removeChild(curr); | |
728 toTable->addChild(curr); | |
729 if (curr->isTableSection()) | |
730 toRenderTableSection(curr)->setNeedsCellRecalc(); | |
731 curr->setNeedsLayoutAndPrefWidthsRecalc(); | |
732 curr = next; | |
733 } | |
734 | |
735 // This marks fromTable for section and cell recalculation. | |
736 markTableForSectionAndCellRecalculation(fromTablePart); | |
737 | |
738 // startChild is now part of toTable. This marks toTable for section and cel
l recalculation. | |
739 markTableForSectionAndCellRecalculation(startChild); | |
740 } | |
741 | |
742 RenderObject* RenderBlock::splitTablePartsAroundChild(RenderObject* beforeChild) | |
743 { | |
744 ASSERT(beforeChild->isTablePart()); | |
745 | |
746 while (beforeChild->parent() != this) { | |
747 RenderObject* tablePartToSplit = beforeChild->parent(); | |
748 if (!tablePartToSplit->isTablePart() && !tablePartToSplit->isTable()) | |
749 break; | |
750 if (tablePartToSplit->firstChild() != beforeChild) { | |
751 // Get our table container. | |
752 RenderObject* curr = tablePartToSplit; | |
753 while (!curr->isTable()) | |
754 curr = curr->parent(); | |
755 RenderTable* table = toRenderTable(curr); | |
756 | |
757 // Create an anonymous table container next to our table container. | |
758 RenderBlock* parentBlock = toRenderBlock(table->parent()); | |
759 RenderTable* postTable = RenderTable::createAnonymousWithParentRende
rer(parentBlock); | |
760 parentBlock->children()->insertChildNode(parentBlock, postTable, tab
le->nextSibling()); | |
761 | |
762 // Move all the children from beforeChild to the newly created anony
mous table container. | |
763 moveAllTableChildrenTo(tablePartToSplit, postTable, beforeChild); | |
764 | |
765 beforeChild = postTable; | |
766 } else | |
767 beforeChild = tablePartToSplit; | |
768 } | |
769 return beforeChild; | |
770 } | |
771 | |
772 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
enderBlock* newBlockBox, RenderObject* newChild) | 685 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
enderBlock* newBlockBox, RenderObject* newChild) |
773 { | 686 { |
774 RenderBlock* pre = 0; | 687 RenderBlock* pre = 0; |
775 RenderBlock* post = 0; | 688 RenderBlock* post = 0; |
776 RenderBlock* block = this; // Eventually block will not just be |this|, but
will also be a block nested inside |this|. Assign to a variable | 689 RenderBlock* block = this; // Eventually block will not just be |this|, but
will also be a block nested inside |this|. Assign to a variable |
777 // so that we don't have to patch all of the rest
of the code later on. | 690 // so that we don't have to patch all of the rest
of the code later on. |
778 | 691 |
779 // Delete the block's line boxes before we do the split. | 692 // Delete the block's line boxes before we do the split. |
780 block->deleteLineBoxTree(); | 693 block->deleteLineBoxTree(); |
781 | 694 |
782 if (beforeChild && beforeChild->parent() != this) | 695 if (beforeChild && beforeChild->parent() != this) |
783 beforeChild = splitAnonymousBlocksAroundChild(beforeChild); | 696 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); |
784 | 697 |
785 if (beforeChild != firstChild()) { | 698 if (beforeChild != firstChild()) { |
786 pre = block->createAnonymousColumnsBlock(); | 699 pre = block->createAnonymousColumnsBlock(); |
787 pre->setChildrenInline(block->childrenInline()); | 700 pre->setChildrenInline(block->childrenInline()); |
788 } | 701 } |
789 | 702 |
790 if (beforeChild) { | 703 if (beforeChild) { |
791 post = block->createAnonymousColumnsBlock(); | 704 post = block->createAnonymousColumnsBlock(); |
792 post->setChildrenInline(block->childrenInline()); | 705 post->setChildrenInline(block->childrenInline()); |
793 } | 706 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 return; | 796 return; |
884 } | 797 } |
885 | 798 |
886 ASSERT(beforeChildAnonymousContainer->isTable()); | 799 ASSERT(beforeChildAnonymousContainer->isTable()); |
887 if (newChild->isTablePart()) { | 800 if (newChild->isTablePart()) { |
888 // Insert into the anonymous table. | 801 // Insert into the anonymous table. |
889 beforeChildAnonymousContainer->addChild(newChild, beforeChild); | 802 beforeChildAnonymousContainer->addChild(newChild, beforeChild); |
890 return; | 803 return; |
891 } | 804 } |
892 | 805 |
893 beforeChild = splitTablePartsAroundChild(beforeChild); | 806 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); |
894 | 807 |
895 ASSERT(beforeChild->parent() == this); | 808 ASSERT(beforeChild->parent() == this); |
896 if (beforeChild->parent() != this) { | 809 if (beforeChild->parent() != this) { |
897 // We should never reach here. If we do, we need to use the | 810 // We should never reach here. If we do, we need to use the |
898 // safe fallback to use the topmost beforeChild container. | 811 // safe fallback to use the topmost beforeChild container. |
899 beforeChild = beforeChildContainer; | 812 beforeChild = beforeChildContainer; |
900 } | 813 } |
901 } else { | 814 } else { |
902 // We will reach here when beforeChild is a run-in element. | 815 // We will reach here when beforeChild is a run-in element. |
903 // If run-in element precedes a block-level element, it becomes the | 816 // If run-in element precedes a block-level element, it becomes the |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 return new (renderArena()) RootInlineBox(this); | 982 return new (renderArena()) RootInlineBox(this); |
1070 } | 983 } |
1071 | 984 |
1072 RootInlineBox* RenderBlock::createAndAppendRootInlineBox() | 985 RootInlineBox* RenderBlock::createAndAppendRootInlineBox() |
1073 { | 986 { |
1074 RootInlineBox* rootBox = createRootInlineBox(); | 987 RootInlineBox* rootBox = createRootInlineBox(); |
1075 m_lineBoxes.appendLineBox(rootBox); | 988 m_lineBoxes.appendLineBox(rootBox); |
1076 return rootBox; | 989 return rootBox; |
1077 } | 990 } |
1078 | 991 |
1079 void RenderBlock::moveChildTo(RenderBlock* toBlock, RenderObject* child, RenderO
bject* beforeChild, bool fullRemoveInsert) | |
1080 { | |
1081 ASSERT(this == child->parent()); | |
1082 ASSERT(!beforeChild || toBlock == beforeChild->parent()); | |
1083 if (fullRemoveInsert) { | |
1084 // Takes care of adding the new child correctly if toBlock and fromBlock | |
1085 // have different kind of children (block vs inline). | |
1086 toBlock->addChildIgnoringContinuation(children()->removeChildNode(this,
child), beforeChild); | |
1087 } else | |
1088 toBlock->children()->insertChildNode(toBlock, children()->removeChildNod
e(this, child, false), beforeChild, false); | |
1089 } | |
1090 | |
1091 void RenderBlock::moveChildrenTo(RenderBlock* toBlock, RenderObject* startChild,
RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert) | |
1092 { | |
1093 ASSERT(!beforeChild || toBlock == beforeChild->parent()); | |
1094 | |
1095 for (RenderObject* child = startChild; child && child != endChild; ) { | |
1096 // Save our next sibling as moveChildTo will clear it. | |
1097 RenderObject* nextSibling = child->nextSibling(); | |
1098 moveChildTo(toBlock, child, beforeChild, fullRemoveInsert); | |
1099 child = nextSibling; | |
1100 } | |
1101 } | |
1102 | |
1103 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) | 992 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) |
1104 { | 993 { |
1105 // makeChildrenNonInline takes a block whose children are *all* inline and i
t | 994 // makeChildrenNonInline takes a block whose children are *all* inline and i
t |
1106 // makes sure that inline children are coalesced under anonymous | 995 // makes sure that inline children are coalesced under anonymous |
1107 // blocks. If |insertionPoint| is defined, then it represents the insertion
point for | 996 // blocks. If |insertionPoint| is defined, then it represents the insertion
point for |
1108 // the new block child that is causing us to have to wrap all the inlines.
This | 997 // the new block child that is causing us to have to wrap all the inlines.
This |
1109 // means that we cannot coalesce inlines before |insertionPoint| with inline
s following | 998 // means that we cannot coalesce inlines before |insertionPoint| with inline
s following |
1110 // |insertionPoint|, because the new child is going to be inserted in betwee
n the inlines, | 999 // |insertionPoint|, because the new child is going to be inserted in betwee
n the inlines, |
1111 // splitting them. | 1000 // splitting them. |
1112 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 1001 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
(...skipping 6327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7440 } | 7329 } |
7441 | 7330 |
7442 String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::Fl
oatingObject* floatingObject) | 7331 String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::Fl
oatingObject* floatingObject) |
7443 { | 7332 { |
7444 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->x(
), floatingObject->y(), floatingObject->maxX(), floatingObject->maxY()); | 7333 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->x(
), floatingObject->y(), floatingObject->maxX(), floatingObject->maxY()); |
7445 } | 7334 } |
7446 | 7335 |
7447 #endif | 7336 #endif |
7448 | 7337 |
7449 } // namespace WebCore | 7338 } // namespace WebCore |
OLD | NEW |