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 "MainFrame.h"
33 #include "ResourceLoadInfo.h"
34 #include "UserScript.h"
35 #include "UserStyleSheet.h"
37 #if ENABLE(USER_MESSAGE_HANDLERS)
38 #include "UserMessageHandlerDescriptor.h"
41 #if ENABLE(CONTENT_EXTENSIONS)
42 #include "ContentExtensionCompiler.h"
43 #include "ContentExtensionsBackend.h"
48 RefPtr<UserContentController> UserContentController::create()
50 return adoptRef(new UserContentController);
53 UserContentController::UserContentController()
57 UserContentController::~UserContentController()
61 void UserContentController::addPage(Page& page)
63 ASSERT(!m_pages.contains(&page));
67 void UserContentController::removePage(Page& page)
69 ASSERT(m_pages.contains(&page));
70 m_pages.remove(&page);
73 void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
76 m_userScripts = std::make_unique<UserScriptMap>();
78 auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
80 scriptsInWorld = std::make_unique<UserScriptVector>();
81 scriptsInWorld->append(WTF::move(userScript));
84 void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
89 auto it = m_userScripts->find(&world);
90 if (it == m_userScripts->end())
93 auto scripts = it->value.get();
94 for (int i = scripts->size() - 1; i >= 0; --i) {
95 if (scripts->at(i)->url() == url)
99 if (scripts->isEmpty())
100 m_userScripts->remove(it);
103 void UserContentController::removeUserScripts(DOMWrapperWorld& world)
108 m_userScripts->remove(&world);
111 void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
113 if (!m_userStyleSheets)
114 m_userStyleSheets = std::make_unique<UserStyleSheetMap>();
116 auto& styleSheetsInWorld = m_userStyleSheets->add(&world, nullptr).iterator->value;
117 if (!styleSheetsInWorld)
118 styleSheetsInWorld = std::make_unique<UserStyleSheetVector>();
119 styleSheetsInWorld->append(WTF::move(userStyleSheet));
121 if (injectionTime == InjectInExistingDocuments)
122 invalidateInjectedStyleSheetCacheInAllFrames();
125 void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
127 if (!m_userStyleSheets)
130 auto it = m_userStyleSheets->find(&world);
131 if (it == m_userStyleSheets->end())
134 auto& stylesheets = *it->value;
136 bool sheetsChanged = false;
137 for (int i = stylesheets.size() - 1; i >= 0; --i) {
138 if (stylesheets[i]->url() == url) {
139 stylesheets.remove(i);
140 sheetsChanged = true;
147 if (stylesheets.isEmpty())
148 m_userStyleSheets->remove(it);
150 invalidateInjectedStyleSheetCacheInAllFrames();
153 void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
155 if (!m_userStyleSheets)
158 if (!m_userStyleSheets->remove(&world))
161 invalidateInjectedStyleSheetCacheInAllFrames();
164 #if ENABLE(USER_MESSAGE_HANDLERS)
165 void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
167 if (!m_userMessageHandlerDescriptors)
168 m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
170 m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
173 void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
175 if (!m_userMessageHandlerDescriptors)
178 m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
182 #if ENABLE(CONTENT_EXTENSIONS)
183 void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
185 if (!m_contentExtensionBackend)
186 m_contentExtensionBackend = std::make_unique<ContentExtensions::ContentExtensionsBackend>();
188 m_contentExtensionBackend->addContentExtension(name, contentExtension);
191 void UserContentController::removeUserContentExtension(const String& name)
193 if (!m_contentExtensionBackend)
196 m_contentExtensionBackend->removeContentExtension(name);
199 void UserContentController::removeAllUserContentExtensions()
201 if (!m_contentExtensionBackend)
204 m_contentExtensionBackend->removeAllContentExtensions();
207 void UserContentController::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
209 if (!m_contentExtensionBackend)
212 m_contentExtensionBackend->processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
217 void UserContentController::removeAllUserContent()
219 m_userScripts = nullptr;
221 if (m_userStyleSheets) {
222 m_userStyleSheets = nullptr;
223 invalidateInjectedStyleSheetCacheInAllFrames();
227 void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
229 for (auto& page : m_pages) {
230 for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
231 frame->document()->styleSheetCollection().invalidateInjectedStyleSheetCache();
232 frame->document()->styleResolverChanged(DeferRecalcStyle);
237 } // namespace WebCore