summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderTableSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderTableSection.cpp')
-rw-r--r--WebCore/rendering/RenderTableSection.cpp128
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;
}