blob: d550bcb8b4a555aebb5ac73d753487dbf4832daa [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Neither the name of Google Inc. nor the names of its
11 * contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "core/dom/NodeRenderingTraversal.h"
29
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010030#include "core/dom/PseudoElement.h"
Torne (Richard Coles)e5249552013-05-15 11:35:13 +010031#include "core/dom/shadow/ComposedShadowTreeWalker.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010032
33namespace WebCore {
34
35namespace NodeRenderingTraversal {
36
37void ParentDetails::didTraverseInsertionPoint(InsertionPoint* insertionPoint)
38{
39 if (!m_insertionPoint) {
40 m_insertionPoint = insertionPoint;
41 m_resetStyleInheritance = m_resetStyleInheritance || insertionPoint->resetStyleInheritance();
42 }
43}
44
45void ParentDetails::didTraverseShadowRoot(const ShadowRoot* root)
46{
47 m_resetStyleInheritance = m_resetStyleInheritance || root->resetStyleInheritance();
48}
49
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010050ContainerNode* parent(const Node* node, ParentDetails* details)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010051{
Torne (Richard Coles)f5e4ad52013-08-05 13:57:57 +010052 // FIXME: Once everything lazy attaches we should assert that we don't need a distribution recalc here.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010053 ComposedShadowTreeWalker walker(node, ComposedShadowTreeWalker::CrossUpperBoundary, ComposedShadowTreeWalker::CanStartFromShadowBoundary);
54 ContainerNode* found = toContainerNode(walker.traverseParent(walker.get(), details));
55 return details->outOfComposition() ? 0 : found;
56}
57
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010058Node* nextSibling(const Node* node)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010059{
60 ComposedShadowTreeWalker walker(node);
61 if (node->isBeforePseudoElement()) {
62 walker.parent();
63 walker.firstChild();
64 } else
65 walker.nextSibling();
66
67 if (walker.get() || node->isAfterPseudoElement())
68 return walker.get();
69
70 Node* parent = walker.traverseParent(node);
71 if (parent && parent->isElementNode())
72 return toElement(parent)->pseudoElement(AFTER);
73
74 return 0;
75}
76
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010077Node* previousSibling(const Node* node)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010078{
79 ComposedShadowTreeWalker walker(node);
80 if (node->isAfterPseudoElement()) {
81 walker.parent();
82 walker.lastChild();
83 } else
84 walker.previousSibling();
85
86 if (walker.get() || node->isBeforePseudoElement())
87 return walker.get();
88
89 Node* parent = walker.traverseParent(node);
90 if (parent && parent->isElementNode())
91 return toElement(parent)->pseudoElement(BEFORE);
92
93 return 0;
94}
95
96Node* nextInScope(const Node* node)
97{
98 ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
99 walker.next();
100 return walker.get();
101}
102
103Node* previousInScope(const Node* node)
104{
105 ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
106 walker.previous();
107 return walker.get();
108}
109
110Node* parentInScope(const Node* node)
111{
112 ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
113 walker.parent();
114 return walker.get();
115}
116
117Node* lastChildInScope(const Node* node)
118{
119 ComposedShadowTreeWalker walker = ComposedShadowTreeWalker(node, ComposedShadowTreeWalker::DoNotCrossUpperBoundary);
120 walker.lastChild();
121 return walker.get();
122}
123
124}
125
126} // namespace