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/chrome/browser/tabs/tab_model.h" | 5 #import "ios/chrome/browser/tabs/tab_model.h" |
6 | 6 |
7 #include <cstdint> | 7 #include <cstdint> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 // Used to ensure thread-safety of the certificate policy management code. | 187 // Used to ensure thread-safety of the certificate policy management code. |
188 base::CancelableTaskTracker _clearPoliciesTaskTracker; | 188 base::CancelableTaskTracker _clearPoliciesTaskTracker; |
189 } | 189 } |
190 | 190 |
191 // Session window for the contents of the tab model. | 191 // Session window for the contents of the tab model. |
192 @property(nonatomic, readonly) SessionWindowIOS* windowForSavingSession; | 192 @property(nonatomic, readonly) SessionWindowIOS* windowForSavingSession; |
193 | 193 |
194 // Returns YES if tab URL host indicates that tab is an NTP tab. | 194 // Returns YES if tab URL host indicates that tab is an NTP tab. |
195 - (BOOL)isNTPTab:(Tab*)tab; | 195 - (BOOL)isNTPTab:(Tab*)tab; |
196 | 196 |
197 // Opens a tab at the specified URL and registers its JS-supplied window name if | |
198 // appropriate. For certain transition types, will consult the order controller | |
199 // and thus may only use |index| as a hint. |parentTab| may be nil if there | |
200 // is no parent associated with this new tab, as may |windowName| if not | |
201 // applicable. |openedByDOM| is YES if the page was opened by DOM. | |
202 // The |index| parameter can be set to | |
203 // TabModelConstants::kTabPositionAutomatically if the caller doesn't have a | |
204 // preference for the position of the tab. | |
205 - (Tab*)insertTabWithLoadParams: | |
206 (const web::NavigationManager::WebLoadParams&)params | |
207 windowName:(NSString*)windowName | |
208 opener:(Tab*)parentTab | |
209 openedByDOM:(BOOL)openedByDOM | |
210 atIndex:(NSUInteger)index | |
211 inBackground:(BOOL)inBackground; | |
212 | |
213 // Call to switch the selected tab. Broadcasts about the change in selection. | 197 // Call to switch the selected tab. Broadcasts about the change in selection. |
214 // It's ok for |newTab| to be nil in case the last tab is going away. In that | 198 // It's ok for |newTab| to be nil in case the last tab is going away. In that |
215 // case, the "tab deselected" notification gets sent, but no corresponding | 199 // case, the "tab deselected" notification gets sent, but no corresponding |
216 // "tab selected" notification is sent. |persist| indicates whether or not | 200 // "tab selected" notification is sent. |persist| indicates whether or not |
217 // the tab's state should be persisted in history upon switching. | 201 // the tab's state should be persisted in history upon switching. |
218 - (void)changeSelectedTabFrom:(Tab*)oldTab | 202 - (void)changeSelectedTabFrom:(Tab*)oldTab |
219 to:(Tab*)newTab | 203 to:(Tab*)newTab |
220 persistState:(BOOL)persist; | 204 persistState:(BOOL)persist; |
221 | 205 |
222 // Tells the snapshot cache the adjacent tab session ids. | 206 // Tells the snapshot cache the adjacent tab session ids. |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 402 |
419 - (NSUInteger)indexOfTab:(Tab*)tab { | 403 - (NSUInteger)indexOfTab:(Tab*)tab { |
420 int index = _webStateList.GetIndexOfWebState(tab.webState); | 404 int index = _webStateList.GetIndexOfWebState(tab.webState); |
421 if (index == WebStateList::kInvalidIndex) | 405 if (index == WebStateList::kInvalidIndex) |
422 return NSNotFound; | 406 return NSNotFound; |
423 | 407 |
424 DCHECK_GE(index, 0); | 408 DCHECK_GE(index, 0); |
425 return static_cast<NSUInteger>(index); | 409 return static_cast<NSUInteger>(index); |
426 } | 410 } |
427 | 411 |
428 - (Tab*)tabWithWindowName:(NSString*)windowName { | |
429 if (!windowName) | |
430 return nil; | |
431 for (Tab* tab in self) { | |
432 if ([windowName isEqualToString:tab.windowName]) { | |
433 return tab; | |
434 } | |
435 } | |
436 return nil; | |
437 } | |
438 | |
439 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { | 412 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { |
440 int startIndex = WebStateList::kInvalidIndex; | 413 int startIndex = WebStateList::kInvalidIndex; |
441 if (afterTab) | 414 if (afterTab) |
442 startIndex = _webStateList.GetIndexOfWebState(afterTab.webState); | 415 startIndex = _webStateList.GetIndexOfWebState(afterTab.webState); |
443 | 416 |
444 if (startIndex == WebStateList::kInvalidIndex) | 417 if (startIndex == WebStateList::kInvalidIndex) |
445 startIndex = _webStateList.GetIndexOfWebState(tab.webState); | 418 startIndex = _webStateList.GetIndexOfWebState(tab.webState); |
446 | 419 |
447 const int index = _webStateList.GetIndexOfNextWebStateOpenedBy( | 420 const int index = _webStateList.GetIndexOfNextWebStateOpenedBy( |
448 tab.webState, startIndex, false); | 421 tab.webState, startIndex, false); |
(...skipping 20 matching lines...) Expand all Loading... |
469 | 442 |
470 - (Tab*)openerOfTab:(Tab*)tab { | 443 - (Tab*)openerOfTab:(Tab*)tab { |
471 int index = _webStateList.GetIndexOfWebState(tab.webState); | 444 int index = _webStateList.GetIndexOfWebState(tab.webState); |
472 if (index == WebStateList::kInvalidIndex) | 445 if (index == WebStateList::kInvalidIndex) |
473 return nil; | 446 return nil; |
474 | 447 |
475 web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index); | 448 web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index); |
476 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; | 449 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; |
477 } | 450 } |
478 | 451 |
479 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL | 452 - (Tab*)insertTabWithURL:(const GURL&)URL |
480 referrer:(const web::Referrer&)referrer | 453 referrer:(const web::Referrer&)referrer |
481 transition:(ui::PageTransition)transition | 454 transition:(ui::PageTransition)transition |
482 windowName:(NSString*)windowName | 455 opener:(Tab*)parentTab |
483 opener:(Tab*)parentTab | 456 openedByDOM:(BOOL)openedByDOM |
484 openedByDOM:(BOOL)openedByDOM | 457 atIndex:(NSUInteger)index |
485 atIndex:(NSUInteger)index | 458 inBackground:(BOOL)inBackground { |
486 inBackground:(BOOL)inBackground { | |
487 web::NavigationManager::WebLoadParams params(URL); | 459 web::NavigationManager::WebLoadParams params(URL); |
488 params.referrer = referrer; | 460 params.referrer = referrer; |
489 params.transition_type = transition; | 461 params.transition_type = transition; |
490 return [self insertOrUpdateTabWithLoadParams:params | 462 return [self insertTabWithLoadParams:params |
491 windowName:windowName | 463 opener:parentTab |
492 opener:parentTab | 464 openedByDOM:openedByDOM |
493 openedByDOM:openedByDOM | 465 atIndex:index |
494 atIndex:index | 466 inBackground:inBackground]; |
495 inBackground:inBackground]; | |
496 } | 467 } |
497 | 468 |
498 - (Tab*)insertOrUpdateTabWithLoadParams: | 469 - (Tab*)insertTabWithLoadParams: |
499 (const web::NavigationManager::WebLoadParams&)loadParams | 470 (const web::NavigationManager::WebLoadParams&)params |
500 windowName:(NSString*)windowName | 471 opener:(Tab*)parentTab |
501 opener:(Tab*)parentTab | 472 openedByDOM:(BOOL)openedByDOM |
502 openedByDOM:(BOOL)openedByDOM | 473 atIndex:(NSUInteger)index |
503 atIndex:(NSUInteger)index | 474 inBackground:(BOOL)inBackground { |
504 inBackground:(BOOL)inBackground { | 475 DCHECK(_browserState); |
505 // Find the tab for the given window name. If found, load with | 476 base::scoped_nsobject<Tab> tab([[Tab alloc] initWithBrowserState:_browserState |
506 // |originalParams| in it, otherwise create a new tab for it. | 477 opener:parentTab |
507 Tab* tab = [self tabWithWindowName:windowName]; | 478 openedByDOM:openedByDOM |
508 if (tab) { | 479 model:self]); |
509 // Updating a tab shouldn't be possible with web usage suspended, since | 480 [tab webController].webUsageEnabled = webUsageEnabled_; |
510 // whatever page would be driving it should also be suspended. | |
511 DCHECK(webUsageEnabled_); | |
512 | 481 |
513 web::NavigationManager::WebLoadParams updatedParams(loadParams); | 482 [self insertTab:tab |
514 updatedParams.is_renderer_initiated = (parentTab != nil); | 483 atIndex:index |
515 [tab.webController loadWithParams:updatedParams]; | 484 opener:parentTab |
| 485 transition:params.transition_type]; |
516 | 486 |
517 // Force the page to start loading even if it's in the background. | 487 if (!inBackground && _tabUsageRecorder) |
518 [tab.webController triggerPendingLoad]; | 488 _tabUsageRecorder->TabCreatedForSelection(tab); |
519 | 489 |
520 if (!inBackground) | 490 [[tab webController] loadWithParams:params]; |
521 [self setCurrentTab:tab]; | 491 // Force the page to start loading even if it's in the background. |
522 } else { | 492 if (webUsageEnabled_) |
523 tab = [self insertTabWithLoadParams:loadParams | 493 [[tab webController] triggerPendingLoad]; |
524 windowName:windowName | 494 NSDictionary* userInfo = @{ |
525 opener:parentTab | 495 kTabModelTabKey : tab, |
526 openedByDOM:openedByDOM | 496 kTabModelOpenInBackgroundKey : @(inBackground), |
527 atIndex:index | 497 }; |
528 inBackground:inBackground]; | 498 [[NSNotificationCenter defaultCenter] |
529 } | 499 postNotificationName:kTabModelNewTabWillOpenNotification |
| 500 object:self |
| 501 userInfo:userInfo]; |
| 502 |
| 503 if (!inBackground) |
| 504 [self setCurrentTab:tab]; |
530 | 505 |
531 return tab; | 506 return tab; |
532 } | 507 } |
533 | 508 |
534 - (Tab*)insertBlankTabWithTransition:(ui::PageTransition)transition | 509 - (Tab*)insertBlankTabWithTransition:(ui::PageTransition)transition |
535 opener:(Tab*)parentTab | 510 opener:(Tab*)parentTab |
536 openedByDOM:(BOOL)openedByDOM | 511 openedByDOM:(BOOL)openedByDOM |
537 atIndex:(NSUInteger)index | 512 atIndex:(NSUInteger)index |
538 inBackground:(BOOL)inBackground { | 513 inBackground:(BOOL)inBackground { |
539 GURL emptyURL; | 514 GURL emptyURL; |
540 web::NavigationManager::WebLoadParams params(emptyURL); | 515 web::NavigationManager::WebLoadParams params(emptyURL); |
541 params.transition_type = transition; | 516 params.transition_type = transition; |
542 // Tabs open by DOM are always renderer initiated. | 517 // Tabs open by DOM are always renderer initiated. |
543 params.is_renderer_initiated = openedByDOM; | 518 params.is_renderer_initiated = openedByDOM; |
544 return [self insertTabWithLoadParams:params | 519 return [self insertTabWithLoadParams:params |
545 windowName:nil | |
546 opener:parentTab | 520 opener:parentTab |
547 openedByDOM:openedByDOM | 521 openedByDOM:openedByDOM |
548 atIndex:index | 522 atIndex:index |
549 inBackground:inBackground]; | 523 inBackground:inBackground]; |
550 } | 524 } |
551 | 525 |
552 - (Tab*)insertTabWithWebState:(std::unique_ptr<web::WebState>)webState | 526 - (Tab*)insertTabWithWebState:(std::unique_ptr<web::WebState>)webState |
553 atIndex:(NSUInteger)index { | 527 atIndex:(NSUInteger)index { |
554 DCHECK(_browserState); | 528 DCHECK(_browserState); |
555 DCHECK_EQ(webState->GetBrowserState(), _browserState); | 529 DCHECK_EQ(webState->GetBrowserState(), _browserState); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 } | 844 } |
871 window.selectedIndex = [self indexOfTab:_currentTab]; | 845 window.selectedIndex = [self indexOfTab:_currentTab]; |
872 return window; | 846 return window; |
873 } | 847 } |
874 | 848 |
875 - (BOOL)isNTPTab:(Tab*)tab { | 849 - (BOOL)isNTPTab:(Tab*)tab { |
876 std::string host = tab.url.host(); | 850 std::string host = tab.url.host(); |
877 return host == kChromeUINewTabHost || host == kChromeUIBookmarksHost; | 851 return host == kChromeUINewTabHost || host == kChromeUIBookmarksHost; |
878 } | 852 } |
879 | 853 |
880 - (Tab*)insertTabWithLoadParams: | |
881 (const web::NavigationManager::WebLoadParams&)params | |
882 windowName:(NSString*)windowName | |
883 opener:(Tab*)parentTab | |
884 openedByDOM:(BOOL)openedByDOM | |
885 atIndex:(NSUInteger)index | |
886 inBackground:(BOOL)inBackground { | |
887 DCHECK(_browserState); | |
888 base::scoped_nsobject<Tab> tab([[Tab alloc] | |
889 initWithWindowName:windowName | |
890 opener:parentTab | |
891 openedByDOM:openedByDOM | |
892 model:self | |
893 browserState:_browserState]); | |
894 [tab webController].webUsageEnabled = webUsageEnabled_; | |
895 | |
896 [self insertTab:tab | |
897 atIndex:index | |
898 opener:parentTab | |
899 transition:params.transition_type]; | |
900 | |
901 if (!inBackground && _tabUsageRecorder) | |
902 _tabUsageRecorder->TabCreatedForSelection(tab); | |
903 | |
904 [[tab webController] loadWithParams:params]; | |
905 // Force the page to start loading even if it's in the background. | |
906 if (webUsageEnabled_) | |
907 [[tab webController] triggerPendingLoad]; | |
908 NSDictionary* userInfo = @{ | |
909 kTabModelTabKey : tab, | |
910 kTabModelOpenInBackgroundKey : @(inBackground), | |
911 }; | |
912 [[NSNotificationCenter defaultCenter] | |
913 postNotificationName:kTabModelNewTabWillOpenNotification | |
914 object:self | |
915 userInfo:userInfo]; | |
916 | |
917 if (!inBackground) | |
918 [self setCurrentTab:tab]; | |
919 | |
920 return tab; | |
921 } | |
922 | |
923 - (void)changeSelectedTabFrom:(Tab*)oldTab | 854 - (void)changeSelectedTabFrom:(Tab*)oldTab |
924 to:(Tab*)newTab | 855 to:(Tab*)newTab |
925 persistState:(BOOL)persist { | 856 persistState:(BOOL)persist { |
926 if (oldTab) { | 857 if (oldTab) { |
927 // Save state, such as scroll position, before switching tabs. | 858 // Save state, such as scroll position, before switching tabs. |
928 if (oldTab != newTab && persist) | 859 if (oldTab != newTab && persist) |
929 [oldTab recordStateInHistory]; | 860 [oldTab recordStateInHistory]; |
930 [self postNotificationName:kTabModelTabDeselectedNotification | 861 [self postNotificationName:kTabModelTabDeselectedNotification |
931 withTab:oldTab]; | 862 withTab:oldTab]; |
932 } | 863 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 - (void)applicationWillEnterForeground:(NSNotification*)notify { | 1034 - (void)applicationWillEnterForeground:(NSNotification*)notify { |
1104 if (_tabUsageRecorder) { | 1035 if (_tabUsageRecorder) { |
1105 _tabUsageRecorder->AppWillEnterForeground(); | 1036 _tabUsageRecorder->AppWillEnterForeground(); |
1106 } | 1037 } |
1107 } | 1038 } |
1108 | 1039 |
1109 @end | 1040 @end |
1110 | 1041 |
1111 @implementation TabModel (PrivateForTestingOnly) | 1042 @implementation TabModel (PrivateForTestingOnly) |
1112 | 1043 |
1113 - (Tab*)addTabWithURL:(const GURL&)URL | 1044 - (Tab*)addTabWithURL:(const GURL&)URL referrer:(const web::Referrer&)referrer { |
1114 referrer:(const web::Referrer&)referrer | |
1115 windowName:(NSString*)windowName { | |
1116 return [self insertTabWithURL:URL | 1045 return [self insertTabWithURL:URL |
1117 referrer:referrer | 1046 referrer:referrer |
1118 windowName:windowName | |
1119 opener:nil | 1047 opener:nil |
1120 atIndex:self.count]; | 1048 atIndex:self.count]; |
1121 } | 1049 } |
1122 | 1050 |
1123 - (Tab*)insertTabWithURL:(const GURL&)URL | 1051 - (Tab*)insertTabWithURL:(const GURL&)URL |
1124 referrer:(const web::Referrer&)referrer | 1052 referrer:(const web::Referrer&)referrer |
1125 windowName:(NSString*)windowName | |
1126 opener:(Tab*)parentTab | 1053 opener:(Tab*)parentTab |
1127 atIndex:(NSUInteger)index { | 1054 atIndex:(NSUInteger)index { |
1128 DCHECK(_browserState); | 1055 DCHECK(_browserState); |
1129 base::scoped_nsobject<Tab> tab([[Tab alloc] | 1056 base::scoped_nsobject<Tab> tab([[Tab alloc] initWithBrowserState:_browserState |
1130 initWithWindowName:windowName | 1057 opener:parentTab |
1131 opener:parentTab | 1058 openedByDOM:NO |
1132 openedByDOM:NO | 1059 model:self]); |
1133 model:self | |
1134 browserState:_browserState]); | |
1135 web::NavigationManager::WebLoadParams params(URL); | 1060 web::NavigationManager::WebLoadParams params(URL); |
1136 params.referrer = referrer; | 1061 params.referrer = referrer; |
1137 params.transition_type = ui::PAGE_TRANSITION_TYPED; | 1062 params.transition_type = ui::PAGE_TRANSITION_TYPED; |
1138 [[tab webController] loadWithParams:params]; | 1063 [[tab webController] loadWithParams:params]; |
1139 [tab webController].webUsageEnabled = webUsageEnabled_; | 1064 [tab webController].webUsageEnabled = webUsageEnabled_; |
1140 [self insertTab:tab atIndex:index opener:parentTab]; | 1065 [self insertTab:tab atIndex:index opener:parentTab]; |
1141 return tab; | 1066 return tab; |
1142 } | 1067 } |
1143 | 1068 |
1144 @end | 1069 @end |
OLD | NEW |