diff options
| author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
| commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
| tree | e367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/rendering/RenderTable.cpp | |
| parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
| download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz | |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/rendering/RenderTable.cpp')
| -rw-r--r-- | Source/WebCore/rendering/RenderTable.cpp | 115 |
1 files changed, 82 insertions, 33 deletions
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp index 7d5cfe94f..3249afb8a 100644 --- a/Source/WebCore/rendering/RenderTable.cpp +++ b/Source/WebCore/rendering/RenderTable.cpp @@ -28,12 +28,12 @@ #include "AutoTableLayout.h" #include "CollapsedBorderValue.h" -#include "DeleteButtonController.h" #include "Document.h" #include "FixedTableLayout.h" #include "FrameView.h" #include "HitTestResult.h" #include "HTMLNames.h" +#include "HTMLTableElement.h" #include "LayoutRepainter.h" #include "RenderLayer.h" #include "RenderTableCaption.h" @@ -42,6 +42,7 @@ #include "RenderTableSection.h" #include "RenderView.h" #include "StyleInheritedData.h" +#include <wtf/StackStats.h> using namespace std; @@ -49,8 +50,8 @@ namespace WebCore { using namespace HTMLNames; -RenderTable::RenderTable(Node* node) - : RenderBlock(node) +RenderTable::RenderTable(Element* element) + : RenderBlock(element) , m_head(0) , m_foot(0) , m_firstBody(0) @@ -113,10 +114,6 @@ static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, Rend void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) { - // Make sure we don't append things after :after-generated content if we have it. - if (!beforeChild) - beforeChild = afterPseudoElementRenderer(); - bool wrapInAnonymousSection = !child->isOutOfFlowPositioned(); if (child->isTableCaption()) @@ -159,6 +156,9 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild) else wrapInAnonymousSection = true; + if (child->isTableSection()) + setNeedsSectionRecalc(); + if (!wrapInAnonymousSection) { if (beforeChild && beforeChild->parent() != this) beforeChild = splitAnonymousBoxesAroundChild(beforeChild); @@ -255,7 +255,7 @@ void RenderTable::updateLogicalWidth() LayoutUnit containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth; Length styleLogicalWidth = style()->logicalWidth(); - if (styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive()) + if ((styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive()) || styleLogicalWidth.isIntrinsic()) setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection)); else { // Subtract out any fixed margins from our available width for auto width tables. @@ -267,7 +267,7 @@ void RenderTable::updateLogicalWidth() LayoutUnit availableContentLogicalWidth = max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal); if (shrinkToAvoidFloats() && cb->containsFloats() && !hasPerpendicularContainingBlock) { // FIXME: Work with regions someday. - availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, 0, 0); + availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, 0); } // Ensure we aren't bigger than our available width. @@ -280,14 +280,14 @@ void RenderTable::updateLogicalWidth() // Ensure we aren't bigger than our max-width style. Length styleMaxLogicalWidth = style()->logicalMaxWidth(); - if (styleMaxLogicalWidth.isSpecified() && !styleMaxLogicalWidth.isNegative()) { + if ((styleMaxLogicalWidth.isSpecified() && !styleMaxLogicalWidth.isNegative()) || styleMaxLogicalWidth.isIntrinsic()) { LayoutUnit computedMaxLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMaxLogicalWidth, availableLogicalWidth); setLogicalWidth(min<int>(logicalWidth(), computedMaxLogicalWidth)); } // Ensure we aren't smaller than our min-width style. Length styleMinLogicalWidth = style()->logicalMinWidth(); - if (styleMinLogicalWidth.isSpecified() && !styleMinLogicalWidth.isNegative()) { + if ((styleMinLogicalWidth.isSpecified() && !styleMinLogicalWidth.isNegative()) || styleMinLogicalWidth.isIntrinsic()) { LayoutUnit computedMinLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth); setLogicalWidth(max<int>(logicalWidth(), computedMinLogicalWidth)); } @@ -298,7 +298,7 @@ void RenderTable::updateLogicalWidth() if (!hasPerpendicularContainingBlock) { LayoutUnit containerLogicalWidthForAutoMargins = availableLogicalWidth; if (avoidsFloats() && cb->containsFloats()) - containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(0, 0); // FIXME: Work with regions someday. + containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(0); // FIXME: Work with regions someday. ComputedMarginValues marginValues; bool hasInvertedDirection = cb->style()->isLeftToRightDirection() == style()->isLeftToRightDirection(); computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth(), @@ -315,14 +315,15 @@ void RenderTable::updateLogicalWidth() // This method takes a RenderStyle's logical width, min-width, or max-width length and computes its actual value. LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth) { + if (styleLogicalWidth.isIntrinsic()) + return computeIntrinsicLogicalWidthUsing(styleLogicalWidth, availableWidth, bordersPaddingAndSpacingInRowDirection()); + // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not. LayoutUnit borders = 0; - bool isCSSTable = !node() || !node()->hasTagName(tableTag); - if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive()) { - recalcBordersInRowDirection(); - if (style()->boxSizing() == CONTENT_BOX) - borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd()); - } + bool isCSSTable = !node() || !isHTMLTableElement(node()); + if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive() && style()->boxSizing() == CONTENT_BOX) + borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd()); + return minimumValueForLength(styleLogicalWidth, availableWidth, view()) + borders; } @@ -333,7 +334,7 @@ LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length& // HTML tables size as though CSS height includes border/padding, CSS tables do not. LayoutUnit borders = LayoutUnit(); // FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow. - if ((node() && node()->hasTagName(tableTag)) || style()->boxSizing() == BORDER_BOX) { + if ((node() && isHTMLTableElement(node())) || style()->boxSizing() == BORDER_BOX) { LayoutUnit borderAndPaddingBefore = borderBefore() + (collapseBorders() ? LayoutUnit() : paddingBefore()); LayoutUnit borderAndPaddingAfter = borderAfter() + (collapseBorders() ? LayoutUnit() : paddingAfter()); borders = borderAndPaddingBefore + borderAndPaddingAfter; @@ -382,6 +383,14 @@ void RenderTable::distributeExtraLogicalHeight(int extraLogicalHeight) // ASSERT(!topSection() || !extraLogicalHeight); } +void RenderTable::simplifiedNormalFlowLayout() +{ + for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) { + section->layoutIfNeeded(); + section->computeOverflowFromCells(); + } +} + void RenderTable::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; @@ -391,12 +400,14 @@ void RenderTable::layout() return; recalcSectionsIfNeeded(); + // FIXME: We should do this recalc lazily in borderStart/borderEnd so that we don't have to make sure + // to call this before we call borderStart/borderEnd to avoid getting a stale value. + recalcBordersInRowDirection(); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); - LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode()); + LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); setLogicalHeight(0); - m_overflow.clear(); initMaxMarginValues(); @@ -643,7 +654,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs PaintInfo info(paintInfo); info.phase = paintPhase; - info.updatePaintingRootForChildren(this); + info.updateSubtreePaintRootForChildren(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) { @@ -670,7 +681,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs // Paint outline. if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE) - paintOutline(paintInfo.context, LayoutRect(paintOffset, size())); + paintOutline(paintInfo, LayoutRect(paintOffset, size())); } void RenderTable::subtractCaptionRect(LayoutRect& rect) const @@ -698,9 +709,10 @@ void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& p LayoutRect rect(paintOffset, size()); subtractCaptionRect(rect); - if (!boxShadowShouldBeAppliedToBackground(determineBackgroundBleedAvoidance(paintInfo.context))) + BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context); + if (!boxShadowShouldBeAppliedToBackground(bleedAvoidance)) paintBoxShadow(paintInfo, rect, style(), Normal); - paintBackground(paintInfo, rect); + paintBackground(paintInfo, rect, bleedAvoidance); paintBoxShadow(paintInfo, rect, style(), Inset); if (style()->hasBorder() && !collapseBorders()) @@ -718,18 +730,49 @@ void RenderTable::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset paintMaskImages(paintInfo, rect); } +void RenderTable::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) const +{ + recalcSectionsIfNeeded(); + // FIXME: Do the recalc in borderStart/borderEnd and make those const_cast this call. + // Then m_borderStart/m_borderEnd will be transparent a cache and it removes the possibility + // of reading out stale values. + const_cast<RenderTable*>(this)->recalcBordersInRowDirection(); + // FIXME: Restructure the table layout code so that we can make this method const. + const_cast<RenderTable*>(this)->m_tableLayout->computeIntrinsicLogicalWidths(minWidth, maxWidth); + + // FIXME: We should include captions widths here like we do in computePreferredLogicalWidths. +} + void RenderTable::computePreferredLogicalWidths() { ASSERT(preferredLogicalWidthsDirty()); - recalcSectionsIfNeeded(); - recalcBordersInRowDirection(); + computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); + + int bordersPaddingAndSpacing = bordersPaddingAndSpacingInRowDirection(); + m_minPreferredLogicalWidth += bordersPaddingAndSpacing; + m_maxPreferredLogicalWidth += bordersPaddingAndSpacing; - m_tableLayout->computePreferredLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); + m_tableLayout->applyPreferredLogicalWidthQuirks(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth); for (unsigned i = 0; i < m_captions.size(); i++) m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_captions[i]->minPreferredLogicalWidth()); + RenderStyle* styleToUse = style(); + // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for min-width. + if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) { + m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value())); + m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value())); + } + + // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for maxWidth. + if (styleToUse->logicalMaxWidth().isFixed()) { + m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value())); + m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value())); + } + + // FIXME: We should be adding borderAndPaddingLogicalWidth here, but m_tableLayout->computePreferredLogicalWidths already does, + // so a bunch of tests break doing this naively. setPreferredLogicalWidthsDirty(false); } @@ -762,7 +805,6 @@ void RenderTable::splitColumn(unsigned position, unsigned firstSpan) } m_columnPos.grow(numEffCols() + 1); - setNeedsLayoutAndPrefWidthsRecalc(); } void RenderTable::appendColumn(unsigned span) @@ -784,7 +826,6 @@ void RenderTable::appendColumn(unsigned span) } m_columnPos.grow(numEffCols() + 1); - setNeedsLayoutAndPrefWidthsRecalc(); } RenderTableCol* RenderTable::firstColumn() const @@ -1314,9 +1355,16 @@ int RenderTable::firstLineBoxBaseline() const return -1; } -LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy) +LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy, PaintPhase phase) { - LayoutRect rect = RenderBlock::overflowClipRect(location, region, relevancy); + LayoutRect rect; + // Don't clip out the table's side of the collapsed borders if we're in the paint phase that will ask the sections to paint them. + // Likewise, if we're self-painting we avoid clipping them out as the clip rect that will be passed down to child layers from RenderLayer will do that instead. + if (phase == PaintPhaseChildBlockBackgrounds || layer()->isSelfPaintingLayer()) { + rect = borderBoxRectInRegion(region); + rect.setLocation(location + rect.location()); + } else + rect = RenderBox::overflowClipRect(location, region, relevancy); // 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 @@ -1368,7 +1416,8 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu RenderTable* RenderTable::createAnonymousWithParentRenderer(const RenderObject* parent) { RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), TABLE); - RenderTable* newTable = new (parent->renderArena()) RenderTable(parent->document() /* is anonymous */); + RenderTable* newTable = new (parent->renderArena()) RenderTable(0); + newTable->setDocumentForAnonymous(parent->document()); newTable->setStyle(newStyle.release()); return newTable; } |
