Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / dom / NodeTraversal.cpp
blob5b04a116c03b8803d98a2a8eb57217c2bcfa5968
1 /*
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/)
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.
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.
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.
25 #include "config.h"
26 #include "core/dom/NodeTraversal.h"
28 #include "core/dom/ContainerNode.h"
29 #include "core/dom/Range.h"
31 namespace blink {
33 Node* NodeTraversal::previousIncludingPseudo(const Node& current, const Node* stayWithin)
35 if (current == stayWithin)
36 return 0;
37 if (Node* previous = current.pseudoAwarePreviousSibling()) {
38 while (previous->pseudoAwareLastChild())
39 previous = previous->pseudoAwareLastChild();
40 return previous;
42 return current.parentNode();
45 Node* NodeTraversal::nextIncludingPseudo(const Node& current, const Node* stayWithin)
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 (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
54 if (parent == stayWithin)
55 return 0;
56 if (Node* next = parent->pseudoAwareNextSibling())
57 return next;
59 return 0;
62 Node* NodeTraversal::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
64 if (current == stayWithin)
65 return 0;
66 if (Node* next = current.pseudoAwareNextSibling())
67 return next;
68 for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
69 if (parent == stayWithin)
70 return 0;
71 if (Node* next = parent->pseudoAwareNextSibling())
72 return next;
74 return 0;
77 Node* NodeTraversal::nextAncestorSibling(const Node& current)
79 ASSERT(!current.nextSibling());
80 for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
81 if (parent->nextSibling())
82 return parent->nextSibling();
84 return 0;
87 Node* NodeTraversal::nextAncestorSibling(const Node& current, const Node* stayWithin)
89 ASSERT(!current.nextSibling());
90 ASSERT(current != stayWithin);
91 for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
92 if (parent == stayWithin)
93 return 0;
94 if (parent->nextSibling())
95 return parent->nextSibling();
97 return 0;
100 Node* NodeTraversal::lastWithin(const ContainerNode& current)
102 Node* descendant = current.lastChild();
103 for (Node* child = descendant; child; child = child->lastChild())
104 descendant = child;
105 return descendant;
108 Node& NodeTraversal::lastWithinOrSelf(Node& current)
110 Node* lastDescendant = current.isContainerNode() ? NodeTraversal::lastWithin(toContainerNode(current)) : 0;
111 return lastDescendant ? *lastDescendant : current;
114 Node* NodeTraversal::previous(const Node& current, const Node* stayWithin)
116 if (current == stayWithin)
117 return 0;
118 if (current.previousSibling()) {
119 Node* previous = current.previousSibling();
120 while (Node* child = previous->lastChild())
121 previous = child;
122 return previous;
124 return current.parentNode();
127 Node* NodeTraversal::previousSkippingChildren(const Node& current, const Node* stayWithin)
129 if (current == stayWithin)
130 return 0;
131 if (current.previousSibling())
132 return current.previousSibling();
133 for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
134 if (parent == stayWithin)
135 return 0;
136 if (parent->previousSibling())
137 return parent->previousSibling();
139 return 0;
142 Node* NodeTraversal::nextPostOrder(const Node& current, const Node* stayWithin)
144 if (current == stayWithin)
145 return 0;
146 if (!current.nextSibling())
147 return current.parentNode();
148 Node* next = current.nextSibling();
149 while (Node* child = next->firstChild())
150 next = child;
151 return next;
154 static Node* previousAncestorSiblingPostOrder(const Node& current, const Node* stayWithin)
156 ASSERT(!current.previousSibling());
157 for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
158 if (parent == stayWithin)
159 return 0;
160 if (parent->previousSibling())
161 return parent->previousSibling();
163 return 0;
166 Node* NodeTraversal::previousPostOrder(const Node& current, const Node* stayWithin)
168 if (Node* lastChild = current.lastChild())
169 return lastChild;
170 if (current == stayWithin)
171 return 0;
172 if (current.previousSibling())
173 return current.previousSibling();
174 return previousAncestorSiblingPostOrder(current, stayWithin);
177 Node* NodeTraversal::commonAncestor(const Node& nodeA, const Node& nodeB)
179 return Range::commonAncestorContainer(&nodeA, &nodeB);
182 } // namespace blink