Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / dom / CustomElementRegistry.cpp
1 /*
2  * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "CustomElementRegistry.h"
28
29 #include "CustomElementReactionQueue.h"
30 #include "DOMWindow.h"
31 #include "Document.h"
32 #include "Element.h"
33 #include "ElementTraversal.h"
34 #include "JSCustomElementInterface.h"
35 #include "MathMLNames.h"
36 #include "QualifiedName.h"
37 #include "ShadowRoot.h"
38 #include <runtime/JSCJSValueInlines.h>
39 #include <wtf/text/AtomicString.h>
40
41 namespace WebCore {
42
43 Ref<CustomElementRegistry> CustomElementRegistry::create(DOMWindow& window)
44 {
45     return adoptRef(*new CustomElementRegistry(window));
46 }
47
48 CustomElementRegistry::CustomElementRegistry(DOMWindow& window)
49     : m_window(window)
50 {
51 }
52
53 CustomElementRegistry::~CustomElementRegistry() = default;
54
55 // https://dom.spec.whatwg.org/#concept-shadow-including-tree-order
56 static void enqueueUpgradeInShadowIncludingTreeOrder(ContainerNode& node, JSCustomElementInterface& elementInterface)
57 {
58     for (Element* element = ElementTraversal::firstWithin(node); element; element = ElementTraversal::next(*element)) {
59         if (element->isCustomElementUpgradeCandidate() && element->tagQName() == elementInterface.name())
60             element->enqueueToUpgrade(elementInterface);
61         if (auto* shadowRoot = element->shadowRoot()) {
62             if (shadowRoot->mode() != ShadowRootMode::UserAgent)
63                 enqueueUpgradeInShadowIncludingTreeOrder(*shadowRoot, elementInterface);
64         }
65     }
66 }
67
68 void CustomElementRegistry::addElementDefinition(Ref<JSCustomElementInterface>&& elementInterface)
69 {
70     AtomicString localName = elementInterface->name().localName();
71     ASSERT(!m_nameMap.contains(localName));
72     m_constructorMap.add(elementInterface->constructor(), elementInterface.ptr());
73     m_nameMap.add(localName, elementInterface.copyRef());
74
75     if (auto* document = m_window.document())
76         enqueueUpgradeInShadowIncludingTreeOrder(*document, elementInterface.get());
77
78     if (auto promise = m_promiseMap.take(localName))
79         promise.value()->resolve();
80 }
81
82 JSCustomElementInterface* CustomElementRegistry::findInterface(const Element& element) const
83 {
84     return findInterface(element.tagQName());
85 }
86
87 JSCustomElementInterface* CustomElementRegistry::findInterface(const QualifiedName& name) const
88 {
89     if (name.namespaceURI() != HTMLNames::xhtmlNamespaceURI)
90         return nullptr;
91     return m_nameMap.get(name.localName());
92 }
93
94 JSCustomElementInterface* CustomElementRegistry::findInterface(const AtomicString& name) const
95 {
96     return m_nameMap.get(name);
97 }
98
99 JSCustomElementInterface* CustomElementRegistry::findInterface(const JSC::JSObject* constructor) const
100 {
101     return m_constructorMap.get(constructor);
102 }
103
104 bool CustomElementRegistry::containsConstructor(const JSC::JSObject* constructor) const
105 {
106     return m_constructorMap.contains(constructor);
107 }
108
109 JSC::JSValue CustomElementRegistry::get(const AtomicString& name)
110 {
111     if (auto* elementInterface = m_nameMap.get(name))
112         return elementInterface->constructor();
113     return JSC::jsUndefined();
114 }
115
116 }