1 | /* |
2 | * Copyright (C) 2014 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 "WebUserContentController.h" |
28 | |
29 | #include "DataReference.h" |
30 | #include "FrameInfoData.h" |
31 | #include "InjectUserScriptImmediately.h" |
32 | #include "InjectedBundleScriptWorld.h" |
33 | #include "WebCompiledContentRuleList.h" |
34 | #include "WebFrame.h" |
35 | #include "WebPage.h" |
36 | #include "WebProcess.h" |
37 | #include "WebUserContentControllerMessages.h" |
38 | #include "WebUserContentControllerProxyMessages.h" |
39 | #include <WebCore/DOMWrapperWorld.h> |
40 | #include <WebCore/Frame.h> |
41 | #include <WebCore/SecurityOriginData.h> |
42 | #include <WebCore/SerializedScriptValue.h> |
43 | #include <WebCore/UserStyleSheet.h> |
44 | #include <wtf/NeverDestroyed.h> |
45 | |
46 | #if ENABLE(USER_MESSAGE_HANDLERS) |
47 | #include <WebCore/UserMessageHandler.h> |
48 | #include <WebCore/UserMessageHandlerDescriptor.h> |
49 | #endif |
50 | |
51 | namespace WebKit { |
52 | using namespace WebCore; |
53 | |
54 | static HashMap<UserContentControllerIdentifier, WebUserContentController*>& userContentControllers() |
55 | { |
56 | static NeverDestroyed<HashMap<UserContentControllerIdentifier, WebUserContentController*>> userContentControllers; |
57 | |
58 | return userContentControllers; |
59 | } |
60 | |
61 | typedef HashMap<uint64_t, std::pair<RefPtr<InjectedBundleScriptWorld>, unsigned>> WorldMap; |
62 | |
63 | static WorldMap& worldMap() |
64 | { |
65 | static NeverDestroyed<WorldMap> map(std::initializer_list<WorldMap::KeyValuePairType> { { 1, std::make_pair(&InjectedBundleScriptWorld::normalWorld(), 1) } }); |
66 | |
67 | return map; |
68 | } |
69 | |
70 | Ref<WebUserContentController> WebUserContentController::getOrCreate(UserContentControllerIdentifier identifier) |
71 | { |
72 | auto& userContentControllerPtr = userContentControllers().add(identifier, nullptr).iterator->value; |
73 | if (userContentControllerPtr) |
74 | return *userContentControllerPtr; |
75 | |
76 | RefPtr<WebUserContentController> userContentController = adoptRef(new WebUserContentController(identifier)); |
77 | userContentControllerPtr = userContentController.get(); |
78 | |
79 | return userContentController.releaseNonNull(); |
80 | } |
81 | |
82 | WebUserContentController::WebUserContentController(UserContentControllerIdentifier identifier) |
83 | : m_identifier(identifier) |
84 | { |
85 | WebProcess::singleton().addMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier, *this); |
86 | } |
87 | |
88 | WebUserContentController::~WebUserContentController() |
89 | { |
90 | ASSERT(userContentControllers().contains(m_identifier)); |
91 | |
92 | WebProcess::singleton().removeMessageReceiver(Messages::WebUserContentController::messageReceiverName(), m_identifier); |
93 | |
94 | userContentControllers().remove(m_identifier); |
95 | } |
96 | |
97 | void WebUserContentController::addUserContentWorlds(const Vector<std::pair<uint64_t, String>>& worlds) |
98 | { |
99 | for (auto& world : worlds) { |
100 | ASSERT(world.first); |
101 | ASSERT(world.first != 1); |
102 | |
103 | worldMap().ensure(world.first, [&] { |
104 | #if PLATFORM(GTK) || PLATFORM(WPE) |
105 | // The GLib API doesn't allow to create script worlds from the UI process. We need to |
106 | // use the existing world created by the web extension if any. The world name is used |
107 | // as the identifier. |
108 | if (auto* existingWorld = InjectedBundleScriptWorld::find(world.second)) |
109 | return std::make_pair(Ref<InjectedBundleScriptWorld>(*existingWorld), 1); |
110 | #endif |
111 | return std::make_pair(InjectedBundleScriptWorld::create(world.second), 1); |
112 | }); |
113 | } |
114 | } |
115 | |
116 | void WebUserContentController::removeUserContentWorlds(const Vector<uint64_t>& worldIdentifiers) |
117 | { |
118 | for (auto& worldIdentifier : worldIdentifiers) { |
119 | ASSERT(worldIdentifier); |
120 | ASSERT(worldIdentifier != 1); |
121 | |
122 | auto it = worldMap().find(worldIdentifier); |
123 | if (it == worldMap().end()) { |
124 | WTFLogAlways("Trying to remove a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
125 | return; |
126 | } |
127 | |
128 | it->value.second--; |
129 | |
130 | if (!it->value.second) |
131 | worldMap().remove(it); |
132 | } |
133 | } |
134 | |
135 | void WebUserContentController::addUserScripts(Vector<WebUserScriptData>&& userScripts, InjectUserScriptImmediately immediately) |
136 | { |
137 | for (const auto& userScriptData : userScripts) { |
138 | auto it = worldMap().find(userScriptData.worldIdentifier); |
139 | if (it == worldMap().end()) { |
140 | WTFLogAlways("Trying to add a UserScript to a UserContentWorld (id=%" PRIu64 ") that does not exist." , userScriptData.worldIdentifier); |
141 | continue; |
142 | } |
143 | |
144 | UserScript script = userScriptData.userScript; |
145 | addUserScriptInternal(*it->value.first, userScriptData.identifier, WTFMove(script), immediately); |
146 | } |
147 | } |
148 | |
149 | void WebUserContentController::removeUserScript(uint64_t worldIdentifier, uint64_t userScriptIdentifier) |
150 | { |
151 | auto it = worldMap().find(worldIdentifier); |
152 | if (it == worldMap().end()) { |
153 | WTFLogAlways("Trying to remove a UserScript from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
154 | return; |
155 | } |
156 | |
157 | removeUserScriptInternal(*it->value.first, userScriptIdentifier); |
158 | } |
159 | |
160 | void WebUserContentController::removeAllUserScripts(const Vector<uint64_t>& worldIdentifiers) |
161 | { |
162 | for (auto& worldIdentifier : worldIdentifiers) { |
163 | auto it = worldMap().find(worldIdentifier); |
164 | if (it == worldMap().end()) { |
165 | WTFLogAlways("Trying to remove all UserScripts from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
166 | return; |
167 | } |
168 | |
169 | removeUserScripts(*it->value.first); |
170 | } |
171 | } |
172 | |
173 | void WebUserContentController::addUserStyleSheets(const Vector<WebUserStyleSheetData>& userStyleSheets) |
174 | { |
175 | for (const auto& userStyleSheetData : userStyleSheets) { |
176 | auto it = worldMap().find(userStyleSheetData.worldIdentifier); |
177 | if (it == worldMap().end()) { |
178 | WTFLogAlways("Trying to add a UserStyleSheet to a UserContentWorld (id=%" PRIu64 ") that does not exist." , userStyleSheetData.worldIdentifier); |
179 | continue; |
180 | } |
181 | |
182 | UserStyleSheet sheet = userStyleSheetData.userStyleSheet; |
183 | addUserStyleSheetInternal(*it->value.first, userStyleSheetData.identifier, WTFMove(sheet)); |
184 | } |
185 | |
186 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
187 | } |
188 | |
189 | void WebUserContentController::removeUserStyleSheet(uint64_t worldIdentifier, uint64_t userStyleSheetIdentifier) |
190 | { |
191 | auto it = worldMap().find(worldIdentifier); |
192 | if (it == worldMap().end()) { |
193 | WTFLogAlways("Trying to remove a UserStyleSheet from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
194 | return; |
195 | } |
196 | |
197 | removeUserStyleSheetInternal(*it->value.first, userStyleSheetIdentifier); |
198 | } |
199 | |
200 | void WebUserContentController::removeAllUserStyleSheets(const Vector<uint64_t>& worldIdentifiers) |
201 | { |
202 | bool sheetsChanged = false; |
203 | for (auto& worldIdentifier : worldIdentifiers) { |
204 | auto it = worldMap().find(worldIdentifier); |
205 | if (it == worldMap().end()) { |
206 | WTFLogAlways("Trying to remove all UserStyleSheets from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
207 | return; |
208 | } |
209 | |
210 | if (m_userStyleSheets.remove(it->value.first.get())) |
211 | sheetsChanged = true; |
212 | } |
213 | |
214 | if (sheetsChanged) |
215 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
216 | } |
217 | |
218 | #if ENABLE(USER_MESSAGE_HANDLERS) |
219 | class WebUserMessageHandlerDescriptorProxy : public WebCore::UserMessageHandlerDescriptor { |
220 | public: |
221 | static Ref<WebUserMessageHandlerDescriptorProxy> create(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier) |
222 | { |
223 | return adoptRef(*new WebUserMessageHandlerDescriptorProxy(controller, name, world, identifier)); |
224 | } |
225 | |
226 | virtual ~WebUserMessageHandlerDescriptorProxy() |
227 | { |
228 | } |
229 | |
230 | uint64_t identifier() { return m_identifier; } |
231 | |
232 | private: |
233 | WebUserMessageHandlerDescriptorProxy(WebUserContentController* controller, const String& name, InjectedBundleScriptWorld& world, uint64_t identifier) |
234 | : WebCore::UserMessageHandlerDescriptor(name, world.coreWorld()) |
235 | , m_controller(controller) |
236 | , m_identifier(identifier) |
237 | { |
238 | } |
239 | |
240 | // WebCore::UserMessageHandlerDescriptor |
241 | void didPostMessage(WebCore::UserMessageHandler& handler, WebCore::SerializedScriptValue* value) override |
242 | { |
243 | WebCore::Frame* frame = handler.frame(); |
244 | if (!frame) |
245 | return; |
246 | |
247 | WebFrame* webFrame = WebFrame::fromCoreFrame(*frame); |
248 | if (!webFrame) |
249 | return; |
250 | |
251 | WebPage* webPage = webFrame->page(); |
252 | if (!webPage) |
253 | return; |
254 | |
255 | WebProcess::singleton().parentProcessConnection()->send(Messages::WebUserContentControllerProxy::DidPostMessage(webPage->pageID(), webFrame->info(), m_identifier, IPC::DataReference(value->data())), m_controller->identifier()); |
256 | } |
257 | |
258 | RefPtr<WebUserContentController> m_controller; |
259 | uint64_t m_identifier; |
260 | }; |
261 | #endif |
262 | |
263 | void WebUserContentController::addUserScriptMessageHandlers(const Vector<WebScriptMessageHandlerData>& scriptMessageHandlers) |
264 | { |
265 | #if ENABLE(USER_MESSAGE_HANDLERS) |
266 | for (auto& handler : scriptMessageHandlers) { |
267 | auto it = worldMap().find(handler.worldIdentifier); |
268 | if (it == worldMap().end()) { |
269 | WTFLogAlways("Trying to add a UserScriptMessageHandler to a UserContentWorld (id=%" PRIu64 ") that does not exist." , handler.worldIdentifier); |
270 | continue; |
271 | } |
272 | |
273 | addUserScriptMessageHandlerInternal(*it->value.first, handler.identifier, handler.name); |
274 | } |
275 | #else |
276 | UNUSED_PARAM(scriptMessageHandlers); |
277 | #endif |
278 | } |
279 | |
280 | void WebUserContentController::removeUserScriptMessageHandler(uint64_t worldIdentifier, uint64_t userScriptMessageHandlerIdentifier) |
281 | { |
282 | #if ENABLE(USER_MESSAGE_HANDLERS) |
283 | auto it = worldMap().find(worldIdentifier); |
284 | if (it == worldMap().end()) { |
285 | WTFLogAlways("Trying to remove a UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
286 | return; |
287 | } |
288 | |
289 | removeUserScriptMessageHandlerInternal(*it->value.first, userScriptMessageHandlerIdentifier); |
290 | #else |
291 | UNUSED_PARAM(worldIdentifier); |
292 | UNUSED_PARAM(userScriptMessageHandlerIdentifier); |
293 | #endif |
294 | } |
295 | |
296 | void WebUserContentController::removeAllUserScriptMessageHandlers(const Vector<uint64_t>& worldIdentifiers) |
297 | { |
298 | #if ENABLE(USER_MESSAGE_HANDLERS) |
299 | bool userMessageHandlersChanged = false; |
300 | for (auto& worldIdentifier : worldIdentifiers) { |
301 | auto it = worldMap().find(worldIdentifier); |
302 | if (it == worldMap().end()) { |
303 | WTFLogAlways("Trying to remove all UserScriptMessageHandler from a UserContentWorld (id=%" PRIu64 ") that does not exist." , worldIdentifier); |
304 | return; |
305 | } |
306 | |
307 | if (m_userMessageHandlers.remove(it->value.first.get())) |
308 | userMessageHandlersChanged = true; |
309 | } |
310 | |
311 | if (userMessageHandlersChanged) |
312 | invalidateAllRegisteredUserMessageHandlerInvalidationClients(); |
313 | #else |
314 | UNUSED_PARAM(worldIdentifiers); |
315 | #endif |
316 | } |
317 | |
318 | #if ENABLE(USER_MESSAGE_HANDLERS) |
319 | void WebUserContentController::addUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier, const String& name) |
320 | { |
321 | auto& messageHandlersInWorld = m_userMessageHandlers.ensure(&world, [] { return Vector<std::pair<uint64_t, RefPtr<WebUserMessageHandlerDescriptorProxy>>> { }; }).iterator->value; |
322 | if (messageHandlersInWorld.findMatching([&](auto& pair) { return pair.first == userScriptMessageHandlerIdentifier; }) != notFound) |
323 | return; |
324 | messageHandlersInWorld.append(std::make_pair(userScriptMessageHandlerIdentifier, WebUserMessageHandlerDescriptorProxy::create(this, name, world, userScriptMessageHandlerIdentifier))); |
325 | } |
326 | |
327 | void WebUserContentController::removeUserScriptMessageHandlerInternal(InjectedBundleScriptWorld& world, uint64_t userScriptMessageHandlerIdentifier) |
328 | { |
329 | auto it = m_userMessageHandlers.find(&world); |
330 | if (it == m_userMessageHandlers.end()) |
331 | return; |
332 | |
333 | auto protectedThis = makeRef(*this); |
334 | |
335 | auto& userMessageHandlers = it->value; |
336 | bool userMessageHandlersChanged = userMessageHandlers.removeFirstMatching([userScriptMessageHandlerIdentifier](auto& pair) { |
337 | return pair.first == userScriptMessageHandlerIdentifier; |
338 | }); |
339 | |
340 | if (!userMessageHandlersChanged) |
341 | return; |
342 | |
343 | if (userMessageHandlers.isEmpty()) |
344 | m_userMessageHandlers.remove(it); |
345 | |
346 | invalidateAllRegisteredUserMessageHandlerInvalidationClients(); |
347 | } |
348 | #endif |
349 | |
350 | #if ENABLE(CONTENT_EXTENSIONS) |
351 | void WebUserContentController::addContentRuleLists(Vector<std::pair<String, WebCompiledContentRuleListData>>&& contentRuleLists) |
352 | { |
353 | for (auto&& contentRuleList : contentRuleLists) { |
354 | auto compiledContentRuleList = WebCompiledContentRuleList::create(WTFMove(contentRuleList.second)); |
355 | |
356 | m_contentExtensionBackend.addContentExtension(contentRuleList.first, WTFMove(compiledContentRuleList)); |
357 | } |
358 | } |
359 | |
360 | void WebUserContentController::removeContentRuleList(const String& name) |
361 | { |
362 | m_contentExtensionBackend.removeContentExtension(name); |
363 | } |
364 | |
365 | void WebUserContentController::removeAllContentRuleLists() |
366 | { |
367 | m_contentExtensionBackend.removeAllContentExtensions(); |
368 | } |
369 | #endif |
370 | |
371 | void WebUserContentController::addUserScriptInternal(InjectedBundleScriptWorld& world, const Optional<uint64_t>& userScriptIdentifier, UserScript&& userScript, InjectUserScriptImmediately immediately) |
372 | { |
373 | if (immediately == InjectUserScriptImmediately::Yes) { |
374 | Page::forEachPage([&] (auto& page) { |
375 | if (&page.userContentProvider() != this) |
376 | return; |
377 | |
378 | auto& mainFrame = page.mainFrame(); |
379 | if (userScript.injectedFrames() == InjectInTopFrameOnly) { |
380 | mainFrame.injectUserScriptImmediately(world.coreWorld(), userScript); |
381 | return; |
382 | } |
383 | |
384 | for (auto* frame = &mainFrame; frame; frame = frame->tree().traverseNext(&mainFrame)) |
385 | frame->injectUserScriptImmediately(world.coreWorld(), userScript); |
386 | }); |
387 | } |
388 | |
389 | auto& scriptsInWorld = m_userScripts.ensure(&world, [] { return Vector<std::pair<Optional<uint64_t>, WebCore::UserScript>>(); }).iterator->value; |
390 | if (userScriptIdentifier && scriptsInWorld.findMatching([&](auto& pair) { return pair.first == userScriptIdentifier; }) != notFound) |
391 | return; |
392 | |
393 | scriptsInWorld.append(std::make_pair(userScriptIdentifier, WTFMove(userScript))); |
394 | } |
395 | |
396 | void WebUserContentController::addUserScript(InjectedBundleScriptWorld& world, UserScript&& userScript) |
397 | { |
398 | addUserScriptInternal(world, WTF::nullopt, WTFMove(userScript), InjectUserScriptImmediately::No); |
399 | } |
400 | |
401 | void WebUserContentController::removeUserScriptWithURL(InjectedBundleScriptWorld& world, const URL& url) |
402 | { |
403 | auto it = m_userScripts.find(&world); |
404 | if (it == m_userScripts.end()) |
405 | return; |
406 | |
407 | auto& scripts = it->value; |
408 | scripts.removeAllMatching([&](auto& pair) { |
409 | return pair.second.url() == url; |
410 | }); |
411 | |
412 | if (scripts.isEmpty()) |
413 | m_userScripts.remove(it); |
414 | } |
415 | |
416 | void WebUserContentController::removeUserScriptInternal(InjectedBundleScriptWorld& world, uint64_t userScriptIdentifier) |
417 | { |
418 | auto it = m_userScripts.find(&world); |
419 | if (it == m_userScripts.end()) |
420 | return; |
421 | |
422 | auto& scripts = it->value; |
423 | scripts.removeFirstMatching([userScriptIdentifier](auto& pair) { |
424 | return pair.first == userScriptIdentifier; |
425 | }); |
426 | |
427 | if (scripts.isEmpty()) |
428 | m_userScripts.remove(it); |
429 | } |
430 | |
431 | void WebUserContentController::removeUserScripts(InjectedBundleScriptWorld& world) |
432 | { |
433 | m_userScripts.remove(&world); |
434 | } |
435 | |
436 | void WebUserContentController::addUserStyleSheetInternal(InjectedBundleScriptWorld& world, const Optional<uint64_t>& userStyleSheetIdentifier, UserStyleSheet&& userStyleSheet) |
437 | { |
438 | auto& styleSheetsInWorld = m_userStyleSheets.ensure(&world, [] { return Vector<std::pair<Optional<uint64_t>, WebCore::UserStyleSheet>>(); }).iterator->value; |
439 | if (userStyleSheetIdentifier && styleSheetsInWorld.findMatching([&](auto& pair) { return pair.first == userStyleSheetIdentifier; }) != notFound) |
440 | return; |
441 | |
442 | styleSheetsInWorld.append(std::make_pair(userStyleSheetIdentifier, WTFMove(userStyleSheet))); |
443 | } |
444 | |
445 | void WebUserContentController::addUserStyleSheet(InjectedBundleScriptWorld& world, UserStyleSheet&& userStyleSheet) |
446 | { |
447 | addUserStyleSheetInternal(world, WTF::nullopt, WTFMove(userStyleSheet)); |
448 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
449 | } |
450 | |
451 | void WebUserContentController::removeUserStyleSheetWithURL(InjectedBundleScriptWorld& world, const URL& url) |
452 | { |
453 | auto it = m_userStyleSheets.find(&world); |
454 | if (it == m_userStyleSheets.end()) |
455 | return; |
456 | |
457 | auto& stylesheets = it->value; |
458 | bool sheetsChanged = stylesheets.removeAllMatching([&](auto& pair) { |
459 | return pair.second.url() == url; |
460 | }); |
461 | |
462 | if (!sheetsChanged) |
463 | return; |
464 | |
465 | if (stylesheets.isEmpty()) |
466 | m_userStyleSheets.remove(it); |
467 | |
468 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
469 | } |
470 | |
471 | void WebUserContentController::removeUserStyleSheetInternal(InjectedBundleScriptWorld& world, uint64_t userStyleSheetIdentifier) |
472 | { |
473 | auto it = m_userStyleSheets.find(&world); |
474 | if (it == m_userStyleSheets.end()) |
475 | return; |
476 | |
477 | auto& stylesheets = it->value; |
478 | bool sheetsChanged = stylesheets.removeFirstMatching([userStyleSheetIdentifier](auto& pair) { |
479 | return pair.first == userStyleSheetIdentifier; |
480 | }); |
481 | |
482 | if (!sheetsChanged) |
483 | return; |
484 | |
485 | if (stylesheets.isEmpty()) |
486 | m_userStyleSheets.remove(it); |
487 | |
488 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
489 | } |
490 | |
491 | void WebUserContentController::removeUserStyleSheets(InjectedBundleScriptWorld& world) |
492 | { |
493 | if (!m_userStyleSheets.remove(&world)) |
494 | return; |
495 | |
496 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
497 | } |
498 | |
499 | void WebUserContentController::removeAllUserContent() |
500 | { |
501 | m_userScripts.clear(); |
502 | |
503 | if (!m_userStyleSheets.isEmpty()) { |
504 | m_userStyleSheets.clear(); |
505 | invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); |
506 | } |
507 | } |
508 | |
509 | void WebUserContentController::forEachUserScript(Function<void(WebCore::DOMWrapperWorld&, const WebCore::UserScript&)>&& functor) const |
510 | { |
511 | for (const auto& worldAndUserScriptVector : m_userScripts) { |
512 | auto& world = worldAndUserScriptVector.key->coreWorld(); |
513 | for (const auto& identifierUserScriptPair : worldAndUserScriptVector.value) |
514 | functor(world, identifierUserScriptPair.second); |
515 | } |
516 | } |
517 | |
518 | void WebUserContentController::forEachUserStyleSheet(Function<void(const WebCore::UserStyleSheet&)>&& functor) const |
519 | { |
520 | for (auto& styleSheetVector : m_userStyleSheets.values()) { |
521 | for (const auto& identifierUserStyleSheetPair : styleSheetVector) |
522 | functor(identifierUserStyleSheetPair.second); |
523 | } |
524 | } |
525 | |
526 | #if ENABLE(USER_MESSAGE_HANDLERS) |
527 | void WebUserContentController::forEachUserMessageHandler(Function<void(const WebCore::UserMessageHandlerDescriptor&)>&& functor) const |
528 | { |
529 | for (auto& userMessageHandlerVector : m_userMessageHandlers.values()) { |
530 | for (auto& pair : userMessageHandlerVector) |
531 | functor(*pair.second.get()); |
532 | } |
533 | } |
534 | #endif |
535 | |
536 | } // namespace WebKit |
537 | |