Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / dom / ShadowRoot.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2015 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Neither the name of Google Inc. nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "ShadowRoot.h"
30
31 #include "AuthorStyleSheets.h"
32 #include "CSSStyleSheet.h"
33 #include "ElementTraversal.h"
34 #include "RenderElement.h"
35 #include "RuntimeEnabledFeatures.h"
36 #include "SlotAssignment.h"
37 #include "StyleResolver.h"
38 #include "markup.h"
39
40 namespace WebCore {
41
42 struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope {
43     unsigned countersAndFlags[1];
44     void* styleResolver;
45     void* authorStyleSheets;
46     void* host;
47 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
48     void* slotAssignment;
49 #endif
50 };
51
52 COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small);
53
54 ShadowRoot::ShadowRoot(Document& document, Type type)
55     : DocumentFragment(document, CreateShadowRoot)
56     , TreeScope(*this, document)
57     , m_type(type)
58 {
59 }
60
61 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
62
63 ShadowRoot::ShadowRoot(Document& document, std::unique_ptr<SlotAssignment>&& slotAssignment)
64     : DocumentFragment(document, CreateShadowRoot)
65     , TreeScope(*this, document)
66     , m_type(Type::UserAgent)
67     , m_slotAssignment(WTFMove(slotAssignment))
68 {
69 }
70
71 #endif
72
73 ShadowRoot::~ShadowRoot()
74 {
75     // We cannot let ContainerNode destructor call willBeDeletedFrom()
76     // for this ShadowRoot instance because TreeScope destructor
77     // clears Node::m_treeScope thus ContainerNode is no longer able
78     // to access it Document reference after that.
79     willBeDeletedFrom(document());
80
81     // We must remove all of our children first before the TreeScope destructor
82     // runs so we don't go through TreeScopeAdopter for each child with a
83     // destructed tree scope in each descendant.
84     removeDetachedChildren();
85 }
86
87 StyleResolver& ShadowRoot::styleResolver()
88 {
89     if (m_type == Type::UserAgent)
90         return document().userAgentShadowTreeStyleResolver();
91
92     if (!m_styleResolver) {
93         // FIXME: We could share style resolver with shadow roots that have identical style.
94         m_styleResolver = std::make_unique<StyleResolver>(document());
95         if (m_authorStyleSheets)
96             m_styleResolver->appendAuthorStyleSheets(m_authorStyleSheets->activeStyleSheets());
97     }
98     return *m_styleResolver;
99 }
100
101 void ShadowRoot::resetStyleResolver()
102 {
103     m_styleResolver = nullptr;
104 }
105
106 AuthorStyleSheets& ShadowRoot::authorStyleSheets()
107 {
108     if (!m_authorStyleSheets)
109         m_authorStyleSheets = std::make_unique<AuthorStyleSheets>(*this);
110     return *m_authorStyleSheets;
111 }
112
113 void ShadowRoot::updateStyle()
114 {
115     bool shouldRecalcStyle = false;
116
117     if (m_authorStyleSheets) {
118         // FIXME: Make optimized updated work.
119         shouldRecalcStyle = m_authorStyleSheets->updateActiveStyleSheets(AuthorStyleSheets::FullUpdate);
120     }
121
122     if (shouldRecalcStyle)
123         setNeedsStyleRecalc();
124 }
125
126 PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionCode& ec)
127 {
128     ec = DATA_CLONE_ERR;
129     return 0;
130 }
131
132 String ShadowRoot::innerHTML() const
133 {
134     return createMarkup(*this, ChildrenOnly);
135 }
136
137 void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
138 {
139     if (isOrphan()) {
140         ec = INVALID_ACCESS_ERR;
141         return;
142     }
143
144     if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, ec))
145         replaceChildrenWithFragment(*this, fragment.releaseNonNull(), ec);
146 }
147
148 bool ShadowRoot::childTypeAllowed(NodeType type) const
149 {
150     switch (type) {
151     case ELEMENT_NODE:
152     case PROCESSING_INSTRUCTION_NODE:
153     case COMMENT_NODE:
154     case TEXT_NODE:
155     case CDATA_SECTION_NODE:
156         return true;
157     default:
158         return false;
159     }
160 }
161
162 void ShadowRoot::setResetStyleInheritance(bool value)
163 {
164     if (isOrphan())
165         return;
166
167     if (value != m_resetStyleInheritance) {
168         m_resetStyleInheritance = value;
169         if (host())
170             setNeedsStyleRecalc();
171     }
172 }
173
174 Ref<Node> ShadowRoot::cloneNodeInternal(Document&, CloningOperation)
175 {
176     RELEASE_ASSERT_NOT_REACHED();
177     return *static_cast<Node*>(nullptr); // ShadowRoots should never be cloned.
178 }
179
180 void ShadowRoot::removeAllEventListeners()
181 {
182     DocumentFragment::removeAllEventListeners();
183     for (Node* node = firstChild(); node; node = NodeTraversal::next(*node))
184         node->removeAllEventListeners();
185 }
186
187 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
188
189 HTMLSlotElement* ShadowRoot::findAssignedSlot(const Node& node)
190 {
191     if (!m_slotAssignment)
192         return nullptr;
193     return m_slotAssignment->findAssignedSlot(node, *this);
194 }
195
196 void ShadowRoot::addSlotElementByName(const AtomicString& name, HTMLSlotElement& slot)
197 {
198     if (!m_slotAssignment)
199         m_slotAssignment = std::make_unique<SlotAssignment>();
200
201     return m_slotAssignment->addSlotElementByName(name, slot, *this);
202 }
203
204 void ShadowRoot::removeSlotElementByName(const AtomicString& name, HTMLSlotElement& slot)
205 {
206     return m_slotAssignment->removeSlotElementByName(name, slot, *this);
207 }
208
209 void ShadowRoot::invalidateSlotAssignments()
210 {
211     if (m_slotAssignment)
212         m_slotAssignment->invalidate(*this);
213 }
214
215 void ShadowRoot::invalidateDefaultSlotAssignments()
216 {
217     if (m_slotAssignment)
218         m_slotAssignment->invalidateDefaultSlot(*this);
219 }
220
221 const Vector<Node*>* ShadowRoot::assignedNodesForSlot(const HTMLSlotElement& slot)
222 {
223     if (!m_slotAssignment)
224         return nullptr;
225     return m_slotAssignment->assignedNodesForSlot(slot, *this);
226 }
227
228 #endif
229
230 }