1 | /* |
2 | * Copyright (C) 2010-2016 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 "InjectedBundle.h" |
28 | |
29 | #include "APIArray.h" |
30 | #include "APIData.h" |
31 | #include "InjectedBundleScriptWorld.h" |
32 | #include "NetworkConnectionToWebProcessMessages.h" |
33 | #include "NetworkProcessConnection.h" |
34 | #include "NetworkSessionCreationParameters.h" |
35 | #include "NotificationPermissionRequestManager.h" |
36 | #include "UserData.h" |
37 | #include "WebConnectionToUIProcess.h" |
38 | #include "WebCoreArgumentCoders.h" |
39 | #include "WebFrame.h" |
40 | #include "WebFrameNetworkingContext.h" |
41 | #include "WebPage.h" |
42 | #include "WebPageGroupProxy.h" |
43 | #include "WebPreferencesKeys.h" |
44 | #include "WebPreferencesStore.h" |
45 | #include "WebProcess.h" |
46 | #include "WebProcessCreationParameters.h" |
47 | #include "WebProcessMessages.h" |
48 | #include "WebProcessPoolMessages.h" |
49 | #include "WebUserContentController.h" |
50 | #include "WebsiteDataStoreParameters.h" |
51 | #include <JavaScriptCore/APICast.h> |
52 | #include <JavaScriptCore/Exception.h> |
53 | #include <JavaScriptCore/JSLock.h> |
54 | #include <WebCore/ApplicationCache.h> |
55 | #include <WebCore/ApplicationCacheStorage.h> |
56 | #include <WebCore/CommonVM.h> |
57 | #include <WebCore/Document.h> |
58 | #include <WebCore/Frame.h> |
59 | #include <WebCore/FrameLoader.h> |
60 | #include <WebCore/FrameView.h> |
61 | #include <WebCore/GCController.h> |
62 | #include <WebCore/GeolocationClient.h> |
63 | #include <WebCore/GeolocationController.h> |
64 | #include <WebCore/GeolocationPosition.h> |
65 | #include <WebCore/JSDOMConvertBufferSource.h> |
66 | #include <WebCore/JSDOMExceptionHandling.h> |
67 | #include <WebCore/JSDOMWindow.h> |
68 | #include <WebCore/JSNotification.h> |
69 | #include <WebCore/Page.h> |
70 | #include <WebCore/PageGroup.h> |
71 | #include <WebCore/PrintContext.h> |
72 | #include <WebCore/RuntimeEnabledFeatures.h> |
73 | #include <WebCore/SWContextManager.h> |
74 | #include <WebCore/ScriptController.h> |
75 | #include <WebCore/SecurityOrigin.h> |
76 | #include <WebCore/SecurityPolicy.h> |
77 | #include <WebCore/Settings.h> |
78 | #include <WebCore/UserGestureIndicator.h> |
79 | #include <WebCore/UserScript.h> |
80 | #include <WebCore/UserStyleSheet.h> |
81 | #include <pal/SessionID.h> |
82 | #include <wtf/ProcessPrivilege.h> |
83 | |
84 | #if ENABLE(NOTIFICATIONS) |
85 | #include "WebNotificationManager.h" |
86 | #endif |
87 | |
88 | namespace WebKit { |
89 | using namespace WebCore; |
90 | using namespace JSC; |
91 | |
92 | RefPtr<InjectedBundle> InjectedBundle::create(WebProcessCreationParameters& parameters, API::Object* initializationUserData) |
93 | { |
94 | auto bundle = adoptRef(*new InjectedBundle(parameters)); |
95 | |
96 | bundle->m_sandboxExtension = SandboxExtension::create(WTFMove(parameters.injectedBundlePathExtensionHandle)); |
97 | if (!bundle->initialize(parameters, initializationUserData)) |
98 | return nullptr; |
99 | |
100 | return bundle; |
101 | } |
102 | |
103 | InjectedBundle::InjectedBundle(const WebProcessCreationParameters& parameters) |
104 | : m_path(parameters.injectedBundlePath) |
105 | , m_platformBundle(0) |
106 | , m_client(std::make_unique<API::InjectedBundle::Client>()) |
107 | { |
108 | } |
109 | |
110 | InjectedBundle::~InjectedBundle() |
111 | { |
112 | } |
113 | |
114 | void InjectedBundle::setClient(std::unique_ptr<API::InjectedBundle::Client>&& client) |
115 | { |
116 | if (!client) |
117 | m_client = std::make_unique<API::InjectedBundle::Client>(); |
118 | else |
119 | m_client = WTFMove(client); |
120 | } |
121 | |
122 | void InjectedBundle::setServiceWorkerProxyCreationCallback(void (*callback)(uint64_t)) |
123 | { |
124 | #if ENABLE(SERVICE_WORKER) |
125 | SWContextManager::singleton().setServiceWorkerCreationCallback(callback); |
126 | #endif |
127 | } |
128 | |
129 | void InjectedBundle::postMessage(const String& messageName, API::Object* messageBody) |
130 | { |
131 | auto& webProcess = WebProcess::singleton(); |
132 | webProcess.parentProcessConnection()->send(Messages::WebProcessPool::HandleMessage(messageName, UserData(webProcess.transformObjectsToHandles(messageBody))), 0); |
133 | } |
134 | |
135 | void InjectedBundle::postSynchronousMessage(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) |
136 | { |
137 | UserData returnUserData; |
138 | |
139 | auto& webProcess = WebProcess::singleton(); |
140 | if (!webProcess.parentProcessConnection()->sendSync(Messages::WebProcessPool::HandleSynchronousMessage(messageName, UserData(webProcess.transformObjectsToHandles(messageBody))), |
141 | Messages::WebProcessPool::HandleSynchronousMessage::Reply(returnUserData), 0)) |
142 | returnData = nullptr; |
143 | else |
144 | returnData = webProcess.transformHandlesToObjects(returnUserData.object()); |
145 | } |
146 | |
147 | WebConnection* InjectedBundle::webConnectionToUIProcess() const |
148 | { |
149 | return WebProcess::singleton().webConnectionToUIProcess(); |
150 | } |
151 | |
152 | void InjectedBundle::overrideBoolPreferenceForTestRunner(WebPageGroupProxy* pageGroup, const String& preference, bool enabled) |
153 | { |
154 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
155 | |
156 | if (preference == "WebKitTabToLinksPreferenceKey" ) { |
157 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::tabsToLinksKey(), enabled); |
158 | for (auto* page : pages) |
159 | WebPage::fromCorePage(page)->setTabToLinksEnabled(enabled); |
160 | } |
161 | |
162 | if (preference == "WebKit2AsynchronousPluginInitializationEnabled" ) { |
163 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey(), enabled); |
164 | for (auto* page : pages) |
165 | WebPage::fromCorePage(page)->setAsynchronousPluginInitializationEnabled(enabled); |
166 | } |
167 | |
168 | if (preference == "WebKit2AsynchronousPluginInitializationEnabledForAllPlugins" ) { |
169 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey(), enabled); |
170 | for (auto* page : pages) |
171 | WebPage::fromCorePage(page)->setAsynchronousPluginInitializationEnabledForAllPlugins(enabled); |
172 | } |
173 | |
174 | if (preference == "WebKit2ArtificialPluginInitializationDelayEnabled" ) { |
175 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey(), enabled); |
176 | for (auto* page : pages) |
177 | WebPage::fromCorePage(page)->setArtificialPluginInitializationDelayEnabled(enabled); |
178 | } |
179 | |
180 | #if ENABLE(SERVICE_CONTROLS) |
181 | if (preference == "WebKitImageControlsEnabled" ) { |
182 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey(), enabled); |
183 | for (auto* page : pages) |
184 | page->settings().setImageControlsEnabled(enabled); |
185 | return; |
186 | } |
187 | #endif |
188 | |
189 | if (preference == "WebKitWebAnimationsEnabled" ) |
190 | RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsEnabled(enabled); |
191 | |
192 | if (preference == "WebKitWebAnimationsCSSIntegrationEnabled" ) |
193 | RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsCSSIntegrationEnabled(enabled); |
194 | |
195 | if (preference == "WebKitCacheAPIEnabled" ) |
196 | RuntimeEnabledFeatures::sharedFeatures().setCacheAPIEnabled(enabled); |
197 | |
198 | #if ENABLE(STREAMS_API) |
199 | if (preference == "WebKitReadableByteStreamAPIEnabled" ) |
200 | RuntimeEnabledFeatures::sharedFeatures().setReadableByteStreamAPIEnabled(enabled); |
201 | if (preference == "WebKitWritableStreamAPIEnabled" ) |
202 | RuntimeEnabledFeatures::sharedFeatures().setWritableStreamAPIEnabled(enabled); |
203 | #endif |
204 | |
205 | if (preference == "WebKitInteractiveFormValidationEnabled" ) |
206 | RuntimeEnabledFeatures::sharedFeatures().setInteractiveFormValidationEnabled(enabled); |
207 | |
208 | #if ENABLE(WEBGL2) |
209 | if (preference == "WebKitWebGL2Enabled" ) |
210 | RuntimeEnabledFeatures::sharedFeatures().setWebGL2Enabled(enabled); |
211 | #endif |
212 | |
213 | #if ENABLE(WEBGPU) |
214 | if (preference == "WebKitWebGPUEnabled" ) |
215 | RuntimeEnabledFeatures::sharedFeatures().setWebGPUEnabled(enabled); |
216 | #endif |
217 | |
218 | if (preference == "WebKitModernMediaControlsEnabled" ) |
219 | RuntimeEnabledFeatures::sharedFeatures().setModernMediaControlsEnabled(enabled); |
220 | |
221 | #if ENABLE(ENCRYPTED_MEDIA) |
222 | if (preference == "WebKitEncryptedMediaAPIEnabled" ) { |
223 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::encryptedMediaAPIEnabledKey(), enabled); |
224 | RuntimeEnabledFeatures::sharedFeatures().setEncryptedMediaAPIEnabled(enabled); |
225 | } |
226 | #endif |
227 | |
228 | #if ENABLE(MEDIA_STREAM) |
229 | if (preference == "WebKitMediaDevicesEnabled" ) |
230 | RuntimeEnabledFeatures::sharedFeatures().setMediaDevicesEnabled(enabled); |
231 | if (preference == "WebKitScreenCaptureEnabled" ) |
232 | RuntimeEnabledFeatures::sharedFeatures().setScreenCaptureEnabled(enabled); |
233 | #endif |
234 | |
235 | #if ENABLE(WEB_RTC) |
236 | if (preference == "WebKitWebRTCMDNSICECandidatesEnabled" ) |
237 | RuntimeEnabledFeatures::sharedFeatures().setWebRTCMDNSICECandidatesEnabled(enabled); |
238 | if (preference == "WebKitWebRTCUnifiedPlanEnabled" ) |
239 | RuntimeEnabledFeatures::sharedFeatures().setWebRTCUnifiedPlanEnabled(enabled); |
240 | #endif |
241 | |
242 | if (preference == "WebKitIsSecureContextAttributeEnabled" ) { |
243 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::isSecureContextAttributeEnabledKey(), enabled); |
244 | RuntimeEnabledFeatures::sharedFeatures().setIsSecureContextAttributeEnabled(enabled); |
245 | } |
246 | |
247 | if (preference == "WebKitWebAPIStatisticsEnabled" ) |
248 | RuntimeEnabledFeatures::sharedFeatures().setWebAPIStatisticsEnabled(enabled); |
249 | |
250 | if (preference == "CSSCustomPropertiesAndValuesEnabled" ) |
251 | RuntimeEnabledFeatures::sharedFeatures().setCSSCustomPropertiesAndValuesEnabled(enabled); |
252 | |
253 | #if ENABLE(LAYOUT_FORMATTING_CONTEXT) |
254 | if (preference == "LayoutFormattingContextEnabled" ) |
255 | RuntimeEnabledFeatures::sharedFeatures().setLayoutFormattingContextEnabled(enabled); |
256 | #endif |
257 | |
258 | #if ENABLE(CSS_PAINTING_API) |
259 | if (preference == "CSSPaintingAPIEnabled" ) |
260 | RuntimeEnabledFeatures::sharedFeatures().setCSSPaintingAPIEnabled(enabled); |
261 | #endif |
262 | |
263 | #if ENABLE(CSS_TYPED_OM) |
264 | if (preference == "CSSTypedOMEnabled" ) |
265 | RuntimeEnabledFeatures::sharedFeatures().setCSSTypedOMEnabled(enabled); |
266 | #endif |
267 | |
268 | // Map the names used in LayoutTests with the names used in WebCore::Settings and WebPreferencesStore. |
269 | #define FOR_EACH_OVERRIDE_BOOL_PREFERENCE(macro) \ |
270 | macro(WebKitJavaEnabled, JavaEnabled, javaEnabled) \ |
271 | macro(WebKitJavaScriptEnabled, ScriptEnabled, javaScriptEnabled) \ |
272 | macro(WebKitPluginsEnabled, PluginsEnabled, pluginsEnabled) \ |
273 | macro(WebKitUsesPageCachePreferenceKey, UsesPageCache, usesPageCache) \ |
274 | macro(WebKitWebAudioEnabled, WebAudioEnabled, webAudioEnabled) \ |
275 | macro(WebKitWebGLEnabled, WebGLEnabled, webGLEnabled) \ |
276 | macro(WebKitXSSAuditorEnabled, XSSAuditorEnabled, xssAuditorEnabled) \ |
277 | macro(WebKitShouldRespectImageOrientation, ShouldRespectImageOrientation, shouldRespectImageOrientation) \ |
278 | macro(WebKitDisplayImagesKey, LoadsImagesAutomatically, loadsImagesAutomatically) \ |
279 | macro(WebKitLargeImageAsyncDecodingEnabled, LargeImageAsyncDecodingEnabled, largeImageAsyncDecodingEnabled) \ |
280 | macro(WebKitAnimatedImageAsyncDecodingEnabled, AnimatedImageAsyncDecodingEnabled, animatedImageAsyncDecodingEnabled) \ |
281 | \ |
282 | |
283 | #define OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES(TestRunnerName, SettingsName, WebPreferencesName) \ |
284 | if (preference == #TestRunnerName) { \ |
285 | WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::WebPreferencesName##Key(), enabled); \ |
286 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) \ |
287 | (*iter)->settings().set##SettingsName(enabled); \ |
288 | return; \ |
289 | } |
290 | |
291 | FOR_EACH_OVERRIDE_BOOL_PREFERENCE(OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES) |
292 | |
293 | OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES(WebKitHiddenPageDOMTimerThrottlingEnabled, HiddenPageDOMTimerThrottlingEnabled, hiddenPageDOMTimerThrottlingEnabled) |
294 | |
295 | #undef OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES |
296 | #undef FOR_EACH_OVERRIDE_BOOL_PREFERENCE |
297 | } |
298 | |
299 | void InjectedBundle::setAllowUniversalAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) |
300 | { |
301 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
302 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
303 | (*iter)->settings().setAllowUniversalAccessFromFileURLs(enabled); |
304 | } |
305 | |
306 | void InjectedBundle::setAllowFileAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) |
307 | { |
308 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
309 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
310 | (*iter)->settings().setAllowFileAccessFromFileURLs(enabled); |
311 | } |
312 | |
313 | void InjectedBundle::setNeedsStorageAccessFromFileURLsQuirk(WebPageGroupProxy* pageGroup, bool needsQuirk) |
314 | { |
315 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
316 | for (auto page : pages) |
317 | page->settings().setNeedsStorageAccessFromFileURLsQuirk(needsQuirk); |
318 | } |
319 | |
320 | void InjectedBundle::setMinimumLogicalFontSize(WebPageGroupProxy* pageGroup, int size) |
321 | { |
322 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
323 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
324 | (*iter)->settings().setMinimumLogicalFontSize(size); |
325 | } |
326 | |
327 | void InjectedBundle::setFrameFlatteningEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
328 | { |
329 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
330 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
331 | (*iter)->settings().setFrameFlattening(enabled ? FrameFlattening::FullyEnabled : FrameFlattening::Disabled); |
332 | } |
333 | |
334 | void InjectedBundle::setAsyncFrameScrollingEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
335 | { |
336 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
337 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
338 | (*iter)->settings().setAsyncFrameScrollingEnabled(enabled); |
339 | } |
340 | |
341 | void InjectedBundle::setJavaScriptCanAccessClipboard(WebPageGroupProxy* pageGroup, bool enabled) |
342 | { |
343 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
344 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
345 | (*iter)->settings().setJavaScriptCanAccessClipboard(enabled); |
346 | } |
347 | |
348 | void InjectedBundle::setPrivateBrowsingEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
349 | { |
350 | ASSERT(!hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); |
351 | WebProcess::singleton().enablePrivateBrowsingForTesting(enabled); |
352 | |
353 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
354 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
355 | (*iter)->enableLegacyPrivateBrowsing(enabled); |
356 | } |
357 | |
358 | void InjectedBundle::(WebPageGroupProxy* pageGroup, bool enabled) |
359 | { |
360 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
361 | HashSet<Page*>::const_iterator end = pages.end(); |
362 | for (HashSet<Page*>::const_iterator iter = pages.begin(); iter != end; ++iter) |
363 | (*iter)->settings().setJavaScriptCanOpenWindowsAutomatically(!enabled); |
364 | } |
365 | |
366 | void InjectedBundle::setAuthorAndUserStylesEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
367 | { |
368 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
369 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
370 | (*iter)->settings().setAuthorAndUserStylesEnabled(enabled); |
371 | } |
372 | |
373 | void InjectedBundle::setSpatialNavigationEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
374 | { |
375 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
376 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
377 | (*iter)->settings().setSpatialNavigationEnabled(enabled); |
378 | } |
379 | |
380 | void InjectedBundle::addOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) |
381 | { |
382 | SecurityPolicy::addOriginAccessWhitelistEntry(SecurityOrigin::createFromString(sourceOrigin).get(), destinationProtocol, destinationHost, allowDestinationSubdomains); |
383 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::AddOriginAccessWhitelistEntry { sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains }, 0); |
384 | |
385 | } |
386 | |
387 | void InjectedBundle::removeOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) |
388 | { |
389 | SecurityPolicy::removeOriginAccessWhitelistEntry(SecurityOrigin::createFromString(sourceOrigin).get(), destinationProtocol, destinationHost, allowDestinationSubdomains); |
390 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveOriginAccessWhitelistEntry { sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains }, 0); |
391 | } |
392 | |
393 | void InjectedBundle::resetOriginAccessWhitelists() |
394 | { |
395 | SecurityPolicy::resetOriginAccessWhitelists(); |
396 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ResetOriginAccessWhitelists { }, 0); |
397 | } |
398 | |
399 | void InjectedBundle::setAsynchronousSpellCheckingEnabled(WebPageGroupProxy* pageGroup, bool enabled) |
400 | { |
401 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
402 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
403 | (*iter)->settings().setAsynchronousSpellCheckingEnabled(enabled); |
404 | } |
405 | |
406 | int InjectedBundle::numberOfPages(WebFrame* frame, double pageWidthInPixels, double pageHeightInPixels) |
407 | { |
408 | Frame* coreFrame = frame ? frame->coreFrame() : 0; |
409 | if (!coreFrame) |
410 | return -1; |
411 | if (!pageWidthInPixels) |
412 | pageWidthInPixels = coreFrame->view()->width(); |
413 | if (!pageHeightInPixels) |
414 | pageHeightInPixels = coreFrame->view()->height(); |
415 | |
416 | return PrintContext::numberOfPages(*coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels)); |
417 | } |
418 | |
419 | int InjectedBundle::pageNumberForElementById(WebFrame* frame, const String& id, double pageWidthInPixels, double pageHeightInPixels) |
420 | { |
421 | Frame* coreFrame = frame ? frame->coreFrame() : 0; |
422 | if (!coreFrame) |
423 | return -1; |
424 | |
425 | Element* element = coreFrame->document()->getElementById(id); |
426 | if (!element) |
427 | return -1; |
428 | |
429 | if (!pageWidthInPixels) |
430 | pageWidthInPixels = coreFrame->view()->width(); |
431 | if (!pageHeightInPixels) |
432 | pageHeightInPixels = coreFrame->view()->height(); |
433 | |
434 | return PrintContext::pageNumberForElement(element, FloatSize(pageWidthInPixels, pageHeightInPixels)); |
435 | } |
436 | |
437 | String InjectedBundle::pageSizeAndMarginsInPixels(WebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) |
438 | { |
439 | Frame* coreFrame = frame ? frame->coreFrame() : 0; |
440 | if (!coreFrame) |
441 | return String(); |
442 | |
443 | return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft); |
444 | } |
445 | |
446 | bool InjectedBundle::isPageBoxVisible(WebFrame* frame, int pageIndex) |
447 | { |
448 | Frame* coreFrame = frame ? frame->coreFrame() : 0; |
449 | if (!coreFrame) |
450 | return false; |
451 | |
452 | return PrintContext::isPageBoxVisible(coreFrame, pageIndex); |
453 | } |
454 | |
455 | bool InjectedBundle::isProcessingUserGesture() |
456 | { |
457 | return UserGestureIndicator::processingUserGesture(); |
458 | } |
459 | |
460 | void InjectedBundle::addUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, String&& source, String&& url, API::Array* whitelist, API::Array* blacklist, WebCore::UserScriptInjectionTime injectionTime, WebCore::UserContentInjectedFrames injectedFrames) |
461 | { |
462 | UserScript userScript { WTFMove(source), URL(URL(), url), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectionTime, injectedFrames }; |
463 | |
464 | pageGroup->userContentController().addUserScript(*scriptWorld, WTFMove(userScript)); |
465 | } |
466 | |
467 | void InjectedBundle::addUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& source, const String& url, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames injectedFrames) |
468 | { |
469 | UserStyleSheet userStyleSheet{ source, URL(URL(), url), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectedFrames, UserStyleUserLevel }; |
470 | |
471 | pageGroup->userContentController().addUserStyleSheet(*scriptWorld, WTFMove(userStyleSheet)); |
472 | } |
473 | |
474 | void InjectedBundle::removeUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) |
475 | { |
476 | pageGroup->userContentController().removeUserScriptWithURL(*scriptWorld, URL(URL(), url)); |
477 | } |
478 | |
479 | void InjectedBundle::removeUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) |
480 | { |
481 | pageGroup->userContentController().removeUserStyleSheetWithURL(*scriptWorld, URL(URL(), url)); |
482 | } |
483 | |
484 | void InjectedBundle::removeUserScripts(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) |
485 | { |
486 | pageGroup->userContentController().removeUserScripts(*scriptWorld); |
487 | } |
488 | |
489 | void InjectedBundle::removeUserStyleSheets(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) |
490 | { |
491 | pageGroup->userContentController().removeUserStyleSheets(*scriptWorld); |
492 | } |
493 | |
494 | void InjectedBundle::removeAllUserContent(WebPageGroupProxy* pageGroup) |
495 | { |
496 | pageGroup->userContentController().removeAllUserContent(); |
497 | } |
498 | |
499 | void InjectedBundle::garbageCollectJavaScriptObjects() |
500 | { |
501 | GCController::singleton().garbageCollectNow(); |
502 | } |
503 | |
504 | void InjectedBundle::garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(bool waitUntilDone) |
505 | { |
506 | GCController::singleton().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); |
507 | } |
508 | |
509 | size_t InjectedBundle::javaScriptObjectsCount() |
510 | { |
511 | JSLockHolder lock(commonVM()); |
512 | return commonVM().heap.objectCount(); |
513 | } |
514 | |
515 | void InjectedBundle::reportException(JSContextRef context, JSValueRef exception) |
516 | { |
517 | if (!context || !exception) |
518 | return; |
519 | |
520 | JSC::ExecState* execState = toJS(context); |
521 | JSLockHolder lock(execState); |
522 | |
523 | // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a Page. |
524 | JSC::JSGlobalObject* globalObject = execState->lexicalGlobalObject(); |
525 | if (!toJSDOMWindow(globalObject->vm(), globalObject)) |
526 | return; |
527 | |
528 | WebCore::reportException(execState, toJS(execState, exception)); |
529 | } |
530 | |
531 | void InjectedBundle::didCreatePage(WebPage* page) |
532 | { |
533 | m_client->didCreatePage(*this, *page); |
534 | } |
535 | |
536 | void InjectedBundle::willDestroyPage(WebPage* page) |
537 | { |
538 | m_client->willDestroyPage(*this, *page); |
539 | } |
540 | |
541 | void InjectedBundle::didInitializePageGroup(WebPageGroupProxy* pageGroup) |
542 | { |
543 | m_client->didInitializePageGroup(*this, *pageGroup); |
544 | } |
545 | |
546 | void InjectedBundle::didReceiveMessage(const String& messageName, API::Object* messageBody) |
547 | { |
548 | m_client->didReceiveMessage(*this, messageName, messageBody); |
549 | } |
550 | |
551 | void InjectedBundle::didReceiveMessageToPage(WebPage* page, const String& messageName, API::Object* messageBody) |
552 | { |
553 | m_client->didReceiveMessageToPage(*this, *page, messageName, messageBody); |
554 | } |
555 | |
556 | void InjectedBundle::setUserStyleSheetLocation(WebPageGroupProxy* pageGroup, const String& location) |
557 | { |
558 | const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); |
559 | for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) |
560 | (*iter)->settings().setUserStyleSheetLocation(URL(URL(), location)); |
561 | } |
562 | |
563 | void InjectedBundle::setWebNotificationPermission(WebPage* page, const String& originString, bool allowed) |
564 | { |
565 | #if ENABLE(NOTIFICATIONS) |
566 | page->notificationPermissionRequestManager()->setPermissionLevelForTesting(originString, allowed); |
567 | #else |
568 | UNUSED_PARAM(page); |
569 | UNUSED_PARAM(originString); |
570 | UNUSED_PARAM(allowed); |
571 | #endif |
572 | } |
573 | |
574 | void InjectedBundle::removeAllWebNotificationPermissions(WebPage* page) |
575 | { |
576 | #if ENABLE(NOTIFICATIONS) |
577 | page->notificationPermissionRequestManager()->removeAllPermissionsForTesting(); |
578 | #else |
579 | UNUSED_PARAM(page); |
580 | #endif |
581 | } |
582 | |
583 | uint64_t InjectedBundle::webNotificationID(JSContextRef jsContext, JSValueRef jsNotification) |
584 | { |
585 | #if ENABLE(NOTIFICATIONS) |
586 | WebCore::Notification* notification = JSNotification::toWrapped(toJS(jsContext)->vm(), toJS(toJS(jsContext), jsNotification)); |
587 | if (!notification) |
588 | return 0; |
589 | return WebProcess::singleton().supplement<WebNotificationManager>()->notificationIDForTesting(notification); |
590 | #else |
591 | UNUSED_PARAM(jsContext); |
592 | UNUSED_PARAM(jsNotification); |
593 | return 0; |
594 | #endif |
595 | } |
596 | |
597 | // FIXME Get rid of this function and move it into WKBundle.cpp. |
598 | Ref<API::Data> InjectedBundle::createWebDataFromUint8Array(JSContextRef context, JSValueRef data) |
599 | { |
600 | JSC::ExecState* execState = toJS(context); |
601 | JSLockHolder lock(execState); |
602 | RefPtr<Uint8Array> arrayData = WebCore::toUnsharedUint8Array(execState->vm(), toJS(execState, data)); |
603 | return API::Data::create(static_cast<unsigned char*>(arrayData->baseAddress()), arrayData->byteLength()); |
604 | } |
605 | |
606 | InjectedBundle::DocumentIDToURLMap InjectedBundle::liveDocumentURLs(WebPageGroupProxy* pageGroup, bool excludeDocumentsInPageGroupPages) |
607 | { |
608 | DocumentIDToURLMap result; |
609 | |
610 | for (const auto* document : Document::allDocuments()) |
611 | result.add(document->identifier().toUInt64(), document->url().string()); |
612 | |
613 | if (excludeDocumentsInPageGroupPages) { |
614 | for (const auto* page : PageGroup::pageGroup(pageGroup->identifier())->pages()) { |
615 | for (const auto* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
616 | if (!frame->document()) |
617 | continue; |
618 | result.remove(frame->document()->identifier().toUInt64()); |
619 | } |
620 | } |
621 | } |
622 | |
623 | return result; |
624 | } |
625 | |
626 | void InjectedBundle::setTabKeyCyclesThroughElements(WebPage* page, bool enabled) |
627 | { |
628 | page->corePage()->setTabKeyCyclesThroughElements(enabled); |
629 | } |
630 | |
631 | void InjectedBundle::setWebAnimationsEnabled(bool enabled) |
632 | { |
633 | RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsEnabled(enabled); |
634 | } |
635 | |
636 | void InjectedBundle::setWebAnimationsCSSIntegrationEnabled(bool enabled) |
637 | { |
638 | RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsCSSIntegrationEnabled(enabled); |
639 | } |
640 | |
641 | } // namespace WebKit |
642 | |