Remove InsertionPoint and ContentDistributor
[WebKit-https.git] / Source / WebCore / dom / NodeRenderingTraversal.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2013 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Neither the name of Google Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "NodeRenderingTraversal.h"
30
31 #include "ShadowRoot.h"
32
33 namespace WebCore {
34
35 namespace NodeRenderingTraversal {
36
37 enum ShadowRootCrossing { CrossShadowRoot, DontCrossShadowRoot };
38
39 static ContainerNode* traverseParent(const Node* node, ShadowRootCrossing shadowRootCrossing)
40 {
41     if (shadowRootCrossing == DontCrossShadowRoot  && node->isShadowRoot())
42         return nullptr;
43
44     ContainerNode* parent = node->parentNode();
45     if (parent && parent->shadowRoot())
46         return nullptr;
47
48     if (!parent)
49         return nullptr;
50
51     if (is<ShadowRoot>(*parent))
52         return shadowRootCrossing == CrossShadowRoot ? downcast<ShadowRoot>(parent)->host() : parent;
53
54     return parent;
55 }
56
57 static Node* traverseFirstChild(const Node* node, ShadowRootCrossing shadowRootCrossing)
58 {
59     ASSERT(node);
60     if (node->shadowRoot()) {
61         if (shadowRootCrossing == DontCrossShadowRoot)
62             return nullptr;
63         node = node->shadowRoot();
64     }
65     return node->firstChild();
66 }
67
68 static Node* traverseLastChild(const Node* node, ShadowRootCrossing shadowRootCrossing)
69 {
70     ASSERT(node);
71     if (node->shadowRoot()) {
72         if (shadowRootCrossing == DontCrossShadowRoot)
73             return nullptr;
74         node = node->shadowRoot();
75     }
76     return node->lastChild();
77 }
78
79 static Node* traverseNextSibling(const Node* node)
80 {
81     ASSERT(node);
82     return node->nextSibling();
83 }
84
85 static Node* traversePreviousSibling(const Node* node)
86 {
87     ASSERT(node);
88     return node->previousSibling();
89 }
90
91 ContainerNode* parentSlow(const Node* node)
92 {
93     ASSERT(!node->isShadowRoot());
94
95     return traverseParent(node, CrossShadowRoot);
96 }
97
98 Node* firstChildSlow(const Node* node)
99 {
100     ASSERT(!node->isShadowRoot());
101
102     return traverseFirstChild(node, DontCrossShadowRoot);
103 }
104
105 Node* nextSiblingSlow(const Node* node)
106 {
107     ASSERT(!node->isShadowRoot());
108
109     return traverseNextSibling(node);
110 }
111
112 Node* previousSiblingSlow(const Node* node)
113 {
114     ASSERT(!node->isShadowRoot());
115
116     return traversePreviousSibling(node);
117 }
118
119 Node* nextInScope(const Node* node)
120 {
121     if (Node* next = traverseFirstChild(node, DontCrossShadowRoot))
122         return next;
123     if (Node* next = traverseNextSibling(node))
124         return next;
125     const Node* current = node;
126     while (current && !traverseNextSibling(current))
127         current = traverseParent(current, DontCrossShadowRoot);
128     return current ? traverseNextSibling(current) : 0;
129 }
130
131 Node* previousInScope(const Node* node)
132 {
133     if (Node* current = traversePreviousSibling(node)) {
134         while (Node* child = traverseLastChild(current, DontCrossShadowRoot))
135             current = child;
136         return current;
137     }
138     return traverseParent(node, DontCrossShadowRoot);
139 }
140
141 Node* parentInScope(const Node* node)
142 {
143     return traverseParent(node, DontCrossShadowRoot);
144 }
145
146 Node* lastChildInScope(const Node* node)
147 {
148     return traverseLastChild(node, DontCrossShadowRoot);
149 }
150
151 }
152
153 } // namespace