Index: Source/core/dom/custom/CustomElementScheduler.cpp |
diff --git a/Source/core/dom/custom/CustomElementScheduler.cpp b/Source/core/dom/custom/CustomElementScheduler.cpp |
index b0b2772c2d3f3b8dffe187d1b9216d3a70607f7b..897a9a376f8ae0e96f9f1c090b7f8075afca591d 100644 |
--- a/Source/core/dom/custom/CustomElementScheduler.cpp |
+++ b/Source/core/dom/custom/CustomElementScheduler.cpp |
@@ -49,6 +49,47 @@ namespace blink { |
DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler) |
+// FIXME: Consider moving the element's callback queue to ElementRareData. |
+typedef WillBeHeapHashMap<RawPtrWillBeMember<Element>, OwnPtrWillBeMember<CustomElementCallbackQueue> > ElementCallbackQueueMap; |
+ |
+static ElementCallbackQueueMap& callbackQueues() |
+{ |
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<ElementCallbackQueueMap>, map, (adoptPtrWillBeNoop(new ElementCallbackQueueMap()))); |
+ return *map; |
+} |
+ |
+static CustomElementCallbackQueue& ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element> element) |
+{ |
+ ElementCallbackQueueMap::ValueType* it = callbackQueues().add(element.get(), nullptr).storedValue; |
+ if (!it->value) |
+ it->value = CustomElementCallbackQueue::create(element); |
+ return *it->value.get(); |
+} |
+ |
+// Finds or creates the callback queue for element. |
+static CustomElementCallbackQueue& scheduleCallbackQueue(PassRefPtrWillBeRawPtr<Element> passElement) |
+{ |
+ RefPtrWillBeRawPtr<Element> element(passElement); |
+ |
+ CustomElementCallbackQueue& callbackQueue = ensureCallbackQueue(element); |
+ if (callbackQueue.inCreatedCallback()) { |
+ // Don't move it. Authors use the createdCallback like a |
+ // constructor. By not moving it, the createdCallback |
+ // completes before any other callbacks are entered for this |
+ // element. |
+ return callbackQueue; |
+ } |
+ |
+ if (CustomElementProcessingStack::inCallbackDeliveryScope()) { |
+ // The processing stack is active. |
+ CustomElementProcessingStack::instance().enqueue(&callbackQueue); |
+ return callbackQueue; |
+ } |
+ |
+ CustomElementMicrotaskDispatcher::instance().enqueue(&callbackQueue); |
+ return callbackQueue; |
+} |
+ |
void CustomElementScheduler::scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, CustomElementLifecycleCallbacks::CallbackType type) |
{ |
ASSERT(type != CustomElementLifecycleCallbacks::AttributeChangedCallback); |
@@ -56,7 +97,7 @@ void CustomElementScheduler::scheduleCallback(PassRefPtr<CustomElementLifecycleC |
if (!callbacks->hasCallback(type)) |
return; |
- CustomElementCallbackQueue& queue = instance().schedule(element); |
+ CustomElementCallbackQueue& queue = scheduleCallbackQueue(element); |
queue.append(CustomElementCallbackInvocation::createInvocation(callbacks, type)); |
} |
@@ -65,7 +106,7 @@ void CustomElementScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomE |
if (!callbacks->hasCallback(CustomElementLifecycleCallbacks::AttributeChangedCallback)) |
return; |
- CustomElementCallbackQueue& queue = instance().schedule(element); |
+ CustomElementCallbackQueue& queue = scheduleCallbackQueue(element); |
queue.append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue)); |
} |
@@ -100,67 +141,17 @@ void CustomElementScheduler::enqueueMicrotaskStep(Document& document, PassOwnPtr |
master.customElementMicrotaskRunQueue()->enqueue(document.importLoader(), step, importIsSync); |
} |
-CustomElementScheduler& CustomElementScheduler::instance() |
-{ |
- DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CustomElementScheduler>, instance, (adoptPtrWillBeNoop (new CustomElementScheduler()))); |
- return *instance; |
-} |
- |
-CustomElementCallbackQueue& CustomElementScheduler::ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element> element) |
-{ |
- ElementCallbackQueueMap::ValueType* it = m_elementCallbackQueueMap.add(element.get(), nullptr).storedValue; |
- if (!it->value) |
- it->value = CustomElementCallbackQueue::create(element); |
- return *it->value.get(); |
-} |
void CustomElementScheduler::callbackDispatcherDidFinish() |
{ |
if (CustomElementMicrotaskDispatcher::instance().elementQueueIsEmpty()) |
- instance().clearElementCallbackQueueMap(); |
+ callbackQueues().clear(); |
} |
void CustomElementScheduler::microtaskDispatcherDidFinish() |
{ |
ASSERT(!CustomElementProcessingStack::inCallbackDeliveryScope()); |
- instance().clearElementCallbackQueueMap(); |
-} |
- |
-void CustomElementScheduler::clearElementCallbackQueueMap() |
-{ |
- ElementCallbackQueueMap emptyMap; |
- m_elementCallbackQueueMap.swap(emptyMap); |
-} |
- |
-// Finds or creates the callback queue for element. |
-CustomElementCallbackQueue& CustomElementScheduler::schedule(PassRefPtrWillBeRawPtr<Element> passElement) |
-{ |
- RefPtrWillBeRawPtr<Element> element(passElement); |
- |
- CustomElementCallbackQueue& callbackQueue = ensureCallbackQueue(element); |
- if (callbackQueue.inCreatedCallback()) { |
- // Don't move it. Authors use the createdCallback like a |
- // constructor. By not moving it, the createdCallback |
- // completes before any other callbacks are entered for this |
- // element. |
- return callbackQueue; |
- } |
- |
- if (CustomElementProcessingStack::inCallbackDeliveryScope()) { |
- // The processing stack is active. |
- CustomElementProcessingStack::instance().enqueue(&callbackQueue); |
- return callbackQueue; |
- } |
- |
- CustomElementMicrotaskDispatcher::instance().enqueue(&callbackQueue); |
- return callbackQueue; |
-} |
- |
-void CustomElementScheduler::trace(Visitor* visitor) |
-{ |
-#if ENABLE(OILPAN) |
- visitor->trace(m_elementCallbackQueueMap); |
-#endif |
+ callbackQueues().clear(); |
} |
} // namespace blink |