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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLSlotElement.cpp

Issue 2460813002: Make slots in non-shadow trees participate in a flat tree (Closed)
Patch Set: update expectation Created 4 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLSlotElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2015 Google Inc. All rights reserved. 2 * Copyright (C) 2015 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 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 const HeapVector<Member<Node>>& HTMLSlotElement::assignedNodes() { 61 const HeapVector<Member<Node>>& HTMLSlotElement::assignedNodes() {
62 DCHECK(!needsDistributionRecalc()); 62 DCHECK(!needsDistributionRecalc());
63 DCHECK(isInShadowTree() || m_assignedNodes.isEmpty()); 63 DCHECK(isInShadowTree() || m_assignedNodes.isEmpty());
64 return m_assignedNodes; 64 return m_assignedNodes;
65 } 65 }
66 66
67 const HeapVector<Member<Node>> HTMLSlotElement::assignedNodesForBinding( 67 const HeapVector<Member<Node>> HTMLSlotElement::assignedNodesForBinding(
68 const AssignedNodesOptions& options) { 68 const AssignedNodesOptions& options) {
69 updateDistribution(); 69 updateDistribution();
70 if (options.hasFlatten() && options.flatten()) 70 if (options.hasFlatten() && options.flatten())
71 return getDistributedNodes(); 71 return getDistributedNodesForBinding();
72 return m_assignedNodes; 72 return m_assignedNodes;
73 } 73 }
74 74
75 void HTMLSlotElement::updateDistributedNodesManually() { 75 const HeapVector<Member<Node>>
76 DCHECK(!supportsDistribution()); 76 HTMLSlotElement::getDistributedNodesForBinding() {
77 // A slot is unlikely to be used outside of a shadow tree. 77 DCHECK(!needsDistributionRecalc());
78 // We do not need to optimize this case in most cases. 78 if (supportsDistribution())
79 // TODO(hayato): If this path causes a performance issue, we should move 79 return m_distributedNodes;
80 // ShadowRoot::m_slotAssignment into TreeScopreRareData-ish and 80
81 // update the distribution code so it considers a document tree too. 81 // If a slot does not support distribution, its m_distributedNodes should not
82 clearDistribution(); 82 // be used. Instead, calculate distribution manually here. This happens only
83 // in a slot in non-shadow trees, so its assigned nodes are always empty.
84 HeapVector<Member<Node>> distributedNodes;
83 Node* child = NodeTraversal::firstChild(*this); 85 Node* child = NodeTraversal::firstChild(*this);
84 while (child) { 86 while (child) {
85 if (!child->isSlotable()) { 87 if (!child->isSlotable()) {
86 child = NodeTraversal::nextSkippingChildren(*child, this); 88 child = NodeTraversal::nextSkippingChildren(*child, this);
87 continue; 89 continue;
88 } 90 }
89 if (isHTMLSlotElement(child)) { 91 if (isHTMLSlotElement(child)) {
90 child = NodeTraversal::next(*child, this); 92 child = NodeTraversal::next(*child, this);
91 } else { 93 } else {
92 m_distributedNodes.append(child); 94 distributedNodes.append(child);
93 child = NodeTraversal::nextSkippingChildren(*child, this); 95 child = NodeTraversal::nextSkippingChildren(*child, this);
94 } 96 }
95 } 97 }
98 return distributedNodes;
96 } 99 }
97 100
98 const HeapVector<Member<Node>>& HTMLSlotElement::getDistributedNodes() { 101 const HeapVector<Member<Node>>& HTMLSlotElement::getDistributedNodes() {
99 DCHECK(!needsDistributionRecalc()); 102 DCHECK(!needsDistributionRecalc());
100 // m_distributedNodes of slots in non-shadow trees are not updated in recalc 103 DCHECK(supportsDistribution() || m_distributedNodes.isEmpty());
101 // distribution flow.
102 if (!supportsDistribution())
103 updateDistributedNodesManually();
104 return m_distributedNodes; 104 return m_distributedNodes;
105 } 105 }
106 106
107 void HTMLSlotElement::appendAssignedNode(Node& hostChild) { 107 void HTMLSlotElement::appendAssignedNode(Node& hostChild) {
108 DCHECK(hostChild.isSlotable()); 108 DCHECK(hostChild.isSlotable());
109 m_assignedNodes.append(&hostChild); 109 m_assignedNodes.append(&hostChild);
110 } 110 }
111 111
112 void HTMLSlotElement::resolveDistributedNodes() { 112 void HTMLSlotElement::resolveDistributedNodes() {
113 for (auto& node : m_assignedNodes) { 113 for (auto& node : m_assignedNodes) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } 149 }
150 150
151 void HTMLSlotElement::dispatchSlotChangeEvent() { 151 void HTMLSlotElement::dispatchSlotChangeEvent() {
152 m_slotchangeEventEnqueued = false; 152 m_slotchangeEventEnqueued = false;
153 Event* event = Event::createBubble(EventTypeNames::slotchange); 153 Event* event = Event::createBubble(EventTypeNames::slotchange);
154 event->setTarget(this); 154 event->setTarget(this);
155 dispatchScopedEvent(event); 155 dispatchScopedEvent(event);
156 } 156 }
157 157
158 Node* HTMLSlotElement::distributedNodeNextTo(const Node& node) const { 158 Node* HTMLSlotElement::distributedNodeNextTo(const Node& node) const {
159 DCHECK(supportsDistribution());
159 const auto& it = m_distributedIndices.find(&node); 160 const auto& it = m_distributedIndices.find(&node);
160 if (it == m_distributedIndices.end()) 161 if (it == m_distributedIndices.end())
161 return nullptr; 162 return nullptr;
162 size_t index = it->value; 163 size_t index = it->value;
163 if (index + 1 == m_distributedNodes.size()) 164 if (index + 1 == m_distributedNodes.size())
164 return nullptr; 165 return nullptr;
165 return m_distributedNodes[index + 1].get(); 166 return m_distributedNodes[index + 1].get();
166 } 167 }
167 168
168 Node* HTMLSlotElement::distributedNodePreviousTo(const Node& node) const { 169 Node* HTMLSlotElement::distributedNodePreviousTo(const Node& node) const {
170 DCHECK(supportsDistribution());
169 const auto& it = m_distributedIndices.find(&node); 171 const auto& it = m_distributedIndices.find(&node);
170 if (it == m_distributedIndices.end()) 172 if (it == m_distributedIndices.end())
171 return nullptr; 173 return nullptr;
172 size_t index = it->value; 174 size_t index = it->value;
173 if (index == 0) 175 if (index == 0)
174 return nullptr; 176 return nullptr;
175 return m_distributedNodes[index - 1].get(); 177 return m_distributedNodes[index - 1].get();
176 } 178 }
177 179
178 AtomicString HTMLSlotElement::name() const { 180 AtomicString HTMLSlotElement::name() const {
179 return normalizeSlotName(fastGetAttribute(HTMLNames::nameAttr)); 181 return normalizeSlotName(fastGetAttribute(HTMLNames::nameAttr));
180 } 182 }
181 183
182 void HTMLSlotElement::attachLayoutTree(const AttachContext& context) { 184 void HTMLSlotElement::attachLayoutTree(const AttachContext& context) {
183 for (auto& node : getDistributedNodes()) { 185 if (supportsDistribution()) {
184 if (node->needsAttach()) 186 for (auto& node : m_distributedNodes) {
185 node->attachLayoutTree(context); 187 if (node->needsAttach())
188 node->attachLayoutTree(context);
189 }
186 } 190 }
187
188 HTMLElement::attachLayoutTree(context); 191 HTMLElement::attachLayoutTree(context);
189 } 192 }
190 193
191 void HTMLSlotElement::detachLayoutTree(const AttachContext& context) { 194 void HTMLSlotElement::detachLayoutTree(const AttachContext& context) {
192 for (auto& node : m_distributedNodes) 195 if (supportsDistribution()) {
193 node->lazyReattachIfAttached(); 196 for (auto& node : m_distributedNodes)
194 197 node->lazyReattachIfAttached();
198 }
195 HTMLElement::detachLayoutTree(context); 199 HTMLElement::detachLayoutTree(context);
196 } 200 }
197 201
198 void HTMLSlotElement::attributeChanged(const QualifiedName& name, 202 void HTMLSlotElement::attributeChanged(const QualifiedName& name,
199 const AtomicString& oldValue, 203 const AtomicString& oldValue,
200 const AtomicString& newValue, 204 const AtomicString& newValue,
201 AttributeModificationReason reason) { 205 AttributeModificationReason reason) {
202 if (name == nameAttr) { 206 if (name == nameAttr) {
203 if (ShadowRoot* root = containingShadowRoot()) { 207 if (ShadowRoot* root = containingShadowRoot()) {
204 if (root->isV1() && oldValue != newValue) 208 if (root->isV1() && oldValue != newValue)
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 357
354 DEFINE_TRACE(HTMLSlotElement) { 358 DEFINE_TRACE(HTMLSlotElement) {
355 visitor->trace(m_assignedNodes); 359 visitor->trace(m_assignedNodes);
356 visitor->trace(m_distributedNodes); 360 visitor->trace(m_distributedNodes);
357 visitor->trace(m_oldDistributedNodes); 361 visitor->trace(m_oldDistributedNodes);
358 visitor->trace(m_distributedIndices); 362 visitor->trace(m_distributedIndices);
359 HTMLElement::trace(visitor); 363 HTMLElement::trace(visitor);
360 } 364 }
361 365
362 } // namespace blink 366 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLSlotElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698