| 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 |