summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderBlock.cpp')
-rw-r--r--WebCore/rendering/RenderBlock.cpp138
1 files changed, 100 insertions, 38 deletions
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 7040e06..204a0c3 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -44,6 +44,7 @@
#include "RenderView.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "TransformState.h"
#include <wtf/StdLibExtras.h>
#ifdef ANDROID_LAYOUT
@@ -62,13 +63,7 @@ static const int verticalLineClickFudgeFactor = 3;
using namespace HTMLNames;
-static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child)
-{
- ASSERT(from == child->parent());
- toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);
-}
-
-struct ColumnInfo {
+struct ColumnInfo : public Noncopyable {
ColumnInfo()
: m_desiredColumnWidth(0)
, m_desiredColumnCount(1)
@@ -167,6 +162,7 @@ RenderBlock::~RenderBlock()
void RenderBlock::destroy()
{
+<<<<<<< HEAD:WebCore/rendering/RenderBlock.cpp
// Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
// properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
children()->destroyLeftoverChildren();
@@ -178,7 +174,20 @@ void RenderBlock::destroy()
m_inlineContinuation->destroy();
m_inlineContinuation = 0;
}
+=======
+ // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
+ // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
+ children()->destroyLeftoverChildren();
+>>>>>>> webkit.org at r51976:WebCore/rendering/RenderBlock.cpp
+ // Destroy our continuation before anything other than anonymous children.
+ // The reason we don't destroy it before anonymous children is that they may
+ // have continuations of their own that are anonymous children of our continuation.
+ if (m_inlineContinuation) {
+ m_inlineContinuation->destroy();
+ m_inlineContinuation = 0;
+ }
+
if (!documentBeingDestroyed()) {
if (firstLineBox()) {
// We can't wait for RenderBox::destroy to clear the selection,
@@ -406,6 +415,19 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
m_lineBoxes.appendLineBox(rootBox);
return rootBox;
}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
+}
+
+void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child)
+{
+ ASSERT(this == child->parent());
+ ASSERT(!beforeChild || to == beforeChild->parent());
+ toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
+}
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
@@ -443,9 +465,9 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
RenderObject* no = o;
o = no->nextSibling();
- moveChild(block, block->children(), this, children(), no);
+ moveChildTo(block, block->children(), no);
}
- moveChild(block, block->children(), this, children(), inlineRunEnd);
+ moveChildTo(block, block->children(), inlineRunEnd);
}
#ifndef NDEBUG
@@ -520,7 +542,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);
+ nextBlock->moveChildTo(prevBlock, prevBlock->children(), no);
}
nextBlock->deleteLineBoxTree();
@@ -543,7 +565,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- moveChild(this, children(), anonBlock, anonBlock->children(), no);
+ anonBlock->moveChildTo(this, children(), no);
}
// Delete the now-empty block's lines and nuke it.
@@ -613,15 +635,15 @@ void RenderBlock::finishDelayUpdateScrollInfo()
if (gDelayUpdateScrollInfo == 0) {
ASSERT(gDelayedUpdateScrollInfoSet);
- for (DelayedUpdateScrollInfoSet::iterator it = gDelayedUpdateScrollInfoSet->begin(); it != gDelayedUpdateScrollInfoSet->end(); ++it) {
+ OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
+ gDelayedUpdateScrollInfoSet = 0;
+
+ for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
RenderBlock* block = *it;
if (block->hasOverflowClip()) {
block->layer()->updateScrollInfoAfterLayout();
}
}
-
- delete gDelayedUpdateScrollInfoSet;
- gDelayedUpdateScrollInfoSet = 0;
}
}
@@ -876,7 +898,11 @@ void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marg
}
y += (collapsedTopPos - collapsedTopNeg) - marginTop;
}
- child->layer()->setStaticY(y);
+ RenderLayer* childLayer = child->layer();
+ if (childLayer->staticY() != y) {
+ child->layer()->setStaticY(y);
+ child->setChildNeedsLayout(true, false);
+ }
}
}
@@ -965,7 +991,7 @@ bool RenderBlock::handleRunInChild(RenderBox* child)
// Move the nodes from the old child to the new child, but skip any :before/:after content. It has already
// been regenerated by the new inline.
for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
- if (runInIsGenerated || runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER) {
+ if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
}
@@ -1535,7 +1561,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
// Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
- if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground))
+ if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
}
@@ -1919,23 +1945,28 @@ bool RenderBlock::isSelectionRoot() const
return false;
}
-GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* /*repaintContainer*/)
+GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
{
ASSERT(!needsLayout());
if (!shouldPaintSelectionGaps())
return GapRects();
- // FIXME: this is broken with transforms and a non-null repaintContainer
- FloatPoint absContentPoint = localToAbsolute(FloatPoint());
+ // FIXME: this is broken with transforms
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+ mapLocalToContainer(repaintContainer, false, false, transformState);
+ FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
+ int x = offsetFromRepaintContainer.x();
+ int y = offsetFromRepaintContainer.y();
+
if (hasOverflowClip())
- absContentPoint -= layer()->scrolledContentOffset();
+ layer()->subtractScrolledContentOffset(x, y);
int lastTop = 0;
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
- return fillSelectionGaps(this, absContentPoint.x(), absContentPoint.y(), absContentPoint.x(), absContentPoint.y(), lastTop, lastLeft, lastRight);
+ return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
}
void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
@@ -1945,7 +1976,14 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
int lastLeft = leftSelectionOffset(this, lastTop);
int lastRight = rightSelectionOffset(this, lastTop);
paintInfo.context->save();
- fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
+ if (!gapRectsBounds.isEmpty()) {
+ if (RenderLayer* layer = enclosingLayer()) {
+ IntSize offset = hasLayer() ? IntSize() : offsetFromAncestorContainer(layer->renderer());
+ gapRectsBounds.move(offset - IntSize(tx, ty));
+ layer->addBlockSelectionGapsBounds(gapRectsBounds);
+ }
+ }
paintInfo.context->restore();
}
}
@@ -2132,7 +2170,7 @@ IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos,
return IntRect();
IntRect gapRect(xPos, yPos, width, height);
if (paintInfo && selObj->style()->visibility() == VISIBLE)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2153,7 +2191,7 @@ IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int las
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
return gapRect;
}
@@ -2169,7 +2207,7 @@ IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yP
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -2185,7 +2223,7 @@ IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int y
IntRect gapRect(left, top, width, height);
if (paintInfo)
- paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor());
+ paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
return gapRect;
}
@@ -3418,7 +3456,7 @@ VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint&
RootInlineBox* firstRootBoxWithChildren = 0;
RootInlineBox* lastRootBoxWithChildren = 0;
for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
- if (!root->firstChild())
+ if (!root->firstLeafChild())
continue;
if (!firstRootBoxWithChildren)
firstRootBoxWithChildren = root;
@@ -3565,11 +3603,15 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
} else if (colGap < availWidth) {
desiredColumnCount = availWidth / colGap;
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else if (style()->hasAutoColumnCount()) {
if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
} else {
@@ -3579,6 +3621,8 @@ void RenderBlock::calcColumnWidth()
desiredColumnWidth = colWidth;
} else if (colWidth < availWidth) {
desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
+ if (desiredColumnCount < 1)
+ desiredColumnCount = 1;
desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
}
}
@@ -3629,7 +3673,7 @@ Vector<IntRect>* RenderBlock::columnRects() const
return &gColumnInfoMap->get(this)->m_columnRects;
}
-int RenderBlock::layoutColumns(int endOfContent)
+int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
{
// Don't do anything if we have no columns
if (!hasColumns())
@@ -3642,17 +3686,20 @@ int RenderBlock::layoutColumns(int endOfContent)
bool computeIntrinsicHeight = (endOfContent == -1);
- // Fill the columns in to the available height. Attempt to balance the height of the columns
- int availableHeight = contentHeight();
- int colHeight = computeIntrinsicHeight ? availableHeight / desiredColumnCount : availableHeight;
-
+ // Fill the columns in to the available height. Attempt to balance the height of the columns.
// Add in half our line-height to help with best-guess initial balancing.
int columnSlop = lineHeight(false) / 2;
int remainingSlopSpace = columnSlop * desiredColumnCount;
+ int availableHeight = contentHeight();
+ int colHeight;
+ if (computeIntrinsicHeight && requestedColumnHeight >= 0)
+ colHeight = requestedColumnHeight;
+ else if (computeIntrinsicHeight)
+ colHeight = availableHeight / desiredColumnCount + columnSlop;
+ else
+ colHeight = availableHeight;
+ int originalColHeight = colHeight;
- if (computeIntrinsicHeight)
- colHeight += columnSlop;
-
int colGap = columnGap();
// Compute a collection of column rects.
@@ -3668,7 +3715,8 @@ int RenderBlock::layoutColumns(int endOfContent)
int currY = top;
unsigned colCount = desiredColumnCount;
int maxColBottom = borderTop() + paddingTop();
- int contentBottom = top + availableHeight;
+ int contentBottom = top + availableHeight;
+ int minimumColumnHeight = -1;
for (unsigned i = 0; i < colCount; i++) {
// If we aren't constrained, then the last column can just get all the remaining space.
if (computeIntrinsicHeight && i == colCount - 1)
@@ -3688,6 +3736,11 @@ int RenderBlock::layoutColumns(int endOfContent)
paintObject(paintInfo, 0, 0);
setHasColumns(true);
+ if (computeIntrinsicHeight && v->minimumColumnHeight() > originalColHeight) {
+ // The initial column height was too small to contain one line of text.
+ minimumColumnHeight = max(minimumColumnHeight, v->minimumColumnHeight());
+ }
+
int adjustedBottom = v->bestTruncatedAt();
if (adjustedBottom <= currY)
adjustedBottom = currY + colHeight;
@@ -3724,6 +3777,11 @@ int RenderBlock::layoutColumns(int endOfContent)
colCount++;
}
+ if (minimumColumnHeight >= 0) {
+ // If originalColHeight was too small, we need to try to layout again.
+ return layoutColumns(endOfContent, minimumColumnHeight);
+ }
+
int overflowRight = max(width(), currX - colGap);
int overflowLeft = min(0, currX + desiredColumnWidth + colGap);
int overflowHeight = maxColBottom;
@@ -4208,6 +4266,10 @@ void RenderBlock::calcInlinePrefWidths()
} else
inlineMax += childMax;
}
+
+ // Ignore spaces after a list marker.
+ if (child->isListMarker())
+ stripFrontSpaces = true;
} else {
m_minPrefWidth = max(inlineMin, m_minPrefWidth);
m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);