[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[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 "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
40 namespace WebCore {
41
42 Ref<UserContentController> UserContentController::create()
43 {
44     return adoptRef(*new UserContentController);
45 }
46
47 UserContentController::UserContentController() = default;
48
49 UserContentController::~UserContentController() = default;
50
51 void 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
60 void 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)
69 void UserContentController::forEachUserMessageHandler(Function<void(const UserMessageHandlerDescriptor&)>&&) const
70 {
71 }
72 #endif
73
74 void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
75 {
76     auto& scriptsInWorld = m_userScripts.ensure(&world, [&] { return makeUnique<UserScriptVector>(); }).iterator->value;
77     scriptsInWorld->append(WTFMove(userScript));
78 }
79
80 void 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
96 void UserContentController::removeUserScripts(DOMWrapperWorld& world)
97 {
98     m_userScripts.remove(&world);
99 }
100
101 void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
102 {
103     auto& styleSheetsInWorld = m_userStyleSheets.ensure(&world, [&] { return makeUnique<UserStyleSheetVector>(); }).iterator->value;
104     styleSheetsInWorld->append(WTFMove(userStyleSheet));
105
106     if (injectionTime == InjectInExistingDocuments)
107         invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
108 }
109
110 void 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
135 void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
136 {
137     if (!m_userStyleSheets.remove(&world))
138         return;
139
140     invalidateInjectedStyleSheetCacheInAllFramesInAllPages();
141 }
142
143 void 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