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

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

Issue 2622193002: Dispatch slotchange events in "notify mutation observers" steps (Closed)
Patch Set: Created 3 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) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 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 19 matching lines...) Expand all
30 30
31 #include "core/dom/MutationObserver.h" 31 #include "core/dom/MutationObserver.h"
32 32
33 #include "bindings/core/v8/ExceptionState.h" 33 #include "bindings/core/v8/ExceptionState.h"
34 #include "bindings/core/v8/Microtask.h" 34 #include "bindings/core/v8/Microtask.h"
35 #include "core/dom/MutationCallback.h" 35 #include "core/dom/MutationCallback.h"
36 #include "core/dom/MutationObserverInit.h" 36 #include "core/dom/MutationObserverInit.h"
37 #include "core/dom/MutationObserverRegistration.h" 37 #include "core/dom/MutationObserverRegistration.h"
38 #include "core/dom/MutationRecord.h" 38 #include "core/dom/MutationRecord.h"
39 #include "core/dom/Node.h" 39 #include "core/dom/Node.h"
40 #include "core/html/HTMLSlotElement.h"
40 #include "core/inspector/InspectorInstrumentation.h" 41 #include "core/inspector/InspectorInstrumentation.h"
41 #include <algorithm> 42 #include <algorithm>
42 43
43 namespace blink { 44 namespace blink {
44 45
45 static unsigned s_observerPriority = 0; 46 static unsigned s_observerPriority = 0;
46 47
47 struct MutationObserver::ObserverLessThan { 48 struct MutationObserver::ObserverLessThan {
48 bool operator()(const Member<MutationObserver>& lhs, 49 bool operator()(const Member<MutationObserver>& lhs,
49 const Member<MutationObserver>& rhs) { 50 const Member<MutationObserver>& rhs) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 DCHECK(m_registrations.contains(registration)); 165 DCHECK(m_registrations.contains(registration));
165 m_registrations.remove(registration); 166 m_registrations.remove(registration);
166 } 167 }
167 168
168 static MutationObserverSet& activeMutationObservers() { 169 static MutationObserverSet& activeMutationObservers() {
169 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, 170 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers,
170 (new MutationObserverSet)); 171 (new MutationObserverSet));
171 return activeObservers; 172 return activeObservers;
172 } 173 }
173 174
175 using SlotChangeList = HeapVector<Member<HTMLSlotElement>>;
176
177 // TODO(hayato): We should have a SlotChangeList for each unit of related
178 // similar-origin browsing context.
179 // https://html.spec.whatwg.org/multipage/browsers.html#unit-of-related-similar- origin-browsing-contexts
180 static SlotChangeList& activeSlotChangeList() {
181 DEFINE_STATIC_LOCAL(SlotChangeList, slotChangeList, (new SlotChangeList));
tkent 2017/01/11 11:24:17 I'm afraid static strong references to HTMLSlotEle
hayato 2017/01/12 03:47:41 The content of |slotlist| is always cleared at the
tkent 2017/01/12 06:24:35 Is the microtask guaranteed to be executed? Is v8
182 return slotChangeList;
183 }
184
174 static MutationObserverSet& suspendedMutationObservers() { 185 static MutationObserverSet& suspendedMutationObservers() {
175 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, 186 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers,
176 (new MutationObserverSet)); 187 (new MutationObserverSet));
177 return suspendedObservers; 188 return suspendedObservers;
178 } 189 }
179 190
191 static void ensureEnqueueMicrotask() {
192 if (activeMutationObservers().isEmpty() && activeSlotChangeList().isEmpty())
193 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));
194 }
195
196 void MutationObserver::enqueueSlotChange(HTMLSlotElement& slot) {
197 DCHECK(isMainThread());
198 ensureEnqueueMicrotask();
199 activeSlotChangeList().push_back(&slot);
200 }
201
180 static void activateObserver(MutationObserver* observer) { 202 static void activateObserver(MutationObserver* observer) {
181 if (activeMutationObservers().isEmpty()) 203 ensureEnqueueMicrotask();
182 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));
183
184 activeMutationObservers().add(observer); 204 activeMutationObservers().add(observer);
185 } 205 }
186 206
187 void MutationObserver::enqueueMutationRecord(MutationRecord* mutation) { 207 void MutationObserver::enqueueMutationRecord(MutationRecord* mutation) {
188 DCHECK(isMainThread()); 208 DCHECK(isMainThread());
189 m_records.push_back(mutation); 209 m_records.push_back(mutation);
190 activateObserver(this); 210 activateObserver(this);
191 InspectorInstrumentation::asyncTaskScheduled( 211 InspectorInstrumentation::asyncTaskScheduled(
192 m_callback->getExecutionContext(), mutation->type(), mutation); 212 m_callback->getExecutionContext(), mutation->type(), mutation);
193 } 213 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 copyToVector(suspendedMutationObservers(), suspended); 270 copyToVector(suspendedMutationObservers(), suspended);
251 for (const auto& observer : suspended) { 271 for (const auto& observer : suspended) {
252 if (!observer->shouldBeSuspended()) { 272 if (!observer->shouldBeSuspended()) {
253 suspendedMutationObservers().remove(observer); 273 suspendedMutationObservers().remove(observer);
254 activateObserver(observer); 274 activateObserver(observer);
255 } 275 }
256 } 276 }
257 } 277 }
258 278
259 void MutationObserver::deliverMutations() { 279 void MutationObserver::deliverMutations() {
280 // These steps are defined in DOM Standard's "notify mutation observers".
281 // https://dom.spec.whatwg.org/#notify-mutation-observers
260 DCHECK(isMainThread()); 282 DCHECK(isMainThread());
283
261 MutationObserverVector observers; 284 MutationObserverVector observers;
262 copyToVector(activeMutationObservers(), observers); 285 copyToVector(activeMutationObservers(), observers);
263 activeMutationObservers().clear(); 286 activeMutationObservers().clear();
287
288 SlotChangeList slots;
289 copyToVector(activeSlotChangeList(), slots);
tkent 2017/01/11 11:24:17 slots.swap(activeSlotChangeList()) should work.
hayato 2017/01/12 03:47:41 Done
290 activeSlotChangeList().clear();
291 for (const auto& slot : slots)
292 slot->clearSlotChangeEventEnqueued();
293
264 std::sort(observers.begin(), observers.end(), ObserverLessThan()); 294 std::sort(observers.begin(), observers.end(), ObserverLessThan());
265 for (const auto& observer : observers) { 295 for (const auto& observer : observers) {
266 if (observer->shouldBeSuspended()) 296 if (observer->shouldBeSuspended())
267 suspendedMutationObservers().add(observer); 297 suspendedMutationObservers().add(observer);
268 else 298 else
269 observer->deliver(); 299 observer->deliver();
270 } 300 }
301 for (const auto& slot : slots)
302 slot->dispatchSlotChangeEvent();
271 } 303 }
272 304
273 DEFINE_TRACE(MutationObserver) { 305 DEFINE_TRACE(MutationObserver) {
274 visitor->trace(m_callback); 306 visitor->trace(m_callback);
275 visitor->trace(m_records); 307 visitor->trace(m_records);
276 visitor->trace(m_registrations); 308 visitor->trace(m_registrations);
277 visitor->trace(m_callback); 309 visitor->trace(m_callback);
278 } 310 }
279 311
280 } // namespace blink 312 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/MutationObserver.h ('k') | third_party/WebKit/Source/core/html/HTMLSlotElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698