Home | History | Annotate | Download | only in html
      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 "core/html/HTMLTableRowElement.h"
     27 
     28 #include "bindings/v8/ExceptionState.h"
     29 #include "core/HTMLNames.h"
     30 #include "core/dom/ElementTraversal.h"
     31 #include "core/dom/ExceptionCode.h"
     32 #include "core/html/HTMLCollection.h"
     33 #include "core/html/HTMLTableCellElement.h"
     34 #include "core/html/HTMLTableElement.h"
     35 #include "core/html/HTMLTableSectionElement.h"
     36 
     37 namespace WebCore {
     38 
     39 using namespace HTMLNames;
     40 
     41 inline HTMLTableRowElement::HTMLTableRowElement(Document& document)
     42     : HTMLTablePartElement(trTag, document)
     43 {
     44     ScriptWrappable::init(this);
     45 }
     46 
     47 DEFINE_NODE_FACTORY(HTMLTableRowElement)
     48 
     49 bool HTMLTableRowElement::hasLegalLinkAttribute(const QualifiedName& name) const
     50 {
     51     return name == backgroundAttr || HTMLTablePartElement::hasLegalLinkAttribute(name);
     52 }
     53 
     54 const QualifiedName& HTMLTableRowElement::subResourceAttributeName() const
     55 {
     56     return backgroundAttr;
     57 }
     58 
     59 int HTMLTableRowElement::rowIndex() const
     60 {
     61     ContainerNode* table = parentNode();
     62     if (!table)
     63         return -1;
     64     table = table->parentNode();
     65     if (!isHTMLTableElement(table))
     66         return -1;
     67 
     68     // To match Firefox, the row indices work like this:
     69     //   Rows from the first <thead> are numbered before all <tbody> rows.
     70     //   Rows from the first <tfoot> are numbered after all <tbody> rows.
     71     //   Rows from other <thead> and <tfoot> elements don't get row indices at all.
     72 
     73     int rIndex = 0;
     74 
     75     if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) {
     76         for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*head); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
     77             if (row == this)
     78                 return rIndex;
     79             ++rIndex;
     80         }
     81     }
     82 
     83     for (Element* child = ElementTraversal::firstWithin(*table); child; child = ElementTraversal::nextSibling(*child)) {
     84         if (child->hasTagName(tbodyTag)) {
     85             HTMLTableSectionElement* section = toHTMLTableSectionElement(child);
     86             for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*section); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
     87                 if (row == this)
     88                     return rIndex;
     89                 ++rIndex;
     90             }
     91         }
     92     }
     93 
     94     if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
     95         for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
     96             if (row == this)
     97                 return rIndex;
     98             ++rIndex;
     99         }
    100     }
    101 
    102     // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer.
    103     return -1;
    104 }
    105 
    106 int HTMLTableRowElement::sectionRowIndex() const
    107 {
    108     int rIndex = 0;
    109     const Node* n = this;
    110     do {
    111         n = n->previousSibling();
    112         if (n && isHTMLTableRowElement(*n))
    113             ++rIndex;
    114     } while (n);
    115 
    116     return rIndex;
    117 }
    118 
    119 PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(ExceptionState& exceptionState)
    120 {
    121     // The default 'index' argument value is -1.
    122     return insertCell(-1, exceptionState);
    123 }
    124 
    125 PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
    126 {
    127     RefPtrWillBeRawPtr<HTMLCollection> children = cells();
    128     int numCells = children ? children->length() : 0;
    129     if (index < -1 || index > numCells) {
    130         exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [-1, " + String::number(numCells) + "].");
    131         return nullptr;
    132     }
    133 
    134     RefPtrWillBeRawPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
    135     if (numCells == index || index == -1)
    136         appendChild(cell, exceptionState);
    137     else
    138         insertBefore(cell, children->item(index), exceptionState);
    139     return cell.release();
    140 }
    141 
    142 void HTMLTableRowElement::deleteCell(int index, ExceptionState& exceptionState)
    143 {
    144     RefPtrWillBeRawPtr<HTMLCollection> children = cells();
    145     int numCells = children ? children->length() : 0;
    146     if (index == -1)
    147         index = numCells-1;
    148     if (index >= 0 && index < numCells) {
    149         RefPtrWillBeRawPtr<Element> cell = children->item(index);
    150         HTMLElement::removeChild(cell.get(), exceptionState);
    151     } else {
    152         exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [0, " + String::number(numCells) + ").");
    153     }
    154 }
    155 
    156 PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableRowElement::cells()
    157 {
    158     return ensureCachedHTMLCollection(TRCells);
    159 }
    160 
    161 }
    162