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