Chromium Code Reviews| 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 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 817 // Called when WKWebView URL has been changed. | 817 // Called when WKWebView URL has been changed. |
| 818 - (void)webViewURLDidChange; | 818 - (void)webViewURLDidChange; |
| 819 // Returns YES if a KVO change to |newURL| could be a 'navigation' within the | 819 // Returns YES if a KVO change to |newURL| could be a 'navigation' within the |
| 820 // document (hash change, pushState/replaceState, etc.). This should only be | 820 // document (hash change, pushState/replaceState, etc.). This should only be |
| 821 // used in the context of a URL KVO callback firing, and only if |isLoading| is | 821 // used in the context of a URL KVO callback firing, and only if |isLoading| is |
| 822 // YES for the web view (since if it's not, no guesswork is needed). | 822 // YES for the web view (since if it's not, no guesswork is needed). |
| 823 - (BOOL)isKVOChangePotentialSameDocumentNavigationToURL:(const GURL&)newURL; | 823 - (BOOL)isKVOChangePotentialSameDocumentNavigationToURL:(const GURL&)newURL; |
| 824 // Called when a non-document-changing URL change occurs. Updates the | 824 // Called when a non-document-changing URL change occurs. Updates the |
| 825 // _documentURL, and informs the superclass of the change. | 825 // _documentURL, and informs the superclass of the change. |
| 826 - (void)URLDidChangeWithoutDocumentChange:(const GURL&)URL; | 826 - (void)URLDidChangeWithoutDocumentChange:(const GURL&)URL; |
| 827 // Returns YES if there is currently a requested but uncommitted load for | 827 // Returns context for pending navigation that has |URL|. null if there is no |
| 828 // |targetURL|. | 828 // matching pending navigation. |
| 829 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL; | 829 - (web::NavigationContextImpl*)contextForPendingNavigationWithURL: |
| 830 (const GURL&)URL; | |
| 830 // Loads request for the URL of the current navigation item. Subclasses may | 831 // Loads request for the URL of the current navigation item. Subclasses may |
| 831 // choose to build a new NSURLRequest and call |loadRequest| on the underlying | 832 // choose to build a new NSURLRequest and call |loadRequest| on the underlying |
| 832 // web view, or use native web view navigation where possible (for example, | 833 // web view, or use native web view navigation where possible (for example, |
| 833 // going back and forward through the history stack). | 834 // going back and forward through the history stack). |
| 834 - (void)loadRequestForCurrentNavigationItem; | 835 - (void)loadRequestForCurrentNavigationItem; |
| 835 // Reports Navigation.IOSWKWebViewSlowFastBackForward UMA. No-op if pending | 836 // Reports Navigation.IOSWKWebViewSlowFastBackForward UMA. No-op if pending |
| 836 // navigation is not back forward navigation. | 837 // navigation is not back forward navigation. |
| 837 - (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast; | 838 - (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast; |
| 838 | 839 |
| 839 // Handlers for JavaScript messages. |message| contains a JavaScript command and | 840 // Handlers for JavaScript messages. |message| contains a JavaScript command and |
| (...skipping 3291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4131 | 4132 |
| 4132 // Web View should not be created for App Specific URLs. | 4133 // Web View should not be created for App Specific URLs. |
| 4133 if (!web::GetWebClient()->IsAppSpecificURL(URL)) { | 4134 if (!web::GetWebClient()->IsAppSpecificURL(URL)) { |
| 4134 [self ensureWebViewCreated]; | 4135 [self ensureWebViewCreated]; |
| 4135 DCHECK(_webView) << "_webView null while trying to load HTML"; | 4136 DCHECK(_webView) << "_webView null while trying to load HTML"; |
| 4136 } | 4137 } |
| 4137 WKNavigation* navigation = | 4138 WKNavigation* navigation = |
| 4138 [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; | 4139 [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; |
| 4139 [_navigationStates setState:web::WKNavigationState::REQUESTED | 4140 [_navigationStates setState:web::WKNavigationState::REQUESTED |
| 4140 forNavigation:navigation]; | 4141 forNavigation:navigation]; |
| 4141 std::unique_ptr<web::NavigationContextImpl> context = | 4142 std::unique_ptr<web::NavigationContextImpl> context; |
| 4142 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, URL); | 4143 if (_webStateImpl->HasWebUI()) { |
| 4144 // WebUI uses |loadHTML:forURL:| to feed the content to web view. This | |
| 4145 // should not be treated as a navigation, but WKNavigationDelegate callbacks | |
| 4146 // still expect a valid context. | |
| 4147 context = | |
| 4148 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, URL); | |
| 4149 } else { | |
| 4150 context = [self | |
| 4151 registerLoadRequestForURL:URL | |
| 4152 referrer:web::Referrer() | |
| 4153 transition:ui::PageTransition::PAGE_TRANSITION_TYPED]; | |
| 4154 } | |
| 4143 [_navigationStates setContext:std::move(context) forNavigation:navigation]; | 4155 [_navigationStates setContext:std::move(context) forNavigation:navigation]; |
| 4144 } | 4156 } |
| 4145 | 4157 |
| 4146 - (void)loadHTML:(NSString*)HTML forAppSpecificURL:(const GURL&)URL { | 4158 - (void)loadHTML:(NSString*)HTML forAppSpecificURL:(const GURL&)URL { |
| 4147 CHECK(web::GetWebClient()->IsAppSpecificURL(URL)); | 4159 CHECK(web::GetWebClient()->IsAppSpecificURL(URL)); |
| 4148 [self loadHTML:HTML forURL:URL]; | 4160 [self loadHTML:HTML forURL:URL]; |
| 4149 } | 4161 } |
| 4150 | 4162 |
| 4151 - (void)loadHTMLForCurrentURL:(NSString*)HTML { | 4163 - (void)loadHTMLForCurrentURL:(NSString*)HTML { |
| 4152 [self loadHTML:HTML forURL:self.currentURL]; | 4164 [self loadHTML:HTML forURL:self.currentURL]; |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4512 [self setDocumentURL:net::GURLWithNSURL([_webView URL])]; | 4524 [self setDocumentURL:net::GURLWithNSURL([_webView URL])]; |
| 4513 | 4525 |
| 4514 if (!_lastRegisteredRequestURL.is_valid() && | 4526 if (!_lastRegisteredRequestURL.is_valid() && |
| 4515 _documentURL != _lastRegisteredRequestURL) { | 4527 _documentURL != _lastRegisteredRequestURL) { |
| 4516 // if |_lastRegisteredRequestURL| is an invalid URL, then |_documentURL| | 4528 // if |_lastRegisteredRequestURL| is an invalid URL, then |_documentURL| |
| 4517 // will be "about:blank". | 4529 // will be "about:blank". |
| 4518 [[self sessionController] updatePendingItem:_documentURL]; | 4530 [[self sessionController] updatePendingItem:_documentURL]; |
| 4519 } | 4531 } |
| 4520 | 4532 |
| 4521 // If |navigation| is nil (which happens for windows open by DOM), then it | 4533 // If |navigation| is nil (which happens for windows open by DOM), then it |
| 4522 // should be the first and the only pending navigaiton. | 4534 // should be the first and the only pending navigation. |
| 4523 BOOL isLastNavigation = | 4535 BOOL isLastNavigation = |
| 4524 !navigation || | 4536 !navigation || |
| 4525 [[_navigationStates lastAddedNavigation] isEqual:navigation]; | 4537 [[_navigationStates lastAddedNavigation] isEqual:navigation]; |
| 4526 DCHECK(_documentURL == _lastRegisteredRequestURL || // latest navigation | 4538 DCHECK(_documentURL == _lastRegisteredRequestURL || // latest navigation |
| 4527 !isLastNavigation || // previous navigation | 4539 !isLastNavigation || // previous navigation |
| 4528 (!_lastRegisteredRequestURL.is_valid() && // invalid URL load | 4540 (!_lastRegisteredRequestURL.is_valid() && // invalid URL load |
| 4529 _documentURL.spec() == url::kAboutBlankURL)); | 4541 _documentURL.spec() == url::kAboutBlankURL)); |
| 4530 | 4542 |
| 4531 // Update HTTP response headers. | 4543 // Update HTTP response headers. |
| 4532 _webStateImpl->UpdateHttpResponseHeaders(_documentURL); | 4544 _webStateImpl->UpdateHttpResponseHeaders(_documentURL); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4764 // A fast back navigation caused by pushState does not call | 4776 // A fast back navigation caused by pushState does not call |
| 4765 // |didCommitNavigation:|, so signal page change explicitly. | 4777 // |didCommitNavigation:|, so signal page change explicitly. |
| 4766 // TODO(crbug.com/659816): Because back-forward navigation is disabled for | 4778 // TODO(crbug.com/659816): Because back-forward navigation is disabled for |
| 4767 // pages that used push/replace State API, this code will not be executed. | 4779 // pages that used push/replace State API, this code will not be executed. |
| 4768 DCHECK_EQ(_documentURL.GetOrigin(), webViewURL.GetOrigin()); | 4780 DCHECK_EQ(_documentURL.GetOrigin(), webViewURL.GetOrigin()); |
| 4769 BOOL isSameDocumentNavigation = | 4781 BOOL isSameDocumentNavigation = |
| 4770 [self isKVOChangePotentialSameDocumentNavigationToURL:webViewURL]; | 4782 [self isKVOChangePotentialSameDocumentNavigationToURL:webViewURL]; |
| 4771 [self setDocumentURL:webViewURL]; | 4783 [self setDocumentURL:webViewURL]; |
| 4772 [self webPageChanged]; | 4784 [self webPageChanged]; |
| 4773 | 4785 |
| 4786 web::NavigationContextImpl* context = | |
| 4787 [self contextForPendingNavigationWithURL:webViewURL]; | |
| 4774 // Same document navigation does not contain response headers. | 4788 // Same document navigation does not contain response headers. |
| 4775 // TODO(crbug.com/713836): Instead of creating a new context, find | |
| 4776 // existing navigation context stored in |_navigationStates| and use it. | |
| 4777 std::unique_ptr<web::NavigationContextImpl> context = | |
| 4778 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, | |
| 4779 webViewURL); | |
| 4780 net::HttpResponseHeaders* headers = | 4789 net::HttpResponseHeaders* headers = |
| 4781 isSameDocumentNavigation ? nullptr | 4790 isSameDocumentNavigation ? nullptr |
| 4782 : _webStateImpl->GetHttpResponseHeaders(); | 4791 : _webStateImpl->GetHttpResponseHeaders(); |
| 4783 context->SetResponseHeaders(headers); | 4792 context->SetResponseHeaders(headers); |
| 4784 context->SetIsSameDocument(isSameDocumentNavigation); | 4793 context->SetIsSameDocument(isSameDocumentNavigation); |
| 4785 _webStateImpl->OnNavigationFinished(context.get()); | 4794 _webStateImpl->OnNavigationFinished(context); |
| 4786 } | 4795 } |
| 4787 | 4796 |
| 4788 [self updateSSLStatusForCurrentNavigationItem]; | 4797 [self updateSSLStatusForCurrentNavigationItem]; |
| 4789 | 4798 |
| 4790 // Fast back forward navigation may not call |didFinishNavigation:|, so | 4799 // Fast back forward navigation may not call |didFinishNavigation:|, so |
| 4791 // signal did finish navigation explicitly. | 4800 // signal did finish navigation explicitly. |
| 4792 if (_lastRegisteredRequestURL == _documentURL) { | 4801 if (_lastRegisteredRequestURL == _documentURL) { |
| 4793 [self didFinishNavigation:nil]; | 4802 [self didFinishNavigation:nil]; |
| 4794 } | 4803 } |
| 4795 } | 4804 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4922 // history changes when a window.history.didPushState or | 4931 // history changes when a window.history.didPushState or |
| 4923 // window.history.didReplaceState message is received, which should happen in | 4932 // window.history.didReplaceState message is received, which should happen in |
| 4924 // the next runloop. | 4933 // the next runloop. |
| 4925 // | 4934 // |
| 4926 // Otherwise, simulate the whole delegate flow for a load (since the | 4935 // Otherwise, simulate the whole delegate flow for a load (since the |
| 4927 // superclass currently doesn't have a clean separation between URL changes | 4936 // superclass currently doesn't have a clean separation between URL changes |
| 4928 // and document changes). Note that the order of these calls is important: | 4937 // and document changes). Note that the order of these calls is important: |
| 4929 // registering a load request logically comes before updating the document | 4938 // registering a load request logically comes before updating the document |
| 4930 // URL, but also must come first since it uses state that is reset on URL | 4939 // URL, but also must come first since it uses state that is reset on URL |
| 4931 // changes. | 4940 // changes. |
| 4932 std::unique_ptr<web::NavigationContextImpl> navigationContext; | 4941 |
| 4942 // |newNavigationContext| only exists if this method has to create a new | |
| 4943 // context object. | |
| 4944 std::unique_ptr<web::NavigationContextImpl> newNavigationContext; | |
| 4933 if (!_changingHistoryState) { | 4945 if (!_changingHistoryState) { |
| 4934 if ([self isLoadRequestPendingForURL:newURL]) { | 4946 if ([self contextForPendingNavigationWithURL:newURL]) { |
| 4935 // |loadWithParams:| was called with URL that has different fragment | 4947 // |loadWithParams:| was called with URL that has different fragment |
| 4936 // comparing to the orevious URL. | 4948 // comparing to the previous URL. |
|
kkhorimoto
2017/05/17 23:05:37
Can we restructure this if statement since this co
Eugene But (OOO till 7-30)
2017/05/18 14:47:29
We could but, I wanted to keep a comment to explai
kkhorimoto
2017/05/18 18:32:04
Hmm not a lot of great ways to do it. Maybe we co
Eugene But (OOO till 7-30)
2017/05/18 18:46:22
Thanks! Initially I had raw NavigationContextImpl*
| |
| 4937 // TODO(crbug.com/713836): Instead of creating a new context, find | |
| 4938 // existing navigation context stored in |_navigationStates| and use it. | |
| 4939 navigationContext = web::NavigationContextImpl::CreateNavigationContext( | |
| 4940 _webStateImpl, newURL); | |
| 4941 } else { | 4949 } else { |
| 4942 // This could be: | 4950 // This could be: |
| 4943 // 1.) Renderer-initiated fragment change | 4951 // 1.) Renderer-initiated fragment change |
| 4944 // 2.) Assigning same-origin URL to window.location | 4952 // 2.) Assigning same-origin URL to window.location |
| 4945 // 3.) Incorrectly handled window.location.replace (crbug.com/307072) | 4953 // 3.) Incorrectly handled window.location.replace (crbug.com/307072) |
| 4946 // 4.) Back-forward same document navigation | 4954 // 4.) Back-forward same document navigation |
| 4947 navigationContext = [self registerLoadRequestForURL:newURL]; | 4955 newNavigationContext = [self registerLoadRequestForURL:newURL]; |
| 4948 | 4956 |
| 4949 // Use the current title for items created by same document navigations. | 4957 // Use the current title for items created by same document navigations. |
| 4950 auto* pendingItem = self.navigationManagerImpl->GetPendingItem(); | 4958 auto* pendingItem = self.navigationManagerImpl->GetPendingItem(); |
| 4951 if (pendingItem) | 4959 if (pendingItem) |
| 4952 pendingItem->SetTitle(_webStateImpl->GetTitle()); | 4960 pendingItem->SetTitle(_webStateImpl->GetTitle()); |
| 4953 } | 4961 } |
| 4954 navigationContext->SetIsSameDocument(true); | |
| 4955 } | 4962 } |
| 4956 | 4963 |
| 4957 [self setDocumentURL:newURL]; | 4964 [self setDocumentURL:newURL]; |
| 4958 | 4965 |
| 4959 if (!_changingHistoryState) { | 4966 if (!_changingHistoryState) { |
| 4960 [self didStartLoadingURL:_documentURL]; | 4967 [self didStartLoadingURL:_documentURL]; |
| 4961 _webStateImpl->OnNavigationFinished(navigationContext.get()); | 4968 |
| 4969 // Pass either newly created context (if it exists) or context that already | |
| 4970 // existed before. | |
| 4971 web::NavigationContextImpl* navigationContext = newNavigationContext.get(); | |
| 4972 if (!navigationContext) | |
| 4973 navigationContext = [self contextForPendingNavigationWithURL:newURL]; | |
| 4974 navigationContext->SetIsSameDocument(true); | |
| 4975 _webStateImpl->OnNavigationFinished(navigationContext); | |
| 4976 | |
| 4962 [self updateSSLStatusForCurrentNavigationItem]; | 4977 [self updateSSLStatusForCurrentNavigationItem]; |
| 4963 [self didFinishNavigation:nil]; | 4978 [self didFinishNavigation:nil]; |
| 4964 } | 4979 } |
| 4965 } | 4980 } |
| 4966 | 4981 |
| 4967 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL { | 4982 - (web::NavigationContextImpl*)contextForPendingNavigationWithURL: |
| 4968 if (self.loadPhase != web::LOAD_REQUESTED) | 4983 (const GURL&)URL { |
| 4969 return NO; | 4984 for (id navigation in [_navigationStates pendingNavigations]) { |
| 4985 if (navigation == [NSNull null]) { | |
| 4986 // null is a valid navigation object passed to WKNavigationDelegate | |
| 4987 // callbacks and represents window opening action. | |
| 4988 navigation = nil; | |
| 4989 } | |
| 4970 | 4990 |
| 4971 web::NavigationItem* pendingItem = | 4991 web::NavigationContextImpl* context = |
| 4972 self.webState->GetNavigationManager()->GetPendingItem(); | 4992 [_navigationStates contextForNavigation:navigation]; |
| 4973 return pendingItem && pendingItem->GetURL() == targetURL; | 4993 if (context->GetUrl() == URL) { |
| 4994 return context; | |
| 4995 } | |
| 4996 } | |
| 4997 return nullptr; | |
| 4974 } | 4998 } |
| 4975 | 4999 |
| 4976 - (void)loadRequestForCurrentNavigationItem { | 5000 - (void)loadRequestForCurrentNavigationItem { |
| 4977 DCHECK(_webView); | 5001 DCHECK(_webView); |
| 4978 DCHECK(self.currentNavItem); | 5002 DCHECK(self.currentNavItem); |
| 4979 // If a load is kicked off on a WKWebView with a frame whose size is {0, 0} or | 5003 // If a load is kicked off on a WKWebView with a frame whose size is {0, 0} or |
| 4980 // that has a negative dimension for a size, rendering issues occur that | 5004 // that has a negative dimension for a size, rendering issues occur that |
| 4981 // manifest in erroneous scrolling and tap handling (crbug.com/574996, | 5005 // manifest in erroneous scrolling and tap handling (crbug.com/574996, |
| 4982 // crbug.com/577793). | 5006 // crbug.com/577793). |
| 4983 DCHECK_GT(CGRectGetWidth([_webView frame]), 0.0); | 5007 DCHECK_GT(CGRectGetWidth([_webView frame]), 0.0); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5172 - (NSUInteger)observerCount { | 5196 - (NSUInteger)observerCount { |
| 5173 DCHECK_EQ(_observerBridges.size(), [_observers count]); | 5197 DCHECK_EQ(_observerBridges.size(), [_observers count]); |
| 5174 return [_observers count]; | 5198 return [_observers count]; |
| 5175 } | 5199 } |
| 5176 | 5200 |
| 5177 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5201 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
| 5178 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5202 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
| 5179 } | 5203 } |
| 5180 | 5204 |
| 5181 @end | 5205 @end |
| OLD | NEW |