blob: 68e3cf327637df47606c1ed6d941cb6bf279d0c8 [file] [log] [blame]
/*
* Copyright (C) 1997 Martin Jones (mjones@kde.org)
* (C) 1997 Torben Weis (weis@kde.org)
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights
* reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "third_party/blink/renderer/core/html/html_table_row_element.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
#include "third_party/blink/renderer/core/html/html_table_cell_element.h"
#include "third_party/blink/renderer/core/html/html_table_element.h"
#include "third_party/blink/renderer/core/html/html_table_rows_collection.h"
#include "third_party/blink/renderer/core/html/html_table_section_element.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
HTMLTableRowElement::HTMLTableRowElement(Document& document)
: HTMLTablePartElement(html_names::kTrTag, document) {}
bool HTMLTableRowElement::HasLegalLinkAttribute(
const QualifiedName& name) const {
return name == html_names::kBackgroundAttr ||
HTMLTablePartElement::HasLegalLinkAttribute(name);
}
const QualifiedName& HTMLTableRowElement::SubResourceAttributeName() const {
return html_names::kBackgroundAttr;
}
static int FindIndexInRowCollection(const HTMLCollection& rows,
const HTMLTableRowElement& target) {
Element* candidate = rows.item(0);
for (int i = 0; candidate; i++, candidate = rows.item(i)) {
if (target == candidate)
return i;
}
return -1;
}
int HTMLTableRowElement::rowIndex() const {
ContainerNode* maybe_table = parentNode();
if (maybe_table && IsA<HTMLTableSectionElement>(maybe_table)) {
// Skip THEAD, TBODY and TFOOT.
maybe_table = maybe_table->parentNode();
}
auto* html_table_element = DynamicTo<HTMLTableElement>(maybe_table);
if (!html_table_element)
return -1;
return FindIndexInRowCollection(*html_table_element->rows(), *this);
}
int HTMLTableRowElement::sectionRowIndex() const {
ContainerNode* maybe_table = parentNode();
if (!maybe_table)
return -1;
HTMLCollection* rows = nullptr;
if (auto* section = DynamicTo<HTMLTableSectionElement>(maybe_table))
rows = section->rows();
else if (auto* table = DynamicTo<HTMLTableElement>(maybe_table))
rows = table->rows();
if (!rows)
return -1;
return FindIndexInRowCollection(*rows, *this);
}
HTMLElement* HTMLTableRowElement::insertCell(int index,
ExceptionState& exception_state) {
HTMLCollection* children = cells();
int num_cells = children ? children->length() : 0;
if (index < -1 || index > num_cells) {
exception_state.ThrowDOMException(
DOMExceptionCode::kIndexSizeError,
"The value provided (" + String::Number(index) +
") is outside the range [-1, " + String::Number(num_cells) + "].");
return nullptr;
}
auto* cell = MakeGarbageCollected<HTMLTableCellElement>(html_names::kTdTag,
GetDocument());
if (num_cells == index || index == -1)
AppendChild(cell, exception_state);
else
InsertBefore(cell, children->item(index), exception_state);
return cell;
}
void HTMLTableRowElement::deleteCell(int index,
ExceptionState& exception_state) {
HTMLCollection* children = cells();
int num_cells = children ? children->length() : 0;
// 1. If index is less than −1 or greater than or equal to the number of
// elements in the cells collection, then throw "IndexSizeError".
if (index < -1 || index >= num_cells) {
exception_state.ThrowDOMException(
DOMExceptionCode::kIndexSizeError,
"The value provided (" + String::Number(index) +
") is outside the range [0, " + String::Number(num_cells) + ").");
return;
}
// 2. If index is −1, remove the last element in the cells collection
// from its parent, or do nothing if the cells collection is empty.
if (index == -1) {
if (num_cells == 0)
return;
index = num_cells - 1;
}
// 3. Remove the indexth element in the cells collection from its parent.
Element* cell = children->item(index);
HTMLElement::RemoveChild(cell, exception_state);
}
HTMLCollection* HTMLTableRowElement::cells() {
return EnsureCachedCollection<HTMLCollection>(kTRCells);
}
} // namespace blink