109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/*
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * modification, are permitted provided that the following conditions
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * are met:
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    in the documentation and/or other materials provided with the
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    distribution.
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * 3. Neither the name of Google Inc. nor the names of its contributors
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    may be used to endorse or promote products derived from this
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *    software without specific prior written permission.
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "config.h"
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementScheduler.h"
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/Document.h"
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/Element.h"
3609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementCallbackInvocation.h"
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/custom/CustomElementMicrotaskRunQueue.h"
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/dom/custom/CustomElementProcessingStack.h"
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/custom/CustomElementRegistrationContext.h"
44197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/html/imports/HTMLImportChild.h"
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/html/imports/HTMLImportsController.h"
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler)
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// FIXME: Consider moving the element's callback queue to ElementRareData.
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitypedef WillBeHeapHashMap<RawPtrWillBeMember<Element>, OwnPtrWillBeMember<CustomElementCallbackQueue> > ElementCallbackQueueMap;
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic ElementCallbackQueueMap& callbackQueues()
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<ElementCallbackQueueMap>, map, (adoptPtrWillBeNoop(new ElementCallbackQueueMap())));
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return *map;
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic CustomElementCallbackQueue& ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element> element)
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ElementCallbackQueueMap::ValueType* it = callbackQueues().add(element.get(), nullptr).storedValue;
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!it->value)
657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        it->value = CustomElementCallbackQueue::create(element);
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return *it->value.get();
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Finds or creates the callback queue for element.
707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic CustomElementCallbackQueue& scheduleCallbackQueue(PassRefPtrWillBeRawPtr<Element> passElement)
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtrWillBeRawPtr<Element> element(passElement);
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CustomElementCallbackQueue& callbackQueue = ensureCallbackQueue(element);
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (callbackQueue.inCreatedCallback()) {
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // Don't move it. Authors use the createdCallback like a
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // constructor. By not moving it, the createdCallback
787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // completes before any other callbacks are entered for this
797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // element.
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return callbackQueue;
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (CustomElementProcessingStack::inCallbackDeliveryScope()) {
847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // The processing stack is active.
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CustomElementProcessingStack::instance().enqueue(&callbackQueue);
867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return callbackQueue;
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CustomElementMicrotaskDispatcher::instance().enqueue(&callbackQueue);
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return callbackQueue;
917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
93d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CustomElementScheduler::scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, CustomElementLifecycleCallbacks::CallbackType type)
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(type != CustomElementLifecycleCallbacks::AttributeChangedCallback);
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
97aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (!callbacks->hasCallback(type))
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CustomElementCallbackQueue& queue = scheduleCallbackQueue(element);
101aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    queue.append(CustomElementCallbackInvocation::createInvocation(callbacks, type));
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
104d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CustomElementScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!callbacks->hasCallback(CustomElementLifecycleCallbacks::AttributeChangedCallback))
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    CustomElementCallbackQueue& queue = scheduleCallbackQueue(element);
110aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    queue.append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
113d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void CustomElementScheduler::resolveOrScheduleResolution(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (CustomElementProcessingStack::inCallbackDeliveryScope()) {
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        context->resolve(element.get(), descriptor);
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Document& document = element->document();
121d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    OwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> step = CustomElementMicrotaskResolutionStep::create(context, element, descriptor);
122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    enqueueMicrotaskStep(document, step.release());
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)CustomElementMicrotaskImportStep* CustomElementScheduler::scheduleImport(HTMLImportChild* import)
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(!import->isDone());
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(import->parent());
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Ownership of the new step is transferred to the parent
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // processing step, or the base queue.
132f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    OwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step = CustomElementMicrotaskImportStep::create(import);
133f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    CustomElementMicrotaskImportStep* rawStep = step.get();
134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    enqueueMicrotaskStep(*(import->parent()->document()), step.release(), import->isSync());
13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return rawStep;
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
138197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid CustomElementScheduler::enqueueMicrotaskStep(Document& document, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step, bool importIsSync)
139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Document& master = document.importsController() ? *(document.importsController()->master()) : document;
141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    master.customElementMicrotaskRunQueue()->enqueue(document.importLoader(), step, importIsSync);
142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void CustomElementScheduler::callbackDispatcherDidFinish()
14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (CustomElementMicrotaskDispatcher::instance().elementQueueIsEmpty())
1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        callbackQueues().clear();
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void CustomElementScheduler::microtaskDispatcherDidFinish()
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(!CustomElementProcessingStack::inCallbackDeliveryScope());
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    callbackQueues().clear();
155d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
156d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
157c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
158