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

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: fixed 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));
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
202 void MutationObserver::cleanSlotChangeList(Document& document) {
203 SlotChangeList kept;
204 kept.reserveCapacity(activeSlotChangeList().size());
205 for (auto& slot : activeSlotChangeList()) {
206 if (slot->document() != document)
207 kept.push_back(slot);
208 }
209 activeSlotChangeList().swap(kept);
210 }
211
180 static void activateObserver(MutationObserver* observer) { 212 static void activateObserver(MutationObserver* observer) {
181 if (activeMutationObservers().isEmpty()) 213 ensureEnqueueMicrotask();
182 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));
183
184 activeMutationObservers().add(observer); 214 activeMutationObservers().add(observer);
185 } 215 }
186 216
187 void MutationObserver::enqueueMutationRecord(MutationRecord* mutation) { 217 void MutationObserver::enqueueMutationRecord(MutationRecord* mutation) {
188 DCHECK(isMainThread()); 218 DCHECK(isMainThread());
189 m_records.push_back(mutation); 219 m_records.push_back(mutation);
190 activateObserver(this); 220 activateObserver(this);
191 InspectorInstrumentation::asyncTaskScheduled( 221 InspectorInstrumentation::asyncTaskScheduled(
192 m_callback->getExecutionContext(), mutation->type(), mutation); 222 m_callback->getExecutionContext(), mutation->type(), mutation);
193 } 223 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 copyToVector(suspendedMutationObservers(), suspended); 280 copyToVector(suspendedMutationObservers(), suspended);
251 for (const auto& observer : suspended) { 281 for (const auto& observer : suspended) {
252 if (!observer->shouldBeSuspended()) { 282 if (!observer->shouldBeSuspended()) {
253 suspendedMutationObservers().remove(observer); 283 suspendedMutationObservers().remove(observer);
254 activateObserver(observer); 284 activateObserver(observer);
255 } 285 }
256 } 286 }
257 } 287 }
258 288
259 void MutationObserver::deliverMutations() { 289 void MutationObserver::deliverMutations() {
290 // These steps are defined in DOM Standard's "notify mutation observers".
291 // https://dom.spec.whatwg.org/#notify-mutation-observers
260 DCHECK(isMainThread()); 292 DCHECK(isMainThread());
293
261 MutationObserverVector observers; 294 MutationObserverVector observers;
262 copyToVector(activeMutationObservers(), observers); 295 copyToVector(activeMutationObservers(), observers);
263 activeMutationObservers().clear(); 296 activeMutationObservers().clear();
297
298 SlotChangeList slots;
299 slots.swap(activeSlotChangeList());
300 for (const auto& slot : slots)
301 slot->clearSlotChangeEventEnqueued();
302
264 std::sort(observers.begin(), observers.end(), ObserverLessThan()); 303 std::sort(observers.begin(), observers.end(), ObserverLessThan());
265 for (const auto& observer : observers) { 304 for (const auto& observer : observers) {
266 if (observer->shouldBeSuspended()) 305 if (observer->shouldBeSuspended())
267 suspendedMutationObservers().add(observer); 306 suspendedMutationObservers().add(observer);
268 else 307 else
269 observer->deliver(); 308 observer->deliver();
270 } 309 }
310 for (const auto& slot : slots)
311 slot->dispatchSlotChangeEvent();
271 } 312 }
272 313
273 DEFINE_TRACE(MutationObserver) { 314 DEFINE_TRACE(MutationObserver) {
274 visitor->trace(m_callback); 315 visitor->trace(m_callback);
275 visitor->trace(m_records); 316 visitor->trace(m_records);
276 visitor->trace(m_registrations); 317 visitor->trace(m_registrations);
277 visitor->trace(m_callback); 318 visitor->trace(m_callback);
278 } 319 }
279 320
280 } // namespace blink 321 } // 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