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 "core/CSSPropertyNames.h" 29 #include "core/CSSValueKeywords.h" 30 #include "core/HTMLNames.h" 31 #include "core/dom/Attribute.h" 32 #include "core/dom/ElementTraversal.h" 33 #include "core/html/HTMLTableElement.h" 34 #include "core/rendering/RenderTableCell.h" 35 36 using std::max; 37 using std::min; 38 39 namespace blink { 40 41 // Clamp rowspan and colspan at 8k. 42 // Firefox used a limit of 8190 for rowspan but they changed it to 65,534. 43 // (FIXME: We should consider increasing this limit (crbug.com/78577). 44 // Firefox uses a limit of 1,000 for colspan and resets the value to 1 45 // but we don't discriminate between rowspan / colspan as it is artificial. 46 static const int maxColRowSpan = 8190; 47 48 using namespace HTMLNames; 49 50 inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName, Document& document) 51 : HTMLTablePartElement(tagName, document) 52 { 53 } 54 55 DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement) 56 57 int HTMLTableCellElement::colSpan() const 58 { 59 const AtomicString& colSpanValue = fastGetAttribute(colspanAttr); 60 return max(1, min(colSpanValue.toInt(), maxColRowSpan)); 61 } 62 63 int HTMLTableCellElement::rowSpan() const 64 { 65 const AtomicString& rowSpanValue = fastGetAttribute(rowspanAttr); 66 return max(1, min(rowSpanValue.toInt(), maxColRowSpan)); 67 } 68 69 int HTMLTableCellElement::cellIndex() const 70 { 71 if (!isHTMLTableRowElement(parentElement())) 72 return -1; 73 74 int index = 0; 75 for (const HTMLTableCellElement* element = Traversal<HTMLTableCellElement>::previousSibling(*this); element; element = Traversal<HTMLTableCellElement>::previousSibling(*element)) 76 ++index; 77 78 return index; 79 } 80 81 bool HTMLTableCellElement::isPresentationAttribute(const QualifiedName& name) const 82 { 83 if (name == nowrapAttr || name == widthAttr || name == heightAttr) 84 return true; 85 return HTMLTablePartElement::isPresentationAttribute(name); 86 } 87 88 void HTMLTableCellElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style) 89 { 90 if (name == nowrapAttr) 91 addPropertyToPresentationAttributeStyle(style, CSSPropertyWhiteSpace, CSSValueWebkitNowrap); 92 else if (name == widthAttr) { 93 if (!value.isEmpty()) { 94 int widthInt = value.toInt(); 95 if (widthInt > 0) // width="0" is ignored for compatibility with WinIE. 96 addHTMLLengthToStyle(style, CSSPropertyWidth, value); 97 } 98 } else if (name == heightAttr) { 99 if (!value.isEmpty()) { 100 int heightInt = value.toInt(); 101 if (heightInt > 0) // height="0" is ignored for compatibility with WinIE. 102 addHTMLLengthToStyle(style, CSSPropertyHeight, value); 103 } 104 } else 105 HTMLTablePartElement::collectStyleForPresentationAttribute(name, value, style); 106 } 107 108 void HTMLTableCellElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 109 { 110 if (name == rowspanAttr) { 111 if (renderer() && renderer()->isTableCell()) 112 toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); 113 } else if (name == colspanAttr) { 114 if (renderer() && renderer()->isTableCell()) 115 toRenderTableCell(renderer())->colSpanOrRowSpanChanged(); 116 } else 117 HTMLTablePartElement::parseAttribute(name, value); 118 } 119 120 const StylePropertySet* HTMLTableCellElement::additionalPresentationAttributeStyle() 121 { 122 if (HTMLTableElement* table = findParentTable()) 123 return table->additionalCellStyle(); 124 return 0; 125 } 126 127 bool HTMLTableCellElement::isURLAttribute(const Attribute& attribute) const 128 { 129 return attribute.name() == backgroundAttr || HTMLTablePartElement::isURLAttribute(attribute); 130 } 131 132 bool HTMLTableCellElement::hasLegalLinkAttribute(const QualifiedName& name) const 133 { 134 return (hasTagName(tdTag) && name == backgroundAttr) || HTMLTablePartElement::hasLegalLinkAttribute(name); 135 } 136 137 const QualifiedName& HTMLTableCellElement::subResourceAttributeName() const 138 { 139 return hasTagName(tdTag) ? backgroundAttr : HTMLTablePartElement::subResourceAttributeName(); 140 } 141 142 const AtomicString& HTMLTableCellElement::abbr() const 143 { 144 return fastGetAttribute(abbrAttr); 145 } 146 147 const AtomicString& HTMLTableCellElement::axis() const 148 { 149 return fastGetAttribute(axisAttr); 150 } 151 152 void HTMLTableCellElement::setColSpan(int n) 153 { 154 setIntegralAttribute(colspanAttr, n); 155 } 156 157 const AtomicString& HTMLTableCellElement::headers() const 158 { 159 return fastGetAttribute(headersAttr); 160 } 161 162 void HTMLTableCellElement::setRowSpan(int n) 163 { 164 setIntegralAttribute(rowspanAttr, n); 165 } 166 167 const AtomicString& HTMLTableCellElement::scope() const 168 { 169 return fastGetAttribute(scopeAttr); 170 } 171 172 HTMLTableCellElement* HTMLTableCellElement::cellAbove() const 173 { 174 RenderObject* cellRenderer = renderer(); 175 if (!cellRenderer) 176 return 0; 177 if (!cellRenderer->isTableCell()) 178 return 0; 179 180 RenderTableCell* tableCellRenderer = toRenderTableCell(cellRenderer); 181 RenderTableCell* cellAboveRenderer = tableCellRenderer->table()->cellAbove(tableCellRenderer); 182 if (!cellAboveRenderer) 183 return 0; 184 185 return toHTMLTableCellElement(cellAboveRenderer->node()); 186 } 187 188 } // namespace blink 189