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 <objc/runtime.h> | 7 #import <objc/runtime.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/ios/block_types.h" | 10 #include "base/ios/block_types.h" |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; | 325 - (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; |
326 // Evaluates the supplied JavaScript in the web view. Calls |handler| with | 326 // Evaluates the supplied JavaScript in the web view. Calls |handler| with |
327 // results of the evaluation (which may be nil if the implementing object has no | 327 // results of the evaluation (which may be nil if the implementing object has no |
328 // way to run the evaluation or the evaluation returns a nil value) or an | 328 // way to run the evaluation or the evaluation returns a nil value) or an |
329 // NSError if there is an error. The |handler| can be nil. | 329 // NSError if there is an error. The |handler| can be nil. |
330 - (void)evaluateJavaScript:(NSString*)script | 330 - (void)evaluateJavaScript:(NSString*)script |
331 JSONResultHandler:(void (^)(scoped_ptr<base::Value>, NSError*))handler; | 331 JSONResultHandler:(void (^)(scoped_ptr<base::Value>, NSError*))handler; |
332 // Generates the JavaScript string used to update the UIWebView's URL so that it | 332 // Generates the JavaScript string used to update the UIWebView's URL so that it |
333 // matches the URL displayed in the omnibox and sets window.history.state to | 333 // matches the URL displayed in the omnibox and sets window.history.state to |
334 // stateObject. Needed for history.pushState() and history.replaceState(). | 334 // stateObject. Needed for history.pushState() and history.replaceState(). |
335 - (NSString*)javascriptToReplaceWebViewURL:(const GURL&)url | 335 - (NSString*)javascriptToReplaceWebViewURL:(const GURL&)URL |
336 stateObjectJSON:(NSString*)stateObject; | 336 stateObjectJSON:(NSString*)stateObject; |
| 337 // Injects JavaScript into the web view to update the URL to |URL|, to set |
| 338 // window.history.state to |stateObject|, and to trigger a popstate() event. |
| 339 // Upon the scripts completion, resets |urlOnStartLoading_| and |
| 340 // |_lastRegisteredRequestURL| to |URL|. This is necessary so that sites that |
| 341 // depend on URL params/fragments continue to work correctly and that checks for |
| 342 // the URL don't incorrectly trigger |-pageChanged| calls. |
| 343 - (void)setPushedOrReplacedURL:(const GURL&)URL |
| 344 stateObject:(NSString*)stateObject; |
337 - (BOOL)isLoaded; | 345 - (BOOL)isLoaded; |
338 // Called by NSNotificationCenter upon orientation changes. | 346 // Called by NSNotificationCenter upon orientation changes. |
339 - (void)orientationDidChange; | 347 - (void)orientationDidChange; |
340 // Queries the web view for the user-scalable meta tag and calls | 348 // Queries the web view for the user-scalable meta tag and calls |
341 // |-applyPageDisplayState:userScalable:| with the result. | 349 // |-applyPageDisplayState:userScalable:| with the result. |
342 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState; | 350 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState; |
343 // Restores state of the web view's scroll view from |scrollState|. | 351 // Restores state of the web view's scroll view from |scrollState|. |
344 // |isUserScalable| represents the value of user-scalable meta tag. | 352 // |isUserScalable| represents the value of user-scalable meta tag. |
345 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState | 353 - (void)applyPageDisplayState:(const web::PageDisplayState&)displayState |
346 userScalable:(BOOL)isUserScalable; | 354 userScalable:(BOOL)isUserScalable; |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 _webStateImpl->GetCacheMode()); | 1265 _webStateImpl->GetCacheMode()); |
1258 } else if (preferCache) { | 1266 } else if (preferCache) { |
1259 _webStateImpl->GetRequestTracker()->SetCacheModeFromUIThread( | 1267 _webStateImpl->GetRequestTracker()->SetCacheModeFromUIThread( |
1260 net::RequestTracker::CACHE_HISTORY); | 1268 net::RequestTracker::CACHE_HISTORY); |
1261 } | 1269 } |
1262 _webStateImpl->SetIsLoading(true); | 1270 _webStateImpl->SetIsLoading(true); |
1263 [_delegate webDidAddPendingURL]; | 1271 [_delegate webDidAddPendingURL]; |
1264 _webStateImpl->OnProvisionalNavigationStarted(requestURL); | 1272 _webStateImpl->OnProvisionalNavigationStarted(requestURL); |
1265 } | 1273 } |
1266 | 1274 |
1267 - (NSString*)javascriptToReplaceWebViewURL:(const GURL&)url | 1275 - (NSString*)javascriptToReplaceWebViewURL:(const GURL&)URL |
1268 stateObjectJSON:(NSString*)stateObject { | 1276 stateObjectJSON:(NSString*)stateObject { |
1269 std::string outURL; | 1277 std::string outURL; |
1270 base::EscapeJSONString(url.spec(), true, &outURL); | 1278 base::EscapeJSONString(URL.spec(), true, &outURL); |
1271 return | 1279 return |
1272 [NSString stringWithFormat:@"__gCrWeb.replaceWebViewURL(%@, %@);", | 1280 [NSString stringWithFormat:@"__gCrWeb.replaceWebViewURL(%@, %@);", |
1273 base::SysUTF8ToNSString(outURL), stateObject]; | 1281 base::SysUTF8ToNSString(outURL), stateObject]; |
1274 } | 1282 } |
1275 | 1283 |
1276 - (void)finishPushStateNavigationToURL:(const GURL&)url | 1284 - (void)setPushedOrReplacedURL:(const GURL&)URL |
1277 withStateObject:(NSString*)stateObject { | 1285 stateObject:(NSString*)stateObject { |
1278 // TODO(stuartmorgan): Make CRWSessionController manage this internally (or | 1286 // TODO(stuartmorgan): Make CRWSessionController manage this internally (or |
1279 // remove it; it's not clear this matches other platforms' behavior). | 1287 // remove it; it's not clear this matches other platforms' behavior). |
1280 _webStateImpl->GetNavigationManagerImpl().OnNavigationItemCommitted(); | 1288 _webStateImpl->GetNavigationManagerImpl().OnNavigationItemCommitted(); |
1281 | 1289 |
1282 NSString* replaceWebViewUrlJS = | 1290 NSString* replaceWebViewUrlJS = |
1283 [self javascriptToReplaceWebViewURL:url stateObjectJSON:stateObject]; | 1291 [self javascriptToReplaceWebViewURL:URL stateObjectJSON:stateObject]; |
1284 std::string outState; | 1292 std::string outState; |
1285 base::EscapeJSONString(base::SysNSStringToUTF8(stateObject), true, &outState); | 1293 base::EscapeJSONString(base::SysNSStringToUTF8(stateObject), true, &outState); |
1286 NSString* popstateJS = | 1294 NSString* popstateJS = |
1287 [NSString stringWithFormat:@"__gCrWeb.dispatchPopstateEvent(%@);", | 1295 [NSString stringWithFormat:@"__gCrWeb.dispatchPopstateEvent(%@);", |
1288 base::SysUTF8ToNSString(outState)]; | 1296 base::SysUTF8ToNSString(outState)]; |
1289 NSString* combinedJS = | 1297 NSString* combinedJS = |
1290 [NSString stringWithFormat:@"%@%@", replaceWebViewUrlJS, popstateJS]; | 1298 [NSString stringWithFormat:@"%@%@", replaceWebViewUrlJS, popstateJS]; |
1291 GURL urlCopy(url); | 1299 GURL urlCopy(URL); |
1292 base::WeakNSObject<CRWWebController> weakSelf(self); | 1300 base::WeakNSObject<CRWWebController> weakSelf(self); |
1293 [self evaluateJavaScript:combinedJS | 1301 [self evaluateJavaScript:combinedJS |
1294 stringResultHandler:^(NSString*, NSError*) { | 1302 stringResultHandler:^(NSString*, NSError*) { |
1295 if (!weakSelf || weakSelf.get()->_isBeingDestroyed) | 1303 if (!weakSelf || weakSelf.get()->_isBeingDestroyed) |
1296 return; | 1304 return; |
1297 base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); | 1305 base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); |
1298 strongSelf.get()->_URLOnStartLoading = urlCopy; | 1306 strongSelf.get()->_URLOnStartLoading = urlCopy; |
1299 strongSelf.get()->_lastRegisteredRequestURL = urlCopy; | 1307 strongSelf.get()->_lastRegisteredRequestURL = urlCopy; |
1300 }]; | 1308 }]; |
1301 } | 1309 } |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 [self restoreStateFromHistory]; | 1775 [self restoreStateFromHistory]; |
1768 _webStateImpl->OnPageLoaded(currentURL, loadSuccess); | 1776 _webStateImpl->OnPageLoaded(currentURL, loadSuccess); |
1769 _webStateImpl->SetIsLoading(false); | 1777 _webStateImpl->SetIsLoading(false); |
1770 // Inform the embedder the load completed. | 1778 // Inform the embedder the load completed. |
1771 [_delegate webDidFinishWithURL:currentURL loadSuccess:loadSuccess]; | 1779 [_delegate webDidFinishWithURL:currentURL loadSuccess:loadSuccess]; |
1772 } | 1780 } |
1773 | 1781 |
1774 - (void)finishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry { | 1782 - (void)finishHistoryNavigationFromEntry:(CRWSessionEntry*)fromEntry { |
1775 [_delegate webWillFinishHistoryNavigationFromEntry:fromEntry]; | 1783 [_delegate webWillFinishHistoryNavigationFromEntry:fromEntry]; |
1776 | 1784 |
1777 // Check if toEntry was created by a JavaScript window.history.pushState() | 1785 // If the current entry has a serialized state object, inject its state into |
1778 // call from fromEntry. If it was, don't load the URL. Instead update | 1786 // the web view. |
1779 // UIWebView's URL and dispatch a popstate event. | 1787 web::NavigationItemImpl* currentItem = |
1780 if ([_webStateImpl->GetNavigationManagerImpl().GetSessionController() | 1788 self.currentSessionEntry.navigationItemImpl; |
| 1789 NSString* state = currentItem->GetSerializedStateObject(); |
| 1790 if (state.length) |
| 1791 [self setPushedOrReplacedURL:currentItem->GetURL() stateObject:state]; |
| 1792 // Only load the new URL if the current entry was not created by a JavaScript |
| 1793 // window.history.pushState() call from |fromEntry|. |
| 1794 if (![_webStateImpl->GetNavigationManagerImpl().GetSessionController() |
1781 isPushStateNavigationBetweenEntry:fromEntry | 1795 isPushStateNavigationBetweenEntry:fromEntry |
1782 andEntry:self.currentSessionEntry]) { | 1796 andEntry:self.currentSessionEntry]) { |
1783 NSString* state = [self currentSessionEntry] | |
1784 .navigationItemImpl->GetSerializedStateObject(); | |
1785 [self finishPushStateNavigationToURL:[self currentNavigationURL] | |
1786 withStateObject:state]; | |
1787 } else { | |
1788 web::NavigationItem* currentItem = | 1797 web::NavigationItem* currentItem = |
1789 _webStateImpl->GetNavigationManagerImpl().GetVisibleItem(); | 1798 _webStateImpl->GetNavigationManagerImpl().GetVisibleItem(); |
1790 GURL endURL = [self URLForHistoryNavigationFromItem:fromEntry.navigationItem | 1799 GURL endURL = [self URLForHistoryNavigationFromItem:fromEntry.navigationItem |
1791 toItem:currentItem]; | 1800 toItem:currentItem]; |
1792 ui::PageTransition transition = ui::PageTransitionFromInt( | 1801 ui::PageTransition transition = ui::PageTransitionFromInt( |
1793 ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); | 1802 ui::PAGE_TRANSITION_RELOAD | ui::PAGE_TRANSITION_FORWARD_BACK); |
1794 | 1803 |
1795 web::WebLoadParams params(endURL); | 1804 web::WebLoadParams params(endURL); |
1796 if (currentItem) { | 1805 if (currentItem) { |
1797 params.referrer = currentItem->GetReferrer(); | 1806 params.referrer = currentItem->GetReferrer(); |
(...skipping 2013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3811 if (!_externalRequest || !_externalRequest->window_name) | 3820 if (!_externalRequest || !_externalRequest->window_name) |
3812 return @""; | 3821 return @""; |
3813 return _externalRequest->window_name; | 3822 return _externalRequest->window_name; |
3814 } | 3823 } |
3815 | 3824 |
3816 - (void)resetExternalRequest { | 3825 - (void)resetExternalRequest { |
3817 _externalRequest.reset(); | 3826 _externalRequest.reset(); |
3818 } | 3827 } |
3819 | 3828 |
3820 @end | 3829 @end |
OLD | NEW |