1/* 2 * Copyright (C) 2010, 2013 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 "Arguments.h" 31#include "InjectedBundleScriptWorld.h" 32#include "InjectedBundleUserMessageCoders.h" 33#include "NotificationPermissionRequestManager.h" 34#include "SessionTracker.h" 35#include "WKAPICast.h" 36#include "WKBundleAPICast.h" 37#include "WebApplicationCacheManager.h" 38#include "WebConnectionToUIProcess.h" 39#include "WebContextMessageKinds.h" 40#include "WebCookieManager.h" 41#include "WebCoreArgumentCoders.h" 42#include "WebDatabaseManager.h" 43#include "WebFrame.h" 44#include "WebFrameNetworkingContext.h" 45#include "WebPage.h" 46#include "WebPreferencesKeys.h" 47#include "WebPreferencesStore.h" 48#include "WebProcess.h" 49#include "WebProcessCreationParameters.h" 50#include <JavaScriptCore/APICast.h> 51#include <JavaScriptCore/JSLock.h> 52#include <WebCore/ApplicationCache.h> 53#include <WebCore/ApplicationCacheStorage.h> 54#include <WebCore/FrameLoader.h> 55#include <WebCore/FrameView.h> 56#include <WebCore/GCController.h> 57#include <WebCore/GeolocationClient.h> 58#include <WebCore/GeolocationController.h> 59#include <WebCore/GeolocationPosition.h> 60#include <WebCore/JSDOMWindow.h> 61#include <WebCore/JSNotification.h> 62#include <WebCore/MainFrame.h> 63#include <WebCore/Page.h> 64#include <WebCore/PageGroup.h> 65#include <WebCore/PrintContext.h> 66#include <WebCore/ResourceHandle.h> 67#include <WebCore/ResourceLoadScheduler.h> 68#include <WebCore/ScriptController.h> 69#include <WebCore/SecurityOrigin.h> 70#include <WebCore/SecurityPolicy.h> 71#include <WebCore/SessionID.h> 72#include <WebCore/Settings.h> 73#include <WebCore/UserGestureIndicator.h> 74 75#if ENABLE(CSS_REGIONS) || ENABLE(CSS_COMPOSITING) 76#include <WebCore/RuntimeEnabledFeatures.h> 77#endif 78 79#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 80#include "WebNotificationManager.h" 81#endif 82 83using namespace WebCore; 84using namespace JSC; 85 86namespace WebKit { 87 88PassRefPtr<InjectedBundle> InjectedBundle::create(const WebProcessCreationParameters& parameters, API::Object* initializationUserData) 89{ 90 RefPtr<InjectedBundle> bundle = adoptRef(new InjectedBundle(parameters)); 91 92 bundle->m_sandboxExtension = SandboxExtension::create(parameters.injectedBundlePathExtensionHandle); 93 if (!bundle->initialize(parameters, initializationUserData)) 94 return nullptr; 95 96 return bundle.release(); 97} 98 99InjectedBundle::InjectedBundle(const WebProcessCreationParameters& parameters) 100 : m_path(parameters.injectedBundlePath) 101 , m_platformBundle(0) 102{ 103} 104 105InjectedBundle::~InjectedBundle() 106{ 107} 108 109void InjectedBundle::initializeClient(const WKBundleClientBase* client) 110{ 111 m_client.initialize(client); 112} 113 114void InjectedBundle::postMessage(const String& messageName, API::Object* messageBody) 115{ 116 auto encoder = std::make_unique<IPC::MessageEncoder>(WebContextLegacyMessages::messageReceiverName(), WebContextLegacyMessages::postMessageMessageName(), 0); 117 encoder->encode(messageName); 118 encoder->encode(InjectedBundleUserMessageEncoder(messageBody)); 119 120 WebProcess::shared().parentProcessConnection()->sendMessage(WTF::move(encoder)); 121} 122 123void InjectedBundle::postSynchronousMessage(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) 124{ 125 InjectedBundleUserMessageDecoder messageDecoder(returnData); 126 127 uint64_t syncRequestID; 128 std::unique_ptr<IPC::MessageEncoder> encoder = WebProcess::shared().parentProcessConnection()->createSyncMessageEncoder(WebContextLegacyMessages::messageReceiverName(), WebContextLegacyMessages::postSynchronousMessageMessageName(), 0, syncRequestID); 129 encoder->encode(messageName); 130 encoder->encode(InjectedBundleUserMessageEncoder(messageBody)); 131 132 std::unique_ptr<IPC::MessageDecoder> replyDecoder = WebProcess::shared().parentProcessConnection()->sendSyncMessage(syncRequestID, WTF::move(encoder), std::chrono::milliseconds::max()); 133 if (!replyDecoder || !replyDecoder->decode(messageDecoder)) { 134 returnData = nullptr; 135 return; 136 } 137} 138 139WebConnection* InjectedBundle::webConnectionToUIProcess() const 140{ 141 return WebProcess::shared().webConnectionToUIProcess(); 142} 143 144void InjectedBundle::setAlwaysAcceptCookies(bool accept) 145{ 146 WebProcess::shared().supplement<WebCookieManager>()->setHTTPCookieAcceptPolicy(accept ? HTTPCookieAcceptPolicyAlways : HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain); 147} 148 149void InjectedBundle::removeAllVisitedLinks() 150{ 151 PageGroup::removeAllVisitedLinks(); 152} 153 154void InjectedBundle::setCacheModel(uint32_t cacheModel) 155{ 156 WebProcess::shared().setCacheModel(cacheModel); 157} 158 159void InjectedBundle::overrideBoolPreferenceForTestRunner(WebPageGroupProxy* pageGroup, const String& preference, bool enabled) 160{ 161 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 162 163 if (preference == "WebKitTabToLinksPreferenceKey") { 164 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::tabsToLinksKey(), enabled); 165 for (auto* page : pages) 166 WebPage::fromCorePage(page)->setTabToLinksEnabled(enabled); 167 } 168 169 if (preference == "WebKit2AsynchronousPluginInitializationEnabled") { 170 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey(), enabled); 171 for (auto* page : pages) 172 WebPage::fromCorePage(page)->setAsynchronousPluginInitializationEnabled(enabled); 173 } 174 175 if (preference == "WebKit2AsynchronousPluginInitializationEnabledForAllPlugins") { 176 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey(), enabled); 177 for (auto* page : pages) 178 WebPage::fromCorePage(page)->setAsynchronousPluginInitializationEnabledForAllPlugins(enabled); 179 } 180 181 if (preference == "WebKit2ArtificialPluginInitializationDelayEnabled") { 182 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey(), enabled); 183 for (auto* page : pages) 184 WebPage::fromCorePage(page)->setArtificialPluginInitializationDelayEnabled(enabled); 185 } 186 187#if ENABLE(SERVICE_CONTROLS) 188 if (preference == "WebKitImageControlsEnabled") { 189 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey(), enabled); 190 for (auto* page : pages) 191 page->settings().setImageControlsEnabled(enabled); 192 return; 193 } 194#endif 195 196#if ENABLE(CSS_REGIONS) 197 if (preference == "WebKitCSSRegionsEnabled") 198 RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(enabled); 199#endif 200 201#if ENABLE(CSS_COMPOSITING) 202 if (preference == "WebKitCSSCompositingEnabled") 203 RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled(enabled); 204#endif 205 206 // Map the names used in LayoutTests with the names used in WebCore::Settings and WebPreferencesStore. 207#define FOR_EACH_OVERRIDE_BOOL_PREFERENCE(macro) \ 208 macro(WebKitAcceleratedCompositingEnabled, AcceleratedCompositingEnabled, acceleratedCompositingEnabled) \ 209 macro(WebKitCanvasUsesAcceleratedDrawing, CanvasUsesAcceleratedDrawing, canvasUsesAcceleratedDrawing) \ 210 macro(WebKitFrameFlatteningEnabled, FrameFlatteningEnabled, frameFlatteningEnabled) \ 211 macro(WebKitJavaEnabled, JavaEnabled, javaEnabled) \ 212 macro(WebKitJavaScriptEnabled, ScriptEnabled, javaScriptEnabled) \ 213 macro(WebKitLoadSiteIconsKey, LoadsSiteIconsIgnoringImageLoadingSetting, loadsSiteIconsIgnoringImageLoadingPreference) \ 214 macro(WebKitOfflineWebApplicationCacheEnabled, OfflineWebApplicationCacheEnabled, offlineWebApplicationCacheEnabled) \ 215 macro(WebKitPageCacheSupportsPluginsPreferenceKey, PageCacheSupportsPlugins, pageCacheSupportsPlugins) \ 216 macro(WebKitPluginsEnabled, PluginsEnabled, pluginsEnabled) \ 217 macro(WebKitUsesPageCachePreferenceKey, UsesPageCache, usesPageCache) \ 218 macro(WebKitWebAudioEnabled, WebAudioEnabled, webAudioEnabled) \ 219 macro(WebKitWebGLEnabled, WebGLEnabled, webGLEnabled) \ 220 macro(WebKitXSSAuditorEnabled, XSSAuditorEnabled, xssAuditorEnabled) \ 221 macro(WebKitShouldRespectImageOrientation, ShouldRespectImageOrientation, shouldRespectImageOrientation) \ 222 macro(WebKitEnableCaretBrowsing, CaretBrowsingEnabled, caretBrowsingEnabled) \ 223 macro(WebKitDisplayImagesKey, LoadsImagesAutomatically, loadsImagesAutomatically) \ 224 macro(WebKitMediaStreamEnabled, MediaStreamEnabled, mediaStreamEnabled) 225 226#define OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES(TestRunnerName, SettingsName, WebPreferencesName) \ 227 if (preference == #TestRunnerName) { \ 228 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::WebPreferencesName##Key(), enabled); \ 229 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) \ 230 (*iter)->settings().set##SettingsName(enabled); \ 231 return; \ 232 } 233 234 FOR_EACH_OVERRIDE_BOOL_PREFERENCE(OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES) 235 236#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) 237 OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES(WebKitHiddenPageDOMTimerThrottlingEnabled, HiddenPageDOMTimerThrottlingEnabled, hiddenPageDOMTimerThrottlingEnabled) 238#endif 239 240#undef OVERRIDE_PREFERENCE_AND_SET_IN_EXISTING_PAGES 241#undef FOR_EACH_OVERRIDE_BOOL_PREFERENCE 242} 243 244void InjectedBundle::overrideXSSAuditorEnabledForTestRunner(WebPageGroupProxy* pageGroup, bool enabled) 245{ 246 // Override the preference for all future pages. 247 WebPreferencesStore::overrideBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey(), enabled); 248 249 // Change the setting for existing ones. 250 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 251 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 252 (*iter)->settings().setXSSAuditorEnabled(enabled); 253} 254 255void InjectedBundle::setAllowUniversalAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) 256{ 257 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 258 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 259 (*iter)->settings().setAllowUniversalAccessFromFileURLs(enabled); 260} 261 262void InjectedBundle::setAllowFileAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) 263{ 264 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 265 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 266 (*iter)->settings().setAllowFileAccessFromFileURLs(enabled); 267} 268 269void InjectedBundle::setMinimumLogicalFontSize(WebPageGroupProxy* pageGroup, int size) 270{ 271 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 272 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 273 (*iter)->settings().setMinimumLogicalFontSize(size); 274} 275 276void InjectedBundle::setFrameFlatteningEnabled(WebPageGroupProxy* pageGroup, bool enabled) 277{ 278 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 279 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 280 (*iter)->settings().setFrameFlatteningEnabled(enabled); 281} 282 283void InjectedBundle::setPluginsEnabled(WebPageGroupProxy* pageGroup, bool enabled) 284{ 285 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 286 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 287 (*iter)->settings().setPluginsEnabled(enabled); 288} 289 290void InjectedBundle::setJavaScriptCanAccessClipboard(WebPageGroupProxy* pageGroup, bool enabled) 291{ 292 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 293 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 294 (*iter)->settings().setJavaScriptCanAccessClipboard(enabled); 295} 296 297void InjectedBundle::setPrivateBrowsingEnabled(WebPageGroupProxy* pageGroup, bool enabled) 298{ 299 // FIXME (NetworkProcess): This test-only function doesn't work with NetworkProcess, <https://bugs.webkit.org/show_bug.cgi?id=115274>. 300#if PLATFORM(COCOA) || USE(CFNETWORK) || USE(SOUP) 301 if (enabled) 302 WebFrameNetworkingContext::ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()); 303 else 304 SessionTracker::destroySession(SessionID::legacyPrivateSessionID()); 305#endif 306 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 307 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 308 (*iter)->enableLegacyPrivateBrowsing(enabled); 309} 310 311void InjectedBundle::setPopupBlockingEnabled(WebPageGroupProxy* pageGroup, bool enabled) 312{ 313 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 314 HashSet<Page*>::const_iterator end = pages.end(); 315 for (HashSet<Page*>::const_iterator iter = pages.begin(); iter != end; ++iter) 316 (*iter)->settings().setJavaScriptCanOpenWindowsAutomatically(!enabled); 317} 318 319void InjectedBundle::setAuthorAndUserStylesEnabled(WebPageGroupProxy* pageGroup, bool enabled) 320{ 321 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 322 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 323 (*iter)->settings().setAuthorAndUserStylesEnabled(enabled); 324} 325 326void InjectedBundle::setSpatialNavigationEnabled(WebPageGroupProxy* pageGroup, bool enabled) 327{ 328 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 329 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 330 (*iter)->settings().setSpatialNavigationEnabled(enabled); 331} 332 333void InjectedBundle::addOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) 334{ 335 SecurityPolicy::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); 336} 337 338void InjectedBundle::removeOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) 339{ 340 SecurityPolicy::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); 341} 342 343void InjectedBundle::resetOriginAccessWhitelists() 344{ 345 SecurityPolicy::resetOriginAccessWhitelists(); 346} 347 348void InjectedBundle::setAsynchronousSpellCheckingEnabled(WebPageGroupProxy* pageGroup, bool enabled) 349{ 350 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 351 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 352 (*iter)->settings().setAsynchronousSpellCheckingEnabled(enabled); 353} 354 355void InjectedBundle::clearAllDatabases() 356{ 357#if ENABLE(SQL_DATABASE) 358 WebProcess::shared().supplement<WebDatabaseManager>()->deleteAllDatabases(); 359#endif 360} 361 362void InjectedBundle::setDatabaseQuota(uint64_t quota) 363{ 364#if ENABLE(SQL_DATABASE) 365 // Historically, we've used the following (somewhat non-sensical) string 366 // for the databaseIdentifier of local files. 367 WebProcess::shared().supplement<WebDatabaseManager>()->setQuotaForOrigin("file__0", quota); 368#else 369 UNUSED_PARAM(quota); 370#endif 371} 372 373void InjectedBundle::clearApplicationCache() 374{ 375 WebProcess::shared().supplement<WebApplicationCacheManager>()->deleteAllEntries(); 376} 377 378void InjectedBundle::clearApplicationCacheForOrigin(const String& originString) 379{ 380 RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(originString); 381 ApplicationCache::deleteCacheForOrigin(origin.get()); 382} 383 384void InjectedBundle::setAppCacheMaximumSize(uint64_t size) 385{ 386 WebProcess::shared().supplement<WebApplicationCacheManager>()->setAppCacheMaximumSize(size); 387} 388 389uint64_t InjectedBundle::appCacheUsageForOrigin(const String& originString) 390{ 391 RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(originString); 392 return ApplicationCache::diskUsageForOrigin(origin.get()); 393} 394 395void InjectedBundle::setApplicationCacheOriginQuota(const String& originString, uint64_t bytes) 396{ 397 RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(originString); 398 cacheStorage().storeUpdatedQuotaForOrigin(origin.get(), bytes); 399} 400 401void InjectedBundle::resetApplicationCacheOriginQuota(const String& originString) 402{ 403 RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromString(originString); 404 cacheStorage().storeUpdatedQuotaForOrigin(origin.get(), cacheStorage().defaultOriginQuota()); 405} 406 407PassRefPtr<API::Array> InjectedBundle::originsWithApplicationCache() 408{ 409 HashSet<RefPtr<SecurityOrigin>> origins; 410 cacheStorage().getOriginsWithCache(origins); 411 412 Vector<RefPtr<API::Object>> originIdentifiers; 413 originIdentifiers.reserveInitialCapacity(origins.size()); 414 415 for (const auto& origin : origins) 416 originIdentifiers.uncheckedAppend(API::String::create(origin->databaseIdentifier())); 417 418 return API::Array::create(WTF::move(originIdentifiers)); 419} 420 421int InjectedBundle::numberOfPages(WebFrame* frame, double pageWidthInPixels, double pageHeightInPixels) 422{ 423 Frame* coreFrame = frame ? frame->coreFrame() : 0; 424 if (!coreFrame) 425 return -1; 426 if (!pageWidthInPixels) 427 pageWidthInPixels = coreFrame->view()->width(); 428 if (!pageHeightInPixels) 429 pageHeightInPixels = coreFrame->view()->height(); 430 431 return PrintContext::numberOfPages(coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels)); 432} 433 434int InjectedBundle::pageNumberForElementById(WebFrame* frame, const String& id, double pageWidthInPixels, double pageHeightInPixels) 435{ 436 Frame* coreFrame = frame ? frame->coreFrame() : 0; 437 if (!coreFrame) 438 return -1; 439 440 Element* element = coreFrame->document()->getElementById(id); 441 if (!element) 442 return -1; 443 444 if (!pageWidthInPixels) 445 pageWidthInPixels = coreFrame->view()->width(); 446 if (!pageHeightInPixels) 447 pageHeightInPixels = coreFrame->view()->height(); 448 449 return PrintContext::pageNumberForElement(element, FloatSize(pageWidthInPixels, pageHeightInPixels)); 450} 451 452String InjectedBundle::pageSizeAndMarginsInPixels(WebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) 453{ 454 Frame* coreFrame = frame ? frame->coreFrame() : 0; 455 if (!coreFrame) 456 return String(); 457 458 return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft); 459} 460 461bool InjectedBundle::isPageBoxVisible(WebFrame* frame, int pageIndex) 462{ 463 Frame* coreFrame = frame ? frame->coreFrame() : 0; 464 if (!coreFrame) 465 return false; 466 467 return PrintContext::isPageBoxVisible(coreFrame, pageIndex); 468} 469 470bool InjectedBundle::isProcessingUserGesture() 471{ 472 return ScriptController::processingUserGesture(); 473} 474 475void InjectedBundle::addUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& source, const String& url, API::Array* whitelist, API::Array* blacklist, WebCore::UserScriptInjectionTime injectionTime, WebCore::UserContentInjectedFrames injectedFrames) 476{ 477 // url is not from URL::string(), i.e. it has not already been parsed by URL, so we have to use the relative URL constructor for URL instead of the ParsedURLStringTag version. 478 PageGroup::pageGroup(pageGroup->identifier())->addUserScriptToWorld(scriptWorld->coreWorld(), source, URL(URL(), url), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectionTime, injectedFrames); 479} 480 481void InjectedBundle::addUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& source, const String& url, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames injectedFrames) 482{ 483 // url is not from URL::string(), i.e. it has not already been parsed by URL, so we have to use the relative URL constructor for URL instead of the ParsedURLStringTag version. 484 PageGroup::pageGroup(pageGroup->identifier())->addUserStyleSheetToWorld(scriptWorld->coreWorld(), source, URL(URL(), url), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectedFrames); 485} 486 487void InjectedBundle::removeUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) 488{ 489 // url is not from URL::string(), i.e. it has not already been parsed by URL, so we have to use the relative URL constructor for URL instead of the ParsedURLStringTag version. 490 PageGroup::pageGroup(pageGroup->identifier())->removeUserScriptFromWorld(scriptWorld->coreWorld(), URL(URL(), url)); 491} 492 493void InjectedBundle::removeUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) 494{ 495 // url is not from URL::string(), i.e. it has not already been parsed by URL, so we have to use the relative URL constructor for URL instead of the ParsedURLStringTag version. 496 PageGroup::pageGroup(pageGroup->identifier())->removeUserStyleSheetFromWorld(scriptWorld->coreWorld(), URL(URL(), url)); 497} 498 499void InjectedBundle::removeUserScripts(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) 500{ 501 PageGroup::pageGroup(pageGroup->identifier())->removeUserScriptsFromWorld(scriptWorld->coreWorld()); 502} 503 504void InjectedBundle::removeUserStyleSheets(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) 505{ 506 PageGroup::pageGroup(pageGroup->identifier())->removeUserStyleSheetsFromWorld(scriptWorld->coreWorld()); 507} 508 509void InjectedBundle::removeAllUserContent(WebPageGroupProxy* pageGroup) 510{ 511 PageGroup::pageGroup(pageGroup->identifier())->removeAllUserContent(); 512} 513 514void InjectedBundle::garbageCollectJavaScriptObjects() 515{ 516 gcController().garbageCollectNow(); 517} 518 519void InjectedBundle::garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(bool waitUntilDone) 520{ 521 gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 522} 523 524size_t InjectedBundle::javaScriptObjectsCount() 525{ 526 JSLockHolder lock(JSDOMWindow::commonVM()); 527 return JSDOMWindow::commonVM().heap.objectCount(); 528} 529 530void InjectedBundle::reportException(JSContextRef context, JSValueRef exception) 531{ 532 if (!context || !exception) 533 return; 534 535 JSC::ExecState* execState = toJS(context); 536 JSLockHolder lock(execState); 537 538 // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a Page. 539 if (!toJSDOMWindow(execState->lexicalGlobalObject())) 540 return; 541 542 WebCore::reportException(execState, toJS(execState, exception)); 543} 544 545void InjectedBundle::didCreatePage(WebPage* page) 546{ 547 m_client.didCreatePage(this, page); 548} 549 550void InjectedBundle::willDestroyPage(WebPage* page) 551{ 552 m_client.willDestroyPage(this, page); 553} 554 555void InjectedBundle::didInitializePageGroup(WebPageGroupProxy* pageGroup) 556{ 557 m_client.didInitializePageGroup(this, pageGroup); 558} 559 560void InjectedBundle::didReceiveMessage(const String& messageName, API::Object* messageBody) 561{ 562 m_client.didReceiveMessage(this, messageName, messageBody); 563} 564 565void InjectedBundle::didReceiveMessageToPage(WebPage* page, const String& messageName, API::Object* messageBody) 566{ 567 m_client.didReceiveMessageToPage(this, page, messageName, messageBody); 568} 569 570void InjectedBundle::setUserStyleSheetLocation(WebPageGroupProxy* pageGroup, const String& location) 571{ 572 const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); 573 for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) 574 (*iter)->settings().setUserStyleSheetLocation(URL(URL(), location)); 575} 576 577void InjectedBundle::setWebNotificationPermission(WebPage* page, const String& originString, bool allowed) 578{ 579#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 580 page->notificationPermissionRequestManager()->setPermissionLevelForTesting(originString, allowed); 581#else 582 UNUSED_PARAM(page); 583 UNUSED_PARAM(originString); 584 UNUSED_PARAM(allowed); 585#endif 586} 587 588void InjectedBundle::removeAllWebNotificationPermissions(WebPage* page) 589{ 590#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 591 page->notificationPermissionRequestManager()->removeAllPermissionsForTesting(); 592#else 593 UNUSED_PARAM(page); 594#endif 595} 596 597uint64_t InjectedBundle::webNotificationID(JSContextRef jsContext, JSValueRef jsNotification) 598{ 599#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 600 WebCore::Notification* notification = toNotification(toJS(toJS(jsContext), jsNotification)); 601 if (!notification) 602 return 0; 603 return WebProcess::shared().supplement<WebNotificationManager>()->notificationIDForTesting(notification); 604#else 605 UNUSED_PARAM(jsContext); 606 UNUSED_PARAM(jsNotification); 607 return 0; 608#endif 609} 610 611// FIXME Get rid of this function and move it into WKBundle.cpp. 612PassRefPtr<API::Data> InjectedBundle::createWebDataFromUint8Array(JSContextRef context, JSValueRef data) 613{ 614 JSC::ExecState* execState = toJS(context); 615 RefPtr<Uint8Array> arrayData = WebCore::toUint8Array(toJS(execState, data)); 616 return API::Data::create(static_cast<unsigned char*>(arrayData->baseAddress()), arrayData->byteLength()); 617} 618 619void InjectedBundle::setTabKeyCyclesThroughElements(WebPage* page, bool enabled) 620{ 621 page->corePage()->setTabKeyCyclesThroughElements(enabled); 622} 623 624void InjectedBundle::setSerialLoadingEnabled(bool enabled) 625{ 626 resourceLoadScheduler()->setSerialLoadingEnabled(enabled); 627} 628 629void InjectedBundle::setCSSRegionsEnabled(bool enabled) 630{ 631#if ENABLE(CSS_REGIONS) 632 RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(enabled); 633#else 634 UNUSED_PARAM(enabled); 635#endif 636} 637 638void InjectedBundle::setCSSCompositingEnabled(bool enabled) 639{ 640#if ENABLE(CSS_COMPOSITING) 641 RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled(enabled); 642#else 643 UNUSED_PARAM(enabled); 644#endif 645} 646 647void InjectedBundle::dispatchPendingLoadRequests() 648{ 649 resourceLoadScheduler()->servePendingRequests(); 650} 651 652} // namespace WebKit 653