Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ios / web / web_state / web_view_internal_creation_util.mm
blobed7a80f11c67b86d1ea9e5f67defeb278f98ead5
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_internal_creation_util.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 #import "ios/web/public/browsing_data_partition.h"
15 #include "ios/web/public/web_client.h"
16 #import "ios/web/public/web_view_creation_util.h"
17 #include "ios/web/ui_web_view_util.h"
18 #import "ios/web/weak_nsobject_counter.h"
19 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
20 #import "ios/web/web_state/ui/crw_ui_simple_web_view_controller.h"
21 #import "ios/web/web_state/ui/crw_wk_simple_web_view_controller.h"
22 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
24 #if !defined(NDEBUG)
25 #import "ios/web/web_state/ui/crw_debug_web_view.h"
26 #endif
28 #if !defined(NDEBUG)
30 namespace {
31 // Returns the counter of all the active WKWebViews.
32 web::WeakNSObjectCounter& GetActiveWKWebViewCounter() {
33   static web::WeakNSObjectCounter active_wk_web_view_counter;
34   return active_wk_web_view_counter;
36 // Decides if WKWebView can be created.
37 BOOL gAllowWKWebViewCreation = NO;
38 }  // namespace
40 @interface WKWebView (CRWAdditions)
41 @end
43 @implementation WKWebView (CRWAdditions)
45 + (void)load {
46   id (^allocator)(Class klass, NSZone* zone) = ^id(Class klass, NSZone* zone) {
47     if (gAllowWKWebViewCreation) {
48       return NSAllocateObject(klass, 0, zone);
49     }
50     // You have hit this because you are trying to create a WKWebView directly.
51     // Please use one of the web::CreateWKWKWebView methods that vend a
52     // WKWebView instead.
53     NOTREACHED();
54     return nil;
55   };
56   web::AddAllocWithZoneMethod([WKWebView class], allocator);
59 @end
61 #endif  // !defined(NDEBUG)
63 namespace web {
65 UIWebView* CreateWebView(CGRect frame,
66                          NSString* request_group_id,
67                          BOOL use_desktop_user_agent) {
68   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
69                                              use_desktop_user_agent);
70   return web::CreateWebView(frame);
73 UIWebView* CreateWebView(CGRect frame) {
74   DCHECK(web::GetWebClient());
75   web::GetWebClient()->PreWebViewCreation();
77   UIWebView* result = nil;
78 #if defined(NDEBUG)
79   result = [[UIWebView alloc] initWithFrame:frame];
80 #else
81   // TODO(eugenebut): create constant for @"LogJavascript" (crbug.com/391807).
82   if ([[NSUserDefaults standardUserDefaults] boolForKey:@"LogJavascript"])
83     result = [[CRWDebugWebView alloc] initWithFrame:frame];
84   else
85     result = [[UIWebView alloc] initWithFrame:frame];
86 #endif  // defined(NDEBUG)
88   // Disable data detector types. Safari does the same.
89   [result setDataDetectorTypes:UIDataDetectorTypeNone];
90   [result setScalesPageToFit:YES];
92   // By default UIWebView uses a very sluggish scroll speed. Set it to a more
93   // reasonable value.
94   result.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
96   web::GetWebClient()->PostWebViewCreation(result);
98   return result;
101 WKWebView* CreateWKWebView(CGRect frame,
102                            WKWebViewConfiguration* configuration,
103                            BrowserState* browser_state,
104                            NSString* request_group_id,
105                            BOOL use_desktop_user_agent) {
106   web::BuildAndRegisterUserAgentForUIWebView(request_group_id,
107                                              use_desktop_user_agent);
108   return CreateWKWebView(frame, configuration, browser_state);
111 WKWebView* CreateWKWebView(CGRect frame,
112                            WKWebViewConfiguration* configuration,
113                            BrowserState* browser_state) {
114   DCHECK(browser_state);
115   DCHECK(configuration);
116   DCHECK(web::BrowsingDataPartition::IsSynchronized());
117   WKWebViewConfigurationProvider& config_provider =
118       WKWebViewConfigurationProvider::FromBrowserState(browser_state);
119   DCHECK_EQ([config_provider.GetWebViewConfiguration() processPool],
120             [configuration processPool]);
122   DCHECK(web::GetWebClient());
123   web::GetWebClient()->PreWebViewCreation();
124 #if !defined(NDEBUG)
125   gAllowWKWebViewCreation = YES;
126 #endif
128   WKWebView* result =
129       [[WKWebView alloc] initWithFrame:frame configuration:configuration];
130 #if !defined(NDEBUG)
131   GetActiveWKWebViewCounter().Insert(result);
132   gAllowWKWebViewCreation = NO;
133 #endif
135   // TODO(stuartmorgan): Figure out how to make this work; two different client
136   // methods for the two web view types?
137   // web::GetWebClient()->PostWebViewCreation(result);
139   return result;
142 NSUInteger GetActiveWKWebViewsCount() {
143 #if defined(NDEBUG)
144   // This should not be used in release builds.
145   CHECK(0);
146   return 0;
147 #else
148   return GetActiveWKWebViewCounter().Size();
149 #endif
152 id<CRWSimpleWebViewController> CreateSimpleWebViewController(
153     CGRect frame,
154     BrowserState* browser_state,
155     WebViewType web_view_type) {
156   DCHECK(web::BrowsingDataPartition::IsSynchronized());
158   // Transparently return the correct subclass.
159   if (web_view_type == WK_WEB_VIEW_TYPE) {
160     base::scoped_nsobject<WKWebView> web_view(
161         web::CreateWKWebView(frame, browser_state));
162     return [[CRWWKSimpleWebViewController alloc] initWithWKWebView:web_view];
163   }
164   base::scoped_nsobject<UIWebView> web_view(web::CreateWebView(frame));
165   return [[CRWUISimpleWebViewController alloc] initWithUIWebView:web_view];
168 id<CRWSimpleWebViewController> CreateStaticFileSimpleWebViewController(
169     CGRect frame,
170     BrowserState* browser_state,
171     WebViewType web_view_type) {
172   DCHECK(web::BrowsingDataPartition::IsSynchronized());
174   // Transparently return the correct subclass.
175   if (web_view_type == WK_WEB_VIEW_TYPE) {
176     // TOOD(shreyasv): Create a new util function vending a WKWebView, wrap that
177     // now return the UIWebView version. crbug.com/403634.
178   }
179   base::scoped_nsobject<UIWebView> staticFileWebView(
180       CreateStaticFileWebView(frame, browser_state));
181   return [[CRWUISimpleWebViewController alloc]
182       initWithUIWebView:staticFileWebView];
185 UIWebView* CreateStaticFileWebView(CGRect frame, BrowserState* browser_state) {
186   DCHECK(web::GetWebClient());
187   web::GetWebClient()->PreWebViewCreation();
189   UIWebView* result =
190       [[CRWStaticFileWebView alloc] initWithFrame:frame
191                                      browserState:browser_state];
193   web::GetWebClient()->PostWebViewCreation(result);
194   return result;
197 UIWebView* CreateStaticFileWebView() {
198   return CreateStaticFileWebView(CGRectZero, nullptr);
201 }  // namespace web