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, 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 37 namespace WebCore { 38 39 using namespace HTMLNames; 40 41 HTMLTableRowElement::HTMLTableRowElement(const QualifiedName& tagName, Document* document) 42 : HTMLTablePartElement(tagName, document) 43 { 44 ASSERT(hasTagName(trTag)); 45 } 46 47 PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document* document) 48 { 49 return adoptRef(new HTMLTableRowElement(trTag, document)); 50 } 51 52 PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document* document) 53 { 54 return adoptRef(new HTMLTableRowElement(tagName, document)); 55 } 56 57 int 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 107 int 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 121 PassRefPtr<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 144 void 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 157 PassRefPtr<HTMLCollection> HTMLTableRowElement::cells() 158 { 159 return HTMLCollection::create(this, TRCells); 160 } 161 162 void HTMLTableRowElement::setCells(HTMLCollection*, ExceptionCode& ec) 163 { 164 ec = NO_MODIFICATION_ALLOWED_ERR; 165 } 166 167 } 168