OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |