| 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 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 // an error if the returned URL is not reliable from a security point of view. | 469 // an error if the returned URL is not reliable from a security point of view. |
| 470 // Note that this method is expensive, so it should always be cached locally if | 470 // Note that this method is expensive, so it should always be cached locally if |
| 471 // it's needed multiple times in a method. | 471 // it's needed multiple times in a method. |
| 472 @property(nonatomic, readonly) GURL currentURL; | 472 @property(nonatomic, readonly) GURL currentURL; |
| 473 // Returns the referrer for the current page. | 473 // Returns the referrer for the current page. |
| 474 @property(nonatomic, readonly) web::Referrer currentReferrer; | 474 @property(nonatomic, readonly) web::Referrer currentReferrer; |
| 475 | 475 |
| 476 // Returns YES if the user interacted with the page recently. | 476 // Returns YES if the user interacted with the page recently. |
| 477 @property(nonatomic, readonly) BOOL userClickedRecently; | 477 @property(nonatomic, readonly) BOOL userClickedRecently; |
| 478 | 478 |
| 479 // Whether or not desktop user agent is used for the currentItem. | 479 // User agent type of the transient item if any, the pending item if a |
| 480 @property(nonatomic, readonly) BOOL usesDesktopUserAgent; | 480 // navigation is in progress or the last committed item otherwise. |
| 481 // Returns MOBILE, the default type, if navigation manager is nullptr or empty. |
| 482 @property(nonatomic, readonly) web::UserAgentType userAgentType; |
| 481 | 483 |
| 482 // Facade for Mojo API. | 484 // Facade for Mojo API. |
| 483 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; | 485 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; |
| 484 | 486 |
| 485 // TODO(crbug.com/692871): Remove these functions and replace with more | 487 // TODO(crbug.com/692871): Remove these functions and replace with more |
| 486 // appropriate NavigationItem getters. | 488 // appropriate NavigationItem getters. |
| 487 // Returns the navigation item for the current page. | 489 // Returns the navigation item for the current page. |
| 488 @property(nonatomic, readonly) web::NavigationItemImpl* currentNavItem; | 490 @property(nonatomic, readonly) web::NavigationItemImpl* currentNavItem; |
| 489 // Returns the current transition type. | 491 // Returns the current transition type. |
| 490 @property(nonatomic, readonly) ui::PageTransition currentTransition; | 492 @property(nonatomic, readonly) ui::PageTransition currentTransition; |
| 491 // Returns the referrer for current navigation item. May be empty. | 493 // Returns the referrer for current navigation item. May be empty. |
| 492 @property(nonatomic, readonly) web::Referrer currentNavItemReferrer; | 494 @property(nonatomic, readonly) web::Referrer currentNavItemReferrer; |
| 493 // The HTTP headers associated with the current navigation item. These are nil | 495 // The HTTP headers associated with the current navigation item. These are nil |
| 494 // unless the request was a POST. | 496 // unless the request was a POST. |
| 495 @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; | 497 @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; |
| 496 | 498 |
| 497 // Requires page reconstruction if |item| has a non-NONE UserAgentType and it | 499 // Updates web view's user agent according to |userAgentType|. It is no-op if |
| 498 // differs from that of |fromItem|. | 500 // |userAgentType| is NONE. |
| 499 - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item | 501 - (void)updateWebViewUserAgentFromUserAgentType: |
| 500 previousUserAgentType:(web::UserAgentType)userAgentType; | 502 (web::UserAgentType)userAgentType; |
| 503 |
| 504 // Requires that the next load rebuild the web view. This is expensive, and |
| 505 // should be used only in the case where something has changed that web view |
| 506 // only checks on creation, such that the whole object needs to be rebuilt. |
| 507 // TODO(stuartmorgan): Merge this and reinitializeWebViewAndReload:. They are |
| 508 // currently subtly different in terms of implementation, but are for |
| 509 // fundamentally the same purpose. |
| 510 - (void)requirePageReconstruction; |
| 501 | 511 |
| 502 // Removes the container view from the hierarchy and resets the ivar. | 512 // Removes the container view from the hierarchy and resets the ivar. |
| 503 - (void)resetContainerView; | 513 - (void)resetContainerView; |
| 504 // Called when the web page has changed document and/or URL, and so the page | 514 // Called when the web page has changed document and/or URL, and so the page |
| 505 // navigation should be reported to the delegate, and internal state updated to | 515 // navigation should be reported to the delegate, and internal state updated to |
| 506 // reflect the fact that the navigation has occurred. | 516 // reflect the fact that the navigation has occurred. |
| 507 // TODO(stuartmorgan): The code conflates URL changes and document object | 517 // TODO(stuartmorgan): The code conflates URL changes and document object |
| 508 // changes; the two need to be separated and handled differently. | 518 // changes; the two need to be separated and handled differently. |
| 509 - (void)webPageChanged; | 519 - (void)webPageChanged; |
| 510 // Resets any state that is associated with a specific document object (e.g., | 520 // Resets any state that is associated with a specific document object (e.g., |
| (...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1629 [self didFinishWithURL:targetURL loadSuccess:NO]; | 1639 [self didFinishWithURL:targetURL loadSuccess:NO]; |
| 1630 return; | 1640 return; |
| 1631 } | 1641 } |
| 1632 | 1642 |
| 1633 // JavaScript should never be evaluated here. User-entered JS should be | 1643 // JavaScript should never be evaluated here. User-entered JS should be |
| 1634 // evaluated via stringByEvaluatingUserJavaScriptFromString. | 1644 // evaluated via stringByEvaluatingUserJavaScriptFromString. |
| 1635 DCHECK(!targetURL.SchemeIs(url::kJavaScriptScheme)); | 1645 DCHECK(!targetURL.SchemeIs(url::kJavaScriptScheme)); |
| 1636 | 1646 |
| 1637 [self ensureWebViewCreated]; | 1647 [self ensureWebViewCreated]; |
| 1638 | 1648 |
| 1649 // Update web view's user agent is called for every load, which may have |
| 1650 // performance implications because update web view's user agent may |
| 1651 // potentially send a message to a separate thread. However, this is not an |
| 1652 // issue for WKWebView because WKWebView's |setCustomUserAgent| is non-op if |
| 1653 // user agent stays thesame. |
| 1654 [self updateWebViewUserAgentFromUserAgentType:self.userAgentType]; |
| 1655 |
| 1639 [self loadRequestForCurrentNavigationItem]; | 1656 [self loadRequestForCurrentNavigationItem]; |
| 1640 } | 1657 } |
| 1641 | 1658 |
| 1642 - (void)updatePendingNavigationInfoFromNavigationAction: | 1659 - (void)updatePendingNavigationInfoFromNavigationAction: |
| 1643 (WKNavigationAction*)action { | 1660 (WKNavigationAction*)action { |
| 1644 if (action.targetFrame.mainFrame) { | 1661 if (action.targetFrame.mainFrame) { |
| 1645 _pendingNavigationInfo.reset( | 1662 _pendingNavigationInfo.reset( |
| 1646 [[CRWWebControllerPendingNavigationInfo alloc] init]); | 1663 [[CRWWebControllerPendingNavigationInfo alloc] init]); |
| 1647 [_pendingNavigationInfo | 1664 [_pendingNavigationInfo |
| 1648 setReferrer:[self referrerFromNavigationAction:action]]; | 1665 setReferrer:[self referrerFromNavigationAction:action]]; |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2039 return; | 2056 return; |
| 2040 } | 2057 } |
| 2041 | 2058 |
| 2042 if (!_webStateImpl->IsShowingWebInterstitial()) | 2059 if (!_webStateImpl->IsShowingWebInterstitial()) |
| 2043 [self recordStateInHistory]; | 2060 [self recordStateInHistory]; |
| 2044 | 2061 |
| 2045 [self clearTransientContentView]; | 2062 [self clearTransientContentView]; |
| 2046 | 2063 |
| 2047 // Update the user agent before attempting the navigation. | 2064 // Update the user agent before attempting the navigation. |
| 2048 web::NavigationItem* toItem = items[index].get(); | 2065 web::NavigationItem* toItem = items[index].get(); |
| 2049 web::NavigationItem* previousItem = sessionController.currentItem; | 2066 [self updateWebViewUserAgentFromUserAgentType:toItem->GetUserAgentType()]; |
| 2050 web::UserAgentType previousUserAgentType = | |
| 2051 previousItem ? previousItem->GetUserAgentType() | |
| 2052 : web::UserAgentType::NONE; | |
| 2053 [self updateDesktopUserAgentForItem:toItem | |
| 2054 previousUserAgentType:previousUserAgentType]; | |
| 2055 | 2067 |
| 2068 web::NavigationItem* fromItem = sessionController.currentItem; |
| 2056 BOOL sameDocumentNavigation = | 2069 BOOL sameDocumentNavigation = |
| 2057 [sessionController isSameDocumentNavigationBetweenItem:previousItem | 2070 [sessionController isSameDocumentNavigationBetweenItem:fromItem |
| 2058 andItem:toItem]; | 2071 andItem:toItem]; |
| 2059 if (sameDocumentNavigation) { | 2072 if (sameDocumentNavigation) { |
| 2060 [sessionController goToItemAtIndex:index]; | 2073 [sessionController goToItemAtIndex:index]; |
| 2061 [self updateHTML5HistoryState]; | 2074 [self updateHTML5HistoryState]; |
| 2062 } else { | 2075 } else { |
| 2063 [sessionController discardNonCommittedItems]; | 2076 [sessionController discardNonCommittedItems]; |
| 2064 [sessionController setPendingItemIndex:index]; | 2077 [sessionController setPendingItemIndex:index]; |
| 2065 | 2078 |
| 2066 web::NavigationItemImpl* pendingItem = sessionController.pendingItem; | 2079 web::NavigationItemImpl* pendingItem = sessionController.pendingItem; |
| 2067 pendingItem->SetTransitionType(ui::PageTransitionFromInt( | 2080 pendingItem->SetTransitionType(ui::PageTransitionFromInt( |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 // The page should be closed if it was initiated by the DOM and there has been | 2215 // The page should be closed if it was initiated by the DOM and there has been |
| 2203 // no user interaction with the page since the web view was created, or if | 2216 // no user interaction with the page since the web view was created, or if |
| 2204 // the page has no navigation items, as occurs when an App Store link is | 2217 // the page has no navigation items, as occurs when an App Store link is |
| 2205 // opened from another application. | 2218 // opened from another application. |
| 2206 BOOL rendererInitiatedWithoutInteraction = | 2219 BOOL rendererInitiatedWithoutInteraction = |
| 2207 self.hasOpener && !_userInteractedWithWebController; | 2220 self.hasOpener && !_userInteractedWithWebController; |
| 2208 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); | 2221 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); |
| 2209 return rendererInitiatedWithoutInteraction || noNavigationItems; | 2222 return rendererInitiatedWithoutInteraction || noNavigationItems; |
| 2210 } | 2223 } |
| 2211 | 2224 |
| 2212 - (BOOL)usesDesktopUserAgent { | 2225 - (web::UserAgentType)userAgentType { |
| 2213 web::NavigationItem* item = self.currentNavItem; | 2226 web::NavigationItem* item = self.currentNavItem; |
| 2214 return item && item->GetUserAgentType() == web::UserAgentType::DESKTOP; | 2227 return item ? item->GetUserAgentType() : web::UserAgentType::MOBILE; |
| 2215 } | 2228 } |
| 2216 | 2229 |
| 2217 - (web::MojoFacade*)mojoFacade { | 2230 - (web::MojoFacade*)mojoFacade { |
| 2218 if (!_mojoFacade) { | 2231 if (!_mojoFacade) { |
| 2219 service_manager::mojom::InterfaceProvider* interfaceProvider = | 2232 service_manager::mojom::InterfaceProvider* interfaceProvider = |
| 2220 _webStateImpl->GetMojoInterfaceRegistry(); | 2233 _webStateImpl->GetMojoInterfaceRegistry(); |
| 2221 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); | 2234 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); |
| 2222 } | 2235 } |
| 2223 return _mojoFacade.get(); | 2236 return _mojoFacade.get(); |
| 2224 } | 2237 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2243 [delegate webController:strongSelf didLoadPassKitObject:data]; | 2256 [delegate webController:strongSelf didLoadPassKitObject:data]; |
| 2244 } | 2257 } |
| 2245 }; | 2258 }; |
| 2246 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); | 2259 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); |
| 2247 _passKitDownloader.reset([[CRWPassKitDownloader alloc] | 2260 _passKitDownloader.reset([[CRWPassKitDownloader alloc] |
| 2248 initWithContextGetter:browserState->GetRequestContext() | 2261 initWithContextGetter:browserState->GetRequestContext() |
| 2249 completionHandler:passKitCompletion]); | 2262 completionHandler:passKitCompletion]); |
| 2250 return _passKitDownloader.get(); | 2263 return _passKitDownloader.get(); |
| 2251 } | 2264 } |
| 2252 | 2265 |
| 2253 - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item | 2266 - (void)updateWebViewUserAgentFromUserAgentType: |
| 2254 previousUserAgentType:(web::UserAgentType)userAgentType { | 2267 (web::UserAgentType)userAgentType { |
| 2255 if (!item) | 2268 if (userAgentType == web::UserAgentType::NONE) |
| 2256 return; | 2269 return; |
| 2257 web::UserAgentType itemUserAgentType = item->GetUserAgentType(); | 2270 |
| 2258 if (itemUserAgentType == web::UserAgentType::NONE) | 2271 NSString* userAgent = |
| 2259 return; | 2272 base::SysUTF8ToNSString(web::GetWebClient()->GetUserAgent(userAgentType)); |
| 2260 if (itemUserAgentType != userAgentType) | 2273 [_webView setCustomUserAgent:userAgent]; |
| 2261 [self requirePageReconstruction]; | |
| 2262 } | 2274 } |
| 2263 | 2275 |
| 2264 #pragma mark - | 2276 #pragma mark - |
| 2265 #pragma mark CRWWebControllerContainerViewDelegate | 2277 #pragma mark CRWWebControllerContainerViewDelegate |
| 2266 | 2278 |
| 2267 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: | 2279 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: |
| 2268 (CRWWebControllerContainerView*)containerView { | 2280 (CRWWebControllerContainerView*)containerView { |
| 2269 return _webViewProxy.get(); | 2281 return _webViewProxy.get(); |
| 2270 } | 2282 } |
| 2271 | 2283 |
| (...skipping 1776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4048 scrollView:self.webScrollView]); | 4060 scrollView:self.webScrollView]); |
| 4049 [_containerView displayWebViewContentView:webViewContentView]; | 4061 [_containerView displayWebViewContentView:webViewContentView]; |
| 4050 } | 4062 } |
| 4051 } | 4063 } |
| 4052 | 4064 |
| 4053 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config { | 4065 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config { |
| 4054 // Do not attach the context menu controller immediately as the JavaScript | 4066 // Do not attach the context menu controller immediately as the JavaScript |
| 4055 // delegate must be specified. | 4067 // delegate must be specified. |
| 4056 return web::BuildWKWebView(CGRectZero, config, | 4068 return web::BuildWKWebView(CGRectZero, config, |
| 4057 self.webStateImpl->GetBrowserState(), | 4069 self.webStateImpl->GetBrowserState(), |
| 4058 self.usesDesktopUserAgent); | 4070 self.userAgentType); |
| 4059 } | 4071 } |
| 4060 | 4072 |
| 4061 - (void)setWebView:(WKWebView*)webView { | 4073 - (void)setWebView:(WKWebView*)webView { |
| 4062 DCHECK_NE(_webView.get(), webView); | 4074 DCHECK_NE(_webView.get(), webView); |
| 4063 | 4075 |
| 4064 // Unwind the old web view. | 4076 // Unwind the old web view. |
| 4065 // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is | 4077 // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is |
| 4066 // fixed. | 4078 // fixed. |
| 4067 CRWWKScriptMessageRouter* messageRouter = | 4079 CRWWKScriptMessageRouter* messageRouter = |
| 4068 [self webViewConfigurationProvider].GetScriptMessageRouter(); | 4080 [self webViewConfigurationProvider].GetScriptMessageRouter(); |
| (...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5112 - (void)simulateLoadRequestWithURL:(const GURL&)URL { | 5124 - (void)simulateLoadRequestWithURL:(const GURL&)URL { |
| 5113 _lastRegisteredRequestURL = URL; | 5125 _lastRegisteredRequestURL = URL; |
| 5114 _loadPhase = web::LOAD_REQUESTED; | 5126 _loadPhase = web::LOAD_REQUESTED; |
| 5115 } | 5127 } |
| 5116 | 5128 |
| 5117 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5129 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
| 5118 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5130 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
| 5119 } | 5131 } |
| 5120 | 5132 |
| 5121 @end | 5133 @end |
| OLD | NEW |