diff options
Diffstat (limited to 'WebCore/rendering/RenderTable.cpp')
-rw-r--r-- | WebCore/rendering/RenderTable.cpp | 145 |
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; +} + } |