2 * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "UserContentController.h"
29 #include "DOMWrapperWorld.h"
31 #include "DocumentLoader.h"
32 #include "ExtensionStyleSheets.h"
33 #include "MainFrame.h"
35 #include "ResourceLoadInfo.h"
36 #include "UserScript.h"
37 #include "UserStyleSheet.h"
38 #include <runtime/JSCellInlines.h>
39 #include <runtime/StructureInlines.h>
41 #if ENABLE(USER_MESSAGE_HANDLERS)
42 #include "UserMessageHandlerDescriptor.h"
45 #if ENABLE(CONTENT_EXTENSIONS)
46 #include "ContentExtensionCompiler.h"
47 #include "ContentExtensionsBackend.h"
52 Ref<UserContentController> UserContentController::create()
54 return adoptRef(*new UserContentController);
57 UserContentController::UserContentController()
61 UserContentController::~UserContentController()
65 void UserContentController::addPage(Page& page)
67 ASSERT(!m_pages.contains(&page));
71 void UserContentController::removePage(Page& page)
73 ASSERT(m_pages.contains(&page));
74 m_pages.remove(&page);
77 void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
80 m_userScripts = std::make_unique<UserScriptMap>();
82 auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
84 scriptsInWorld = std::make_unique<UserScriptVector>();
85 scriptsInWorld->append(WTF::move(userScript));
88 void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
93 auto it = m_userScripts->find(&world);
94 if (it == m_userScripts->end())
97 auto scripts = it->value.get();
98 for (int i = scripts->size() - 1; i >= 0; --i) {
99 if (scripts->at(i)->url() == url)
103 if (scripts->isEmpty())
104 m_userScripts->remove(it);
107 void UserContentController::removeUserScripts(DOMWrapperWorld& world)
112 m_userScripts->remove(&world);
115 void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
117 if (!m_userStyleSheets)
118 m_userStyleSheets = std::make_unique<UserStyleSheetMap>();
120 auto& styleSheetsInWorld = m_userStyleSheets->add(&world, nullptr).iterator->value;
121 if (!styleSheetsInWorld)
122 styleSheetsInWorld = std::make_unique<UserStyleSheetVector>();
123 styleSheetsInWorld->append(WTF::move(userStyleSheet));
125 if (injectionTime == InjectInExistingDocuments)
126 invalidateInjectedStyleSheetCacheInAllFrames();
129 void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
131 if (!m_userStyleSheets)
134 auto it = m_userStyleSheets->find(&world);
135 if (it == m_userStyleSheets->end())
138 auto& stylesheets = *it->value;
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;
151 if (stylesheets.isEmpty())
152 m_userStyleSheets->remove(it);
154 invalidateInjectedStyleSheetCacheInAllFrames();
157 void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
159 if (!m_userStyleSheets)
162 if (!m_userStyleSheets->remove(&world))
165 invalidateInjectedStyleSheetCacheInAllFrames();
168 #if ENABLE(USER_MESSAGE_HANDLERS)
169 void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
171 if (!m_userMessageHandlerDescriptors)
172 m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
174 m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
177 void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
179 if (!m_userMessageHandlerDescriptors)
182 m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
186 #if ENABLE(CONTENT_EXTENSIONS)
187 void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
189 if (!m_contentExtensionBackend)
190 m_contentExtensionBackend = std::make_unique<ContentExtensions::ContentExtensionsBackend>();
192 m_contentExtensionBackend->addContentExtension(name, contentExtension);
195 void UserContentController::removeUserContentExtension(const String& name)
197 if (!m_contentExtensionBackend)
200 m_contentExtensionBackend->removeContentExtension(name);
203 void UserContentController::removeAllUserContentExtensions()
205 if (!m_contentExtensionBackend)
208 m_contentExtensionBackend->removeAllContentExtensions();
211 ContentExtensions::BlockedStatus UserContentController::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
213 if (!m_contentExtensionBackend)
214 return ContentExtensions::BlockedStatus::NotBlocked;
216 if (!initiatingDocumentLoader.userContentExtensionsEnabled())
217 return ContentExtensions::BlockedStatus::NotBlocked;
219 return m_contentExtensionBackend->processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
222 Vector<ContentExtensions::Action> UserContentController::actionsForResourceLoad(const ResourceLoadInfo& resourceLoadInfo, DocumentLoader& initiatingDocumentLoader)
224 if (!m_contentExtensionBackend)
225 return Vector<ContentExtensions::Action>();
227 if (!initiatingDocumentLoader.userContentExtensionsEnabled())
228 return Vector<ContentExtensions::Action>();
230 return m_contentExtensionBackend->actionsForResourceLoad(resourceLoadInfo);
234 void UserContentController::removeAllUserContent()
236 m_userScripts = nullptr;
238 if (m_userStyleSheets) {
239 m_userStyleSheets = nullptr;
240 invalidateInjectedStyleSheetCacheInAllFrames();
244 void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
246 for (auto& page : m_pages) {
247 for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
248 frame->document()->extensionStyleSheets().invalidateInjectedStyleSheetCache();
249 frame->document()->styleResolverChanged(DeferRecalcStyle);
254 } // namespace WebCore