| 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 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 // navigation is committed. | 594 // navigation is committed. |
| 595 - (void)commitPendingNavigationInfo; | 595 - (void)commitPendingNavigationInfo; |
| 596 // Returns a NSMutableURLRequest that represents the current NavigationItem. | 596 // Returns a NSMutableURLRequest that represents the current NavigationItem. |
| 597 - (NSMutableURLRequest*)requestForCurrentNavigationItem; | 597 - (NSMutableURLRequest*)requestForCurrentNavigationItem; |
| 598 // Returns the WKBackForwardListItemHolder for the current navigation item. | 598 // Returns the WKBackForwardListItemHolder for the current navigation item. |
| 599 - (web::WKBackForwardListItemHolder*)currentBackForwardListItemHolder; | 599 - (web::WKBackForwardListItemHolder*)currentBackForwardListItemHolder; |
| 600 // Updates the WKBackForwardListItemHolder navigation item. | 600 // Updates the WKBackForwardListItemHolder navigation item. |
| 601 - (void)updateCurrentBackForwardListItemHolder; | 601 - (void)updateCurrentBackForwardListItemHolder; |
| 602 | 602 |
| 603 // Loads the current nativeController in a native view. If a web view is | 603 // Loads the current nativeController in a native view. If a web view is |
| 604 // present, removes it and swaps in the native view in its place. | 604 // present, removes it and swaps in the native view in its place. |context| can |
| 605 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess; | 605 // not be null. |
| 606 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess |
| 607 navigationContext:(web::NavigationContextImpl*)context; |
| 608 // Loads the correct HTML page for |error| in a native controller, retrieved |
| 609 // from the native provider. |
| 610 - (void)loadErrorInNativeView:(NSError*)error |
| 611 navigationContext:(web::NavigationContextImpl*)context; |
| 606 // YES if the navigation to |url| should be treated as a reload. | 612 // YES if the navigation to |url| should be treated as a reload. |
| 607 - (BOOL)shouldReload:(const GURL&)destinationURL | 613 - (BOOL)shouldReload:(const GURL&)destinationURL |
| 608 transition:(ui::PageTransition)transition; | 614 transition:(ui::PageTransition)transition; |
| 609 // Internal implementation of reload. Reloads without notifying the delegate. | 615 // Internal implementation of reload. Reloads without notifying the delegate. |
| 610 // Most callers should use -reload instead. | 616 // Most callers should use -reload instead. |
| 611 - (void)reloadInternal; | 617 - (void)reloadInternal; |
| 612 // Aborts any load for both the web view and web controller. | 618 // Aborts any load for both the web view and web controller. |
| 613 - (void)abortLoad; | 619 - (void)abortLoad; |
| 614 // Updates the internal state and informs the delegate that any outstanding load | 620 // Updates the internal state and informs the delegate that any outstanding load |
| 615 // operations are cancelled. | 621 // operations are cancelled. |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 return web::Referrer(GURL(base::SysNSStringToUTF8(referrerString)), | 1347 return web::Referrer(GURL(base::SysNSStringToUTF8(referrerString)), |
| 1342 web::ReferrerPolicyAlways); | 1348 web::ReferrerPolicyAlways); |
| 1343 } | 1349 } |
| 1344 | 1350 |
| 1345 - (void)pushStateWithPageURL:(const GURL&)pageURL | 1351 - (void)pushStateWithPageURL:(const GURL&)pageURL |
| 1346 stateObject:(NSString*)stateObject | 1352 stateObject:(NSString*)stateObject |
| 1347 transition:(ui::PageTransition)transition { | 1353 transition:(ui::PageTransition)transition { |
| 1348 [[self sessionController] pushNewItemWithURL:pageURL | 1354 [[self sessionController] pushNewItemWithURL:pageURL |
| 1349 stateObject:stateObject | 1355 stateObject:stateObject |
| 1350 transition:transition]; | 1356 transition:transition]; |
| 1351 _webStateImpl->OnSameDocumentNavigation(pageURL); | 1357 std::unique_ptr<web::NavigationContext> context = |
| 1358 web::NavigationContextImpl::CreateSameDocumentNavigationContext( |
| 1359 _webStateImpl, pageURL); |
| 1360 _webStateImpl->OnNavigationFinished(context.get()); |
| 1352 self.userInteractionRegistered = NO; | 1361 self.userInteractionRegistered = NO; |
| 1353 } | 1362 } |
| 1354 | 1363 |
| 1355 - (void)replaceStateWithPageURL:(const GURL&)pageURL | 1364 - (void)replaceStateWithPageURL:(const GURL&)pageURL |
| 1356 stateObject:(NSString*)stateObject { | 1365 stateObject:(NSString*)stateObject { |
| 1357 [[self sessionController] updateCurrentItemWithURL:pageURL | 1366 [[self sessionController] updateCurrentItemWithURL:pageURL |
| 1358 stateObject:stateObject]; | 1367 stateObject:stateObject]; |
| 1359 _webStateImpl->OnSameDocumentNavigation(pageURL); | 1368 std::unique_ptr<web::NavigationContext> context = |
| 1369 web::NavigationContextImpl::CreateSameDocumentNavigationContext( |
| 1370 _webStateImpl, pageURL); |
| 1371 _webStateImpl->OnNavigationFinished(context.get()); |
| 1360 } | 1372 } |
| 1361 | 1373 |
| 1362 - (void)setDocumentURL:(const GURL&)newURL { | 1374 - (void)setDocumentURL:(const GURL&)newURL { |
| 1363 if (newURL != _documentURL && newURL.is_valid()) { | 1375 if (newURL != _documentURL && newURL.is_valid()) { |
| 1364 _documentURL = newURL; | 1376 _documentURL = newURL; |
| 1365 _interactionRegisteredSinceLastURLChange = NO; | 1377 _interactionRegisteredSinceLastURLChange = NO; |
| 1366 } | 1378 } |
| 1367 } | 1379 } |
| 1368 | 1380 |
| 1369 - (void)setNavigationItemTitle:(NSString*)title { | 1381 - (void)setNavigationItemTitle:(NSString*)title { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1519 // Typically on PAGE_TRANSITION_CLIENT_REDIRECT. | 1531 // Typically on PAGE_TRANSITION_CLIENT_REDIRECT. |
| 1520 [[self sessionController] updatePendingItem:requestURL]; | 1532 [[self sessionController] updatePendingItem:requestURL]; |
| 1521 } else { | 1533 } else { |
| 1522 // A new session history entry needs to be created. | 1534 // A new session history entry needs to be created. |
| 1523 self.navigationManagerImpl->AddPendingItem( | 1535 self.navigationManagerImpl->AddPendingItem( |
| 1524 requestURL, referrer, transition, | 1536 requestURL, referrer, transition, |
| 1525 web::NavigationInitiationType::RENDERER_INITIATED, | 1537 web::NavigationInitiationType::RENDERER_INITIATED, |
| 1526 web::NavigationManager::UserAgentOverrideOption::INHERIT); | 1538 web::NavigationManager::UserAgentOverrideOption::INHERIT); |
| 1527 } | 1539 } |
| 1528 std::unique_ptr<web::NavigationContextImpl> context = | 1540 std::unique_ptr<web::NavigationContextImpl> context = |
| 1529 web::NavigationContextImpl::CreateNavigationContext( | 1541 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, |
| 1530 _webStateImpl, requestURL, nullptr /* response_headers */); | 1542 requestURL); |
| 1531 _webStateImpl->SetIsLoading(true); | 1543 _webStateImpl->SetIsLoading(true); |
| 1532 // TODO(crbug.com/713836): pass context to |OnProvisionalNavigationStarted|. | 1544 // TODO(crbug.com/713836): pass context to |OnProvisionalNavigationStarted|. |
| 1533 _webStateImpl->OnProvisionalNavigationStarted(requestURL); | 1545 _webStateImpl->OnProvisionalNavigationStarted(requestURL); |
| 1534 return context; | 1546 return context; |
| 1535 } | 1547 } |
| 1536 | 1548 |
| 1537 - (void)updateHTML5HistoryState { | 1549 - (void)updateHTML5HistoryState { |
| 1538 web::NavigationItemImpl* currentItem = self.currentNavItem; | 1550 web::NavigationItemImpl* currentItem = self.currentNavItem; |
| 1539 if (!currentItem) | 1551 if (!currentItem) |
| 1540 return; | 1552 return; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1754 holder->set_http_method([_pendingNavigationInfo HTTPMethod]); | 1766 holder->set_http_method([_pendingNavigationInfo HTTPMethod]); |
| 1755 | 1767 |
| 1756 // Only update the MIME type in the holder if there was MIME type information | 1768 // Only update the MIME type in the holder if there was MIME type information |
| 1757 // as part of this pending load. It will be nil when doing a fast | 1769 // as part of this pending load. It will be nil when doing a fast |
| 1758 // back/forward navigation, for instance, because the callback that would | 1770 // back/forward navigation, for instance, because the callback that would |
| 1759 // populate it is not called in that flow. | 1771 // populate it is not called in that flow. |
| 1760 if ([_pendingNavigationInfo MIMEType]) | 1772 if ([_pendingNavigationInfo MIMEType]) |
| 1761 holder->set_mime_type([_pendingNavigationInfo MIMEType]); | 1773 holder->set_mime_type([_pendingNavigationInfo MIMEType]); |
| 1762 } | 1774 } |
| 1763 | 1775 |
| 1764 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess { | 1776 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess |
| 1777 navigationContext:(web::NavigationContextImpl*)context { |
| 1765 const GURL currentURL([self currentURL]); | 1778 const GURL currentURL([self currentURL]); |
| 1766 [self didStartLoadingURL:currentURL]; | 1779 [self didStartLoadingURL:currentURL]; |
| 1767 _loadPhase = web::PAGE_LOADED; | 1780 _loadPhase = web::PAGE_LOADED; |
| 1768 if (loadSuccess) { | 1781 _webStateImpl->OnNavigationFinished(context); |
| 1769 _webStateImpl->OnNavigationCommitted(currentURL); | |
| 1770 } else { | |
| 1771 _webStateImpl->OnErrorPageNavigation(currentURL); | |
| 1772 } | |
| 1773 | 1782 |
| 1774 // Perform post-load-finished updates. | 1783 // Perform post-load-finished updates. |
| 1775 [self didFinishWithURL:currentURL loadSuccess:loadSuccess]; | 1784 [self didFinishWithURL:currentURL loadSuccess:loadSuccess]; |
| 1776 | 1785 |
| 1777 NSString* title = [self.nativeController title]; | 1786 NSString* title = [self.nativeController title]; |
| 1778 if (title) { | 1787 if (title) { |
| 1779 [self setNavigationItemTitle:title]; | 1788 [self setNavigationItemTitle:title]; |
| 1780 } | 1789 } |
| 1781 | 1790 |
| 1782 if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { | 1791 if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { |
| 1783 [self.nativeController setDelegate:self]; | 1792 [self.nativeController setDelegate:self]; |
| 1784 } | 1793 } |
| 1785 } | 1794 } |
| 1786 | 1795 |
| 1787 - (void)loadErrorInNativeView:(NSError*)error { | 1796 - (void)loadErrorInNativeView:(NSError*)error |
| 1797 navigationContext:(web::NavigationContextImpl*)context { |
| 1788 [self removeWebViewAllowingCachedReconstruction:NO]; | 1798 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 1789 web::NavigationItem* item = self.currentNavItem; | 1799 web::NavigationItem* item = self.currentNavItem; |
| 1790 const GURL currentURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1800 const GURL currentURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1791 | 1801 |
| 1792 if (web::IsWKWebViewSSLCertError(error)) { | 1802 if (web::IsWKWebViewSSLCertError(error)) { |
| 1793 // This could happen only if certificate is absent or could not be parsed. | 1803 // This could happen only if certificate is absent or could not be parsed. |
| 1794 error = web::NetErrorFromError(error, net::ERR_SSL_SERVER_CERT_BAD_FORMAT); | 1804 error = web::NetErrorFromError(error, net::ERR_SSL_SERVER_CERT_BAD_FORMAT); |
| 1795 #if defined(DEBUG) | 1805 #if defined(DEBUG) |
| 1796 net::SSLInfo info; | 1806 net::SSLInfo info; |
| 1797 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); | 1807 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); |
| 1798 CHECK(!error.cert); | 1808 CHECK(!error.cert); |
| 1799 #endif | 1809 #endif |
| 1800 } else { | 1810 } else { |
| 1801 error = web::NetErrorFromError(error); | 1811 error = web::NetErrorFromError(error); |
| 1802 } | 1812 } |
| 1803 | 1813 |
| 1804 BOOL isPost = [self isCurrentNavigationItemPOST]; | 1814 BOOL isPost = [self isCurrentNavigationItemPOST]; |
| 1805 [self setNativeController:[_nativeProvider controllerForURL:currentURL | 1815 [self setNativeController:[_nativeProvider controllerForURL:currentURL |
| 1806 withError:error | 1816 withError:error |
| 1807 isPost:isPost]]; | 1817 isPost:isPost]]; |
| 1808 [self loadNativeViewWithSuccess:NO]; | 1818 [self loadNativeViewWithSuccess:NO navigationContext:context]; |
| 1809 } | 1819 } |
| 1810 | 1820 |
| 1811 // Load the current URL in a native controller, retrieved from the native | 1821 // Loads the current URL in a native controller, retrieved from the native |
| 1812 // provider. Call |loadNativeViewWithSuccess:YES| to load the native controller. | 1822 // provider. |
| 1813 - (void)loadCurrentURLInNativeView { | 1823 - (void)loadCurrentURLInNativeView { |
| 1814 // Free the web view. | 1824 // Free the web view. |
| 1815 [self removeWebViewAllowingCachedReconstruction:NO]; | 1825 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 1816 | 1826 |
| 1817 web::NavigationItem* item = self.currentNavItem; | 1827 web::NavigationItem* item = self.currentNavItem; |
| 1818 const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); | 1828 const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 1819 const web::Referrer referrer; | 1829 const web::Referrer referrer; |
| 1820 id<CRWNativeContent> nativeContent = | 1830 id<CRWNativeContent> nativeContent = |
| 1821 [_nativeProvider controllerForURL:targetURL webState:self.webState]; | 1831 [_nativeProvider controllerForURL:targetURL webState:self.webState]; |
| 1822 // Unlike the WebView case, always create a new controller and view. | 1832 // Unlike the WebView case, always create a new controller and view. |
| 1823 // TODO(pinkerton): What to do if this does return nil? | 1833 // TODO(pinkerton): What to do if this does return nil? |
| 1824 [self setNativeController:nativeContent]; | 1834 [self setNativeController:nativeContent]; |
| 1825 if ([nativeContent respondsToSelector:@selector(virtualURL)]) { | 1835 if ([nativeContent respondsToSelector:@selector(virtualURL)]) { |
| 1826 item->SetVirtualURL([nativeContent virtualURL]); | 1836 item->SetVirtualURL([nativeContent virtualURL]); |
| 1827 } | 1837 } |
| 1828 | 1838 |
| 1829 std::unique_ptr<web::NavigationContextImpl> navigationContext = | 1839 std::unique_ptr<web::NavigationContextImpl> navigationContext = |
| 1830 [self registerLoadRequestForURL:targetURL | 1840 [self registerLoadRequestForURL:targetURL |
| 1831 referrer:referrer | 1841 referrer:referrer |
| 1832 transition:self.currentTransition]; | 1842 transition:self.currentTransition]; |
| 1833 [self loadNativeViewWithSuccess:YES]; | 1843 [self loadNativeViewWithSuccess:YES |
| 1844 navigationContext:navigationContext.get()]; |
| 1834 } | 1845 } |
| 1835 | 1846 |
| 1836 - (void)loadWithParams:(const NavigationManager::WebLoadParams&)params { | 1847 - (void)loadWithParams:(const NavigationManager::WebLoadParams&)params { |
| 1837 DCHECK(!(params.transition_type & ui::PAGE_TRANSITION_FORWARD_BACK)); | 1848 DCHECK(!(params.transition_type & ui::PAGE_TRANSITION_FORWARD_BACK)); |
| 1838 | 1849 |
| 1839 // Clear transient view before making any changes to history and navigation | 1850 // Clear transient view before making any changes to history and navigation |
| 1840 // manager. TODO(stuartmorgan): Drive Transient Item clearing from | 1851 // manager. TODO(stuartmorgan): Drive Transient Item clearing from |
| 1841 // navigation system, rather than from WebController. | 1852 // navigation system, rather than from WebController. |
| 1842 [self clearTransientContentView]; | 1853 [self clearTransientContentView]; |
| 1843 | 1854 |
| (...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3167 // Reset SSL status to default, unless the load was cancelled (manually or by | 3178 // Reset SSL status to default, unless the load was cancelled (manually or by |
| 3168 // back-forward navigation). | 3179 // back-forward navigation). |
| 3169 web::NavigationManager* navManager = self.webState->GetNavigationManager(); | 3180 web::NavigationManager* navManager = self.webState->GetNavigationManager(); |
| 3170 if (navManager->GetLastCommittedItem() && [error code] != NSURLErrorCancelled) | 3181 if (navManager->GetLastCommittedItem() && [error code] != NSURLErrorCancelled) |
| 3171 navManager->GetLastCommittedItem()->GetSSL() = web::SSLStatus(); | 3182 navManager->GetLastCommittedItem()->GetSSL() = web::SSLStatus(); |
| 3172 | 3183 |
| 3173 NSURL* errorURL = [NSURL | 3184 NSURL* errorURL = [NSURL |
| 3174 URLWithString:[userInfo objectForKey:NSURLErrorFailingURLStringErrorKey]]; | 3185 URLWithString:[userInfo objectForKey:NSURLErrorFailingURLStringErrorKey]]; |
| 3175 const GURL errorGURL = net::GURLWithNSURL(errorURL); | 3186 const GURL errorGURL = net::GURLWithNSURL(errorURL); |
| 3176 | 3187 |
| 3188 web::NavigationContextImpl* navigationContext = |
| 3189 [_navigationStates contextForNavigation:navigation]; |
| 3190 navigationContext->SetIsErrorPage(true); |
| 3191 |
| 3177 // Handles Frame Load Interrupted errors from WebView. | 3192 // Handles Frame Load Interrupted errors from WebView. |
| 3178 if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)] && | 3193 if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)] && |
| 3179 error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) { | 3194 error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) { |
| 3180 // See if the delegate wants to handle this case. | 3195 // See if the delegate wants to handle this case. |
| 3181 if (errorGURL.is_valid() && | 3196 if (errorGURL.is_valid() && |
| 3182 [_delegate | 3197 [_delegate |
| 3183 respondsToSelector:@selector( | 3198 respondsToSelector:@selector( |
| 3184 controllerForUnhandledContentAtURL:)]) { | 3199 controllerForUnhandledContentAtURL:)]) { |
| 3185 id<CRWNativeContent> controller = | 3200 id<CRWNativeContent> controller = |
| 3186 [_delegate controllerForUnhandledContentAtURL:errorGURL]; | 3201 [_delegate controllerForUnhandledContentAtURL:errorGURL]; |
| 3187 if (controller) { | 3202 if (controller) { |
| 3188 [self loadCompleteWithSuccess:NO forNavigation:navigation]; | 3203 [self loadCompleteWithSuccess:NO forNavigation:navigation]; |
| 3189 [self removeWebViewAllowingCachedReconstruction:NO]; | 3204 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 3190 [self setNativeController:controller]; | 3205 [self setNativeController:controller]; |
| 3191 [self loadNativeViewWithSuccess:YES]; | 3206 [self loadNativeViewWithSuccess:YES |
| 3207 navigationContext:navigationContext]; |
| 3192 return; | 3208 return; |
| 3193 } | 3209 } |
| 3194 } | 3210 } |
| 3195 | 3211 |
| 3196 // Ignore errors that originate from URLs that are opened in external apps. | 3212 // Ignore errors that originate from URLs that are opened in external apps. |
| 3197 if ([_openedApplicationURL containsObject:errorURL]) | 3213 if ([_openedApplicationURL containsObject:errorURL]) |
| 3198 return; | 3214 return; |
| 3199 // Certain frame errors don't have URL information for some reason; for | 3215 // Certain frame errors don't have URL information for some reason; for |
| 3200 // those cases (so far the only known case is plugin content loaded directly | 3216 // those cases (so far the only known case is plugin content loaded directly |
| 3201 // in a frame) just ignore the error. See crbug.com/414295 | 3217 // in a frame) just ignore the error. See crbug.com/414295 |
| 3202 if (!errorURL) { | 3218 if (!errorURL) { |
| 3203 DCHECK(!inMainFrame); | 3219 DCHECK(!inMainFrame); |
| 3204 return; | 3220 return; |
| 3205 } | 3221 } |
| 3206 // The wrapper error uses the URL of the error and not the requested URL | 3222 // The wrapper error uses the URL of the error and not the requested URL |
| 3207 // (which can be different in case of a redirect) to match desktop Chrome | 3223 // (which can be different in case of a redirect) to match desktop Chrome |
| 3208 // behavior. | 3224 // behavior. |
| 3209 NSError* wrapperError = [NSError | 3225 NSError* wrapperError = [NSError |
| 3210 errorWithDomain:[error domain] | 3226 errorWithDomain:[error domain] |
| 3211 code:[error code] | 3227 code:[error code] |
| 3212 userInfo:@{ | 3228 userInfo:@{ |
| 3213 NSURLErrorFailingURLStringErrorKey : [errorURL absoluteString], | 3229 NSURLErrorFailingURLStringErrorKey : [errorURL absoluteString], |
| 3214 NSUnderlyingErrorKey : error | 3230 NSUnderlyingErrorKey : error |
| 3215 }]; | 3231 }]; |
| 3216 [self loadCompleteWithSuccess:NO forNavigation:navigation]; | 3232 [self loadCompleteWithSuccess:NO forNavigation:navigation]; |
| 3217 [self loadErrorInNativeView:wrapperError]; | 3233 [self loadErrorInNativeView:wrapperError |
| 3234 navigationContext:navigationContext]; |
| 3218 return; | 3235 return; |
| 3219 } | 3236 } |
| 3220 | 3237 |
| 3221 if ([error code] == NSURLErrorCancelled) { | 3238 if ([error code] == NSURLErrorCancelled) { |
| 3222 [self handleCancelledError:error]; | 3239 [self handleCancelledError:error]; |
| 3223 // NSURLErrorCancelled errors that aren't handled by aborting the load will | 3240 // NSURLErrorCancelled errors that aren't handled by aborting the load will |
| 3224 // automatically be retried by the web view, so early return in this case. | 3241 // automatically be retried by the web view, so early return in this case. |
| 3225 return; | 3242 return; |
| 3226 } | 3243 } |
| 3227 | 3244 |
| 3228 [self loadCompleteWithSuccess:NO forNavigation:navigation]; | 3245 [self loadCompleteWithSuccess:NO forNavigation:navigation]; |
| 3229 [self loadErrorInNativeView:error]; | 3246 [self loadErrorInNativeView:error navigationContext:navigationContext]; |
| 3230 } | 3247 } |
| 3231 | 3248 |
| 3232 - (void)handleCancelledError:(NSError*)error { | 3249 - (void)handleCancelledError:(NSError*)error { |
| 3233 if ([self shouldCancelLoadForCancelledError:error]) { | 3250 if ([self shouldCancelLoadForCancelledError:error]) { |
| 3234 [self loadCancelled]; | 3251 [self loadCancelled]; |
| 3235 [[self sessionController] discardNonCommittedItems]; | 3252 [[self sessionController] discardNonCommittedItems]; |
| 3236 } | 3253 } |
| 3237 } | 3254 } |
| 3238 | 3255 |
| 3239 - (BOOL)shouldCancelLoadForCancelledError:(NSError*)error { | 3256 - (BOOL)shouldCancelLoadForCancelledError:(NSError*)error { |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4205 | 4222 |
| 4206 // Web View should not be created for App Specific URLs. | 4223 // Web View should not be created for App Specific URLs. |
| 4207 if (!web::GetWebClient()->IsAppSpecificURL(URL)) { | 4224 if (!web::GetWebClient()->IsAppSpecificURL(URL)) { |
| 4208 [self ensureWebViewCreated]; | 4225 [self ensureWebViewCreated]; |
| 4209 DCHECK(_webView) << "_webView null while trying to load HTML"; | 4226 DCHECK(_webView) << "_webView null while trying to load HTML"; |
| 4210 } | 4227 } |
| 4211 WKNavigation* navigation = | 4228 WKNavigation* navigation = |
| 4212 [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; | 4229 [_webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; |
| 4213 [_navigationStates setState:web::WKNavigationState::REQUESTED | 4230 [_navigationStates setState:web::WKNavigationState::REQUESTED |
| 4214 forNavigation:navigation]; | 4231 forNavigation:navigation]; |
| 4232 std::unique_ptr<web::NavigationContextImpl> context = |
| 4233 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, URL); |
| 4234 [_navigationStates setContext:std::move(context) forNavigation:navigation]; |
| 4215 } | 4235 } |
| 4216 | 4236 |
| 4217 - (void)loadHTML:(NSString*)HTML forAppSpecificURL:(const GURL&)URL { | 4237 - (void)loadHTML:(NSString*)HTML forAppSpecificURL:(const GURL&)URL { |
| 4218 CHECK(web::GetWebClient()->IsAppSpecificURL(URL)); | 4238 CHECK(web::GetWebClient()->IsAppSpecificURL(URL)); |
| 4219 [self loadHTML:HTML forURL:URL]; | 4239 [self loadHTML:HTML forURL:URL]; |
| 4220 } | 4240 } |
| 4221 | 4241 |
| 4222 - (void)loadHTMLForCurrentURL:(NSString*)HTML { | 4242 - (void)loadHTMLForCurrentURL:(NSString*)HTML { |
| 4223 [self loadHTML:HTML forURL:self.currentURL]; | 4243 [self loadHTML:HTML forURL:self.currentURL]; |
| 4224 } | 4244 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4487 // dangerous. | 4507 // dangerous. |
| 4488 if (web::GetWebClient()->IsAppSpecificURL(_documentURL)) { | 4508 if (web::GetWebClient()->IsAppSpecificURL(_documentURL)) { |
| 4489 [self abortLoad]; | 4509 [self abortLoad]; |
| 4490 NavigationManager::WebLoadParams params(webViewURL); | 4510 NavigationManager::WebLoadParams params(webViewURL); |
| 4491 [self loadWithParams:params]; | 4511 [self loadWithParams:params]; |
| 4492 } | 4512 } |
| 4493 return; | 4513 return; |
| 4494 } else { | 4514 } else { |
| 4495 std::unique_ptr<web::NavigationContextImpl> navigationContext = | 4515 std::unique_ptr<web::NavigationContextImpl> navigationContext = |
| 4496 [self registerLoadRequestForURL:webViewURL]; | 4516 [self registerLoadRequestForURL:webViewURL]; |
| 4517 [_navigationStates setContext:std::move(navigationContext) |
| 4518 forNavigation:navigation]; |
| 4497 } | 4519 } |
| 4498 } | 4520 } |
| 4499 | 4521 |
| 4500 // Ensure the URL is registered and loadPhase is as expected. | 4522 // Ensure the URL is registered and loadPhase is as expected. |
| 4501 DCHECK(_lastRegisteredRequestURL == webViewURL); | 4523 DCHECK(_lastRegisteredRequestURL == webViewURL); |
| 4502 DCHECK(self.loadPhase == web::LOAD_REQUESTED); | 4524 DCHECK(self.loadPhase == web::LOAD_REQUESTED); |
| 4503 } | 4525 } |
| 4504 | 4526 |
| 4505 - (void)webView:(WKWebView*)webView | 4527 - (void)webView:(WKWebView*)webView |
| 4506 didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { | 4528 didReceiveServerRedirectForProvisionalNavigation:(WKNavigation*)navigation { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4630 // TODO(crbug.com/712269): | 4652 // TODO(crbug.com/712269): |
| 4631 for (int i = 0; i < self.navigationManagerImpl->GetItemCount(); i++) { | 4653 for (int i = 0; i < self.navigationManagerImpl->GetItemCount(); i++) { |
| 4632 web::NavigationItem* item = self.navigationManagerImpl->GetItemAtIndex(i); | 4654 web::NavigationItem* item = self.navigationManagerImpl->GetItemAtIndex(i); |
| 4633 if (item->GetURL() == _documentURL) { | 4655 if (item->GetURL() == _documentURL) { |
| 4634 // Do not discard pending entry, because another pending navigation is | 4656 // Do not discard pending entry, because another pending navigation is |
| 4635 // still in progress and will commit or fail soon. | 4657 // still in progress and will commit or fail soon. |
| 4636 [self.sessionController goToItemAtIndex:i discardNonCommittedItems:NO]; | 4658 [self.sessionController goToItemAtIndex:i discardNonCommittedItems:NO]; |
| 4637 } | 4659 } |
| 4638 } | 4660 } |
| 4639 } | 4661 } |
| 4640 self.webStateImpl->OnNavigationCommitted(_documentURL); | 4662 |
| 4663 web::NavigationContextImpl* context = |
| 4664 [_navigationStates contextForNavigation:navigation]; |
| 4665 context->SetResponseHeaders(_webStateImpl->GetHttpResponseHeaders()); |
| 4666 self.webStateImpl->OnNavigationFinished(context); |
| 4641 | 4667 |
| 4642 [self updateSSLStatusForCurrentNavigationItem]; | 4668 [self updateSSLStatusForCurrentNavigationItem]; |
| 4643 | 4669 |
| 4644 // Attempt to update the HTML5 history state. | 4670 // Attempt to update the HTML5 history state. |
| 4645 [self updateHTML5HistoryState]; | 4671 [self updateHTML5HistoryState]; |
| 4646 | 4672 |
| 4647 // This is the point where pending entry has been committed, and navigation | 4673 // This is the point where pending entry has been committed, and navigation |
| 4648 // item title should be updated. | 4674 // item title should be updated. |
| 4649 [self setNavigationItemTitle:[_webView title]]; | 4675 [self setNavigationItemTitle:[_webView title]]; |
| 4650 | 4676 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4822 } | 4848 } |
| 4823 | 4849 |
| 4824 if (!navigationWasCommitted && ![_pendingNavigationInfo cancelled]) { | 4850 if (!navigationWasCommitted && ![_pendingNavigationInfo cancelled]) { |
| 4825 // A fast back/forward within the same origin does not call | 4851 // A fast back/forward within the same origin does not call |
| 4826 // |didCommitNavigation:|, so signal page change explicitly. | 4852 // |didCommitNavigation:|, so signal page change explicitly. |
| 4827 DCHECK_EQ(_documentURL.GetOrigin(), webViewURL.GetOrigin()); | 4853 DCHECK_EQ(_documentURL.GetOrigin(), webViewURL.GetOrigin()); |
| 4828 BOOL isSameDocumentNavigation = | 4854 BOOL isSameDocumentNavigation = |
| 4829 [self isKVOChangePotentialSameDocumentNavigationToURL:webViewURL]; | 4855 [self isKVOChangePotentialSameDocumentNavigationToURL:webViewURL]; |
| 4830 [self setDocumentURL:webViewURL]; | 4856 [self setDocumentURL:webViewURL]; |
| 4831 [self webPageChanged]; | 4857 [self webPageChanged]; |
| 4832 if (isSameDocumentNavigation) { | 4858 |
| 4833 _webStateImpl->OnSameDocumentNavigation(webViewURL); | 4859 // Same document navigation does not contain response headers. |
| 4834 } else { | 4860 std::unique_ptr<web::NavigationContextImpl> context = |
| 4835 _webStateImpl->OnNavigationCommitted(webViewURL); | 4861 web::NavigationContextImpl::CreateNavigationContext(_webStateImpl, |
| 4836 } | 4862 webViewURL); |
| 4863 net::HttpResponseHeaders* headers = |
| 4864 isSameDocumentNavigation ? nullptr |
| 4865 : _webStateImpl->GetHttpResponseHeaders(); |
| 4866 context->SetResponseHeaders(headers); |
| 4867 context->SetIsSameDocument(isSameDocumentNavigation); |
| 4868 _webStateImpl->OnNavigationFinished(context.get()); |
| 4837 } | 4869 } |
| 4838 | 4870 |
| 4839 [self updateSSLStatusForCurrentNavigationItem]; | 4871 [self updateSSLStatusForCurrentNavigationItem]; |
| 4840 | 4872 |
| 4841 // Fast back forward navigation may not call |didFinishNavigation:|, so | 4873 // Fast back forward navigation may not call |didFinishNavigation:|, so |
| 4842 // signal did finish navigation explicitly. | 4874 // signal did finish navigation explicitly. |
| 4843 if (_lastRegisteredRequestURL == _documentURL) { | 4875 if (_lastRegisteredRequestURL == _documentURL) { |
| 4844 [self didFinishNavigation:nil]; | 4876 [self didFinishNavigation:nil]; |
| 4845 } | 4877 } |
| 4846 } | 4878 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4975 // the next runloop. | 5007 // the next runloop. |
| 4976 // | 5008 // |
| 4977 // Otherwise, simulate the whole delegate flow for a load (since the | 5009 // Otherwise, simulate the whole delegate flow for a load (since the |
| 4978 // superclass currently doesn't have a clean separation between URL changes | 5010 // superclass currently doesn't have a clean separation between URL changes |
| 4979 // and document changes). Note that the order of these calls is important: | 5011 // and document changes). Note that the order of these calls is important: |
| 4980 // registering a load request logically comes before updating the document | 5012 // registering a load request logically comes before updating the document |
| 4981 // URL, but also must come first since it uses state that is reset on URL | 5013 // URL, but also must come first since it uses state that is reset on URL |
| 4982 // changes. | 5014 // changes. |
| 4983 std::unique_ptr<web::NavigationContextImpl> navigationContext; | 5015 std::unique_ptr<web::NavigationContextImpl> navigationContext; |
| 4984 if (!_changingHistoryState) { | 5016 if (!_changingHistoryState) { |
| 4985 // If this wasn't a previously-expected load (e.g., certain back/forward | 5017 if ([self isLoadRequestPendingForURL:newURL]) { |
| 4986 // navigations), register the load request. | 5018 // |loadWithParams:| was called with URL that has different fragment |
| 4987 if (![self isLoadRequestPendingForURL:newURL]) | 5019 // comparing to the orevious URL. |
| 5020 // TODO(crbug.com/713836): Instead of creating a new context, find |
| 5021 // existing navigation context stored in |_navigationStates| and use it. |
| 5022 navigationContext = web::NavigationContextImpl::CreateNavigationContext( |
| 5023 _webStateImpl, newURL); |
| 5024 } else { |
| 5025 // This could be: |
| 5026 // 1.) Renderer-initiated fragment change |
| 5027 // 2.) Assigning same-origin URL to window.location |
| 5028 // 3.) Incorrectly handled window.location.replace (crbug.com/307072) |
| 5029 // 4.) Back-forward same document navigation |
| 4988 navigationContext = [self registerLoadRequestForURL:newURL]; | 5030 navigationContext = [self registerLoadRequestForURL:newURL]; |
| 5031 } |
| 5032 navigationContext->SetIsSameDocument(true); |
| 4989 } | 5033 } |
| 4990 | 5034 |
| 4991 [self setDocumentURL:newURL]; | 5035 [self setDocumentURL:newURL]; |
| 4992 | 5036 |
| 4993 if (!_changingHistoryState) { | 5037 if (!_changingHistoryState) { |
| 4994 [self didStartLoadingURL:_documentURL]; | 5038 [self didStartLoadingURL:_documentURL]; |
| 4995 _webStateImpl->OnSameDocumentNavigation(newURL); | 5039 _webStateImpl->OnNavigationFinished(navigationContext.get()); |
| 4996 [self updateSSLStatusForCurrentNavigationItem]; | 5040 [self updateSSLStatusForCurrentNavigationItem]; |
| 4997 [self didFinishNavigation:nil]; | 5041 [self didFinishNavigation:nil]; |
| 4998 } | 5042 } |
| 4999 } | 5043 } |
| 5000 | 5044 |
| 5001 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL { | 5045 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL { |
| 5002 if (self.loadPhase != web::LOAD_REQUESTED) | 5046 if (self.loadPhase != web::LOAD_REQUESTED) |
| 5003 return NO; | 5047 return NO; |
| 5004 | 5048 |
| 5005 web::NavigationItem* pendingItem = | 5049 web::NavigationItem* pendingItem = |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5032 if (POSTData.length && !repostedForm) { | 5076 if (POSTData.length && !repostedForm) { |
| 5033 [request setHTTPMethod:@"POST"]; | 5077 [request setHTTPMethod:@"POST"]; |
| 5034 [request setHTTPBody:POSTData]; | 5078 [request setHTTPBody:POSTData]; |
| 5035 [request setAllHTTPHeaderFields:self.currentHTTPHeaders]; | 5079 [request setAllHTTPHeaderFields:self.currentHTTPHeaders]; |
| 5036 GURL navigationURL = | 5080 GURL navigationURL = |
| 5037 currentItem ? currentItem->GetURL() : GURL::EmptyGURL(); | 5081 currentItem ? currentItem->GetURL() : GURL::EmptyGURL(); |
| 5038 std::unique_ptr<web::NavigationContextImpl> navigationContext = | 5082 std::unique_ptr<web::NavigationContextImpl> navigationContext = |
| 5039 [self registerLoadRequestForURL:navigationURL | 5083 [self registerLoadRequestForURL:navigationURL |
| 5040 referrer:self.currentNavItemReferrer | 5084 referrer:self.currentNavItemReferrer |
| 5041 transition:self.currentTransition]; | 5085 transition:self.currentTransition]; |
| 5042 [self loadPOSTRequest:request]; | 5086 WKNavigation* navigation = [self loadPOSTRequest:request]; |
| 5087 [_navigationStates setContext:std::move(navigationContext) |
| 5088 forNavigation:navigation]; |
| 5043 return; | 5089 return; |
| 5044 } | 5090 } |
| 5045 | 5091 |
| 5046 ProceduralBlock defaultNavigationBlock = ^{ | 5092 ProceduralBlock defaultNavigationBlock = ^{ |
| 5047 web::NavigationItem* item = self.currentNavItem; | 5093 web::NavigationItem* item = self.currentNavItem; |
| 5048 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); | 5094 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 5049 std::unique_ptr<web::NavigationContextImpl> navigationContext = | 5095 std::unique_ptr<web::NavigationContextImpl> navigationContext = |
| 5050 [self registerLoadRequestForURL:navigationURL | 5096 [self registerLoadRequestForURL:navigationURL |
| 5051 referrer:self.currentNavItemReferrer | 5097 referrer:self.currentNavItemReferrer |
| 5052 transition:self.currentTransition]; | 5098 transition:self.currentTransition]; |
| 5053 [self loadRequest:request]; | 5099 WKNavigation* navigation = [self loadRequest:request]; |
| 5100 [_navigationStates setContext:std::move(navigationContext) |
| 5101 forNavigation:navigation]; |
| 5054 [self reportBackForwardNavigationTypeForFastNavigation:NO]; | 5102 [self reportBackForwardNavigationTypeForFastNavigation:NO]; |
| 5055 }; | 5103 }; |
| 5056 | 5104 |
| 5057 // When navigating via WKBackForwardListItem to pages created or updated by | 5105 // When navigating via WKBackForwardListItem to pages created or updated by |
| 5058 // calls to pushState() and replaceState(), sometimes web_bundle.js is not | 5106 // calls to pushState() and replaceState(), sometimes web_bundle.js is not |
| 5059 // injected correctly. This means that calling window.history navigation | 5107 // injected correctly. This means that calling window.history navigation |
| 5060 // functions will invoke WKWebView's non-overridden implementations, causing a | 5108 // functions will invoke WKWebView's non-overridden implementations, causing a |
| 5061 // mismatch between the WKBackForwardList and NavigationManager. | 5109 // mismatch between the WKBackForwardList and NavigationManager. |
| 5062 // TODO(crbug.com/659816): Figure out how to prevent web_bundle.js injection | 5110 // TODO(crbug.com/659816): Figure out how to prevent web_bundle.js injection |
| 5063 // flake. | 5111 // flake. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5094 } else { | 5142 } else { |
| 5095 // |didCommitNavigation:| may not be called for fast navigation, so update | 5143 // |didCommitNavigation:| may not be called for fast navigation, so update |
| 5096 // the navigation type now as it is already known. | 5144 // the navigation type now as it is already known. |
| 5097 holder->set_navigation_type(WKNavigationTypeBackForward); | 5145 holder->set_navigation_type(WKNavigationTypeBackForward); |
| 5098 navigation = | 5146 navigation = |
| 5099 [_webView goToBackForwardListItem:holder->back_forward_list_item()]; | 5147 [_webView goToBackForwardListItem:holder->back_forward_list_item()]; |
| 5100 [self reportBackForwardNavigationTypeForFastNavigation:YES]; | 5148 [self reportBackForwardNavigationTypeForFastNavigation:YES]; |
| 5101 } | 5149 } |
| 5102 [_navigationStates setState:web::WKNavigationState::REQUESTED | 5150 [_navigationStates setState:web::WKNavigationState::REQUESTED |
| 5103 forNavigation:navigation]; | 5151 forNavigation:navigation]; |
| 5152 [_navigationStates setContext:std::move(navigationContext) |
| 5153 forNavigation:navigation]; |
| 5104 }; | 5154 }; |
| 5105 | 5155 |
| 5106 // If the request is not a form submission or resubmission, or the user | 5156 // If the request is not a form submission or resubmission, or the user |
| 5107 // doesn't need to confirm the load, then continue right away. | 5157 // doesn't need to confirm the load, then continue right away. |
| 5108 | 5158 |
| 5109 if (!repostedForm || currentItem->ShouldSkipRepostFormConfirmation()) { | 5159 if (!repostedForm || currentItem->ShouldSkipRepostFormConfirmation()) { |
| 5110 webViewNavigationBlock(); | 5160 webViewNavigationBlock(); |
| 5111 return; | 5161 return; |
| 5112 } | 5162 } |
| 5113 | 5163 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5200 - (NSUInteger)observerCount { | 5250 - (NSUInteger)observerCount { |
| 5201 DCHECK_EQ(_observerBridges.size(), [_observers count]); | 5251 DCHECK_EQ(_observerBridges.size(), [_observers count]); |
| 5202 return [_observers count]; | 5252 return [_observers count]; |
| 5203 } | 5253 } |
| 5204 | 5254 |
| 5205 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5255 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
| 5206 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5256 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
| 5207 } | 5257 } |
| 5208 | 5258 |
| 5209 @end | 5259 @end |
| OLD | NEW |