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, 2010 Apple Inc. All rights reserved.
8 *
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
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 #include "config.h"
26 #include "HTMLTableCellElement.h"
27
28 #include "Attribute.h"
29 #include "CSSPropertyNames.h"
30 #include "CSSValueKeywords.h"
31 #include "HTMLNames.h"
32 #include "HTMLTableElement.h"
33 #include "RenderTableCell.h"
34
35 using std::max;
36 using std::min;
37
38 namespace WebCore {
39
40 // Clamp rowspan at 8k to match Firefox.
41 static const int maxRowspan = 8190;
42
43 using namespace HTMLNames;
44
HTMLTableCellElement(const QualifiedName & tagName,Document * document)45 inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName, Document* document)
46 : HTMLTablePartElement(tagName, document)
47 , m_rowSpan(1)
48 , m_colSpan(1)
49 {
50 }
51
create(const QualifiedName & tagName,Document * document)52 PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document* document)
53 {
54 return adoptRef(new HTMLTableCellElement(tagName, document));
55 }
56
cellIndex() const57 int HTMLTableCellElement::cellIndex() const
58 {
59 int index = 0;
60 for (const Node * node = previousSibling(); node; node = node->previousSibling()) {
61 if (node->hasTagName(tdTag) || node->hasTagName(thTag))
62 index++;
63 }
64
65 return index;
66 }
67
mapToEntry(const QualifiedName & attrName,MappedAttributeEntry & result) const68 bool HTMLTableCellElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
69 {
70 if (attrName == nowrapAttr) {
71 result = eUniversal;
72 return false;
73 }
74
75 if (attrName == widthAttr ||
76 attrName == heightAttr) {
77 result = eCell; // Because of the quirky behavior of ignoring 0 values, cells are special.
78 return false;
79 }
80
81 return HTMLTablePartElement::mapToEntry(attrName, result);
82 }
83
parseMappedAttribute(Attribute * attr)84 void HTMLTableCellElement::parseMappedAttribute(Attribute* attr)
85 {
86 if (attr->name() == rowspanAttr) {
87 m_rowSpan = max(1, min(attr->value().toInt(), maxRowspan));
88 if (renderer() && renderer()->isTableCell())
89 toRenderTableCell(renderer())->updateFromElement();
90 } else if (attr->name() == colspanAttr) {
91 m_colSpan = max(1, attr->value().toInt());
92 if (renderer() && renderer()->isTableCell())
93 toRenderTableCell(renderer())->updateFromElement();
94 } else if (attr->name() == nowrapAttr) {
95 if (!attr->isNull())
96 addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueWebkitNowrap);
97 } else if (attr->name() == widthAttr) {
98 if (!attr->value().isEmpty()) {
99 int widthInt = attr->value().toInt();
100 if (widthInt > 0) // width="0" is ignored for compatibility with WinIE.
101 addCSSLength(attr, CSSPropertyWidth, attr->value());
102 }
103 } else if (attr->name() == heightAttr) {
104 if (!attr->value().isEmpty()) {
105 int heightInt = attr->value().toInt();
106 if (heightInt > 0) // height="0" is ignored for compatibility with WinIE.
107 addCSSLength(attr, CSSPropertyHeight, attr->value());
108 }
109 } else
110 HTMLTablePartElement::parseMappedAttribute(attr);
111 }
112
113 // used by table cells to share style decls created by the enclosing table.
additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration * > & results)114 void HTMLTableCellElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
115 {
116 ContainerNode* p = parentNode();
117 while (p && !p->hasTagName(tableTag))
118 p = p->parentNode();
119 if (!p)
120 return;
121 static_cast<HTMLTableElement*>(p)->addSharedCellDecls(results);
122 }
123
isURLAttribute(Attribute * attr) const124 bool HTMLTableCellElement::isURLAttribute(Attribute *attr) const
125 {
126 return attr->name() == backgroundAttr;
127 }
128
abbr() const129 String HTMLTableCellElement::abbr() const
130 {
131 return getAttribute(abbrAttr);
132 }
133
axis() const134 String HTMLTableCellElement::axis() const
135 {
136 return getAttribute(axisAttr);
137 }
138
setColSpan(int n)139 void HTMLTableCellElement::setColSpan(int n)
140 {
141 setAttribute(colspanAttr, String::number(n));
142 }
143
headers() const144 String HTMLTableCellElement::headers() const
145 {
146 return getAttribute(headersAttr);
147 }
148
setRowSpan(int n)149 void HTMLTableCellElement::setRowSpan(int n)
150 {
151 setAttribute(rowspanAttr, String::number(n));
152 }
153
scope() const154 String HTMLTableCellElement::scope() const
155 {
156 return getAttribute(scopeAttr);
157 }
158
addSubresourceAttributeURLs(ListHashSet<KURL> & urls) const159 void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
160 {
161 HTMLTablePartElement::addSubresourceAttributeURLs(urls);
162
163 addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr)));
164 }
165
cellAbove() const166 HTMLTableCellElement* HTMLTableCellElement::cellAbove() const
167 {
168 RenderObject* cellRenderer = renderer();
169 if (!cellRenderer)
170 return 0;
171 if (!cellRenderer->isTableCell())
172 return 0;
173
174 RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer);
175 RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer);
176 if (!cellAboveRenderer)
177 return 0;
178
179 return static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
180 }
181
182 } // namespace WebCore
183