Index: Source/core/dom/MutationObserver.cpp |
diff --git a/Source/core/dom/MutationObserver.cpp b/Source/core/dom/MutationObserver.cpp |
index 4402477d9e6fc8674f65f8df1b94c70a8dda4f40..21bdd693b54f76cd875ed58e981969bdc9814b58 100644 |
--- a/Source/core/dom/MutationObserver.cpp |
+++ b/Source/core/dom/MutationObserver.cpp |
@@ -36,6 +36,7 @@ |
#include "bindings/v8/ExceptionState.h" |
#include "core/dom/Document.h" |
#include "core/dom/ExceptionCode.h" |
+#include "core/dom/Microtask.h" |
#include "core/dom/MutationCallback.h" |
#include "core/dom/MutationObserverRegistration.h" |
#include "core/dom/MutationRecord.h" |
@@ -182,18 +183,26 @@ static MutationObserverSet& suspendedMutationObservers() |
return suspendedObservers; |
} |
+static void activateObserver(PassRefPtr<MutationObserver> observer) |
+{ |
+ if (activeMutationObservers().isEmpty()) |
+ Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); |
+ |
+ activeMutationObservers().add(observer); |
+} |
+ |
void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation) |
{ |
ASSERT(isMainThread()); |
m_records.append(mutation); |
- activeMutationObservers().add(this); |
+ activateObserver(this); |
InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionContext(), this); |
} |
void MutationObserver::setHasTransientRegistration() |
{ |
ASSERT(isMainThread()); |
- activeMutationObservers().add(this); |
+ activateObserver(this); |
} |
HashSet<Node*> MutationObserver::getObservedNodes() const |
@@ -234,40 +243,35 @@ void MutationObserver::deliver() |
InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionContext()); |
} |
-void MutationObserver::deliverAllMutations() |
+void MutationObserver::resumeSuspendedObservers() |
{ |
ASSERT(isMainThread()); |
- static bool deliveryInProgress = false; |
- if (deliveryInProgress) |
+ if (suspendedMutationObservers().isEmpty()) |
return; |
- deliveryInProgress = true; |
- |
- if (!suspendedMutationObservers().isEmpty()) { |
- Vector<RefPtr<MutationObserver> > suspended; |
- copyToVector(suspendedMutationObservers(), suspended); |
- for (size_t i = 0; i < suspended.size(); ++i) { |
- if (!suspended[i]->canDeliver()) |
- continue; |
+ Vector<RefPtr<MutationObserver> > suspended; |
+ copyToVector(suspendedMutationObservers(), suspended); |
+ for (size_t i = 0; i < suspended.size(); ++i) { |
+ if (suspended[i]->canDeliver()) { |
suspendedMutationObservers().remove(suspended[i]); |
- activeMutationObservers().add(suspended[i]); |
+ activateObserver(suspended[i]); |
} |
} |
+} |
- while (!activeMutationObservers().isEmpty()) { |
- Vector<RefPtr<MutationObserver> > observers; |
- copyToVector(activeMutationObservers(), observers); |
- activeMutationObservers().clear(); |
- std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
- for (size_t i = 0; i < observers.size(); ++i) { |
- if (observers[i]->canDeliver()) |
- observers[i]->deliver(); |
- else |
- suspendedMutationObservers().add(observers[i]); |
- } |
+void MutationObserver::deliverMutations() |
+{ |
+ ASSERT(isMainThread()); |
+ Vector<RefPtr<MutationObserver> > observers; |
+ copyToVector(activeMutationObservers(), observers); |
+ activeMutationObservers().clear(); |
+ std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
+ for (size_t i = 0; i < observers.size(); ++i) { |
+ if (observers[i]->canDeliver()) |
+ observers[i]->deliver(); |
+ else |
+ suspendedMutationObservers().add(observers[i]); |
} |
- |
- deliveryInProgress = false; |
} |
} // namespace WebCore |