diff options
Diffstat (limited to 'WebCore/rendering/RenderTableSection.cpp')
-rw-r--r-- | WebCore/rendering/RenderTableSection.cpp | 128 |
1 files changed, 91 insertions, 37 deletions
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp index ad2bfaf..59fb324 100644 --- a/WebCore/rendering/RenderTableSection.cpp +++ b/WebCore/rendering/RenderTableSection.cpp @@ -47,7 +47,7 @@ namespace WebCore { using namespace HTMLNames; RenderTableSection::RenderTableSection(Node* node) - : RenderContainer(node) + : RenderBox(node) , m_gridRows(0) , m_cCol(0) , m_cRow(-1) @@ -75,7 +75,7 @@ void RenderTableSection::destroy() { RenderTable* recalcTable = table(); - RenderContainer::destroy(); + RenderBox::destroy(); // recalc cell info because RenderTable has unguarded pointers // stored that point to this RenderTableSection. @@ -89,11 +89,11 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild if (!beforeChild && isAfterContent(lastChild())) beforeChild = lastChild(); - bool isTableSection = element() && (element()->hasTagName(theadTag) || element()->hasTagName(tbodyTag) || element()->hasTagName(tfootTag)); + bool isTableSection = node() && (node()->hasTagName(theadTag) || node()->hasTagName(tbodyTag) || node()->hasTagName(tfootTag)); if (!child->isTableRow()) { - if (isTableSection && child->element() && child->element()->hasTagName(formTag) && document()->isHTMLDocument()) { - RenderContainer::addChild(child, beforeChild); + if (isTableSection && child->node() && child->node()->hasTagName(formTag) && document()->isHTMLDocument()) { + RenderBox::addChild(child, beforeChild); return; } @@ -147,8 +147,14 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild while (beforeChild && beforeChild->parent() != this) beforeChild = beforeChild->parent(); - ASSERT(!beforeChild || beforeChild->isTableRow() || isTableSection && beforeChild->element() && beforeChild->element()->hasTagName(formTag) && document()->isHTMLDocument()); - RenderContainer::addChild(child, beforeChild); + ASSERT(!beforeChild || beforeChild->isTableRow() || isTableSection && beforeChild->node() && beforeChild->node()->hasTagName(formTag) && document()->isHTMLDocument()); + RenderBox::addChild(child, beforeChild); +} + +void RenderTableSection::removeChild(RenderObject* oldChild) +{ + setNeedsCellRecalc(); + RenderBox::removeChild(oldChild); } bool RenderTableSection::ensureRows(int numRows) @@ -242,7 +248,7 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row) for (int r = 0; r < rSpan; r++) { CellStruct& c = cellAt(m_cRow + r, m_cCol); - if (currentCell.cell && !c.cell) + if (!c.cell) c.cell = currentCell.cell; if (currentCell.inColSpan) c.inColSpan = true; @@ -252,10 +258,8 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row) currentCell.cell = 0; currentCell.inColSpan = true; } - if (cell) { - cell->setRow(m_cRow); - cell->setCol(table()->effColToCol(col)); - } + cell->setRow(m_cRow); + cell->setCol(table()->effColToCol(col)); } void RenderTableSection::setCellWidths() @@ -425,6 +429,21 @@ int RenderTableSection::calcRowHeight() return m_rowPos[m_gridRows]; } +void RenderTableSection::layout() +{ + ASSERT(needsLayout()); + + LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); + for (RenderObject* child = children()->firstChild(); child; child = child->nextSibling()) { + if (child->isTableRow()) { + child->layoutIfNeeded(); + ASSERT(!child->needsLayout()); + } + } + statePusher.pop(); + setNeedsLayout(false); +} + int RenderTableSection::layoutRows(int toAdd) { #ifndef NDEBUG @@ -598,17 +617,37 @@ int RenderTableSection::layoutRows(int toAdd) (!table()->style()->height().isAuto() && rHeight != cell->height()); for (RenderObject* o = cell->firstChild(); o; o = o->nextSibling()) { - if (!o->isText() && o->style()->height().isPercent() && (o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()) || flexAllChildren)) { + if (!o->isText() && o->style()->height().isPercent() && (flexAllChildren || o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()))) { // Tables with no sections do not flex. if (!o->isTable() || static_cast<RenderTable*>(o)->hasSections()) { o->setNeedsLayout(true, false); - cell->setChildNeedsLayout(true, false); cellChildrenFlex = true; } } } - + + if (HashSet<RenderBox*>* percentHeightDescendants = cell->percentHeightDescendants()) { + HashSet<RenderBox*>::iterator end = percentHeightDescendants->end(); + for (HashSet<RenderBox*>::iterator it = percentHeightDescendants->begin(); it != end; ++it) { + RenderBox* box = *it; + if (!box->isReplaced() && !box->scrollsOverflow() && !flexAllChildren) + continue; + + while (box != cell) { + if (box->normalChildNeedsLayout()) + break; + box->setChildNeedsLayout(true, false); + box = box->containingBlock(); + ASSERT(box); + if (!box) + break; + } + cellChildrenFlex = true; + } + } + if (cellChildrenFlex) { + cell->setChildNeedsLayout(true, false); // Alignment within a cell is based off the calculated // height, which becomes irrelevant once the cell has // been resized based off its percentage. @@ -702,14 +741,16 @@ int RenderTableSection::layoutRows(int toAdd) int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includeSelf) const { - int bottom = RenderContainer::lowestPosition(includeOverflowInterior, includeSelf); + int bottom = RenderBox::lowestPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return bottom; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { - for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { - if (cell->isTableCell()) - bottom = max(bottom, static_cast<RenderTableCell*>(cell)->y() + cell->lowestPosition(false)); + for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { + if (curr->isTableCell()) { + RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + bottom = max(bottom, cell->y() + cell->lowestPosition(false)); + } } } @@ -718,14 +759,16 @@ int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includ int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const { - int right = RenderContainer::rightmostPosition(includeOverflowInterior, includeSelf); + int right = RenderBox::rightmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return right; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { - for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { - if (cell->isTableCell()) - right = max(right, static_cast<RenderTableCell*>(cell)->x() + cell->rightmostPosition(false)); + for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { + if (curr->isTableCell()) { + RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + right = max(right, cell->x() + cell->rightmostPosition(false)); + } } } @@ -734,14 +777,16 @@ int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool inc int RenderTableSection::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const { - int left = RenderContainer::leftmostPosition(includeOverflowInterior, includeSelf); + int left = RenderBox::leftmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return left; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { - for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { - if (cell->isTableCell()) - left = min(left, static_cast<RenderTableCell*>(cell)->x() + cell->leftmostPosition(false)); + for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { + if (curr->isTableCell()) { + RenderTableCell* cell = static_cast<RenderTableCell*>(curr); + left = min(left, cell->x() + cell->leftmostPosition(false)); + } } } @@ -957,7 +1002,7 @@ void RenderTableSection::recalcOuterBorder() m_outerBorderRight = calcOuterBorderRight(rtl); } -int RenderTableSection::getBaselineOfFirstLineBox() const +int RenderTableSection::firstLineBoxBaseline() const { if (!m_gridRows) return -1; @@ -994,8 +1039,20 @@ void RenderTableSection::paint(PaintInfo& paintInfo, int tx, int ty) tx += x(); ty += y(); + PaintPhase phase = paintInfo.phase; + bool pushedClip = pushContentsClip(paintInfo, tx, ty); + paintObject(paintInfo, tx, ty); + if (pushedClip) + popContentsClip(paintInfo, phase, tx, ty); +} + +void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty) +{ // Check which rows and cols are visible and only paint these. // FIXME: Could use a binary search here. + unsigned totalRows = m_gridRows; + unsigned totalCols = table()->columns().size(); + PaintPhase paintPhase = paintInfo.phase; int x = paintInfo.rect.x(); int y = paintInfo.rect.y(); @@ -1102,10 +1159,10 @@ void RenderTableSection::paint(PaintInfo& paintInfo, int tx, int ty) // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for // painting the row background for the cell. - if (!row->hasLayer()) + if (!row->hasSelfPaintingLayer()) cell->paintBackgroundsBehindCell(paintInfo, tx, ty, row); } - if ((!cell->hasLayer() && !row->hasLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders) + if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders) cell->paint(paintInfo, tx, ty); } } @@ -1190,12 +1247,6 @@ void RenderTableSection::splitColumn(int pos, int newSize) } } -RenderObject* RenderTableSection::removeChildNode(RenderObject* child, bool fullRemove) -{ - setNeedsCellRecalc(); - return RenderContainer::removeChildNode(child, fullRemove); -} - // Hit Testing bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action) { @@ -1204,12 +1255,15 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul tx += x(); ty += y(); + if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos)) + return false; + for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { // FIXME: We have to skip over inline flows, since they can show up inside table rows // at the moment (a demoted inline <form> for example). If we ever implement a // table-specific hit-test method (which we should do for performance reasons anyway), // then we can remove this check. - if (!child->hasLayer() && !child->isRenderInline() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) { + if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) { updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty)); return true; } |