2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "HTMLTableRowsCollection.h"
32 #include "HTMLNames.h"
33 #include "HTMLTableElement.h"
34 #include "HTMLTableRowElement.h"
38 using namespace HTMLNames
;
40 static bool isInHead(Element
* row
)
42 return row
->parent() && static_cast<Element
*>(row
->parent())->hasLocalName(theadTag
);
45 static bool isInBody(Element
* row
)
47 return row
->parent() && static_cast<Element
*>(row
->parent())->hasLocalName(tbodyTag
);
50 static bool isInFoot(Element
* row
)
52 return row
->parent() && static_cast<Element
*>(row
->parent())->hasLocalName(tfootTag
);
55 HTMLTableRowElement
* HTMLTableRowsCollection::rowAfter(HTMLTableElement
* table
, HTMLTableRowElement
* previous
)
59 // Start by looking for the next row in this section.
60 // Continue only if there is none.
61 if (previous
&& previous
->parent() != table
) {
62 for (child
= previous
->nextSibling(); child
; child
= child
->nextSibling()) {
63 if (child
->hasTagName(trTag
))
64 return static_cast<HTMLTableRowElement
*>(child
);
68 // If still looking at head sections, find the first row in the next head section.
70 child
= table
->firstChild();
71 else if (isInHead(previous
))
72 child
= previous
->parent()->nextSibling();
73 for (; child
; child
= child
->nextSibling()) {
74 if (child
->hasTagName(theadTag
)) {
75 for (Node
* grandchild
= child
->firstChild(); grandchild
; grandchild
= grandchild
->nextSibling()) {
76 if (grandchild
->hasTagName(trTag
))
77 return static_cast<HTMLTableRowElement
*>(grandchild
);
82 // If still looking at top level and bodies, find the next row in top level or the first in the next body section.
83 if (!previous
|| isInHead(previous
))
84 child
= table
->firstChild();
85 else if (previous
->parent() == table
)
86 child
= previous
->nextSibling();
87 else if (isInBody(previous
))
88 child
= previous
->parent()->nextSibling();
89 for (; child
; child
= child
->nextSibling()) {
90 if (child
->hasTagName(trTag
))
91 return static_cast<HTMLTableRowElement
*>(child
);
92 if (child
->hasTagName(tbodyTag
)) {
93 for (Node
* grandchild
= child
->firstChild(); grandchild
; grandchild
= grandchild
->nextSibling()) {
94 if (grandchild
->hasTagName(trTag
))
95 return static_cast<HTMLTableRowElement
*>(grandchild
);
100 // Find the first row in the next foot section.
101 if (!previous
|| !isInFoot(previous
))
102 child
= table
->firstChild();
104 child
= previous
->parent()->nextSibling();
105 for (; child
; child
= child
->nextSibling()) {
106 if (child
->hasTagName(tfootTag
)) {
107 for (Node
* grandchild
= child
->firstChild(); grandchild
; grandchild
= grandchild
->nextSibling()) {
108 if (grandchild
->hasTagName(trTag
))
109 return static_cast<HTMLTableRowElement
*>(grandchild
);
117 HTMLTableRowElement
* HTMLTableRowsCollection::lastRow(HTMLTableElement
* table
)
119 for (Node
* child
= table
->lastChild(); child
; child
= child
->previousSibling()) {
120 if (child
->hasTagName(tfootTag
)) {
121 for (Node
* grandchild
= child
->lastChild(); grandchild
; grandchild
= grandchild
->previousSibling()) {
122 if (grandchild
->hasTagName(trTag
))
123 return static_cast<HTMLTableRowElement
*>(grandchild
);
128 for (Node
* child
= table
->lastChild(); child
; child
= child
->previousSibling()) {
129 if (child
->hasTagName(trTag
))
130 return static_cast<HTMLTableRowElement
*>(child
);
131 if (child
->hasTagName(tbodyTag
)) {
132 for (Node
* grandchild
= child
->lastChild(); grandchild
; grandchild
= grandchild
->previousSibling()) {
133 if (grandchild
->hasTagName(trTag
))
134 return static_cast<HTMLTableRowElement
*>(grandchild
);
139 for (Node
* child
= table
->lastChild(); child
; child
= child
->previousSibling()) {
140 if (child
->hasTagName(theadTag
)) {
141 for (Node
* grandchild
= child
->lastChild(); grandchild
; grandchild
= grandchild
->previousSibling()) {
142 if (grandchild
->hasTagName(trTag
))
143 return static_cast<HTMLTableRowElement
*>(grandchild
);
151 HTMLTableRowsCollection::HTMLTableRowsCollection(PassRefPtr
<HTMLTableElement
> table
)
152 : HTMLCollection(table
, OtherCollection
, 0)
156 PassRefPtr
<HTMLTableRowsCollection
> HTMLTableRowsCollection::create(PassRefPtr
<HTMLTableElement
> table
)
158 return adoptRef(new HTMLTableRowsCollection(table
));
161 Element
* HTMLTableRowsCollection::itemAfter(Element
* previous
) const
163 ASSERT(!previous
|| previous
->hasLocalName(trTag
));
164 return rowAfter(static_cast<HTMLTableElement
*>(base()), static_cast<HTMLTableRowElement
*>(previous
));