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 <objc/runtime.h> | 7 #import <objc/runtime.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 // Each observer in |_observers| is associated with a | 262 // Each observer in |_observers| is associated with a |
263 // WebControllerObserverBridge in order to listen from WebState callbacks. | 263 // WebControllerObserverBridge in order to listen from WebState callbacks. |
264 // TODO(droger): Remove |_observerBridges| when all CRWWebControllerObservers | 264 // TODO(droger): Remove |_observerBridges| when all CRWWebControllerObservers |
265 // are converted to WebStateObservers. | 265 // are converted to WebStateObservers. |
266 ScopedVector<web::WebControllerObserverBridge> _observerBridges; | 266 ScopedVector<web::WebControllerObserverBridge> _observerBridges; |
267 // |windowId| that is saved when a page changes. Used to detect refreshes. | 267 // |windowId| that is saved when a page changes. Used to detect refreshes. |
268 base::scoped_nsobject<NSString> _lastSeenWindowID; | 268 base::scoped_nsobject<NSString> _lastSeenWindowID; |
269 // YES if a user interaction has been registered at any time once the page has | 269 // YES if a user interaction has been registered at any time once the page has |
270 // loaded. | 270 // loaded. |
271 BOOL _userInteractionRegistered; | 271 BOOL _userInteractionRegistered; |
| 272 // YES if the user has interacted with the content area since the last URL |
| 273 // change. |
| 274 BOOL _interactionRegisteredSinceLastURLChange; |
| 275 // The actual URL of the document object (i.e., the last committed URL). |
| 276 // TODO(crbug.com/549616): Remove this in favor of just updating the |
| 277 // navigation manager and treating that as authoritative. |
| 278 GURL _documentURL; |
272 // Last URL change reported to webWill/DidStartLoadingURL. Used to detect page | 279 // Last URL change reported to webWill/DidStartLoadingURL. Used to detect page |
273 // location changes (client redirects) in practice. | 280 // location changes (client redirects) in practice. |
274 GURL _lastRegisteredRequestURL; | 281 GURL _lastRegisteredRequestURL; |
275 // Last URL change reported to webDidStartLoadingURL. Used to detect page | 282 // Last URL change reported to webDidStartLoadingURL. Used to detect page |
276 // location changes in practice. | 283 // location changes in practice. |
277 GURL _URLOnStartLoading; | 284 GURL _URLOnStartLoading; |
278 // Page loading phase. | 285 // Page loading phase. |
279 web::LoadPhase _loadPhase; | 286 web::LoadPhase _loadPhase; |
280 // The web::PageDisplayState recorded when the page starts loading. | 287 // The web::PageDisplayState recorded when the page starts loading. |
281 web::PageDisplayState _displayStateOnStartLoading; | 288 web::PageDisplayState _displayStateOnStartLoading; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 // Returns a new autoreleased web view created with given configuration. | 467 // Returns a new autoreleased web view created with given configuration. |
461 - (WKWebView*)createWebViewWithConfiguration:(WKWebViewConfiguration*)config; | 468 - (WKWebView*)createWebViewWithConfiguration:(WKWebViewConfiguration*)config; |
462 // Sets the value of the webView property, and performs its basic setup. | 469 // Sets the value of the webView property, and performs its basic setup. |
463 - (void)setWebView:(WKWebView*)webView; | 470 - (void)setWebView:(WKWebView*)webView; |
464 // Destroys the web view by setting webView property to nil. | 471 // Destroys the web view by setting webView property to nil. |
465 - (void)resetWebView; | 472 - (void)resetWebView; |
466 // Returns the WKWebViewConfigurationProvider associated with the web | 473 // Returns the WKWebViewConfigurationProvider associated with the web |
467 // controller's BrowserState. | 474 // controller's BrowserState. |
468 - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider; | 475 - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider; |
469 | 476 |
| 477 // Returns the current URL of the web view, and sets |trustLevel| accordingly |
| 478 // based on the confidence in the verification. |
| 479 - (GURL)webURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel; |
470 // Returns |YES| if |url| should be loaded in a native view. | 480 // Returns |YES| if |url| should be loaded in a native view. |
471 - (BOOL)shouldLoadURLInNativeView:(const GURL&)url; | 481 - (BOOL)shouldLoadURLInNativeView:(const GURL&)url; |
472 // Loads the HTML into the page at the given URL. | 482 // Loads the HTML into the page at the given URL. |
473 - (void)loadHTML:(NSString*)html forURL:(const GURL&)url; | 483 - (void)loadHTML:(NSString*)html forURL:(const GURL&)url; |
474 // Loads the current nativeController in a native view. If a web view is | 484 // Loads the current nativeController in a native view. If a web view is |
475 // present, removes it and swaps in the native view in its place. | 485 // present, removes it and swaps in the native view in its place. |
476 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess; | 486 - (void)loadNativeViewWithSuccess:(BOOL)loadSuccess; |
477 // YES if the navigation to |url| should be treated as a reload. | 487 // YES if the navigation to |url| should be treated as a reload. |
478 - (BOOL)shouldReload:(const GURL&)destinationURL | 488 - (BOOL)shouldReload:(const GURL&)destinationURL |
479 transition:(ui::PageTransition)transition; | 489 transition:(ui::PageTransition)transition; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 // stack. A state object is a serialized generic JavaScript object that contains | 580 // stack. A state object is a serialized generic JavaScript object that contains |
571 // details of the UI's state for a given CRWSessionEntry/URL. | 581 // details of the UI's state for a given CRWSessionEntry/URL. |
572 // TODO(stuartmorgan): Move the pushState/replaceState logic into | 582 // TODO(stuartmorgan): Move the pushState/replaceState logic into |
573 // NavigationManager. | 583 // NavigationManager. |
574 - (void)pushStateWithPageURL:(const GURL&)pageURL | 584 - (void)pushStateWithPageURL:(const GURL&)pageURL |
575 stateObject:(NSString*)stateObject | 585 stateObject:(NSString*)stateObject |
576 transition:(ui::PageTransition)transition; | 586 transition:(ui::PageTransition)transition; |
577 // Assigns the given URL and state object to the current CRWSessionEntry. | 587 // Assigns the given URL and state object to the current CRWSessionEntry. |
578 - (void)replaceStateWithPageURL:(const GURL&)pageUrl | 588 - (void)replaceStateWithPageURL:(const GURL&)pageUrl |
579 stateObject:(NSString*)stateObject; | 589 stateObject:(NSString*)stateObject; |
| 590 // Sets _documentURL to newURL, and updates any relevant state information. |
| 591 - (void)setDocumentURL:(const GURL&)newURL; |
580 // Returns YES if the current navigation item corresponds to a web page | 592 // Returns YES if the current navigation item corresponds to a web page |
581 // loaded by a POST request. | 593 // loaded by a POST request. |
582 - (BOOL)isCurrentNavigationItemPOST; | 594 - (BOOL)isCurrentNavigationItemPOST; |
583 // Returns whether the given navigation is triggered by a user link click. | 595 // Returns whether the given navigation is triggered by a user link click. |
584 - (BOOL)isLinkNavigation:(WKNavigationType)navigationType; | 596 - (BOOL)isLinkNavigation:(WKNavigationType)navigationType; |
585 | 597 |
586 // Finds all the scrollviews in the view hierarchy and makes sure they do not | 598 // Finds all the scrollviews in the view hierarchy and makes sure they do not |
587 // interfere with scroll to top when tapping the statusbar. | 599 // interfere with scroll to top when tapping the statusbar. |
588 - (void)optOutScrollsToTopForSubviews; | 600 - (void)optOutScrollsToTopForSubviews; |
589 // Tears down the old native controller, and then replaces it with the new one. | 601 // Tears down the old native controller, and then replaces it with the new one. |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1358 self.userInteractionRegistered = NO; | 1370 self.userInteractionRegistered = NO; |
1359 } | 1371 } |
1360 | 1372 |
1361 - (void)replaceStateWithPageURL:(const GURL&)pageUrl | 1373 - (void)replaceStateWithPageURL:(const GURL&)pageUrl |
1362 stateObject:(NSString*)stateObject { | 1374 stateObject:(NSString*)stateObject { |
1363 [[self sessionController] updateCurrentEntryWithURL:pageUrl | 1375 [[self sessionController] updateCurrentEntryWithURL:pageUrl |
1364 stateObject:stateObject]; | 1376 stateObject:stateObject]; |
1365 [self didUpdateHistoryStateWithPageURL:pageUrl]; | 1377 [self didUpdateHistoryStateWithPageURL:pageUrl]; |
1366 } | 1378 } |
1367 | 1379 |
| 1380 - (void)setDocumentURL:(const GURL&)newURL { |
| 1381 if (newURL != _documentURL) { |
| 1382 _documentURL = newURL; |
| 1383 _interactionRegisteredSinceLastURLChange = NO; |
| 1384 } |
| 1385 } |
| 1386 |
1368 - (BOOL)isCurrentNavigationItemPOST { | 1387 - (BOOL)isCurrentNavigationItemPOST { |
1369 // |_pendingNavigationInfo| will be nil if the decidePolicy* delegate methods | 1388 // |_pendingNavigationInfo| will be nil if the decidePolicy* delegate methods |
1370 // were not called. | 1389 // were not called. |
1371 WKNavigationType type = | 1390 WKNavigationType type = |
1372 _pendingNavigationInfo | 1391 _pendingNavigationInfo |
1373 ? [_pendingNavigationInfo navigationType] | 1392 ? [_pendingNavigationInfo navigationType] |
1374 : [self currentBackForwardListItemHolder]->navigation_type(); | 1393 : [self currentBackForwardListItemHolder]->navigation_type(); |
1375 return type == WKNavigationTypeFormSubmitted || | 1394 return type == WKNavigationTypeFormSubmitted || |
1376 type == WKNavigationTypeFormResubmitted; | 1395 type == WKNavigationTypeFormResubmitted; |
1377 } | 1396 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1565 transition = ui::PAGE_TRANSITION_FORWARD_BACK; | 1584 transition = ui::PAGE_TRANSITION_FORWARD_BACK; |
1566 break; | 1585 break; |
1567 case WKNavigationTypeReload: | 1586 case WKNavigationTypeReload: |
1568 transition = ui::PAGE_TRANSITION_RELOAD; | 1587 transition = ui::PAGE_TRANSITION_RELOAD; |
1569 break; | 1588 break; |
1570 case WKNavigationTypeOther: | 1589 case WKNavigationTypeOther: |
1571 // The "Other" type covers a variety of very different cases, which may | 1590 // The "Other" type covers a variety of very different cases, which may |
1572 // or may not be the result of user actions. For now, guess based on | 1591 // or may not be the result of user actions. For now, guess based on |
1573 // whether there's been an interaction since the last URL change. | 1592 // whether there's been an interaction since the last URL change. |
1574 // TODO(crbug.com/549301): See if this heuristic can be improved. | 1593 // TODO(crbug.com/549301): See if this heuristic can be improved. |
1575 transition = self.interactionRegisteredSinceLastURLChange | 1594 transition = _interactionRegisteredSinceLastURLChange |
1576 ? ui::PAGE_TRANSITION_LINK | 1595 ? ui::PAGE_TRANSITION_LINK |
1577 : ui::PAGE_TRANSITION_CLIENT_REDIRECT; | 1596 : ui::PAGE_TRANSITION_CLIENT_REDIRECT; |
1578 break; | 1597 break; |
1579 } | 1598 } |
1580 // The referrer is not known yet, and will be updated later. | 1599 // The referrer is not known yet, and will be updated later. |
1581 const web::Referrer emptyReferrer; | 1600 const web::Referrer emptyReferrer; |
1582 [self registerLoadRequest:URL referrer:emptyReferrer transition:transition]; | 1601 [self registerLoadRequest:URL referrer:emptyReferrer transition:transition]; |
1583 } | 1602 } |
1584 | 1603 |
1585 - (void)registerLoadRequest:(const GURL&)requestURL | 1604 - (void)registerLoadRequest:(const GURL&)requestURL |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 [self loadCurrentURLInNativeView]; | 1959 [self loadCurrentURLInNativeView]; |
1941 } else { | 1960 } else { |
1942 [self loadCurrentURLInWebView]; | 1961 [self loadCurrentURLInWebView]; |
1943 } | 1962 } |
1944 | 1963 |
1945 // Once a URL has been loaded, any cached-based reconstruction state has | 1964 // Once a URL has been loaded, any cached-based reconstruction state has |
1946 // either been handled or obsoleted. | 1965 // either been handled or obsoleted. |
1947 _expectedReconstructionURL = GURL(); | 1966 _expectedReconstructionURL = GURL(); |
1948 } | 1967 } |
1949 | 1968 |
| 1969 - (GURL)webURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel { |
| 1970 DCHECK(trustLevel); |
| 1971 *trustLevel = web::URLVerificationTrustLevel::kAbsolute; |
| 1972 return _documentURL; |
| 1973 } |
| 1974 |
1950 - (BOOL)shouldLoadURLInNativeView:(const GURL&)url { | 1975 - (BOOL)shouldLoadURLInNativeView:(const GURL&)url { |
1951 // App-specific URLs that don't require WebUI are loaded in native views. | 1976 // App-specific URLs that don't require WebUI are loaded in native views. |
1952 return web::GetWebClient()->IsAppSpecificURL(url) && | 1977 return web::GetWebClient()->IsAppSpecificURL(url) && |
1953 !_webStateImpl->HasWebUI(); | 1978 !_webStateImpl->HasWebUI(); |
1954 } | 1979 } |
1955 | 1980 |
1956 - (void)triggerPendingLoad { | 1981 - (void)triggerPendingLoad { |
1957 if (!self.containerView) { | 1982 if (!self.containerView) { |
1958 DCHECK(!_isBeingDestroyed); | 1983 DCHECK(!_isBeingDestroyed); |
1959 // Create the top-level parent view, which will contain the content (whether | 1984 // Create the top-level parent view, which will contain the content (whether |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3153 } | 3178 } |
3154 | 3179 |
3155 + (BOOL)webControllerCanShow:(const GURL&)url { | 3180 + (BOOL)webControllerCanShow:(const GURL&)url { |
3156 return web::UrlHasWebScheme(url) || | 3181 return web::UrlHasWebScheme(url) || |
3157 web::GetWebClient()->IsAppSpecificURL(url) || | 3182 web::GetWebClient()->IsAppSpecificURL(url) || |
3158 url.SchemeIs(url::kFileScheme) || url.SchemeIs(url::kAboutScheme); | 3183 url.SchemeIs(url::kFileScheme) || url.SchemeIs(url::kAboutScheme); |
3159 } | 3184 } |
3160 | 3185 |
3161 - (void)setUserInteractionRegistered:(BOOL)flag { | 3186 - (void)setUserInteractionRegistered:(BOOL)flag { |
3162 _userInteractionRegistered = flag; | 3187 _userInteractionRegistered = flag; |
| 3188 if (flag) |
| 3189 _interactionRegisteredSinceLastURLChange = YES; |
3163 } | 3190 } |
3164 | 3191 |
3165 - (BOOL)userInteractionRegistered { | 3192 - (BOOL)userInteractionRegistered { |
3166 return _userInteractionRegistered; | 3193 return _userInteractionRegistered; |
3167 } | 3194 } |
3168 | 3195 |
3169 - (BOOL)useDesktopUserAgent { | 3196 - (BOOL)useDesktopUserAgent { |
3170 web::NavigationItem* item = [self currentNavItem]; | 3197 web::NavigationItem* item = [self currentNavItem]; |
3171 return item && item->IsOverridingUserAgent(); | 3198 return item && item->IsOverridingUserAgent(); |
3172 } | 3199 } |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4369 return; | 4396 return; |
4370 } | 4397 } |
4371 | 4398 |
4372 if (!_SSLStatusUpdater) { | 4399 if (!_SSLStatusUpdater) { |
4373 _SSLStatusUpdater.reset([[CRWSSLStatusUpdater alloc] | 4400 _SSLStatusUpdater.reset([[CRWSSLStatusUpdater alloc] |
4374 initWithDataSource:self | 4401 initWithDataSource:self |
4375 navigationManager:navManager | 4402 navigationManager:navManager |
4376 certGroupID:self.certGroupID]); | 4403 certGroupID:self.certGroupID]); |
4377 [_SSLStatusUpdater setDelegate:self]; | 4404 [_SSLStatusUpdater setDelegate:self]; |
4378 } | 4405 } |
4379 NSString* host = base::SysUTF8ToNSString(self.documentURL.host()); | 4406 NSString* host = base::SysUTF8ToNSString(_documentURL.host()); |
4380 NSArray* certChain = [self.webView certificateChain]; | 4407 NSArray* certChain = [self.webView certificateChain]; |
4381 BOOL hasOnlySecureContent = [self.webView hasOnlySecureContent]; | 4408 BOOL hasOnlySecureContent = [self.webView hasOnlySecureContent]; |
4382 [_SSLStatusUpdater updateSSLStatusForNavigationItem:currentNavItem | 4409 [_SSLStatusUpdater updateSSLStatusForNavigationItem:currentNavItem |
4383 withCertHost:host | 4410 withCertHost:host |
4384 certChain:certChain | 4411 certChain:certChain |
4385 hasOnlySecureContent:hasOnlySecureContent]; | 4412 hasOnlySecureContent:hasOnlySecureContent]; |
4386 } | 4413 } |
4387 | 4414 |
4388 - (void)didUpdateSSLStatusForCurrentNavigationItem { | 4415 - (void)didUpdateSSLStatusForCurrentNavigationItem { |
4389 if ([_delegate respondsToSelector: | 4416 if ([_delegate respondsToSelector: |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4875 DCHECK_EQ(self.webView, webView); | 4902 DCHECK_EQ(self.webView, webView); |
4876 _certVerificationErrors->Clear(); | 4903 _certVerificationErrors->Clear(); |
4877 // This point should closely approximate the document object change, so reset | 4904 // This point should closely approximate the document object change, so reset |
4878 // the list of injected scripts to those that are automatically injected. | 4905 // the list of injected scripts to those that are automatically injected. |
4879 [self clearInjectedScriptManagers]; | 4906 [self clearInjectedScriptManagers]; |
4880 [self injectWindowID]; | 4907 [self injectWindowID]; |
4881 | 4908 |
4882 // This is the point where the document's URL has actually changed, and | 4909 // This is the point where the document's URL has actually changed, and |
4883 // pending navigation information should be applied to state information. | 4910 // pending navigation information should be applied to state information. |
4884 [self setDocumentURL:net::GURLWithNSURL([self.webView URL])]; | 4911 [self setDocumentURL:net::GURLWithNSURL([self.webView URL])]; |
4885 DCHECK(self.documentURL == self.lastRegisteredRequestURL); | 4912 DCHECK(_documentURL == self.lastRegisteredRequestURL); |
4886 self.webStateImpl->OnNavigationCommitted(self.documentURL); | 4913 self.webStateImpl->OnNavigationCommitted(_documentURL); |
4887 [self commitPendingNavigationInfo]; | 4914 [self commitPendingNavigationInfo]; |
4888 if ([self currentBackForwardListItemHolder]->navigation_type() == | 4915 if ([self currentBackForwardListItemHolder]->navigation_type() == |
4889 WKNavigationTypeBackForward) { | 4916 WKNavigationTypeBackForward) { |
4890 // A fast back/forward won't call decidePolicyForNavigationResponse, so | 4917 // A fast back/forward won't call decidePolicyForNavigationResponse, so |
4891 // the MIME type needs to be updated explicitly. | 4918 // the MIME type needs to be updated explicitly. |
4892 NSString* storedMIMEType = | 4919 NSString* storedMIMEType = |
4893 [self currentBackForwardListItemHolder]->mime_type(); | 4920 [self currentBackForwardListItemHolder]->mime_type(); |
4894 if (storedMIMEType) { | 4921 if (storedMIMEType) { |
4895 self.webStateImpl->SetContentsMimeType( | 4922 self.webStateImpl->SetContentsMimeType( |
4896 base::SysNSStringToUTF8(storedMIMEType)); | 4923 base::SysNSStringToUTF8(storedMIMEType)); |
4897 } | 4924 } |
4898 } | 4925 } |
4899 [self webPageChanged]; | 4926 [self webPageChanged]; |
4900 | 4927 |
4901 [self updateSSLStatusForCurrentNavigationItem]; | 4928 [self updateSSLStatusForCurrentNavigationItem]; |
4902 | 4929 |
4903 // Report cases where SSL cert is missing for a secure connection. | 4930 // Report cases where SSL cert is missing for a secure connection. |
4904 if (self.documentURL.SchemeIsCryptographic()) { | 4931 if (_documentURL.SchemeIsCryptographic()) { |
4905 scoped_refptr<net::X509Certificate> cert = | 4932 scoped_refptr<net::X509Certificate> cert = |
4906 web::CreateCertFromChain([self.webView certificateChain]); | 4933 web::CreateCertFromChain([self.webView certificateChain]); |
4907 UMA_HISTOGRAM_BOOLEAN("WebController.WKWebViewHasCertForSecureConnection", | 4934 UMA_HISTOGRAM_BOOLEAN("WebController.WKWebViewHasCertForSecureConnection", |
4908 cert); | 4935 cert); |
4909 } | 4936 } |
4910 } | 4937 } |
4911 | 4938 |
4912 - (void)webView:(WKWebView*)webView | 4939 - (void)webView:(WKWebView*)webView |
4913 didFinishNavigation:(WKNavigation*)navigation { | 4940 didFinishNavigation:(WKNavigation*)navigation { |
4914 DCHECK(!self.isHalted); | 4941 DCHECK(!self.isHalted); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5090 // could be a same-page navigation (in which case there may not be any other | 5117 // could be a same-page navigation (in which case there may not be any other |
5091 // callback about the URL having changed), then check the actual page URL via | 5118 // callback about the URL having changed), then check the actual page URL via |
5092 // JavaScript. If the origin of the new URL matches the last committed URL, | 5119 // JavaScript. If the origin of the new URL matches the last committed URL, |
5093 // then check window.location.href, and if it matches, trust it. The origin | 5120 // then check window.location.href, and if it matches, trust it. The origin |
5094 // check ensures that if a site somehow corrupts window.location.href it can't | 5121 // check ensures that if a site somehow corrupts window.location.href it can't |
5095 // do a redirect to a slow-loading target page while it is still loading to | 5122 // do a redirect to a slow-loading target page while it is still loading to |
5096 // spoof the origin. On a document-changing URL change, the | 5123 // spoof the origin. On a document-changing URL change, the |
5097 // window.location.href will match the previous URL at this stage, not the web | 5124 // window.location.href will match the previous URL at this stage, not the web |
5098 // view's current URL. | 5125 // view's current URL. |
5099 if (![self.webView isLoading]) { | 5126 if (![self.webView isLoading]) { |
5100 if (self.documentURL == URL) | 5127 if (_documentURL == URL) |
5101 return; | 5128 return; |
5102 [self URLDidChangeWithoutDocumentChange:URL]; | 5129 [self URLDidChangeWithoutDocumentChange:URL]; |
5103 } else if ([self isKVOChangePotentialSameDocumentNavigationToURL:URL]) { | 5130 } else if ([self isKVOChangePotentialSameDocumentNavigationToURL:URL]) { |
5104 [self.webView | 5131 [self.webView |
5105 evaluateJavaScript:@"window.location.href" | 5132 evaluateJavaScript:@"window.location.href" |
5106 completionHandler:^(id result, NSError* error) { | 5133 completionHandler:^(id result, NSError* error) { |
5107 // If the web view has gone away, or the location | 5134 // If the web view has gone away, or the location |
5108 // couldn't be retrieved, abort. | 5135 // couldn't be retrieved, abort. |
5109 if (!self.webView || ![result isKindOfClass:[NSString class]]) { | 5136 if (!self.webView || ![result isKindOfClass:[NSString class]]) { |
5110 return; | 5137 return; |
5111 } | 5138 } |
5112 GURL JSURL([result UTF8String]); | 5139 GURL JSURL([result UTF8String]); |
5113 // Check that window.location matches the new URL. If | 5140 // Check that window.location matches the new URL. If |
5114 // it does not, this is a document-changing URL change as | 5141 // it does not, this is a document-changing URL change as |
5115 // the window location would not have changed to the new | 5142 // the window location would not have changed to the new |
5116 // URL when the script was called. | 5143 // URL when the script was called. |
5117 BOOL windowLocationMatchesNewURL = JSURL == URL; | 5144 BOOL windowLocationMatchesNewURL = JSURL == URL; |
5118 // Re-check origin in case navigaton has occured since | 5145 // Re-check origin in case navigaton has occured since |
5119 // start of JavaScript evaluation. | 5146 // start of JavaScript evaluation. |
5120 BOOL newURLOriginMatchesDocumentURLOrigin = | 5147 BOOL newURLOriginMatchesDocumentURLOrigin = |
5121 self.documentURL.GetOrigin() == URL.GetOrigin(); | 5148 _documentURL.GetOrigin() == URL.GetOrigin(); |
5122 // Check that the web view URL still matches the new URL. | 5149 // Check that the web view URL still matches the new URL. |
5123 // TODO(crbug.com/563568): webViewURLMatchesNewURL check | 5150 // TODO(crbug.com/563568): webViewURLMatchesNewURL check |
5124 // may drop same document URL changes if pending URL | 5151 // may drop same document URL changes if pending URL |
5125 // change occurs immediately after. Revisit heuristics to | 5152 // change occurs immediately after. Revisit heuristics to |
5126 // prevent this. | 5153 // prevent this. |
5127 BOOL webViewURLMatchesNewURL = | 5154 BOOL webViewURLMatchesNewURL = |
5128 net::GURLWithNSURL([self.webView URL]) == URL; | 5155 net::GURLWithNSURL([self.webView URL]) == URL; |
5129 // Check that the new URL is different from the current | 5156 // Check that the new URL is different from the current |
5130 // document URL. If not, URL change should not be reported. | 5157 // document URL. If not, URL change should not be reported. |
5131 BOOL URLDidChangeFromDocumentURL = URL != self.documentURL; | 5158 BOOL URLDidChangeFromDocumentURL = URL != _documentURL; |
5132 if (windowLocationMatchesNewURL && | 5159 if (windowLocationMatchesNewURL && |
5133 newURLOriginMatchesDocumentURLOrigin && | 5160 newURLOriginMatchesDocumentURLOrigin && |
5134 webViewURLMatchesNewURL && URLDidChangeFromDocumentURL) { | 5161 webViewURLMatchesNewURL && URLDidChangeFromDocumentURL) { |
5135 [self URLDidChangeWithoutDocumentChange:URL]; | 5162 [self URLDidChangeWithoutDocumentChange:URL]; |
5136 } | 5163 } |
5137 }]; | 5164 }]; |
5138 } | 5165 } |
5139 } | 5166 } |
5140 | 5167 |
5141 - (BOOL)isKVOChangePotentialSameDocumentNavigationToURL:(const GURL&)newURL { | 5168 - (BOOL)isKVOChangePotentialSameDocumentNavigationToURL:(const GURL&)newURL { |
5142 DCHECK([self.webView isLoading]); | 5169 DCHECK([self.webView isLoading]); |
5143 // If the origin changes, it can't be same-document. | 5170 // If the origin changes, it can't be same-document. |
5144 if (self.documentURL.GetOrigin().is_empty() || | 5171 if (_documentURL.GetOrigin().is_empty() || |
5145 self.documentURL.GetOrigin() != newURL.GetOrigin()) { | 5172 _documentURL.GetOrigin() != newURL.GetOrigin()) { |
5146 return NO; | 5173 return NO; |
5147 } | 5174 } |
5148 if (self.loadPhase == web::LOAD_REQUESTED) { | 5175 if (self.loadPhase == web::LOAD_REQUESTED) { |
5149 // Normally LOAD_REQUESTED indicates that this is a regular, pending | 5176 // Normally LOAD_REQUESTED indicates that this is a regular, pending |
5150 // navigation, but it can also happen during a fast-back navigation across | 5177 // navigation, but it can also happen during a fast-back navigation across |
5151 // a hash change, so that case is potentially a same-document navigation. | 5178 // a hash change, so that case is potentially a same-document navigation. |
5152 return web::GURLByRemovingRefFromGURL(newURL) == | 5179 return web::GURLByRemovingRefFromGURL(newURL) == |
5153 web::GURLByRemovingRefFromGURL(self.documentURL); | 5180 web::GURLByRemovingRefFromGURL(_documentURL); |
5154 } | 5181 } |
5155 // If it passes all the checks above, it might be (but there's no guarantee | 5182 // If it passes all the checks above, it might be (but there's no guarantee |
5156 // that it is). | 5183 // that it is). |
5157 return YES; | 5184 return YES; |
5158 } | 5185 } |
5159 | 5186 |
5160 - (void)URLDidChangeWithoutDocumentChange:(const GURL&)newURL { | 5187 - (void)URLDidChangeWithoutDocumentChange:(const GURL&)newURL { |
5161 DCHECK(newURL == net::GURLWithNSURL([self.webView URL])); | 5188 DCHECK(newURL == net::GURLWithNSURL([self.webView URL])); |
5162 DCHECK_EQ(self.documentURL.host(), newURL.host()); | 5189 DCHECK_EQ(_documentURL.host(), newURL.host()); |
5163 DCHECK(self.documentURL != newURL); | 5190 DCHECK(_documentURL != newURL); |
5164 | 5191 |
5165 // If called during window.history.pushState or window.history.replaceState | 5192 // If called during window.history.pushState or window.history.replaceState |
5166 // JavaScript evaluation, only update the document URL. This callback does not | 5193 // JavaScript evaluation, only update the document URL. This callback does not |
5167 // have any information about the state object and cannot create (or edit) the | 5194 // have any information about the state object and cannot create (or edit) the |
5168 // navigation entry for this page change. Web controller will sync with | 5195 // navigation entry for this page change. Web controller will sync with |
5169 // history changes when a window.history.didPushState or | 5196 // history changes when a window.history.didPushState or |
5170 // window.history.didReplaceState message is received, which should happen in | 5197 // window.history.didReplaceState message is received, which should happen in |
5171 // the next runloop. | 5198 // the next runloop. |
5172 // | 5199 // |
5173 // Otherwise, simulate the whole delegate flow for a load (since the | 5200 // Otherwise, simulate the whole delegate flow for a load (since the |
5174 // superclass currently doesn't have a clean separation between URL changes | 5201 // superclass currently doesn't have a clean separation between URL changes |
5175 // and document changes). Note that the order of these calls is important: | 5202 // and document changes). Note that the order of these calls is important: |
5176 // registering a load request logically comes before updating the document | 5203 // registering a load request logically comes before updating the document |
5177 // URL, but also must come first since it uses state that is reset on URL | 5204 // URL, but also must come first since it uses state that is reset on URL |
5178 // changes. | 5205 // changes. |
5179 if (!self.changingHistoryState) { | 5206 if (!self.changingHistoryState) { |
5180 // If this wasn't a previously-expected load (e.g., certain back/forward | 5207 // If this wasn't a previously-expected load (e.g., certain back/forward |
5181 // navigations), register the load request. | 5208 // navigations), register the load request. |
5182 if (![self isLoadRequestPendingForURL:newURL]) | 5209 if (![self isLoadRequestPendingForURL:newURL]) |
5183 [self registerLoadRequest:newURL]; | 5210 [self registerLoadRequest:newURL]; |
5184 } | 5211 } |
5185 | 5212 |
5186 [self setDocumentURL:newURL]; | 5213 [self setDocumentURL:newURL]; |
5187 | 5214 |
5188 if (!self.changingHistoryState) { | 5215 if (!self.changingHistoryState) { |
5189 [self didStartLoadingURL:self.documentURL updateHistory:YES]; | 5216 [self didStartLoadingURL:_documentURL updateHistory:YES]; |
5190 [self updateSSLStatusForCurrentNavigationItem]; | 5217 [self updateSSLStatusForCurrentNavigationItem]; |
5191 [self didFinishNavigation]; | 5218 [self didFinishNavigation]; |
5192 } | 5219 } |
5193 } | 5220 } |
5194 | 5221 |
5195 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL { | 5222 - (BOOL)isLoadRequestPendingForURL:(const GURL&)targetURL { |
5196 if (self.loadPhase != web::LOAD_REQUESTED) | 5223 if (self.loadPhase != web::LOAD_REQUESTED) |
5197 return NO; | 5224 return NO; |
5198 | 5225 |
5199 web::NavigationItem* pendingItem = | 5226 web::NavigationItem* pendingItem = |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5314 } | 5341 } |
5315 | 5342 |
5316 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; | 5343 return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC; |
5317 } | 5344 } |
5318 | 5345 |
5319 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { | 5346 - (NSString*)refererFromNavigationAction:(WKNavigationAction*)action { |
5320 return [action.request valueForHTTPHeaderField:@"Referer"]; | 5347 return [action.request valueForHTTPHeaderField:@"Referer"]; |
5321 } | 5348 } |
5322 | 5349 |
5323 @end | 5350 @end |
OLD | NEW |