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 "UserScript.h"
31#include "UserStyleSheet.h"
32#include <JavaScriptCore/HeapInlines.h>
33#include <JavaScriptCore/JSCellInlines.h>
34#include <JavaScriptCore/StructureInlines.h>
35
36#if ENABLE(CONTENT_EXTENSIONS)
37#include "CompiledContentExtension.h"
38#endif
39
40namespace WebCore {
41
42Ref<UserContentController> UserContentController::create()
43{
44 return adoptRef(*new UserContentController);
45}
46
47UserContentController::UserContentController() = default;
48
49UserContentController::~UserContentController() = default;
50
51void UserContentController::forEachUserScript(Function<void(DOMWrapperWorld&, const UserScript&)>&& functor) const
52{
53 for (const auto& worldAndUserScriptVector : m_userScripts) {
54 auto& world = *worldAndUserScriptVector.key.get();
55 for (const auto& userScript : *worldAndUserScriptVector.value)
56 functor(world, *userScript);
57 }
58}
59
60void UserContentController::forEachUserStyleSheet(Function<void(const UserStyleSheet&)>&& functor) const
61{
62 for (auto& styleSheetVector : m_userStyleSheets.values()) {
63 for (const auto& styleSheet : *styleSheetVector)
64 functor(*styleSheet);
65 }
66}
67
68#if ENABLE(USER_MESSAGE_HANDLERS)
69void UserContentController::forEachUserMessageHandler(Function<void(const UserMessageHandlerDescriptor&)>&&) const
70{
71}
72#endif
73
74void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
75{
76 auto& scriptsInWorld = m_userScripts.ensure(&world, [&] { return std::make_unique<UserScriptVector>(); }).iterator->value;
77 scriptsInWorld->append(WTFMove(userScript));
78}
79
80void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
81{
82 auto it = m_userScripts.find(&world);
83 if (it == m_userScripts.end())
84 return;
85
86 auto scripts = it->value.get();
87 for (int i = scripts->size() - 1; i >= 0; --i) {
88 if (scripts->at(i)->url() == url)
89 scripts->remove(i);
90 }
91
92 if (scripts->isEmpty())
93 m_userScripts.remove(it);
94}
95
96void UserContentController::removeUserScripts(DOMWrapperWorld& world)
97{
98 m_userScripts.remove(&world);
99}
100
101void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
102{
103 auto& styleSheetsInWorld = m_userStyleSheets.ensure(&world, [&] { return std::make_unique<UserStyleSheetVector>(); }).iterator->value;
104 styleSheetsInWorld->append(WTFMove(userStyleSheet));
105
106 if (injectionTime == InjectInExistingDocuments)
107 invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
108}
109
110void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
111{
112 auto it = m_userStyleSheets.find(&world);
113 if (it == m_userStyleSheets.end())
114 return;
115
116 auto& stylesheets = *it->value;
117
118 bool sheetsChanged = false;
119 for (int i = stylesheets.size() - 1; i >= 0; --i) {
120 if (stylesheets[i]->url() == url) {
121 stylesheets.remove(i);
122 sheetsChanged = true;
123 }
124 }
125
126 if (!sheetsChanged)
127 return;
128
129 if (stylesheets.isEmpty())
130 m_userStyleSheets.remove(it);
131
132 invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
133}
134
135void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
136{
137 if (!m_userStyleSheets.remove(&world))
138 return;
139
140 invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
141}
142
143void UserContentController::removeAllUserContent()
144{
145 m_userScripts.clear();
146
147 if (!m_userStyleSheets.isEmpty()) {
148 m_userStyleSheets.clear();
149 invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
150 }
151}
152
153} // namespace WebCore
154