summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderBlock.cpp')
-rwxr-xr-xSource/WebCore/rendering/RenderBlock.cpp216
1 files changed, 81 insertions, 135 deletions
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index c3017a425..15867e1c6 100755
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -58,6 +58,7 @@
#include "RenderView.h"
#include "Settings.h"
#include "SVGTextRunRenderingContext.h"
+#include "ShadowRoot.h"
#include "TransformState.h"
#include <wtf/StdLibExtras.h>
@@ -852,6 +853,10 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
}
}
+ // Nothing goes before the intruded run-in.
+ if (beforeChild && beforeChild->isRunIn() && runInIsPlacedIntoSiblingBlock(beforeChild))
+ beforeChild = beforeChild->nextSibling();
+
// Check for a spanning element in columns.
RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
if (columnsBlockAncestor) {
@@ -933,13 +938,8 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
RenderBox::addChild(newChild, beforeChild);
- // Handle positioning of run-ins.
- if (newChild->isRunIn())
- moveRunInUnderSiblingBlockIfNeeded(newChild);
- else if (RenderObject* prevSibling = newChild->previousSibling()) {
- if (prevSibling->isRunIn())
- moveRunInUnderSiblingBlockIfNeeded(prevSibling);
- }
+ // Handle placement of run-ins.
+ placeRunInIfNeeded(newChild, DoNotPlaceGeneratedRunIn);
if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
@@ -1046,6 +1046,8 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
if (!child)
return;
+ deleteLineBoxTree();
+
// Since we are going to have block children, we have to move
// back the run-in to its original place.
if (child->isRunIn()) {
@@ -1053,8 +1055,6 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
child = firstChild();
}
- deleteLineBoxTree();
-
while (child) {
RenderObject *inlineRunStart, *inlineRunEnd;
getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
@@ -1768,13 +1768,28 @@ static void destroyRunIn(RenderBoxModelObject* runIn)
ASSERT(runIn->isRunIn());
ASSERT(!runIn->firstChild());
- // If it is a block run-in, delete its line box tree as well. This is needed as our
- // children got moved and our line box tree is no longer valid.
+ // Delete our line box tree. This is needed as our children got moved
+ // and our line box tree is no longer valid.
if (runIn->isRenderBlock())
toRenderBlock(runIn)->deleteLineBoxTree();
+ else if (runIn->isRenderInline())
+ toRenderInline(runIn)->deleteLineBoxTree();
+ else
+ ASSERT_NOT_REACHED();
+
runIn->destroy();
}
+void RenderBlock::placeRunInIfNeeded(RenderObject* newChild, PlaceGeneratedRunInFlag flag)
+{
+ if (newChild->isRunIn() && (flag == PlaceGeneratedRunIn || !newChild->isBeforeOrAfterContent()))
+ moveRunInUnderSiblingBlockIfNeeded(newChild);
+ else if (RenderObject* prevSibling = newChild->previousSibling()) {
+ if (prevSibling->isRunIn() && (flag == PlaceGeneratedRunIn || !newChild->isBeforeOrAfterContent()))
+ moveRunInUnderSiblingBlockIfNeeded(prevSibling);
+ }
+}
+
RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject* runIn)
{
ASSERT(runIn->isRunIn());
@@ -1820,8 +1835,8 @@ void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
if (!runIn->isRenderBlock())
return;
- // We shouldn't run in into the sibling block if we are part of a
- // continuation chain. In that case, treat it as a normal block.
+ // FIXME: We don't support run-ins with or as part of a continuation
+ // as it makes the back-and-forth placing complex.
if (runIn->isElementContinuation() || runIn->virtualContinuation())
return;
@@ -1831,6 +1846,9 @@ void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
if (runInNode && runInNode->hasTagName(selectTag))
return;
+ if (runInNode && runInNode->hasTagName(progressTag))
+ return;
+
RenderObject* curr = runIn->nextSibling();
if (!curr || !curr->isRenderBlock() || !curr->childrenInline())
return;
@@ -1851,19 +1869,39 @@ void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
// since it handles correct placement of the children, especially where we cannot insert
// anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
curr->addChild(newRunIn, curr->firstChild());
+
+ // Make sure that |this| get a layout since its run-in child moved.
+ curr->setNeedsLayoutAndPrefWidthsRecalc();
}
-void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
+bool RenderBlock::runInIsPlacedIntoSiblingBlock(RenderObject* runIn)
{
ASSERT(runIn->isRunIn());
- // If we don't have a parent, there is nothing to move. This might
- // happen if |this| got detached from parent after |runIn| run into |this|.
+ // If we don't have a parent, we can't be moved into our sibling block.
if (!parent())
- return;
+ return false;
// An intruded run-in needs to be an inline.
if (!runIn->isRenderInline())
+ return false;
+
+ return true;
+}
+
+void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
+{
+ ASSERT(runIn->isRunIn());
+
+ if (!runInIsPlacedIntoSiblingBlock(runIn))
+ return;
+
+ // FIXME: Run-in that are now placed in sibling block can break up into continuation
+ // chains when new children are added to it. We cannot easily send them back to their
+ // original place since that requires writing integration logic with RenderInline::addChild
+ // and all other places that might cause continuations to be created (without blowing away
+ // |this|). Disabling this feature for now to prevent crashes.
+ if (runIn->isElementContinuation() || runIn->virtualContinuation())
return;
RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
@@ -1872,6 +1910,9 @@ void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
// Add the run-in block as our previous sibling.
parent()->addChild(newRunIn, this);
+
+ // Make sure that the parent holding the new run-in gets layout.
+ parent()->setNeedsLayoutAndPrefWidthsRecalc();
}
LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
@@ -1974,6 +2015,16 @@ LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo
logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
}
+
+ // If we have collapsed into a previous sibling and so reduced the height of the parent, ensure any floats that now
+ // overhang from the previous sibling are added to our parent
+ RenderObject* prev = child->previousSibling();
+ if (prev && prev->isRenderBlock()) {
+ RenderBlock* block = toRenderBlock(prev);
+ if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTop)
+ addOverhangingFloats(block, false);
+ }
+
return logicalTop;
}
@@ -3346,6 +3397,13 @@ LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPo
return gapRect;
}
+static inline void alignSelectionRectToDevicePixels(LayoutRect& rect)
+{
+ LayoutUnit maxX = floorToInt(rect.maxX());
+ rect.setX(floorToInt(rect.x()));
+ rect.setWidth((maxX - rect.x()).round());
+}
+
LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
{
@@ -3432,15 +3490,15 @@ RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) con
if (isSelectionRoot())
return 0;
- const RenderBox* object = this;
+ const RenderObject* object = this;
RenderObject* sibling;
do {
sibling = object->previousSibling();
while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
sibling = sibling->previousSibling();
- offset -= LayoutSize(object->logicalLeft(), object->logicalTop());
- object = object->parentBox();
+ offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
+ object = object->parent();
} while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
if (!sibling)
@@ -4292,7 +4350,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, LayoutUnit logicalLeftOf
if (!prev->m_floatingObjects)
return;
- logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
+ logicalLeftOffset += marginLogicalLeft();
const FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
FloatingObjectSetIterator prevEnd = prevSet.end();
@@ -5475,7 +5533,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
child->setPreferredLogicalWidthsDirty(false);
} else {
// Inline replaced elts add in their margins to their min/max values.
- float margins = 0;
+ LayoutUnit margins = 0;
Length startMargin = childStyle->marginStart();
Length endMargin = childStyle->marginEnd();
if (startMargin.isFixed())
@@ -5766,7 +5824,7 @@ bool RenderBlock::hasLineIfEmpty() const
if (node()->isRootEditableElement())
return true;
- if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
+ if (node()->isShadowRoot() && toShadowRoot(node())->host()->hasTagName(inputTag))
return true;
return false;
@@ -7001,118 +7059,6 @@ LayoutUnit RenderBlock::collapsedMarginAfterForChild(const RenderBox* child) co
return marginAfterForChild(child);
}
-LayoutUnit RenderBlock::marginBeforeForChild(const RenderBoxModelObject* child) const
-{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
- return child->marginTop();
- case BottomToTopWritingMode:
- return child->marginBottom();
- case LeftToRightWritingMode:
- return child->marginLeft();
- case RightToLeftWritingMode:
- return child->marginRight();
- }
- ASSERT_NOT_REACHED();
- return child->marginTop();
-}
-
-LayoutUnit RenderBlock::marginAfterForChild(const RenderBoxModelObject* child) const
-{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
- return child->marginBottom();
- case BottomToTopWritingMode:
- return child->marginTop();
- case LeftToRightWritingMode:
- return child->marginRight();
- case RightToLeftWritingMode:
- return child->marginLeft();
- }
- ASSERT_NOT_REACHED();
- return child->marginBottom();
-}
-
-LayoutUnit RenderBlock::marginStartForChild(const RenderBoxModelObject* child) const
-{
- if (isHorizontalWritingMode())
- return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
- return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
-}
-
-LayoutUnit RenderBlock::marginEndForChild(const RenderBoxModelObject* child) const
-{
- if (isHorizontalWritingMode())
- return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
- return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
-}
-
-void RenderBlock::setMarginStartForChild(RenderBox* child, LayoutUnit margin)
-{
- if (isHorizontalWritingMode()) {
- if (style()->isLeftToRightDirection())
- child->setMarginLeft(margin);
- else
- child->setMarginRight(margin);
- } else {
- if (style()->isLeftToRightDirection())
- child->setMarginTop(margin);
- else
- child->setMarginBottom(margin);
- }
-}
-
-void RenderBlock::setMarginEndForChild(RenderBox* child, LayoutUnit margin)
-{
- if (isHorizontalWritingMode()) {
- if (style()->isLeftToRightDirection())
- child->setMarginRight(margin);
- else
- child->setMarginLeft(margin);
- } else {
- if (style()->isLeftToRightDirection())
- child->setMarginBottom(margin);
- else
- child->setMarginTop(margin);
- }
-}
-
-void RenderBlock::setMarginBeforeForChild(RenderBox* child, LayoutUnit margin)
-{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
- child->setMarginTop(margin);
- break;
- case BottomToTopWritingMode:
- child->setMarginBottom(margin);
- break;
- case LeftToRightWritingMode:
- child->setMarginLeft(margin);
- break;
- case RightToLeftWritingMode:
- child->setMarginRight(margin);
- break;
- }
-}
-
-void RenderBlock::setMarginAfterForChild(RenderBox* child, LayoutUnit margin)
-{
- switch (style()->writingMode()) {
- case TopToBottomWritingMode:
- child->setMarginBottom(margin);
- break;
- case BottomToTopWritingMode:
- child->setMarginTop(margin);
- break;
- case LeftToRightWritingMode:
- child->setMarginRight(margin);
- break;
- case RightToLeftWritingMode:
- child->setMarginLeft(margin);
- break;
- }
-}
-
RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
{
LayoutUnit childBeforePositive = 0;