summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderTable.cpp')
-rw-r--r--WebCore/rendering/RenderTable.cpp145
1 files changed, 90 insertions, 55 deletions
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index 784a59a..f4b1033 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -55,8 +55,6 @@ RenderTable::RenderTable(Node* node)
, m_firstBody(0)
, m_tableLayout(0)
, m_currentBorder(0)
- , m_frame(Void)
- , m_rules(None)
, m_hasColElements(false)
, m_needsSectionRecalc(0)
, m_hSpacing(0)
@@ -76,7 +74,7 @@ RenderTable::~RenderTable()
delete m_tableLayout;
}
-void RenderTable::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -116,8 +114,8 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
if (!beforeChild && isAfterContent(lastChild()))
beforeChild = lastChild();
- bool wrapInAnonymousSection = true;
- bool isTableElement = element() && element()->hasTagName(tableTag);
+ bool wrapInAnonymousSection = !child->isPositioned();
+ bool isTableElement = node() && node()->hasTagName(tableTag);
if (child->isRenderBlock() && child->style()->display() == TABLE_CAPTION) {
// First caption wins.
@@ -129,7 +127,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
m_caption = 0;
}
if (!m_caption)
- m_caption = static_cast<RenderBlock*>(child);
+ m_caption = toRenderBlock(child);
wrapInAnonymousSection = false;
} else if (child->isTableCol()) {
m_hasColElements = true;
@@ -172,21 +170,16 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
}
} else if (child->isTableCell() || child->isTableRow()) {
wrapInAnonymousSection = true;
- } else {
+ } else
// Allow a form to just sit at the top level.
- wrapInAnonymousSection = !isTableElement || !child->element() || !(child->element()->hasTagName(formTag) && document()->isHTMLDocument());
-
- // FIXME: Allow the delete button container element to sit at the top level. This is needed until http://bugs.webkit.org/show_bug.cgi?id=11363 is fixed.
- if (wrapInAnonymousSection && child->element() && child->element()->isHTMLElement() && static_cast<HTMLElement*>(child->element())->id() == DeleteButtonController::containerElementIdentifier)
- wrapInAnonymousSection = false;
- }
+ wrapInAnonymousSection = !isTableElement || !child->node() || !(child->node()->hasTagName(formTag) && document()->isHTMLDocument());
if (!wrapInAnonymousSection) {
// If the next renderer is actually wrapped in an anonymous table section, we need to go up and find that.
while (beforeChild && !beforeChild->isTableSection() && !beforeChild->isTableCol() && beforeChild->style()->display() != TABLE_CAPTION)
beforeChild = beforeChild->parent();
- RenderContainer::addChild(child, beforeChild);
+ RenderBox::addChild(child, beforeChild);
return;
}
@@ -214,6 +207,12 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
section->addChild(child);
}
+void RenderTable::removeChild(RenderObject* oldChild)
+{
+ RenderBox::removeChild(oldChild);
+ setNeedsSectionRecalc();
+}
+
void RenderTable::calcWidth()
{
#ifdef ANDROID_LAYOUT
@@ -240,7 +239,7 @@ void RenderTable::calcWidth()
} else {
// An auto width table should shrink to fit within the line width if necessary in order to
// avoid overlapping floats.
- availableWidth = cb->lineWidth(y());
+ availableWidth = cb->lineWidth(y(), false);
// Subtract out any fixed margins from our available width for auto width tables.
int marginTotal = 0;
@@ -278,14 +277,7 @@ void RenderTable::layout()
recalcSectionsIfNeeded();
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
-
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
setHeight(0);
@@ -308,17 +300,29 @@ void RenderTable::layout()
else if (document()->settings()->layoutAlgorithm() == Settings::kLayoutSSR) {
// if the width of a table is wider than its container width, or it has a nested table,
// we will render it with single column.
- int cw = containingBlockWidth();
- if (width() > cw || hasChildTable()) {
+ int cw = containingBlockWidthForContent();
+ bool shouldRenderAsSingleColumn = (width() > cw);
+ if (!shouldRenderAsSingleColumn) {
+ RenderObject* child = firstChild();
+ while (child) {
+ if (child->isTable()) {
+ shouldRenderAsSingleColumn = true;
+ break;
+ }
+ child = child->nextInPreOrder();
+ }
+ }
+
+ if (shouldRenderAsSingleColumn) {
m_singleColumn = true;
if (width() > cw)
- setWidth(cw);
+ setWidth(cw);
if (m_minPrefWidth > cw)
- m_minPrefWidth = cw;
- if (m_maxPrefWidth > cw)
- m_maxPrefWidth = cw;
+ m_minPrefWidth = cw;
+ if (m_maxPrefWidth > cw)
+ m_maxPrefWidth = cw;
}
- }
+ }
#endif
if (m_caption && width() != oldWidth)
m_caption->setNeedsLayout(true, false);
@@ -339,18 +343,18 @@ void RenderTable::layout()
bool collapsing = collapseBorders();
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- // FIXME: What about a form that has a display value that makes it a table section?
#ifdef ANDROID_LAYOUT
- if ((relayoutChildren || child->needsLayout()) &&
- !(child->element() && child->element()->hasTagName(formTag))) {
- child->setNeedsLayout(true);
- child->layout();
+ if (relayoutChildren) {
+ child->setNeedsLayout(true, false);
+ if (!child->isTableSection()) {
+ child->layoutIfNeeded();
+ continue;
+ }
+ // fall through
}
-#else
- if (child->needsLayout() && !(child->element() && child->element()->hasTagName(formTag) && !child->isTableSection()))
- child->layout();
#endif
if (child->isTableSection()) {
+ child->layoutIfNeeded();
RenderTableSection* section = static_cast<RenderTableSection*>(child);
calculatedHeight += section->calcRowHeight();
if (collapsing)
@@ -359,6 +363,10 @@ void RenderTable::layout()
}
}
+ // Only lay out one caption, since it's the only one we're going to end up painting.
+ if (m_caption)
+ m_caption->layoutIfNeeded();
+
m_overflowWidth = width() + (collapsing ? outerBorderRight() - borderRight() : 0);
m_overflowLeft = collapsing ? borderLeft() - outerBorderLeft() : 0;
@@ -480,10 +488,8 @@ void RenderTable::layout()
statePusher.pop();
- bool didFullRepaint = true;
+ bool didFullRepaint = repainter.repaintAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
- if (checkForRepaint)
- didFullRepaint = repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
if (!didFullRepaint && sectionMoved)
repaintRectangle(IntRect(m_overflowLeft, movedSectionTop, m_overflowWidth - m_overflowLeft, m_overflowHeight - movedSectionTop));
@@ -511,6 +517,15 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty)
if (tx + overflowLeft(false) >= paintInfo.rect.right() + os || tx + overflowWidth(false) <= paintInfo.rect.x() - os)
return;
+ bool pushedClip = pushContentsClip(paintInfo, tx, ty);
+ paintObject(paintInfo, tx, ty);
+ if (pushedClip)
+ popContentsClip(paintInfo, paintPhase, tx, ty);
+}
+
+void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
+{
+ PaintPhase paintPhase = paintInfo.phase;
if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorations() && style()->visibility() == VISIBLE)
paintBoxDecorations(paintInfo, tx, ty);
@@ -522,19 +537,20 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty)
// We're done. We don't bother painting any children.
if (paintPhase == PaintPhaseBlockBackground)
return;
-
+
// We don't paint our own background, but we do let the kids paint their backgrounds.
if (paintPhase == PaintPhaseChildBlockBackgrounds)
paintPhase = PaintPhaseChildBlockBackground;
+
PaintInfo info(paintInfo);
info.phase = paintPhase;
info.paintingRoot = paintingRootForChildren(paintInfo);
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->hasLayer() && (child->isTableSection() || child == m_caption))
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption))
child->paint(info, tx, ty);
}
-
+
if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
// Collect all the unique border styles that we want to paint in a sorted list. Once we
// have all the styles sorted, we then do individual passes, painting each style of border
@@ -717,7 +733,7 @@ void RenderTable::recalcSections() const
switch (child->style()->display()) {
case TABLE_CAPTION:
if (!m_caption && child->isRenderBlock()) {
- m_caption = static_cast<RenderBlock*>(child);
+ m_caption = toRenderBlock(child);
m_caption->setNeedsLayout(true);
}
break;
@@ -777,12 +793,6 @@ void RenderTable::recalcSections() const
m_needsSectionRecalc = false;
}
-RenderObject* RenderTable::removeChildNode(RenderObject* child, bool fullRemove)
-{
- setNeedsSectionRecalc();
- return RenderContainer::removeChildNode(child, fullRemove);
-}
-
int RenderTable::calcBorderLeft() const
{
if (collapseBorders()) {
@@ -1172,7 +1182,7 @@ void RenderTable::updateFirstLetter()
{
}
-int RenderTable::getBaselineOfFirstLineBox() const
+int RenderTable::firstLineBoxBaseline() const
{
RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot);
if (firstNonEmptySection && !firstNonEmptySection->numRows())
@@ -1181,12 +1191,12 @@ int RenderTable::getBaselineOfFirstLineBox() const
if (!firstNonEmptySection)
return -1;
- return firstNonEmptySection->y() + firstNonEmptySection->getBaselineOfFirstLineBox();
+ return firstNonEmptySection->y() + firstNonEmptySection->firstLineBoxBaseline();
}
-IntRect RenderTable::getOverflowClipRect(int tx, int ty)
+IntRect RenderTable::overflowClipRect(int tx, int ty)
{
- IntRect rect = RenderBlock::getOverflowClipRect(tx, ty);
+ IntRect rect = RenderBlock::overflowClipRect(tx, ty);
// If we have a caption, expand the clip to include the caption.
// FIXME: Technically this is wrong, but it's virtually impossible to fix this
@@ -1202,4 +1212,29 @@ IntRect RenderTable::getOverflowClipRect(int tx, int ty)
return rect;
}
+bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
+{
+ tx += x();
+ ty += y();
+
+ // Check kids first.
+ if (!hasOverflowClip() || overflowClipRect(tx, ty).contains(xPos, yPos)) {
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) &&
+ child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+ }
+ }
+
+ // Check our bounds next.
+ if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+
+ return false;
+}
+
}