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 |