source: webkit/trunk/Source/WebCore/rendering/RenderTableCol.cpp

Last change on this file was 290773, checked in by Alan Bujtas, 3 years ago

REGRESSION (r290512): imported/blink/fast/table/crash-output-element-as-column-group.html asserts sometimes
https://bugs.webkit.org/show_bug.cgi?id=237393

Reviewed by Simon Fraser.

Merging https://chromium.googlesource.com/chromium/src/+/1cfc9b9c37f43567529b09a9824d6d3a7bd9abb6%5E%21/#F2
The reason why crash-output-element-as-column-group.html crashes after r290512 is because
now we allow colgroup after the table content (thead, tbody) -prior to r290512, this test was pretty much a no-op.

  • rendering/RenderTableCol.cpp:

(WebCore::RenderTableCol::updateFromElement):

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1/*
2 * Copyright (C) 1997 Martin Jones ([email protected])
3 * (C) 1997 Torben Weis ([email protected])
4 * (C) 1998 Waldo Bastian ([email protected])
5 * (C) 1999 Lars Knoll ([email protected])
6 * (C) 1999 Antti Koivisto ([email protected])
7 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
8 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 */
25
26#include "config.h"
27#include "RenderTableCol.h"
28
29#include "HTMLNames.h"
30#include "HTMLTableColElement.h"
31#include "RenderChildIterator.h"
32#include "RenderIterator.h"
33#include "RenderTable.h"
34#include "RenderTableCaption.h"
35#include "RenderTableCell.h"
36#include <wtf/IsoMallocInlines.h>
37
38namespace WebCore {
39
40using namespace HTMLNames;
41
42WTF_MAKE_ISO_ALLOCATED_IMPL(RenderTableCol);
43
44RenderTableCol::RenderTableCol(Element& element, RenderStyle&& style)
45 : RenderBox(element, WTFMove(style), 0)
46{
47 // init RenderObject attributes
48 setInline(true); // our object is not Inline
49 updateFromElement();
50}
51
52RenderTableCol::RenderTableCol(Document& document, RenderStyle&& style)
53 : RenderBox(document, WTFMove(style), 0)
54{
55 setInline(true);
56}
57
58void RenderTableCol::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
59{
60 RenderBox::styleDidChange(diff, oldStyle);
61 RenderTable* table = this->table();
62 if (!table)
63 return;
64 // If border was changed, notify table.
65 if (!oldStyle)
66 return;
67 if (oldStyle->border() != style().border()) {
68 table->invalidateCollapsedBorders();
69 return;
70 }
71 if (oldStyle->width() != style().width()) {
72 table->recalcSectionsIfNeeded();
73 for (auto& section : childrenOfType<RenderTableSection>(*table)) {
74 unsigned nEffCols = table->numEffCols();
75 for (unsigned j = 0; j < nEffCols; j++) {
76 unsigned rowCount = section.numRows();
77 for (unsigned i = 0; i < rowCount; i++) {
78 RenderTableCell* cell = section.primaryCellAt(i, j);
79 if (!cell)
80 continue;
81 cell->setPreferredLogicalWidthsDirty(true);
82 }
83 }
84 }
85 }
86}
87
88void RenderTableCol::updateFromElement()
89{
90 ASSERT(element());
91 unsigned oldSpan = m_span;
92 if (element()->hasTagName(colTag) || element()->hasTagName(colgroupTag)) {
93 HTMLTableColElement& tc = static_cast<HTMLTableColElement&>(*element());
94 m_span = tc.span();
95 } else
96 m_span = 1;
97 if (m_span != oldSpan && hasInitializedStyle() && parent())
98 setNeedsLayoutAndPrefWidthsRecalc();
99}
100
101void RenderTableCol::insertedIntoTree(IsInternalMove isInternalMove)
102{
103 RenderBox::insertedIntoTree(isInternalMove);
104 table()->addColumn(this);
105}
106
107void RenderTableCol::willBeRemovedFromTree(IsInternalMove isInternalMove)
108{
109 RenderBox::willBeRemovedFromTree(isInternalMove);
110 table()->removeColumn(this);
111}
112
113bool RenderTableCol::isChildAllowed(const RenderObject& child, const RenderStyle& style) const
114{
115 // We cannot use isTableColumn here as style() may return 0.
116 return style.display() == DisplayType::TableColumn && child.isRenderTableCol();
117}
118
119bool RenderTableCol::canHaveChildren() const
120{
121 // Cols cannot have children. This is actually necessary to fix a bug
122 // with libraries.uc.edu, which makes a <p> be a table-column.
123 return isTableColumnGroup();
124}
125
126LayoutRect RenderTableCol::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext context) const
127{
128 // For now, just repaint the whole table.
129 // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
130 // might have propagated a background color or borders into.
131 // FIXME: check for repaintContainer each time here?
132
133 RenderTable* parentTable = table();
134 if (!parentTable)
135 return LayoutRect();
136 return parentTable->clippedOverflowRect(repaintContainer, context);
137}
138
139void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*)
140{
141 // FIXME: Repaint only the rect the image paints in.
142 repaint();
143}
144
145void RenderTableCol::clearPreferredLogicalWidthsDirtyBits()
146{
147 setPreferredLogicalWidthsDirty(false);
148
149 for (auto& child : childrenOfType<RenderObject>(*this))
150 child.setPreferredLogicalWidthsDirty(false);
151}
152
153RenderTable* RenderTableCol::table() const
154{
155 auto table = parent();
156 if (table && !is<RenderTable>(*table))
157 table = table->parent();
158 return dynamicDowncast<RenderTable>(table);
159}
160
161RenderTableCol* RenderTableCol::enclosingColumnGroup() const
162{
163 if (!is<RenderTableCol>(*parent()))
164 return nullptr;
165
166 RenderTableCol& parentColumnGroup = downcast<RenderTableCol>(*parent());
167 ASSERT(parentColumnGroup.isTableColumnGroup());
168 ASSERT(isTableColumn());
169 return &parentColumnGroup;
170}
171
172RenderTableCol* RenderTableCol::nextColumn() const
173{
174 // If |this| is a column-group, the next column is the colgroup's first child column.
175 if (RenderObject* firstChild = this->firstChild())
176 return downcast<RenderTableCol>(firstChild);
177
178 // Otherwise it's the next column along.
179 RenderObject* next = nextSibling();
180
181 // Failing that, the child is the last column in a column-group, so the next column is the next column/column-group after its column-group.
182 if (!next && is<RenderTableCol>(*parent()))
183 next = parent()->nextSibling();
184
185 for (; next && !is<RenderTableCol>(*next); next = next->nextSibling()) { }
186
187 return downcast<RenderTableCol>(next);
188}
189
190const BorderValue& RenderTableCol::borderAdjoiningCellStartBorder() const
191{
192 return style().borderStart();
193}
194
195const BorderValue& RenderTableCol::borderAdjoiningCellEndBorder() const
196{
197 return style().borderEnd();
198}
199
200const BorderValue& RenderTableCol::borderAdjoiningCellBefore(const RenderTableCell& cell) const
201{
202 ASSERT_UNUSED(cell, table()->colElement(cell.col() + cell.colSpan()) == this);
203 return style().borderStart();
204}
205
206const BorderValue& RenderTableCol::borderAdjoiningCellAfter(const RenderTableCell& cell) const
207{
208 ASSERT_UNUSED(cell, table()->colElement(cell.col() - 1) == this);
209 return style().borderEnd();
210}
211
212LayoutUnit RenderTableCol::offsetLeft() const
213{
214 return table()->offsetLeftForColumn(*this);
215}
216
217LayoutUnit RenderTableCol::offsetTop() const
218{
219 return table()->offsetTopForColumn(*this);
220}
221
222LayoutUnit RenderTableCol::offsetWidth() const
223{
224 return table()->offsetWidthForColumn(*this);
225}
226
227LayoutUnit RenderTableCol::offsetHeight() const
228{
229 return table()->offsetHeightForColumn(*this);
230}
231
232}
Note: See TracBrowser for help on using the repository browser.