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