Chromium Code Reviews| 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..d7bcee68818189ecfa40671510ab91a7e88e7de1 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,60 +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; |
| + callbackQueues().clear(); |
| } |
| void CustomElementScheduler::trace(Visitor* visitor) |
|
esprehn
2014/09/04 02:22:43
Remove this method.
|