1 /* 2 * Copyright (C) 1997 Martin Jones (mjones (at) kde.org) 3 * (C) 1997 Torben Weis (weis (at) kde.org) 4 * (C) 1998 Waldo Bastian (bastian (at) kde.org) 5 * (C) 1999 Lars Knoll (knoll (at) kde.org) 6 * (C) 1999 Antti Koivisto (koivisto (at) 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 "core/html/HTMLTableCellElement.h" 27 28 #include "CSSPropertyNames.h" 29 #include "CSSValueKeywords.h" 30 #include "HTMLNames.h" 31 #include "core/dom/Attribute.h" 32 #include "core/html/HTMLTableElement.h" 33 #include "core/rendering/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 45 inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName, Document* document) 46 : HTMLTablePartElement(tagName, document) 47 { 48 ScriptWrappable::init(this); 49 } 50 51 PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document* document) 52 { 53 return adoptRef(new HTMLTableCellElement(tagName, document)); 54 } 55 56 int HTMLTableCellElement::colSpan() const 57 { 58 const AtomicString& colSpanValue = fastGetAttribute(colspanAttr); 59 return max(1, colSpanValue.toInt()); 60 } 61 62 int HTMLTableCellElement::rowSpan() const 63 { 64 const AtomicString& rowSpanValue = fastGetAttribute(rowspanAttr); 65 return max(1, min(rowSpanValue.toInt(), maxRowspan)); 66 } 67 68 int HTMLTableCellElement::cellIndex() const 69 { 70 int index = 0; 71 if (!parentElement() || !parentElement()->hasTagName(trTag)) 72 return -1; 73 74 for (const Node * node = previousSibling(); node; node = node->previousSibling()) { 75 if (node->hasTagName(tdTag) || node->hasTagName(thTag)) 76 index++; 77 } 78 79 return index; 80 } 81 82 bool HTMLTableCellElement::isPresentationAttribute(const QualifiedName& name) const 83 { 84 if (name == nowrapAttr || name == widthAttr || name == heightAttr) 85 return true; 86 return HTMLTablePartElement::isPresentationAttribute(name); 87 } 88 89 void HTMLTableCellElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) 90 { 91 if (name == nowrapAttr) 92 addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValueWebkitNowrap); 93 else if (name == widthAttr) { 94 if (!value.isEmpty()) { 95 int widthInt = value.toInt(); 96 if (widthInt > 0) // width="0" is ignored for compatibility with WinIE. 97 addHTMLLengthToStyle(style, CSSPropertyWidth, value); 98 } 99 } else if (name == heightAttr) { 100 if (!value.isEmpty()) { 101 int heightInt = value.toInt(); 102 if (heightInt > 0) // height="0" is ignored for compatibility with WinIE. 103 addHTMLLengthToStyle(style, CSSPropertyHeight, value); 104 } 105 } else 106 HTMLTablePartElement::collectStyleForPresentationAttribute(name, value, style); 107 } 108 109 void HTMLTableCellElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 110 { 111 if (name == rowspanAttr) { 112 if (renderer() && renderer()->isTableCell()) 113 toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); 114 } else if (name == colspanAttr) { 115 if (renderer() && renderer()->isTableCell()) 116 toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); 117 } else 118 HTMLTablePartElement::parseAttribute(name, value); 119 } 120 121 const StylePropertySet* HTMLTableCellElement::additionalPresentationAttributeStyle() 122 { 123 if (HTMLTableElement* table = findParentTable()) 124 return table->additionalCellStyle(); 125 return 0; 126 } 127 128 bool HTMLTableCellElement::isURLAttribute(const Attribute& attribute) const 129 { 130 return attribute.name() == backgroundAttr || HTMLTablePartElement::isURLAttribute(attribute); 131 } 132 133 String HTMLTableCellElement::abbr() const 134 { 135 return getAttribute(abbrAttr); 136 } 137 138 String HTMLTableCellElement::axis() const 139 { 140 return getAttribute(axisAttr); 141 } 142 143 void HTMLTableCellElement::setColSpan(int n) 144 { 145 setAttribute(colspanAttr, String::number(n)); 146 } 147 148 String HTMLTableCellElement::headers() const 149 { 150 return getAttribute(headersAttr); 151 } 152 153 void HTMLTableCellElement::setRowSpan(int n) 154 { 155 setAttribute(rowspanAttr, String::number(n)); 156 } 157 158 String HTMLTableCellElement::scope() const 159 { 160 return getAttribute(scopeAttr); 161 } 162 163 void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const 164 { 165 HTMLTablePartElement::addSubresourceAttributeURLs(urls); 166 167 addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr))); 168 } 169 170 HTMLTableCellElement* HTMLTableCellElement::cellAbove() const 171 { 172 RenderObject* cellRenderer = renderer(); 173 if (!cellRenderer) 174 return 0; 175 if (!cellRenderer->isTableCell()) 176 return 0; 177 178 RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer); 179 RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer); 180 if (!cellAboveRenderer) 181 return 0; 182 183 return static_cast<HTMLTableCellElement*>(cellAboveRenderer->node()); 184 } 185 186 #ifndef NDEBUG 187 188 HTMLTableCellElement* toHTMLTableCellElement(Node* node) 189 { 190 ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(HTMLNames::tdTag) || node->hasTagName(HTMLNames::thTag)); 191 return static_cast<HTMLTableCellElement*>(node); 192 } 193 194 const HTMLTableCellElement* toHTMLTableCellElement(const Node* node) 195 { 196 ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(HTMLNames::tdTag) || node->hasTagName(HTMLNames::thTag)); 197 return static_cast<const HTMLTableCellElement*>(node); 198 } 199 200 #endif 201 202 } // namespace WebCore 203