| 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
|
|
|