Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / rendering / RenderTableCol.cpp
1 /*
2  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3  *           (C) 1997 Torben Weis (weis@kde.org)
4  *           (C) 1998 Waldo Bastian (bastian@kde.org)
5  *           (C) 1999 Lars Knoll (knoll@kde.org)
6  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
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 "RenderIterator.h"
32 #include "RenderTable.h"
33 #include "RenderTableCaption.h"
34 #include "RenderTableCell.h"
35
36 namespace WebCore {
37
38 using namespace HTMLNames;
39
40 RenderTableCol::RenderTableCol(Element& element, Ref<RenderStyle>&& style)
41     : RenderBox(element, WTFMove(style), 0)
42 {
43     // init RenderObject attributes
44     setInline(true); // our object is not Inline
45     updateFromElement();
46 }
47
48 void RenderTableCol::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
49 {
50     RenderBox::styleDidChange(diff, oldStyle);
51     RenderTable* table = this->table();
52     if (!table)
53         return;
54     // If border was changed, notify table.
55     if (oldStyle && oldStyle->border() != style().border())
56         table->invalidateCollapsedBorders();
57     else if (oldStyle->width() != style().width()) {
58         table->recalcSectionsIfNeeded();
59         for (auto& section : childrenOfType<RenderTableSection>(*table)) {
60             unsigned nEffCols = table->numEffCols();
61             for (unsigned j = 0; j < nEffCols; j++) {
62                 unsigned rowCount = section.numRows();
63                 for (unsigned i = 0; i < rowCount; i++) {
64                     RenderTableCell* cell = section.primaryCellAt(i, j);
65                     if (!cell)
66                         continue;
67                     cell->setPreferredLogicalWidthsDirty(true);
68                 }
69             }
70         }
71     }
72 }
73
74 void RenderTableCol::updateFromElement()
75 {
76     unsigned oldSpan = m_span;
77     if (element().hasTagName(colTag) || element().hasTagName(colgroupTag)) {
78         HTMLTableColElement& tc = static_cast<HTMLTableColElement&>(element());
79         m_span = tc.span();
80     } else
81         m_span = !(hasInitializedStyle() && style().display() == TABLE_COLUMN_GROUP);
82     if (m_span != oldSpan && hasInitializedStyle() && parent())
83         setNeedsLayoutAndPrefWidthsRecalc();
84 }
85
86 void RenderTableCol::insertedIntoTree()
87 {
88     RenderBox::insertedIntoTree();
89     table()->addColumn(this);
90 }
91
92 void RenderTableCol::willBeRemovedFromTree()
93 {
94     RenderBox::willBeRemovedFromTree();
95     table()->removeColumn(this);
96 }
97
98 bool RenderTableCol::isChildAllowed(const RenderObject& child, const RenderStyle& style) const
99 {
100     // We cannot use isTableColumn here as style() may return 0.
101     return style.display() == TABLE_COLUMN && child.isRenderTableCol();
102 }
103
104 bool RenderTableCol::canHaveChildren() const
105 {
106     // Cols cannot have children. This is actually necessary to fix a bug
107     // with libraries.uc.edu, which makes a <p> be a table-column.
108     return isTableColumnGroup();
109 }
110
111 LayoutRect RenderTableCol::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
112 {
113     // For now, just repaint the whole table.
114     // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
115     // might have propagated a background color or borders into.
116     // FIXME: check for repaintContainer each time here?
117
118     RenderTable* parentTable = table();
119     if (!parentTable)
120         return LayoutRect();
121     return parentTable->clippedOverflowRectForRepaint(repaintContainer);
122 }
123
124 void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*)
125 {
126     // FIXME: Repaint only the rect the image paints in.
127     repaint();
128 }
129
130 void RenderTableCol::clearPreferredLogicalWidthsDirtyBits()
131 {
132     setPreferredLogicalWidthsDirty(false);
133
134     for (RenderObject* child = firstChild(); child; child = child->nextSibling())
135         child->setPreferredLogicalWidthsDirty(false);
136 }
137
138 RenderTable* RenderTableCol::table() const
139 {
140     auto table = parent();
141     if (table && !is<RenderTable>(*table))
142         table = table->parent();
143     return is<RenderTable>(table) ? downcast<RenderTable>(table) : nullptr;
144 }
145
146 RenderTableCol* RenderTableCol::enclosingColumnGroup() const
147 {
148     if (!is<RenderTableCol>(*parent()))
149         return nullptr;
150
151     RenderTableCol& parentColumnGroup = downcast<RenderTableCol>(*parent());
152     ASSERT(parentColumnGroup.isTableColumnGroup());
153     ASSERT(isTableColumn());
154     return &parentColumnGroup;
155 }
156
157 RenderTableCol* RenderTableCol::nextColumn() const
158 {
159     // If |this| is a column-group, the next column is the colgroup's first child column.
160     if (RenderObject* firstChild = this->firstChild())
161         return downcast<RenderTableCol>(firstChild);
162
163     // Otherwise it's the next column along.
164     RenderObject* next = nextSibling();
165
166     // 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.
167     if (!next && is<RenderTableCol>(*parent()))
168         next = parent()->nextSibling();
169
170     for (; next && !is<RenderTableCol>(*next); next = next->nextSibling()) {
171         // We allow captions mixed with columns and column-groups.
172         if (is<RenderTableCaption>(*next))
173             continue;
174
175         return nullptr;
176     }
177
178     return downcast<RenderTableCol>(next);
179 }
180
181 const BorderValue& RenderTableCol::borderAdjoiningCellStartBorder(const RenderTableCell*) const
182 {
183     return style().borderStart();
184 }
185
186 const BorderValue& RenderTableCol::borderAdjoiningCellEndBorder(const RenderTableCell*) const
187 {
188     return style().borderEnd();
189 }
190
191 const BorderValue& RenderTableCol::borderAdjoiningCellBefore(const RenderTableCell* cell) const
192 {
193     ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()) == this);
194     return style().borderStart();
195 }
196
197 const BorderValue& RenderTableCol::borderAdjoiningCellAfter(const RenderTableCell* cell) const
198 {
199     ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1) == this);
200     return style().borderEnd();
201 }
202
203 LayoutUnit RenderTableCol::offsetLeft() const
204 {
205     return table()->offsetLeftForColumn(*this);
206 }
207
208 LayoutUnit RenderTableCol::offsetTop() const
209 {
210     return table()->offsetTopForColumn(*this);
211 }
212
213 LayoutUnit RenderTableCol::offsetWidth() const
214 {
215     return table()->offsetWidthForColumn(*this);
216 }
217
218 LayoutUnit RenderTableCol::offsetHeight() const
219 {
220     return table()->offsetHeightForColumn(*this);
221 }
222
223 }