Chromium Code Reviews| Index: ios/web/web_state/ui/crw_wk_web_view_web_controller.mm |
| diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm |
| index 368587eab562249bab292466ff34a608391942d3..d6504fd18e7bdc656b695e70b56f408b7d71f026 100644 |
| --- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm |
| +++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm |
| @@ -56,6 +56,57 @@ NSString* GetRefererFromNavigationAction(WKNavigationAction* action) { |
| NSString* const kScriptMessageName = @"crwebinvoke"; |
| NSString* const kScriptImmediateName = @"crwebinvokeimmediate"; |
| +// JavaScript template to do a POST request using an XMLHttpRequest. |
| +// The request is retried once on failure, as it can be marked as failing to |
| +// 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.
|
| +// response are correctly set). |
| +// |
| +// The template takes three arguments (in order): |
| +// * The quoted and escaped URL to send a POST request to. |
| +// * The HTTP headers of the request. They should be written as valid JavaScript |
| +// statements, adding headers to the XMLHttpRequest variable named 'req' |
| +// (e.g. 'req.setRequestHeader("Foo", "Bar");'). |
| +// * The base64 string of POST request body. |
| +// * Content-Type string |
| +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.
|
| + @"<html><script>" |
| + "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.
|
| + " contentType = contentType || '';" |
| + " 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.
|
| + " var byteCharacters = b64Data;" |
| + " var byteArrays = [];" |
| + " for (var offset = 0; offset < byteCharacters.length; offset += " |
| + "sliceSize) {" |
| + " var slice = byteCharacters.slice(offset, offset + sliceSize);" |
| + " var byteNumbers = new Array(slice.length);" |
| + " for (var i = 0; i < slice.length; i++) {" |
| + " byteNumbers[i] = slice.charCodeAt(i);" |
| + " }" |
| + " var byteArray = new Uint8Array(byteNumbers);" |
| + " byteArrays.push(byteArray);" |
| + " }" |
| + " var blob = new Blob(byteArrays, {type: contentType});" |
| + " return blob;" |
| + "}" |
| + " function createAndSendPostRequest() {" |
| + " var req = new XMLHttpRequest();" |
| + " req.open(\"POST\", \"%@\", false);" |
| + " %@" //< This sets request headers. |
| + " var blob = b64toBlob(atob(\"%@\"), \"%@\");" //< base64 string and |
| + // content type |
| + " req.send(blob);" |
| + " if (req.status != 200) {" |
| + " throw req.status;" |
| + " }" |
| + " return req.responseText;" |
| + " }" |
| + " " |
| + " document.open();" |
| + " document.write(createAndSendPostRequest());" |
| + " document.close();" |
| + |
| + "</script></html>"; |
| + |
| // Utility functions for storing the source of NSErrors received by WKWebViews: |
| // - Errors received by |-webView:didFailProvisionalNavigation:withError:| are |
| // recorded using WKWebViewErrorSource::PROVISIONAL_LOAD. These should be |
| @@ -70,9 +121,8 @@ NSError* WKWebViewErrorWithSource(NSError* error, WKWebViewErrorSource source) { |
| base::scoped_nsobject<NSMutableDictionary> userInfo( |
| [error.userInfo mutableCopy]); |
| [userInfo setObject:@(source) forKey:kWKWebViewErrorSourceKey]; |
| - return [NSError errorWithDomain:error.domain |
| - code:error.code |
| - userInfo:userInfo]; |
| + return |
| + [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
|
| } |
| WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| DCHECK(error); |
| @@ -82,9 +132,9 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } // namespace |
| -@interface CRWWKWebViewWebController () <WKNavigationDelegate, |
| - WKScriptMessageHandler, |
| - WKUIDelegate> { |
| +@interface CRWWKWebViewWebController ()<WKNavigationDelegate, |
| + WKScriptMessageHandler, |
| + WKUIDelegate> { |
| // The WKWebView managed by this instance. |
| base::scoped_nsobject<WKWebView> _wkWebView; |
| @@ -448,6 +498,40 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| [_wkWebView loadRequest:request]; |
| } |
| +// 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.
|
| +// replaces document with the result. |
| +- (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.
|
| + NSString* base64Data = [[request HTTPBody] base64EncodedStringWithOptions:0]; |
| + NSString* originURL = [[request URL] absoluteString]; |
| + NSString* contentType = nil; |
| + 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.
|
| + for (NSString* headerField in [[request allHTTPHeaderFields] allKeys]) { |
| + if ([headerField isEqualToString:@"Content-Type"]) { |
| + contentType = |
| + [[[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.
|
| + } |
| + [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.
|
| + headerField, |
| + [request allHTTPHeaderFields][headerField]]; |
| + } |
| + |
| + 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.
|
| + headerString, base64Data, contentType]; |
| +} |
| + |
| +// Loads POST request with body in |_wkWebView| by constructing an HTML page |
| +// that executes the request through javascript and replaces document with the |
| +// result. |
| +// Note that this approach includes multiple body encodings and decodings, plus |
| +// the data is passed to |_wkWebView| on main thread, hence the performance is |
| +// 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.
|
| +// This is necessary because WKWebView ignores POST request body. |
| +// Workaround for https://bugs.webkit.org/show_bug.cgi?id=145410 |
| +- (void)loadPOSTRequestWithBody:(NSMutableURLRequest*)request { |
| + 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.
|
| + [_wkWebView loadHTMLString:htmlString baseURL:request.URL]; |
| +} |
| + |
| - (void)loadWebHTMLString:(NSString*)html forURL:(const GURL&)URL { |
| [_wkWebView loadHTMLString:html baseURL:net::NSURLWithGURL(URL)]; |
| } |
| @@ -477,25 +561,36 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| - (void)loadRequestForCurrentNavigationItem { |
| DCHECK(self.webView && !self.nativeController); |
| + DCHECK([self currentSessionEntry]); |
| + |
| + web::WKBackForwardListItemHolder* holder = |
| + [self currentBackForwardListItemHolder]; |
| + BOOL isFormResubmission = |
| + (holder->navigation_type() == WKNavigationTypeFormResubmitted || |
| + holder->navigation_type() == WKNavigationTypeFormSubmitted); |
| + web::NavigationItemImpl* currentItem = |
| + [self currentSessionEntry].navigationItemImpl; |
| + NSData* POSTData = currentItem->GetPostData(); |
| + NSMutableURLRequest* request = [self requestForCurrentNavigationItem]; |
| ProceduralBlock defaultNavigationBlock = ^{ |
| [self registerLoadRequest:[self currentNavigationURL] |
| referrer:[self currentSessionEntryReferrer] |
| transition:[self currentTransition]]; |
| - [self loadRequest:[self requestForCurrentNavigationItem]]; |
| + [self loadRequest:request]; |
| }; |
| - // If there is no corresponding WKBackForwardListItem, or the item is not in |
| - // the current WKWebView's back-forward list, navigating using WKWebView API |
| - // is not possible. In this case, fall back to the default navigation |
| - // mechanism. |
| - web::WKBackForwardListItemHolder* holder = |
| - [self currentBackForwardListItemHolder]; |
| - if (!holder->back_forward_list_item() || |
| - ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { |
| - defaultNavigationBlock(); |
| - return; |
| - } |
| + // If the request has POST data and is not a form resubmission, configure and |
| + // run the POST request. |
| + 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.
|
| + [request setHTTPMethod:@"POST"]; |
| + [request setHTTPBody:POSTData]; |
| + [request setAllHTTPHeaderFields:[self currentHTTPHeaders]]; |
| + [self registerLoadRequest:[self currentNavigationURL] |
| + referrer:[self currentSessionEntryReferrer] |
| + transition:[self currentTransition]]; |
| + [self loadPOSTRequestWithBody:request]; |
| + }; |
| 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.
|
| // If the current navigation URL is the same as the URL of the visible |
| @@ -512,12 +607,26 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| }; |
| + // If there is no corresponding WKBackForwardListItem, or the item is not in |
| + // the current WKWebView's back-forward list, or this is a POST request with |
| + // data, navigating using WKWebView API is not possible. In this case, fall |
| + // back to the default navigation mechanism. |
| + if (!holder->back_forward_list_item() || |
| + ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { |
| + 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.
|
| + defaultNavigationBlock(); |
| + return; |
| + } |
| + } |
| + |
| + 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.
|
| + POSTBlock(); |
| + return; |
| + } |
| + |
| // If the request is not a form submission or resubmission, or the user |
| // doesn't need to confirm the load, then continue right away. |
| - web::NavigationItemImpl* currentItem = |
| - [self currentSessionEntry].navigationItemImpl; |
| - if ((holder->navigation_type() != WKNavigationTypeFormResubmitted && |
| - holder->navigation_type() != WKNavigationTypeFormSubmitted) || |
| + if (!isFormResubmission || |
| currentItem->ShouldSkipResubmitDataConfirmation()) { |
| webViewNavigationBlock(); |
| return; |
| @@ -525,6 +634,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| // If the request is form submission or resubmission, then prompt the |
| // user before proceeding. |
| + DCHECK(isFormResubmission); |
| [self.delegate webController:self |
| onFormResubmissionForRequest:nil |
| continueBlock:webViewNavigationBlock |
| @@ -622,9 +732,9 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| - (NSString*)activityIndicatorGroupID { |
| - return [NSString stringWithFormat: |
| - @"WKWebViewWebController.NetworkActivityIndicatorKey.%@", |
| - self.webStateImpl->GetRequestGroupID()]; |
| + return [NSString |
| + 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.
|
| + self.webStateImpl->GetRequestGroupID()]; |
| } |
| #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) |
| @@ -780,8 +890,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| - (void)webViewWebProcessDidCrash { |
| - if ([self.delegate respondsToSelector: |
| - @selector(webControllerWebProcessDidCrash:)]) { |
| + if ([self.delegate |
| + respondsToSelector:@selector(webControllerWebProcessDidCrash:)]) { |
| [self.delegate webControllerWebProcessDidCrash:self]; |
| } |
| } |
| @@ -790,9 +900,9 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| DCHECK(responseHandler); |
| [self evaluateJavaScript:@"__gCrWeb.getPageReferrerPolicy()" |
| stringResultHandler:^(NSString* referrer, NSError* error) { |
| - DCHECK_NE(error.code, WKErrorJavaScriptExceptionOccurred); |
| - responseHandler(!error ? referrer : nil); |
| - }]; |
| + DCHECK_NE(error.code, WKErrorJavaScriptExceptionOccurred); |
| + responseHandler(!error ? referrer : nil); |
| + }]; |
| } |
| - (void)didBlockPopupWithURL:(GURL)popupURL |
| @@ -803,15 +913,15 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| web::Referrer referrer(sourceURL, referrerPolicy); |
| NSString* const kWindowName = @""; // obsoleted |
| base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); |
| - void(^showPopupHandler)() = ^{ |
| - // On Desktop cross-window comunication is not supported for unblocked |
| - // popups; so it's ok to create a new independent page. |
| - CRWWebController* child = [[weakSelf delegate] |
| - webPageOrderedOpen:popupURL |
| - referrer:referrer |
| - windowName:kWindowName |
| - inBackground:NO]; |
| - DCHECK(!child || child.sessionController.openedByDOM); |
| + void (^showPopupHandler)() = ^{ |
| + // On Desktop cross-window comunication is not supported for unblocked |
| + // popups; so it's ok to create a new independent page. |
| + CRWWebController* child = |
| + [[weakSelf delegate] webPageOrderedOpen:popupURL |
| + referrer:referrer |
| + windowName:kWindowName |
| + inBackground:NO]; |
| + DCHECK(!child || child.sessionController.openedByDOM); |
| }; |
| web::BlockedPopupInfo info(popupURL, referrer, kWindowName, showPopupHandler); |
| @@ -819,18 +929,18 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| - (void)didBlockPopupWithURL:(GURL)popupURL sourceURL:(GURL)sourceURL { |
| - if (![self.delegate respondsToSelector: |
| - @selector(webController:didBlockPopup:)]) { |
| + if (![self.delegate |
| + respondsToSelector:@selector(webController:didBlockPopup:)]) { |
| return; |
| } |
| base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); |
| dispatch_async(dispatch_get_main_queue(), ^{ |
| - [self queryPageReferrerPolicy:^(NSString* policy) { |
| - [weakSelf didBlockPopupWithURL:popupURL |
| - sourceURL:sourceURL |
| - referrerPolicy:base::SysNSStringToUTF8(policy)]; |
| - }]; |
| + [self queryPageReferrerPolicy:^(NSString* policy) { |
| + [weakSelf didBlockPopupWithURL:popupURL |
| + sourceURL:sourceURL |
| + referrerPolicy:base::SysNSStringToUTF8(policy)]; |
| + }]; |
| }); |
| } |
| @@ -962,12 +1072,9 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| CHECK(scriptMessage.frameInfo.mainFrame); |
| int errorCode = 0; |
| std::string errorMessage; |
| - scoped_ptr<base::Value> inputJSONData( |
| - base::JSONReader::ReadAndReturnError( |
| - base::SysNSStringToUTF8(scriptMessage.body), |
| - false, |
| - &errorCode, |
| - &errorMessage)); |
| + scoped_ptr<base::Value> inputJSONData(base::JSONReader::ReadAndReturnError( |
| + base::SysNSStringToUTF8(scriptMessage.body), false, &errorCode, |
| + &errorMessage)); |
| if (errorCode) { |
| DLOG(WARNING) << "JSON parse error: %s" << errorMessage.c_str(); |
| return NO; |
| @@ -980,9 +1087,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| message->GetString("crwWindowId", &windowID); |
| // Check for correct windowID |
| if (![[self windowId] isEqualToString:base::SysUTF8ToNSString(windowID)]) { |
| - DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " |
| - << [self windowId] << " != " |
| - << base::SysUTF8ToNSString(windowID); |
| + DLOG(WARNING) << "Message from JS ignored due to non-matching windowID: " << |
| + [self windowId] << " != " << base::SysUTF8ToNSString(windowID); |
| return NO; |
| } |
| base::DictionaryValue* command = nullptr; |
| @@ -1037,7 +1143,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| #pragma mark JavaScript message handlers |
| - (BOOL)handleWindowHistoryWillChangeStateMessage: |
| - (base::DictionaryValue*)message |
| + (base::DictionaryValue*)message |
| context:(NSDictionary*)context { |
| _changingHistoryState = YES; |
| return |
| @@ -1052,8 +1158,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| - (BOOL)handleWindowHistoryDidReplaceStateMessage: |
| - (base::DictionaryValue*)message |
| - context:(NSDictionary*)context { |
| + (base::DictionaryValue*)message |
| + context:(NSDictionary*)context { |
| DCHECK(_changingHistoryState); |
| _changingHistoryState = NO; |
| return [super handleWindowHistoryDidReplaceStateMessage:message |
| @@ -1090,8 +1196,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) |
| // TODO(eugenebut): use WKWebView progress even if Chrome net stack is enabled. |
| - (void)webViewEstimatedProgressDidChange { |
| - if ([self.delegate respondsToSelector: |
| - @selector(webController:didUpdateProgress:)]) { |
| + if ([self.delegate |
| + respondsToSelector:@selector(webController:didUpdateProgress:)]) { |
| [self.delegate webController:self |
| didUpdateProgress:[_wkWebView estimatedProgress]]; |
| } |
| @@ -1117,8 +1223,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| } |
| - (void)webViewTitleDidChange { |
| - if ([self.delegate respondsToSelector: |
| - @selector(webController:titleDidChange:)]) { |
| + if ([self.delegate |
| + respondsToSelector:@selector(webController:titleDidChange:)]) { |
| DCHECK(self.title); |
| [self.delegate webController:self titleDidChange:self.title]; |
| } |
| @@ -1161,31 +1267,31 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| [self URLDidChangeWithoutDocumentChange:url]; |
| } else if (!_documentURL.host().empty() && |
| _documentURL.host() == url.host()) { |
| - [_wkWebView evaluateJavaScript:@"window.location.href" |
| - completionHandler:^(id result, NSError* error) { |
| - // If the web view has gone away, or the location |
| - // couldn't be retrieved, abort. |
| - if (!_wkWebView || |
| - ![result isKindOfClass:[NSString class]]) { |
| - return; |
| - } |
| - GURL jsURL([result UTF8String]); |
| - // Make sure that the URL is as expected, and re-check |
| - // the host to prevent race conditions. |
| - if (jsURL == url && _documentURL.host() == url.host()) { |
| - [self URLDidChangeWithoutDocumentChange:url]; |
| - } |
| - }]; |
| + [_wkWebView |
| + evaluateJavaScript:@"window.location.href" |
| + completionHandler:^(id result, NSError* error) { |
| + // If the web view has gone away, or the location |
| + // couldn't be retrieved, abort. |
| + if (!_wkWebView || ![result isKindOfClass:[NSString class]]) { |
| + return; |
| + } |
| + GURL jsURL([result UTF8String]); |
| + // Make sure that the URL is as expected, and re-check |
| + // the host to prevent race conditions. |
| + if (jsURL == url && _documentURL.host() == url.host()) { |
| + [self URLDidChangeWithoutDocumentChange:url]; |
| + } |
| + }]; |
| } |
| } |
| #pragma mark - |
| #pragma mark WKNavigationDelegate Methods |
| -- (void)webView:(WKWebView *)webView |
| - decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction |
| +- (void)webView:(WKWebView*)webView |
| + decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction |
| decisionHandler: |
| - (void (^)(WKNavigationActionPolicy))decisionHandler { |
| + (void (^)(WKNavigationActionPolicy))decisionHandler { |
| if (self.isBeingDestroyed) { |
| decisionHandler(WKNavigationActionPolicyCancel); |
| return; |
| @@ -1219,8 +1325,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| : WKNavigationActionPolicyCancel); |
| } |
| -- (void)webView:(WKWebView *)webView |
| - decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse |
| +- (void)webView:(WKWebView*)webView |
| + decidePolicyForNavigationResponse:(WKNavigationResponse*)navigationResponse |
| decisionHandler: |
| (void (^)(WKNavigationResponsePolicy))handler { |
| if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { |
| @@ -1252,8 +1358,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| // TODO(stuartmorgan): Move all the guesswork around these states out of the |
| // superclass, and wire these up to the remaining methods. |
| -- (void)webView:(WKWebView *)webView |
| - didStartProvisionalNavigation:(WKNavigation *)navigation { |
| +- (void)webView:(WKWebView*)webView |
| + didStartProvisionalNavigation:(WKNavigation*)navigation { |
| GURL webViewURL = net::GURLWithNSURL(webView.URL); |
| if (webViewURL.is_empty() && base::ios::IsRunningOnIOS9OrLater()) { |
| // May happen on iOS9, however in didCommitNavigation: callback the URL |
| @@ -1289,17 +1395,16 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| DCHECK(self.loadPhase == web::LOAD_REQUESTED); |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didReceiveServerRedirectForProvisionalNavigation: |
| - (WKNavigation *)navigation { |
| +- (void)webView:(WKWebView*)webView |
| + didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { |
| [self registerLoadRequest:net::GURLWithNSURL(webView.URL) |
| referrer:[self currentReferrer] |
| transition:ui::PAGE_TRANSITION_SERVER_REDIRECT]; |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didFailProvisionalNavigation:(WKNavigation *)navigation |
| - withError:(NSError *)error { |
| +- (void)webView:(WKWebView*)webView |
| + didFailProvisionalNavigation:(WKNavigation*)navigation |
| + withError:(NSError*)error { |
| [self discardPendingReferrerString]; |
| if (_pendingNavigationCancelled) { |
| @@ -1333,8 +1438,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| [self discardPendingNavigationTypeForMainFrame]; |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didCommitNavigation:(WKNavigation *)navigation { |
| +- (void)webView:(WKWebView*)webView |
| + didCommitNavigation:(WKNavigation*)navigation { |
| DCHECK_EQ(_wkWebView, webView); |
| // This point should closely approximate the document object change, so reset |
| // the list of injected scripts to those that are automatically injected. |
| @@ -1356,8 +1461,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| #endif |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didFinishNavigation:(WKNavigation *)navigation { |
| +- (void)webView:(WKWebView*)webView |
| + didFinishNavigation:(WKNavigation*)navigation { |
| DCHECK(!self.isHalted); |
| // Trigger JavaScript driven post-document-load-completion tasks. |
| // TODO(jyquinn): Investigate using WKUserScriptInjectionTimeAtDocumentEnd to |
| @@ -1367,18 +1472,19 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| [self didFinishNavigation]; |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didFailNavigation:(WKNavigation *)navigation |
| - withError:(NSError *)error { |
| +- (void)webView:(WKWebView*)webView |
| + didFailNavigation:(WKNavigation*)navigation |
| + withError:(NSError*)error { |
| [self handleLoadError:WKWebViewErrorWithSource(error, NAVIGATION) |
| inMainFrame:YES]; |
| } |
| -- (void)webView:(WKWebView *)webView |
| - didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge |
| - completionHandler: |
| - (void (^)(NSURLSessionAuthChallengeDisposition disposition, |
| - NSURLCredential *credential))completionHandler { |
| +- (void) |
| + webView:(WKWebView*)webView |
| +didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge |
| + completionHandler: |
| + (void (^)(NSURLSessionAuthChallengeDisposition disposition, |
| + NSURLCredential* credential))completionHandler { |
| if (![challenge.protectionSpace.authenticationMethod |
| isEqual:NSURLAuthenticationMethodServerTrust]) { |
| completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); |
| @@ -1409,8 +1515,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| windowFeatures:(WKWindowFeatures*)windowFeatures { |
| GURL requestURL = net::GURLWithNSURL(navigationAction.request.URL); |
| NSString* referer = GetRefererFromNavigationAction(navigationAction); |
| - GURL referrerURL = referer ? GURL(base::SysNSStringToUTF8(referer)) : |
| - [self currentURL]; |
| + GURL referrerURL = |
| + referer ? GURL(base::SysNSStringToUTF8(referer)) : [self currentURL]; |
| if (![self userIsInteracting] && |
| [self shouldBlockPopupWithURL:requestURL sourceURL:referrerURL]) { |
| @@ -1434,7 +1540,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| - (void)webView:(WKWebView*)webView |
| runJavaScriptAlertPanelWithMessage:(NSString*)message |
| initiatedByFrame:(WKFrameInfo*)frame |
| - completionHandler:(void(^)())completionHandler { |
| + completionHandler:(void (^)())completionHandler { |
| SEL alertSelector = @selector(webController: |
| runJavaScriptAlertPanelWithMessage: |
| requestURL: |
| @@ -1453,7 +1559,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| runJavaScriptConfirmPanelWithMessage:(NSString*)message |
| initiatedByFrame:(WKFrameInfo*)frame |
| completionHandler: |
| - (void (^)(BOOL result))completionHandler { |
| + (void (^)(BOOL result))completionHandler { |
| SEL confirmationSelector = @selector(webController: |
| runJavaScriptConfirmPanelWithMessage: |
| requestURL: |
| @@ -1461,8 +1567,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| if ([self.UIDelegate respondsToSelector:confirmationSelector]) { |
| [self.UIDelegate webController:self |
| runJavaScriptConfirmPanelWithMessage:message |
| - requestURL: |
| - net::GURLWithNSURL(frame.request.URL) |
| + requestURL:net::GURLWithNSURL( |
| + frame.request.URL) |
| completionHandler:completionHandler]; |
| } else if (completionHandler) { |
| completionHandler(NO); |
| @@ -1474,7 +1580,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| defaultText:(NSString*)defaultText |
| initiatedByFrame:(WKFrameInfo*)frame |
| completionHandler: |
| - (void (^)(NSString *result))completionHandler { |
| + (void (^)(NSString* result))completionHandler { |
| SEL textInputSelector = @selector(webController: |
| runJavaScriptTextInputPanelWithPrompt: |
| placeholderText: |
| @@ -1484,8 +1590,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| [self.UIDelegate webController:self |
| runJavaScriptTextInputPanelWithPrompt:prompt |
| placeholderText:defaultText |
| - requestURL: |
| - net::GURLWithNSURL(frame.request.URL) |
| + requestURL:net::GURLWithNSURL( |
| + frame.request.URL) |
| completionHandler:completionHandler]; |
| } else if (completionHandler) { |
| completionHandler(nil); |