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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 // an error if the returned URL is not reliable from a security point of view. | 452 // an error if the returned URL is not reliable from a security point of view. |
453 // Note that this method is expensive, so it should always be cached locally if | 453 // Note that this method is expensive, so it should always be cached locally if |
454 // it's needed multiple times in a method. | 454 // it's needed multiple times in a method. |
455 @property(nonatomic, readonly) GURL currentURL; | 455 @property(nonatomic, readonly) GURL currentURL; |
456 // Returns the referrer for the current page. | 456 // Returns the referrer for the current page. |
457 @property(nonatomic, readonly) web::Referrer currentReferrer; | 457 @property(nonatomic, readonly) web::Referrer currentReferrer; |
458 | 458 |
459 // Returns YES if the user interacted with the page recently. | 459 // Returns YES if the user interacted with the page recently. |
460 @property(nonatomic, readonly) BOOL userClickedRecently; | 460 @property(nonatomic, readonly) BOOL userClickedRecently; |
461 | 461 |
462 // User agent type of the transient item if any, the pending item if a | 462 // Whether or not desktop user agent is used for the currentItem. |
463 // navigation is in progress or the last committed item otherwise. | 463 @property(nonatomic, readonly) BOOL usesDesktopUserAgent; |
464 // Returns MOBILE, the default type, if navigation manager is nullptr or empty. | |
465 @property(nonatomic, readonly) web::UserAgentType userAgentType; | |
466 | 464 |
467 // Facade for Mojo API. | 465 // Facade for Mojo API. |
468 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; | 466 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; |
469 | 467 |
470 // TODO(crbug.com/692871): Remove these functions and replace with more | 468 // TODO(crbug.com/692871): Remove these functions and replace with more |
471 // appropriate NavigationItem getters. | 469 // appropriate NavigationItem getters. |
472 // Returns the navigation item for the current page. | 470 // Returns the navigation item for the current page. |
473 @property(nonatomic, readonly) web::NavigationItemImpl* currentNavItem; | 471 @property(nonatomic, readonly) web::NavigationItemImpl* currentNavItem; |
474 // Returns the current transition type. | 472 // Returns the current transition type. |
475 @property(nonatomic, readonly) ui::PageTransition currentTransition; | 473 @property(nonatomic, readonly) ui::PageTransition currentTransition; |
476 // Returns the referrer for current navigation item. May be empty. | 474 // Returns the referrer for current navigation item. May be empty. |
477 @property(nonatomic, readonly) web::Referrer currentNavItemReferrer; | 475 @property(nonatomic, readonly) web::Referrer currentNavItemReferrer; |
478 // The HTTP headers associated with the current navigation item. These are nil | 476 // The HTTP headers associated with the current navigation item. These are nil |
479 // unless the request was a POST. | 477 // unless the request was a POST. |
480 @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; | 478 @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; |
481 | 479 |
482 // Updates web view's user agent according to |userAgentType|. It is no-op if | 480 // Requires page reconstruction if |item| has a non-NONE UserAgentType and it |
483 // |userAgentType| is NONE. | 481 // differs from that of |fromItem|. |
484 - (void)updateWebViewUserAgentFromUserAgentType: | 482 - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item |
485 (web::UserAgentType)userAgentType; | 483 previousUserAgentType:(web::UserAgentType)userAgentType; |
486 | |
487 // Requires that the next load rebuild the web view. This is expensive, and | |
488 // should be used only in the case where something has changed that web view | |
489 // only checks on creation, such that the whole object needs to be rebuilt. | |
490 // TODO(stuartmorgan): Merge this and reinitializeWebViewAndReload:. They are | |
491 // currently subtly different in terms of implementation, but are for | |
492 // fundamentally the same purpose. | |
493 - (void)requirePageReconstruction; | |
494 | 484 |
495 // Removes the container view from the hierarchy and resets the ivar. | 485 // Removes the container view from the hierarchy and resets the ivar. |
496 - (void)resetContainerView; | 486 - (void)resetContainerView; |
497 // Called when the web page has changed document and/or URL, and so the page | 487 // Called when the web page has changed document and/or URL, and so the page |
498 // navigation should be reported to the delegate, and internal state updated to | 488 // navigation should be reported to the delegate, and internal state updated to |
499 // reflect the fact that the navigation has occurred. | 489 // reflect the fact that the navigation has occurred. |
500 // TODO(stuartmorgan): The code conflates URL changes and document object | 490 // TODO(stuartmorgan): The code conflates URL changes and document object |
501 // changes; the two need to be separated and handled differently. | 491 // changes; the two need to be separated and handled differently. |
502 - (void)webPageChanged; | 492 - (void)webPageChanged; |
503 // Resets any state that is associated with a specific document object (e.g., | 493 // Resets any state that is associated with a specific document object (e.g., |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1619 [self didFinishWithURL:targetURL loadSuccess:NO]; | 1609 [self didFinishWithURL:targetURL loadSuccess:NO]; |
1620 return; | 1610 return; |
1621 } | 1611 } |
1622 | 1612 |
1623 // JavaScript should never be evaluated here. User-entered JS should be | 1613 // JavaScript should never be evaluated here. User-entered JS should be |
1624 // evaluated via stringByEvaluatingUserJavaScriptFromString. | 1614 // evaluated via stringByEvaluatingUserJavaScriptFromString. |
1625 DCHECK(!targetURL.SchemeIs(url::kJavaScriptScheme)); | 1615 DCHECK(!targetURL.SchemeIs(url::kJavaScriptScheme)); |
1626 | 1616 |
1627 [self ensureWebViewCreated]; | 1617 [self ensureWebViewCreated]; |
1628 | 1618 |
1629 // Update web view's user agent is called for every load, which may have | |
1630 // performance implications because update web view's user agent may | |
1631 // potentially send a message to a separate thread. However, this is not an | |
1632 // issue for WKWebView because WKWebView's |setCustomUserAgent| is non-op if | |
1633 // user agent stays thesame. | |
1634 [self updateWebViewUserAgentFromUserAgentType:self.userAgentType]; | |
1635 | |
1636 [self loadRequestForCurrentNavigationItem]; | 1619 [self loadRequestForCurrentNavigationItem]; |
1637 } | 1620 } |
1638 | 1621 |
1639 - (void)updatePendingNavigationInfoFromNavigationAction: | 1622 - (void)updatePendingNavigationInfoFromNavigationAction: |
1640 (WKNavigationAction*)action { | 1623 (WKNavigationAction*)action { |
1641 if (action.targetFrame.mainFrame) { | 1624 if (action.targetFrame.mainFrame) { |
1642 _pendingNavigationInfo.reset( | 1625 _pendingNavigationInfo.reset( |
1643 [[CRWWebControllerPendingNavigationInfo alloc] init]); | 1626 [[CRWWebControllerPendingNavigationInfo alloc] init]); |
1644 [_pendingNavigationInfo | 1627 [_pendingNavigationInfo |
1645 setReferrer:[self referrerFromNavigationAction:action]]; | 1628 setReferrer:[self referrerFromNavigationAction:action]]; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2036 return; | 2019 return; |
2037 } | 2020 } |
2038 | 2021 |
2039 if (!_webStateImpl->IsShowingWebInterstitial()) | 2022 if (!_webStateImpl->IsShowingWebInterstitial()) |
2040 [self recordStateInHistory]; | 2023 [self recordStateInHistory]; |
2041 | 2024 |
2042 [self clearTransientContentView]; | 2025 [self clearTransientContentView]; |
2043 | 2026 |
2044 // Update the user agent before attempting the navigation. | 2027 // Update the user agent before attempting the navigation. |
2045 web::NavigationItem* toItem = items[index].get(); | 2028 web::NavigationItem* toItem = items[index].get(); |
2046 [self updateWebViewUserAgentFromUserAgentType:toItem->GetUserAgentType()]; | 2029 web::NavigationItem* previousItem = sessionController.currentItem; |
| 2030 web::UserAgentType previousUserAgentType = |
| 2031 previousItem ? previousItem->GetUserAgentType() |
| 2032 : web::UserAgentType::NONE; |
| 2033 [self updateDesktopUserAgentForItem:toItem |
| 2034 previousUserAgentType:previousUserAgentType]; |
2047 | 2035 |
2048 web::NavigationItem* fromItem = sessionController.currentItem; | |
2049 BOOL sameDocumentNavigation = | 2036 BOOL sameDocumentNavigation = |
2050 [sessionController isSameDocumentNavigationBetweenItem:fromItem | 2037 [sessionController isSameDocumentNavigationBetweenItem:previousItem |
2051 andItem:toItem]; | 2038 andItem:toItem]; |
2052 if (sameDocumentNavigation) { | 2039 if (sameDocumentNavigation) { |
2053 [sessionController goToItemAtIndex:index]; | 2040 [sessionController goToItemAtIndex:index]; |
2054 [self updateHTML5HistoryState]; | 2041 [self updateHTML5HistoryState]; |
2055 } else { | 2042 } else { |
2056 [sessionController discardNonCommittedItems]; | 2043 [sessionController discardNonCommittedItems]; |
2057 [sessionController setPendingItemIndex:index]; | 2044 [sessionController setPendingItemIndex:index]; |
2058 | 2045 |
2059 web::NavigationItemImpl* pendingItem = sessionController.pendingItem; | 2046 web::NavigationItemImpl* pendingItem = sessionController.pendingItem; |
2060 pendingItem->SetTransitionType(ui::PageTransitionFromInt( | 2047 pendingItem->SetTransitionType(ui::PageTransitionFromInt( |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 // The page should be closed if it was initiated by the DOM and there has been | 2182 // The page should be closed if it was initiated by the DOM and there has been |
2196 // no user interaction with the page since the web view was created, or if | 2183 // no user interaction with the page since the web view was created, or if |
2197 // the page has no navigation items, as occurs when an App Store link is | 2184 // the page has no navigation items, as occurs when an App Store link is |
2198 // opened from another application. | 2185 // opened from another application. |
2199 BOOL rendererInitiatedWithoutInteraction = | 2186 BOOL rendererInitiatedWithoutInteraction = |
2200 self.hasOpener && !_userInteractedWithWebController; | 2187 self.hasOpener && !_userInteractedWithWebController; |
2201 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); | 2188 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); |
2202 return rendererInitiatedWithoutInteraction || noNavigationItems; | 2189 return rendererInitiatedWithoutInteraction || noNavigationItems; |
2203 } | 2190 } |
2204 | 2191 |
2205 - (web::UserAgentType)userAgentType { | 2192 - (BOOL)usesDesktopUserAgent { |
2206 web::NavigationItem* item = self.currentNavItem; | 2193 web::NavigationItem* item = self.currentNavItem; |
2207 return item ? item->GetUserAgentType() : web::UserAgentType::MOBILE; | 2194 return item && item->GetUserAgentType() == web::UserAgentType::DESKTOP; |
2208 } | 2195 } |
2209 | 2196 |
2210 - (web::MojoFacade*)mojoFacade { | 2197 - (web::MojoFacade*)mojoFacade { |
2211 if (!_mojoFacade) { | 2198 if (!_mojoFacade) { |
2212 service_manager::mojom::InterfaceProvider* interfaceProvider = | 2199 service_manager::mojom::InterfaceProvider* interfaceProvider = |
2213 _webStateImpl->GetMojoInterfaceRegistry(); | 2200 _webStateImpl->GetMojoInterfaceRegistry(); |
2214 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); | 2201 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); |
2215 } | 2202 } |
2216 return _mojoFacade.get(); | 2203 return _mojoFacade.get(); |
2217 } | 2204 } |
(...skipping 18 matching lines...) Expand all Loading... |
2236 [delegate webController:strongSelf didLoadPassKitObject:data]; | 2223 [delegate webController:strongSelf didLoadPassKitObject:data]; |
2237 } | 2224 } |
2238 }; | 2225 }; |
2239 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); | 2226 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); |
2240 _passKitDownloader.reset([[CRWPassKitDownloader alloc] | 2227 _passKitDownloader.reset([[CRWPassKitDownloader alloc] |
2241 initWithContextGetter:browserState->GetRequestContext() | 2228 initWithContextGetter:browserState->GetRequestContext() |
2242 completionHandler:passKitCompletion]); | 2229 completionHandler:passKitCompletion]); |
2243 return _passKitDownloader.get(); | 2230 return _passKitDownloader.get(); |
2244 } | 2231 } |
2245 | 2232 |
2246 - (void)updateWebViewUserAgentFromUserAgentType: | 2233 - (void)updateDesktopUserAgentForItem:(web::NavigationItem*)item |
2247 (web::UserAgentType)userAgentType { | 2234 previousUserAgentType:(web::UserAgentType)userAgentType { |
2248 if (userAgentType == web::UserAgentType::NONE) | 2235 if (!item) |
2249 return; | 2236 return; |
2250 | 2237 web::UserAgentType itemUserAgentType = item->GetUserAgentType(); |
2251 NSString* userAgent = | 2238 if (itemUserAgentType == web::UserAgentType::NONE) |
2252 base::SysUTF8ToNSString(web::GetWebClient()->GetUserAgent(userAgentType)); | 2239 return; |
2253 [_webView setCustomUserAgent:userAgent]; | 2240 if (itemUserAgentType != userAgentType) |
| 2241 [self requirePageReconstruction]; |
2254 } | 2242 } |
2255 | 2243 |
2256 #pragma mark - | 2244 #pragma mark - |
2257 #pragma mark CRWWebControllerContainerViewDelegate | 2245 #pragma mark CRWWebControllerContainerViewDelegate |
2258 | 2246 |
2259 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: | 2247 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: |
2260 (CRWWebControllerContainerView*)containerView { | 2248 (CRWWebControllerContainerView*)containerView { |
2261 return _webViewProxy.get(); | 2249 return _webViewProxy.get(); |
2262 } | 2250 } |
2263 | 2251 |
(...skipping 1781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4045 scrollView:self.webScrollView]); | 4033 scrollView:self.webScrollView]); |
4046 [_containerView displayWebViewContentView:webViewContentView]; | 4034 [_containerView displayWebViewContentView:webViewContentView]; |
4047 } | 4035 } |
4048 } | 4036 } |
4049 | 4037 |
4050 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config { | 4038 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config { |
4051 // Do not attach the context menu controller immediately as the JavaScript | 4039 // Do not attach the context menu controller immediately as the JavaScript |
4052 // delegate must be specified. | 4040 // delegate must be specified. |
4053 return web::BuildWKWebView(CGRectZero, config, | 4041 return web::BuildWKWebView(CGRectZero, config, |
4054 self.webStateImpl->GetBrowserState(), | 4042 self.webStateImpl->GetBrowserState(), |
4055 self.userAgentType); | 4043 self.usesDesktopUserAgent); |
4056 } | 4044 } |
4057 | 4045 |
4058 - (void)setWebView:(WKWebView*)webView { | 4046 - (void)setWebView:(WKWebView*)webView { |
4059 DCHECK_NE(_webView.get(), webView); | 4047 DCHECK_NE(_webView.get(), webView); |
4060 | 4048 |
4061 // Unwind the old web view. | 4049 // Unwind the old web view. |
4062 // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is | 4050 // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is |
4063 // fixed. | 4051 // fixed. |
4064 CRWWKScriptMessageRouter* messageRouter = | 4052 CRWWKScriptMessageRouter* messageRouter = |
4065 [self webViewConfigurationProvider].GetScriptMessageRouter(); | 4053 [self webViewConfigurationProvider].GetScriptMessageRouter(); |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5082 - (void)simulateLoadRequestWithURL:(const GURL&)URL { | 5070 - (void)simulateLoadRequestWithURL:(const GURL&)URL { |
5083 _lastRegisteredRequestURL = URL; | 5071 _lastRegisteredRequestURL = URL; |
5084 _loadPhase = web::LOAD_REQUESTED; | 5072 _loadPhase = web::LOAD_REQUESTED; |
5085 } | 5073 } |
5086 | 5074 |
5087 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5075 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
5088 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5076 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
5089 } | 5077 } |
5090 | 5078 |
5091 @end | 5079 @end |
OLD | NEW |