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 "GenericCachedHTMLCollection.h"
29#include "HTMLNames.h"
30#include "HTMLTableCellElement.h"
31#include "HTMLTableElement.h"
32#include "HTMLTableSectionElement.h"
33#include "NodeList.h"
34#include "NodeRareData.h"
35#include "Text.h"
36#include <wtf/IsoMallocInlines.h>
37
38namespace WebCore {
39
40WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLTableRowElement);
41
42using namespace HTMLNames;
43
44inline HTMLTableRowElement::HTMLTableRowElement(const QualifiedName& tagName, Document& document)
45 : HTMLTablePartElement(tagName, document)
46{
47 ASSERT(hasTagName(trTag));
48}
49
50Ref<HTMLTableRowElement> HTMLTableRowElement::create(Document& document)
51{
52 return adoptRef(*new HTMLTableRowElement(trTag, document));
53}
54
55Ref<HTMLTableRowElement> HTMLTableRowElement::create(const QualifiedName& tagName, Document& document)
56{
57 return adoptRef(*new HTMLTableRowElement(tagName, document));
58}
59
60static inline RefPtr<HTMLTableElement> findTable(const HTMLTableRowElement& row)
61{
62 auto* parent = row.parentNode();
63 if (is<HTMLTableElement>(parent))
64 return downcast<HTMLTableElement>(parent);
65 if (is<HTMLTableSectionElement>(parent)) {
66 auto* grandparent = parent->parentNode();
67 if (is<HTMLTableElement>(grandparent))
68 return downcast<HTMLTableElement>(grandparent);
69 }
70 return nullptr;
71}
72
73int HTMLTableRowElement::rowIndex() const
74{
75 auto table = findTable(*this);
76 if (!table)
77 return -1;
78
79 auto rows = table->rows();
80 unsigned length = rows->length();
81 for (unsigned i = 0; i < length; ++i) {
82 if (rows->item(i) == this)
83 return i;
84 }
85
86 return -1;
87}
88
89static inline RefPtr<HTMLCollection> findRows(const HTMLTableRowElement& row)
90{
91 auto parent = makeRefPtr(row.parentNode());
92 if (is<HTMLTableSectionElement>(parent))
93 return downcast<HTMLTableSectionElement>(*parent).rows();
94 if (is<HTMLTableElement>(parent))
95 return downcast<HTMLTableElement>(*parent).rows();
96 return nullptr;
97}
98
99int HTMLTableRowElement::sectionRowIndex() const
100{
101 auto rows = findRows(*this);
102 if (!rows)
103 return -1;
104
105 unsigned length = rows->length();
106 for (unsigned i = 0; i < length; ++i) {
107 if (rows->item(i) == this)
108 return i;
109 }
110
111 return -1;
112}
113
114ExceptionOr<Ref<HTMLTableCellElement>> HTMLTableRowElement::insertCell(int index)
115{
116 if (index < -1)
117 return Exception { IndexSizeError };
118 auto children = cells();
119 int numCells = children->length();
120 if (index > numCells)
121 return Exception { IndexSizeError };
122 auto cell = HTMLTableCellElement::create(tdTag, document());
123 ExceptionOr<void> result;
124 if (index < 0 || index >= numCells)
125 result = appendChild(cell);
126 else
127 result = insertBefore(cell, index < 1 ? firstChild() : children->item(index));
128 if (result.hasException())
129 return result.releaseException();
130 return cell;
131}
132
133ExceptionOr<void> HTMLTableRowElement::deleteCell(int index)
134{
135 auto children = cells();
136 int numCells = children->length();
137 if (index == -1) {
138 if (!numCells)
139 return { };
140 index = numCells - 1;
141 }
142 if (index < 0 || index >= numCells)
143 return Exception { IndexSizeError };
144 return removeChild(*children->item(index));
145}
146
147Ref<HTMLCollection> HTMLTableRowElement::cells()
148{
149 return ensureRareData().ensureNodeLists().addCachedCollection<GenericCachedHTMLCollection<CollectionTypeTraits<TRCells>::traversalType>>(*this, TRCells);
150}
151
152}
153