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

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

Issue 1760153002: Check slot's distribution state more strictly (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update Created 4 years, 9 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) 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 27 matching lines...) Expand all
38 #include "core/dom/shadow/InsertionPoint.h" 38 #include "core/dom/shadow/InsertionPoint.h"
39 #include "core/events/Event.h" 39 #include "core/events/Event.h"
40 #include "core/html/AssignedNodesOptions.h" 40 #include "core/html/AssignedNodesOptions.h"
41 41
42 namespace blink { 42 namespace blink {
43 43
44 using namespace HTMLNames; 44 using namespace HTMLNames;
45 45
46 inline HTMLSlotElement::HTMLSlotElement(Document& document) 46 inline HTMLSlotElement::HTMLSlotElement(Document& document)
47 : HTMLElement(slotTag, document) 47 : HTMLElement(slotTag, document)
48 , m_distributionState(DistributionUnchanged) 48 , m_distributionState(DistributionDone)
49 { 49 {
50 setHasCustomStyleCallbacks(); 50 setHasCustomStyleCallbacks();
51 } 51 }
52 52
53 DEFINE_NODE_FACTORY(HTMLSlotElement); 53 DEFINE_NODE_FACTORY(HTMLSlotElement);
54 54
55 const WillBeHeapVector<RefPtrWillBeMember<Node>> HTMLSlotElement::getAssignedNod esForBinding(const AssignedNodesOptions& options) 55 const WillBeHeapVector<RefPtrWillBeMember<Node>> HTMLSlotElement::getAssignedNod esForBinding(const AssignedNodesOptions& options)
56 { 56 {
57 updateDistribution(); 57 updateDistribution();
58 if (options.hasFlatten() && options.flatten()) 58 if (options.hasFlatten() && options.flatten())
59 return getDistributedNodes(); 59 return getDistributedNodes();
60 return m_assignedNodes; 60 return m_assignedNodes;
61 } 61 }
62 62
63 const WillBeHeapVector<RefPtrWillBeMember<Node>>& HTMLSlotElement::getDistribute dNodes() 63 const WillBeHeapVector<RefPtrWillBeMember<Node>>& HTMLSlotElement::getDistribute dNodes()
64 { 64 {
65 ASSERT(!needsDistributionRecalc()); 65 ASSERT(!needsDistributionRecalc());
66 if (isInShadowTree()) 66 if (isInShadowTree())
67 return m_distributedNodes; 67 return m_distributedNodes;
68 68
69 // A slot is unlikely to be used outside of a shadow tree. 69 // A slot is unlikely to be used outside of a shadow tree.
70 // We do not need to optimize this case in most cases. 70 // We do not need to optimize this case in most cases.
71 // TODO(hayato): If this path causes a performance issue, we should move 71 // TODO(hayato): If this path causes a performance issue, we should move
72 // ShadowRootRaraDate::m_descendantSlots into TreeScopreRareData-ish and 72 // ShadowRootRaraDate::m_descendantSlots into TreeScopreRareData-ish and
73 // update the distribution code so it considers a document tree too. 73 // update the distribution code so it considers a document tree too.
74 clearDistribution(); 74 willUpdateDistribution();
75 for (Node& child : NodeTraversal::childrenOf(*this)) { 75 for (Node& child : NodeTraversal::childrenOf(*this)) {
76 if (!child.isSlotAssignable()) 76 if (!child.isSlotAssignable())
77 continue; 77 continue;
78 if (isHTMLSlotElement(child)) 78 if (isHTMLSlotElement(child))
79 m_distributedNodes.appendVector(toHTMLSlotElement(child).getDistribu tedNodes()); 79 m_distributedNodes.appendVector(toHTMLSlotElement(child).getDistribu tedNodes());
80 else 80 else
81 m_distributedNodes.append(&child); 81 m_distributedNodes.append(&child);
82 } 82 }
83 didUpdateDistribution();
83 return m_distributedNodes; 84 return m_distributedNodes;
84 } 85 }
85 86
86 void HTMLSlotElement::appendAssignedNode(Node& node) 87 void HTMLSlotElement::appendAssignedNode(Node& node)
87 { 88 {
89 ASSERT(m_distributionState == DistributionOnGoing);
88 m_assignedNodes.append(&node); 90 m_assignedNodes.append(&node);
89 } 91 }
90 92
91 void HTMLSlotElement::appendDistributedNode(Node& node) 93 void HTMLSlotElement::appendDistributedNode(Node& node)
92 { 94 {
95 ASSERT(m_distributionState == DistributionOnGoing);
93 size_t size = m_distributedNodes.size(); 96 size_t size = m_distributedNodes.size();
94 m_distributedNodes.append(&node); 97 m_distributedNodes.append(&node);
95 m_distributedIndices.set(&node, size); 98 m_distributedIndices.set(&node, size);
96 } 99 }
97 100
98 void HTMLSlotElement::appendDistributedNodesFrom(const HTMLSlotElement& other) 101 void HTMLSlotElement::appendDistributedNodesFrom(const HTMLSlotElement& other)
99 { 102 {
103 ASSERT(m_distributionState == DistributionOnGoing);
100 size_t index = m_distributedNodes.size(); 104 size_t index = m_distributedNodes.size();
101 m_distributedNodes.appendVector(other.m_distributedNodes); 105 m_distributedNodes.appendVector(other.m_distributedNodes);
102 for (const auto& node : other.m_distributedNodes) 106 for (const auto& node : other.m_distributedNodes)
103 m_distributedIndices.set(node.get(), index++); 107 m_distributedIndices.set(node.get(), index++);
104 } 108 }
105 109
106 void HTMLSlotElement::clearDistribution() 110 void HTMLSlotElement::willUpdateDistribution()
107 { 111 {
112 ASSERT(m_distributionState != DistributionOnGoing);
113 m_distributionState = DistributionOnGoing;
108 m_assignedNodes.clear(); 114 m_assignedNodes.clear();
109 m_oldDistributedNodes.swap(m_distributedNodes); 115 m_oldDistributedNodes.swap(m_distributedNodes);
110 m_distributedNodes.clear(); 116 m_distributedNodes.clear();
111 m_distributedIndices.clear(); 117 m_distributedIndices.clear();
112 m_distributionState = DistributionReset;
113 } 118 }
114 119
115 bool HTMLSlotElement::hasSlotChangeEventListener() 120 bool HTMLSlotElement::hasSlotChangeEventListener()
116 { 121 {
117 return eventTargetData() && eventTargetData()->eventListenerMap.find(EventTy peNames::slotchange); 122 return eventTargetData() && eventTargetData()->eventListenerMap.find(EventTy peNames::slotchange);
118 } 123 }
119 124
120 void HTMLSlotElement::dispatchSlotChangeEvent() 125 void HTMLSlotElement::dispatchSlotChangeEvent()
121 { 126 {
122 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::slotchange); 127 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::slotchange);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 continue; 244 continue;
240 if (isHTMLSlotElement(child)) 245 if (isHTMLSlotElement(child))
241 appendDistributedNodesFrom(toHTMLSlotElement(child)); 246 appendDistributedNodesFrom(toHTMLSlotElement(child));
242 else 247 else
243 appendDistributedNode(child); 248 appendDistributedNode(child);
244 } 249 }
245 } 250 }
246 251
247 bool HTMLSlotElement::distributionChanged() 252 bool HTMLSlotElement::distributionChanged()
248 { 253 {
249 if (m_distributionState == DistributionReset) 254 ASSERT(m_distributionState != DistributionOnGoing);
255 if (m_distributionState == DistributionDone)
250 m_distributionState = m_oldDistributedNodes == m_distributedNodes ? Dist ributionUnchanged : DistributionChanged; 256 m_distributionState = m_oldDistributedNodes == m_distributedNodes ? Dist ributionUnchanged : DistributionChanged;
251 return m_distributionState == DistributionChanged; 257 return m_distributionState == DistributionChanged;
252 } 258 }
253 259
254 void HTMLSlotElement::didUpdateDistribution() 260 void HTMLSlotElement::didUpdateDistribution()
255 { 261 {
262 ASSERT(m_distributionState == DistributionOnGoing);
263 m_distributionState = DistributionDone;
256 if (isChildOfV1ShadowHost()) { 264 if (isChildOfV1ShadowHost()) {
257 ElementShadow* shadow = parentElementShadow(); 265 ElementShadow* shadow = parentElementShadow();
258 ASSERT(shadow); 266 ASSERT(shadow);
259 if (!shadow->needsDistributionRecalc() && distributionChanged()) 267 if (!shadow->needsDistributionRecalc() && distributionChanged())
260 shadow->setNeedsDistributionRecalc(); 268 shadow->setNeedsDistributionRecalc();
261 } 269 }
262 if (hasSlotChangeEventListener() && distributionChanged()) { 270 if (hasSlotChangeEventListener() && distributionChanged()) {
263 // TODO(hayato): Do not enqueue a slotchange event for the same slot twi ce in the microtask queue 271 // TODO(hayato): Do not enqueue a slotchange event for the same slot twi ce in the microtask queue
264 Microtask::enqueueMicrotask(WTF::bind(&HTMLSlotElement::dispatchSlotChan geEvent, PassRefPtrWillBeRawPtr<HTMLSlotElement>(this))); 272 Microtask::enqueueMicrotask(WTF::bind(&HTMLSlotElement::dispatchSlotChan geEvent, PassRefPtrWillBeRawPtr<HTMLSlotElement>(this)));
265 } 273 }
266 } 274 }
267 275
276 void HTMLSlotElement::clearDistribution()
kochi 2016/03/04 03:49:07 Why this is not updateDistribution()? insertedInt
hayato 2016/03/04 05:15:14 Could you elaborate?
kochi 2016/03/04 08:17:15 The previous one was obvious that it "clears" m_di
277 {
278 willUpdateDistribution();
279 didUpdateDistribution();
280 }
281
268 DEFINE_TRACE(HTMLSlotElement) 282 DEFINE_TRACE(HTMLSlotElement)
269 { 283 {
270 #if ENABLE(OILPAN) 284 #if ENABLE(OILPAN)
271 visitor->trace(m_assignedNodes); 285 visitor->trace(m_assignedNodes);
272 visitor->trace(m_distributedNodes); 286 visitor->trace(m_distributedNodes);
273 visitor->trace(m_distributedIndices); 287 visitor->trace(m_distributedIndices);
274 visitor->trace(m_oldDistributedNodes); 288 visitor->trace(m_oldDistributedNodes);
275 #endif 289 #endif
276 HTMLElement::trace(visitor); 290 HTMLElement::trace(visitor);
277 } 291 }
278 292
279 } // namespace blink 293 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698