OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/web/web_state/ui/crw_web_controller.h" | 5 #import "ios/web/web_state/ui/crw_web_controller.h" |
6 | 6 |
7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
8 | 8 |
9 #import <objc/runtime.h> | 9 #import <objc/runtime.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 4417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4428 BOOL previousItemWasLoadedInNativeView = | 4428 BOOL previousItemWasLoadedInNativeView = |
4429 [self shouldLoadURLInNativeView:lastCommittedURL]; | 4429 [self shouldLoadURLInNativeView:lastCommittedURL]; |
4430 if (!isFirstLoad && !previousItemWasLoadedInNativeView) | 4430 if (!isFirstLoad && !previousItemWasLoadedInNativeView) |
4431 [self.sessionController discardNonCommittedItems]; | 4431 [self.sessionController discardNonCommittedItems]; |
4432 } | 4432 } |
4433 | 4433 |
4434 handler(allowNavigation ? WKNavigationResponsePolicyAllow | 4434 handler(allowNavigation ? WKNavigationResponsePolicyAllow |
4435 : WKNavigationResponsePolicyCancel); | 4435 : WKNavigationResponsePolicyCancel); |
4436 } | 4436 } |
4437 | 4437 |
4438 // TODO(stuartmorgan): Move all the guesswork around these states out of the | |
4439 // superclass, and wire these up to the remaining methods. | |
4440 - (void)webView:(WKWebView*)webView | 4438 - (void)webView:(WKWebView*)webView |
4441 didStartProvisionalNavigation:(WKNavigation*)navigation { | 4439 didStartProvisionalNavigation:(WKNavigation*)navigation { |
4442 [_navigationStates setState:web::WKNavigationState::STARTED | 4440 [_navigationStates setState:web::WKNavigationState::STARTED |
4443 forNavigation:navigation]; | 4441 forNavigation:navigation]; |
4444 | 4442 |
4445 if (navigation && | |
4446 ![[_navigationStates lastAddedNavigation] isEqual:navigation]) { | |
4447 // |navigation| is not the latest navigation and will be cancelled. | |
4448 // Ignore |navigation| as a new navigation will start soon. | |
4449 return; | |
4450 } | |
4451 | |
4452 GURL webViewURL = net::GURLWithNSURL(webView.URL); | 4443 GURL webViewURL = net::GURLWithNSURL(webView.URL); |
4453 if (webViewURL.is_empty()) { | 4444 if (webViewURL.is_empty()) { |
4454 // May happen on iOS9, however in didCommitNavigation: callback the URL | 4445 // May happen on iOS9, however in didCommitNavigation: callback the URL |
4455 // will be "about:blank". | 4446 // will be "about:blank". |
4456 webViewURL = GURL(url::kAboutBlankURL); | 4447 webViewURL = GURL(url::kAboutBlankURL); |
4457 } | 4448 } |
4458 | 4449 |
4459 // Intercept renderer-initiated navigations. If this navigation has not yet | 4450 web::NavigationContextImpl* context = |
4460 // been registered, do so. loadPhase check is necessary because | 4451 [_navigationStates contextForNavigation:navigation]; |
4461 // lastRegisteredRequestURL may be the same as the webViewURL on a new tab | 4452 if (context) { |
4462 // created by window.open (default is about::blank). | 4453 // This is already seen and registered navigation. |
4463 if (_lastRegisteredRequestURL != webViewURL || | 4454 |
4464 self.loadPhase != web::LOAD_REQUESTED) { | 4455 if (context->GetUrl() != webViewURL) { |
4465 // Reset current WebUI if one exists. | 4456 // Update last seen URL because it may be changed by WKWebView (f.e. by |
4466 [self clearWebUI]; | 4457 // performing characters escaping). |
| 4458 web::NavigationItem* item = web::GetItemWithUniqueID( |
| 4459 self.navigationManagerImpl, context->GetNavigationItemUniqueID()); |
| 4460 if (item) { |
| 4461 item->SetVirtualURL(webViewURL); |
| 4462 item->SetURL(webViewURL); |
| 4463 } |
| 4464 |
| 4465 _lastRegisteredRequestURL = webViewURL; |
| 4466 } |
| 4467 return; |
| 4468 } |
| 4469 |
| 4470 // This is renderer-initiated navigation which was not seen before and should |
| 4471 // be registered. |
| 4472 |
| 4473 [self clearWebUI]; |
| 4474 |
| 4475 if (web::GetWebClient()->IsAppSpecificURL(webViewURL)) { |
4467 // Restart app specific URL loads to properly capture state. | 4476 // Restart app specific URL loads to properly capture state. |
4468 // TODO(crbug.com/546347): Extract necessary tasks for app specific URL | 4477 // TODO(crbug.com/546347): Extract necessary tasks for app specific URL |
4469 // navigation rather than restarting the load. | 4478 // navigation rather than restarting the load. |
4470 if (web::GetWebClient()->IsAppSpecificURL(webViewURL)) { | 4479 |
4471 // Renderer-initiated loads of WebUI can be done only from other WebUI | 4480 // Renderer-initiated loads of WebUI can be done only from other WebUI |
4472 // pages. WebUI pages may have increased power and using the same web | 4481 // pages. WebUI pages may have increased power and using the same web |
4473 // process (which may potentially be controller by an attacker) is | 4482 // process (which may potentially be controller by an attacker) is |
4474 // dangerous. | 4483 // dangerous. |
4475 if (web::GetWebClient()->IsAppSpecificURL(_documentURL)) { | 4484 if (web::GetWebClient()->IsAppSpecificURL(_documentURL)) { |
4476 [self abortLoad]; | 4485 [self abortLoad]; |
4477 NavigationManager::WebLoadParams params(webViewURL); | 4486 NavigationManager::WebLoadParams params(webViewURL); |
4478 [self loadWithParams:params]; | 4487 [self loadWithParams:params]; |
4479 } | |
4480 return; | |
4481 } else { | |
4482 std::unique_ptr<web::NavigationContextImpl> navigationContext = | |
4483 [self registerLoadRequestForURL:webViewURL]; | |
4484 [_navigationStates setContext:std::move(navigationContext) | |
4485 forNavigation:navigation]; | |
4486 } | 4488 } |
| 4489 return; |
4487 } | 4490 } |
4488 | 4491 |
4489 // Ensure the URL is registered and loadPhase is as expected. | 4492 std::unique_ptr<web::NavigationContextImpl> navigationContext = |
4490 DCHECK(_lastRegisteredRequestURL == webViewURL); | 4493 [self registerLoadRequestForURL:webViewURL]; |
| 4494 [_navigationStates setContext:std::move(navigationContext) |
| 4495 forNavigation:navigation]; |
4491 DCHECK(self.loadPhase == web::LOAD_REQUESTED); | 4496 DCHECK(self.loadPhase == web::LOAD_REQUESTED); |
4492 } | 4497 } |
4493 | 4498 |
4494 - (void)webView:(WKWebView*)webView | 4499 - (void)webView:(WKWebView*)webView |
4495 didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { | 4500 didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { |
4496 [_navigationStates setState:web::WKNavigationState::REDIRECTED | 4501 [_navigationStates setState:web::WKNavigationState::REDIRECTED |
4497 forNavigation:navigation]; | 4502 forNavigation:navigation]; |
4498 | 4503 |
4499 // It is fine to ignore returned NavigationContext. Context does not change | 4504 // It is fine to ignore returned NavigationContext. Context does not change |
4500 // for redirect and old context stored _navigationStates is valid and it | 4505 // for redirect and old context stored _navigationStates is valid and it |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5239 - (NSUInteger)observerCount { | 5244 - (NSUInteger)observerCount { |
5240 DCHECK_EQ(_observerBridges.size(), [_observers count]); | 5245 DCHECK_EQ(_observerBridges.size(), [_observers count]); |
5241 return [_observers count]; | 5246 return [_observers count]; |
5242 } | 5247 } |
5243 | 5248 |
5244 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5249 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
5245 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5250 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
5246 } | 5251 } |
5247 | 5252 |
5248 @end | 5253 @end |
OLD | NEW |