0

Always set the serialized state object for history navigations.

The state object should always be injected for history navigations if
one exists, but the new document should only be loaded for non-push
history navigations.

BUG=483709

Review URL: https://codereview.chromium.org/1353503003

Cr-Commit-Position: refs/heads/master@{#350066}
This commit is contained in:
kkhorimoto
2015-09-21 16:44:08 -07:00
committed by Commit bot
parent f1422520b4
commit a15f6f0cd8
2 changed files with 27 additions and 24 deletions

@ -185,12 +185,6 @@ class WebStateImpl;
// Loads the URL indicated by current session state.
- (void)loadCurrentURL;
// Updates UIWebView's URL and urlOnStartLoading_ during back/forward navigation
// over pushed URLs. Needed so that sites that depend on URL params/fragment
// continue to work correctly and checks for the URL don't incorrectly trigger
// -pageChanged calls.
- (void)finishPushStateNavigationToURL:(const GURL&)url
withStateObject:(NSString*)stateObject;
// Loads the HTML into the page.
- (void)loadHTML:(NSString*)html;
// Loads HTML in the page and presents it as if it was originating from an
@ -306,8 +300,8 @@ class WebStateImpl;
- (void)restoreStateAfterURLRejection;
// Helper method called at the end of history navigation methods goBack,
// goForward, and goDelta. Determines whether to load a new URL or call
// |finishPushStateNavigationToURL:withStateObject:|. |fromEntry| is the
// goForward, and goDelta. Loads a new URL if the current entry is not from a
// pushState() navigation from |fromEntry|. |fromEntry| is the
// CRWSessionEntry that was the current entry prior to the navigation.
// TODO(rohitrao): This is only exposed so Tab can call it temporarily. Remove
// as soon as all the Tab calls have moved into CRWWebController.

@ -332,8 +332,16 @@ void CancelAllTouches(UIScrollView* web_scroll_view) {
// Generates the JavaScript string used to update the UIWebView's URL so that it
// matches the URL displayed in the omnibox and sets window.history.state to
// stateObject. Needed for history.pushState() and history.replaceState().
- (NSString*)javascriptToReplaceWebViewURL:(const GURL&)url
- (NSString*)javascriptToReplaceWebViewURL:(const GURL&)URL
stateObjectJSON:(NSString*)stateObject;
// Injects JavaScript into the web view to update the URL to |URL|, to set
// window.history.state to |stateObject|, and to trigger a popstate() event.
// Upon the scripts completion, resets |urlOnStartLoading_| and
// |_lastRegisteredRequestURL| to |URL|. This is necessary so that sites that
// depend on URL params/fragments continue to work correctly and that checks for
// the URL don't incorrectly trigger |-pageChanged| calls.
- (void)setPushedOrReplacedURL:(const GURL&)URL
stateObject:(NSString*)stateObject;
- (BOOL)isLoaded;
// Called by NSNotificationCenter upon orientation changes.
- (void)orientationDidChange;
@ -1264,23 +1272,23 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5;
_webStateImpl->OnProvisionalNavigationStarted(requestURL);
}
- (NSString*)javascriptToReplaceWebViewURL:(const GURL&)url
- (NSString*)javascriptToReplaceWebViewURL:(const GURL&)URL
stateObjectJSON:(NSString*)stateObject {
std::string outURL;
base::EscapeJSONString(url.spec(), true, &outURL);
base::EscapeJSONString(URL.spec(), true, &outURL);
return
[NSString stringWithFormat:@"__gCrWeb.replaceWebViewURL(%@, %@);",
base::SysUTF8ToNSString(outURL), stateObject];
}
- (void)finishPushStateNavigationToURL:(const GURL&)url
withStateObject:(NSString*)stateObject {
- (void)setPushedOrReplacedURL:(const GURL&)URL
stateObject:(NSString*)stateObject {
// TODO(stuartmorgan): Make CRWSessionController manage this internally (or
// remove it; it's not clear this matches other platforms' behavior).
_webStateImpl->GetNavigationManagerImpl().OnNavigationItemCommitted();
NSString* replaceWebViewUrlJS =
[self javascriptToReplaceWebViewURL:url stateObjectJSON:stateObject];
[self javascriptToReplaceWebViewURL:URL stateObjectJSON:stateObject];
std::string outState;
base::EscapeJSONString(base::SysNSStringToUTF8(stateObject), true, &outState);
NSString* popstateJS =
@ -1288,7 +1296,7 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5;
base::SysUTF8ToNSString(outState)];
NSString* combinedJS =
[NSString stringWithFormat:@"%@%@", replaceWebViewUrlJS, popstateJS];
GURL urlCopy(url);
GURL urlCopy(URL);
base::WeakNSObject<CRWWebController> weakSelf(self);
[self evaluateJavaScript:combinedJS
stringResultHandler:^(NSString*, NSError*) {
@ -1774,17 +1782,18 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5;
- (void)finishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry {
[_delegate webWillFinishHistoryNavigationFromEntry:fromEntry];
// Check if toEntry was created by a JavaScript window.history.pushState()
// call from fromEntry. If it was, don't load the URL. Instead update
// UIWebView's URL and dispatch a popstate event.
if ([_webStateImpl->GetNavigationManagerImpl().GetSessionController()
// If the current entry has a serialized state object, inject its state into
// the web view.
web::NavigationItemImpl* currentItem =
self.currentSessionEntry.navigationItemImpl;
NSString* state = currentItem->GetSerializedStateObject();
if (state.length)
[self setPushedOrReplacedURL:currentItem->GetURL() stateObject:state];
// Only load the new URL if the current entry was not created by a JavaScript
// window.history.pushState() call from |fromEntry|.
if (![_webStateImpl->GetNavigationManagerImpl().GetSessionController()
isPushStateNavigationBetweenEntry:fromEntry
andEntry:self.currentSessionEntry]) {
NSString* state = [self currentSessionEntry]
.navigationItemImpl->GetSerializedStateObject();
[self finishPushStateNavigationToURL:[self currentNavigationURL]
withStateObject:state];
} else {
web::NavigationItem* currentItem =
_webStateImpl->GetNavigationManagerImpl().GetVisibleItem();
GURL endURL = [self URLForHistoryNavigationFromItem:fromEntry.navigationItem