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..1dbc7f4140291fc79fd5ef7235f4a6e98ea22f45 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)); |
|
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
|
| + 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,20 @@ 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(); |
| + |
| + SlotChangeList slots; |
| + copyToVector(activeSlotChangeList(), slots); |
|
tkent
2017/01/11 11:24:17
slots.swap(activeSlotChangeList()) should work.
hayato
2017/01/12 03:47:41
Done
|
| + activeSlotChangeList().clear(); |
| + for (const auto& slot : slots) |
| + slot->clearSlotChangeEventEnqueued(); |
| + |
| std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
| for (const auto& observer : observers) { |
| if (observer->shouldBeSuspended()) |
| @@ -268,6 +298,8 @@ void MutationObserver::deliverMutations() { |
| else |
| observer->deliver(); |
| } |
| + for (const auto& slot : slots) |
| + slot->dispatchSlotChangeEvent(); |
| } |
| DEFINE_TRACE(MutationObserver) { |