blob: 61297f0bff1af4a37c577383470008e4bd10b0fc [file] [log] [blame]
darin@apple.comeb701802008-01-03 01:25:51 +00001/*
eseidel787da6b2006-05-12 19:44:03 +00002 * 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)
kling@webkit.orge72793e2011-12-24 21:24:59 +00007 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010, 2011 Apple Inc. All rights reserved.
eseidel787da6b2006-05-12 19:44:03 +00008 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
ddkilzerc8eccec2007-09-26 02:29:57 +000021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
eseidel787da6b2006-05-12 19:44:03 +000023 */
darin@apple.comeb701802008-01-03 01:25:51 +000024
eseidel787da6b2006-05-12 19:44:03 +000025#include "config.h"
26#include "HTMLTableElement.h"
27
weinig@apple.comc3608932010-05-19 17:48:06 +000028#include "Attribute.h"
kling@webkit.org8b0e8432012-02-11 19:29:49 +000029#include "CSSImageValue.h"
eseidel787da6b2006-05-12 19:44:03 +000030#include "CSSPropertyNames.h"
eseidel787da6b2006-05-12 19:44:03 +000031#include "CSSValueKeywords.h"
kling@webkit.org2340d5e2012-02-25 17:43:32 +000032#include "CSSValuePool.h"
eseidel787da6b2006-05-12 19:44:03 +000033#include "ExceptionCode.h"
mkwst@chromium.org33cdf432013-02-08 14:21:48 +000034#include "ExceptionCodePlaceholder.h"
eseidel787da6b2006-05-12 19:44:03 +000035#include "HTMLNames.h"
darin@apple.com7b7981b2010-10-01 00:04:02 +000036#include "HTMLParserIdioms.h"
eseidel787da6b2006-05-12 19:44:03 +000037#include "HTMLTableCaptionElement.h"
darin@apple.comeb701802008-01-03 01:25:51 +000038#include "HTMLTableRowElement.h"
darin@apple.com9a925fa2009-05-04 18:00:34 +000039#include "HTMLTableRowsCollection.h"
eseidel787da6b2006-05-12 19:44:03 +000040#include "HTMLTableSectionElement.h"
41#include "RenderTable.h"
akling@apple.com179f7df2013-02-25 15:49:25 +000042#include "StylePropertySet.h"
akling@apple.comf8515982013-09-02 18:50:01 +000043#include <wtf/Ref.h>
eseidel787da6b2006-05-12 19:44:03 +000044
45namespace WebCore {
46
47using namespace HTMLNames;
48
weinig@apple.com49178832013-09-15 00:39:29 +000049HTMLTableElement::HTMLTableElement(const QualifiedName& tagName, Document& document)
weinig@apple.comdedf67e2013-09-15 05:23:01 +000050 : HTMLElement(tagName, document)
hyatteef21e02006-09-17 07:57:56 +000051 , m_borderAttr(false)
52 , m_borderColorAttr(false)
53 , m_frameAttr(false)
54 , m_rulesAttr(UnsetRules)
55 , m_padding(1)
eseidel787da6b2006-05-12 19:44:03 +000056{
jchaffraix@webkit.org94d95b02008-12-04 22:39:05 +000057 ASSERT(hasTagName(tableTag));
eseidel787da6b2006-05-12 19:44:03 +000058}
59
weinig@apple.com49178832013-09-15 00:39:29 +000060PassRefPtr<HTMLTableElement> HTMLTableElement::create(Document& document)
darin@apple.com877ce5b2010-05-28 15:38:58 +000061{
darin@apple.comf190b3d2010-06-16 23:07:32 +000062 return adoptRef(new HTMLTableElement(tableTag, document));
darin@apple.com877ce5b2010-05-28 15:38:58 +000063}
64
weinig@apple.com49178832013-09-15 00:39:29 +000065PassRefPtr<HTMLTableElement> HTMLTableElement::create(const QualifiedName& tagName, Document& document)
darin@apple.com877ce5b2010-05-28 15:38:58 +000066{
darin@apple.comf190b3d2010-06-16 23:07:32 +000067 return adoptRef(new HTMLTableElement(tagName, document));
darin@apple.com877ce5b2010-05-28 15:38:58 +000068}
69
darin@apple.comeb701802008-01-03 01:25:51 +000070HTMLTableCaptionElement* HTMLTableElement::caption() const
eseidel787da6b2006-05-12 19:44:03 +000071{
darin@apple.comeb701802008-01-03 01:25:51 +000072 for (Node* child = firstChild(); child; child = child->nextSibling()) {
73 if (child->hasTagName(captionTag))
gyuyoung.kim@samsung.comb86fc582013-11-21 04:45:49 +000074 return toHTMLTableCaptionElement(child);
eseidel787da6b2006-05-12 19:44:03 +000075 }
darin@apple.comeb701802008-01-03 01:25:51 +000076 return 0;
77}
78
79void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionCode& ec)
80{
81 deleteCaption();
82 insertBefore(newCaption, firstChild(), ec);
83}
84
85HTMLTableSectionElement* HTMLTableElement::tHead() const
86{
87 for (Node* child = firstChild(); child; child = child->nextSibling()) {
88 if (child->hasTagName(theadTag))
commit-queue@webkit.orga8be4192013-11-20 18:26:34 +000089 return static_cast<HTMLTableSectionElement*>(child);
darin@apple.comeb701802008-01-03 01:25:51 +000090 }
91 return 0;
92}
93
94void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionCode& ec)
95{
96 deleteTHead();
97
98 Node* child;
99 for (child = firstChild(); child; child = child->nextSibling())
100 if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
101 break;
102
103 insertBefore(newHead, child, ec);
104}
105
106HTMLTableSectionElement* HTMLTableElement::tFoot() const
107{
108 for (Node* child = firstChild(); child; child = child->nextSibling()) {
109 if (child->hasTagName(tfootTag))
commit-queue@webkit.orga8be4192013-11-20 18:26:34 +0000110 return static_cast<HTMLTableSectionElement*>(child);
darin@apple.comeb701802008-01-03 01:25:51 +0000111 }
112 return 0;
113}
114
115void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionCode& ec)
116{
117 deleteTFoot();
118
119 Node* child;
120 for (child = firstChild(); child; child = child->nextSibling())
121 if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
122 break;
123
124 insertBefore(newFoot, child, ec);
125}
126
127PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
128{
129 if (HTMLTableSectionElement* existingHead = tHead())
130 return existingHead;
weinig@apple.com49178832013-09-15 00:39:29 +0000131 RefPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000132 setTHead(head, IGNORE_EXCEPTION);
darin@apple.comeb701802008-01-03 01:25:51 +0000133 return head.release();
eseidel787da6b2006-05-12 19:44:03 +0000134}
135
136void HTMLTableElement::deleteTHead()
137{
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000138 removeChild(tHead(), IGNORE_EXCEPTION);
eseidel787da6b2006-05-12 19:44:03 +0000139}
140
darin@apple.comeb701802008-01-03 01:25:51 +0000141PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
eseidel787da6b2006-05-12 19:44:03 +0000142{
darin@apple.comeb701802008-01-03 01:25:51 +0000143 if (HTMLTableSectionElement* existingFoot = tFoot())
144 return existingFoot;
weinig@apple.com49178832013-09-15 00:39:29 +0000145 RefPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000146 setTFoot(foot, IGNORE_EXCEPTION);
darin@apple.comeb701802008-01-03 01:25:51 +0000147 return foot.release();
eseidel787da6b2006-05-12 19:44:03 +0000148}
149
150void HTMLTableElement::deleteTFoot()
151{
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000152 removeChild(tFoot(), IGNORE_EXCEPTION);
eseidel787da6b2006-05-12 19:44:03 +0000153}
154
alexis.menard@openbossa.org83fc9ae2012-04-25 02:11:26 +0000155PassRefPtr<HTMLElement> HTMLTableElement::createTBody()
156{
weinig@apple.com49178832013-09-15 00:39:29 +0000157 RefPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
alexis.menard@openbossa.org83fc9ae2012-04-25 02:11:26 +0000158 Node* referenceElement = lastBody() ? lastBody()->nextSibling() : 0;
159 insertBefore(body, referenceElement, ASSERT_NO_EXCEPTION);
160 return body.release();
161}
162
darin@apple.comeb701802008-01-03 01:25:51 +0000163PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
eseidel787da6b2006-05-12 19:44:03 +0000164{
darin@apple.comeb701802008-01-03 01:25:51 +0000165 if (HTMLTableCaptionElement* existingCaption = caption())
166 return existingCaption;
weinig@apple.com6becaaf2013-09-14 21:33:13 +0000167 RefPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(captionTag, document());
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000168 setCaption(caption, IGNORE_EXCEPTION);
darin@apple.comeb701802008-01-03 01:25:51 +0000169 return caption.release();
eseidel787da6b2006-05-12 19:44:03 +0000170}
171
172void HTMLTableElement::deleteCaption()
173{
mkwst@chromium.org33cdf432013-02-08 14:21:48 +0000174 removeChild(caption(), IGNORE_EXCEPTION);
darin@apple.comeb701802008-01-03 01:25:51 +0000175}
176
177HTMLTableSectionElement* HTMLTableElement::lastBody() const
178{
179 for (Node* child = lastChild(); child; child = child->previousSibling()) {
180 if (child->hasTagName(tbodyTag))
commit-queue@webkit.orga8be4192013-11-20 18:26:34 +0000181 return static_cast<HTMLTableSectionElement*>(child);
eseidel787da6b2006-05-12 19:44:03 +0000182 }
darin@apple.comeb701802008-01-03 01:25:51 +0000183 return 0;
eseidel787da6b2006-05-12 19:44:03 +0000184}
185
darinf0d19342007-05-01 19:59:53 +0000186PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec)
eseidel787da6b2006-05-12 19:44:03 +0000187{
darin@apple.comeb701802008-01-03 01:25:51 +0000188 if (index < -1) {
eseidel787da6b2006-05-12 19:44:03 +0000189 ec = INDEX_SIZE_ERR;
darinf0d19342007-05-01 19:59:53 +0000190 return 0;
eseidel787da6b2006-05-12 19:44:03 +0000191 }
darin@apple.comeb701802008-01-03 01:25:51 +0000192
akling@apple.comf8515982013-09-02 18:50:01 +0000193 Ref<HTMLTableElement> protectFromMutationEvents(*this);
inferno@chromium.org50a2ce72012-03-01 18:19:03 +0000194
195 RefPtr<HTMLTableRowElement> lastRow = 0;
196 RefPtr<HTMLTableRowElement> row = 0;
darin@apple.comeb701802008-01-03 01:25:51 +0000197 if (index == -1)
198 lastRow = HTMLTableRowsCollection::lastRow(this);
199 else {
200 for (int i = 0; i <= index; ++i) {
inferno@chromium.org50a2ce72012-03-01 18:19:03 +0000201 row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
darin@apple.comeb701802008-01-03 01:25:51 +0000202 if (!row) {
203 if (i != index) {
204 ec = INDEX_SIZE_ERR;
205 return 0;
206 }
207 break;
208 }
209 lastRow = row;
210 }
211 }
212
inferno@chromium.org50a2ce72012-03-01 18:19:03 +0000213 RefPtr<ContainerNode> parent;
darin@apple.comeb701802008-01-03 01:25:51 +0000214 if (lastRow)
dglazkov@chromium.orge43caa72010-11-18 00:20:10 +0000215 parent = row ? row->parentNode() : lastRow->parentNode();
darin@apple.comeb701802008-01-03 01:25:51 +0000216 else {
217 parent = lastBody();
218 if (!parent) {
weinig@apple.com49178832013-09-15 00:39:29 +0000219 RefPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
220 RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
darin@apple.comeb701802008-01-03 01:25:51 +0000221 newBody->appendChild(newRow, ec);
222 appendChild(newBody.release(), ec);
223 return newRow.release();
224 }
225 }
226
weinig@apple.com49178832013-09-15 00:39:29 +0000227 RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
inferno@chromium.org50a2ce72012-03-01 18:19:03 +0000228 parent->insertBefore(newRow, row.get(), ec);
darin@apple.comeb701802008-01-03 01:25:51 +0000229 return newRow.release();
eseidel787da6b2006-05-12 19:44:03 +0000230}
231
232void HTMLTableElement::deleteRow(int index, ExceptionCode& ec)
233{
darin@apple.comeb701802008-01-03 01:25:51 +0000234 HTMLTableRowElement* row = 0;
235 if (index == -1)
236 row = HTMLTableRowsCollection::lastRow(this);
237 else {
238 for (int i = 0; i <= index; ++i) {
239 row = HTMLTableRowsCollection::rowAfter(this, row);
240 if (!row)
241 break;
eseidel787da6b2006-05-12 19:44:03 +0000242 }
eseidel787da6b2006-05-12 19:44:03 +0000243 }
darin@apple.comeb701802008-01-03 01:25:51 +0000244 if (!row) {
eseidel787da6b2006-05-12 19:44:03 +0000245 ec = INDEX_SIZE_ERR;
darin@apple.comeb701802008-01-03 01:25:51 +0000246 return;
247 }
248 row->remove(ec);
eseidel787da6b2006-05-12 19:44:03 +0000249}
250
rwlbuisda67f4e2007-08-25 16:57:13 +0000251static inline bool isTableCellAncestor(Node* n)
252{
253 return n->hasTagName(theadTag) || n->hasTagName(tbodyTag) ||
254 n->hasTagName(tfootTag) || n->hasTagName(trTag) ||
255 n->hasTagName(thTag);
256}
257
258static bool setTableCellsChanged(Node* n)
259{
260 ASSERT(n);
261 bool cellChanged = false;
262
263 if (n->hasTagName(tdTag))
264 cellChanged = true;
265 else if (isTableCellAncestor(n)) {
266 for (Node* child = n->firstChild(); child; child = child->nextSibling())
267 cellChanged |= setTableCellsChanged(child);
268 }
269
270 if (cellChanged)
hyatt@apple.comf6d72f32009-04-10 00:05:02 +0000271 n->setNeedsStyleRecalc();
rwlbuisda67f4e2007-08-25 16:57:13 +0000272
273 return cellChanged;
274}
275
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000276static bool getBordersFromFrameAttributeValue(const AtomicString& value, bool& borderTop, bool& borderRight, bool& borderBottom, bool& borderLeft)
277{
278 borderTop = false;
279 borderRight = false;
280 borderBottom = false;
281 borderLeft = false;
282
283 if (equalIgnoringCase(value, "above"))
284 borderTop = true;
285 else if (equalIgnoringCase(value, "below"))
286 borderBottom = true;
287 else if (equalIgnoringCase(value, "hsides"))
288 borderTop = borderBottom = true;
289 else if (equalIgnoringCase(value, "vsides"))
290 borderLeft = borderRight = true;
291 else if (equalIgnoringCase(value, "lhs"))
292 borderLeft = true;
293 else if (equalIgnoringCase(value, "rhs"))
294 borderRight = true;
295 else if (equalIgnoringCase(value, "box") || equalIgnoringCase(value, "border"))
296 borderTop = borderBottom = borderLeft = borderRight = true;
297 else if (!equalIgnoringCase(value, "void"))
298 return false;
299 return true;
300}
301
weinig@apple.comac1cc352013-11-09 03:24:55 +0000302void HTMLTableElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet& style)
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000303{
akling@apple.comb75eeea2013-02-23 17:57:50 +0000304 if (name == widthAttr)
305 addHTMLLengthToStyle(style, CSSPropertyWidth, value);
306 else if (name == heightAttr)
307 addHTMLLengthToStyle(style, CSSPropertyHeight, value);
308 else if (name == borderAttr)
309 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, parseBorderWidthAttribute(value), CSSPrimitiveValue::CSS_PX);
310 else if (name == bordercolorAttr) {
311 if (!value.isEmpty())
312 addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
313 } else if (name == bgcolorAttr)
314 addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
315 else if (name == backgroundAttr) {
316 String url = stripLeadingAndTrailingHTMLSpaces(value);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000317 if (!url.isEmpty())
weinig@apple.comac1cc352013-11-09 03:24:55 +0000318 style.setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url).string())));
akling@apple.comb75eeea2013-02-23 17:57:50 +0000319 } else if (name == valignAttr) {
320 if (!value.isEmpty())
321 addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, value);
322 } else if (name == cellspacingAttr) {
323 if (!value.isEmpty())
324 addHTMLLengthToStyle(style, CSSPropertyBorderSpacing, value);
325 } else if (name == vspaceAttr) {
326 addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
327 addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
328 } else if (name == hspaceAttr) {
329 addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
330 addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
331 } else if (name == alignAttr) {
332 if (!value.isEmpty()) {
333 if (equalIgnoringCase(value, "center")) {
kling@webkit.org569556d2012-11-12 23:52:12 +0000334 addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitMarginStart, CSSValueAuto);
335 addPropertyToPresentationAttributeStyle(style, CSSPropertyWebkitMarginEnd, CSSValueAuto);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000336 } else
akling@apple.comb75eeea2013-02-23 17:57:50 +0000337 addPropertyToPresentationAttributeStyle(style, CSSPropertyFloat, value);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000338 }
akling@apple.comb75eeea2013-02-23 17:57:50 +0000339 } else if (name == rulesAttr) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000340 // The presence of a valid rules attribute causes border collapsing to be enabled.
341 if (m_rulesAttr != UnsetRules)
kling@webkit.org569556d2012-11-12 23:52:12 +0000342 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderCollapse, CSSValueCollapse);
akling@apple.comb75eeea2013-02-23 17:57:50 +0000343 } else if (name == frameAttr) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000344 bool borderTop;
345 bool borderRight;
346 bool borderBottom;
347 bool borderLeft;
akling@apple.comb75eeea2013-02-23 17:57:50 +0000348 if (getBordersFromFrameAttributeValue(value, borderTop, borderRight, borderBottom, borderLeft)) {
kling@webkit.org569556d2012-11-12 23:52:12 +0000349 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, CSSValueThin);
350 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopStyle, borderTop ? CSSValueSolid : CSSValueHidden);
351 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomStyle, borderBottom ? CSSValueSolid : CSSValueHidden);
352 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderLeftStyle, borderLeft ? CSSValueSolid : CSSValueHidden);
353 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightStyle, borderRight ? CSSValueSolid : CSSValueHidden);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000354 }
355 } else
akling@apple.comb75eeea2013-02-23 17:57:50 +0000356 HTMLElement::collectStyleForPresentationAttribute(name, value, style);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000357}
358
kling@webkit.org44bc0dd2012-02-28 22:21:02 +0000359bool HTMLTableElement::isPresentationAttribute(const QualifiedName& name) const
kling@webkit.org11f25562012-02-13 10:36:55 +0000360{
kling@webkit.org44bc0dd2012-02-28 22:21:02 +0000361 if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == backgroundAttr || name == valignAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr || name == cellspacingAttr || name == borderAttr || name == bordercolorAttr || name == frameAttr || name == rulesAttr)
kling@webkit.org11f25562012-02-13 10:36:55 +0000362 return true;
kling@webkit.org44bc0dd2012-02-28 22:21:02 +0000363 return HTMLElement::isPresentationAttribute(name);
kling@webkit.org11f25562012-02-13 10:36:55 +0000364}
365
akling@apple.com43e9d042012-11-18 16:55:06 +0000366void HTMLTableElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
eseidel787da6b2006-05-12 19:44:03 +0000367{
darin@apple.com12304112008-01-04 01:17:05 +0000368 CellBorders bordersBefore = cellBorders();
hyatt@apple.comcd9e4092008-01-18 21:56:31 +0000369 unsigned short oldPadding = m_padding;
370
akling@apple.com43e9d042012-11-18 16:55:06 +0000371 if (name == borderAttr) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000372 // FIXME: This attribute is a mess.
akling@apple.comb75eeea2013-02-23 17:57:50 +0000373 m_borderAttr = parseBorderWidthAttribute(value);
akling@apple.com43e9d042012-11-18 16:55:06 +0000374 } else if (name == bordercolorAttr) {
375 m_borderColorAttr = !value.isEmpty();
376 } else if (name == frameAttr) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000377 // FIXME: This attribute is a mess.
378 bool borderTop;
379 bool borderRight;
380 bool borderBottom;
381 bool borderLeft;
akling@apple.com43e9d042012-11-18 16:55:06 +0000382 m_frameAttr = getBordersFromFrameAttributeValue(value, borderTop, borderRight, borderBottom, borderLeft);
383 } else if (name == rulesAttr) {
hyatteef21e02006-09-17 07:57:56 +0000384 m_rulesAttr = UnsetRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000385 if (equalIgnoringCase(value, "none"))
hyatteef21e02006-09-17 07:57:56 +0000386 m_rulesAttr = NoneRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000387 else if (equalIgnoringCase(value, "groups"))
hyatteef21e02006-09-17 07:57:56 +0000388 m_rulesAttr = GroupsRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000389 else if (equalIgnoringCase(value, "rows"))
hyatteef21e02006-09-17 07:57:56 +0000390 m_rulesAttr = RowsRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000391 else if (equalIgnoringCase(value, "cols"))
hyatteef21e02006-09-17 07:57:56 +0000392 m_rulesAttr = ColsRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000393 else if (equalIgnoringCase(value, "all"))
hyatteef21e02006-09-17 07:57:56 +0000394 m_rulesAttr = AllRules;
akling@apple.com43e9d042012-11-18 16:55:06 +0000395 } else if (name == cellpaddingAttr) {
396 if (!value.isEmpty())
andersca@apple.comff9adb82013-10-25 01:15:36 +0000397 m_padding = std::max(0, value.toInt());
eseidel787da6b2006-05-12 19:44:03 +0000398 else
hyatteef21e02006-09-17 07:57:56 +0000399 m_padding = 1;
akling@apple.com43e9d042012-11-18 16:55:06 +0000400 } else if (name == colsAttr) {
eseidel787da6b2006-05-12 19:44:03 +0000401 // ###
eseidel787da6b2006-05-12 19:44:03 +0000402 } else
akling@apple.com43e9d042012-11-18 16:55:06 +0000403 HTMLElement::parseAttribute(name, value);
darin@apple.com12304112008-01-04 01:17:05 +0000404
hyatt@apple.comcd9e4092008-01-18 21:56:31 +0000405 if (bordersBefore != cellBorders() || oldPadding != m_padding) {
kling@webkit.org854221b2012-01-26 19:02:27 +0000406 m_sharedCellStyle = 0;
darin@apple.com12304112008-01-04 01:17:05 +0000407 bool cellChanged = false;
408 for (Node* child = firstChild(); child; child = child->nextSibling())
409 cellChanged |= setTableCellsChanged(child);
410 if (cellChanged)
hyatt@apple.comf6d72f32009-04-10 00:05:02 +0000411 setNeedsStyleRecalc();
darin@apple.com12304112008-01-04 01:17:05 +0000412 }
eseidel787da6b2006-05-12 19:44:03 +0000413}
414
alexis@webkit.org71873a02013-06-19 22:07:23 +0000415static StylePropertySet* leakBorderStyle(CSSValueID value)
kling@webkit.org854221b2012-01-26 19:02:27 +0000416{
akling@apple.com12907082013-04-14 14:24:46 +0000417 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
kling@webkit.org854221b2012-01-26 19:02:27 +0000418 style->setProperty(CSSPropertyBorderTopStyle, value);
419 style->setProperty(CSSPropertyBorderBottomStyle, value);
420 style->setProperty(CSSPropertyBorderLeftStyle, value);
421 style->setProperty(CSSPropertyBorderRightStyle, value);
422 return style.release().leakRef();
423}
424
kling@webkit.org569556d2012-11-12 23:52:12 +0000425const StylePropertySet* HTMLTableElement::additionalPresentationAttributeStyle()
eseidel787da6b2006-05-12 19:44:03 +0000426{
robert@webkit.orgceeb5dc2012-04-24 19:03:44 +0000427 if (m_frameAttr)
kling@webkit.org854221b2012-01-26 19:02:27 +0000428 return 0;
robert@webkit.orgceeb5dc2012-04-24 19:03:44 +0000429
430 if (!m_borderAttr && !m_borderColorAttr) {
431 // Setting the border to 'hidden' allows it to win over any border
432 // set on the table's cells during border-conflict resolution.
433 if (m_rulesAttr != UnsetRules) {
434 static StylePropertySet* solidBorderStyle = leakBorderStyle(CSSValueHidden);
435 return solidBorderStyle;
436 }
437 return 0;
438 }
darin@apple.com48ac3c42008-06-14 08:46:51 +0000439
kling@webkit.org854221b2012-01-26 19:02:27 +0000440 if (m_borderColorAttr) {
antti@apple.come89e04d2012-02-03 19:46:48 +0000441 static StylePropertySet* solidBorderStyle = leakBorderStyle(CSSValueSolid);
kling@webkit.org854221b2012-01-26 19:02:27 +0000442 return solidBorderStyle;
eseidel787da6b2006-05-12 19:44:03 +0000443 }
antti@apple.come89e04d2012-02-03 19:46:48 +0000444 static StylePropertySet* outsetBorderStyle = leakBorderStyle(CSSValueOutset);
kling@webkit.org854221b2012-01-26 19:02:27 +0000445 return outsetBorderStyle;
eseidel787da6b2006-05-12 19:44:03 +0000446}
447
darin@apple.com12304112008-01-04 01:17:05 +0000448HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
449{
450 switch (m_rulesAttr) {
451 case NoneRules:
452 case GroupsRules:
453 return NoBorders;
454 case AllRules:
455 return SolidBorders;
456 case ColsRules:
457 return SolidBordersColsOnly;
458 case RowsRules:
459 return SolidBordersRowsOnly;
460 case UnsetRules:
461 if (!m_borderAttr)
462 return NoBorders;
463 if (m_borderColorAttr)
464 return SolidBorders;
465 return InsetBorders;
466 }
467 ASSERT_NOT_REACHED();
468 return NoBorders;
469}
470
antti@apple.come89e04d2012-02-03 19:46:48 +0000471PassRefPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
hyatt@apple.comcd9e4092008-01-18 21:56:31 +0000472{
akling@apple.com12907082013-04-14 14:24:46 +0000473 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
hyatt@apple.comcd9e4092008-01-18 21:56:31 +0000474
kling@webkit.org854221b2012-01-26 19:02:27 +0000475 switch (cellBorders()) {
476 case SolidBordersColsOnly:
477 style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
478 style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
479 style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
480 style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
kling@webkit.orgb01b7972012-04-10 00:44:20 +0000481 style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
kling@webkit.org854221b2012-01-26 19:02:27 +0000482 break;
483 case SolidBordersRowsOnly:
484 style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
485 style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
486 style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
487 style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
kling@webkit.orgb01b7972012-04-10 00:44:20 +0000488 style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
kling@webkit.org854221b2012-01-26 19:02:27 +0000489 break;
490 case SolidBorders:
kling@webkit.orgb01b7972012-04-10 00:44:20 +0000491 style->setProperty(CSSPropertyBorderWidth, cssValuePool().createValue(1, CSSPrimitiveValue::CSS_PX));
492 style->setProperty(CSSPropertyBorderStyle, cssValuePool().createIdentifierValue(CSSValueSolid));
493 style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
kling@webkit.org854221b2012-01-26 19:02:27 +0000494 break;
495 case InsetBorders:
kling@webkit.orgb01b7972012-04-10 00:44:20 +0000496 style->setProperty(CSSPropertyBorderWidth, cssValuePool().createValue(1, CSSPrimitiveValue::CSS_PX));
497 style->setProperty(CSSPropertyBorderStyle, cssValuePool().createIdentifierValue(CSSValueInset));
498 style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
kling@webkit.org854221b2012-01-26 19:02:27 +0000499 break;
500 case NoBorders:
robert@webkit.orgf911cc32012-08-25 16:20:23 +0000501 // If 'rules=none' then allow any borders set at cell level to take effect.
kling@webkit.org854221b2012-01-26 19:02:27 +0000502 break;
eseidel787da6b2006-05-12 19:44:03 +0000503 }
kling@webkit.orge72793e2011-12-24 21:24:59 +0000504
kling@webkit.org2340d5e2012-02-25 17:43:32 +0000505 if (m_padding)
kling@webkit.orgb01b7972012-04-10 00:44:20 +0000506 style->setProperty(CSSPropertyPadding, cssValuePool().createValue(m_padding, CSSPrimitiveValue::CSS_PX));
kling@webkit.orge72793e2011-12-24 21:24:59 +0000507
kling@webkit.org854221b2012-01-26 19:02:27 +0000508 return style.release();
hyatt@apple.comcd9e4092008-01-18 21:56:31 +0000509}
510
kling@webkit.org513d26f2012-08-06 13:14:04 +0000511const StylePropertySet* HTMLTableElement::additionalCellStyle()
kling@webkit.org854221b2012-01-26 19:02:27 +0000512{
513 if (!m_sharedCellStyle)
514 m_sharedCellStyle = createSharedCellStyle();
kling@webkit.orgdc26b372012-02-09 07:14:55 +0000515 return m_sharedCellStyle.get();
kling@webkit.org854221b2012-01-26 19:02:27 +0000516}
517
antti@apple.come89e04d2012-02-03 19:46:48 +0000518static StylePropertySet* leakGroupBorderStyle(int rows)
kling@webkit.org854221b2012-01-26 19:02:27 +0000519{
akling@apple.com12907082013-04-14 14:24:46 +0000520 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
kling@webkit.org854221b2012-01-26 19:02:27 +0000521 if (rows) {
522 style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
523 style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
524 style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
525 style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
526 } else {
527 style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
528 style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
529 style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
530 style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
531 }
532 return style.release().leakRef();
533}
534
kling@webkit.org513d26f2012-08-06 13:14:04 +0000535const StylePropertySet* HTMLTableElement::additionalGroupStyle(bool rows)
hyatteef21e02006-09-17 07:57:56 +0000536{
537 if (m_rulesAttr != GroupsRules)
kling@webkit.org854221b2012-01-26 19:02:27 +0000538 return 0;
hyatteef21e02006-09-17 07:57:56 +0000539
kling@webkit.org854221b2012-01-26 19:02:27 +0000540 if (rows) {
antti@apple.come89e04d2012-02-03 19:46:48 +0000541 static StylePropertySet* rowBorderStyle = leakGroupBorderStyle(true);
kling@webkit.org854221b2012-01-26 19:02:27 +0000542 return rowBorderStyle;
hyatteef21e02006-09-17 07:57:56 +0000543 }
antti@apple.come89e04d2012-02-03 19:46:48 +0000544 static StylePropertySet* columnBorderStyle = leakGroupBorderStyle(false);
kling@webkit.org854221b2012-01-26 19:02:27 +0000545 return columnBorderStyle;
hyatteef21e02006-09-17 07:57:56 +0000546}
547
kling@webkit.orgd8a6d152012-05-08 16:27:04 +0000548bool HTMLTableElement::isURLAttribute(const Attribute& attribute) const
eseidel787da6b2006-05-12 19:44:03 +0000549{
kling@webkit.orgd8a6d152012-05-08 16:27:04 +0000550 return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
eseidel787da6b2006-05-12 19:44:03 +0000551}
552
rniwa@webkit.org4823cc12012-07-09 17:40:09 +0000553PassRefPtr<HTMLCollection> HTMLTableElement::rows()
eseidel787da6b2006-05-12 19:44:03 +0000554{
rniwa@webkit.org28acc312012-06-29 23:56:42 +0000555 return ensureCachedHTMLCollection(TableRows);
eseidel787da6b2006-05-12 19:44:03 +0000556}
557
rniwa@webkit.org4823cc12012-07-09 17:40:09 +0000558PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
eseidel787da6b2006-05-12 19:44:03 +0000559{
kling@webkit.orga3a65e32012-01-01 21:05:42 +0000560 return ensureCachedHTMLCollection(TableTBodies);
eseidel787da6b2006-05-12 19:44:03 +0000561}
562
eseidel787da6b2006-05-12 19:44:03 +0000563String HTMLTableElement::rules() const
564{
commit-queue@webkit.org03477c82011-09-02 17:07:51 +0000565 return getAttribute(rulesAttr);
eseidel787da6b2006-05-12 19:44:03 +0000566}
567
eseidel787da6b2006-05-12 19:44:03 +0000568String HTMLTableElement::summary() const
569{
commit-queue@webkit.org03477c82011-09-02 17:07:51 +0000570 return getAttribute(summaryAttr);
eseidel787da6b2006-05-12 19:44:03 +0000571}
572
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000573void HTMLTableElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
beidson@apple.coma4fb38f2008-03-27 04:08:17 +0000574{
commit-queue@webkit.orgbd9bc9a2012-05-30 20:50:31 +0000575 HTMLElement::addSubresourceAttributeURLs(urls);
ddkilzer@apple.come9a55042008-12-23 00:00:14 +0000576
akling@apple.com622b1a42013-08-30 14:30:12 +0000577 addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
beidson@apple.coma4fb38f2008-03-27 04:08:17 +0000578}
579
eseidel787da6b2006-05-12 19:44:03 +0000580}