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/core/v8/ExceptionState.h"
     29 #include "core/HTMLNames.h"
     30 #include "core/dom/ElementTraversal.h"
     31 #include "core/dom/ExceptionCode.h"
     32 #include "core/dom/NodeListsNodeData.h"
     33 #include "core/html/HTMLCollection.h"
     34 #include "core/html/HTMLTableCellElement.h"
     35 #include "core/html/HTMLTableElement.h"
     36 #include "core/html/HTMLTableSectionElement.h"
     37 
     38 namespace blink {
     39 
     40 using namespace HTMLNames;
     41 
     42 inline HTMLTableRowElement::HTMLTableRowElement(Document& document)
     43     : HTMLTablePartElement(trTag, document)
     44 {
     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 (HTMLElement* tbody = Traversal<HTMLElement>::firstChild(*table, HasHTMLTagName(tbodyTag)); tbody; tbody = Traversal<HTMLElement>::nextSibling(*tbody, HasHTMLTagName(tbodyTag))) {
     84         for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*tbody); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
     85             if (row == this)
     86                 return rIndex;
     87             ++rIndex;
     88         }
     89     }
     90 
     91     if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
     92         for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
     93             if (row == this)
     94                 return rIndex;
     95             ++rIndex;
     96         }
     97     }
     98 
     99     // We get here for rows that are in <thead> or <tfoot> sections other than the main header and footer.
    100     return -1;
    101 }
    102 
    103 int HTMLTableRowElement::sectionRowIndex() const
    104 {
    105     int rIndex = 0;
    106     const Node* n = this;
    107     do {
    108         n = n->previousSibling();
    109         if (n && isHTMLTableRowElement(*n))
    110             ++rIndex;
    111     } while (n);
    112 
    113     return rIndex;
    114 }
    115 
    116 PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
    117 {
    118     RefPtrWillBeRawPtr<HTMLCollection> children = cells();
    119     int numCells = children ? children->length() : 0;
    120     if (index < -1 || index > numCells) {
    121         exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [-1, " + String::number(numCells) + "].");
    122         return nullptr;
    123     }
    124 
    125     RefPtrWillBeRawPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
    126     if (numCells == index || index == -1)
    127         appendChild(cell, exceptionState);
    128     else
    129         insertBefore(cell, children->item(index), exceptionState);
    130     return cell.release();
    131 }
    132 
    133 void HTMLTableRowElement::deleteCell(int index, ExceptionState& exceptionState)
    134 {
    135     RefPtrWillBeRawPtr<HTMLCollection> children = cells();
    136     int numCells = children ? children->length() : 0;
    137     if (index == -1)
    138         index = numCells-1;
    139     if (index >= 0 && index < numCells) {
    140         RefPtrWillBeRawPtr<Element> cell = children->item(index);
    141         HTMLElement::removeChild(cell.get(), exceptionState);
    142     } else {
    143         exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [0, " + String::number(numCells) + ").");
    144     }
    145 }
    146 
    147 PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableRowElement::cells()
    148 {
    149     return ensureCachedCollection<HTMLCollection>(TRCells);
    150 }
    151 
    152 }
    153