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

Side by Side Diff: ios/web/web_state/ui/crw_wk_web_view_web_controller.mm

Issue 1375023002: Adds support for POST request with bodies on WKWebView. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missing javascript Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 #import "ios/web/web_state/ui/crw_wk_web_view_web_controller.h" 5 #import "ios/web/web_state/ui/crw_wk_web_view_web_controller.h"
6 6
7 #import <WebKit/WebKit.h> 7 #import <WebKit/WebKit.h>
8 8
9 #include "base/ios/ios_util.h" 9 #include "base/ios/ios_util.h"
10 #include "base/ios/weak_nsobject.h" 10 #include "base/ios/weak_nsobject.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 namespace { 50 namespace {
51 // Extracts Referer value from WKNavigationAction request header. 51 // Extracts Referer value from WKNavigationAction request header.
52 NSString* GetRefererFromNavigationAction(WKNavigationAction* action) { 52 NSString* GetRefererFromNavigationAction(WKNavigationAction* action) {
53 return [action.request valueForHTTPHeaderField:@"Referer"]; 53 return [action.request valueForHTTPHeaderField:@"Referer"];
54 } 54 }
55 55
56 NSString* const kScriptMessageName = @"crwebinvoke"; 56 NSString* const kScriptMessageName = @"crwebinvoke";
57 NSString* const kScriptImmediateName = @"crwebinvokeimmediate"; 57 NSString* const kScriptImmediateName = @"crwebinvokeimmediate";
58 58
59 // JavaScript template to do a POST request using an XMLHttpRequest.
60 // The request is retried once on failure, as it can be marked as failing to
61 // load the resource because of 302s on POST request (the cookies of the first
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 "the cookies of the first response are correctly s
stkhapugin 2015/09/30 15:05:14 Done.
62 // response are correctly set).
63 //
64 // The template takes three arguments (in order):
65 // * The quoted and escaped URL to send a POST request to.
66 // * The HTTP headers of the request. They should be written as valid JavaScript
67 // statements, adding headers to the XMLHttpRequest variable named 'req'
68 // (e.g. 'req.setRequestHeader("Foo", "Bar");').
69 // * The base64 string of POST request body.
70 // * Content-Type string
71 NSString* const kPostRequestTemplate =
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 This is a large piece of JS code. Maybe it will be
stkhapugin 2015/09/30 15:05:14 This is actually a piece of html. How do you think
Eugene But (OOO till 7-30) 2015/09/30 15:45:16 You can load your script from file and then wrap i
stkhapugin 2015/12/03 15:43:00 Acknowledged.
72 @"<html><script>"
73 "function b64toBlob(b64Data, contentType) {"
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 NIT: s/b64toBlob/b64ToBlob (camelCase according to
stkhapugin 2015/09/30 15:05:14 Done.
74 " contentType = contentType || '';"
75 " sliceSize = 512;"
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 var sliceSize; Otherwise this code creates a globa
stkhapugin 2015/09/30 15:05:14 Done.
76 " var byteCharacters = b64Data;"
77 " var byteArrays = [];"
78 " for (var offset = 0; offset < byteCharacters.length; offset += "
79 "sliceSize) {"
80 " var slice = byteCharacters.slice(offset, offset + sliceSize);"
81 " var byteNumbers = new Array(slice.length);"
82 " for (var i = 0; i < slice.length; i++) {"
83 " byteNumbers[i] = slice.charCodeAt(i);"
84 " }"
85 " var byteArray = new Uint8Array(byteNumbers);"
86 " byteArrays.push(byteArray);"
87 " }"
88 " var blob = new Blob(byteArrays, {type: contentType});"
89 " return blob;"
90 "}"
91 " function createAndSendPostRequest() {"
92 " var req = new XMLHttpRequest();"
93 " req.open(\"POST\", \"%@\", false);"
94 " %@" //< This sets request headers.
95 " var blob = b64toBlob(atob(\"%@\"), \"%@\");" //< base64 string and
96 // content type
97 " req.send(blob);"
98 " if (req.status != 200) {"
99 " throw req.status;"
100 " }"
101 " return req.responseText;"
102 " }"
103 " "
104 " document.open();"
105 " document.write(createAndSendPostRequest());"
106 " document.close();"
107
108 "</script></html>";
109
59 // Utility functions for storing the source of NSErrors received by WKWebViews: 110 // Utility functions for storing the source of NSErrors received by WKWebViews:
60 // - Errors received by |-webView:didFailProvisionalNavigation:withError:| are 111 // - Errors received by |-webView:didFailProvisionalNavigation:withError:| are
61 // recorded using WKWebViewErrorSource::PROVISIONAL_LOAD. These should be 112 // recorded using WKWebViewErrorSource::PROVISIONAL_LOAD. These should be
62 // aborted. 113 // aborted.
63 // - Errors received by |-webView:didFailNavigation:withError:| are recorded 114 // - Errors received by |-webView:didFailNavigation:withError:| are recorded
64 // using WKWebViewsource::NAVIGATION. These errors should not be aborted, as 115 // using WKWebViewsource::NAVIGATION. These errors should not be aborted, as
65 // the WKWebView will automatically retry the load. 116 // the WKWebView will automatically retry the load.
66 NSString* const kWKWebViewErrorSourceKey = @"ErrorSource"; 117 NSString* const kWKWebViewErrorSourceKey = @"ErrorSource";
67 typedef enum { NONE = 0, PROVISIONAL_LOAD, NAVIGATION } WKWebViewErrorSource; 118 typedef enum { NONE = 0, PROVISIONAL_LOAD, NAVIGATION } WKWebViewErrorSource;
68 NSError* WKWebViewErrorWithSource(NSError* error, WKWebViewErrorSource source) { 119 NSError* WKWebViewErrorWithSource(NSError* error, WKWebViewErrorSource source) {
69 DCHECK(error); 120 DCHECK(error);
70 base::scoped_nsobject<NSMutableDictionary> userInfo( 121 base::scoped_nsobject<NSMutableDictionary> userInfo(
71 [error.userInfo mutableCopy]); 122 [error.userInfo mutableCopy]);
72 [userInfo setObject:@(source) forKey:kWKWebViewErrorSourceKey]; 123 [userInfo setObject:@(source) forKey:kWKWebViewErrorSourceKey];
73 return [NSError errorWithDomain:error.domain 124 return
74 code:error.code 125 [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 NIT: I understand that this was done by git cl for
stuartmorgan 2015/09/29 21:24:44 git cl format shouldn't have touched all these oth
stkhapugin 2015/09/30 15:05:14 Done.
stkhapugin 2015/09/30 15:05:14 Done. Thanks for explaining the reason, because I
75 userInfo:userInfo];
76 } 126 }
77 WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { 127 WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
78 DCHECK(error); 128 DCHECK(error);
79 return static_cast<WKWebViewErrorSource>( 129 return static_cast<WKWebViewErrorSource>(
80 [error.userInfo[kWKWebViewErrorSourceKey] integerValue]); 130 [error.userInfo[kWKWebViewErrorSourceKey] integerValue]);
81 } 131 }
82 132
83 } // namespace 133 } // namespace
84 134
85 @interface CRWWKWebViewWebController () <WKNavigationDelegate, 135 @interface CRWWKWebViewWebController ()<WKNavigationDelegate,
86 WKScriptMessageHandler, 136 WKScriptMessageHandler,
87 WKUIDelegate> { 137 WKUIDelegate> {
88 // The WKWebView managed by this instance. 138 // The WKWebView managed by this instance.
89 base::scoped_nsobject<WKWebView> _wkWebView; 139 base::scoped_nsobject<WKWebView> _wkWebView;
90 140
91 // The Watch Dog that detects and reports WKWebView crashes. 141 // The Watch Dog that detects and reports WKWebView crashes.
92 base::scoped_nsobject<CRWWKWebViewCrashDetector> _crashDetector; 142 base::scoped_nsobject<CRWWKWebViewCrashDetector> _crashDetector;
93 143
94 // The actual URL of the document object (i.e., the last committed URL). 144 // The actual URL of the document object (i.e., the last committed URL).
95 // TODO(stuartmorgan): Remove this in favor of just updating the session 145 // TODO(stuartmorgan): Remove this in favor of just updating the session
96 // controller and treating that as authoritative. For now, this allows sharing 146 // controller and treating that as authoritative. For now, this allows sharing
97 // the flow that's currently in the superclass. 147 // the flow that's currently in the superclass.
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 return web::WEB_VIEW_DOCUMENT_TYPE_HTML; 491 return web::WEB_VIEW_DOCUMENT_TYPE_HTML;
442 } 492 }
443 493
444 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; 494 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC;
445 } 495 }
446 496
447 - (void)loadRequest:(NSMutableURLRequest*)request { 497 - (void)loadRequest:(NSMutableURLRequest*)request {
448 [_wkWebView loadRequest:request]; 498 [_wkWebView loadRequest:request];
449 } 499 }
450 500
501 // Constructs an HTML page that executes the request through javascript and
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 NIT: s/javascript/JavaScript
stkhapugin 2015/09/30 15:05:14 Done.
502 // replaces document with the result.
503 - (NSString*)htmlForPOSTRequest:(NSURLRequest*)request {
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 Every method needs a predeclaration, and method co
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 s/htmlForPOSTRequest:/HTMLForPOSTRequest:
stkhapugin 2015/09/30 15:05:14 Done.
stkhapugin 2015/09/30 15:05:14 Done.
504 NSString* base64Data = [[request HTTPBody] base64EncodedStringWithOptions:0];
505 NSString* originURL = [[request URL] absoluteString];
506 NSString* contentType = nil;
507 NSMutableString* headerString = [[[NSMutableString alloc] init] autorelease];
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 [NSMutableString string]
stkhapugin 2015/09/30 15:05:13 Done.
508 for (NSString* headerField in [[request allHTTPHeaderFields] allKeys]) {
509 if ([headerField isEqualToString:@"Content-Type"]) {
510 contentType =
511 [[[request allHTTPHeaderFields][headerField] copy] autorelease];
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 Is it really necessary to copy this string?
stkhapugin 2015/09/30 15:05:14 Done.
512 }
513 [headerString appendFormat:@"req.setRequestHeader(\"%@\", \"%@\");",
bzanotti 2015/09/30 09:06:54 There might be some escaping required here.
stkhapugin 2015/09/30 15:05:14 Done.
514 headerField,
515 [request allHTTPHeaderFields][headerField]];
516 }
517
518 return [NSString stringWithFormat:kPostRequestTemplate, originURL,
bzanotti 2015/09/30 09:06:54 Same here for |originURL|, it might require some e
stkhapugin 2015/09/30 15:05:14 Done.
519 headerString, base64Data, contentType];
520 }
521
522 // Loads POST request with body in |_wkWebView| by constructing an HTML page
523 // that executes the request through javascript and replaces document with the
524 // result.
525 // Note that this approach includes multiple body encodings and decodings, plus
526 // the data is passed to |_wkWebView| on main thread, hence the performance is
527 // expected to be low.
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 How does it perform with huge images? :)
stkhapugin 2015/09/30 15:05:14 I tested with iPad Air 1 and a 3k*2k image, and it
Eugene But (OOO till 7-30) 2015/09/30 15:45:16 Thank you. Then I guess you can remove "hence the
Eugene But (OOO till 7-30) 2015/12/02 17:06:14 Please address this comment.
stkhapugin 2015/12/03 15:43:00 Done.
stkhapugin 2015/12/03 15:43:00 Done.
528 // This is necessary because WKWebView ignores POST request body.
529 // Workaround for https://bugs.webkit.org/show_bug.cgi?id=145410
530 - (void)loadPOSTRequestWithBody:(NSMutableURLRequest*)request {
531 NSString* htmlString = [self htmlForPOSTRequest:request];
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 NIT: s/htmlString/HTML acronyms should be all ca
stkhapugin 2015/09/30 15:05:14 Done.
532 [_wkWebView loadHTMLString:htmlString baseURL:request.URL];
533 }
534
451 - (void)loadWebHTMLString:(NSString*)html forURL:(const GURL&)URL { 535 - (void)loadWebHTMLString:(NSString*)html forURL:(const GURL&)URL {
452 [_wkWebView loadHTMLString:html baseURL:net::NSURLWithGURL(URL)]; 536 [_wkWebView loadHTMLString:html baseURL:net::NSURLWithGURL(URL)];
453 } 537 }
454 538
455 - (BOOL)scriptHasBeenInjectedForClass:(Class)jsInjectionManagerClass 539 - (BOOL)scriptHasBeenInjectedForClass:(Class)jsInjectionManagerClass
456 presenceBeacon:(NSString*)beacon { 540 presenceBeacon:(NSString*)beacon {
457 return [_injectedScriptManagers containsObject:jsInjectionManagerClass]; 541 return [_injectedScriptManagers containsObject:jsInjectionManagerClass];
458 } 542 }
459 543
460 - (void)injectScript:(NSString*)script forClass:(Class)JSInjectionManagerClass { 544 - (void)injectScript:(NSString*)script forClass:(Class)JSInjectionManagerClass {
461 // Skip evaluation if there's no content (e.g., if what's being injected is 545 // Skip evaluation if there's no content (e.g., if what's being injected is
462 // an umbrella manager). 546 // an umbrella manager).
463 if ([script length]) { 547 if ([script length]) {
464 [super injectScript:script forClass:JSInjectionManagerClass]; 548 [super injectScript:script forClass:JSInjectionManagerClass];
465 // Every injection except windowID requires windowID check. 549 // Every injection except windowID requires windowID check.
466 if (JSInjectionManagerClass != [CRWJSWindowIdManager class]) 550 if (JSInjectionManagerClass != [CRWJSWindowIdManager class])
467 script = [self scriptByAddingWindowIDCheckForScript:script]; 551 script = [self scriptByAddingWindowIDCheckForScript:script];
468 web::EvaluateJavaScript(_wkWebView, script, nil); 552 web::EvaluateJavaScript(_wkWebView, script, nil);
469 } 553 }
470 [_injectedScriptManagers addObject:JSInjectionManagerClass]; 554 [_injectedScriptManagers addObject:JSInjectionManagerClass];
471 } 555 }
472 556
473 - (void)willLoadCurrentURLInWebView { 557 - (void)willLoadCurrentURLInWebView {
474 // TODO(stuartmorgan): Get a WKWebView version of the request ID verification 558 // TODO(stuartmorgan): Get a WKWebView version of the request ID verification
475 // code working for debug builds. 559 // code working for debug builds.
476 } 560 }
477 561
478 - (void)loadRequestForCurrentNavigationItem { 562 - (void)loadRequestForCurrentNavigationItem {
479 DCHECK(self.webView && !self.nativeController); 563 DCHECK(self.webView && !self.nativeController);
564 DCHECK([self currentSessionEntry]);
565
566 web::WKBackForwardListItemHolder* holder =
567 [self currentBackForwardListItemHolder];
568 BOOL isFormResubmission =
569 (holder->navigation_type() == WKNavigationTypeFormResubmitted ||
570 holder->navigation_type() == WKNavigationTypeFormSubmitted);
571 web::NavigationItemImpl* currentItem =
572 [self currentSessionEntry].navigationItemImpl;
573 NSData* POSTData = currentItem->GetPostData();
574 NSMutableURLRequest* request = [self requestForCurrentNavigationItem];
480 575
481 ProceduralBlock defaultNavigationBlock = ^{ 576 ProceduralBlock defaultNavigationBlock = ^{
482 [self registerLoadRequest:[self currentNavigationURL] 577 [self registerLoadRequest:[self currentNavigationURL]
483 referrer:[self currentSessionEntryReferrer] 578 referrer:[self currentSessionEntryReferrer]
484 transition:[self currentTransition]]; 579 transition:[self currentTransition]];
485 [self loadRequest:[self requestForCurrentNavigationItem]]; 580 [self loadRequest:request];
486 }; 581 };
487 582
488 // If there is no corresponding WKBackForwardListItem, or the item is not in 583 // If the request has POST data and is not a form resubmission, configure and
489 // the current WKWebView's back-forward list, navigating using WKWebView API 584 // run the POST request.
490 // is not possible. In this case, fall back to the default navigation 585 ProceduralBlock POSTBlock = ^{
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 Is there a specific reason why you want to hold th
stkhapugin 2015/09/30 15:05:14 It's a question of style, really. Two blocks were
Eugene But (OOO till 7-30) 2015/09/30 15:45:16 Block creation has some overhead, so it's not only
Eugene But (OOO till 7-30) 2015/10/08 17:46:32 Please address this comment.
Eugene But (OOO till 7-30) 2015/12/02 17:06:14 Please address this comment.
stkhapugin 2015/12/03 15:43:00 Done.
stkhapugin 2015/12/03 15:43:00 Done.
stkhapugin 2015/12/03 15:43:00 Done.
491 // mechanism. 586 [request setHTTPMethod:@"POST"];
492 web::WKBackForwardListItemHolder* holder = 587 [request setHTTPBody:POSTData];
493 [self currentBackForwardListItemHolder]; 588 [request setAllHTTPHeaderFields:[self currentHTTPHeaders]];
494 if (!holder->back_forward_list_item() || 589 [self registerLoadRequest:[self currentNavigationURL]
495 ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { 590 referrer:[self currentSessionEntryReferrer]
496 defaultNavigationBlock(); 591 transition:[self currentTransition]];
497 return; 592 [self loadPOSTRequestWithBody:request];
498 } 593 };
499 594
500 ProceduralBlock webViewNavigationBlock = ^{ 595 ProceduralBlock webViewNavigationBlock = ^{
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 Please move this block closer to the place where i
stkhapugin 2015/09/30 15:05:13 Please see above.
Eugene But (OOO till 7-30) 2015/09/30 15:45:16 From C++ Style Guide: "Place a function's variable
Eugene But (OOO till 7-30) 2015/10/08 17:46:32 Please address this comment.
Eugene But (OOO till 7-30) 2015/12/02 17:06:14 Please address this comment.
stkhapugin 2015/12/03 15:43:00 Done.
stkhapugin 2015/12/03 15:43:00 Done.
stkhapugin 2015/12/03 15:43:00 Done.
501 // If the current navigation URL is the same as the URL of the visible 596 // If the current navigation URL is the same as the URL of the visible
502 // page, that means the user requested a reload. |goToBackForwardListItem| 597 // page, that means the user requested a reload. |goToBackForwardListItem|
503 // will be a no-op when it is passed the current back forward list item, 598 // will be a no-op when it is passed the current back forward list item,
504 // so |reload| must be explicitly called. 599 // so |reload| must be explicitly called.
505 [self registerLoadRequest:[self currentNavigationURL] 600 [self registerLoadRequest:[self currentNavigationURL]
506 referrer:[self currentSessionEntryReferrer] 601 referrer:[self currentSessionEntryReferrer]
507 transition:[self currentTransition]]; 602 transition:[self currentTransition]];
508 if ([self currentNavigationURL] == net::GURLWithNSURL([_wkWebView URL])) { 603 if ([self currentNavigationURL] == net::GURLWithNSURL([_wkWebView URL])) {
509 [_wkWebView reload]; 604 [_wkWebView reload];
510 } else { 605 } else {
511 [_wkWebView goToBackForwardListItem:holder->back_forward_list_item()]; 606 [_wkWebView goToBackForwardListItem:holder->back_forward_list_item()];
512 } 607 }
513 }; 608 };
514 609
610 // If there is no corresponding WKBackForwardListItem, or the item is not in
611 // the current WKWebView's back-forward list, or this is a POST request with
612 // data, navigating using WKWebView API is not possible. In this case, fall
613 // back to the default navigation mechanism.
614 if (!holder->back_forward_list_item() ||
615 ![self isBackForwardListItemValid:holder->back_forward_list_item()]) {
616 if (!POSTData.length) {
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 If POSTData exist, navigation is postResubmission
stkhapugin 2015/09/30 15:05:14 Done.
617 defaultNavigationBlock();
618 return;
619 }
620 }
621
622 if (POSTData.length && !isFormResubmission) {
Eugene But (OOO till 7-30) 2015/09/29 17:46:45 Should this "if" go before previous top level if (
stkhapugin 2015/09/30 15:05:14 Done.
623 POSTBlock();
624 return;
625 }
626
515 // If the request is not a form submission or resubmission, or the user 627 // If the request is not a form submission or resubmission, or the user
516 // doesn't need to confirm the load, then continue right away. 628 // doesn't need to confirm the load, then continue right away.
517 web::NavigationItemImpl* currentItem = 629 if (!isFormResubmission ||
518 [self currentSessionEntry].navigationItemImpl;
519 if ((holder->navigation_type() != WKNavigationTypeFormResubmitted &&
520 holder->navigation_type() != WKNavigationTypeFormSubmitted) ||
521 currentItem->ShouldSkipResubmitDataConfirmation()) { 630 currentItem->ShouldSkipResubmitDataConfirmation()) {
522 webViewNavigationBlock(); 631 webViewNavigationBlock();
523 return; 632 return;
524 } 633 }
525 634
526 // If the request is form submission or resubmission, then prompt the 635 // If the request is form submission or resubmission, then prompt the
527 // user before proceeding. 636 // user before proceeding.
637 DCHECK(isFormResubmission);
528 [self.delegate webController:self 638 [self.delegate webController:self
529 onFormResubmissionForRequest:nil 639 onFormResubmissionForRequest:nil
530 continueBlock:webViewNavigationBlock 640 continueBlock:webViewNavigationBlock
531 cancelBlock:defaultNavigationBlock]; 641 cancelBlock:defaultNavigationBlock];
532 } 642 }
533 643
534 // Overrides the hashchange workaround in the super class that manually 644 // Overrides the hashchange workaround in the super class that manually
535 // triggers Javascript hashchange events. If navigating with native API, 645 // triggers Javascript hashchange events. If navigating with native API,
536 // i.e. using a back forward list item, hashchange events will be triggered 646 // i.e. using a back forward list item, hashchange events will be triggered
537 // automatically, so no URL tampering is required. 647 // automatically, so no URL tampering is required.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 725
616 - (NSString*)requestGroupIDForUserAgent { 726 - (NSString*)requestGroupIDForUserAgent {
617 #if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 727 #if defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
618 return self.webStateImpl->GetRequestGroupID(); 728 return self.webStateImpl->GetRequestGroupID();
619 #else 729 #else
620 return nil; 730 return nil;
621 #endif 731 #endif
622 } 732 }
623 733
624 - (NSString*)activityIndicatorGroupID { 734 - (NSString*)activityIndicatorGroupID {
625 return [NSString stringWithFormat: 735 return [NSString
626 @"WKWebViewWebController.NetworkActivityIndicatorKey.%@", 736 stringWithFormat:@"WKWebViewWebController.NetworkActivityIndicatorKey.%@",
Eugene But (OOO till 7-30) 2015/09/29 17:46:46 Please revert this (and subsequent) changes to avo
stkhapugin 2015/09/30 15:05:14 Done.
627 self.webStateImpl->GetRequestGroupID()]; 737 self.webStateImpl->GetRequestGroupID()];
628 } 738 }
629 739
630 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 740 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
631 - (int)certGroupID { 741 - (int)certGroupID {
632 DCHECK(self.webStateImpl); 742 DCHECK(self.webStateImpl);
633 // Request tracker IDs are used as certificate groups. 743 // Request tracker IDs are used as certificate groups.
634 return self.webStateImpl->GetRequestTracker()->identifier(); 744 return self.webStateImpl->GetRequestTracker()->identifier();
635 } 745 }
636 #endif 746 #endif
637 747
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 883
774 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); 884 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self);
775 id crashHandler = ^{ 885 id crashHandler = ^{
776 [weakSelf webViewWebProcessDidCrash]; 886 [weakSelf webViewWebProcessDidCrash];
777 }; 887 };
778 return [[CRWWKWebViewCrashDetector alloc] initWithWebView:webView 888 return [[CRWWKWebViewCrashDetector alloc] initWithWebView:webView
779 crashHandler:crashHandler]; 889 crashHandler:crashHandler];
780 } 890 }
781 891
782 - (void)webViewWebProcessDidCrash { 892 - (void)webViewWebProcessDidCrash {
783 if ([self.delegate respondsToSelector: 893 if ([self.delegate
784 @selector(webControllerWebProcessDidCrash:)]) { 894 respondsToSelector:@selector(webControllerWebProcessDidCrash:)]) {
785 [self.delegate webControllerWebProcessDidCrash:self]; 895 [self.delegate webControllerWebProcessDidCrash:self];
786 } 896 }
787 } 897 }
788 898
789 - (void)queryPageReferrerPolicy:(void(^)(NSString*))responseHandler { 899 - (void)queryPageReferrerPolicy:(void(^)(NSString*))responseHandler {
790 DCHECK(responseHandler); 900 DCHECK(responseHandler);
791 [self evaluateJavaScript:@"__gCrWeb.getPageReferrerPolicy()" 901 [self evaluateJavaScript:@"__gCrWeb.getPageReferrerPolicy()"
792 stringResultHandler:^(NSString* referrer, NSError* error) { 902 stringResultHandler:^(NSString* referrer, NSError* error) {
793 DCHECK_NE(error.code, WKErrorJavaScriptExceptionOccurred); 903 DCHECK_NE(error.code, WKErrorJavaScriptExceptionOccurred);
794 responseHandler(!error ? referrer : nil); 904 responseHandler(!error ? referrer : nil);
795 }]; 905 }];
796 } 906 }
797 907
798 - (void)didBlockPopupWithURL:(GURL)popupURL 908 - (void)didBlockPopupWithURL:(GURL)popupURL
799 sourceURL:(GURL)sourceURL 909 sourceURL:(GURL)sourceURL
800 referrerPolicy:(const std::string&)referrerPolicyString { 910 referrerPolicy:(const std::string&)referrerPolicyString {
801 web::ReferrerPolicy referrerPolicy = 911 web::ReferrerPolicy referrerPolicy =
802 [self referrerPolicyFromString:referrerPolicyString]; 912 [self referrerPolicyFromString:referrerPolicyString];
803 web::Referrer referrer(sourceURL, referrerPolicy); 913 web::Referrer referrer(sourceURL, referrerPolicy);
804 NSString* const kWindowName = @""; // obsoleted 914 NSString* const kWindowName = @""; // obsoleted
805 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); 915 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self);
806 void(^showPopupHandler)() = ^{ 916 void (^showPopupHandler)() = ^{
807 // On Desktop cross-window comunication is not supported for unblocked 917 // On Desktop cross-window comunication is not supported for unblocked
808 // popups; so it's ok to create a new independent page. 918 // popups; so it's ok to create a new independent page.
809 CRWWebController* child = [[weakSelf delegate] 919 CRWWebController* child =
810 webPageOrderedOpen:popupURL 920 [[weakSelf delegate] webPageOrderedOpen:popupURL
811 referrer:referrer 921 referrer:referrer
812 windowName:kWindowName 922 windowName:kWindowName
813 inBackground:NO]; 923 inBackground:NO];
814 DCHECK(!child || child.sessionController.openedByDOM); 924 DCHECK(!child || child.sessionController.openedByDOM);
815 }; 925 };
816 926
817 web::BlockedPopupInfo info(popupURL, referrer, kWindowName, showPopupHandler); 927 web::BlockedPopupInfo info(popupURL, referrer, kWindowName, showPopupHandler);
818 [self.delegate webController:self didBlockPopup:info]; 928 [self.delegate webController:self didBlockPopup:info];
819 } 929 }
820 930
821 - (void)didBlockPopupWithURL:(GURL)popupURL sourceURL:(GURL)sourceURL { 931 - (void)didBlockPopupWithURL:(GURL)popupURL sourceURL:(GURL)sourceURL {
822 if (![self.delegate respondsToSelector: 932 if (![self.delegate
823 @selector(webController:didBlockPopup:)]) { 933 respondsToSelector:@selector(webController:didBlockPopup:)]) {
824 return; 934 return;
825 } 935 }
826 936
827 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); 937 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self);
828 dispatch_async(dispatch_get_main_queue(), ^{ 938 dispatch_async(dispatch_get_main_queue(), ^{
829 [self queryPageReferrerPolicy:^(NSString* policy) { 939 [self queryPageReferrerPolicy:^(NSString* policy) {
830 [weakSelf didBlockPopupWithURL:popupURL 940 [weakSelf didBlockPopupWithURL:popupURL
831 sourceURL:sourceURL 941 sourceURL:sourceURL
832 referrerPolicy:base::SysNSStringToUTF8(policy)]; 942 referrerPolicy:base::SysNSStringToUTF8(policy)];
833 }]; 943 }];
834 }); 944 });
835 } 945 }
836 946
837 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 947 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
838 - (void)handleSSLError:(NSError*)error { 948 - (void)handleSSLError:(NSError*)error {
839 DCHECK(web::IsWKWebViewSSLError(error)); 949 DCHECK(web::IsWKWebViewSSLError(error));
840 950
841 net::SSLInfo sslInfo; 951 net::SSLInfo sslInfo;
842 web::GetSSLInfoFromWKWebViewSSLError(error, &sslInfo); 952 web::GetSSLInfoFromWKWebViewSSLError(error, &sslInfo);
843 953
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 // TODO(jyquinn): Evaluate whether this is necessary for WKWebView. 1065 // TODO(jyquinn): Evaluate whether this is necessary for WKWebView.
956 if (![self respondToWKScriptMessage:message]) { 1066 if (![self respondToWKScriptMessage:message]) {
957 DLOG(WARNING) << "Message from JS not handled due to invalid format"; 1067 DLOG(WARNING) << "Message from JS not handled due to invalid format";
958 } 1068 }
959 } 1069 }
960 1070
961 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage { 1071 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage {
962 CHECK(scriptMessage.frameInfo.mainFrame); 1072 CHECK(scriptMessage.frameInfo.mainFrame);
963 int errorCode = 0; 1073 int errorCode = 0;
964 std::string errorMessage; 1074 std::string errorMessage;
965 scoped_ptr<base::Value> inputJSONData( 1075 scoped_ptr<base::Value> inputJSONData(base::JSONReader::ReadAndReturnError(
966 base::JSONReader::ReadAndReturnError( 1076 base::SysNSStringToUTF8(scriptMessage.body), false, &errorCode,
967 base::SysNSStringToUTF8(scriptMessage.body), 1077 &errorMessage));
968 false,
969 &errorCode,
970 &errorMessage));
971 if (errorCode) { 1078 if (errorCode) {
972 DLOG(WARNING) << "JSON parse error: %s" << errorMessage.c_str(); 1079 DLOG(WARNING) << "JSON parse error: %s" << errorMessage.c_str();
973 return NO; 1080 return NO;
974 } 1081 }
975 base::DictionaryValue* message = nullptr; 1082 base::DictionaryValue* message = nullptr;
976 if (!inputJSONData->GetAsDictionary(&message)) { 1083 if (!inputJSONData->GetAsDictionary(&message)) {
977 return NO; 1084 return NO;
978 } 1085 }
979 std::string windowID; 1086 std::string windowID;
980 message->GetString("crwWindowId", &windowID); 1087 message->GetString("crwWindowId", &windowID);
981 // Check for correct windowID 1088 // Check for correct windowID
982 if (![[self windowId] isEqualToString:base::SysUTF8ToNSString(windowID)]) { 1089 if (![[self windowId] isEqualToString:base::SysUTF8ToNSString(windowID)]) {
983 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " 1090 DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " <<
984 << [self windowId] << " != " 1091 [self windowId] << " != " << base::SysUTF8ToNSString(windowID);
985 << base::SysUTF8ToNSString(windowID);
986 return NO; 1092 return NO;
987 } 1093 }
988 base::DictionaryValue* command = nullptr; 1094 base::DictionaryValue* command = nullptr;
989 if (!message->GetDictionary("crwCommand", &command)) { 1095 if (!message->GetDictionary("crwCommand", &command)) {
990 return NO; 1096 return NO;
991 } 1097 }
992 if ([scriptMessage.name isEqualToString:kScriptImmediateName] || 1098 if ([scriptMessage.name isEqualToString:kScriptImmediateName] ||
993 [scriptMessage.name isEqualToString:kScriptMessageName]) { 1099 [scriptMessage.name isEqualToString:kScriptMessageName]) {
994 return [self respondToMessage:command 1100 return [self respondToMessage:command
995 userIsInteracting:[self userIsInteracting] 1101 userIsInteracting:[self userIsInteracting]
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 // Don't abort NSURLErrorCancelled errors originating from navigation 1136 // Don't abort NSURLErrorCancelled errors originating from navigation
1031 // as the WKWebView will automatically retry these loads. 1137 // as the WKWebView will automatically retry these loads.
1032 WKWebViewErrorSource source = WKWebViewErrorSourceFromError(error); 1138 WKWebViewErrorSource source = WKWebViewErrorSourceFromError(error);
1033 return source != NAVIGATION; 1139 return source != NAVIGATION;
1034 } 1140 }
1035 1141
1036 #pragma mark - 1142 #pragma mark -
1037 #pragma mark JavaScript message handlers 1143 #pragma mark JavaScript message handlers
1038 1144
1039 - (BOOL)handleWindowHistoryWillChangeStateMessage: 1145 - (BOOL)handleWindowHistoryWillChangeStateMessage:
1040 (base::DictionaryValue*)message 1146 (base::DictionaryValue*)message
1041 context:(NSDictionary*)context { 1147 context:(NSDictionary*)context {
1042 _changingHistoryState = YES; 1148 _changingHistoryState = YES;
1043 return 1149 return
1044 [super handleWindowHistoryWillChangeStateMessage:message context:context]; 1150 [super handleWindowHistoryWillChangeStateMessage:message context:context];
1045 } 1151 }
1046 1152
1047 - (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message 1153 - (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message
1048 context:(NSDictionary*)context { 1154 context:(NSDictionary*)context {
1049 DCHECK(_changingHistoryState); 1155 DCHECK(_changingHistoryState);
1050 _changingHistoryState = NO; 1156 _changingHistoryState = NO;
1051 return [super handleWindowHistoryDidPushStateMessage:message context:context]; 1157 return [super handleWindowHistoryDidPushStateMessage:message context:context];
1052 } 1158 }
1053 1159
1054 - (BOOL)handleWindowHistoryDidReplaceStateMessage: 1160 - (BOOL)handleWindowHistoryDidReplaceStateMessage:
1055 (base::DictionaryValue*)message 1161 (base::DictionaryValue*)message
1056 context:(NSDictionary*)context { 1162 context:(NSDictionary*)context {
1057 DCHECK(_changingHistoryState); 1163 DCHECK(_changingHistoryState);
1058 _changingHistoryState = NO; 1164 _changingHistoryState = NO;
1059 return [super handleWindowHistoryDidReplaceStateMessage:message 1165 return [super handleWindowHistoryDidReplaceStateMessage:message
1060 context:context]; 1166 context:context];
1061 } 1167 }
1062 1168
1063 #pragma mark - 1169 #pragma mark -
1064 #pragma mark WebUI 1170 #pragma mark WebUI
1065 1171
1066 - (void)createWebUIForURL:(const GURL&)URL { 1172 - (void)createWebUIForURL:(const GURL&)URL {
(...skipping 16 matching lines...) Expand all
1083 context:(void*)context { 1189 context:(void*)context {
1084 NSString* dispatcherSelectorName = self.wkWebViewObservers[keyPath]; 1190 NSString* dispatcherSelectorName = self.wkWebViewObservers[keyPath];
1085 DCHECK(dispatcherSelectorName); 1191 DCHECK(dispatcherSelectorName);
1086 if (dispatcherSelectorName) 1192 if (dispatcherSelectorName)
1087 [self performSelector:NSSelectorFromString(dispatcherSelectorName)]; 1193 [self performSelector:NSSelectorFromString(dispatcherSelectorName)];
1088 } 1194 }
1089 1195
1090 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 1196 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
1091 // TODO(eugenebut): use WKWebView progress even if Chrome net stack is enabled. 1197 // TODO(eugenebut): use WKWebView progress even if Chrome net stack is enabled.
1092 - (void)webViewEstimatedProgressDidChange { 1198 - (void)webViewEstimatedProgressDidChange {
1093 if ([self.delegate respondsToSelector: 1199 if ([self.delegate
1094 @selector(webController:didUpdateProgress:)]) { 1200 respondsToSelector:@selector(webController:didUpdateProgress:)]) {
1095 [self.delegate webController:self 1201 [self.delegate webController:self
1096 didUpdateProgress:[_wkWebView estimatedProgress]]; 1202 didUpdateProgress:[_wkWebView estimatedProgress]];
1097 } 1203 }
1098 } 1204 }
1099 1205
1100 - (void)webViewSecurityFeaturesDidChange { 1206 - (void)webViewSecurityFeaturesDidChange {
1101 if (self.loadPhase == web::LOAD_REQUESTED) { 1207 if (self.loadPhase == web::LOAD_REQUESTED) {
1102 // Do not update SSL Status for pending load. It will be updated in 1208 // Do not update SSL Status for pending load. It will be updated in
1103 // |webView:didCommitNavigation:| callback. 1209 // |webView:didCommitNavigation:| callback.
1104 return; 1210 return;
1105 } 1211 }
1106 [self updateSSLStatusForCurrentNavigationItem]; 1212 [self updateSSLStatusForCurrentNavigationItem];
1107 } 1213 }
1108 1214
1109 #endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 1215 #endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
1110 1216
1111 - (void)webViewLoadingStateDidChange { 1217 - (void)webViewLoadingStateDidChange {
1112 if ([_wkWebView isLoading]) { 1218 if ([_wkWebView isLoading]) {
1113 [self addActivityIndicatorTask]; 1219 [self addActivityIndicatorTask];
1114 } else { 1220 } else {
1115 [self clearActivityIndicatorTasks]; 1221 [self clearActivityIndicatorTasks];
1116 } 1222 }
1117 } 1223 }
1118 1224
1119 - (void)webViewTitleDidChange { 1225 - (void)webViewTitleDidChange {
1120 if ([self.delegate respondsToSelector: 1226 if ([self.delegate
1121 @selector(webController:titleDidChange:)]) { 1227 respondsToSelector:@selector(webController:titleDidChange:)]) {
1122 DCHECK(self.title); 1228 DCHECK(self.title);
1123 [self.delegate webController:self titleDidChange:self.title]; 1229 [self.delegate webController:self titleDidChange:self.title];
1124 } 1230 }
1125 } 1231 }
1126 1232
1127 - (void)webViewURLDidChange { 1233 - (void)webViewURLDidChange {
1128 // TODO(stuartmorgan): Determine if there are any cases where this still 1234 // TODO(stuartmorgan): Determine if there are any cases where this still
1129 // happens, and if so whether anything should be done when it does. 1235 // happens, and if so whether anything should be done when it does.
1130 if (![_wkWebView URL]) { 1236 if (![_wkWebView URL]) {
1131 DVLOG(1) << "Received nil URL callback"; 1237 DVLOG(1) << "Received nil URL callback";
(...skipping 22 matching lines...) Expand all
1154 // somehow corrupts window.location.href it can't do a redirect to a 1260 // somehow corrupts window.location.href it can't do a redirect to a
1155 // slow-loading target page while it is still loading to spoof the domain. 1261 // slow-loading target page while it is still loading to spoof the domain.
1156 // On a document-changing URL change, the window.location.href will match the 1262 // On a document-changing URL change, the window.location.href will match the
1157 // previous URL at this stage, not the web view's current URL. 1263 // previous URL at this stage, not the web view's current URL.
1158 if (![_wkWebView isLoading]) { 1264 if (![_wkWebView isLoading]) {
1159 if (_documentURL == url) 1265 if (_documentURL == url)
1160 return; 1266 return;
1161 [self URLDidChangeWithoutDocumentChange:url]; 1267 [self URLDidChangeWithoutDocumentChange:url];
1162 } else if (!_documentURL.host().empty() && 1268 } else if (!_documentURL.host().empty() &&
1163 _documentURL.host() == url.host()) { 1269 _documentURL.host() == url.host()) {
1164 [_wkWebView evaluateJavaScript:@"window.location.href" 1270 [_wkWebView
1165 completionHandler:^(id result, NSError* error) { 1271 evaluateJavaScript:@"window.location.href"
1166 // If the web view has gone away, or the location 1272 completionHandler:^(id result, NSError* error) {
1167 // couldn't be retrieved, abort. 1273 // If the web view has gone away, or the location
1168 if (!_wkWebView || 1274 // couldn't be retrieved, abort.
1169 ![result isKindOfClass:[NSString class]]) { 1275 if (!_wkWebView || ![result isKindOfClass:[NSString class]]) {
1170 return; 1276 return;
1171 } 1277 }
1172 GURL jsURL([result UTF8String]); 1278 GURL jsURL([result UTF8String]);
1173 // Make sure that the URL is as expected, and re-check 1279 // Make sure that the URL is as expected, and re-check
1174 // the host to prevent race conditions. 1280 // the host to prevent race conditions.
1175 if (jsURL == url && _documentURL.host() == url.host()) { 1281 if (jsURL == url && _documentURL.host() == url.host()) {
1176 [self URLDidChangeWithoutDocumentChange:url]; 1282 [self URLDidChangeWithoutDocumentChange:url];
1177 } 1283 }
1178 }]; 1284 }];
1179 } 1285 }
1180 } 1286 }
1181 1287
1182 #pragma mark - 1288 #pragma mark -
1183 #pragma mark WKNavigationDelegate Methods 1289 #pragma mark WKNavigationDelegate Methods
1184 1290
1185 - (void)webView:(WKWebView *)webView 1291 - (void)webView:(WKWebView*)webView
1186 decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction 1292 decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction
1187 decisionHandler: 1293 decisionHandler:
1188 (void (^)(WKNavigationActionPolicy))decisionHandler { 1294 (void (^)(WKNavigationActionPolicy))decisionHandler {
1189 if (self.isBeingDestroyed) { 1295 if (self.isBeingDestroyed) {
1190 decisionHandler(WKNavigationActionPolicyCancel); 1296 decisionHandler(WKNavigationActionPolicyCancel);
1191 return; 1297 return;
1192 } 1298 }
1193 1299
1194 NSURLRequest* request = navigationAction.request; 1300 NSURLRequest* request = navigationAction.request;
1195 GURL url = net::GURLWithNSURL(request.URL); 1301 GURL url = net::GURLWithNSURL(request.URL);
1196 1302
1197 // The page will not be changed until this navigation is commited, so the 1303 // The page will not be changed until this navigation is commited, so the
1198 // retrieved referrer will be pending until |didCommitNavigation| callback. 1304 // retrieved referrer will be pending until |didCommitNavigation| callback.
(...skipping 13 matching lines...) Expand all
1212 1318
1213 if (allowLoad) { 1319 if (allowLoad) {
1214 allowLoad = self.webStateImpl->ShouldAllowRequest(request); 1320 allowLoad = self.webStateImpl->ShouldAllowRequest(request);
1215 _pendingNavigationCancelled = !allowLoad; 1321 _pendingNavigationCancelled = !allowLoad;
1216 } 1322 }
1217 1323
1218 decisionHandler(allowLoad ? WKNavigationActionPolicyAllow 1324 decisionHandler(allowLoad ? WKNavigationActionPolicyAllow
1219 : WKNavigationActionPolicyCancel); 1325 : WKNavigationActionPolicyCancel);
1220 } 1326 }
1221 1327
1222 - (void)webView:(WKWebView *)webView 1328 - (void)webView:(WKWebView*)webView
1223 decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse 1329 decidePolicyForNavigationResponse:(WKNavigationResponse*)navigationResponse
1224 decisionHandler: 1330 decisionHandler:
1225 (void (^)(WKNavigationResponsePolicy))handler { 1331 (void (^)(WKNavigationResponsePolicy))handler {
1226 if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { 1332 if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) {
1227 // Create HTTP headers from the response. 1333 // Create HTTP headers from the response.
1228 // TODO(kkhorimoto): Due to the limited interface of NSHTTPURLResponse, some 1334 // TODO(kkhorimoto): Due to the limited interface of NSHTTPURLResponse, some
1229 // data in the HttpResponseHeaders generated here is inexact. Once 1335 // data in the HttpResponseHeaders generated here is inexact. Once
1230 // UIWebView is no longer supported, update WebState's implementation so 1336 // UIWebView is no longer supported, update WebState's implementation so
1231 // that the Content-Language and the MIME type can be set without using this 1337 // that the Content-Language and the MIME type can be set without using this
1232 // imperfect conversion. 1338 // imperfect conversion.
1233 scoped_refptr<net::HttpResponseHeaders> HTTPHeaders = 1339 scoped_refptr<net::HttpResponseHeaders> HTTPHeaders =
(...skipping 11 matching lines...) Expand all
1245 self.webStateImpl->ShouldAllowResponse(navigationResponse.response); 1351 self.webStateImpl->ShouldAllowResponse(navigationResponse.response);
1246 _pendingNavigationCancelled = !allowNavigation; 1352 _pendingNavigationCancelled = !allowNavigation;
1247 } 1353 }
1248 1354
1249 handler(allowNavigation ? WKNavigationResponsePolicyAllow 1355 handler(allowNavigation ? WKNavigationResponsePolicyAllow
1250 : WKNavigationResponsePolicyCancel); 1356 : WKNavigationResponsePolicyCancel);
1251 } 1357 }
1252 1358
1253 // TODO(stuartmorgan): Move all the guesswork around these states out of the 1359 // TODO(stuartmorgan): Move all the guesswork around these states out of the
1254 // superclass, and wire these up to the remaining methods. 1360 // superclass, and wire these up to the remaining methods.
1255 - (void)webView:(WKWebView *)webView 1361 - (void)webView:(WKWebView*)webView
1256 didStartProvisionalNavigation:(WKNavigation *)navigation { 1362 didStartProvisionalNavigation:(WKNavigation*)navigation {
1257 GURL webViewURL = net::GURLWithNSURL(webView.URL); 1363 GURL webViewURL = net::GURLWithNSURL(webView.URL);
1258 if (webViewURL.is_empty() && base::ios::IsRunningOnIOS9OrLater()) { 1364 if (webViewURL.is_empty() && base::ios::IsRunningOnIOS9OrLater()) {
1259 // May happen on iOS9, however in didCommitNavigation: callback the URL 1365 // May happen on iOS9, however in didCommitNavigation: callback the URL
1260 // will be "about:blank". TODO(eugenebut): File radar for this issue 1366 // will be "about:blank". TODO(eugenebut): File radar for this issue
1261 // (crbug.com/523549). 1367 // (crbug.com/523549).
1262 webViewURL = GURL(url::kAboutBlankURL); 1368 webViewURL = GURL(url::kAboutBlankURL);
1263 } 1369 }
1264 1370
1265 // Intercept renderer-initiated navigations. If this navigation has not yet 1371 // Intercept renderer-initiated navigations. If this navigation has not yet
1266 // been registered, do so. loadPhase check is necessary because 1372 // been registered, do so. loadPhase check is necessary because
(...skipping 15 matching lines...) Expand all
1282 return; 1388 return;
1283 } else { 1389 } else {
1284 [self registerLoadRequest:webViewURL]; 1390 [self registerLoadRequest:webViewURL];
1285 } 1391 }
1286 } 1392 }
1287 // Ensure the URL is registered and loadPhase is as expected. 1393 // Ensure the URL is registered and loadPhase is as expected.
1288 DCHECK(self.lastRegisteredRequestURL == webViewURL); 1394 DCHECK(self.lastRegisteredRequestURL == webViewURL);
1289 DCHECK(self.loadPhase == web::LOAD_REQUESTED); 1395 DCHECK(self.loadPhase == web::LOAD_REQUESTED);
1290 } 1396 }
1291 1397
1292 - (void)webView:(WKWebView *)webView 1398 - (void)webView:(WKWebView*)webView
1293 didReceiveServerRedirectForProvisionalNavigation: 1399 didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation {
1294 (WKNavigation *)navigation {
1295 [self registerLoadRequest:net::GURLWithNSURL(webView.URL) 1400 [self registerLoadRequest:net::GURLWithNSURL(webView.URL)
1296 referrer:[self currentReferrer] 1401 referrer:[self currentReferrer]
1297 transition:ui::PAGE_TRANSITION_SERVER_REDIRECT]; 1402 transition:ui::PAGE_TRANSITION_SERVER_REDIRECT];
1298 } 1403 }
1299 1404
1300 - (void)webView:(WKWebView *)webView 1405 - (void)webView:(WKWebView*)webView
1301 didFailProvisionalNavigation:(WKNavigation *)navigation 1406 didFailProvisionalNavigation:(WKNavigation*)navigation
1302 withError:(NSError *)error { 1407 withError:(NSError*)error {
1303 [self discardPendingReferrerString]; 1408 [self discardPendingReferrerString];
1304 1409
1305 if (_pendingNavigationCancelled) { 1410 if (_pendingNavigationCancelled) {
1306 // Directly cancelled navigations are simply discarded without handling 1411 // Directly cancelled navigations are simply discarded without handling
1307 // their potential errors. 1412 // their potential errors.
1308 _pendingNavigationCancelled = NO; 1413 _pendingNavigationCancelled = NO;
1309 return; 1414 return;
1310 } 1415 }
1311 1416
1312 error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD); 1417 error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD);
(...skipping 13 matching lines...) Expand all
1326 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 1431 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
1327 if (web::IsWKWebViewSSLError(error)) 1432 if (web::IsWKWebViewSSLError(error))
1328 [self handleSSLError:error]; 1433 [self handleSSLError:error];
1329 else 1434 else
1330 #endif 1435 #endif
1331 [self handleLoadError:error inMainFrame:YES]; 1436 [self handleLoadError:error inMainFrame:YES];
1332 1437
1333 [self discardPendingNavigationTypeForMainFrame]; 1438 [self discardPendingNavigationTypeForMainFrame];
1334 } 1439 }
1335 1440
1336 - (void)webView:(WKWebView *)webView 1441 - (void)webView:(WKWebView*)webView
1337 didCommitNavigation:(WKNavigation *)navigation { 1442 didCommitNavigation:(WKNavigation*)navigation {
1338 DCHECK_EQ(_wkWebView, webView); 1443 DCHECK_EQ(_wkWebView, webView);
1339 // This point should closely approximate the document object change, so reset 1444 // This point should closely approximate the document object change, so reset
1340 // the list of injected scripts to those that are automatically injected. 1445 // the list of injected scripts to those that are automatically injected.
1341 _injectedScriptManagers.reset([[NSMutableSet alloc] init]); 1446 _injectedScriptManagers.reset([[NSMutableSet alloc] init]);
1342 [self injectWindowID]; 1447 [self injectWindowID];
1343 1448
1344 // The page has changed; commit the pending referrer. 1449 // The page has changed; commit the pending referrer.
1345 [self commitPendingReferrerString]; 1450 [self commitPendingReferrerString];
1346 1451
1347 // This is the point where the document's URL has actually changed. 1452 // This is the point where the document's URL has actually changed.
1348 _documentURL = net::GURLWithNSURL([_wkWebView URL]); 1453 _documentURL = net::GURLWithNSURL([_wkWebView URL]);
1349 DCHECK(_documentURL == self.lastRegisteredRequestURL); 1454 DCHECK(_documentURL == self.lastRegisteredRequestURL);
1350 [self webPageChanged]; 1455 [self webPageChanged];
1351 1456
1352 [self updateCurrentBackForwardListItemHolder]; 1457 [self updateCurrentBackForwardListItemHolder];
1353 1458
1354 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) 1459 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW)
1355 [self updateSSLStatusForCurrentNavigationItem]; 1460 [self updateSSLStatusForCurrentNavigationItem];
1356 #endif 1461 #endif
1357 } 1462 }
1358 1463
1359 - (void)webView:(WKWebView *)webView 1464 - (void)webView:(WKWebView*)webView
1360 didFinishNavigation:(WKNavigation *)navigation { 1465 didFinishNavigation:(WKNavigation*)navigation {
1361 DCHECK(!self.isHalted); 1466 DCHECK(!self.isHalted);
1362 // Trigger JavaScript driven post-document-load-completion tasks. 1467 // Trigger JavaScript driven post-document-load-completion tasks.
1363 // TODO(jyquinn): Investigate using WKUserScriptInjectionTimeAtDocumentEnd to 1468 // TODO(jyquinn): Investigate using WKUserScriptInjectionTimeAtDocumentEnd to
1364 // inject this material at the appropriate time rather than invoking here. 1469 // inject this material at the appropriate time rather than invoking here.
1365 web::EvaluateJavaScript(webView, 1470 web::EvaluateJavaScript(webView,
1366 @"__gCrWeb.didFinishNavigation()", nil); 1471 @"__gCrWeb.didFinishNavigation()", nil);
1367 [self didFinishNavigation]; 1472 [self didFinishNavigation];
1368 } 1473 }
1369 1474
1370 - (void)webView:(WKWebView *)webView 1475 - (void)webView:(WKWebView*)webView
1371 didFailNavigation:(WKNavigation *)navigation 1476 didFailNavigation:(WKNavigation*)navigation
1372 withError:(NSError *)error { 1477 withError:(NSError*)error {
1373 [self handleLoadError:WKWebViewErrorWithSource(error, NAVIGATION) 1478 [self handleLoadError:WKWebViewErrorWithSource(error, NAVIGATION)
1374 inMainFrame:YES]; 1479 inMainFrame:YES];
1375 } 1480 }
1376 1481
1377 - (void)webView:(WKWebView *)webView 1482 - (void)
1378 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 1483 webView:(WKWebView*)webView
1379 completionHandler: 1484 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
1380 (void (^)(NSURLSessionAuthChallengeDisposition disposition, 1485 completionHandler:
1381 NSURLCredential *credential))completionHandler { 1486 (void (^)(NSURLSessionAuthChallengeDisposition disposition,
1487 NSURLCredential* credential))completionHandler {
1382 if (![challenge.protectionSpace.authenticationMethod 1488 if (![challenge.protectionSpace.authenticationMethod
1383 isEqual:NSURLAuthenticationMethodServerTrust]) { 1489 isEqual:NSURLAuthenticationMethodServerTrust]) {
1384 completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); 1490 completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
1385 return; 1491 return;
1386 } 1492 }
1387 1493
1388 SecTrustRef trust = challenge.protectionSpace.serverTrust; 1494 SecTrustRef trust = challenge.protectionSpace.serverTrust;
1389 scoped_refptr<net::X509Certificate> cert = web::CreateCertFromTrust(trust); 1495 scoped_refptr<net::X509Certificate> cert = web::CreateCertFromTrust(trust);
1390 [_certVerificationController 1496 [_certVerificationController
1391 decidePolicyForCert:cert 1497 decidePolicyForCert:cert
(...skipping 10 matching lines...) Expand all
1402 } 1508 }
1403 1509
1404 #pragma mark WKUIDelegate Methods 1510 #pragma mark WKUIDelegate Methods
1405 1511
1406 - (WKWebView*)webView:(WKWebView*)webView 1512 - (WKWebView*)webView:(WKWebView*)webView
1407 createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration 1513 createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration
1408 forNavigationAction:(WKNavigationAction*)navigationAction 1514 forNavigationAction:(WKNavigationAction*)navigationAction
1409 windowFeatures:(WKWindowFeatures*)windowFeatures { 1515 windowFeatures:(WKWindowFeatures*)windowFeatures {
1410 GURL requestURL = net::GURLWithNSURL(navigationAction.request.URL); 1516 GURL requestURL = net::GURLWithNSURL(navigationAction.request.URL);
1411 NSString* referer = GetRefererFromNavigationAction(navigationAction); 1517 NSString* referer = GetRefererFromNavigationAction(navigationAction);
1412 GURL referrerURL = referer ? GURL(base::SysNSStringToUTF8(referer)) : 1518 GURL referrerURL =
1413 [self currentURL]; 1519 referer ? GURL(base::SysNSStringToUTF8(referer)) : [self currentURL];
1414 1520
1415 if (![self userIsInteracting] && 1521 if (![self userIsInteracting] &&
1416 [self shouldBlockPopupWithURL:requestURL sourceURL:referrerURL]) { 1522 [self shouldBlockPopupWithURL:requestURL sourceURL:referrerURL]) {
1417 [self didBlockPopupWithURL:requestURL sourceURL:referrerURL]; 1523 [self didBlockPopupWithURL:requestURL sourceURL:referrerURL];
1418 // Desktop Chrome does not return a window for the blocked popups; 1524 // Desktop Chrome does not return a window for the blocked popups;
1419 // follow the same approach by returning nil; 1525 // follow the same approach by returning nil;
1420 return nil; 1526 return nil;
1421 } 1527 }
1422 1528
1423 id child = [self createChildWebControllerWithReferrerURL:referrerURL]; 1529 id child = [self createChildWebControllerWithReferrerURL:referrerURL];
1424 // WKWebView requires WKUIDelegate to return a child view created with 1530 // WKWebView requires WKUIDelegate to return a child view created with
1425 // exactly the same |configuration| object (exception is raised if config is 1531 // exactly the same |configuration| object (exception is raised if config is
1426 // different). |configuration| param and config returned by 1532 // different). |configuration| param and config returned by
1427 // WKWebViewConfigurationProvider are different objects because WKWebView 1533 // WKWebViewConfigurationProvider are different objects because WKWebView
1428 // makes a shallow copy of the config inside init, so every WKWebView 1534 // makes a shallow copy of the config inside init, so every WKWebView
1429 // owns a separate shallow copy of WKWebViewConfiguration. 1535 // owns a separate shallow copy of WKWebViewConfiguration.
1430 [child ensureWebViewCreatedWithConfiguration:configuration]; 1536 [child ensureWebViewCreatedWithConfiguration:configuration];
1431 return [child webView]; 1537 return [child webView];
1432 } 1538 }
1433 1539
1434 - (void)webView:(WKWebView*)webView 1540 - (void)webView:(WKWebView*)webView
1435 runJavaScriptAlertPanelWithMessage:(NSString*)message 1541 runJavaScriptAlertPanelWithMessage:(NSString*)message
1436 initiatedByFrame:(WKFrameInfo*)frame 1542 initiatedByFrame:(WKFrameInfo*)frame
1437 completionHandler:(void(^)())completionHandler { 1543 completionHandler:(void (^)())completionHandler {
1438 SEL alertSelector = @selector(webController: 1544 SEL alertSelector = @selector(webController:
1439 runJavaScriptAlertPanelWithMessage: 1545 runJavaScriptAlertPanelWithMessage:
1440 requestURL: 1546 requestURL:
1441 completionHandler:); 1547 completionHandler:);
1442 if ([self.UIDelegate respondsToSelector:alertSelector]) { 1548 if ([self.UIDelegate respondsToSelector:alertSelector]) {
1443 [self.UIDelegate webController:self 1549 [self.UIDelegate webController:self
1444 runJavaScriptAlertPanelWithMessage:message 1550 runJavaScriptAlertPanelWithMessage:message
1445 requestURL:net::GURLWithNSURL(frame.request.URL) 1551 requestURL:net::GURLWithNSURL(frame.request.URL)
1446 completionHandler:completionHandler]; 1552 completionHandler:completionHandler];
1447 } else if (completionHandler) { 1553 } else if (completionHandler) {
1448 completionHandler(); 1554 completionHandler();
1449 } 1555 }
1450 } 1556 }
1451 1557
1452 - (void)webView:(WKWebView*)webView 1558 - (void)webView:(WKWebView*)webView
1453 runJavaScriptConfirmPanelWithMessage:(NSString*)message 1559 runJavaScriptConfirmPanelWithMessage:(NSString*)message
1454 initiatedByFrame:(WKFrameInfo*)frame 1560 initiatedByFrame:(WKFrameInfo*)frame
1455 completionHandler: 1561 completionHandler:
1456 (void (^)(BOOL result))completionHandler { 1562 (void (^)(BOOL result))completionHandler {
1457 SEL confirmationSelector = @selector(webController: 1563 SEL confirmationSelector = @selector(webController:
1458 runJavaScriptConfirmPanelWithMessage: 1564 runJavaScriptConfirmPanelWithMessage:
1459 requestURL: 1565 requestURL:
1460 completionHandler:); 1566 completionHandler:);
1461 if ([self.UIDelegate respondsToSelector:confirmationSelector]) { 1567 if ([self.UIDelegate respondsToSelector:confirmationSelector]) {
1462 [self.UIDelegate webController:self 1568 [self.UIDelegate webController:self
1463 runJavaScriptConfirmPanelWithMessage:message 1569 runJavaScriptConfirmPanelWithMessage:message
1464 requestURL: 1570 requestURL:net::GURLWithNSURL(
1465 net::GURLWithNSURL(frame.request.URL) 1571 frame.request.URL)
1466 completionHandler:completionHandler]; 1572 completionHandler:completionHandler];
1467 } else if (completionHandler) { 1573 } else if (completionHandler) {
1468 completionHandler(NO); 1574 completionHandler(NO);
1469 } 1575 }
1470 } 1576 }
1471 1577
1472 - (void)webView:(WKWebView*)webView 1578 - (void)webView:(WKWebView*)webView
1473 runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt 1579 runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
1474 defaultText:(NSString*)defaultText 1580 defaultText:(NSString*)defaultText
1475 initiatedByFrame:(WKFrameInfo*)frame 1581 initiatedByFrame:(WKFrameInfo*)frame
1476 completionHandler: 1582 completionHandler:
1477 (void (^)(NSString *result))completionHandler { 1583 (void (^)(NSString* result))completionHandler {
1478 SEL textInputSelector = @selector(webController: 1584 SEL textInputSelector = @selector(webController:
1479 runJavaScriptTextInputPanelWithPrompt: 1585 runJavaScriptTextInputPanelWithPrompt:
1480 placeholderText: 1586 placeholderText:
1481 requestURL: 1587 requestURL:
1482 completionHandler:); 1588 completionHandler:);
1483 if ([self.UIDelegate respondsToSelector:textInputSelector]) { 1589 if ([self.UIDelegate respondsToSelector:textInputSelector]) {
1484 [self.UIDelegate webController:self 1590 [self.UIDelegate webController:self
1485 runJavaScriptTextInputPanelWithPrompt:prompt 1591 runJavaScriptTextInputPanelWithPrompt:prompt
1486 placeholderText:defaultText 1592 placeholderText:defaultText
1487 requestURL: 1593 requestURL:net::GURLWithNSURL(
1488 net::GURLWithNSURL(frame.request.URL) 1594 frame.request.URL)
1489 completionHandler:completionHandler]; 1595 completionHandler:completionHandler];
1490 } else if (completionHandler) { 1596 } else if (completionHandler) {
1491 completionHandler(nil); 1597 completionHandler(nil);
1492 } 1598 }
1493 } 1599 }
1494 1600
1495 @end 1601 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698