| 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 25 matching lines...) Expand all Loading... |
| 36 #include "base/strings/sys_string_conversions.h" | 36 #include "base/strings/sys_string_conversions.h" |
| 37 #include "base/strings/utf_string_conversions.h" | 37 #include "base/strings/utf_string_conversions.h" |
| 38 #include "base/time/time.h" | 38 #include "base/time/time.h" |
| 39 #include "base/values.h" | 39 #include "base/values.h" |
| 40 #import "ios/net/http_response_headers_util.h" | 40 #import "ios/net/http_response_headers_util.h" |
| 41 #import "ios/net/nsurlrequest_util.h" | 41 #import "ios/net/nsurlrequest_util.h" |
| 42 #include "ios/web/history_state_util.h" | 42 #include "ios/web/history_state_util.h" |
| 43 #import "ios/web/interstitials/web_interstitial_impl.h" | 43 #import "ios/web/interstitials/web_interstitial_impl.h" |
| 44 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" | 44 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" |
| 45 #import "ios/web/navigation/crw_session_controller.h" | 45 #import "ios/web/navigation/crw_session_controller.h" |
| 46 #import "ios/web/navigation/crw_session_entry.h" | |
| 47 #import "ios/web/navigation/navigation_item_impl.h" | 46 #import "ios/web/navigation/navigation_item_impl.h" |
| 48 #import "ios/web/navigation/navigation_manager_impl.h" | 47 #import "ios/web/navigation/navigation_manager_impl.h" |
| 49 #include "ios/web/net/cert_host_pair.h" | 48 #include "ios/web/net/cert_host_pair.h" |
| 50 #import "ios/web/net/crw_cert_verification_controller.h" | 49 #import "ios/web/net/crw_cert_verification_controller.h" |
| 51 #import "ios/web/net/crw_ssl_status_updater.h" | 50 #import "ios/web/net/crw_ssl_status_updater.h" |
| 52 #include "ios/web/public/browser_state.h" | 51 #include "ios/web/public/browser_state.h" |
| 53 #include "ios/web/public/favicon_url.h" | 52 #include "ios/web/public/favicon_url.h" |
| 54 #import "ios/web/public/java_script_dialog_presenter.h" | 53 #import "ios/web/public/java_script_dialog_presenter.h" |
| 55 #import "ios/web/public/navigation_item.h" | 54 #import "ios/web/public/navigation_item.h" |
| 56 #import "ios/web/public/navigation_manager.h" | 55 #import "ios/web/public/navigation_manager.h" |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 | 457 |
| 459 // Returns YES if the user interacted with the page recently. | 458 // Returns YES if the user interacted with the page recently. |
| 460 @property(nonatomic, readonly) BOOL userClickedRecently; | 459 @property(nonatomic, readonly) BOOL userClickedRecently; |
| 461 | 460 |
| 462 // Whether or not desktop user agent is used for the currentItem. | 461 // Whether or not desktop user agent is used for the currentItem. |
| 463 @property(nonatomic, readonly) BOOL usesDesktopUserAgent; | 462 @property(nonatomic, readonly) BOOL usesDesktopUserAgent; |
| 464 | 463 |
| 465 // Facade for Mojo API. | 464 // Facade for Mojo API. |
| 466 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; | 465 @property(nonatomic, readonly) web::MojoFacade* mojoFacade; |
| 467 | 466 |
| 468 // Updates Desktop User Agent and calls webWillFinishHistoryNavigationFromEntry: | 467 // TODO(crbug.com/692871): Remove these functions and replace with more |
| 469 // on CRWWebDelegate. TODO(crbug.com/684098): Remove this method and inline its | 468 // appropriate NavigationItem getters. |
| 470 // content. | 469 // Returns the navigation item for the current page. |
| 471 - (void)webWillFinishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry; | 470 @property(nonatomic, readonly) web::NavigationItemImpl* currentNavItem; |
| 472 // Recreates web view if |entry| and |fromEntry| have different value for | 471 // Returns the current transition type. |
| 473 // IsOverridingUserAgent() flag. | 472 @property(nonatomic, readonly) ui::PageTransition currentTransition; |
| 474 - (void)updateDesktopUserAgentForEntry:(CRWSessionEntry*)entry | 473 // Returns the referrer for current navigation item. May be empty. |
| 475 fromEntry:(CRWSessionEntry*)fromEntry; | 474 @property(nonatomic, readonly) web::Referrer currentNavItemReferrer; |
| 475 // The HTTP headers associated with the current navigation item. These are nil |
| 476 // unless the request was a POST. |
| 477 @property(nonatomic, readonly) NSDictionary* currentHTTPHeaders; |
| 478 |
| 476 // Removes the container view from the hierarchy and resets the ivar. | 479 // Removes the container view from the hierarchy and resets the ivar. |
| 477 - (void)resetContainerView; | 480 - (void)resetContainerView; |
| 478 // Called when the web page has changed document and/or URL, and so the page | 481 // Called when the web page has changed document and/or URL, and so the page |
| 479 // navigation should be reported to the delegate, and internal state updated to | 482 // navigation should be reported to the delegate, and internal state updated to |
| 480 // reflect the fact that the navigation has occurred. | 483 // reflect the fact that the navigation has occurred. |
| 481 // TODO(stuartmorgan): The code conflates URL changes and document object | 484 // TODO(stuartmorgan): The code conflates URL changes and document object |
| 482 // changes; the two need to be separated and handled differently. | 485 // changes; the two need to be separated and handled differently. |
| 483 - (void)webPageChanged; | 486 - (void)webPageChanged; |
| 484 // Resets any state that is associated with a specific document object (e.g., | 487 // Resets any state that is associated with a specific document object (e.g., |
| 485 // page interaction tracking). | 488 // page interaction tracking). |
| 486 - (void)resetDocumentSpecificState; | 489 - (void)resetDocumentSpecificState; |
| 487 // Called when a page (native or web) has actually started loading (i.e., for | 490 // Called when a page (native or web) has actually started loading (i.e., for |
| 488 // a web page the document has actually changed), or after the load request has | 491 // a web page the document has actually changed), or after the load request has |
| 489 // been registered for a non-document-changing URL change. Updates internal | 492 // been registered for a non-document-changing URL change. Updates internal |
| 490 // state not specific to web pages, and informs the delegate. | 493 // state not specific to web pages, and informs the delegate. |
| 491 - (void)didStartLoadingURL:(const GURL&)URL updateHistory:(BOOL)updateHistory; | 494 - (void)didStartLoadingURL:(const GURL&)URL updateHistory:(BOOL)updateHistory; |
| 492 // Returns YES if the URL looks like it is one CRWWebController can show. | 495 // Returns YES if the URL looks like it is one CRWWebController can show. |
| 493 + (BOOL)webControllerCanShow:(const GURL&)url; | 496 + (BOOL)webControllerCanShow:(const GURL&)url; |
| 494 // Clears the currently-displayed transient content view. | 497 // Clears the currently-displayed transient content view. |
| 495 - (void)clearTransientContentView; | 498 - (void)clearTransientContentView; |
| 496 // Returns a lazily created CRWTouchTrackingRecognizer. | 499 // Returns a lazily created CRWTouchTrackingRecognizer. |
| 497 - (CRWTouchTrackingRecognizer*)touchTrackingRecognizer; | 500 - (CRWTouchTrackingRecognizer*)touchTrackingRecognizer; |
| 498 // Shows placeholder overlay. | 501 // Shows placeholder overlay. |
| 499 - (void)addPlaceholderOverlay; | 502 - (void)addPlaceholderOverlay; |
| 500 // Removes placeholder overlay. | 503 // Removes placeholder overlay. |
| 501 - (void)removePlaceholderOverlay; | 504 - (void)removePlaceholderOverlay; |
| 502 | 505 |
| 503 // Returns the current entry from the underlying session controller. | |
| 504 // TODO(stuartmorgan): Audit all calls to these methods; these are just wrappers | |
| 505 // around the same logic as GetActiveEntry, so should probably not be used for | |
| 506 // the same reason that GetActiveEntry is deprecated. (E.g., page operations | |
| 507 // should generally be dealing with the last commited entry, not a pending | |
| 508 // entry). | |
| 509 - (CRWSessionEntry*)currentSessionEntry; | |
| 510 // Returns the navigation item for the current page. | |
| 511 - (web::NavigationItem*)currentNavItem; | |
| 512 // Returns the current transition type. | |
| 513 - (ui::PageTransition)currentTransition; | |
| 514 // Returns the referrer for current navigation item. May be empty. | |
| 515 - (web::Referrer)currentSessionEntryReferrer; | |
| 516 // The HTTP headers associated with the current navigation item. These are nil | |
| 517 // unless the request was a POST. | |
| 518 - (NSDictionary*)currentHTTPHeaders; | |
| 519 | |
| 520 // Creates a web view if it's not yet created. | 506 // Creates a web view if it's not yet created. |
| 521 - (void)ensureWebViewCreated; | 507 - (void)ensureWebViewCreated; |
| 522 // Creates a web view with given |config|. No-op if web view is already created. | 508 // Creates a web view with given |config|. No-op if web view is already created. |
| 523 - (void)ensureWebViewCreatedWithConfiguration:(WKWebViewConfiguration*)config; | 509 - (void)ensureWebViewCreatedWithConfiguration:(WKWebViewConfiguration*)config; |
| 524 // Returns a new autoreleased web view created with given configuration. | 510 // Returns a new autoreleased web view created with given configuration. |
| 525 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config; | 511 - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config; |
| 526 // Sets the value of the webView property, and performs its basic setup. | 512 // Sets the value of the webView property, and performs its basic setup. |
| 527 - (void)setWebView:(WKWebView*)webView; | 513 - (void)setWebView:(WKWebView*)webView; |
| 528 // Removes webView, optionally tracking the URL of the evicted | 514 // Removes webView, optionally tracking the URL of the evicted |
| 529 // page for later cache-based reconstruction. | 515 // page for later cache-based reconstruction. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 // Update the appropriate parts of the model and broadcast to the embedder. This | 587 // Update the appropriate parts of the model and broadcast to the embedder. This |
| 602 // may be called multiple times and thus must be idempotent. | 588 // may be called multiple times and thus must be idempotent. |
| 603 - (void)loadCompleteWithSuccess:(BOOL)loadSuccess; | 589 - (void)loadCompleteWithSuccess:(BOOL)loadSuccess; |
| 604 // Called after URL is finished loading and _loadPhase is set to PAGE_LOADED. | 590 // Called after URL is finished loading and _loadPhase is set to PAGE_LOADED. |
| 605 - (void)didFinishWithURL:(const GURL&)currentURL loadSuccess:(BOOL)loadSuccess; | 591 - (void)didFinishWithURL:(const GURL&)currentURL loadSuccess:(BOOL)loadSuccess; |
| 606 // Navigates forwards or backwards by |delta| pages. No-op if delta is out of | 592 // Navigates forwards or backwards by |delta| pages. No-op if delta is out of |
| 607 // bounds. Reloads if delta is 0. | 593 // bounds. Reloads if delta is 0. |
| 608 // TODO(crbug.com/661316): Move this method to NavigationManager. | 594 // TODO(crbug.com/661316): Move this method to NavigationManager. |
| 609 - (void)goDelta:(int)delta; | 595 - (void)goDelta:(int)delta; |
| 610 // Loads a new URL if the current entry is not from a pushState() navigation. | 596 // Loads a new URL if the current entry is not from a pushState() navigation. |
| 611 // |fromEntry| is the CRWSessionEntry that was the current entry prior to the | 597 // |item| is the NavigationItem that was the current entry prior to the |
| 612 // navigation. | 598 // navigation. |
| 613 - (void)finishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry; | 599 - (void)finishHistoryNavigationFromItem:(web::NavigationItem*)item; |
| 614 // Informs the native controller if web usage is allowed or not. | 600 // Informs the native controller if web usage is allowed or not. |
| 615 - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; | 601 - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; |
| 616 // Called when web controller receives a new message from the web page. | 602 // Called when web controller receives a new message from the web page. |
| 617 - (void)didReceiveScriptMessage:(WKScriptMessage*)message; | 603 - (void)didReceiveScriptMessage:(WKScriptMessage*)message; |
| 618 // Returns a new script which wraps |script| with windowID check so |script| is | 604 // Returns a new script which wraps |script| with windowID check so |script| is |
| 619 // not evaluated on windowID mismatch. | 605 // not evaluated on windowID mismatch. |
| 620 - (NSString*)scriptByAddingWindowIDCheckForScript:(NSString*)script; | 606 - (NSString*)scriptByAddingWindowIDCheckForScript:(NSString*)script; |
| 621 // Attempts to handle a script message. Returns YES on success, NO otherwise. | 607 // Attempts to handle a script message. Returns YES on success, NO otherwise. |
| 622 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage; | 608 - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage; |
| 623 // Registers load request with empty referrer and link or client redirect | 609 // Registers load request with empty referrer and link or client redirect |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1272 } | 1258 } |
| 1273 // Any non-web URL source is trusted. | 1259 // Any non-web URL source is trusted. |
| 1274 *trustLevel = web::URLVerificationTrustLevel::kAbsolute; | 1260 *trustLevel = web::URLVerificationTrustLevel::kAbsolute; |
| 1275 if (self.nativeController) { | 1261 if (self.nativeController) { |
| 1276 if ([self.nativeController respondsToSelector:@selector(virtualURL)]) { | 1262 if ([self.nativeController respondsToSelector:@selector(virtualURL)]) { |
| 1277 return [self.nativeController virtualURL]; | 1263 return [self.nativeController virtualURL]; |
| 1278 } else { | 1264 } else { |
| 1279 return [self.nativeController url]; | 1265 return [self.nativeController url]; |
| 1280 } | 1266 } |
| 1281 } | 1267 } |
| 1282 web::NavigationItem* item = [self currentNavItem]; | 1268 web::NavigationItem* item = self.currentNavItem; |
| 1283 return item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1269 return item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1284 } | 1270 } |
| 1285 | 1271 |
| 1286 - (WKWebView*)webView { | 1272 - (WKWebView*)webView { |
| 1287 return _webView.get(); | 1273 return _webView.get(); |
| 1288 } | 1274 } |
| 1289 | 1275 |
| 1290 - (UIScrollView*)webScrollView { | 1276 - (UIScrollView*)webScrollView { |
| 1291 return [_webView scrollView]; | 1277 return [_webView scrollView]; |
| 1292 } | 1278 } |
| 1293 | 1279 |
| 1294 - (GURL)currentURL { | 1280 - (GURL)currentURL { |
| 1295 web::URLVerificationTrustLevel trustLevel = | 1281 web::URLVerificationTrustLevel trustLevel = |
| 1296 web::URLVerificationTrustLevel::kNone; | 1282 web::URLVerificationTrustLevel::kNone; |
| 1297 return [self currentURLWithTrustLevel:&trustLevel]; | 1283 return [self currentURLWithTrustLevel:&trustLevel]; |
| 1298 } | 1284 } |
| 1299 | 1285 |
| 1300 - (web::Referrer)currentReferrer { | 1286 - (web::Referrer)currentReferrer { |
| 1301 // Referrer string doesn't include the fragment, so in cases where the | 1287 // Referrer string doesn't include the fragment, so in cases where the |
| 1302 // previous URL is equal to the current referrer plus the fragment the | 1288 // previous URL is equal to the current referrer plus the fragment the |
| 1303 // previous URL is returned as current referrer. | 1289 // previous URL is returned as current referrer. |
| 1304 NSString* referrerString = _currentReferrerString; | 1290 NSString* referrerString = _currentReferrerString; |
| 1305 | 1291 |
| 1306 // In case of an error evaluating the JavaScript simply return empty string. | 1292 // In case of an error evaluating the JavaScript simply return empty string. |
| 1307 if ([referrerString length] == 0) | 1293 if ([referrerString length] == 0) |
| 1308 return web::Referrer(); | 1294 return web::Referrer(); |
| 1309 | 1295 |
| 1310 web::NavigationItem* item = [self currentNavItem]; | 1296 web::NavigationItem* item = self.currentNavItem; |
| 1311 GURL navigationURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1297 GURL navigationURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1312 NSString* previousURLString = base::SysUTF8ToNSString(navigationURL.spec()); | 1298 NSString* previousURLString = base::SysUTF8ToNSString(navigationURL.spec()); |
| 1313 // Check if the referrer is equal to the previous URL minus the hash symbol. | 1299 // Check if the referrer is equal to the previous URL minus the hash symbol. |
| 1314 // L'#' is used to convert the char '#' to a unichar. | 1300 // L'#' is used to convert the char '#' to a unichar. |
| 1315 if ([previousURLString length] > [referrerString length] && | 1301 if ([previousURLString length] > [referrerString length] && |
| 1316 [previousURLString hasPrefix:referrerString] && | 1302 [previousURLString hasPrefix:referrerString] && |
| 1317 [previousURLString characterAtIndex:[referrerString length]] == L'#') { | 1303 [previousURLString characterAtIndex:[referrerString length]] == L'#') { |
| 1318 referrerString = previousURLString; | 1304 referrerString = previousURLString; |
| 1319 } | 1305 } |
| 1320 // Since referrer is being extracted from the destination page, the correct | 1306 // Since referrer is being extracted from the destination page, the correct |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 // |_pendingNavigationInfo| will be nil if the decidePolicy* delegate methods | 1361 // |_pendingNavigationInfo| will be nil if the decidePolicy* delegate methods |
| 1376 // were not called. | 1362 // were not called. |
| 1377 NSString* HTTPMethod = | 1363 NSString* HTTPMethod = |
| 1378 _pendingNavigationInfo | 1364 _pendingNavigationInfo |
| 1379 ? [_pendingNavigationInfo HTTPMethod] | 1365 ? [_pendingNavigationInfo HTTPMethod] |
| 1380 : [self currentBackForwardListItemHolder]->http_method(); | 1366 : [self currentBackForwardListItemHolder]->http_method(); |
| 1381 return [HTTPMethod isEqual:@"POST"]; | 1367 return [HTTPMethod isEqual:@"POST"]; |
| 1382 } | 1368 } |
| 1383 | 1369 |
| 1384 - (BOOL)isCurrentNavigationBackForward { | 1370 - (BOOL)isCurrentNavigationBackForward { |
| 1385 if (![self currentNavItem]) | 1371 if (!self.currentNavItem) |
| 1386 return NO; | 1372 return NO; |
| 1387 WKNavigationType currentNavigationType = | 1373 WKNavigationType currentNavigationType = |
| 1388 [self currentBackForwardListItemHolder]->navigation_type(); | 1374 [self currentBackForwardListItemHolder]->navigation_type(); |
| 1389 return currentNavigationType == WKNavigationTypeBackForward; | 1375 return currentNavigationType == WKNavigationTypeBackForward; |
| 1390 } | 1376 } |
| 1391 | 1377 |
| 1392 - (BOOL)isLinkNavigation:(WKNavigationType)navigationType { | 1378 - (BOOL)isLinkNavigation:(WKNavigationType)navigationType { |
| 1393 switch (navigationType) { | 1379 switch (navigationType) { |
| 1394 case WKNavigationTypeLinkActivated: | 1380 case WKNavigationTypeLinkActivated: |
| 1395 return YES; | 1381 return YES; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 // A new session history entry needs to be created. | 1535 // A new session history entry needs to be created. |
| 1550 self.navigationManagerImpl->AddPendingItem( | 1536 self.navigationManagerImpl->AddPendingItem( |
| 1551 requestURL, referrer, transition, | 1537 requestURL, referrer, transition, |
| 1552 web::NavigationInitiationType::RENDERER_INITIATED); | 1538 web::NavigationInitiationType::RENDERER_INITIATED); |
| 1553 } | 1539 } |
| 1554 _webStateImpl->SetIsLoading(true); | 1540 _webStateImpl->SetIsLoading(true); |
| 1555 _webStateImpl->OnProvisionalNavigationStarted(requestURL); | 1541 _webStateImpl->OnProvisionalNavigationStarted(requestURL); |
| 1556 } | 1542 } |
| 1557 | 1543 |
| 1558 - (void)updateHTML5HistoryState { | 1544 - (void)updateHTML5HistoryState { |
| 1559 web::NavigationItemImpl* currentItem = | 1545 web::NavigationItemImpl* currentItem = self.currentNavItem; |
| 1560 static_cast<web::NavigationItemImpl*>([self currentNavItem]); | |
| 1561 if (!currentItem) | 1546 if (!currentItem) |
| 1562 return; | 1547 return; |
| 1563 | 1548 |
| 1564 // Same-document navigations must trigger a popState event. | 1549 // Same-document navigations must trigger a popState event. |
| 1565 CRWSessionController* sessionController = self.sessionController; | 1550 CRWSessionController* sessionController = self.sessionController; |
| 1566 BOOL sameDocumentNavigation = [sessionController | 1551 BOOL sameDocumentNavigation = [sessionController |
| 1567 isSameDocumentNavigationBetweenItem:sessionController.currentItem | 1552 isSameDocumentNavigationBetweenItem:sessionController.currentItem |
| 1568 andItem:sessionController.previousItem]; | 1553 andItem:sessionController.previousItem]; |
| 1569 // WKWebView doesn't send hashchange events for same-document non-BFLI | 1554 // WKWebView doesn't send hashchange events for same-document non-BFLI |
| 1570 // navigations, so one must be dispatched manually for hash change same- | 1555 // navigations, so one must be dispatched manually for hash change same- |
| 1571 // document navigations. | 1556 // document navigations. |
| 1572 web::NavigationItem* previousItem = | |
| 1573 self.sessionController.previousEntry.navigationItem; | |
| 1574 const GURL URL = currentItem->GetURL(); | 1557 const GURL URL = currentItem->GetURL(); |
| 1558 web::NavigationItem* previousItem = self.sessionController.previousItem; |
| 1575 const GURL oldURL = previousItem ? previousItem->GetURL() : GURL(); | 1559 const GURL oldURL = previousItem ? previousItem->GetURL() : GURL(); |
| 1576 BOOL shouldDispatchHashchange = sameDocumentNavigation && previousItem && | 1560 BOOL shouldDispatchHashchange = sameDocumentNavigation && previousItem && |
| 1577 (web::GURLByRemovingRefFromGURL(URL) == | 1561 (web::GURLByRemovingRefFromGURL(URL) == |
| 1578 web::GURLByRemovingRefFromGURL(oldURL)); | 1562 web::GURLByRemovingRefFromGURL(oldURL)); |
| 1579 // The URL and state object must be set for same-document navigations and | 1563 // The URL and state object must be set for same-document navigations and |
| 1580 // NavigationItems that were created or updated by calls to pushState() or | 1564 // NavigationItems that were created or updated by calls to pushState() or |
| 1581 // replaceState(). | 1565 // replaceState(). |
| 1582 BOOL shouldUpdateState = sameDocumentNavigation || | 1566 BOOL shouldUpdateState = sameDocumentNavigation || |
| 1583 currentItem->IsCreatedFromPushState() || | 1567 currentItem->IsCreatedFromPushState() || |
| 1584 currentItem->HasStateBeenReplaced(); | 1568 currentItem->HasStateBeenReplaced(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 | 1601 |
| 1618 - (NSString*)javaScriptToDispatchHashChangeWithOldURL:(const GURL&)oldURL | 1602 - (NSString*)javaScriptToDispatchHashChangeWithOldURL:(const GURL&)oldURL |
| 1619 newURL:(const GURL&)newURL { | 1603 newURL:(const GURL&)newURL { |
| 1620 return [NSString | 1604 return [NSString |
| 1621 stringWithFormat:@"__gCrWeb.dispatchHashchangeEvent(\'%s\', \'%s\');", | 1605 stringWithFormat:@"__gCrWeb.dispatchHashchangeEvent(\'%s\', \'%s\');", |
| 1622 oldURL.spec().c_str(), newURL.spec().c_str()]; | 1606 oldURL.spec().c_str(), newURL.spec().c_str()]; |
| 1623 } | 1607 } |
| 1624 | 1608 |
| 1625 - (void)injectHTML5HistoryScriptWithHashChange:(BOOL)dispatchHashChange | 1609 - (void)injectHTML5HistoryScriptWithHashChange:(BOOL)dispatchHashChange |
| 1626 sameDocumentNavigation:(BOOL)sameDocumentNavigation { | 1610 sameDocumentNavigation:(BOOL)sameDocumentNavigation { |
| 1627 web::NavigationItemImpl* currentItem = | 1611 web::NavigationItemImpl* currentItem = self.currentNavItem; |
| 1628 static_cast<web::NavigationItemImpl*>([self currentNavItem]); | |
| 1629 if (!currentItem) | 1612 if (!currentItem) |
| 1630 return; | 1613 return; |
| 1631 | 1614 |
| 1632 const GURL URL = currentItem->GetURL(); | 1615 const GURL URL = currentItem->GetURL(); |
| 1633 NSString* stateObject = currentItem->GetSerializedStateObject(); | 1616 NSString* stateObject = currentItem->GetSerializedStateObject(); |
| 1634 NSMutableString* script = [NSMutableString | 1617 NSMutableString* script = [NSMutableString |
| 1635 stringWithString:[self javaScriptToReplaceWebViewURL:URL | 1618 stringWithString:[self javaScriptToReplaceWebViewURL:URL |
| 1636 stateObjectJSON:stateObject]]; | 1619 stateObjectJSON:stateObject]]; |
| 1637 if (sameDocumentNavigation) { | 1620 if (sameDocumentNavigation) { |
| 1638 [script | 1621 [script |
| 1639 appendString:[self javaScriptToDispatchPopStateWithObject:stateObject]]; | 1622 appendString:[self javaScriptToDispatchPopStateWithObject:stateObject]]; |
| 1640 } | 1623 } |
| 1641 if (dispatchHashChange) { | 1624 if (dispatchHashChange) { |
| 1642 web::NavigationItemImpl* previousItem = | 1625 web::NavigationItemImpl* previousItem = self.sessionController.previousItem; |
| 1643 self.sessionController.previousEntry.navigationItemImpl; | |
| 1644 const GURL oldURL = previousItem ? previousItem->GetURL() : GURL(); | 1626 const GURL oldURL = previousItem ? previousItem->GetURL() : GURL(); |
| 1645 [script appendString:[self javaScriptToDispatchHashChangeWithOldURL:oldURL | 1627 [script appendString:[self javaScriptToDispatchHashChangeWithOldURL:oldURL |
| 1646 newURL:URL]]; | 1628 newURL:URL]]; |
| 1647 } | 1629 } |
| 1648 base::WeakNSObject<CRWWebController> weakSelf(self); | 1630 base::WeakNSObject<CRWWebController> weakSelf(self); |
| 1649 [self executeJavaScript:script | 1631 [self executeJavaScript:script |
| 1650 completionHandler:^(id, NSError*) { | 1632 completionHandler:^(id, NSError*) { |
| 1651 if (!weakSelf || weakSelf.get()->_isBeingDestroyed) | 1633 if (!weakSelf || weakSelf.get()->_isBeingDestroyed) |
| 1652 return; | 1634 return; |
| 1653 base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); | 1635 base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); |
| 1654 strongSelf.get()->_URLOnStartLoading = URL; | 1636 strongSelf.get()->_URLOnStartLoading = URL; |
| 1655 strongSelf.get()->_lastRegisteredRequestURL = URL; | 1637 strongSelf.get()->_lastRegisteredRequestURL = URL; |
| 1656 }]; | 1638 }]; |
| 1657 } | 1639 } |
| 1658 | 1640 |
| 1659 // Load the current URL in a web view, first ensuring the web view is visible. | 1641 // Load the current URL in a web view, first ensuring the web view is visible. |
| 1660 - (void)loadCurrentURLInWebView { | 1642 - (void)loadCurrentURLInWebView { |
| 1661 // Clear the set of URLs opened in external applications. | 1643 // Clear the set of URLs opened in external applications. |
| 1662 _openedApplicationURL.reset([[NSMutableSet alloc] init]); | 1644 _openedApplicationURL.reset([[NSMutableSet alloc] init]); |
| 1663 | 1645 |
| 1664 web::NavigationItem* item = [self currentNavItem]; | 1646 web::NavigationItem* item = self.currentNavItem; |
| 1665 GURL targetURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1647 GURL targetURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1666 // Load the url. The UIWebView delegate callbacks take care of updating the | 1648 // Load the url. The UIWebView delegate callbacks take care of updating the |
| 1667 // session history and UI. | 1649 // session history and UI. |
| 1668 if (!targetURL.is_valid()) { | 1650 if (!targetURL.is_valid()) { |
| 1669 [self didFinishWithURL:targetURL loadSuccess:NO]; | 1651 [self didFinishWithURL:targetURL loadSuccess:NO]; |
| 1670 return; | 1652 return; |
| 1671 } | 1653 } |
| 1672 | 1654 |
| 1673 // JavaScript should never be evaluated here. User-entered JS should be | 1655 // JavaScript should never be evaluated here. User-entered JS should be |
| 1674 // evaluated via stringByEvaluatingUserJavaScriptFromString. | 1656 // evaluated via stringByEvaluatingUserJavaScriptFromString. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1709 if ([_pendingNavigationInfo MIMEType]) { | 1691 if ([_pendingNavigationInfo MIMEType]) { |
| 1710 self.webStateImpl->SetContentsMimeType( | 1692 self.webStateImpl->SetContentsMimeType( |
| 1711 base::SysNSStringToUTF8([_pendingNavigationInfo MIMEType])); | 1693 base::SysNSStringToUTF8([_pendingNavigationInfo MIMEType])); |
| 1712 } | 1694 } |
| 1713 [self updateCurrentBackForwardListItemHolder]; | 1695 [self updateCurrentBackForwardListItemHolder]; |
| 1714 | 1696 |
| 1715 _pendingNavigationInfo.reset(); | 1697 _pendingNavigationInfo.reset(); |
| 1716 } | 1698 } |
| 1717 | 1699 |
| 1718 - (NSMutableURLRequest*)requestForCurrentNavigationItem { | 1700 - (NSMutableURLRequest*)requestForCurrentNavigationItem { |
| 1719 web::NavigationItem* item = [self currentNavItem]; | 1701 web::NavigationItem* item = self.currentNavItem; |
| 1720 const GURL currentNavigationURL = | 1702 const GURL currentNavigationURL = |
| 1721 item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1703 item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1722 NSMutableURLRequest* request = [NSMutableURLRequest | 1704 NSMutableURLRequest* request = [NSMutableURLRequest |
| 1723 requestWithURL:net::NSURLWithGURL(currentNavigationURL)]; | 1705 requestWithURL:net::NSURLWithGURL(currentNavigationURL)]; |
| 1724 const web::Referrer referrer([self currentSessionEntryReferrer]); | 1706 const web::Referrer referrer(self.currentNavItemReferrer); |
| 1725 if (referrer.url.is_valid()) { | 1707 if (referrer.url.is_valid()) { |
| 1726 std::string referrerValue = | 1708 std::string referrerValue = |
| 1727 web::ReferrerHeaderValueForNavigation(currentNavigationURL, referrer); | 1709 web::ReferrerHeaderValueForNavigation(currentNavigationURL, referrer); |
| 1728 if (!referrerValue.empty()) { | 1710 if (!referrerValue.empty()) { |
| 1729 [request setValue:base::SysUTF8ToNSString(referrerValue) | 1711 [request setValue:base::SysUTF8ToNSString(referrerValue) |
| 1730 forHTTPHeaderField:kReferrerHeaderName]; | 1712 forHTTPHeaderField:kReferrerHeaderName]; |
| 1731 } | 1713 } |
| 1732 } | 1714 } |
| 1733 | 1715 |
| 1734 // If there are headers in the current session entry add them to |request|. | 1716 // If there are headers in the current session entry add them to |request|. |
| 1735 // Headers that would overwrite fields already present in |request| are | 1717 // Headers that would overwrite fields already present in |request| are |
| 1736 // skipped. | 1718 // skipped. |
| 1737 NSDictionary* headers = [self currentHTTPHeaders]; | 1719 NSDictionary* headers = self.currentHTTPHeaders; |
| 1738 for (NSString* headerName in headers) { | 1720 for (NSString* headerName in headers) { |
| 1739 if (![request valueForHTTPHeaderField:headerName]) { | 1721 if (![request valueForHTTPHeaderField:headerName]) { |
| 1740 [request setValue:[headers objectForKey:headerName] | 1722 [request setValue:[headers objectForKey:headerName] |
| 1741 forHTTPHeaderField:headerName]; | 1723 forHTTPHeaderField:headerName]; |
| 1742 } | 1724 } |
| 1743 } | 1725 } |
| 1744 | 1726 |
| 1745 return request; | 1727 return request; |
| 1746 } | 1728 } |
| 1747 | 1729 |
| 1748 - (web::WKBackForwardListItemHolder*)currentBackForwardListItemHolder { | 1730 - (web::WKBackForwardListItemHolder*)currentBackForwardListItemHolder { |
| 1749 web::NavigationItem* item = [self currentSessionEntry].navigationItemImpl; | 1731 web::NavigationItem* item = self.currentNavItem; |
| 1750 DCHECK(item); | 1732 DCHECK(item); |
| 1751 web::WKBackForwardListItemHolder* holder = | 1733 web::WKBackForwardListItemHolder* holder = |
| 1752 web::WKBackForwardListItemHolder::FromNavigationItem(item); | 1734 web::WKBackForwardListItemHolder::FromNavigationItem(item); |
| 1753 DCHECK(holder); | 1735 DCHECK(holder); |
| 1754 return holder; | 1736 return holder; |
| 1755 } | 1737 } |
| 1756 | 1738 |
| 1757 - (void)updateCurrentBackForwardListItemHolder { | 1739 - (void)updateCurrentBackForwardListItemHolder { |
| 1758 // WebUI pages (which are loaded via loadHTMLString:baseURL:) have no entry | 1740 // WebUI pages (which are loaded via loadHTMLString:baseURL:) have no entry |
| 1759 // in the back/forward list, so the current item will still be the previous | 1741 // in the back/forward list, so the current item will still be the previous |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1797 [self setNavigationItemTitle:title]; | 1779 [self setNavigationItemTitle:title]; |
| 1798 } | 1780 } |
| 1799 | 1781 |
| 1800 if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { | 1782 if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { |
| 1801 [self.nativeController setDelegate:self]; | 1783 [self.nativeController setDelegate:self]; |
| 1802 } | 1784 } |
| 1803 } | 1785 } |
| 1804 | 1786 |
| 1805 - (void)loadErrorInNativeView:(NSError*)error { | 1787 - (void)loadErrorInNativeView:(NSError*)error { |
| 1806 [self removeWebViewAllowingCachedReconstruction:NO]; | 1788 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 1807 web::NavigationItem* item = [self currentNavItem]; | 1789 web::NavigationItem* item = self.currentNavItem; |
| 1808 const GURL currentURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1790 const GURL currentURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 1809 | 1791 |
| 1810 if (web::IsWKWebViewSSLCertError(error)) { | 1792 if (web::IsWKWebViewSSLCertError(error)) { |
| 1811 // This could happen only if certificate is absent or could not be parsed. | 1793 // This could happen only if certificate is absent or could not be parsed. |
| 1812 error = web::NetErrorFromError(error, net::ERR_SSL_SERVER_CERT_BAD_FORMAT); | 1794 error = web::NetErrorFromError(error, net::ERR_SSL_SERVER_CERT_BAD_FORMAT); |
| 1813 #if defined(DEBUG) | 1795 #if defined(DEBUG) |
| 1814 net::SSLInfo info; | 1796 net::SSLInfo info; |
| 1815 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); | 1797 web::GetSSLInfoFromWKWebViewSSLCertError(error, &info); |
| 1816 CHECK(!error.cert); | 1798 CHECK(!error.cert); |
| 1817 #endif | 1799 #endif |
| 1818 } else { | 1800 } else { |
| 1819 error = web::NetErrorFromError(error); | 1801 error = web::NetErrorFromError(error); |
| 1820 } | 1802 } |
| 1821 | 1803 |
| 1822 BOOL isPost = [self isCurrentNavigationItemPOST]; | 1804 BOOL isPost = [self isCurrentNavigationItemPOST]; |
| 1823 [self setNativeController:[_nativeProvider controllerForURL:currentURL | 1805 [self setNativeController:[_nativeProvider controllerForURL:currentURL |
| 1824 withError:error | 1806 withError:error |
| 1825 isPost:isPost]]; | 1807 isPost:isPost]]; |
| 1826 [self loadNativeViewWithSuccess:NO]; | 1808 [self loadNativeViewWithSuccess:NO]; |
| 1827 } | 1809 } |
| 1828 | 1810 |
| 1829 // Load the current URL in a native controller, retrieved from the native | 1811 // Load the current URL in a native controller, retrieved from the native |
| 1830 // provider. Call |loadNativeViewWithSuccess:YES| to load the native controller. | 1812 // provider. Call |loadNativeViewWithSuccess:YES| to load the native controller. |
| 1831 - (void)loadCurrentURLInNativeView { | 1813 - (void)loadCurrentURLInNativeView { |
| 1832 // Free the web view. | 1814 // Free the web view. |
| 1833 [self removeWebViewAllowingCachedReconstruction:NO]; | 1815 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 1834 | 1816 |
| 1835 web::NavigationItem* item = [self currentNavItem]; | 1817 web::NavigationItem* item = self.currentNavItem; |
| 1836 const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); | 1818 const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 1837 const web::Referrer referrer; | 1819 const web::Referrer referrer; |
| 1838 id<CRWNativeContent> nativeContent = | 1820 id<CRWNativeContent> nativeContent = |
| 1839 [_nativeProvider controllerForURL:targetURL webState:self.webState]; | 1821 [_nativeProvider controllerForURL:targetURL webState:self.webState]; |
| 1840 // Unlike the WebView case, always create a new controller and view. | 1822 // Unlike the WebView case, always create a new controller and view. |
| 1841 // TODO(pinkerton): What to do if this does return nil? | 1823 // TODO(pinkerton): What to do if this does return nil? |
| 1842 [self setNativeController:nativeContent]; | 1824 [self setNativeController:nativeContent]; |
| 1843 if ([nativeContent respondsToSelector:@selector(virtualURL)]) { | 1825 if ([nativeContent respondsToSelector:@selector(virtualURL)]) { |
| 1844 item->SetVirtualURL([nativeContent virtualURL]); | 1826 item->SetVirtualURL([nativeContent virtualURL]); |
| 1845 } | 1827 } |
| 1846 | 1828 |
| 1847 [self registerLoadRequest:targetURL | 1829 [self registerLoadRequest:targetURL |
| 1848 referrer:referrer | 1830 referrer:referrer |
| 1849 transition:[self currentTransition]]; | 1831 transition:self.currentTransition]; |
| 1850 [self loadNativeViewWithSuccess:YES]; | 1832 [self loadNativeViewWithSuccess:YES]; |
| 1851 } | 1833 } |
| 1852 | 1834 |
| 1853 - (void)loadWithParams:(const NavigationManager::WebLoadParams&)originalParams { | 1835 - (void)loadWithParams:(const NavigationManager::WebLoadParams&)originalParams { |
| 1854 // Make a copy of |params|, as some of the delegate methods may modify it. | 1836 // Make a copy of |params|, as some of the delegate methods may modify it. |
| 1855 NavigationManager::WebLoadParams params(originalParams); | 1837 NavigationManager::WebLoadParams params(originalParams); |
| 1856 | 1838 |
| 1857 // Initiating a navigation from the UI, record the current page state before | 1839 // Initiating a navigation from the UI, record the current page state before |
| 1858 // the new page loads. Don't record for back/forward, as the current entry | 1840 // the new page loads. Don't record for back/forward, as the current entry |
| 1859 // has already been moved to the next entry in the history. Do, however, | 1841 // has already been moved to the next entry in the history. Do, however, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1878 } else { | 1860 } else { |
| 1879 // Clear transient view before making any changes to history and navigation | 1861 // Clear transient view before making any changes to history and navigation |
| 1880 // manager. TODO(stuartmorgan): Drive Transient Item clearing from | 1862 // manager. TODO(stuartmorgan): Drive Transient Item clearing from |
| 1881 // navigation system, rather than from WebController. | 1863 // navigation system, rather than from WebController. |
| 1882 [self clearTransientContentView]; | 1864 [self clearTransientContentView]; |
| 1883 | 1865 |
| 1884 // TODO(stuartmorgan): Why doesn't recordStateInHistory get called for | 1866 // TODO(stuartmorgan): Why doesn't recordStateInHistory get called for |
| 1885 // forward/back transitions? | 1867 // forward/back transitions? |
| 1886 [self recordStateInHistory]; | 1868 [self recordStateInHistory]; |
| 1887 | 1869 |
| 1888 if (!self.currentSessionEntry) | 1870 if (!self.currentNavItem) |
| 1889 initialNavigation = YES; | 1871 initialNavigation = YES; |
| 1890 | 1872 |
| 1891 web::NavigationInitiationType navigationInitiationType = | 1873 web::NavigationInitiationType navigationInitiationType = |
| 1892 params.is_renderer_initiated | 1874 params.is_renderer_initiated |
| 1893 ? web::NavigationInitiationType::RENDERER_INITIATED | 1875 ? web::NavigationInitiationType::RENDERER_INITIATED |
| 1894 : web::NavigationInitiationType::USER_INITIATED; | 1876 : web::NavigationInitiationType::USER_INITIATED; |
| 1895 self.navigationManagerImpl->AddPendingItem( | 1877 self.navigationManagerImpl->AddPendingItem( |
| 1896 navUrl, params.referrer, transition, navigationInitiationType); | 1878 navUrl, params.referrer, transition, navigationInitiationType); |
| 1897 | 1879 |
| 1898 web::NavigationItemImpl* addedItem = | 1880 web::NavigationItemImpl* addedItem = self.currentNavItem; |
| 1899 [self currentSessionEntry].navigationItemImpl; | |
| 1900 DCHECK(addedItem); | 1881 DCHECK(addedItem); |
| 1901 if (params.extra_headers) | 1882 if (params.extra_headers) |
| 1902 addedItem->AddHttpRequestHeaders(params.extra_headers); | 1883 addedItem->AddHttpRequestHeaders(params.extra_headers); |
| 1903 if (params.post_data) { | 1884 if (params.post_data) { |
| 1904 DCHECK([addedItem->GetHttpRequestHeaders() objectForKey:@"Content-Type"]) | 1885 DCHECK([addedItem->GetHttpRequestHeaders() objectForKey:@"Content-Type"]) |
| 1905 << "Post data should have an associated content type"; | 1886 << "Post data should have an associated content type"; |
| 1906 addedItem->SetPostData(params.post_data); | 1887 addedItem->SetPostData(params.post_data); |
| 1907 addedItem->SetShouldSkipRepostFormConfirmation(true); | 1888 addedItem->SetShouldSkipRepostFormConfirmation(true); |
| 1908 } | 1889 } |
| 1909 } | 1890 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1925 | 1906 |
| 1926 // Abort any outstanding page load. This ensures the delegate gets informed | 1907 // Abort any outstanding page load. This ensures the delegate gets informed |
| 1927 // about the outgoing page, and further messages from the page are suppressed. | 1908 // about the outgoing page, and further messages from the page are suppressed. |
| 1928 if (_loadPhase != web::PAGE_LOADED) | 1909 if (_loadPhase != web::PAGE_LOADED) |
| 1929 [self abortLoad]; | 1910 [self abortLoad]; |
| 1930 | 1911 |
| 1931 DCHECK(!_isHalted); | 1912 DCHECK(!_isHalted); |
| 1932 // Remove the transient content view. | 1913 // Remove the transient content view. |
| 1933 [self clearTransientContentView]; | 1914 [self clearTransientContentView]; |
| 1934 | 1915 |
| 1935 web::NavigationItem* item = [self currentNavItem]; | 1916 web::NavigationItem* item = self.currentNavItem; |
| 1936 const GURL currentURL = item ? item->GetURL() : GURL::EmptyGURL(); | 1917 const GURL currentURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 1937 // If it's a chrome URL, but not a native one, create the WebUI instance. | 1918 // If it's a chrome URL, but not a native one, create the WebUI instance. |
| 1938 if (web::GetWebClient()->IsAppSpecificURL(currentURL) && | 1919 if (web::GetWebClient()->IsAppSpecificURL(currentURL) && |
| 1939 ![_nativeProvider hasControllerForURL:currentURL]) { | 1920 ![_nativeProvider hasControllerForURL:currentURL]) { |
| 1940 if (!(item->GetTransitionType() & ui::PAGE_TRANSITION_TYPED || | 1921 if (!(item->GetTransitionType() & ui::PAGE_TRANSITION_TYPED || |
| 1941 item->GetTransitionType() & ui::PAGE_TRANSITION_AUTO_BOOKMARK) && | 1922 item->GetTransitionType() & ui::PAGE_TRANSITION_AUTO_BOOKMARK) && |
| 1942 self.sessionController.openedByDOM) { | 1923 self.sessionController.openedByDOM) { |
| 1943 // WebUI URLs can not be opened by DOM to prevent cross-site scripting as | 1924 // WebUI URLs can not be opened by DOM to prevent cross-site scripting as |
| 1944 // they have increased power. WebUI URLs may only be opened when the user | 1925 // they have increased power. WebUI URLs may only be opened when the user |
| 1945 // types in the URL or use bookmarks. | 1926 // types in the URL or use bookmarks. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1998 _containerView.get().frame = containerViewFrame; | 1979 _containerView.get().frame = containerViewFrame; |
| 1999 DCHECK(!CGRectIsEmpty(_containerView.get().frame)); | 1980 DCHECK(!CGRectIsEmpty(_containerView.get().frame)); |
| 2000 | 1981 |
| 2001 // TODO(crbug.com/691116): Remove this workaround once tests are no longer | 1982 // TODO(crbug.com/691116): Remove this workaround once tests are no longer |
| 2002 // dependent upon this accessibility ID. | 1983 // dependent upon this accessibility ID. |
| 2003 if (!base::ios::IsRunningOnIOS10OrLater()) | 1984 if (!base::ios::IsRunningOnIOS10OrLater()) |
| 2004 [_containerView setAccessibilityIdentifier:@"Container View"]; | 1985 [_containerView setAccessibilityIdentifier:@"Container View"]; |
| 2005 | 1986 |
| 2006 [_containerView addGestureRecognizer:[self touchTrackingRecognizer]]; | 1987 [_containerView addGestureRecognizer:[self touchTrackingRecognizer]]; |
| 2007 // Is |currentUrl| a web scheme or native chrome scheme. | 1988 // Is |currentUrl| a web scheme or native chrome scheme. |
| 2008 web::NavigationItem* item = [self currentNavItem]; | 1989 web::NavigationItem* item = self.currentNavItem; |
| 2009 const GURL currentNavigationURL = | 1990 const GURL currentNavigationURL = |
| 2010 item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 1991 item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 2011 BOOL isChromeScheme = | 1992 BOOL isChromeScheme = |
| 2012 web::GetWebClient()->IsAppSpecificURL(currentNavigationURL); | 1993 web::GetWebClient()->IsAppSpecificURL(currentNavigationURL); |
| 2013 | 1994 |
| 2014 // Don't immediately load the web page if in overlay mode. Always load if | 1995 // Don't immediately load the web page if in overlay mode. Always load if |
| 2015 // native. | 1996 // native. |
| 2016 if (isChromeScheme || !_overlayPreviewMode) { | 1997 if (isChromeScheme || !_overlayPreviewMode) { |
| 2017 // TODO(jimblackler): end the practice of calling |loadCurrentURL| when it | 1998 // TODO(jimblackler): end the practice of calling |loadCurrentURL| when it |
| 2018 // is possible there is no current URL. If the call performs necessary | 1999 // is possible there is no current URL. If the call performs necessary |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2112 } | 2093 } |
| 2113 [_delegate webLoadCancelled:_URLOnStartLoading]; | 2094 [_delegate webLoadCancelled:_URLOnStartLoading]; |
| 2114 break; | 2095 break; |
| 2115 case web::PAGE_LOADED: | 2096 case web::PAGE_LOADED: |
| 2116 break; | 2097 break; |
| 2117 } | 2098 } |
| 2118 } | 2099 } |
| 2119 | 2100 |
| 2120 - (void)goToItemAtIndex:(int)index { | 2101 - (void)goToItemAtIndex:(int)index { |
| 2121 CRWSessionController* sessionController = self.sessionController; | 2102 CRWSessionController* sessionController = self.sessionController; |
| 2122 NSArray* entries = sessionController.entries; | 2103 web::NavigationItemList items = sessionController.items; |
| 2123 if (index < 0 || index >= static_cast<int>(entries.count)) { | 2104 if (index < 0 || index >= static_cast<int>(items.size())) { |
| 2124 NOTREACHED(); | 2105 NOTREACHED(); |
| 2125 return; | 2106 return; |
| 2126 } | 2107 } |
| 2127 | 2108 |
| 2128 if (!_webStateImpl->IsShowingWebInterstitial()) | 2109 if (!_webStateImpl->IsShowingWebInterstitial()) |
| 2129 [self recordStateInHistory]; | 2110 [self recordStateInHistory]; |
| 2130 CRWSessionEntry* fromEntry = sessionController.currentEntry; | 2111 web::NavigationItem* fromItem = sessionController.currentItem; |
| 2131 CRWSessionEntry* toEntry = entries[index]; | 2112 web::NavigationItem* toItem = items[index]; |
| 2132 | 2113 |
| 2133 NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; | 2114 NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; |
| 2134 if (![userDefaults boolForKey:@"PendingIndexNavigationDisabled"]) { | 2115 if (![userDefaults boolForKey:@"PendingIndexNavigationDisabled"]) { |
| 2135 [self clearTransientContentView]; | 2116 [self clearTransientContentView]; |
| 2136 [self updateDesktopUserAgentForEntry:toEntry fromEntry:fromEntry]; | |
| 2137 | 2117 |
| 2138 BOOL sameDocumentNavigation = [sessionController | 2118 // Require page reconstruction if the navigation changes the user agent. |
| 2139 isSameDocumentNavigationBetweenItem:fromEntry.navigationItem | 2119 if (fromItem->IsOverridingUserAgent() != toItem->IsOverridingUserAgent()) { |
| 2140 andItem:toEntry.navigationItem]; | 2120 [self requirePageReconstruction]; |
| 2121 } |
| 2122 |
| 2123 BOOL sameDocumentNavigation = |
| 2124 [sessionController isSameDocumentNavigationBetweenItem:fromItem |
| 2125 andItem:toItem]; |
| 2141 if (sameDocumentNavigation) { | 2126 if (sameDocumentNavigation) { |
| 2142 [sessionController goToItemAtIndex:index]; | 2127 [sessionController goToItemAtIndex:index]; |
| 2143 [self updateHTML5HistoryState]; | 2128 [self updateHTML5HistoryState]; |
| 2144 } else { | 2129 } else { |
| 2145 [sessionController discardNonCommittedItems]; | 2130 [sessionController discardNonCommittedItems]; |
| 2146 [sessionController setPendingItemIndex:index]; | 2131 [sessionController setPendingItemIndex:index]; |
| 2147 | 2132 |
| 2148 web::NavigationItemImpl* pendingItem = | 2133 web::NavigationItemImpl* pendingItem = sessionController.pendingItem; |
| 2149 sessionController.pendingEntry.navigationItemImpl; | |
| 2150 pendingItem->SetTransitionType(ui::PageTransitionFromInt( | 2134 pendingItem->SetTransitionType(ui::PageTransitionFromInt( |
| 2151 pendingItem->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK)); | 2135 pendingItem->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK)); |
| 2152 | 2136 |
| 2153 [self loadCurrentURL]; | 2137 [self loadCurrentURL]; |
| 2154 } | 2138 } |
| 2155 } else { | 2139 } else { |
| 2156 [sessionController goToItemAtIndex:index]; | 2140 [sessionController goToItemAtIndex:index]; |
| 2157 if (fromEntry) | 2141 if (fromItem) |
| 2158 [self finishHistoryNavigationFromEntry:fromEntry]; | 2142 [self finishHistoryNavigationFromItem:fromItem]; |
| 2159 } | 2143 } |
| 2160 } | 2144 } |
| 2161 | 2145 |
| 2162 - (BOOL)isLoaded { | 2146 - (BOOL)isLoaded { |
| 2163 return _loadPhase == web::PAGE_LOADED; | 2147 return _loadPhase == web::PAGE_LOADED; |
| 2164 } | 2148 } |
| 2165 | 2149 |
| 2166 - (void)didFinishNavigation { | 2150 - (void)didFinishNavigation { |
| 2167 // This can be called at multiple times after the document has loaded. Do | 2151 // This can be called at multiple times after the document has loaded. Do |
| 2168 // nothing if the document has already loaded. | 2152 // nothing if the document has already loaded. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2212 // WKWebView will cache the WebUI HTML in the previous WKBackForwardListItem | 2196 // WKWebView will cache the WebUI HTML in the previous WKBackForwardListItem |
| 2213 // since it's loaded via |-loadHTML:forURL:| instead of an NSURLRequest. As a | 2197 // since it's loaded via |-loadHTML:forURL:| instead of an NSURLRequest. As a |
| 2214 // result, the WebUI's HTML and URL will be loaded when navigating to that | 2198 // result, the WebUI's HTML and URL will be loaded when navigating to that |
| 2215 // WKBackForwardListItem, causing a mismatch between the visible content and | 2199 // WKBackForwardListItem, causing a mismatch between the visible content and |
| 2216 // the visible URL (WebUI page will be visible, but URL will be the previous | 2200 // the visible URL (WebUI page will be visible, but URL will be the previous |
| 2217 // page's URL). To prevent this potential URL spoofing vulnerability, reset | 2201 // page's URL). To prevent this potential URL spoofing vulnerability, reset |
| 2218 // the previous NavigationItem's WKBackForwardListItem to force loading via | 2202 // the previous NavigationItem's WKBackForwardListItem to force loading via |
| 2219 // NSURLRequest. | 2203 // NSURLRequest. |
| 2220 if (_webUIManager) { | 2204 if (_webUIManager) { |
| 2221 web::NavigationItem* lastNavigationItem = | 2205 web::NavigationItem* lastNavigationItem = |
| 2222 self.sessionController.previousEntry.navigationItem; | 2206 self.sessionController.previousItem; |
| 2223 if (lastNavigationItem) { | 2207 if (lastNavigationItem) { |
| 2224 web::WKBackForwardListItemHolder* holder = | 2208 web::WKBackForwardListItemHolder* holder = |
| 2225 web::WKBackForwardListItemHolder::FromNavigationItem( | 2209 web::WKBackForwardListItemHolder::FromNavigationItem( |
| 2226 lastNavigationItem); | 2210 lastNavigationItem); |
| 2227 DCHECK(holder); | 2211 DCHECK(holder); |
| 2228 holder->set_back_forward_list_item(nil); | 2212 holder->set_back_forward_list_item(nil); |
| 2229 } | 2213 } |
| 2230 } | 2214 } |
| 2231 | 2215 |
| 2232 [self restoreStateFromHistory]; | 2216 [self restoreStateFromHistory]; |
| 2233 _webStateImpl->SetIsLoading(false); | 2217 _webStateImpl->SetIsLoading(false); |
| 2234 _webStateImpl->OnPageLoaded(currentURL, loadSuccess); | 2218 _webStateImpl->OnPageLoaded(currentURL, loadSuccess); |
| 2235 } | 2219 } |
| 2236 | 2220 |
| 2237 - (void)goDelta:(int)delta { | 2221 - (void)goDelta:(int)delta { |
| 2238 if (_isBeingDestroyed) | 2222 if (_isBeingDestroyed) |
| 2239 return; | 2223 return; |
| 2240 | 2224 |
| 2241 if (delta == 0) { | 2225 if (delta == 0) { |
| 2242 [self reload]; | 2226 [self reload]; |
| 2243 return; | 2227 return; |
| 2244 } | 2228 } |
| 2245 | 2229 |
| 2246 if (self.navigationManagerImpl->CanGoToOffset(delta)) { | 2230 if (self.navigationManagerImpl->CanGoToOffset(delta)) { |
| 2247 NSInteger index = self.navigationManagerImpl->GetIndexForOffset(delta); | 2231 NSInteger index = self.navigationManagerImpl->GetIndexForOffset(delta); |
| 2248 [self goToItemAtIndex:index]; | 2232 [self goToItemAtIndex:index]; |
| 2249 } | 2233 } |
| 2250 } | 2234 } |
| 2251 | 2235 |
| 2252 - (void)finishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry { | 2236 - (void)finishHistoryNavigationFromItem:(web::NavigationItem*)item { |
| 2253 [self webWillFinishHistoryNavigationFromEntry:fromEntry]; | 2237 // Require page reconstruction if the navigation changes the user agent. |
| 2238 web::NavigationItemImpl* currentItem = self.currentNavItem; |
| 2239 if (currentItem->IsOverridingUserAgent() != item->IsOverridingUserAgent()) { |
| 2240 [self requirePageReconstruction]; |
| 2241 } |
| 2254 | 2242 |
| 2255 // Only load the new URL if it has a different document than |fromEntry| to | 2243 // Only load the new URL if it has a different document than |fromEntry| to |
| 2256 // prevent extra page loads from NavigationItems created by hash changes or | 2244 // prevent extra page loads from NavigationItems created by hash changes or |
| 2257 // calls to window.history.pushState(). | 2245 // calls to window.history.pushState(). |
| 2258 BOOL shouldLoadURL = ![self.sessionController | 2246 BOOL shouldLoadURL = ![self.sessionController |
| 2259 isSameDocumentNavigationBetweenItem:fromEntry.navigationItem | 2247 isSameDocumentNavigationBetweenItem:item |
| 2260 andItem:self.currentNavItem]; | 2248 andItem:self.currentNavItem]; |
| 2261 web::NavigationItemImpl* currentItem = | 2249 GURL endURL = [self URLForHistoryNavigationFromItem:item toItem:currentItem]; |
| 2262 self.currentSessionEntry.navigationItemImpl; | |
| 2263 GURL endURL = [self URLForHistoryNavigationFromItem:fromEntry.navigationItem | |
| 2264 toItem:currentItem]; | |
| 2265 if (shouldLoadURL) { | 2250 if (shouldLoadURL) { |
| 2266 ui::PageTransition transition = ui::PageTransitionFromInt( | 2251 ui::PageTransition transition = ui::PageTransitionFromInt( |
| 2267 ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); | 2252 ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); |
| 2268 | 2253 |
| 2269 NavigationManager::WebLoadParams params(endURL); | 2254 NavigationManager::WebLoadParams params(endURL); |
| 2270 if (currentItem) { | 2255 if (currentItem) { |
| 2271 params.referrer = currentItem->GetReferrer(); | 2256 params.referrer = currentItem->GetReferrer(); |
| 2272 } | 2257 } |
| 2273 params.transition_type = transition; | 2258 params.transition_type = transition; |
| 2274 [self loadWithParams:params]; | 2259 [self loadWithParams:params]; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 // no user interaction with the page since the web view was created, or if | 2309 // no user interaction with the page since the web view was created, or if |
| 2325 // the page has no navigation items, as occurs when an App Store link is | 2310 // the page has no navigation items, as occurs when an App Store link is |
| 2326 // opened from another application. | 2311 // opened from another application. |
| 2327 BOOL rendererInitiatedWithoutInteraction = | 2312 BOOL rendererInitiatedWithoutInteraction = |
| 2328 self.sessionController.openedByDOM && !_userInteractedWithWebController; | 2313 self.sessionController.openedByDOM && !_userInteractedWithWebController; |
| 2329 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); | 2314 BOOL noNavigationItems = !(self.navigationManagerImpl->GetItemCount()); |
| 2330 return rendererInitiatedWithoutInteraction || noNavigationItems; | 2315 return rendererInitiatedWithoutInteraction || noNavigationItems; |
| 2331 } | 2316 } |
| 2332 | 2317 |
| 2333 - (BOOL)usesDesktopUserAgent { | 2318 - (BOOL)usesDesktopUserAgent { |
| 2334 web::NavigationItem* item = [self currentNavItem]; | 2319 web::NavigationItem* item = self.currentNavItem; |
| 2335 return item && item->IsOverridingUserAgent(); | 2320 return item && item->IsOverridingUserAgent(); |
| 2336 } | 2321 } |
| 2337 | 2322 |
| 2338 - (web::MojoFacade*)mojoFacade { | 2323 - (web::MojoFacade*)mojoFacade { |
| 2339 if (!_mojoFacade) { | 2324 if (!_mojoFacade) { |
| 2340 service_manager::mojom::InterfaceProvider* interfaceProvider = | 2325 service_manager::mojom::InterfaceProvider* interfaceProvider = |
| 2341 _webStateImpl->GetMojoInterfaceRegistry(); | 2326 _webStateImpl->GetMojoInterfaceRegistry(); |
| 2342 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); | 2327 _mojoFacade.reset(new web::MojoFacade(interfaceProvider, self)); |
| 2343 } | 2328 } |
| 2344 return _mojoFacade.get(); | 2329 return _mojoFacade.get(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2364 [delegate webController:strongSelf didLoadPassKitObject:data]; | 2349 [delegate webController:strongSelf didLoadPassKitObject:data]; |
| 2365 } | 2350 } |
| 2366 }; | 2351 }; |
| 2367 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); | 2352 web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); |
| 2368 _passKitDownloader.reset([[CRWPassKitDownloader alloc] | 2353 _passKitDownloader.reset([[CRWPassKitDownloader alloc] |
| 2369 initWithContextGetter:browserState->GetRequestContext() | 2354 initWithContextGetter:browserState->GetRequestContext() |
| 2370 completionHandler:passKitCompletion]); | 2355 completionHandler:passKitCompletion]); |
| 2371 return _passKitDownloader.get(); | 2356 return _passKitDownloader.get(); |
| 2372 } | 2357 } |
| 2373 | 2358 |
| 2374 - (void)webWillFinishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry { | |
| 2375 DCHECK(fromEntry); | |
| 2376 [self updateDesktopUserAgentForEntry:self.currentSessionEntry | |
| 2377 fromEntry:fromEntry]; | |
| 2378 [_delegate webWillFinishHistoryNavigationFromEntry:fromEntry]; | |
| 2379 } | |
| 2380 | |
| 2381 - (void)updateDesktopUserAgentForEntry:(CRWSessionEntry*)entry | |
| 2382 fromEntry:(CRWSessionEntry*)fromEntry { | |
| 2383 web::NavigationItemImpl* item = entry.navigationItemImpl; | |
| 2384 web::NavigationItemImpl* fromItem = fromEntry.navigationItemImpl; | |
| 2385 if (!item || !fromItem) | |
| 2386 return; | |
| 2387 bool useDesktopUserAgent = item->IsOverridingUserAgent(); | |
| 2388 if (useDesktopUserAgent != fromItem->IsOverridingUserAgent()) { | |
| 2389 [self requirePageReconstruction]; | |
| 2390 } | |
| 2391 } | |
| 2392 | |
| 2393 #pragma mark - | 2359 #pragma mark - |
| 2394 #pragma mark CRWWebControllerContainerViewDelegate | 2360 #pragma mark CRWWebControllerContainerViewDelegate |
| 2395 | 2361 |
| 2396 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: | 2362 - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: |
| 2397 (CRWWebControllerContainerView*)containerView { | 2363 (CRWWebControllerContainerView*)containerView { |
| 2398 return _webViewProxy.get(); | 2364 return _webViewProxy.get(); |
| 2399 } | 2365 } |
| 2400 | 2366 |
| 2401 - (CGFloat)headerHeightForContainerView: | 2367 - (CGFloat)headerHeightForContainerView: |
| 2402 (CRWWebControllerContainerView*)containerView { | 2368 (CRWWebControllerContainerView*)containerView { |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2830 // for the new page manually. | 2796 // for the new page manually. |
| 2831 [self executeJavaScript:@"__gCrWeb.sendFaviconsToHost();" | 2797 [self executeJavaScript:@"__gCrWeb.sendFaviconsToHost();" |
| 2832 completionHandler:nil]; | 2798 completionHandler:nil]; |
| 2833 | 2799 |
| 2834 // Record that the current NavigationItem was created by a hash change, but | 2800 // Record that the current NavigationItem was created by a hash change, but |
| 2835 // ignore hashchange events that are manually dispatched for same-document | 2801 // ignore hashchange events that are manually dispatched for same-document |
| 2836 // navigations. | 2802 // navigations. |
| 2837 if (_dispatchingSameDocumentHashChangeEvent) { | 2803 if (_dispatchingSameDocumentHashChangeEvent) { |
| 2838 _dispatchingSameDocumentHashChangeEvent = NO; | 2804 _dispatchingSameDocumentHashChangeEvent = NO; |
| 2839 } else { | 2805 } else { |
| 2840 web::NavigationItemImpl* item = | 2806 web::NavigationItemImpl* item = self.currentNavItem; |
| 2841 static_cast<web::NavigationItemImpl*>([self currentNavItem]); | |
| 2842 DCHECK(item); | 2807 DCHECK(item); |
| 2843 item->SetIsCreatedFromHashChange(true); | 2808 item->SetIsCreatedFromHashChange(true); |
| 2844 } | 2809 } |
| 2845 | 2810 |
| 2846 return YES; | 2811 return YES; |
| 2847 } | 2812 } |
| 2848 | 2813 |
| 2849 - (BOOL)handleWindowHistoryBackMessage:(base::DictionaryValue*)message | 2814 - (BOOL)handleWindowHistoryBackMessage:(base::DictionaryValue*)message |
| 2850 context:(NSDictionary*)context { | 2815 context:(NSDictionary*)context { |
| 2851 [self goDelta:-1]; | 2816 [self goDelta:-1]; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2877 - (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message | 2842 - (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message |
| 2878 context:(NSDictionary*)context { | 2843 context:(NSDictionary*)context { |
| 2879 DCHECK(_changingHistoryState); | 2844 DCHECK(_changingHistoryState); |
| 2880 _changingHistoryState = NO; | 2845 _changingHistoryState = NO; |
| 2881 | 2846 |
| 2882 // If there is a pending entry, a new navigation has been registered but | 2847 // If there is a pending entry, a new navigation has been registered but |
| 2883 // hasn't begun loading. Since the pushState message is coming from the | 2848 // hasn't begun loading. Since the pushState message is coming from the |
| 2884 // previous page, ignore it and allow the previously registered navigation to | 2849 // previous page, ignore it and allow the previously registered navigation to |
| 2885 // continue. This can ocur if a pushState is issued from an anchor tag | 2850 // continue. This can ocur if a pushState is issued from an anchor tag |
| 2886 // onClick event, as the click would have already been registered. | 2851 // onClick event, as the click would have already been registered. |
| 2887 if ([self sessionController].pendingEntry) | 2852 if ([self sessionController].pendingItem) |
| 2888 return NO; | 2853 return NO; |
| 2889 | 2854 |
| 2890 std::string pageURL; | 2855 std::string pageURL; |
| 2891 std::string baseURL; | 2856 std::string baseURL; |
| 2892 if (!message->GetString("pageUrl", &pageURL) || | 2857 if (!message->GetString("pageUrl", &pageURL) || |
| 2893 !message->GetString("baseUrl", &baseURL)) { | 2858 !message->GetString("baseUrl", &baseURL)) { |
| 2894 DLOG(WARNING) << "JS message parameter not found: pageUrl or baseUrl"; | 2859 DLOG(WARNING) << "JS message parameter not found: pageUrl or baseUrl"; |
| 2895 return NO; | 2860 return NO; |
| 2896 } | 2861 } |
| 2897 GURL pushURL = web::history_state_util::GetHistoryStateChangeUrl( | 2862 GURL pushURL = web::history_state_util::GetHistoryStateChangeUrl( |
| 2898 [self currentURL], GURL(baseURL), pageURL); | 2863 [self currentURL], GURL(baseURL), pageURL); |
| 2899 // UIWebView seems to choke on unicode characters that haven't been | 2864 // UIWebView seems to choke on unicode characters that haven't been |
| 2900 // escaped; escape the URL now so the expected load URL is correct. | 2865 // escaped; escape the URL now so the expected load URL is correct. |
| 2901 pushURL = URLEscapedForHistory(pushURL); | 2866 pushURL = URLEscapedForHistory(pushURL); |
| 2902 if (!pushURL.is_valid()) | 2867 if (!pushURL.is_valid()) |
| 2903 return YES; | 2868 return YES; |
| 2904 web::NavigationItem* navItem = [self currentNavItem]; | 2869 web::NavigationItem* navItem = self.currentNavItem; |
| 2905 // PushState happened before first navigation entry or called when the | 2870 // PushState happened before first navigation entry or called when the |
| 2906 // navigation entry does not contain a valid URL. | 2871 // navigation entry does not contain a valid URL. |
| 2907 if (!navItem || !navItem->GetURL().is_valid()) | 2872 if (!navItem || !navItem->GetURL().is_valid()) |
| 2908 return YES; | 2873 return YES; |
| 2909 if (!web::history_state_util::IsHistoryStateChangeValid( | 2874 if (!web::history_state_util::IsHistoryStateChangeValid( |
| 2910 [self currentNavItem]->GetURL(), pushURL)) { | 2875 self.currentNavItem->GetURL(), pushURL)) { |
| 2911 // If the current session entry URL origin still doesn't match pushURL's | 2876 // If the current session entry URL origin still doesn't match pushURL's |
| 2912 // origin, ignore the pushState. This can happen if a new URL is loaded | 2877 // origin, ignore the pushState. This can happen if a new URL is loaded |
| 2913 // just before the pushState. | 2878 // just before the pushState. |
| 2914 return YES; | 2879 return YES; |
| 2915 } | 2880 } |
| 2916 std::string stateObjectJSON; | 2881 std::string stateObjectJSON; |
| 2917 if (!message->GetString("stateObject", &stateObjectJSON)) { | 2882 if (!message->GetString("stateObject", &stateObjectJSON)) { |
| 2918 DLOG(WARNING) << "JS message parameter not found: stateObject"; | 2883 DLOG(WARNING) << "JS message parameter not found: stateObject"; |
| 2919 return NO; | 2884 return NO; |
| 2920 } | 2885 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2960 return NO; | 2925 return NO; |
| 2961 } | 2926 } |
| 2962 GURL replaceURL = web::history_state_util::GetHistoryStateChangeUrl( | 2927 GURL replaceURL = web::history_state_util::GetHistoryStateChangeUrl( |
| 2963 [self currentURL], GURL(baseURL), pageURL); | 2928 [self currentURL], GURL(baseURL), pageURL); |
| 2964 // UIWebView seems to choke on unicode characters that haven't been | 2929 // UIWebView seems to choke on unicode characters that haven't been |
| 2965 // escaped; escape the URL now so the expected load URL is correct. | 2930 // escaped; escape the URL now so the expected load URL is correct. |
| 2966 replaceURL = URLEscapedForHistory(replaceURL); | 2931 replaceURL = URLEscapedForHistory(replaceURL); |
| 2967 if (!replaceURL.is_valid()) | 2932 if (!replaceURL.is_valid()) |
| 2968 return YES; | 2933 return YES; |
| 2969 | 2934 |
| 2970 web::NavigationItem* navItem = [self currentNavItem]; | 2935 web::NavigationItem* navItem = self.currentNavItem; |
| 2971 // ReplaceState happened before first navigation entry or called right | 2936 // ReplaceState happened before first navigation entry or called right |
| 2972 // after window.open when the url is empty/not valid. | 2937 // after window.open when the url is empty/not valid. |
| 2973 if (!navItem || (self.navigationManagerImpl->GetItemCount() <= 1 && | 2938 if (!navItem || (self.navigationManagerImpl->GetItemCount() <= 1 && |
| 2974 navItem->GetURL().is_empty())) | 2939 navItem->GetURL().is_empty())) |
| 2975 return YES; | 2940 return YES; |
| 2976 if (!web::history_state_util::IsHistoryStateChangeValid( | 2941 if (!web::history_state_util::IsHistoryStateChangeValid( |
| 2977 [self currentNavItem]->GetURL(), replaceURL)) { | 2942 self.currentNavItem->GetURL(), replaceURL)) { |
| 2978 // If the current session entry URL origin still doesn't match | 2943 // If the current session entry URL origin still doesn't match |
| 2979 // replaceURL's origin, ignore the replaceState. This can happen if a | 2944 // replaceURL's origin, ignore the replaceState. This can happen if a |
| 2980 // new URL is loaded just before the replaceState. | 2945 // new URL is loaded just before the replaceState. |
| 2981 return YES; | 2946 return YES; |
| 2982 } | 2947 } |
| 2983 std::string stateObjectJSON; | 2948 std::string stateObjectJSON; |
| 2984 if (!message->GetString("stateObject", &stateObjectJSON)) { | 2949 if (!message->GetString("stateObject", &stateObjectJSON)) { |
| 2985 DLOG(WARNING) << "JS message parameter not found: stateObject"; | 2950 DLOG(WARNING) << "JS message parameter not found: stateObject"; |
| 2986 return NO; | 2951 return NO; |
| 2987 } | 2952 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3023 // we should be distinguishing better, and be clear about the expected | 2988 // we should be distinguishing better, and be clear about the expected |
| 3024 // WebDelegate and WCO callbacks in each case. | 2989 // WebDelegate and WCO callbacks in each case. |
| 3025 - (void)webPageChanged { | 2990 - (void)webPageChanged { |
| 3026 DCHECK(_loadPhase == web::LOAD_REQUESTED); | 2991 DCHECK(_loadPhase == web::LOAD_REQUESTED); |
| 3027 | 2992 |
| 3028 const GURL currentURL([self currentURL]); | 2993 const GURL currentURL([self currentURL]); |
| 3029 web::Referrer referrer = [self currentReferrer]; | 2994 web::Referrer referrer = [self currentReferrer]; |
| 3030 // If no referrer was known in advance, record it now. (If there was one, | 2995 // If no referrer was known in advance, record it now. (If there was one, |
| 3031 // keep it since it will have a more accurate URL and policy than what can | 2996 // keep it since it will have a more accurate URL and policy than what can |
| 3032 // be extracted from the landing page.) | 2997 // be extracted from the landing page.) |
| 3033 web::NavigationItem* currentItem = [self currentNavItem]; | 2998 web::NavigationItem* currentItem = self.currentNavItem; |
| 3034 if (!currentItem->GetReferrer().url.is_valid()) { | 2999 if (!currentItem->GetReferrer().url.is_valid()) { |
| 3035 currentItem->SetReferrer(referrer); | 3000 currentItem->SetReferrer(referrer); |
| 3036 } | 3001 } |
| 3037 | 3002 |
| 3038 // TODO(stuartmorgan): This shouldn't be called for hash state or | 3003 // TODO(stuartmorgan): This shouldn't be called for hash state or |
| 3039 // push/replaceState. | 3004 // push/replaceState. |
| 3040 [self resetDocumentSpecificState]; | 3005 [self resetDocumentSpecificState]; |
| 3041 | 3006 |
| 3042 [self didStartLoadingURL:currentURL updateHistory:YES]; | 3007 [self didStartLoadingURL:currentURL updateHistory:YES]; |
| 3043 } | 3008 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3083 _userInteractionRegistered = flag; | 3048 _userInteractionRegistered = flag; |
| 3084 if (flag) | 3049 if (flag) |
| 3085 _interactionRegisteredSinceLastURLChange = YES; | 3050 _interactionRegisteredSinceLastURLChange = YES; |
| 3086 } | 3051 } |
| 3087 | 3052 |
| 3088 - (BOOL)userInteractionRegistered { | 3053 - (BOOL)userInteractionRegistered { |
| 3089 return _userInteractionRegistered; | 3054 return _userInteractionRegistered; |
| 3090 } | 3055 } |
| 3091 | 3056 |
| 3092 - (void)cachePOSTDataForRequest:(NSURLRequest*)request | 3057 - (void)cachePOSTDataForRequest:(NSURLRequest*)request |
| 3093 inSessionEntry:(CRWSessionEntry*)currentSessionEntry { | 3058 inNavigationItem:(web::NavigationItemImpl*)item { |
| 3094 NSUInteger maxPOSTDataSizeInBytes = 4096; | 3059 NSUInteger maxPOSTDataSizeInBytes = 4096; |
| 3095 NSString* cookieHeaderName = @"cookie"; | 3060 NSString* cookieHeaderName = @"cookie"; |
| 3096 | 3061 |
| 3097 web::NavigationItemImpl* currentItem = currentSessionEntry.navigationItemImpl; | 3062 DCHECK(item); |
| 3098 DCHECK(currentItem); | |
| 3099 const bool shouldUpdateEntry = | 3063 const bool shouldUpdateEntry = |
| 3100 ui::PageTransitionCoreTypeIs(currentItem->GetTransitionType(), | 3064 ui::PageTransitionCoreTypeIs(item->GetTransitionType(), |
| 3101 ui::PAGE_TRANSITION_FORM_SUBMIT) && | 3065 ui::PAGE_TRANSITION_FORM_SUBMIT) && |
| 3102 ![request HTTPBodyStream] && // Don't cache streams. | 3066 ![request HTTPBodyStream] && // Don't cache streams. |
| 3103 !currentItem->HasPostData() && | 3067 !item->HasPostData() && |
| 3104 currentItem->GetURL() == net::GURLWithNSURL([request URL]); | 3068 item->GetURL() == net::GURLWithNSURL([request URL]); |
| 3105 const bool belowSizeCap = | 3069 const bool belowSizeCap = |
| 3106 [[request HTTPBody] length] < maxPOSTDataSizeInBytes; | 3070 [[request HTTPBody] length] < maxPOSTDataSizeInBytes; |
| 3107 DLOG_IF(WARNING, shouldUpdateEntry && !belowSizeCap) | 3071 DLOG_IF(WARNING, shouldUpdateEntry && !belowSizeCap) |
| 3108 << "Data in POST request exceeds the size cap (" << maxPOSTDataSizeInBytes | 3072 << "Data in POST request exceeds the size cap (" << maxPOSTDataSizeInBytes |
| 3109 << " bytes), and will not be cached."; | 3073 << " bytes), and will not be cached."; |
| 3110 | 3074 |
| 3111 if (shouldUpdateEntry && belowSizeCap) { | 3075 if (shouldUpdateEntry && belowSizeCap) { |
| 3112 currentItem->SetPostData([request HTTPBody]); | 3076 item->SetPostData([request HTTPBody]); |
| 3113 currentItem->ResetHttpRequestHeaders(); | 3077 item->ResetHttpRequestHeaders(); |
| 3114 currentItem->AddHttpRequestHeaders([request allHTTPHeaderFields]); | 3078 item->AddHttpRequestHeaders([request allHTTPHeaderFields]); |
| 3115 // Don't cache the "Cookie" header. | 3079 // Don't cache the "Cookie" header. |
| 3116 // According to NSURLRequest documentation, |-valueForHTTPHeaderField:| is | 3080 // According to NSURLRequest documentation, |-valueForHTTPHeaderField:| is |
| 3117 // case insensitive, so it's enough to test the lower case only. | 3081 // case insensitive, so it's enough to test the lower case only. |
| 3118 if ([request valueForHTTPHeaderField:cookieHeaderName]) { | 3082 if ([request valueForHTTPHeaderField:cookieHeaderName]) { |
| 3119 // Case insensitive search in |headers|. | 3083 // Case insensitive search in |headers|. |
| 3120 NSSet* cookieKeys = [currentItem->GetHttpRequestHeaders() | 3084 NSSet* cookieKeys = [item->GetHttpRequestHeaders() |
| 3121 keysOfEntriesPassingTest:^(id key, id obj, BOOL* stop) { | 3085 keysOfEntriesPassingTest:^(id key, id obj, BOOL* stop) { |
| 3122 NSString* header = (NSString*)key; | 3086 NSString* header = (NSString*)key; |
| 3123 const BOOL found = | 3087 const BOOL found = |
| 3124 [header caseInsensitiveCompare:cookieHeaderName] == | 3088 [header caseInsensitiveCompare:cookieHeaderName] == |
| 3125 NSOrderedSame; | 3089 NSOrderedSame; |
| 3126 *stop = found; | 3090 *stop = found; |
| 3127 return found; | 3091 return found; |
| 3128 }]; | 3092 }]; |
| 3129 DCHECK_EQ(1u, [cookieKeys count]); | 3093 DCHECK_EQ(1u, [cookieKeys count]); |
| 3130 currentItem->RemoveHttpRequestHeaderForKey([cookieKeys anyObject]); | 3094 item->RemoveHttpRequestHeaderForKey([cookieKeys anyObject]); |
| 3131 } | 3095 } |
| 3132 } | 3096 } |
| 3133 } | 3097 } |
| 3134 | 3098 |
| 3135 // TODO(stuartmorgan): This is mostly logic from the original UIWebView delegate | 3099 // TODO(stuartmorgan): This is mostly logic from the original UIWebView delegate |
| 3136 // method, which provides less information than the WKWebView version. Audit | 3100 // method, which provides less information than the WKWebView version. Audit |
| 3137 // this for things that should be handled in the subclass instead. | 3101 // this for things that should be handled in the subclass instead. |
| 3138 - (BOOL)shouldAllowLoadWithNavigationAction:(WKNavigationAction*)action { | 3102 - (BOOL)shouldAllowLoadWithNavigationAction:(WKNavigationAction*)action { |
| 3139 NSURLRequest* request = action.request; | 3103 NSURLRequest* request = action.request; |
| 3140 GURL requestURL = net::GURLWithNSURL(request.URL); | 3104 GURL requestURL = net::GURLWithNSURL(request.URL); |
| 3141 | 3105 |
| 3142 // External application launcher needs |isNavigationTypeLinkActivated| to | 3106 // External application launcher needs |isNavigationTypeLinkActivated| to |
| 3143 // decide if the user intended to open the application by clicking on a link. | 3107 // decide if the user intended to open the application by clicking on a link. |
| 3144 BOOL isNavigationTypeLinkActivated = | 3108 BOOL isNavigationTypeLinkActivated = |
| 3145 action.navigationType == WKNavigationTypeLinkActivated; | 3109 action.navigationType == WKNavigationTypeLinkActivated; |
| 3146 | 3110 |
| 3147 // Check if the link navigation leads to a launch of an external app. | 3111 // Check if the link navigation leads to a launch of an external app. |
| 3148 // TODO(crbug.com/607780): Revise the logic of allowing external app launch | 3112 // TODO(crbug.com/607780): Revise the logic of allowing external app launch |
| 3149 // and move it to externalAppLauncher. | 3113 // and move it to externalAppLauncher. |
| 3150 BOOL isOpenInNewTabNavigation = !(self.navigationManagerImpl->GetItemCount()); | 3114 BOOL isOpenInNewTabNavigation = !(self.navigationManagerImpl->GetItemCount()); |
| 3151 BOOL isPossibleLinkClick = [self isLinkNavigation:action.navigationType]; | 3115 BOOL isPossibleLinkClick = [self isLinkNavigation:action.navigationType]; |
| 3152 if (isPossibleLinkClick || isOpenInNewTabNavigation || | 3116 if (isPossibleLinkClick || isOpenInNewTabNavigation || |
| 3153 PageTransitionCoreTypeIs([self currentTransition], | 3117 PageTransitionCoreTypeIs(self.currentTransition, |
| 3154 ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { | 3118 ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { |
| 3155 web::NavigationItem* item = [self currentNavItem]; | 3119 web::NavigationItem* item = self.currentNavItem; |
| 3156 const GURL currentNavigationURL = | 3120 const GURL currentNavigationURL = |
| 3157 item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 3121 item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 3158 // Check If the URL is handled by a native app. | 3122 // Check If the URL is handled by a native app. |
| 3159 if ([self urlTriggersNativeAppLaunch:requestURL | 3123 if ([self urlTriggersNativeAppLaunch:requestURL |
| 3160 sourceURL:currentNavigationURL | 3124 sourceURL:currentNavigationURL |
| 3161 linkActivatedNavigation:isNavigationTypeLinkActivated]) { | 3125 linkActivatedNavigation:isNavigationTypeLinkActivated]) { |
| 3162 // External app has been launched successfully. Stop the current page | 3126 // External app has been launched successfully. Stop the current page |
| 3163 // load operation (e.g. notifying all observers) and record the URL so | 3127 // load operation (e.g. notifying all observers) and record the URL so |
| 3164 // that errors reported following the 'NO' reply can be safely ignored. | 3128 // that errors reported following the 'NO' reply can be safely ignored. |
| 3165 if ([self shouldClosePageOnNativeApplicationLoad]) | 3129 if ([self shouldClosePageOnNativeApplicationLoad]) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3213 // Record the URL so that errors reported following the 'NO' reply can be | 3177 // Record the URL so that errors reported following the 'NO' reply can be |
| 3214 // safely ignored. | 3178 // safely ignored. |
| 3215 [_openedApplicationURL addObject:request.URL]; | 3179 [_openedApplicationURL addObject:request.URL]; |
| 3216 if ([self shouldClosePageOnNativeApplicationLoad]) | 3180 if ([self shouldClosePageOnNativeApplicationLoad]) |
| 3217 [_delegate webPageOrderedClose]; | 3181 [_delegate webPageOrderedClose]; |
| 3218 } | 3182 } |
| 3219 return NO; | 3183 return NO; |
| 3220 } | 3184 } |
| 3221 | 3185 |
| 3222 if ([[request HTTPMethod] isEqualToString:@"POST"]) { | 3186 if ([[request HTTPMethod] isEqualToString:@"POST"]) { |
| 3223 CRWSessionEntry* currentEntry = [self currentSessionEntry]; | 3187 web::NavigationItemImpl* item = self.currentNavItem; |
| 3224 // TODO(crbug.com/570699): Remove this check once it's no longer possible to | 3188 // TODO(crbug.com/570699): Remove this check once it's no longer possible to |
| 3225 // have no current entries. | 3189 // have no current entries. |
| 3226 if (currentEntry) | 3190 if (item) |
| 3227 [self cachePOSTDataForRequest:request inSessionEntry:currentEntry]; | 3191 [self cachePOSTDataForRequest:request inNavigationItem:item]; |
| 3228 } | 3192 } |
| 3229 | 3193 |
| 3230 return YES; | 3194 return YES; |
| 3231 } | 3195 } |
| 3232 | 3196 |
| 3233 - (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame { | 3197 - (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame { |
| 3234 NSString* MIMEType = [_pendingNavigationInfo MIMEType]; | 3198 NSString* MIMEType = [_pendingNavigationInfo MIMEType]; |
| 3235 if ([_passKitDownloader isMIMETypePassKitType:MIMEType]) | 3199 if ([_passKitDownloader isMIMETypePassKitType:MIMEType]) |
| 3236 return; | 3200 return; |
| 3237 if ([error code] == NSURLErrorUnsupportedURL) | 3201 if ([error code] == NSURLErrorUnsupportedURL) |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3604 | 3568 |
| 3605 - (CRWSessionController*)sessionController { | 3569 - (CRWSessionController*)sessionController { |
| 3606 NavigationManagerImpl* navigationManager = self.navigationManagerImpl; | 3570 NavigationManagerImpl* navigationManager = self.navigationManagerImpl; |
| 3607 return navigationManager ? navigationManager->GetSessionController() : nil; | 3571 return navigationManager ? navigationManager->GetSessionController() : nil; |
| 3608 } | 3572 } |
| 3609 | 3573 |
| 3610 - (NavigationManagerImpl*)navigationManagerImpl { | 3574 - (NavigationManagerImpl*)navigationManagerImpl { |
| 3611 return _webStateImpl ? &(_webStateImpl->GetNavigationManagerImpl()) : nil; | 3575 return _webStateImpl ? &(_webStateImpl->GetNavigationManagerImpl()) : nil; |
| 3612 } | 3576 } |
| 3613 | 3577 |
| 3614 - (CRWSessionEntry*)currentSessionEntry { | 3578 - (web::NavigationItemImpl*)currentNavItem { |
| 3615 return [[self sessionController] currentEntry]; | |
| 3616 } | |
| 3617 | |
| 3618 - (web::NavigationItem*)currentNavItem { | |
| 3619 // This goes through the legacy Session* interface rather than Navigation* | 3579 // This goes through the legacy Session* interface rather than Navigation* |
| 3620 // because it is itself a legacy method that should not exist, and this | 3580 // because it is itself a legacy method that should not exist, and this |
| 3621 // avoids needing to add a GetActiveItem to NavigationManager. If/when this | 3581 // avoids needing to add a GetActiveItem to NavigationManager. If/when this |
| 3622 // method chain becomes a blocker to eliminating SessionController, the logic | 3582 // method chain becomes a blocker to eliminating SessionController, the logic |
| 3623 // can be moved here, using public NavigationManager getters. That's not | 3583 // can be moved here, using public NavigationManager getters. That's not |
| 3624 // done now in order to avoid code duplication. | 3584 // done now in order to avoid code duplication. |
| 3625 return [[self currentSessionEntry] navigationItem]; | 3585 return [[self sessionController] currentItem]; |
| 3626 } | 3586 } |
| 3627 | 3587 |
| 3628 - (ui::PageTransition)currentTransition { | 3588 - (ui::PageTransition)currentTransition { |
| 3629 if ([self currentNavItem]) | 3589 if (self.currentNavItem) |
| 3630 return [self currentNavItem]->GetTransitionType(); | 3590 return self.currentNavItem->GetTransitionType(); |
| 3631 else | 3591 else |
| 3632 return ui::PageTransitionFromInt(0); | 3592 return ui::PageTransitionFromInt(0); |
| 3633 } | 3593 } |
| 3634 | 3594 |
| 3635 - (web::Referrer)currentSessionEntryReferrer { | 3595 - (web::Referrer)currentNavItemReferrer { |
| 3636 web::NavigationItem* currentItem = [self currentNavItem]; | 3596 web::NavigationItem* currentItem = self.currentNavItem; |
| 3637 return currentItem ? currentItem->GetReferrer() : web::Referrer(); | 3597 return currentItem ? currentItem->GetReferrer() : web::Referrer(); |
| 3638 } | 3598 } |
| 3639 | 3599 |
| 3640 - (NSDictionary*)currentHTTPHeaders { | 3600 - (NSDictionary*)currentHTTPHeaders { |
| 3641 DCHECK([self currentSessionEntry]); | 3601 web::NavigationItem* currentItem = self.currentNavItem; |
| 3642 return [self currentSessionEntry].navigationItem->GetHttpRequestHeaders(); | 3602 return currentItem ? currentItem->GetHttpRequestHeaders() : nil; |
| 3643 } | 3603 } |
| 3644 | 3604 |
| 3645 #pragma mark - | 3605 #pragma mark - |
| 3646 #pragma mark CRWWebViewScrollViewProxyObserver | 3606 #pragma mark CRWWebViewScrollViewProxyObserver |
| 3647 | 3607 |
| 3648 - (void)webViewScrollViewDidZoom: | 3608 - (void)webViewScrollViewDidZoom: |
| 3649 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { | 3609 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { |
| 3650 _pageHasZoomed = YES; | 3610 _pageHasZoomed = YES; |
| 3651 | 3611 |
| 3652 base::WeakNSObject<UIScrollView> weakScrollView(self.webScrollView); | 3612 base::WeakNSObject<UIScrollView> weakScrollView(self.webScrollView); |
| 3653 [self extractViewportTagWithCompletion:^( | 3613 [self extractViewportTagWithCompletion:^( |
| 3654 const web::PageViewportState* viewportState) { | 3614 const web::PageViewportState* viewportState) { |
| 3655 if (!weakScrollView) | 3615 if (!weakScrollView) |
| 3656 return; | 3616 return; |
| 3657 base::scoped_nsobject<UIScrollView> scrollView([weakScrollView retain]); | 3617 base::scoped_nsobject<UIScrollView> scrollView([weakScrollView retain]); |
| 3658 if (viewportState && !viewportState->viewport_tag_present() && | 3618 if (viewportState && !viewportState->viewport_tag_present() && |
| 3659 [scrollView minimumZoomScale] == [scrollView maximumZoomScale] && | 3619 [scrollView minimumZoomScale] == [scrollView maximumZoomScale] && |
| 3660 [scrollView zoomScale] > 1.0) { | 3620 [scrollView zoomScale] > 1.0) { |
| 3661 UMA_HISTOGRAM_BOOLEAN(kUMAViewportZoomBugCount, true); | 3621 UMA_HISTOGRAM_BOOLEAN(kUMAViewportZoomBugCount, true); |
| 3662 } | 3622 } |
| 3663 }]; | 3623 }]; |
| 3664 } | 3624 } |
| 3665 | 3625 |
| 3666 - (void)webViewScrollViewDidResetContentSize: | 3626 - (void)webViewScrollViewDidResetContentSize: |
| 3667 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { | 3627 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { |
| 3668 web::NavigationItem* currentItem = [self currentNavItem]; | 3628 web::NavigationItem* currentItem = self.currentNavItem; |
| 3669 if (webViewScrollViewProxy.isZooming || _applyingPageState || !currentItem) | 3629 if (webViewScrollViewProxy.isZooming || _applyingPageState || !currentItem) |
| 3670 return; | 3630 return; |
| 3671 CGSize contentSize = webViewScrollViewProxy.contentSize; | 3631 CGSize contentSize = webViewScrollViewProxy.contentSize; |
| 3672 if (contentSize.width < CGRectGetWidth(webViewScrollViewProxy.frame)) { | 3632 if (contentSize.width < CGRectGetWidth(webViewScrollViewProxy.frame)) { |
| 3673 // The renderer incorrectly resized the content area. Resetting the scroll | 3633 // The renderer incorrectly resized the content area. Resetting the scroll |
| 3674 // view's zoom scale will force a re-rendering. rdar://23963992 | 3634 // view's zoom scale will force a re-rendering. rdar://23963992 |
| 3675 _applyingPageState = YES; | 3635 _applyingPageState = YES; |
| 3676 web::PageZoomState zoomState = | 3636 web::PageZoomState zoomState = |
| 3677 currentItem->GetPageDisplayState().zoom_state(); | 3637 currentItem->GetPageDisplayState().zoom_state(); |
| 3678 if (!zoomState.IsValid()) | 3638 if (!zoomState.IsValid()) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3703 completionHandler:nil]; | 3663 completionHandler:nil]; |
| 3704 } | 3664 } |
| 3705 | 3665 |
| 3706 #pragma mark - | 3666 #pragma mark - |
| 3707 #pragma mark Page State | 3667 #pragma mark Page State |
| 3708 | 3668 |
| 3709 - (void)recordStateInHistory { | 3669 - (void)recordStateInHistory { |
| 3710 // Only record the state if: | 3670 // Only record the state if: |
| 3711 // - the current NavigationItem's URL matches the current URL, and | 3671 // - the current NavigationItem's URL matches the current URL, and |
| 3712 // - the user has interacted with the page. | 3672 // - the user has interacted with the page. |
| 3713 CRWSessionEntry* current = [self currentSessionEntry]; | 3673 web::NavigationItem* item = self.currentNavItem; |
| 3714 if (current && [current navigationItem]->GetURL() == [self currentURL] && | 3674 if (item && item->GetURL() == [self currentURL] && |
| 3715 self.userInteractionRegistered) { | 3675 self.userInteractionRegistered) { |
| 3716 [current navigationItem]->SetPageDisplayState(self.pageDisplayState); | 3676 item->SetPageDisplayState(self.pageDisplayState); |
| 3717 } | 3677 } |
| 3718 } | 3678 } |
| 3719 | 3679 |
| 3720 - (void)restoreStateFromHistory { | 3680 - (void)restoreStateFromHistory { |
| 3721 CRWSessionEntry* current = [self currentSessionEntry]; | 3681 web::NavigationItem* item = self.currentNavItem; |
| 3722 if ([current navigationItem]) | 3682 if (item) |
| 3723 self.pageDisplayState = [current navigationItem]->GetPageDisplayState(); | 3683 self.pageDisplayState = item->GetPageDisplayState(); |
| 3724 } | 3684 } |
| 3725 | 3685 |
| 3726 - (web::PageDisplayState)pageDisplayState { | 3686 - (web::PageDisplayState)pageDisplayState { |
| 3727 web::PageDisplayState displayState; | 3687 web::PageDisplayState displayState; |
| 3728 if (_webView) { | 3688 if (_webView) { |
| 3729 CGPoint scrollOffset = [self scrollPosition]; | 3689 CGPoint scrollOffset = [self scrollPosition]; |
| 3730 displayState.scroll_state().set_offset_x(std::floor(scrollOffset.x)); | 3690 displayState.scroll_state().set_offset_x(std::floor(scrollOffset.x)); |
| 3731 displayState.scroll_state().set_offset_y(std::floor(scrollOffset.y)); | 3691 displayState.scroll_state().set_offset_y(std::floor(scrollOffset.y)); |
| 3732 UIScrollView* scrollView = self.webScrollView; | 3692 UIScrollView* scrollView = self.webScrollView; |
| 3733 displayState.zoom_state().set_minimum_zoom_scale( | 3693 displayState.zoom_state().set_minimum_zoom_scale( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3754 currentPageDisplayState.scroll_state().offset_y() == | 3714 currentPageDisplayState.scroll_state().offset_y() == |
| 3755 _displayStateOnStartLoading.scroll_state().offset_y() && | 3715 _displayStateOnStartLoading.scroll_state().offset_y() && |
| 3756 !_pageHasZoomed) { | 3716 !_pageHasZoomed) { |
| 3757 [self applyPageDisplayState:displayState]; | 3717 [self applyPageDisplayState:displayState]; |
| 3758 } | 3718 } |
| 3759 } | 3719 } |
| 3760 } | 3720 } |
| 3761 | 3721 |
| 3762 - (void)extractViewportTagWithCompletion:(ViewportStateCompletion)completion { | 3722 - (void)extractViewportTagWithCompletion:(ViewportStateCompletion)completion { |
| 3763 DCHECK(completion); | 3723 DCHECK(completion); |
| 3764 web::NavigationItem* currentItem = [self currentNavItem]; | 3724 web::NavigationItem* currentItem = self.currentNavItem; |
| 3765 if (!currentItem) { | 3725 if (!currentItem) { |
| 3766 completion(nullptr); | 3726 completion(nullptr); |
| 3767 return; | 3727 return; |
| 3768 } | 3728 } |
| 3769 NSString* const kViewportContentQuery = | 3729 NSString* const kViewportContentQuery = |
| 3770 @"var viewport = document.querySelector('meta[name=\"viewport\"]');" | 3730 @"var viewport = document.querySelector('meta[name=\"viewport\"]');" |
| 3771 "viewport ? viewport.content : '';"; | 3731 "viewport ? viewport.content : '';"; |
| 3772 base::WeakNSObject<CRWWebController> weakSelf(self); | 3732 base::WeakNSObject<CRWWebController> weakSelf(self); |
| 3773 int itemID = currentItem->GetUniqueID(); | 3733 int itemID = currentItem->GetUniqueID(); |
| 3774 [self executeJavaScript:kViewportContentQuery | 3734 [self executeJavaScript:kViewportContentQuery |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3827 userScalable:viewportState->user_scalable()]; | 3787 userScalable:viewportState->user_scalable()]; |
| 3828 } | 3788 } |
| 3829 }]; | 3789 }]; |
| 3830 } | 3790 } |
| 3831 | 3791 |
| 3832 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState | 3792 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState |
| 3833 userScalable:(BOOL)isUserScalable { | 3793 userScalable:(BOOL)isUserScalable { |
| 3834 // Early return if |scrollState| doesn't match the current NavigationItem. | 3794 // Early return if |scrollState| doesn't match the current NavigationItem. |
| 3835 // This can sometimes occur in tests, as navigation occurs programmatically | 3795 // This can sometimes occur in tests, as navigation occurs programmatically |
| 3836 // and |-applyPageScrollState:| is asynchronous. | 3796 // and |-applyPageScrollState:| is asynchronous. |
| 3837 web::NavigationItem* currentItem = [self currentSessionEntry].navigationItem; | 3797 web::NavigationItem* currentItem = self.currentNavItem; |
| 3838 if (currentItem && currentItem->GetPageDisplayState() != displayState) | 3798 if (currentItem && currentItem->GetPageDisplayState() != displayState) |
| 3839 return; | 3799 return; |
| 3840 DCHECK(displayState.IsValid()); | 3800 DCHECK(displayState.IsValid()); |
| 3841 _applyingPageState = YES; | 3801 _applyingPageState = YES; |
| 3842 if (isUserScalable) { | 3802 if (isUserScalable) { |
| 3843 [self prepareToApplyWebViewScrollZoomScale]; | 3803 [self prepareToApplyWebViewScrollZoomScale]; |
| 3844 [self applyWebViewScrollZoomScaleFromZoomState:displayState.zoom_state()]; | 3804 [self applyWebViewScrollZoomScaleFromZoomState:displayState.zoom_state()]; |
| 3845 [self finishApplyingWebViewScrollZoomScale]; | 3805 [self finishApplyingWebViewScrollZoomScale]; |
| 3846 } | 3806 } |
| 3847 [self applyWebViewScrollOffsetFromScrollState:displayState.scroll_state()]; | 3807 [self applyWebViewScrollOffsetFromScrollState:displayState.scroll_state()]; |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4240 _injectedScriptManagers.reset([[NSMutableSet alloc] init]); | 4200 _injectedScriptManagers.reset([[NSMutableSet alloc] init]); |
| 4241 [self setDocumentURL:_defaultURL]; | 4201 [self setDocumentURL:_defaultURL]; |
| 4242 } | 4202 } |
| 4243 | 4203 |
| 4244 - (void)removeWebViewAllowingCachedReconstruction:(BOOL)allowCache { | 4204 - (void)removeWebViewAllowingCachedReconstruction:(BOOL)allowCache { |
| 4245 if (!_webView) | 4205 if (!_webView) |
| 4246 return; | 4206 return; |
| 4247 | 4207 |
| 4248 _webStateImpl->CancelDialogs(); | 4208 _webStateImpl->CancelDialogs(); |
| 4249 | 4209 |
| 4250 web::NavigationItem* item = [self currentNavItem]; | 4210 web::NavigationItem* item = self.currentNavItem; |
| 4251 if (allowCache && item) { | 4211 if (allowCache && item) { |
| 4252 _expectedReconstructionURL = item->GetVirtualURL(); | 4212 _expectedReconstructionURL = item->GetVirtualURL(); |
| 4253 } else { | 4213 } else { |
| 4254 _expectedReconstructionURL = GURL::EmptyGURL(); | 4214 _expectedReconstructionURL = GURL::EmptyGURL(); |
| 4255 } | 4215 } |
| 4256 | 4216 |
| 4257 [self abortLoad]; | 4217 [self abortLoad]; |
| 4258 [_webView removeFromSuperview]; | 4218 [_webView removeFromSuperview]; |
| 4259 [_containerView resetContent]; | 4219 [_containerView resetContent]; |
| 4260 [self setWebView:nil]; | 4220 [self setWebView:nil]; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4322 } | 4282 } |
| 4323 | 4283 |
| 4324 - (void)stopLoading { | 4284 - (void)stopLoading { |
| 4325 _stoppedWKNavigation.reset([_navigationStates lastAddedNavigation]); | 4285 _stoppedWKNavigation.reset([_navigationStates lastAddedNavigation]); |
| 4326 | 4286 |
| 4327 base::RecordAction(UserMetricsAction("Stop")); | 4287 base::RecordAction(UserMetricsAction("Stop")); |
| 4328 // Discard the pending and transient entried before notifying the tab model | 4288 // Discard the pending and transient entried before notifying the tab model |
| 4329 // observers of the change via |-abortLoad|. | 4289 // observers of the change via |-abortLoad|. |
| 4330 [[self sessionController] discardNonCommittedItems]; | 4290 [[self sessionController] discardNonCommittedItems]; |
| 4331 [self abortLoad]; | 4291 [self abortLoad]; |
| 4332 web::NavigationItem* item = [self currentNavItem]; | 4292 web::NavigationItem* item = self.currentNavItem; |
| 4333 GURL navigationURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); | 4293 GURL navigationURL = item ? item->GetVirtualURL() : GURL::EmptyGURL(); |
| 4334 // If discarding the non-committed entries results in an app-specific URL, | 4294 // If discarding the non-committed entries results in an app-specific URL, |
| 4335 // reload it in its native view. | 4295 // reload it in its native view. |
| 4336 if (!self.nativeController && | 4296 if (!self.nativeController && |
| 4337 [self shouldLoadURLInNativeView:navigationURL]) { | 4297 [self shouldLoadURLInNativeView:navigationURL]) { |
| 4338 [self loadCurrentURLInNativeView]; | 4298 [self loadCurrentURLInNativeView]; |
| 4339 } | 4299 } |
| 4340 } | 4300 } |
| 4341 | 4301 |
| 4342 #pragma mark - | 4302 #pragma mark - |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5046 if (self.loadPhase != web::LOAD_REQUESTED) | 5006 if (self.loadPhase != web::LOAD_REQUESTED) |
| 5047 return NO; | 5007 return NO; |
| 5048 | 5008 |
| 5049 web::NavigationItem* pendingItem = | 5009 web::NavigationItem* pendingItem = |
| 5050 self.webState->GetNavigationManager()->GetPendingItem(); | 5010 self.webState->GetNavigationManager()->GetPendingItem(); |
| 5051 return pendingItem && pendingItem->GetURL() == targetURL; | 5011 return pendingItem && pendingItem->GetURL() == targetURL; |
| 5052 } | 5012 } |
| 5053 | 5013 |
| 5054 - (void)loadRequestForCurrentNavigationItem { | 5014 - (void)loadRequestForCurrentNavigationItem { |
| 5055 DCHECK(_webView && !self.nativeController); | 5015 DCHECK(_webView && !self.nativeController); |
| 5056 DCHECK([self currentSessionEntry]); | 5016 DCHECK(self.currentNavItem); |
| 5057 // If a load is kicked off on a WKWebView with a frame whose size is {0, 0} or | 5017 // If a load is kicked off on a WKWebView with a frame whose size is {0, 0} or |
| 5058 // that has a negative dimension for a size, rendering issues occur that | 5018 // that has a negative dimension for a size, rendering issues occur that |
| 5059 // manifest in erroneous scrolling and tap handling (crbug.com/574996, | 5019 // manifest in erroneous scrolling and tap handling (crbug.com/574996, |
| 5060 // crbug.com/577793). | 5020 // crbug.com/577793). |
| 5061 DCHECK_GT(CGRectGetWidth([_webView frame]), 0.0); | 5021 DCHECK_GT(CGRectGetWidth([_webView frame]), 0.0); |
| 5062 DCHECK_GT(CGRectGetHeight([_webView frame]), 0.0); | 5022 DCHECK_GT(CGRectGetHeight([_webView frame]), 0.0); |
| 5063 | 5023 |
| 5064 web::WKBackForwardListItemHolder* holder = | 5024 web::WKBackForwardListItemHolder* holder = |
| 5065 [self currentBackForwardListItemHolder]; | 5025 [self currentBackForwardListItemHolder]; |
| 5066 BOOL repostedForm = | 5026 BOOL repostedForm = |
| 5067 [holder->http_method() isEqual:@"POST"] && | 5027 [holder->http_method() isEqual:@"POST"] && |
| 5068 (holder->navigation_type() == WKNavigationTypeFormResubmitted || | 5028 (holder->navigation_type() == WKNavigationTypeFormResubmitted || |
| 5069 holder->navigation_type() == WKNavigationTypeFormSubmitted); | 5029 holder->navigation_type() == WKNavigationTypeFormSubmitted); |
| 5070 web::NavigationItemImpl* currentItem = | 5030 web::NavigationItemImpl* currentItem = self.currentNavItem; |
| 5071 [self currentSessionEntry].navigationItemImpl; | |
| 5072 NSData* POSTData = currentItem->GetPostData(); | 5031 NSData* POSTData = currentItem->GetPostData(); |
| 5073 NSMutableURLRequest* request = [self requestForCurrentNavigationItem]; | 5032 NSMutableURLRequest* request = [self requestForCurrentNavigationItem]; |
| 5074 | 5033 |
| 5075 // If the request has POST data and is not a repost form, configure and | 5034 // If the request has POST data and is not a repost form, configure and |
| 5076 // run the POST request. | 5035 // run the POST request. |
| 5077 if (POSTData.length && !repostedForm) { | 5036 if (POSTData.length && !repostedForm) { |
| 5078 [request setHTTPMethod:@"POST"]; | 5037 [request setHTTPMethod:@"POST"]; |
| 5079 [request setHTTPBody:POSTData]; | 5038 [request setHTTPBody:POSTData]; |
| 5080 [request setAllHTTPHeaderFields:[self currentHTTPHeaders]]; | 5039 [request setAllHTTPHeaderFields:self.currentHTTPHeaders]; |
| 5081 GURL navigationURL = | 5040 GURL navigationURL = |
| 5082 currentItem ? currentItem->GetURL() : GURL::EmptyGURL(); | 5041 currentItem ? currentItem->GetURL() : GURL::EmptyGURL(); |
| 5083 [self registerLoadRequest:navigationURL | 5042 [self registerLoadRequest:navigationURL |
| 5084 referrer:[self currentSessionEntryReferrer] | 5043 referrer:self.currentNavItemReferrer |
| 5085 transition:[self currentTransition]]; | 5044 transition:self.currentTransition]; |
| 5086 [self loadPOSTRequest:request]; | 5045 [self loadPOSTRequest:request]; |
| 5087 return; | 5046 return; |
| 5088 } | 5047 } |
| 5089 | 5048 |
| 5090 ProceduralBlock defaultNavigationBlock = ^{ | 5049 ProceduralBlock defaultNavigationBlock = ^{ |
| 5091 web::NavigationItem* item = [self currentNavItem]; | 5050 web::NavigationItem* item = self.currentNavItem; |
| 5092 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); | 5051 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 5093 [self registerLoadRequest:navigationURL | 5052 [self registerLoadRequest:navigationURL |
| 5094 referrer:[self currentSessionEntryReferrer] | 5053 referrer:self.currentNavItemReferrer |
| 5095 transition:[self currentTransition]]; | 5054 transition:self.currentTransition]; |
| 5096 [self loadRequest:request]; | 5055 [self loadRequest:request]; |
| 5097 }; | 5056 }; |
| 5098 | 5057 |
| 5099 // When navigating via WKBackForwardListItem to pages created or updated by | 5058 // When navigating via WKBackForwardListItem to pages created or updated by |
| 5100 // calls to pushState() and replaceState(), sometimes core.js is not injected | 5059 // calls to pushState() and replaceState(), sometimes core.js is not injected |
| 5101 // correctly. This means that calling window.history navigation functions | 5060 // correctly. This means that calling window.history navigation functions |
| 5102 // will invoke WKWebView's non-overridden implementations, causing a mismatch | 5061 // will invoke WKWebView's non-overridden implementations, causing a mismatch |
| 5103 // between the WKBackForwardList and NavigationManager. | 5062 // between the WKBackForwardList and NavigationManager. |
| 5104 // TODO(crbug.com/659816): Figure out how to prevent core.js injection flake. | 5063 // TODO(crbug.com/659816): Figure out how to prevent core.js injection flake. |
| 5105 if (currentItem->HasStateBeenReplaced() || | 5064 if (currentItem->HasStateBeenReplaced() || |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5116 ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { | 5075 ![self isBackForwardListItemValid:holder->back_forward_list_item()]) { |
| 5117 defaultNavigationBlock(); | 5076 defaultNavigationBlock(); |
| 5118 return; | 5077 return; |
| 5119 } | 5078 } |
| 5120 | 5079 |
| 5121 ProceduralBlock webViewNavigationBlock = ^{ | 5080 ProceduralBlock webViewNavigationBlock = ^{ |
| 5122 // If the current navigation URL is the same as the URL of the visible | 5081 // If the current navigation URL is the same as the URL of the visible |
| 5123 // page, that means the user requested a reload. |goToBackForwardListItem| | 5082 // page, that means the user requested a reload. |goToBackForwardListItem| |
| 5124 // will be a no-op when it is passed the current back forward list item, | 5083 // will be a no-op when it is passed the current back forward list item, |
| 5125 // so |reload| must be explicitly called. | 5084 // so |reload| must be explicitly called. |
| 5126 web::NavigationItem* item = [self currentNavItem]; | 5085 web::NavigationItem* item = self.currentNavItem; |
| 5127 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); | 5086 GURL navigationURL = item ? item->GetURL() : GURL::EmptyGURL(); |
| 5128 [self registerLoadRequest:navigationURL | 5087 [self registerLoadRequest:navigationURL |
| 5129 referrer:[self currentSessionEntryReferrer] | 5088 referrer:self.currentNavItemReferrer |
| 5130 transition:[self currentTransition]]; | 5089 transition:self.currentTransition]; |
| 5131 if (navigationURL == net::GURLWithNSURL([_webView URL])) { | 5090 if (navigationURL == net::GURLWithNSURL([_webView URL])) { |
| 5132 [_navigationStates setState:web::WKNavigationState::REQUESTED | 5091 [_navigationStates setState:web::WKNavigationState::REQUESTED |
| 5133 forNavigation:[_webView reload]]; | 5092 forNavigation:[_webView reload]]; |
| 5134 } else { | 5093 } else { |
| 5135 // |didCommitNavigation:| may not be called for fast navigation, so update | 5094 // |didCommitNavigation:| may not be called for fast navigation, so update |
| 5136 // the navigation type now as it is already known. | 5095 // the navigation type now as it is already known. |
| 5137 holder->set_navigation_type(WKNavigationTypeBackForward); | 5096 holder->set_navigation_type(WKNavigationTypeBackForward); |
| 5138 WKNavigation* navigation = | 5097 WKNavigation* navigation = |
| 5139 [_webView goToBackForwardListItem:holder->back_forward_list_item()]; | 5098 [_webView goToBackForwardListItem:holder->back_forward_list_item()]; |
| 5140 [_navigationStates setState:web::WKNavigationState::REQUESTED | 5099 [_navigationStates setState:web::WKNavigationState::REQUESTED |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5220 - (void)simulateLoadRequestWithURL:(const GURL&)URL { | 5179 - (void)simulateLoadRequestWithURL:(const GURL&)URL { |
| 5221 _lastRegisteredRequestURL = URL; | 5180 _lastRegisteredRequestURL = URL; |
| 5222 _loadPhase = web::LOAD_REQUESTED; | 5181 _loadPhase = web::LOAD_REQUESTED; |
| 5223 } | 5182 } |
| 5224 | 5183 |
| 5225 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { | 5184 - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action { |
| 5226 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; | 5185 return [action.request valueForHTTPHeaderField:kReferrerHeaderName]; |
| 5227 } | 5186 } |
| 5228 | 5187 |
| 5229 @end | 5188 @end |
| OLD | NEW |