Fix breakages in https://codereview.chromium.org/1155713003/
[chromium-blink-merge.git] / ios / web / web_state / web_view_creation_utils.mm
blob68f65701128afdd96a76e82c34a0a4c2b4ebe947
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/web_state/web_view_creation_utils.h"
7 #import <objc/runtime.h>
8 #import <WebKit/WebKit.h>
10 #include "base/logging.h"
11 #include "base/mac/scoped_nsobject.h"
12 #import "ios/web/alloc_with_zone_interceptor.h"
13 #include "ios/web/public/browser_state.h"
14 #include "ios/web/public/web_client.h"
15 #include "ios/web/ui_web_view_util.h"
16 #import "ios/web/weak_nsobject_counter.h"
17 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
18 #import "ios/web/web_state/ui/crw_ui_simple_web_view_controller.h"
19 #import "ios/web/web_state/ui/crw_wk_simple_web_view_controller.h"
20 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
22 #if !defined(NDEBUG)
23 #import "ios/web/web_state/ui/crw_debug_web_view.h"
24 #endif
26 #if !defined(NDEBUG)
28 namespace {
29 // Returns the counter of all the active WKWebViews.
30 web::WeakNSObjectCounter& GetActiveWKWebViewCounter() {
31   static web::WeakNSObjectCounter active_wk_web_view_counter;
32   return active_wk_web_view_counter;
34 // Decides if WKWebView can be created.
35 BOOL gAllowWKWebViewCreation = NO;
36 }  // namespace
38 @interface WKWebView(CRWAdditions)
39 @end
41 @implementation WKWebView(CRWAdditions)
43 + (void)load {
44   id (^allocator)(Class klass, NSZone* zone) = ^id(Class klass, NSZone* zone) {
45     if (gAllowWKWebViewCreation) {
46       return NSAllocateObject(klass, 0, zone);
47     }
48     // You have hit this because you are trying to create a WKWebView directly.
49     // Please use one of the web::CreateWKWKWebView methods that vend a
50     // WKWebView instead.
51     NOTREACHED();
52     return nil;
53   };
54   web::AddAllocWithZoneMethod([WKWebView class], allocator);
57 @end
59 #endif  // !defined(NDEBUG)
61 namespace {
62 // Returns a new WKWebView for displaying regular web content.
63 // Note: Callers are responsible for releasing the returned WKWebView.
64 WKWebView* CreateWKWebViewWithConfiguration(
65     CGRect frame,
66     WKWebViewConfiguration* configuration) {
67   DCHECK(configuration);
68   DCHECK(web::GetWebClient());
69   web::GetWebClient()->PreWebViewCreation();
70 #if !defined(NDEBUG)
71   gAllowWKWebViewCreation = YES;
72 #endif
74   WKWebView* result =
75       [[WKWebView alloc] initWithFrame:frame configuration:configuration];
76 #if !defined(NDEBUG)
77   GetActiveWKWebViewCounter().Insert(result);
78   gAllowWKWebViewCreation = NO;
79 #endif
81   // TODO(stuartmorgan): Figure out how to make this work; two different client
82   // methods for the two web view types?
83   // web::GetWebClient()->PostWebViewCreation(result);
85   return result;
89 namespace web {
91 UIWebView* CreateWebView(CGRect frame,
92                          NSString* request_group_id,
93                          BOOL use_desktop_user_agent) {
94   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
95                                              use_desktop_user_agent);
96   return web::CreateWebView(frame);
99 UIWebView* CreateWebView(CGRect frame) {
100   DCHECK(web::GetWebClient());
101   web::GetWebClient()->PreWebViewCreation();
103   UIWebView* result = nil;
104 #if defined(NDEBUG)
105   result = [[UIWebView alloc] initWithFrame:frame];
106 #else
107   // TODO(eugenebut): create constant for @"LogJavascript" (crbug.com/391807).
108   if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LogJavascript"])
109     result = [[CRWDebugWebView alloc] initWithFrame:frame];
110   else
111     result = [[UIWebView alloc] initWithFrame:frame];
112 #endif  // defined(NDEBUG)
114   // Disable data detector types. Safari does the same.
115   [result setDataDetectorTypes:UIDataDetectorTypeNone];
116   [result setScalesPageToFit:YES];
118   // By default UIWebView uses a very sluggish scroll speed. Set it to a more
119   // reasonable value.
120   result.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
122   web::GetWebClient()->PostWebViewCreation(result);
124   return result;
127 WKWebView* CreateWKWebView(CGRect frame,
128                            WKWebViewConfiguration* configuration,
129                            BrowserState* browser_state,
130                            NSString* request_group_id,
131                            BOOL use_desktop_user_agent) {
132   DCHECK(browser_state);
133   WKWebViewConfigurationProvider& config_provider =
134       WKWebViewConfigurationProvider::FromBrowserState(browser_state);
135   DCHECK_EQ([config_provider.GetWebViewConfiguration() processPool],
136             [configuration processPool]);
137   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
138                                              use_desktop_user_agent);
139   return CreateWKWebViewWithConfiguration(frame, configuration);
142 WKWebView* CreateWKWebView(CGRect frame, BrowserState* browser_state) {
143   DCHECK(browser_state);
144   WKWebViewConfigurationProvider& config_provider =
145       WKWebViewConfigurationProvider::FromBrowserState(browser_state);
146   return CreateWKWebViewWithConfiguration(
147       frame, config_provider.GetWebViewConfiguration());
150 NSUInteger GetActiveWKWebViewsCount() {
151 #if defined(NDEBUG)
152   // This should not be used in release builds.
153   CHECK(0);
154   return 0;
155 #else
156   return GetActiveWKWebViewCounter().Size();
157 #endif
160 id<CRWSimpleWebViewController> CreateSimpleWebViewController(
161     CGRect frame,
162     BrowserState* browser_state,
163     WebViewType web_view_type) {
164   // Transparently return the correct subclass.
165   if (web_view_type == WK_WEB_VIEW_TYPE) {
166     base::scoped_nsobject<WKWebView> web_view(
167         web::CreateWKWebView(frame, browser_state));
168     return [[CRWWKSimpleWebViewController alloc] initWithWKWebView:web_view];
169   }
170   base::scoped_nsobject<UIWebView> web_view(web::CreateWebView(frame));
171   return [[CRWUISimpleWebViewController alloc] initWithUIWebView:web_view];
174 id<CRWSimpleWebViewController> CreateStaticFileSimpleWebViewController(
175     CGRect frame,
176     BrowserState* browser_state,
177     WebViewType web_view_type) {
178   // Transparently return the correct subclass.
179   if (web_view_type == WK_WEB_VIEW_TYPE) {
180     // TOOD(shreyasv): Create a new util function vending a WKWebView, wrap that
181     // now return the UIWebView version. crbug.com/403634.
182   }
183   base::scoped_nsobject<UIWebView> staticFileWebView(
184       CreateStaticFileWebView(frame, browser_state));
185   return [[CRWUISimpleWebViewController alloc]
186       initWithUIWebView:staticFileWebView];
189 UIWebView* CreateStaticFileWebView(CGRect frame, BrowserState* browser_state) {
190   DCHECK(web::GetWebClient());
191   web::GetWebClient()->PreWebViewCreation();
193   UIWebView* result =
194       [[CRWStaticFileWebView alloc] initWithFrame:frame
195                                      browserState:browser_state];
197   web::GetWebClient()->PostWebViewCreation(result);
198   return result;
201 UIWebView* CreateStaticFileWebView() {
202   return CreateStaticFileWebView(CGRectZero, nullptr);
205 }  // namespace web