Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp

Issue 1562743002: Revert of Support slot element's fallback content feature (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Neither the name of Google Inc. nor the names of its 10 * * Neither the name of Google Inc. nor the names of its
(...skipping 20 matching lines...) Expand all
31 #include "core/html/HTMLShadowElement.h" 31 #include "core/html/HTMLShadowElement.h"
32 #include "core/html/HTMLSlotElement.h" 32 #include "core/html/HTMLSlotElement.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 static inline ElementShadow* shadowFor(const Node& node) 36 static inline ElementShadow* shadowFor(const Node& node)
37 { 37 {
38 return node.isElementNode() ? toElement(node).shadow() : nullptr; 38 return node.isElementNode() ? toElement(node).shadow() : nullptr;
39 } 39 }
40 40
41 static inline bool canBeDistributedToInsertionPoint(const Node& node)
42 {
43 return node.isInV0ShadowTree() || node.isChildOfV0ShadowHost();
44 }
45
46 Node* ComposedTreeTraversal::traverseChild(const Node& node, TraversalDirection direction) 41 Node* ComposedTreeTraversal::traverseChild(const Node& node, TraversalDirection direction)
47 { 42 {
48 ElementShadow* shadow = shadowFor(node); 43 ElementShadow* shadow = shadowFor(node);
49 if (shadow) { 44 if (shadow) {
50 ShadowRoot& shadowRoot = shadow->youngestShadowRoot(); 45 ShadowRoot& shadowRoot = shadow->youngestShadowRoot();
51 return resolveDistributionStartingAt(direction == TraversalDirectionForw ard ? shadowRoot.firstChild() : shadowRoot.lastChild(), direction); 46 return resolveDistributionStartingAt(direction == TraversalDirectionForw ard ? shadowRoot.firstChild() : shadowRoot.lastChild(), direction);
52 } 47 }
53 return resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.firstChild() : node.lastChild(), direction); 48 return resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.firstChild() : node.lastChild(), direction);
54 } 49 }
55 50
56 Node* ComposedTreeTraversal::resolveDistributionStartingAt(const Node* node, Tra versalDirection direction) 51 Node* ComposedTreeTraversal::resolveDistributionStartingAt(const Node* node, Tra versalDirection direction)
57 { 52 {
58 if (!node) 53 if (!node)
59 return nullptr; 54 return nullptr;
60 for (const Node* sibling = node; sibling; sibling = (direction == TraversalD irectionForward ? sibling->nextSibling() : sibling->previousSibling())) { 55 if (node->isInShadowTree() && node->containingShadowRoot()->isV1())
61 if (isHTMLSlotElement(*sibling)) { 56 return v1ResolveDistributionStartingAt(*node, direction);
62 const HTMLSlotElement& slot = toHTMLSlotElement(*sibling); 57 return v0ResolveDistributionStartingAt(*node, direction);
63 if (Node* found = (direction == TraversalDirectionForward ? slot.fir stDistributedNode() : slot.lastDistributedNode()))
64 return found;
65 continue;
66 }
67 if (node->isInV0ShadowTree())
68 return v0ResolveDistributionStartingAt(*sibling, direction);
69 return const_cast<Node*>(sibling);
70 }
71 return nullptr;
72 } 58 }
73 59
74 Node* ComposedTreeTraversal::v0ResolveDistributionStartingAt(const Node& node, T raversalDirection direction) 60 Node* ComposedTreeTraversal::v0ResolveDistributionStartingAt(const Node& node, T raversalDirection direction)
75 { 61 {
76 ASSERT(!isHTMLSlotElement(node));
77 for (const Node* sibling = &node; sibling; sibling = (direction == Traversal DirectionForward ? sibling->nextSibling() : sibling->previousSibling())) { 62 for (const Node* sibling = &node; sibling; sibling = (direction == Traversal DirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
78 if (!isActiveInsertionPoint(*sibling)) 63 if (!isActiveInsertionPoint(*sibling))
79 return const_cast<Node*>(sibling); 64 return const_cast<Node*>(sibling);
80 const InsertionPoint& insertionPoint = toInsertionPoint(*sibling); 65 const InsertionPoint& insertionPoint = toInsertionPoint(*sibling);
81 if (Node* found = (direction == TraversalDirectionForward ? insertionPoi nt.firstDistributedNode() : insertionPoint.lastDistributedNode())) 66 if (Node* found = (direction == TraversalDirectionForward ? insertionPoi nt.firstDistributedNode() : insertionPoint.lastDistributedNode()))
82 return found; 67 return found;
83 ASSERT(isHTMLShadowElement(insertionPoint) || (isHTMLContentElement(inse rtionPoint) && !insertionPoint.hasChildren())); 68 ASSERT(isHTMLShadowElement(insertionPoint) || (isHTMLContentElement(inse rtionPoint) && !insertionPoint.hasChildren()));
84 } 69 }
85 return nullptr; 70 return nullptr;
86 } 71 }
87 72
73 Node* ComposedTreeTraversal::v1ResolveDistributionStartingAt(const Node& node, T raversalDirection direction)
74 {
75 for (const Node* sibling = &node; sibling; sibling = (direction == Traversal DirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
76 if (!isHTMLSlotElement(*sibling))
77 return const_cast<Node*>(sibling);
78 const HTMLSlotElement& slot = toHTMLSlotElement(*sibling);
79 if (Node* found = (direction == TraversalDirectionForward ? slot.firstDi stributedNode() : slot.lastDistributedNode()))
80 return found;
81 }
82 return nullptr;
83 }
84
88 static HTMLSlotElement* finalDestinationSlotFor(const Node& node) 85 static HTMLSlotElement* finalDestinationSlotFor(const Node& node)
89 { 86 {
90 HTMLSlotElement* slot = node.assignedSlot(); 87 HTMLSlotElement* slot = node.assignedSlot();
91 if (!slot) 88 if (!slot)
92 return nullptr; 89 return nullptr;
93 for (HTMLSlotElement* next = slot->assignedSlot(); next; next = next->assign edSlot()) { 90 for (HTMLSlotElement* next = slot->assignedSlot(); next; next = next->assign edSlot()) {
94 slot = next; 91 slot = next;
95 } 92 }
96 return slot; 93 return slot;
97 } 94 }
98 95
96 Node* ComposedTreeTraversal::traverseSiblings(const Node& node, TraversalDirecti on direction)
97 {
98 Node* parent = node.parentNode();
99 if (!parent)
100 return nullptr;
101 if (parent->isElementNode()) {
102 if (ElementShadow* shadow = toElement(parent)->shadow()) {
103 if (shadow->isV1()) {
104 return v1TraverseSiblings(node, direction);
105 }
106 }
107 }
108 return v0TraverseSiblings(node, direction);
109 }
110
99 // TODO(hayato): This may return a wrong result for a node which is not in a 111 // TODO(hayato): This may return a wrong result for a node which is not in a
100 // document composed tree. See ComposedTreeTraversalTest's redistribution test for details. 112 // document composed tree. See ComposedTreeTraversalTest's redistribution test for details.
101 Node* ComposedTreeTraversal::traverseSiblings(const Node& node, TraversalDirecti on direction) 113 Node* ComposedTreeTraversal::v0TraverseSiblings(const Node& node, TraversalDirec tion direction)
102 { 114 {
103 if (node.isChildOfV1ShadowHost()) 115 if (!shadowWhereNodeCanBeDistributed(node))
104 return traverseSiblingsForV1HostChild(node, direction); 116 return traverseSiblingsOrShadowInsertionPointSiblings(node, direction);
105 117
106 if (shadowWhereNodeCanBeDistributed(node))
107 return traverseSiblingsForV0Distribution(node, direction);
108
109 if (Node* found = resolveDistributionStartingAt(direction == TraversalDirect ionForward ? node.nextSibling() : node.previousSibling(), direction))
110 return found;
111
112 if (!node.isInV0ShadowTree())
113 return nullptr;
114
115 // For v0 older shadow tree
116 if (node.parentNode() && node.parentNode()->isShadowRoot()) {
117 ShadowRoot* parentShadowRoot = toShadowRoot(node.parentNode());
118 if (!parentShadowRoot->isYoungest()) {
119 HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadow InsertionPointOfYoungerShadowRoot();
120 ASSERT(assignedInsertionPoint);
121 return traverseSiblings(*assignedInsertionPoint, direction);
122 }
123 }
124 return nullptr;
125 }
126
127 Node* ComposedTreeTraversal::traverseSiblingsForV1HostChild(const Node& node, Tr aversalDirection direction)
128 {
129 HTMLSlotElement* slot = finalDestinationSlotFor(node);
130 if (!slot)
131 return nullptr;
132 if (Node* siblingInDistributedNodes = (direction == TraversalDirectionForwar d ? slot->distributedNodeNextTo(node) : slot->distributedNodePreviousTo(node)))
133 return siblingInDistributedNodes;
134 return traverseSiblings(*slot, direction);
135 }
136
137 Node* ComposedTreeTraversal::traverseSiblingsForV0Distribution(const Node& node, TraversalDirection direction)
138 {
139 const InsertionPoint* finalDestination = resolveReprojection(&node); 118 const InsertionPoint* finalDestination = resolveReprojection(&node);
140 if (!finalDestination) 119 if (!finalDestination)
141 return nullptr; 120 return nullptr;
142 if (Node* found = (direction == TraversalDirectionForward ? finalDestination ->distributedNodeNextTo(&node) : finalDestination->distributedNodePreviousTo(&no de))) 121 if (Node* found = (direction == TraversalDirectionForward ? finalDestination ->distributedNodeNextTo(&node) : finalDestination->distributedNodePreviousTo(&no de)))
143 return found; 122 return found;
144 return traverseSiblings(*finalDestination, direction); 123 return traverseSiblings(*finalDestination, direction);
124 }
145 125
126 Node* ComposedTreeTraversal::v1TraverseSiblings(const Node& node, TraversalDirec tion direction)
127 {
128 HTMLSlotElement* slot = finalDestinationSlotFor(node);
129 if (!slot)
130 return resolveDistributionStartingAt(direction == TraversalDirectionForw ard ? node.nextSibling() : node.previousSibling(), direction);
131 if (Node* siblingInDistributedNodes = (direction == TraversalDirectionForwar d ? slot->distributedNodeNextTo(node) : slot->distributedNodePreviousTo(node)))
132 return siblingInDistributedNodes;
133 return v1TraverseSiblings(*slot, direction);
134 }
135
136 Node* ComposedTreeTraversal::traverseSiblingsOrShadowInsertionPointSiblings(cons t Node& node, TraversalDirection direction)
137 {
138 if (Node* found = resolveDistributionStartingAt(direction == TraversalDirect ionForward ? node.nextSibling() : node.previousSibling(), direction))
139 return found;
140
141 if (node.parentNode() && node.parentNode()->isShadowRoot()) {
142 ShadowRoot* parentShadowRoot = toShadowRoot(node.parentNode());
143 if (!parentShadowRoot->isYoungest()) {
144 HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadow InsertionPointOfYoungerShadowRoot();
145 ASSERT(assignedInsertionPoint);
146 return traverseSiblingsOrShadowInsertionPointSiblings(*assignedInser tionPoint, direction);
147 }
148 }
149 return nullptr;
150 }
151
152 static ElementShadow* parentElementShadow(const Node& node)
153 {
154 Node* parent = node.parentNode();
155 if (!parent)
156 return nullptr;
157 if (parent->isElementNode())
158 return toElement(parent)->shadow();
159 return nullptr;
146 } 160 }
147 161
148 ContainerNode* ComposedTreeTraversal::traverseParent(const Node& node, ParentTra versalDetails* details) 162 ContainerNode* ComposedTreeTraversal::traverseParent(const Node& node, ParentTra versalDetails* details)
149 { 163 {
150 // TODO(hayato): Stop this hack for a pseudo element because a pseudo elemen t is not a child of its parentOrShadowHostNode() in a composed tree. 164 // TODO(hayato): Stop this hack for a pseudo element because a pseudo elemen t is not a child of its parentOrShadowHostNode() in a composed tree.
151 if (node.isPseudoElement()) 165 if (node.isPseudoElement())
152 return node.parentOrShadowHostNode(); 166 return node.parentOrShadowHostNode();
153 167
154 if (node.isChildOfV1ShadowHost()) { 168 ElementShadow* shadow = parentElementShadow(node);
155 HTMLSlotElement* slot = finalDestinationSlotFor(node); 169 if (shadow && shadow->isV1())
156 if (!slot) 170 return v1TraverseParent(node);
157 return nullptr; 171 if (shadowWhereNodeCanBeDistributed(node))
158 return traverseParent(*slot); 172 return v0TraverseParent(node, details);
159 }
160
161 Element* parent = node.parentElement();
162 if (parent && isHTMLSlotElement(parent)) {
163 HTMLSlotElement& slot = toHTMLSlotElement(*parent);
164 if (!slot.getAssignedNodes().isEmpty())
165 return nullptr;
166 return traverseParent(slot, details);
167 }
168
169 if (canBeDistributedToInsertionPoint(node))
170 return traverseParentForV0(node, details);
171
172 ASSERT(!shadowWhereNodeCanBeDistributed(node));
173 return traverseParentOrHost(node); 173 return traverseParentOrHost(node);
174 } 174 }
175 175
176 ContainerNode* ComposedTreeTraversal::traverseParentForV0(const Node& node, Pare ntTraversalDetails* details) 176 ContainerNode* ComposedTreeTraversal::v1TraverseParent(const Node& node)
177 { 177 {
178 if (shadowWhereNodeCanBeDistributed(node)) { 178 HTMLSlotElement* slot = finalDestinationSlotFor(node);
179 if (const InsertionPoint* insertionPoint = resolveReprojection(&node)) { 179 if (!slot)
180 if (details) 180 return nullptr;
181 details->didTraverseInsertionPoint(insertionPoint); 181 if (parentElementShadow(*slot)) {
182 // The node is distributed. But the distribution was stopped at this insertion point. 182 // The node is distributed to the |slot|, however, |slot|, which is a
183 if (shadowWhereNodeCanBeDistributed(*insertionPoint)) 183 // child of a shadow host, is not assigned to any slots.
184 return nullptr;
185 return traverseParent(*insertionPoint);
186 }
187 return nullptr; 184 return nullptr;
188 } 185 }
189 ContainerNode* parent = traverseParentOrHost(node); 186 return traverseParentOrHost(*slot);
190 if (isActiveInsertionPoint(*parent))
191 return nullptr;
192 return parent;
193 } 187 }
194 188
195 ContainerNode* ComposedTreeTraversal::traverseParentOrHost(const Node& node) 189 ContainerNode* ComposedTreeTraversal::v0TraverseParent(const Node& node, ParentT raversalDetails* details)
196 { 190 {
191 if (const InsertionPoint* insertionPoint = resolveReprojection(&node)) {
192 if (details)
193 details->didTraverseInsertionPoint(insertionPoint);
194 // The node is distributed. But the distribution was stopped at this ins ertion point.
195 if (shadowWhereNodeCanBeDistributed(*insertionPoint))
196 return nullptr;
197 return traverseParentOrHost(*insertionPoint);
198 }
199 return nullptr;
200 }
201
202 inline ContainerNode* ComposedTreeTraversal::traverseParentOrHost(const Node& no de)
203 {
204 // TODO(hayato): Support fallback contents of slots. The parent can be a slo t.
197 ContainerNode* parent = node.parentNode(); 205 ContainerNode* parent = node.parentNode();
198 if (!parent) 206 if (!parent)
199 return nullptr; 207 return nullptr;
200 if (!parent->isShadowRoot()) 208 if (!parent->isShadowRoot())
201 return parent; 209 return parent;
202 ShadowRoot* shadowRoot = toShadowRoot(parent); 210 ShadowRoot* shadowRoot = toShadowRoot(parent);
203 ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot()); 211 ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
204 if (!shadowRoot->isYoungest()) 212 if (!shadowRoot->isYoungest())
205 return nullptr; 213 return nullptr;
206 return shadowRoot->host(); 214 Element* host = shadowRoot->host();
215 if (isActiveInsertionPoint(*host))
216 return nullptr;
217 return host;
207 } 218 }
208 219
209 Node* ComposedTreeTraversal::childAt(const Node& node, unsigned index) 220 Node* ComposedTreeTraversal::childAt(const Node& node, unsigned index)
210 { 221 {
211 assertPrecondition(node); 222 assertPrecondition(node);
212 Node* child = traverseFirstChild(node); 223 Node* child = traverseFirstChild(node);
213 while (child && index--) 224 while (child && index--)
214 child = nextSibling(*child); 225 child = nextSibling(*child);
215 assertPostcondition(child); 226 assertPostcondition(child);
216 return child; 227 return child;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 Node& ComposedTreeTraversal::lastWithinOrSelf(const Node& node) 363 Node& ComposedTreeTraversal::lastWithinOrSelf(const Node& node)
353 { 364 {
354 assertPrecondition(node); 365 assertPrecondition(node);
355 Node* lastDescendant = lastWithin(node); 366 Node* lastDescendant = lastWithin(node);
356 Node& result = lastDescendant ? *lastDescendant : const_cast<Node&>(node); 367 Node& result = lastDescendant ? *lastDescendant : const_cast<Node&>(node);
357 assertPostcondition(&result); 368 assertPostcondition(&result);
358 return result; 369 return result;
359 } 370 }
360 371
361 } // namespace 372 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698