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

Unified Diff: ios/web/shell/view_controller.mm

Issue 1149323004: Upstream the iOS web_shell and supporting code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@web-thread-impl
Patch Set: Address review comments Created 5 years, 7 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
« no previous file with comments | « ios/web/shell/view_controller.h ('k') | ios/web/shell/web_exe_main.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/web/shell/view_controller.mm
diff --git a/ios/web/shell/view_controller.mm b/ios/web/shell/view_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..16e78fe72955d84dc38ffc0b678983e3e20f934d
--- /dev/null
+++ b/ios/web/shell/view_controller.mm
@@ -0,0 +1,334 @@
+// Copyright 2014 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/shell/view_controller.h"
+
+#include "base/mac/objc_property_releaser.h"
+#import "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/sys_string_conversions.h"
+#include "ios/net/cookies/cookie_store_ios.h"
+#import "ios/net/crn_http_protocol_handler.h"
+#import "ios/web/navigation/crw_session_controller.h"
+#include "ios/web/navigation/web_load_params.h"
+#import "ios/web/net/crw_url_verifying_protocol_handler.h"
+#include "ios/web/net/request_tracker_factory_impl.h"
+#import "ios/web/net/web_http_protocol_handler_delegate.h"
+#include "ios/web/public/referrer.h"
+#import "ios/web/public/web_controller_factory.h"
+#include "ios/web/public/web_state/web_state.h"
+#include "ios/web/public/web_view_util.h"
+#include "ios/web/shell/shell_browser_state.h"
+#include "ios/web/web_state/ui/crw_web_controller.h"
+#include "ios/web/web_state/web_state_impl.h"
+#include "ui/base/page_transition_types.h"
+
+namespace {
+// Returns true if WKWebView should be used instead of UIWebView.
+// TODO(stuartmorgan): Decide on a better way to control this.
+bool UseWKWebView() {
+#if defined(FORCE_ENABLE_WKWEBVIEW)
+ return web::IsWKWebViewSupported();
+#else
+ return false;
+#endif
+}
+}
+
+@interface ViewController () {
+ web::BrowserState* _browserState;
+ base::scoped_nsobject<CRWWebController> _webController;
+ scoped_ptr<web::RequestTrackerFactoryImpl> _requestTrackerFactory;
+ scoped_ptr<web::WebHTTPProtocolHandlerDelegate> _httpProtocolDelegate;
+
+ base::mac::ObjCPropertyReleaser _propertyReleaser_ViewController;
+}
+@property(nonatomic, readwrite, retain) UITextField* field;
+@end
+
+@implementation ViewController
+
+@synthesize field = _field;
+@synthesize containerView = _containerView;
+@synthesize toolbarView = _toolbarView;
+
+- (instancetype)initWithBrowserState:(web::BrowserState*)browserState {
+ self = [super initWithNibName:@"MainView" bundle:nil];
+ if (self) {
+ _propertyReleaser_ViewController.Init(self, [ViewController class]);
+ _browserState = browserState;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ net::HTTPProtocolHandlerDelegate::SetInstance(nullptr);
+ net::RequestTracker::SetRequestTrackerFactory(nullptr);
+ [super dealloc];
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Set up the toolbar buttons.
+ UIButton* back = [UIButton buttonWithType:UIButtonTypeCustom];
+ [back setImage:[UIImage imageNamed:@"toolbar_back"]
+ forState:UIControlStateNormal];
+ [back setFrame:CGRectMake(0, 0, 44, 44)];
+ [back setImageEdgeInsets:UIEdgeInsetsMake(5, 5, 4, 4)];
+ [back setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
+ [back addTarget:self
+ action:@selector(back)
+ forControlEvents:UIControlEventTouchUpInside];
+
+ UIButton* forward = [UIButton buttonWithType:UIButtonTypeCustom];
+ [forward setImage:[UIImage imageNamed:@"toolbar_forward"]
+ forState:UIControlStateNormal];
+ [forward setFrame:CGRectMake(44, 0, 44, 44)];
+ [forward setImageEdgeInsets:UIEdgeInsetsMake(5, 5, 4, 4)];
+ [forward setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
+ [forward addTarget:self
+ action:@selector(forward)
+ forControlEvents:UIControlEventTouchUpInside];
+
+ base::scoped_nsobject<UITextField> field([[UITextField alloc]
+ initWithFrame:CGRectMake(88, 6, CGRectGetWidth([_toolbarView frame]) - 98,
+ 31)]);
+ [field setDelegate:self];
+ [field setBackground:[[UIImage imageNamed:@"textfield_background"]
+ resizableImageWithCapInsets:UIEdgeInsetsMake(
+ 12, 12, 12, 12)]];
+ [field setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
+ [field setKeyboardType:UIKeyboardTypeWebSearch];
+ [field setAutocorrectionType:UITextAutocorrectionTypeNo];
+ [field setClearButtonMode:UITextFieldViewModeWhileEditing];
+ self.field = field;
+
+ [_toolbarView addSubview:back];
+ [_toolbarView addSubview:forward];
+ [_toolbarView addSubview:field];
+
+ // Set up the network stack before creating the WebState.
+ [self setUpNetworkStack];
+
+ scoped_ptr<web::WebStateImpl> webState(new web::WebStateImpl(_browserState));
+ webState->GetNavigationManagerImpl().InitializeSession(nil, nil, NO, 0);
+ web::WebViewType webViewType =
+ UseWKWebView() ? web::WK_WEB_VIEW_TYPE : web::UI_WEB_VIEW_TYPE;
+ _webController.reset(web::CreateWebController(webViewType, webState.Pass()));
+ [_webController setDelegate:self];
+ [_webController setWebUsageEnabled:YES];
+
+ [[_webController view] setFrame:[_containerView bounds]];
+ [_containerView addSubview:[_webController view]];
+
+ web::WebLoadParams params(GURL("https://dev.chromium.org/"));
+ params.transition_type = ui::PAGE_TRANSITION_TYPED;
+ [_webController loadWithParams:params];
+}
+
+- (void)setUpNetworkStack {
+ // Disable the default cache.
+ [NSURLCache setSharedURLCache:nil];
+
+ _httpProtocolDelegate.reset(new web::WebHTTPProtocolHandlerDelegate(
+ _browserState->GetRequestContext()));
+ net::HTTPProtocolHandlerDelegate::SetInstance(_httpProtocolDelegate.get());
+ BOOL success = [NSURLProtocol registerClass:[CRNHTTPProtocolHandler class]];
+ DCHECK(success);
+ // The CRWURLVerifyingProtocolHandler is used to verify URL in the
+ // CRWWebController. It must be registered after the HttpProtocolHandler
+ // because handlers are called in the reverse order of declaration.
+ success =
+ [NSURLProtocol registerClass:[CRWURLVerifyingProtocolHandler class]];
+ DCHECK(success);
+ _requestTrackerFactory.reset(
+ new web::RequestTrackerFactoryImpl(std::string()));
+ net::RequestTracker::SetRequestTrackerFactory(_requestTrackerFactory.get());
+ net::CookieStoreIOS::SetCookiePolicy(net::CookieStoreIOS::ALLOW);
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
+ if (bar == _toolbarView) {
+ return UIBarPositionTopAttached;
+ }
+ return UIBarPositionAny;
+}
+
+- (void)back {
+ if ([_webController canGoBack]) {
+ [_webController goBack];
+ }
+}
+
+- (void)forward {
+ if ([_webController canGoForward]) {
+ [_webController goForward];
+ }
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField*)field {
+ GURL url = GURL(base::SysNSStringToUTF8([field text]));
+
+ // Do not try to load invalid URLs.
+ if (url.is_valid()) {
+ web::WebLoadParams params(url);
+ params.transition_type = ui::PAGE_TRANSITION_TYPED;
+ [_webController loadWithParams:params];
+ }
+
+ [field resignFirstResponder];
+ [self updateToolbar];
+ return YES;
+}
+
+- (void)updateToolbar {
+ // Do not update the URL if the text field is currently being edited.
+ if ([_field isFirstResponder]) {
+ return;
+ }
+
+ const GURL& url = [_webController webStateImpl]->GetVisibleURL();
+ [_field setText:base::SysUTF8ToNSString(url.spec())];
+}
+
+// -----------------------------------------------------------------------
+#pragma mark Bikeshedding Implementation
+
+// Overridden to allow this view controller to receive motion events by being
+// first responder when no other views are.
+- (BOOL)canBecomeFirstResponder {
+ return YES;
+}
+
+- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent*)event {
+ if (event.subtype == UIEventSubtypeMotionShake) {
+ [self updateToolbarColor];
+ }
+}
+
+- (void)updateToolbarColor {
+ // Cycle through the following set of colors:
+ NSArray* colors = @[
+ // Vanilla Blue.
+ [UIColor colorWithRed:0.337 green:0.467 blue:0.988 alpha:1.0],
+ // Vanilla Red.
+ [UIColor colorWithRed:0.898 green:0.110 blue:0.137 alpha:1.0],
+ // Blue Grey.
+ [UIColor colorWithRed:0.376 green:0.490 blue:0.545 alpha:1.0],
+ // Brown.
+ [UIColor colorWithRed:0.475 green:0.333 blue:0.282 alpha:1.0],
+ // Purple.
+ [UIColor colorWithRed:0.612 green:0.153 blue:0.690 alpha:1.0],
+ // Teal.
+ [UIColor colorWithRed:0.000 green:0.737 blue:0.831 alpha:1.0],
+ // Deep Orange.
+ [UIColor colorWithRed:1.000 green:0.341 blue:0.133 alpha:1.0],
+ // Indigo.
+ [UIColor colorWithRed:0.247 green:0.318 blue:0.710 alpha:1.0],
+ // Vanilla Green.
+ [UIColor colorWithRed:0.145 green:0.608 blue:0.141 alpha:1.0],
+ // Pinkerton.
+ [UIColor colorWithRed:0.914 green:0.118 blue:0.388 alpha:1.0],
+ ];
+
+ NSUInteger currentIndex = [colors indexOfObject:_toolbarView.barTintColor];
+ if (currentIndex == NSNotFound) {
+ currentIndex = 0;
+ }
+ NSUInteger newIndex = currentIndex + 1;
+ if (newIndex >= [colors count]) {
+ // TODO(rohitrao): Out of colors! Consider prompting the user to pick their
+ // own color here. Also consider allowing the user to choose the entire set
+ // of colors or allowing the user to choose color randomization.
+ newIndex = 0;
+ }
+ _toolbarView.barTintColor = [colors objectAtIndex:newIndex];
+}
+
+// -----------------------------------------------------------------------
+// WebDelegate implementation.
+
+- (void)webWillAddPendingURL:(const GURL&)url
+ transition:(ui::PageTransition)transition {
+}
+- (void)webDidAddPendingURL {
+ [self updateToolbar];
+}
+- (void)webCancelStartLoadingRequest {
+}
+- (void)webDidStartLoadingURL:(const GURL&)currentUrl
+ shouldUpdateHistory:(BOOL)updateHistory {
+ [self updateToolbar];
+}
+- (void)webDidFinishWithURL:(const GURL&)url loadSuccess:(BOOL)loadSuccess {
+ [self updateToolbar];
+}
+
+- (CRWWebController*)webPageOrderedOpen:(const GURL&)url
+ referrer:(const web::Referrer&)referrer
+ windowName:(NSString*)windowName
+ inBackground:(BOOL)inBackground {
+ return nil;
+}
+
+- (CRWWebController*)webPageOrderedOpenBlankWithReferrer:
+ (const web::Referrer&)referrer
+ inBackground:(BOOL)inBackground {
+ return nil;
+}
+
+- (void)webPageOrderedClose {
+}
+- (void)goDelta:(int)delta {
+}
+- (void)openURLWithParams:(const web::WebState::OpenURLParams&)params {
+}
+- (BOOL)openExternalURL:(const GURL&)url {
+ return NO;
+}
+- (void)presentSSLError:(const net::SSLInfo&)info
+ forSSLStatus:(const web::SSLStatus&)status
+ recoverable:(BOOL)recoverable
+ callback:(SSLErrorCallback)shouldContinue {
+}
+- (void)presentSpoofingError {
+}
+- (void)webLoadCancelled:(const GURL&)url {
+}
+- (void)webDidUpdateHistoryStateWithPageURL:(const GURL&)pageUrl {
+}
+- (void)webController:(CRWWebController*)webController
+ retrievePlaceholderOverlayImage:(void (^)(UIImage*))block {
+}
+- (void)webController:(CRWWebController*)webController
+ onFormResubmissionForRequest:(NSURLRequest*)request
+ continueBlock:(ProceduralBlock)continueBlock
+ cancelBlock:(ProceduralBlock)cancelBlock {
+}
+- (void)webWillReload {
+}
+- (void)webWillInitiateLoadWithParams:(web::WebLoadParams&)params {
+}
+- (void)webDidUpdateSessionForLoadWithParams:(const web::WebLoadParams&)params
+ wasInitialNavigation:(BOOL)initialNavigation {
+}
+- (void)webWillFinishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry {
+}
+- (void)webWillGoDelta:(int)delta {
+}
+- (void)webDidPrepareForGoBack {
+}
+- (int)downloadImageAtUrl:(const GURL&)url
+ maxBitmapSize:(uint32_t)maxBitmapSize
+ callback:
+ (const web::WebState::ImageDownloadCallback&)callback {
+ return -1;
+}
+
+@end
« no previous file with comments | « ios/web/shell/view_controller.h ('k') | ios/web/shell/web_exe_main.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698