Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/MutationObserver.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.cpp b/third_party/WebKit/Source/core/dom/MutationObserver.cpp |
| index 9bf8da6324c473ddc0fd6fc2f1d21646150d391c..dffd4d5d5733a5492a91171aa782d38bc5cd693e 100644 |
| --- a/third_party/WebKit/Source/core/dom/MutationObserver.cpp |
| +++ b/third_party/WebKit/Source/core/dom/MutationObserver.cpp |
| @@ -37,6 +37,7 @@ |
| #include "core/dom/MutationObserverRegistration.h" |
| #include "core/dom/MutationRecord.h" |
| #include "core/dom/Node.h" |
| +#include "core/html/HTMLSlotElement.h" |
| #include "core/inspector/InspectorInstrumentation.h" |
| #include <algorithm> |
| @@ -171,16 +172,35 @@ static MutationObserverSet& activeMutationObservers() { |
| return activeObservers; |
| } |
| +using SlotChangeList = HeapVector<Member<HTMLSlotElement>>; |
| + |
| +// TODO(hayato): We should have a SlotChangeList for each unit of related |
| +// similar-origin browsing context. |
| +// https://html.spec.whatwg.org/multipage/browsers.html#unit-of-related-similar-origin-browsing-contexts |
| +static SlotChangeList& activeSlotChangeList() { |
| + DEFINE_STATIC_LOCAL(SlotChangeList, slotChangeList, (new SlotChangeList)); |
| + return slotChangeList; |
| +} |
| + |
| static MutationObserverSet& suspendedMutationObservers() { |
| DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, |
| (new MutationObserverSet)); |
| return suspendedObservers; |
| } |
| -static void activateObserver(MutationObserver* observer) { |
| - if (activeMutationObservers().isEmpty()) |
| +static void ensureEnqueueMicrotask() { |
| + if (activeMutationObservers().isEmpty() && activeSlotChangeList().isEmpty()) |
| Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations)); |
| +} |
| + |
| +void MutationObserver::enqueueSlotChange(HTMLSlotElement& slot) { |
| + DCHECK(isMainThread()); |
| + ensureEnqueueMicrotask(); |
| + activeSlotChangeList().push_back(&slot); |
| +} |
| +static void activateObserver(MutationObserver* observer) { |
| + ensureEnqueueMicrotask(); |
| activeMutationObservers().add(observer); |
| } |
| @@ -257,10 +277,19 @@ void MutationObserver::resumeSuspendedObservers() { |
| } |
| void MutationObserver::deliverMutations() { |
| + // These steps are defined in DOM Standard's "notify mutation observers". |
| + // https://dom.spec.whatwg.org/#notify-mutation-observers |
| DCHECK(isMainThread()); |
| + |
| MutationObserverVector observers; |
| copyToVector(activeMutationObservers(), observers); |
| activeMutationObservers().clear(); |
|
kochi
2017/01/12 04:57:55
Can the same .swap() be used for activeMutationObs
hayato
2017/01/12 06:30:17
No. activeMutationObserevers() returns HeapHashSet
|
| + |
| + SlotChangeList slots; |
| + slots.swap(activeSlotChangeList()); |
| + for (const auto& slot : slots) |
| + slot->clearSlotChangeEventEnqueued(); |
| + |
| std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
| for (const auto& observer : observers) { |
| if (observer->shouldBeSuspended()) |
| @@ -268,6 +297,8 @@ void MutationObserver::deliverMutations() { |
| else |
| observer->deliver(); |
| } |
| + for (const auto& slot : slots) |
| + slot->dispatchSlotChangeEvent(); |
| } |
| DEFINE_TRACE(MutationObserver) { |