blob: 11a9661374ce56e2507effbd7d3278e439d948e0 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
6 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "core/dom/NodeTraversal.h"
27
28#include "core/dom/ContainerNode.h"
29
30namespace WebCore {
31namespace NodeTraversal {
32
33Node* previousIncludingPseudo(const Node* current, const Node* stayWithin)
34{
35 if (current == stayWithin)
36 return 0;
37 if (Node* previous = current->pseudoAwarePreviousSibling()) {
38 while (previous->pseudoAwareLastChild())
39 previous = previous->pseudoAwareLastChild();
40 return previous;
41 }
42 return current->parentNode();
43}
44
45Node* nextIncludingPseudo(const Node* current, const Node* stayWithin)
46{
47 if (Node* next = current->pseudoAwareFirstChild())
48 return next;
49 if (current == stayWithin)
50 return 0;
51 if (Node* next = current->pseudoAwareNextSibling())
52 return next;
53 for (current = current->parentNode(); current; current = current->parentNode()) {
54 if (current == stayWithin)
55 return 0;
56 if (Node* next = current->pseudoAwareNextSibling())
57 return next;
58 }
59 return 0;
60}
61
62Node* nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin)
63{
64 if (current == stayWithin)
65 return 0;
66 if (Node* next = current->pseudoAwareNextSibling())
67 return next;
68 for (current = current->parentNode(); current; current = current->parentNode()) {
69 if (current == stayWithin)
70 return 0;
71 if (Node* next = current->pseudoAwareNextSibling())
72 return next;
73 }
74 return 0;
75}
76
77Node* nextAncestorSibling(const Node* current)
78{
79 ASSERT(!current->nextSibling());
80 for (current = current->parentNode(); current; current = current->parentNode()) {
81 if (current->nextSibling())
82 return current->nextSibling();
83 }
84 return 0;
85}
86
87Node* nextAncestorSibling(const Node* current, const Node* stayWithin)
88{
89 ASSERT(!current->nextSibling());
90 ASSERT(current != stayWithin);
91 for (current = current->parentNode(); current; current = current->parentNode()) {
92 if (current == stayWithin)
93 return 0;
94 if (current->nextSibling())
95 return current->nextSibling();
96 }
97 return 0;
98}
99
100Node* previous(const Node* current, const Node* stayWithin)
101{
102 if (current == stayWithin)
103 return 0;
104 if (current->previousSibling()) {
105 Node* previous = current->previousSibling();
106 while (previous->lastChild())
107 previous = previous->lastChild();
108 return previous;
109 }
110 return current->parentNode();
111}
112
113Node* previousSkippingChildren(const Node* current, const Node* stayWithin)
114{
115 if (current == stayWithin)
116 return 0;
117 if (current->previousSibling())
118 return current->previousSibling();
119 for (current = current->parentNode(); current; current = current->parentNode()) {
120 if (current == stayWithin)
121 return 0;
122 if (current->previousSibling())
123 return current->previousSibling();
124 }
125 return 0;
126}
127
128Node* nextPostOrder(const Node* current, const Node* stayWithin)
129{
130 if (current == stayWithin)
131 return 0;
132 if (!current->nextSibling())
133 return current->parentNode();
134 Node* next = current->nextSibling();
135 while (next->firstChild())
136 next = next->firstChild();
137 return next;
138}
139
140static Node* previousAncestorSiblingPostOrder(const Node* current, const Node* stayWithin)
141{
142 ASSERT(!current->previousSibling());
143 for (current = current->parentNode(); current; current = current->parentNode()) {
144 if (current == stayWithin)
145 return 0;
146 if (current->previousSibling())
147 return current->previousSibling();
148 }
149 return 0;
150}
151
152Node* previousPostOrder(const Node* current, const Node* stayWithin)
153{
154 if (current->lastChild())
155 return current->lastChild();
156 if (current == stayWithin)
157 return 0;
158 if (current->previousSibling())
159 return current->previousSibling();
160 return previousAncestorSiblingPostOrder(current, stayWithin);
161}
162
163Node* previousSkippingChildrenPostOrder(const Node* current, const Node* stayWithin)
164{
165 if (current == stayWithin)
166 return 0;
167 if (current->previousSibling())
168 return current->previousSibling();
169 return previousAncestorSiblingPostOrder(current, stayWithin);
170}
171
172}
173}