LayoutTests:
Reviewed by Maciej.
- test for http://bugzilla.opendarwin.org/show_bug.cgi?id=5731
Form element as display table-cell hangs Safari (will eventually crash)
* fast/table/form-with-table-style.html: Added.
* fast/table/form-with-table-style-expected.txt: Added.
* fast/table/form-with-table-style-expected.png: Added.
* fast/table/form-with-table-style-expected.checksum: Added.
WebCore:
Reviewed by Maciej.
- fix http://bugzilla.opendarwin.org/show_bug.cgi?id=5731
Form element as display table-cell hangs Safari (will eventually crash)
Test: fast/table/form-with-table-style.html
Hang was caused by the fact that RenderContainer has code to wrap table
styled elements in appropriate anonymous table elements, but the table
elements themselves have a special case for form elements that causes them
to call through, which led to infinite recursion as RenderContainer kept
making new tables which kept calling through to RenderContainer::addChild.
* rendering/RenderTable.cpp:
(WebCore::RenderTable::addChild): Improved logic about wrapping children
in anonymous table sections in the following ways: (1) Do wrap a form
properly it has a table display style (such as table-cell or table-row).
(2) When an item has a particular display style, check that it has the
right type of render object before casting it to that type. Also
restructured the code a little to make it slightly more readable.
(WebCore::RenderTable::layout): Added a FIXME about forms that have a
display style that makes it a table section, since they will be skipped
here in the loop to lay children out.
(WebCore::RenderTable::recalcSections): Added checks similar to the ones
in addChild above.
* rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::addChild):
Moved form tag logic inside render object type check so that a table row
that happens to be a form element won't be affected by the special form
tag logic. Also added an explicit check for the table-cell style so we
will wrap it in a row rather than just putting the form at this level.
* rendering/RenderTableRow.h: Removed removeChildNode and dump functions
that just called through to the base class.
* rendering/RenderTableRow.cpp: (WebCore::RenderTableRow::addChild):
Moved form tag logic inside render object type check so that a table cell
that happens to be a form element won't be affected by the special form
tag logic. Removed unnecessary null check of section() at end of function.
* rendering/RenderTableCol.h: Removed addChild because all it did was
assert (incorrectly) and then call through to the base class. Changed
_span to be m_span.
* rendering/RenderTableCol.cpp: Removed addChild function. Updated for
change in name of m_span field.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@12298 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index 35c26e9..ddda685 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -74,50 +74,49 @@
RenderContainer::setStyle(_style);
}
-void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild)
+void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild)
{
- RenderObject *row = child;
-
- if (child->element() && child->element()->hasTagName(formTag)) {
- RenderContainer::addChild(child,beforeChild);
- return;
- }
-
if (!child->isTableRow()) {
-
- if (!beforeChild)
- beforeChild = lastChild();
-
- if (beforeChild && beforeChild->isAnonymous())
- row = beforeChild;
- else {
- RenderObject *lastBox = beforeChild;
- while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow())
- lastBox = lastBox->parent();
- if (lastBox && lastBox->isAnonymous()) {
- lastBox->addChild( child, beforeChild );
- return;
- } else {
- row = new (renderArena()) RenderTableRow(document() /* anonymous table */);
- RenderStyle *newStyle = new (renderArena()) RenderStyle();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(TABLE_ROW);
- row->setStyle(newStyle);
- addChild(row, beforeChild);
- }
+ if (child->element() && child->element()->hasTagName(formTag) && child->style()->display() != TABLE_CELL) {
+ RenderContainer::addChild(child, beforeChild);
+ return;
}
+
+ RenderObject* last = beforeChild;
+ if (!last)
+ last = lastChild();
+ if (last && last->isAnonymous()) {
+ last->addChild(child);
+ return;
+ }
+
+ // FIXME: Not sure why this code is needed to pop back up out of the table.
+ // It doesn't affect any of our layout tests, but I'm going to leave it in for now.
+ RenderObject* lastBox = last;
+ while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow())
+ lastBox = lastBox->parent();
+ if (lastBox && lastBox->isAnonymous()) {
+ lastBox->addChild(child, beforeChild);
+ return;
+ }
+
+ RenderObject* row = new (renderArena()) RenderTableRow(document() /* anonymous table */);
+ RenderStyle* newStyle = new (renderArena()) RenderStyle();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(TABLE_ROW);
+ row->setStyle(newStyle);
+ addChild(row, beforeChild);
row->addChild(child);
- child->setNeedsLayoutAndMinMaxRecalc();
return;
}
if (beforeChild)
setNeedCellRecalc();
- cRow++;
+ ++cRow;
cCol = 0;
- ensureRows(cRow+1);
+ ensureRows(cRow + 1);
if (!beforeChild) {
grid[cRow].height = child->style()->height();
@@ -125,8 +124,7 @@
grid[cRow].height = Length();
}
-
- RenderContainer::addChild(child,beforeChild);
+ RenderContainer::addChild(child, beforeChild);
}
bool RenderTableSection::ensureRows(int numRows)