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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 DCHECK(web_state_list); | 110 DCHECK(web_state_list); |
111 DCHECK_CURRENTLY_ON(web::WebThread::UI); | 111 DCHECK_CURRENTLY_ON(web::WebThread::UI); |
112 task_tracker->PostTaskAndReply( | 112 task_tracker->PostTaskAndReply( |
113 task_runner.get(), FROM_HERE, | 113 task_runner.get(), FROM_HERE, |
114 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies, | 114 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies, |
115 policy_cache), | 115 policy_cache), |
116 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache, | 116 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache, |
117 base::Unretained(web_state_list))); | 117 base::Unretained(web_state_list))); |
118 } | 118 } |
119 | 119 |
| 120 // Internal helper function returning the opener for a given WebState by |
| 121 // checking the associated Tab tabId (should be removed once the opener |
| 122 // is passed to the insertTab:atIndex: and replaceTab:withTab: methods). |
| 123 web::WebState* GetOpenerForWebState(const WebStateList& web_state_list, |
| 124 web::WebState* web_state) { |
| 125 Tab* tab = LegacyTabHelper::GetTabForWebState(web_state); |
| 126 NSString* opener_id = |
| 127 [tab navigationManager]->GetSessionController().openerId; |
| 128 if (!opener_id) |
| 129 return nullptr; |
| 130 |
| 131 for (int index = 0; index < web_state_list.count(); ++index) { |
| 132 web::WebState* web_state = web_state_list.GetWebStateAt(index); |
| 133 Tab* tab = LegacyTabHelper::GetTabForWebState(web_state); |
| 134 if ([opener_id isEqualToString:tab.tabId]) |
| 135 return web_state; |
| 136 } |
| 137 |
| 138 return nullptr; |
| 139 } |
| 140 |
120 } // anonymous namespace | 141 } // anonymous namespace |
121 | 142 |
122 @interface TabModelWebStateProxyFactory : NSObject<WebStateProxyFactory> | 143 @interface TabModelWebStateProxyFactory : NSObject<WebStateProxyFactory> |
123 @end | 144 @end |
124 | 145 |
125 @implementation TabModelWebStateProxyFactory | 146 @implementation TabModelWebStateProxyFactory |
126 | 147 |
127 - (id)proxyForWebState:(web::WebState*)webState { | 148 - (id)proxyForWebState:(web::WebState*)webState { |
128 return LegacyTabHelper::GetTabForWebState(webState); | 149 return LegacyTabHelper::GetTabForWebState(webState); |
129 } | 150 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 return nil; | 419 return nil; |
399 for (Tab* tab in self) { | 420 for (Tab* tab in self) { |
400 if ([windowName isEqualToString:tab.windowName]) { | 421 if ([windowName isEqualToString:tab.windowName]) { |
401 return tab; | 422 return tab; |
402 } | 423 } |
403 } | 424 } |
404 return nil; | 425 return nil; |
405 } | 426 } |
406 | 427 |
407 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { | 428 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { |
408 NSUInteger startIndex = NSNotFound; | 429 int startIndex = WebStateList::kInvalidIndex; |
409 // Start looking after |afterTab|. If it's not found, start looking after | |
410 // |tab|. If it's not found either, bail. | |
411 if (afterTab) | 430 if (afterTab) |
412 startIndex = [self indexOfTab:afterTab]; | 431 startIndex = _webStateList.GetIndexOfWebState(afterTab.webState); |
413 if (startIndex == NSNotFound) | 432 |
414 startIndex = [self indexOfTab:tab]; | 433 if (startIndex == WebStateList::kInvalidIndex) |
415 if (startIndex == NSNotFound) | 434 startIndex = _webStateList.GetIndexOfWebState(tab.webState); |
| 435 |
| 436 const int index = _webStateList.GetIndexOfNextWebStateOpenedBy( |
| 437 tab.webState, startIndex, false); |
| 438 if (index == WebStateList::kInvalidIndex) |
416 return nil; | 439 return nil; |
417 NSString* parentID = tab.tabId; | 440 |
418 for (NSUInteger i = startIndex + 1; i < self.count; ++i) { | 441 DCHECK_GE(index, 0); |
419 Tab* current = [self tabAtIndex:i]; | 442 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
420 DCHECK([current navigationManager]); | |
421 CRWSessionController* sessionController = | |
422 [current navigationManager]->GetSessionController(); | |
423 if ([sessionController.openerId isEqualToString:parentID]) | |
424 return current; | |
425 } | |
426 return nil; | |
427 } | 443 } |
428 | 444 |
429 - (Tab*)lastTabWithOpener:(Tab*)tab { | 445 - (Tab*)lastTabWithOpener:(Tab*)tab { |
430 NSUInteger startIndex = [self indexOfTab:tab]; | 446 int startIndex = _webStateList.GetIndexOfWebState(tab.webState); |
431 if (startIndex == NSNotFound) | 447 if (startIndex == WebStateList::kInvalidIndex) |
432 return nil; | 448 return nil; |
433 // There is at least one tab in the model, because otherwise the above check | |
434 // would have returned. | |
435 NSString* parentID = tab.tabId; | |
436 DCHECK([tab navigationManager]); | |
437 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex(); | |
438 | 449 |
439 Tab* match = nil; | 450 const int index = _webStateList.GetIndexOfLastWebStateOpenedBy( |
440 // Find the last tab in the first matching 'group'. A 'group' is a set of | 451 tab.webState, startIndex, true); |
441 // tabs whose opener's id and opener's navigation index match. The navigation | 452 if (index == WebStateList::kInvalidIndex) |
442 // index is used in addition to the session id to detect navigations changes | 453 return nil; |
443 // within the same session. | 454 |
444 for (NSUInteger i = startIndex + 1; i < self.count; ++i) { | 455 DCHECK_GE(index, 0); |
445 Tab* tabToCheck = [self tabAtIndex:i]; | 456 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
446 DCHECK([tabToCheck navigationManager]); | |
447 CRWSessionController* sessionController = | |
448 [tabToCheck navigationManager]->GetSessionController(); | |
449 if ([sessionController.openerId isEqualToString:parentID] && | |
450 sessionController.openerNavigationIndex == parentNavIndex) { | |
451 match = tabToCheck; | |
452 } else if (match) { | |
453 break; | |
454 } | |
455 } | |
456 return match; | |
457 } | 457 } |
458 | 458 |
459 - (Tab*)openerOfTab:(Tab*)tab { | 459 - (Tab*)openerOfTab:(Tab*)tab { |
460 if (![tab navigationManager]) | 460 int index = _webStateList.GetIndexOfWebState(tab.webState); |
| 461 if (index == WebStateList::kInvalidIndex) |
461 return nil; | 462 return nil; |
462 NSString* openerId = [tab navigationManager]->GetSessionController().openerId; | 463 |
463 if (!openerId.length) // Short-circuit if opener is empty. | 464 web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index); |
464 return nil; | 465 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; |
465 for (Tab* iteratedTab in self) { | |
466 if ([iteratedTab.tabId isEqualToString:openerId]) | |
467 return iteratedTab; | |
468 } | |
469 return nil; | |
470 } | 466 } |
471 | 467 |
472 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL | 468 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL |
473 referrer:(const web::Referrer&)referrer | 469 referrer:(const web::Referrer&)referrer |
474 transition:(ui::PageTransition)transition | 470 transition:(ui::PageTransition)transition |
475 windowName:(NSString*)windowName | 471 windowName:(NSString*)windowName |
476 opener:(Tab*)parentTab | 472 opener:(Tab*)parentTab |
477 openedByDOM:(BOOL)openedByDOM | 473 openedByDOM:(BOOL)openedByDOM |
478 atIndex:(NSUInteger)index | 474 atIndex:(NSUInteger)index |
479 inBackground:(BOOL)inBackground { | 475 inBackground:(BOOL)inBackground { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 [self insertTab:tab atIndex:index]; | 548 [self insertTab:tab atIndex:index]; |
553 return tab; | 549 return tab; |
554 } | 550 } |
555 | 551 |
556 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { | 552 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { |
557 DCHECK(tab); | 553 DCHECK(tab); |
558 DCHECK(![_tabRetainer containsObject:tab]); | 554 DCHECK(![_tabRetainer containsObject:tab]); |
559 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 555 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
560 | 556 |
561 [_tabRetainer addObject:tab]; | 557 [_tabRetainer addObject:tab]; |
562 _webStateList.InsertWebState(static_cast<int>(index), tab.webState); | 558 _webStateList.InsertWebState( |
| 559 static_cast<int>(index), tab.webState, |
| 560 GetOpenerForWebState(_webStateList, tab.webState)); |
563 | 561 |
564 // Persist the session due to a new tab being inserted. If this is a | 562 // Persist the session due to a new tab being inserted. If this is a |
565 // background tab (will not become active), saving now will capture the | 563 // background tab (will not become active), saving now will capture the |
566 // state properly. If it does eventually become active, another save will | 564 // state properly. If it does eventually become active, another save will |
567 // be triggered to properly capture the end result. | 565 // be triggered to properly capture the end result. |
568 [self saveSessionImmediately:NO]; | 566 [self saveSessionImmediately:NO]; |
569 | 567 |
570 ++_newTabCount; | 568 ++_newTabCount; |
571 } | 569 } |
572 | 570 |
(...skipping 10 matching lines...) Expand all Loading... |
583 | 581 |
584 int index = _webStateList.GetIndexOfWebState(oldTab.webState); | 582 int index = _webStateList.GetIndexOfWebState(oldTab.webState); |
585 DCHECK_NE(index, WebStateList::kInvalidIndex); | 583 DCHECK_NE(index, WebStateList::kInvalidIndex); |
586 DCHECK_GE(index, 0); | 584 DCHECK_GE(index, 0); |
587 | 585 |
588 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); | 586 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); |
589 [_tabRetainer removeObject:oldTab]; | 587 [_tabRetainer removeObject:oldTab]; |
590 [_tabRetainer addObject:newTab]; | 588 [_tabRetainer addObject:newTab]; |
591 [newTab setParentTabModel:self]; | 589 [newTab setParentTabModel:self]; |
592 | 590 |
593 _webStateList.ReplaceWebStateAt(index, newTab.webState); | 591 _webStateList.ReplaceWebStateAt( |
| 592 index, newTab.webState, |
| 593 GetOpenerForWebState(_webStateList, newTab.webState)); |
594 | 594 |
595 if (self.currentTab == oldTab) | 595 if (self.currentTab == oldTab) |
596 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; | 596 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; |
597 | 597 |
598 [oldTab setParentTabModel:nil]; | 598 [oldTab setParentTabModel:nil]; |
599 [oldTab close]; | 599 [oldTab close]; |
600 } | 600 } |
601 | 601 |
602 - (void)closeTabAtIndex:(NSUInteger)index { | 602 - (void)closeTabAtIndex:(NSUInteger)index { |
603 DCHECK(index < self.count); | 603 DCHECK(index < self.count); |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 web::NavigationManager::WebLoadParams params(URL); | 1105 web::NavigationManager::WebLoadParams params(URL); |
1106 params.referrer = referrer; | 1106 params.referrer = referrer; |
1107 params.transition_type = ui::PAGE_TRANSITION_TYPED; | 1107 params.transition_type = ui::PAGE_TRANSITION_TYPED; |
1108 [[tab webController] loadWithParams:params]; | 1108 [[tab webController] loadWithParams:params]; |
1109 [tab webController].webUsageEnabled = webUsageEnabled_; | 1109 [tab webController].webUsageEnabled = webUsageEnabled_; |
1110 [self insertTab:tab atIndex:index]; | 1110 [self insertTab:tab atIndex:index]; |
1111 return tab; | 1111 return tab; |
1112 } | 1112 } |
1113 | 1113 |
1114 @end | 1114 @end |
OLD | NEW |