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, 2007, 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 "HTMLTableRowElement.h" 27 28#include "ExceptionCode.h" 29#include "HTMLCollection.h" 30#include "HTMLNames.h" 31#include "HTMLTableCellElement.h" 32#include "HTMLTableElement.h" 33#include "HTMLTableSectionElement.h" 34#include "NodeList.h" 35#include "Text.h" 36 37namespace WebCore { 38 39using namespace HTMLNames; 40 41HTMLTableRowElement::HTMLTableRowElement(const QualifiedName& tagName, Document* document) 42 : HTMLTablePartElement(tagName, document) 43{ 44 ASSERT(hasTagName(trTag)); 45} 46 47PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document* document) 48{ 49 return adoptRef(new HTMLTableRowElement(trTag, document)); 50} 51 52PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document* document) 53{ 54 return adoptRef(new HTMLTableRowElement(tagName, document)); 55} 56 57int HTMLTableRowElement::rowIndex() const 58{ 59 ContainerNode* table = parentNode(); 60 if (!table) 61 return -1; 62 table = table->parentNode(); 63 if (!table || !table->hasTagName(tableTag)) 64 return -1; 65 66 // To match Firefox, the row indices work like this: 67 // Rows from the first <thead> are numbered before all <tbody> rows. 68 // Rows from the first <tfoot> are numbered after all <tbody> rows. 69 // Rows from other <thead> and <tfoot> elements don't get row indices at all. 70 71 int rIndex = 0; 72 73 if (HTMLTableSectionElement* head = static_cast<HTMLTableElement*>(table)->tHead()) { 74 for (Node *row = head->firstChild(); row; row = row->nextSibling()) { 75 if (row == this) 76 return rIndex; 77 if (row->hasTagName(trTag)) 78 ++rIndex; 79 } 80 } 81 82 for (Node *node = table->firstChild(); node; node = node->nextSibling()) { 83 if (node->hasTagName(tbodyTag)) { 84 HTMLTableSectionElement* section = static_cast<HTMLTableSectionElement*>(node); 85 for (Node* row = section->firstChild(); row; row = row->nextSibling()) { 86 if (row == this) 87 return rIndex; 88 if (row->hasTagName(trTag)) 89 ++rIndex; 90 } 91 } 92 } 93 94 if (HTMLTableSectionElement* foot = static_cast<HTMLTableElement*>(table)->tFoot()) { 95 for (Node *row = foot->firstChild(); row; row = row->nextSibling()) { 96 if (row == this) 97 return rIndex; 98 if (row->hasTagName(trTag)) 99 ++rIndex; 100 } 101 } 102 103 // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer. 104 return -1; 105} 106 107int HTMLTableRowElement::sectionRowIndex() const 108{ 109 int rIndex = 0; 110 const Node *n = this; 111 do { 112 n = n->previousSibling(); 113 if (n && n->hasTagName(trTag)) 114 rIndex++; 115 } 116 while (n); 117 118 return rIndex; 119} 120 121PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionCode& ec) 122{ 123 RefPtr<HTMLCollection> children = cells(); 124 int numCells = children ? children->length() : 0; 125 if (index < -1 || index > numCells) { 126 ec = INDEX_SIZE_ERR; 127 return 0; 128 } 129 130 RefPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document()); 131 if (index < 0 || index >= numCells) 132 appendChild(cell, ec); 133 else { 134 Node* n; 135 if (index < 1) 136 n = firstChild(); 137 else 138 n = children->item(index); 139 insertBefore(cell, n, ec); 140 } 141 return cell.release(); 142} 143 144void HTMLTableRowElement::deleteCell(int index, ExceptionCode& ec) 145{ 146 RefPtr<HTMLCollection> children = cells(); 147 int numCells = children ? children->length() : 0; 148 if (index == -1) 149 index = numCells-1; 150 if (index >= 0 && index < numCells) { 151 RefPtr<Node> cell = children->item(index); 152 HTMLElement::removeChild(cell.get(), ec); 153 } else 154 ec = INDEX_SIZE_ERR; 155} 156 157PassRefPtr<HTMLCollection> HTMLTableRowElement::cells() 158{ 159 return ensureCachedHTMLCollection(TRCells); 160} 161 162void HTMLTableRowElement::setCells(HTMLCollection*, ExceptionCode& ec) 163{ 164 ec = NO_MODIFICATION_ALLOWED_ERR; 165} 166 167} 168