Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ios/chrome/browser/ui/static_content/static_html_view_controller.h" | 5 #include "ios/chrome/browser/ui/static_content/static_html_view_controller.h" |
| 6 | 6 |
| 7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
| 8 | 8 |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 | 10 |
| 11 #import "base/ios/weak_nsobject.h" | |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/mac/bundle_locations.h" | 12 #include "base/mac/bundle_locations.h" |
| 14 #include "base/mac/foundation_util.h" | 13 #include "base/mac/foundation_util.h" |
| 15 #include "base/mac/scoped_nsobject.h" | |
| 16 #include "ios/web/public/referrer.h" | 14 #include "ios/web/public/referrer.h" |
| 17 #import "ios/web/public/web_state/ui/crw_context_menu_delegate.h" | 15 #import "ios/web/public/web_state/ui/crw_context_menu_delegate.h" |
| 18 #import "ios/web/public/web_state/ui/crw_native_content.h" | 16 #import "ios/web/public/web_state/ui/crw_native_content.h" |
| 19 #import "ios/web/public/web_view_creation_util.h" | 17 #import "ios/web/public/web_view_creation_util.h" |
| 20 #import "net/base/mac/url_conversions.h" | 18 #import "net/base/mac/url_conversions.h" |
| 21 #include "ui/base/page_transition_types.h" | 19 #include "ui/base/page_transition_types.h" |
| 22 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 23 | 21 |
| 22 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
| 23 #error "This file requires ARC support." | |
| 24 #endif | |
| 25 | |
| 24 @implementation IdrHtmlGenerator | 26 @implementation IdrHtmlGenerator |
| 25 - (id)initWithResourceId:(int)resourceId encoding:(NSStringEncoding)encoding { | 27 - (id)initWithResourceId:(int)resourceId encoding:(NSStringEncoding)encoding { |
| 26 if ((self = [super init])) { | 28 if ((self = [super init])) { |
| 27 resourceId_ = resourceId; | 29 resourceId_ = resourceId; |
| 28 encoding_ = encoding; | 30 encoding_ = encoding; |
| 29 } | 31 } |
| 30 return self; | 32 return self; |
| 31 } | 33 } |
| 32 | 34 |
| 33 - (id)initWithResourceId:(int)resourceId { | 35 - (id)initWithResourceId:(int)resourceId { |
| 34 return [self initWithResourceId:resourceId encoding:NSUTF8StringEncoding]; | 36 return [self initWithResourceId:resourceId encoding:NSUTF8StringEncoding]; |
| 35 } | 37 } |
| 36 | 38 |
| 37 - (void)generateHtml:(HtmlCallback)callback { | 39 - (void)generateHtml:(HtmlCallback)callback { |
| 38 base::StringPiece html( | 40 base::StringPiece html( |
| 39 ResourceBundle::GetSharedInstance().GetRawDataResource(resourceId_)); | 41 ResourceBundle::GetSharedInstance().GetRawDataResource(resourceId_)); |
| 40 base::scoped_nsobject<NSString> result([[NSString alloc] | 42 NSString* result = [[NSString alloc] initWithBytes:html.data() |
| 41 initWithBytes:html.data() | 43 length:html.size() |
| 42 length:html.size() | 44 encoding:encoding_]; |
| 43 encoding:encoding_]); | |
| 44 callback(result); | 45 callback(result); |
| 45 } | 46 } |
| 46 @end | 47 @end |
| 47 | 48 |
| 48 @interface StaticHtmlViewController ()<CRWContextMenuDelegate, | 49 @interface StaticHtmlViewController ()<CRWContextMenuDelegate, |
| 49 WKNavigationDelegate> { | 50 WKNavigationDelegate> { |
| 50 @private | 51 @private |
| 51 // The referrer that will be passed when navigating from this page. | 52 // The referrer that will be passed when navigating from this page. |
| 52 web::Referrer referrer_; | 53 web::Referrer referrer_; |
| 53 | 54 |
| 54 // The URL that will be passed to the web page when loading. | 55 // The URL that will be passed to the web page when loading. |
| 55 // If the page is displaying a local HTML file, it contains the file URL to | 56 // If the page is displaying a local HTML file, it contains the file URL to |
| 56 // the file. | 57 // the file. |
| 57 // If the page is a generated HTML, it contains a random resource URL. | 58 // If the page is a generated HTML, it contains a random resource URL. |
| 58 base::scoped_nsobject<NSURL> resourceUrl_; | 59 NSURL* resourceUrl_; |
| 59 | 60 |
| 60 // If the view is displaying a local file, contains the URL of the root | 61 // If the view is displaying a local file, contains the URL of the root |
| 61 // directory containing all resources needed by the page. | 62 // directory containing all resources needed by the page. |
| 62 // The web view will get access to this page. | 63 // The web view will get access to this page. |
| 63 base::scoped_nsobject<NSURL> resourcesRootDirectory_; | 64 NSURL* resourcesRootDirectory_; |
| 64 | 65 |
| 65 // If the view is displaying a resources, contains the name of the resource. | 66 // If the view is displaying a resources, contains the name of the resource. |
| 66 base::scoped_nsobject<NSString> resource_; | 67 NSString* resource_; |
| 67 | 68 |
| 68 // If the view displayes a generated HTML, contains the |HtmlGenerator| to | 69 // If the view displayes a generated HTML, contains the |HtmlGenerator| to |
| 69 // generate it. | 70 // generate it. |
| 70 base::scoped_nsprotocol<id<HtmlGenerator>> generator_; | 71 id<HtmlGenerator> generator_; |
| 71 | 72 |
| 72 // Browser state associated with the view controller, used to create the | 73 // Browser state associated with the view controller, used to create the |
| 73 // WKWebView. | 74 // WKWebView. |
| 74 web::BrowserState* browserState_; // Weak. | 75 web::BrowserState* browserState_; // Weak. |
| 75 | 76 |
| 76 // The web view that is used to display the content. | 77 // The web view that is used to display the content. |
| 77 base::scoped_nsobject<WKWebView> webView_; | 78 WKWebView* webView_; |
| 78 | 79 |
| 79 // The delegate of the native content. | 80 // The delegate of the native content. |
| 80 base::WeakNSProtocol<id<CRWNativeContentDelegate>> delegate_; // weak | 81 __weak id<CRWNativeContentDelegate> delegate_; // weak |
|
stkhapugin
2017/05/30 13:28:16
remove "// weak" comment
lindsayw
2017/06/01 16:02:09
Done.
| |
| 81 | 82 |
| 82 // The loader to navigate from the page. | 83 // The loader to navigate from the page. |
| 83 base::WeakNSProtocol<id<UrlLoader>> loader_; // weak | 84 __weak id<UrlLoader> loader_; // weak |
|
stkhapugin
2017/05/30 13:28:16
remove "// weak" comment
lindsayw
2017/06/01 16:02:08
Done.
| |
| 84 } | 85 } |
| 85 | 86 |
| 86 // Returns the URL of the static page to display. | 87 // Returns the URL of the static page to display. |
| 87 - (NSURL*)resourceURL; | 88 - (NSURL*)resourceURL; |
| 88 // Ensures that webView_ has been created, creating it if necessary. | 89 // Ensures that webView_ has been created, creating it if necessary. |
| 89 - (void)ensureWebViewCreated; | 90 - (void)ensureWebViewCreated; |
| 90 // Determines if the page load should begin based on the current |resourceURL| | 91 // Determines if the page load should begin based on the current |resourceURL| |
| 91 // and if the request is issued by the main frame (|fromMainFrame|). | 92 // and if the request is issued by the main frame (|fromMainFrame|). |
| 92 - (BOOL)shouldStartLoadWithRequest:(NSURLRequest*)request | 93 - (BOOL)shouldStartLoadWithRequest:(NSURLRequest*)request |
| 93 fromMainFrame:(BOOL)fromMainFrame; | 94 fromMainFrame:(BOOL)fromMainFrame; |
| 94 @end | 95 @end |
| 95 | 96 |
| 96 @implementation StaticHtmlViewController | 97 @implementation StaticHtmlViewController |
| 97 | 98 |
| 98 - (instancetype)initWithResource:(NSString*)resource | 99 - (instancetype)initWithResource:(NSString*)resource |
| 99 browserState:(web::BrowserState*)browserState { | 100 browserState:(web::BrowserState*)browserState { |
| 100 DCHECK(resource); | 101 DCHECK(resource); |
| 101 DCHECK(browserState); | 102 DCHECK(browserState); |
| 102 if ((self = [super init])) { | 103 if ((self = [super init])) { |
| 103 resource_.reset([resource copy]); | 104 resource_ = [resource copy]; |
| 104 browserState_ = browserState; | 105 browserState_ = browserState; |
| 105 } | 106 } |
| 106 return self; | 107 return self; |
| 107 } | 108 } |
| 108 | 109 |
| 109 - (instancetype)initWithGenerator:(id<HtmlGenerator>)generator | 110 - (instancetype)initWithGenerator:(id<HtmlGenerator>)generator |
| 110 browserState:(web::BrowserState*)browserState { | 111 browserState:(web::BrowserState*)browserState { |
| 111 DCHECK(generator); | 112 DCHECK(generator); |
| 112 DCHECK(browserState); | 113 DCHECK(browserState); |
| 113 if ((self = [super init])) { | 114 if ((self = [super init])) { |
| 114 generator_.reset([generator retain]); | 115 generator_ = generator; |
| 115 browserState_ = browserState; | 116 browserState_ = browserState; |
| 116 } | 117 } |
| 117 return self; | 118 return self; |
| 118 } | 119 } |
| 119 | 120 |
| 120 - (instancetype)initWithFileURL:(const GURL&)URL | 121 - (instancetype)initWithFileURL:(const GURL&)URL |
| 121 allowingReadAccessToURL:(const GURL&)resourcesRoot | 122 allowingReadAccessToURL:(const GURL&)resourcesRoot |
| 122 browserState:(web::BrowserState*)browserState { | 123 browserState:(web::BrowserState*)browserState { |
| 123 DCHECK(URL.is_valid()); | 124 DCHECK(URL.is_valid()); |
| 124 DCHECK(URL.SchemeIsFile()); | 125 DCHECK(URL.SchemeIsFile()); |
| 125 DCHECK(browserState); | 126 DCHECK(browserState); |
| 126 if ((self = [super init])) { | 127 if ((self = [super init])) { |
| 127 resourceUrl_.reset([net::NSURLWithGURL(URL) retain]); | 128 resourceUrl_ = net::NSURLWithGURL(URL); |
| 128 resourcesRootDirectory_.reset([net::NSURLWithGURL(resourcesRoot) retain]); | 129 resourcesRootDirectory_ = net::NSURLWithGURL(resourcesRoot); |
| 129 browserState_ = browserState; | 130 browserState_ = browserState; |
| 130 } | 131 } |
| 131 return self; | 132 return self; |
| 132 } | 133 } |
| 133 | 134 |
| 134 - (void)dealloc { | 135 - (void)dealloc { |
| 135 [self removeWebViewObservers]; | 136 [self removeWebViewObservers]; |
| 136 [super dealloc]; | |
| 137 } | 137 } |
| 138 | 138 |
| 139 - (void)removeWebViewObservers { | 139 - (void)removeWebViewObservers { |
| 140 [webView_ removeObserver:self forKeyPath:@"title"]; | 140 [webView_ removeObserver:self forKeyPath:@"title"]; |
| 141 } | 141 } |
| 142 | 142 |
| 143 - (void)setLoader:(id<UrlLoader>)loader | 143 - (void)setLoader:(id<UrlLoader>)loader |
| 144 referrer:(const web::Referrer&)referrer { | 144 referrer:(const web::Referrer&)referrer { |
| 145 loader_.reset(loader); | 145 loader_ = loader; |
| 146 referrer_ = referrer; | 146 referrer_ = referrer; |
| 147 } | 147 } |
| 148 | 148 |
| 149 - (void)executeJavaScript:(NSString*)script | 149 - (void)executeJavaScript:(NSString*)script |
| 150 completionHandler:(web::JavaScriptResultBlock)handler { | 150 completionHandler:(web::JavaScriptResultBlock)handler { |
| 151 [webView_ evaluateJavaScript:script completionHandler:handler]; | 151 [webView_ evaluateJavaScript:script completionHandler:handler]; |
| 152 } | 152 } |
| 153 | 153 |
| 154 - (UIScrollView*)scrollView { | 154 - (UIScrollView*)scrollView { |
| 155 return [[self webView] scrollView]; | 155 return [[self webView] scrollView]; |
| 156 } | 156 } |
| 157 | 157 |
| 158 - (WKWebView*)webView { | 158 - (WKWebView*)webView { |
| 159 [self ensureWebViewCreated]; | 159 [self ensureWebViewCreated]; |
| 160 return webView_; | 160 return webView_; |
| 161 } | 161 } |
| 162 | 162 |
| 163 - (void)handleLowMemory { | 163 - (void)handleLowMemory { |
| 164 [self removeWebViewObservers]; | 164 [self removeWebViewObservers]; |
| 165 webView_.reset(); | 165 webView_ = nil; |
| 166 } | 166 } |
| 167 | 167 |
| 168 - (BOOL)isViewAlive { | 168 - (BOOL)isViewAlive { |
| 169 return webView_.get() != nil; | 169 return webView_ != nil; |
| 170 } | 170 } |
| 171 | 171 |
| 172 - (NSString*)title { | 172 - (NSString*)title { |
| 173 return [[self webView] title]; | 173 return [[self webView] title]; |
| 174 } | 174 } |
| 175 | 175 |
| 176 - (void)reload { | 176 - (void)reload { |
| 177 if (!generator_) { | 177 if (!generator_) { |
| 178 [webView_ reload]; | 178 [webView_ reload]; |
| 179 } else { | 179 } else { |
| 180 NSURL* resourceURL = [self resourceURL]; | 180 NSURL* resourceURL = [self resourceURL]; |
| 181 [generator_ generateHtml:^(NSString* HTML) { | 181 [generator_ generateHtml:^(NSString* HTML) { |
| 182 [webView_ loadHTMLString:HTML baseURL:resourceURL]; | 182 [webView_ loadHTMLString:HTML baseURL:resourceURL]; |
| 183 }]; | 183 }]; |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 - (void)triggerPendingLoad { | 187 - (void)triggerPendingLoad { |
| 188 // Ensure that the web view is created, which triggers loading. | 188 // Ensure that the web view is created, which triggers loading. |
| 189 [self ensureWebViewCreated]; | 189 [self ensureWebViewCreated]; |
| 190 } | 190 } |
| 191 | 191 |
| 192 - (void)setDelegate:(id<CRWNativeContentDelegate>)delegate { | 192 - (void)setDelegate:(id<CRWNativeContentDelegate>)delegate { |
| 193 delegate_.reset(delegate); | 193 delegate_ = delegate; |
| 194 } | 194 } |
| 195 | 195 |
| 196 - (void)setScrollEnabled:(BOOL)enabled { | 196 - (void)setScrollEnabled:(BOOL)enabled { |
| 197 [[self scrollView] setScrollEnabled:enabled]; | 197 [[self scrollView] setScrollEnabled:enabled]; |
| 198 } | 198 } |
| 199 | 199 |
| 200 #pragma mark - | 200 #pragma mark - |
| 201 #pragma mark WKNavigationDelegate implementation | 201 #pragma mark WKNavigationDelegate implementation |
| 202 | 202 |
| 203 - (void)webView:(WKWebView*)webView | 203 - (void)webView:(WKWebView*)webView |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 referrer:referrer_ | 256 referrer:referrer_ |
| 257 transition:ui::PAGE_TRANSITION_LINK | 257 transition:ui::PAGE_TRANSITION_LINK |
| 258 rendererInitiated:YES]; | 258 rendererInitiated:YES]; |
| 259 }); | 259 }); |
| 260 } | 260 } |
| 261 return NO; | 261 return NO; |
| 262 } | 262 } |
| 263 | 263 |
| 264 - (NSURL*)resourceURL { | 264 - (NSURL*)resourceURL { |
| 265 if (resourceUrl_) | 265 if (resourceUrl_) |
| 266 return resourceUrl_.get(); | 266 return resourceUrl_; |
| 267 | 267 |
| 268 DCHECK(resource_ || generator_); | 268 DCHECK(resource_ || generator_); |
| 269 NSString* path = nil; | 269 NSString* path = nil; |
| 270 if (resource_) { | 270 if (resource_) { |
| 271 NSBundle* bundle = base::mac::FrameworkBundle(); | 271 NSBundle* bundle = base::mac::FrameworkBundle(); |
| 272 NSString* bundlePath = [bundle bundlePath]; | 272 NSString* bundlePath = [bundle bundlePath]; |
| 273 path = [bundlePath stringByAppendingPathComponent:resource_.get()]; | 273 path = [bundlePath stringByAppendingPathComponent:resource_]; |
| 274 } else { | 274 } else { |
| 275 // Generate a random resource URL to whitelist the load in | 275 // Generate a random resource URL to whitelist the load in |
| 276 // |webView:shouldStartLoadWithRequest:navigationType:| method. | 276 // |webView:shouldStartLoadWithRequest:navigationType:| method. |
| 277 path = [NSString stringWithFormat:@"/whitelist%u%u%u%u", arc4random(), | 277 path = [NSString stringWithFormat:@"/whitelist%u%u%u%u", arc4random(), |
| 278 arc4random(), arc4random(), arc4random()]; | 278 arc4random(), arc4random(), arc4random()]; |
| 279 } | 279 } |
| 280 DCHECK(path); | 280 DCHECK(path); |
| 281 // Necessary because the |fileURLWithPath:| method adds a localhost in the | 281 // Necessary because the |fileURLWithPath:| method adds a localhost in the |
| 282 // URL, and this prevents the URL from being comparable with the ones that | 282 // URL, and this prevents the URL from being comparable with the ones that |
| 283 // UIWebView uses when calling the delegate. | 283 // UIWebView uses when calling the delegate. |
| 284 base::scoped_nsobject<NSURLComponents> components( | 284 NSURLComponents* components = [[NSURLComponents alloc] init]; |
| 285 [[NSURLComponents alloc] init]); | |
| 286 [components setScheme:@"file"]; | 285 [components setScheme:@"file"]; |
| 287 [components setHost:@""]; | 286 [components setHost:@""]; |
| 288 [components setPath:path]; | 287 [components setPath:path]; |
| 289 resourceUrl_.reset([[components URL] retain]); | 288 resourceUrl_ = [components URL]; |
| 290 resourcesRootDirectory_.reset([resourceUrl_ copy]); | 289 resourcesRootDirectory_ = [resourceUrl_ copy]; |
| 291 return resourceUrl_; | 290 return resourceUrl_; |
| 292 } | 291 } |
| 293 | 292 |
| 294 - (void)ensureWebViewCreated { | 293 - (void)ensureWebViewCreated { |
| 295 if (!webView_) { | 294 if (!webView_) { |
| 296 WKWebView* webView = web::BuildWKWebViewWithCustomContextMenu( | 295 WKWebView* webView = web::BuildWKWebViewWithCustomContextMenu( |
| 297 CGRectZero, browserState_, self); | 296 CGRectZero, browserState_, self); |
| 298 [webView addObserver:self forKeyPath:@"title" options:0 context:nullptr]; | 297 [webView addObserver:self forKeyPath:@"title" options:0 context:nullptr]; |
| 299 [webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | | 298 [webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | |
| 300 UIViewAutoresizingFlexibleHeight]; | 299 UIViewAutoresizingFlexibleHeight]; |
| 301 [self loadWebViewContents:webView]; | 300 [self loadWebViewContents:webView]; |
| 302 [webView setNavigationDelegate:self]; | 301 [webView setNavigationDelegate:self]; |
| 303 webView_.reset([webView retain]); | 302 webView_ = webView; |
| 304 } | 303 } |
| 305 } | 304 } |
| 306 | 305 |
| 307 - (void)loadWebViewContents:(WKWebView*)webView { | 306 - (void)loadWebViewContents:(WKWebView*)webView { |
| 308 if (!generator_) { | 307 if (!generator_) { |
| 309 [webView loadFileURL:[self resourceURL] | 308 [webView loadFileURL:[self resourceURL] |
| 310 allowingReadAccessToURL:resourcesRootDirectory_]; | 309 allowingReadAccessToURL:resourcesRootDirectory_]; |
| 311 } else { | 310 } else { |
| 312 NSURL* resourceURL = [self resourceURL]; | 311 NSURL* resourceURL = [self resourceURL]; |
| 313 [generator_ generateHtml:^(NSString* HTML) { | 312 [generator_ generateHtml:^(NSString* HTML) { |
| 314 [webView loadHTMLString:HTML baseURL:resourceURL]; | 313 [webView loadHTMLString:HTML baseURL:resourceURL]; |
| 315 }]; | 314 }]; |
| 316 } | 315 } |
| 317 } | 316 } |
| 318 | 317 |
| 319 @end | 318 @end |
| OLD | NEW |