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 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 if (newChild->isInline()) { | 925 if (newChild->isInline()) { |
926 // No suitable existing anonymous box - create a new one. | 926 // No suitable existing anonymous box - create a new one. |
927 RenderBlock* newBox = createAnonymousBlock(); | 927 RenderBlock* newBox = createAnonymousBlock(); |
928 RenderBox::addChild(newBox, beforeChild); | 928 RenderBox::addChild(newBox, beforeChild); |
929 newBox->addChild(newChild); | 929 newBox->addChild(newChild); |
930 return; | 930 return; |
931 } | 931 } |
932 } | 932 } |
933 | 933 |
934 RenderBox::addChild(newChild, beforeChild); | 934 RenderBox::addChild(newChild, beforeChild); |
| 935 |
| 936 // Handle positioning of run-ins. |
| 937 if (newChild->isRunIn()) |
| 938 moveRunInUnderSiblingBlockIfNeeded(newChild); |
| 939 else if (RenderObject* prevSibling = newChild->previousSibling()) { |
| 940 if (prevSibling->isRunIn()) |
| 941 moveRunInUnderSiblingBlockIfNeeded(prevSibling); |
| 942 } |
935 | 943 |
936 if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRend
erBlock()) | 944 if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRend
erBlock()) |
937 toRenderBlock(parent())->removeLeftoverAnonymousBlock(this); | 945 toRenderBlock(parent())->removeLeftoverAnonymousBlock(this); |
938 // this object may be dead here | 946 // this object may be dead here |
939 } | 947 } |
940 | 948 |
941 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) | 949 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) |
942 { | 950 { |
943 if (continuation() && !isAnonymousBlock()) | 951 if (continuation() && !isAnonymousBlock()) |
944 addChildToContinuation(newChild, beforeChild); | 952 addChildToContinuation(newChild, beforeChild); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 // splitting them. | 1039 // splitting them. |
1032 ASSERT(isInlineBlockOrInlineTable() || !isInline()); | 1040 ASSERT(isInlineBlockOrInlineTable() || !isInline()); |
1033 ASSERT(!insertionPoint || insertionPoint->parent() == this); | 1041 ASSERT(!insertionPoint || insertionPoint->parent() == this); |
1034 | 1042 |
1035 setChildrenInline(false); | 1043 setChildrenInline(false); |
1036 | 1044 |
1037 RenderObject *child = firstChild(); | 1045 RenderObject *child = firstChild(); |
1038 if (!child) | 1046 if (!child) |
1039 return; | 1047 return; |
1040 | 1048 |
| 1049 // Since we are going to have block children, we have to move |
| 1050 // back the run-in to its original place. |
| 1051 if (child->isRunIn()) { |
| 1052 moveRunInToOriginalPosition(child); |
| 1053 child = firstChild(); |
| 1054 } |
| 1055 |
1041 deleteLineBoxTree(); | 1056 deleteLineBoxTree(); |
1042 | 1057 |
1043 while (child) { | 1058 while (child) { |
1044 RenderObject *inlineRunStart, *inlineRunEnd; | 1059 RenderObject *inlineRunStart, *inlineRunEnd; |
1045 getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd); | 1060 getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd); |
1046 | 1061 |
1047 if (!inlineRunStart) | 1062 if (!inlineRunStart) |
1048 break; | 1063 break; |
1049 | 1064 |
1050 child = inlineRunEnd->nextSibling(); | 1065 child = inlineRunEnd->nextSibling(); |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? ZERO_LA
YOUT_UNIT : marginInfo.margin(); | 1732 LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? ZERO_LA
YOUT_UNIT : marginInfo.margin(); |
1718 setLogicalHeight(logicalHeight() + marginOffset); | 1733 setLogicalHeight(logicalHeight() + marginOffset); |
1719 positionNewFloats(); | 1734 positionNewFloats(); |
1720 setLogicalHeight(logicalHeight() - marginOffset); | 1735 setLogicalHeight(logicalHeight() - marginOffset); |
1721 } | 1736 } |
1722 | 1737 |
1723 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginI
nfo) | 1738 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginI
nfo) |
1724 { | 1739 { |
1725 // Handle in the given order | 1740 // Handle in the given order |
1726 return handlePositionedChild(child, marginInfo) | 1741 return handlePositionedChild(child, marginInfo) |
1727 || handleFloatingChild(child, marginInfo) | 1742 || handleFloatingChild(child, marginInfo); |
1728 || handleRunInChild(child); | |
1729 } | 1743 } |
1730 | 1744 |
1731 | 1745 |
1732 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marg
inInfo) | 1746 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marg
inInfo) |
1733 { | 1747 { |
1734 if (child->isPositioned()) { | 1748 if (child->isPositioned()) { |
1735 child->containingBlock()->insertPositionedObject(child); | 1749 child->containingBlock()->insertPositionedObject(child); |
1736 adjustPositionedBlock(child, marginInfo); | 1750 adjustPositionedBlock(child, marginInfo); |
1737 return true; | 1751 return true; |
1738 } | 1752 } |
1739 return false; | 1753 return false; |
1740 } | 1754 } |
1741 | 1755 |
1742 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& margin
Info) | 1756 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& margin
Info) |
1743 { | 1757 { |
1744 if (child->isFloating()) { | 1758 if (child->isFloating()) { |
1745 insertFloatingObject(child); | 1759 insertFloatingObject(child); |
1746 adjustFloatingBlock(marginInfo); | 1760 adjustFloatingBlock(marginInfo); |
1747 return true; | 1761 return true; |
1748 } | 1762 } |
1749 return false; | 1763 return false; |
1750 } | 1764 } |
1751 | 1765 |
1752 bool RenderBlock::handleRunInChild(RenderBox* child) | 1766 static void destroyRunIn(RenderBoxModelObject* runIn) |
1753 { | 1767 { |
1754 // See if we have a run-in element with inline children. If the | 1768 ASSERT(runIn->isRunIn()); |
1755 // children aren't inline, then just treat the run-in as a normal | 1769 ASSERT(!runIn->firstChild()); |
1756 // block. | 1770 |
1757 if (!child->isRunIn() || !child->childrenInline()) | 1771 // If it is a block run-in, delete its line box tree as well. This is needed
as our |
1758 return false; | 1772 // children got moved and our line box tree is no longer valid. |
| 1773 if (runIn->isRenderBlock()) |
| 1774 toRenderBlock(runIn)->deleteLineBoxTree(); |
| 1775 runIn->destroy(); |
| 1776 } |
| 1777 |
| 1778 RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject*
runIn) |
| 1779 { |
| 1780 ASSERT(runIn->isRunIn()); |
| 1781 |
| 1782 // First we destroy any :before/:after content. It will be regenerated by th
e new run-in. |
| 1783 // Exception is if the run-in itself is generated. |
| 1784 if (runIn->style()->styleType() != BEFORE && runIn->style()->styleType() !=
AFTER) { |
| 1785 RenderObject* generatedContent; |
| 1786 if (runIn->getCachedPseudoStyle(BEFORE) && (generatedContent = runIn->be
forePseudoElementRenderer())) |
| 1787 generatedContent->destroy(); |
| 1788 if (runIn->getCachedPseudoStyle(AFTER) && (generatedContent = runIn->aft
erPseudoElementRenderer())) |
| 1789 generatedContent->destroy(); |
| 1790 } |
| 1791 |
| 1792 bool newRunInShouldBeBlock = !runIn->isRenderBlock(); |
| 1793 Node* runInNode = runIn->node(); |
| 1794 RenderBoxModelObject* newRunIn = 0; |
| 1795 if (newRunInShouldBeBlock) |
| 1796 newRunIn = new (renderArena()) RenderBlock(runInNode ? runInNode : docum
ent()); |
| 1797 else |
| 1798 newRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : docu
ment()); |
| 1799 newRunIn->setStyle(runIn->style()); |
| 1800 |
| 1801 runIn->moveAllChildrenTo(newRunIn, true); |
| 1802 |
| 1803 // If the run-in had an element, we need to set the new renderer. |
| 1804 if (runInNode) |
| 1805 runInNode->setRenderer(newRunIn); |
| 1806 |
| 1807 return newRunIn; |
| 1808 } |
| 1809 |
| 1810 void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn) |
| 1811 { |
| 1812 ASSERT(runIn->isRunIn()); |
| 1813 |
| 1814 // See if we have inline children. If the children aren't inline, |
| 1815 // then just treat the run-in as a normal block. |
| 1816 if (!runIn->childrenInline()) |
| 1817 return; |
1759 | 1818 |
1760 // FIXME: We don't handle non-block elements with run-in for now. | 1819 // FIXME: We don't handle non-block elements with run-in for now. |
1761 if (!child->isRenderBlock()) | 1820 if (!runIn->isRenderBlock()) |
1762 return false; | 1821 return; |
1763 | 1822 |
1764 // Run-in child shouldn't intrude into the sibling block if it is part of a | 1823 // We shouldn't run in into the sibling block if we are part of a |
1765 // continuation chain. In that case, treat it as a normal block. | 1824 // continuation chain. In that case, treat it as a normal block. |
1766 if (child->isElementContinuation() || child->virtualContinuation()) | 1825 if (runIn->isElementContinuation() || runIn->virtualContinuation()) |
1767 return false; | 1826 return; |
1768 | 1827 |
1769 // Check if this node is allowed to run-in. E.g. <select> expects its render
er to | 1828 // Check if this node is allowed to run-in. E.g. <select> expects its render
er to |
1770 // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline
run-in. | 1829 // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline
run-in. |
1771 Node* runInNode = child->node(); | 1830 Node* runInNode = runIn->node(); |
1772 if (runInNode && runInNode->hasTagName(selectTag)) | 1831 if (runInNode && runInNode->hasTagName(selectTag)) |
1773 return false; | 1832 return; |
1774 | 1833 |
1775 RenderBlock* blockRunIn = toRenderBlock(child); | 1834 RenderObject* curr = runIn->nextSibling(); |
1776 RenderObject* curr = blockRunIn->nextSibling(); | 1835 if (!curr || !curr->isRenderBlock() || !curr->childrenInline()) |
1777 if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRu
nIn() || curr->isAnonymous() || curr->isFloatingOrPositioned()) | 1836 return; |
1778 return false; | |
1779 | 1837 |
1780 RenderBlock* currBlock = toRenderBlock(curr); | 1838 // Per CSS3, "A run-in cannot run in to a block that already starts with a |
| 1839 // run-in or that itself is a run-in". |
| 1840 if (curr->isRunIn() || (curr->firstChild() && curr->firstChild()->isRunIn())
) |
| 1841 return; |
1781 | 1842 |
1782 // First we destroy any :before/:after content. It will be regenerated by th
e new inline. | 1843 if (curr->isAnonymous() || curr->isFloatingOrPositioned()) |
1783 // Exception is if the run-in itself is generated. | 1844 return; |
1784 if (child->style()->styleType() != BEFORE && child->style()->styleType() !=
AFTER) { | |
1785 RenderObject* generatedContent; | |
1786 if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->be
forePseudoElementRenderer())) | |
1787 generatedContent->destroy(); | |
1788 if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->aft
erPseudoElementRenderer())) | |
1789 generatedContent->destroy(); | |
1790 } | |
1791 | 1845 |
1792 // Remove the old child. | 1846 RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn); |
1793 children()->removeChildNode(this, blockRunIn); | 1847 RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn); |
| 1848 destroyRunIn(oldRunIn); |
1794 | 1849 |
1795 // Create an inline. | 1850 // Now insert the new child under |curr| block. Use addChild instead of inse
rtChildNode |
1796 RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? run
InNode : document()); | 1851 // since it handles correct placement of the children, especially where we c
annot insert |
1797 inlineRunIn->setStyle(blockRunIn->style()); | 1852 // anything before the first child. e.g. details tag. See https://bugs.webki
t.org/show_bug.cgi?id=58228. |
| 1853 curr->addChild(newRunIn, curr->firstChild()); |
| 1854 } |
1798 | 1855 |
1799 // Move the nodes from the old child to the new child | 1856 void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn) |
1800 for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) { | 1857 { |
1801 RenderObject* nextSibling = runInChild->nextSibling(); | 1858 ASSERT(runIn->isRunIn()); |
1802 blockRunIn->children()->removeChildNode(blockRunIn, runInChild); | |
1803 inlineRunIn->addChild(runInChild); // Use addChild instead of appendChil
dNode since it handles correct placement of the children relative to :after-gene
rated content. | |
1804 runInChild = nextSibling; | |
1805 } | |
1806 | 1859 |
1807 // Now insert the new child under |currBlock|. Use addChild instead of inser
tChildNode since it handles correct placement of the children, esp where we cann
ot insert | 1860 // If we don't have a parent, there is nothing to move. This might |
1808 // anything before the first child. e.g. details tag. See https://bugs.webki
t.org/show_bug.cgi?id=58228. | 1861 // happen if |this| got detached from parent after |runIn| run into |this|. |
1809 currBlock->addChild(inlineRunIn, currBlock->firstChild()); | 1862 if (!parent()) |
1810 | 1863 return; |
1811 // If the run-in had an element, we need to set the new renderer. | |
1812 if (runInNode) | |
1813 runInNode->setRenderer(inlineRunIn); | |
1814 | 1864 |
1815 // Destroy the block run-in, which includes deleting its line box tree. | 1865 // An intruded run-in needs to be an inline. |
1816 blockRunIn->deleteLineBoxTree(); | 1866 if (!runIn->isRenderInline()) |
1817 blockRunIn->destroy(); | 1867 return; |
1818 | 1868 |
1819 // The block acts like an inline, so just null out its | 1869 RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn); |
1820 // position. | 1870 RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn); |
1821 | 1871 destroyRunIn(oldRunIn); |
1822 return true; | 1872 |
| 1873 // Add the run-in block as our previous sibling. |
| 1874 parent()->addChild(newRunIn, this); |
1823 } | 1875 } |
1824 | 1876 |
1825 LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo
) | 1877 LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo
) |
1826 { | 1878 { |
1827 // Get the four margin values for the child and cache them. | 1879 // Get the four margin values for the child and cache them. |
1828 const MarginValues childMargins = marginValuesForChild(child); | 1880 const MarginValues childMargins = marginValuesForChild(child); |
1829 | 1881 |
1830 // Get our max pos and neg top margins. | 1882 // Get our max pos and neg top margins. |
1831 LayoutUnit posTop = childMargins.positiveMarginBefore(); | 1883 LayoutUnit posTop = childMargins.positiveMarginBefore(); |
1832 LayoutUnit negTop = childMargins.negativeMarginBefore(); | 1884 LayoutUnit negTop = childMargins.negativeMarginBefore(); |
(...skipping 5467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7300 } | 7352 } |
7301 | 7353 |
7302 String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::Fl
oatingObject* floatingObject) | 7354 String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::Fl
oatingObject* floatingObject) |
7303 { | 7355 { |
7304 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->pi
xelSnappedX(), floatingObject->pixelSnappedY(), floatingObject->pixelSnappedMaxX
(), floatingObject->pixelSnappedMaxY()); | 7356 return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->pi
xelSnappedX(), floatingObject->pixelSnappedY(), floatingObject->pixelSnappedMaxX
(), floatingObject->pixelSnappedMaxY()); |
7305 } | 7357 } |
7306 | 7358 |
7307 #endif | 7359 #endif |
7308 | 7360 |
7309 } // namespace WebCore | 7361 } // namespace WebCore |
OLD | NEW |