Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / page / UserContentController.cpp
1 /*
2  * Copyright (C) 2014-2015 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "UserContentController.h"
28
29 #include "DOMWrapperWorld.h"
30 #include "Document.h"
31 #include "DocumentLoader.h"
32 #include "ExtensionStyleSheets.h"
33 #include "MainFrame.h"
34 #include "Page.h"
35 #include "ResourceLoadInfo.h"
36 #include "UserScript.h"
37 #include "UserStyleSheet.h"
38 #include <runtime/JSCellInlines.h>
39 #include <runtime/StructureInlines.h>
40
41 #if ENABLE(USER_MESSAGE_HANDLERS)
42 #include "UserMessageHandlerDescriptor.h"
43 #endif
44
45 #if ENABLE(CONTENT_EXTENSIONS)
46 #include "ContentExtensionCompiler.h"
47 #include "ContentExtensionsBackend.h"
48 #endif
49
50 namespace WebCore {
51
52 Ref<UserContentController> UserContentController::create()
53 {
54     return adoptRef(*new UserContentController);
55 }
56
57 UserContentController::UserContentController()
58 {
59 }
60
61 UserContentController::~UserContentController()
62 {
63 }
64
65 void UserContentController::addPage(Page& page)
66 {
67     ASSERT(!m_pages.contains(&page));
68     m_pages.add(&page);
69 }
70
71 void UserContentController::removePage(Page& page)
72 {
73     ASSERT(m_pages.contains(&page));
74     m_pages.remove(&page);
75 }
76
77 void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
78 {
79     if (!m_userScripts)
80         m_userScripts = std::make_unique<UserScriptMap>();
81
82     auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
83     if (!scriptsInWorld)
84         scriptsInWorld = std::make_unique<UserScriptVector>();
85     scriptsInWorld->append(WTFMove(userScript));
86 }
87
88 void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
89 {
90     if (!m_userScripts)
91         return;
92
93     auto it = m_userScripts->find(&world);
94     if (it == m_userScripts->end())
95         return;
96
97     auto scripts = it->value.get();
98     for (int i = scripts->size() - 1; i >= 0; --i) {
99         if (scripts->at(i)->url() == url)
100             scripts->remove(i);
101     }
102
103     if (scripts->isEmpty())
104         m_userScripts->remove(it);
105 }
106
107 void UserContentController::removeUserScripts(DOMWrapperWorld& world)
108 {
109     if (!m_userScripts)
110         return;
111
112     m_userScripts->remove(&world);
113 }
114
115 void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
116 {
117     if (!m_userStyleSheets)
118         m_userStyleSheets = std::make_unique<UserStyleSheetMap>();
119
120     auto& styleSheetsInWorld = m_userStyleSheets->add(&world, nullptr).iterator->value;
121     if (!styleSheetsInWorld)
122         styleSheetsInWorld = std::make_unique<UserStyleSheetVector>();
123     styleSheetsInWorld->append(WTFMove(userStyleSheet));
124
125     if (injectionTime == InjectInExistingDocuments)
126         invalidateInjectedStyleSheetCacheInAllFrames();
127 }
128
129 void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
130 {
131     if (!m_userStyleSheets)
132         return;
133
134     auto it = m_userStyleSheets->find(&world);
135     if (it == m_userStyleSheets->end())
136         return;
137
138     auto& stylesheets = *it->value;
139
140     bool sheetsChanged = false;
141     for (int i = stylesheets.size() - 1; i >= 0; --i) {
142         if (stylesheets[i]->url() == url) {
143             stylesheets.remove(i);
144             sheetsChanged = true;
145         }
146     }
147
148     if (!sheetsChanged)
149         return;
150
151     if (stylesheets.isEmpty())
152         m_userStyleSheets->remove(it);
153
154     invalidateInjectedStyleSheetCacheInAllFrames();
155 }
156
157 void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
158 {
159     if (!m_userStyleSheets)
160         return;
161
162     if (!m_userStyleSheets->remove(&world))
163         return;
164
165     invalidateInjectedStyleSheetCacheInAllFrames();
166 }
167
168 #if ENABLE(USER_MESSAGE_HANDLERS)
169 void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
170 {
171     if (!m_userMessageHandlerDescriptors)
172         m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
173
174     m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
175 }
176
177 void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
178 {
179     if (!m_userMessageHandlerDescriptors)
180         return;
181
182     m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
183 }
184 #endif
185
186 #if ENABLE(CONTENT_EXTENSIONS)
187 void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
188 {
189     if (!m_contentExtensionBackend)
190         m_contentExtensionBackend = std::make_unique<ContentExtensions::ContentExtensionsBackend>();
191     
192     m_contentExtensionBackend->addContentExtension(name, contentExtension);
193 }
194
195 void UserContentController::removeUserContentExtension(const String& name)
196 {
197     if (!m_contentExtensionBackend)
198         return;
199
200     m_contentExtensionBackend->removeContentExtension(name);
201 }
202
203 void UserContentController::removeAllUserContentExtensions()
204 {
205     if (!m_contentExtensionBackend)
206         return;
207
208     m_contentExtensionBackend->removeAllContentExtensions();
209 }
210
211 static bool contentExtensionsEnabled(const DocumentLoader& documentLoader)
212 {
213     if (auto frame = documentLoader.frame()) {
214         if (frame->isMainFrame())
215             return documentLoader.userContentExtensionsEnabled();
216         if (auto mainDocumentLoader = frame->mainFrame().loader().documentLoader())
217             return mainDocumentLoader->userContentExtensionsEnabled();
218     }
219
220     return true;
221 }
222     
223 ContentExtensions::BlockedStatus UserContentController::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
224 {
225     if (!m_contentExtensionBackend)
226         return ContentExtensions::BlockedStatus::NotBlocked;
227
228     if (!contentExtensionsEnabled(initiatingDocumentLoader))
229         return ContentExtensions::BlockedStatus::NotBlocked;
230
231     return m_contentExtensionBackend->processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
232 }
233
234 Vector<ContentExtensions::Action> UserContentController::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo, DocumentLoader& initiatingDocumentLoader)
235 {
236     if (!m_contentExtensionBackend)
237         return Vector<ContentExtensions::Action>();
238     
239     if (!contentExtensionsEnabled(initiatingDocumentLoader))
240         return Vector<ContentExtensions::Action>();
241
242     return m_contentExtensionBackend->actionsForResourceLoad(resourceLoadInfo);
243 }
244 #endif
245
246 void UserContentController::removeAllUserContent()
247 {
248     m_userScripts = nullptr;
249
250     if (m_userStyleSheets) {
251         m_userStyleSheets = nullptr;
252         invalidateInjectedStyleSheetCacheInAllFrames();
253     }
254 }
255
256 void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
257 {
258     for (auto& page : m_pages) {
259         for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
260             frame->document()->extensionStyleSheets().invalidateInjectedStyleSheetCache();
261             frame->document()->styleResolverChanged(DeferRecalcStyle);
262         }
263     }
264 }
265
266 } // namespace WebCore