Unreviewed, rolling out r182511.
[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 "MainFrame.h"
32 #include "Page.h"
33 #include "ResourceLoadInfo.h"
34 #include "UserScript.h"
35 #include "UserStyleSheet.h"
36
37 #if ENABLE(USER_MESSAGE_HANDLERS)
38 #include "UserMessageHandlerDescriptor.h"
39 #endif
40
41 #if ENABLE(CONTENT_EXTENSIONS)
42 #include "ContentExtensionCompiler.h"
43 #include "ContentExtensionsBackend.h"
44 #endif
45
46 namespace WebCore {
47
48 RefPtr<UserContentController> UserContentController::create()
49 {
50     return adoptRef(new UserContentController);
51 }
52
53 UserContentController::UserContentController()
54 {
55 }
56
57 UserContentController::~UserContentController()
58 {
59 }
60
61 void UserContentController::addPage(Page& page)
62 {
63     ASSERT(!m_pages.contains(&page));
64     m_pages.add(&page);
65 }
66
67 void UserContentController::removePage(Page& page)
68 {
69     ASSERT(m_pages.contains(&page));
70     m_pages.remove(&page);
71 }
72
73 void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
74 {
75     if (!m_userScripts)
76         m_userScripts = std::make_unique<UserScriptMap>();
77
78     auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
79     if (!scriptsInWorld)
80         scriptsInWorld = std::make_unique<UserScriptVector>();
81     scriptsInWorld->append(WTF::move(userScript));
82 }
83
84 void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
85 {
86     if (!m_userScripts)
87         return;
88
89     auto it = m_userScripts->find(&world);
90     if (it == m_userScripts->end())
91         return;
92
93     auto scripts = it->value.get();
94     for (int i = scripts->size() - 1; i >= 0; --i) {
95         if (scripts->at(i)->url() == url)
96             scripts->remove(i);
97     }
98
99     if (scripts->isEmpty())
100         m_userScripts->remove(it);
101 }
102
103 void UserContentController::removeUserScripts(DOMWrapperWorld& world)
104 {
105     if (!m_userScripts)
106         return;
107
108     m_userScripts->remove(&world);
109 }
110
111 void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
112 {
113     if (!m_userStyleSheets)
114         m_userStyleSheets = std::make_unique<UserStyleSheetMap>();
115
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));
120
121     if (injectionTime == InjectInExistingDocuments)
122         invalidateInjectedStyleSheetCacheInAllFrames();
123 }
124
125 void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
126 {
127     if (!m_userStyleSheets)
128         return;
129
130     auto it = m_userStyleSheets->find(&world);
131     if (it == m_userStyleSheets->end())
132         return;
133
134     auto& stylesheets = *it->value;
135
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;
141         }
142     }
143
144     if (!sheetsChanged)
145         return;
146
147     if (stylesheets.isEmpty())
148         m_userStyleSheets->remove(it);
149
150     invalidateInjectedStyleSheetCacheInAllFrames();
151 }
152
153 void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
154 {
155     if (!m_userStyleSheets)
156         return;
157
158     if (!m_userStyleSheets->remove(&world))
159         return;
160
161     invalidateInjectedStyleSheetCacheInAllFrames();
162 }
163
164 #if ENABLE(USER_MESSAGE_HANDLERS)
165 void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
166 {
167     if (!m_userMessageHandlerDescriptors)
168         m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
169
170     m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
171 }
172
173 void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
174 {
175     if (!m_userMessageHandlerDescriptors)
176         return;
177
178     m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
179 }
180 #endif
181
182 #if ENABLE(CONTENT_EXTENSIONS)
183 void UserContentController::addUserContentExtension(const String& name, RefPtr<ContentExtensions::CompiledContentExtension> contentExtension)
184 {
185     if (!m_contentExtensionBackend)
186         m_contentExtensionBackend = std::make_unique<ContentExtensions::ContentExtensionsBackend>();
187     
188     m_contentExtensionBackend->addContentExtension(name, contentExtension);
189 }
190
191 void UserContentController::removeUserContentExtension(const String& name)
192 {
193     if (!m_contentExtensionBackend)
194         return;
195
196     m_contentExtensionBackend->removeContentExtension(name);
197 }
198
199 void UserContentController::removeAllUserContentExtensions()
200 {
201     if (!m_contentExtensionBackend)
202         return;
203
204     m_contentExtensionBackend->removeAllContentExtensions();
205 }
206
207 void UserContentController::processContentExtensionRulesForLoad(ResourceRequest& request, ResourceType resourceType, DocumentLoader& initiatingDocumentLoader)
208 {
209     if (!m_contentExtensionBackend)
210         return;
211
212     m_contentExtensionBackend->processContentExtensionRulesForLoad(request, resourceType, initiatingDocumentLoader);
213 }
214
215 #endif
216
217 void UserContentController::removeAllUserContent()
218 {
219     m_userScripts = nullptr;
220
221     if (m_userStyleSheets) {
222         m_userStyleSheets = nullptr;
223         invalidateInjectedStyleSheetCacheInAllFrames();
224     }
225 }
226
227 void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
228 {
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);
233         }
234     }
235 }
236
237 } // namespace WebCore