Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Unified Diff: ios/web/web_state/ui/wk_web_view_configuration_provider.mm

Issue 1048613002: Upstream ios/web/web_state/ui support classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/web/web_state/ui/wk_web_view_configuration_provider.mm
diff --git a/ios/web/web_state/ui/wk_web_view_configuration_provider.mm b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
new file mode 100644
index 0000000000000000000000000000000000000000..535f8f1b0a4ebfaddba239f28bca4b29a28fc02b
--- /dev/null
+++ b/ios/web/web_state/ui/wk_web_view_configuration_provider.mm
@@ -0,0 +1,113 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
+
+#import <Foundation/Foundation.h>
+#import <WebKit/WebKit.h>
+
+#import "base/ios/weak_nsobject.h"
+#import "base/logging.h"
+#include "ios/web/public/browser_state.h"
+#import "ios/web/web_state/js/page_script_util.h"
+#import "ios/web/web_state/ui/crw_wk_script_message_router.h"
+
+// TODO(eugenebut): swizzle [[WKWebViewConfiguration alloc] init] to make sure
+// that WKWebViewConfiguration is obtained only from provider and can not be
+// created by alloc/init call.
+
+namespace web {
+
+namespace {
+// A key used to associate a WKWebViewConfigurationProvider with a BrowserState.
+const char kWKWebViewConfigProviderKeyName[] = "wk_web_view_config_provider";
+
+// Returns an autoreleased instance of WKUserScript to be added to
+// configuration's userContentController.
+WKUserScript* GetEarlyPageScript() {
+ // Content of WKUserScript can be injected into the same page multiple times
+ // without notifying WKNavigationDelegate (e.g. after window.document.write
+ // JavaScript call). Injecting the script one more time will invalidate
+ // __gCrWeb.windowId variable and will break the ability to send messages from
+ // JS to the native code. Wrapping injected script into "if (!injected)" check
+ // prevents multiple injections into the same page.
+ NSString* const kSourceTemplate =
+ @"if (!window.__gCrWKUserScriptInjected) {"
+ " window.__gCrWKUserScriptInjected = true; %@"
+ "}";
+ NSString* earlyScript = GetEarlyPageScript(WK_WEB_VIEW_TYPE);
+ NSString* source = [NSString stringWithFormat:kSourceTemplate, earlyScript];
+ return [[[WKUserScript alloc]
+ initWithSource:source
+ injectionTime:WKUserScriptInjectionTimeAtDocumentStart
+ forMainFrameOnly:YES] autorelease];
+}
+
+} // namespace
+
+// static
+WKWebViewConfigurationProvider&
+WKWebViewConfigurationProvider::FromBrowserState(BrowserState* browser_state) {
+ DCHECK([NSThread isMainThread]);
+ DCHECK(browser_state);
+ if (!browser_state->GetUserData(kWKWebViewConfigProviderKeyName)) {
+ browser_state->SetUserData(kWKWebViewConfigProviderKeyName,
+ new WKWebViewConfigurationProvider());
+ }
+ return *(static_cast<WKWebViewConfigurationProvider*>(
+ browser_state->GetUserData(kWKWebViewConfigProviderKeyName)));
+}
+
+WKWebViewConfigurationProvider::WKWebViewConfigurationProvider() {
+}
+
+WKWebViewConfigurationProvider::~WKWebViewConfigurationProvider() {
+}
+
+WKWebViewConfiguration*
+WKWebViewConfigurationProvider::GetWebViewConfiguration() {
+ DCHECK([NSThread isMainThread]);
+ if (!configuration_) {
+ configuration_.reset([[WKWebViewConfiguration alloc] init]);
+ // setJavaScriptCanOpenWindowsAutomatically is required to support popups.
+ [[configuration_ preferences] setJavaScriptCanOpenWindowsAutomatically:YES];
+ [[configuration_ userContentController] addUserScript:GetEarlyPageScript()];
+ }
+ // Prevent callers from changing the internals of configuration.
+ return [[configuration_ copy] autorelease];
+}
+
+CRWWKScriptMessageRouter*
+WKWebViewConfigurationProvider::GetScriptMessageRouter() {
+ DCHECK([NSThread isMainThread]);
+ if (!router_) {
+ WKUserContentController* userContentController =
+ [GetWebViewConfiguration() userContentController];
+ router_.reset([[CRWWKScriptMessageRouter alloc]
+ initWithUserContentController:userContentController]);
+ }
+ return router_;
+}
+
+bool WKWebViewConfigurationProvider::HasWebViewConfiguration() const {
+ DCHECK([NSThread isMainThread]);
+ return configuration_;
+}
+
+void WKWebViewConfigurationProvider::Purge() {
+ DCHECK([NSThread isMainThread]);
+#if !defined(NDEBUG) || !defined(DCHECK_ALWAYS_ON) // Matches DCHECK_IS_ON.
+ base::WeakNSObject<id> weak_configuration(configuration_);
+ base::WeakNSObject<id> weak_router(router_);
+ base::WeakNSObject<id> weak_process_pool([configuration_ processPool]);
+#endif // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+ configuration_.reset();
+ router_.reset();
+ // Make sure that no one retains configuration, router, processPool.
+ DCHECK(!weak_configuration);
+ DCHECK(!weak_router);
+ DCHECK(!weak_process_pool);
+}
+
+} // namespace web

Powered by Google App Engine
This is Rietveld 408576698