Index: ios/shared/chrome/browser/tabs/web_state_list.mm |
diff --git a/ios/shared/chrome/browser/tabs/web_state_list.mm b/ios/shared/chrome/browser/tabs/web_state_list.mm |
index 77c01a6f938064f25c233665c52409ae00e1216c..ccb01f384d5eb9e3366836ba41b73f854866b49f 100644 |
--- a/ios/shared/chrome/browser/tabs/web_state_list.mm |
+++ b/ios/shared/chrome/browser/tabs/web_state_list.mm |
@@ -4,6 +4,7 @@ |
#import "ios/shared/chrome/browser/tabs/web_state_list.h" |
+#include <algorithm> |
#include <utility> |
#include "base/logging.h" |
@@ -105,6 +106,12 @@ bool WebStateList::ContainsIndex(int index) const { |
return 0 <= index && index < count(); |
} |
+web::WebState* WebStateList::GetActiveWebState() const { |
+ if (active_index_ != kInvalidIndex) |
+ return GetWebStateAt(active_index_); |
+ return nullptr; |
+} |
+ |
web::WebState* WebStateList::GetWebStateAt(int index) const { |
DCHECK(ContainsIndex(index)); |
return web_state_wrappers_[index]->web_state(); |
@@ -150,6 +157,9 @@ void WebStateList::InsertWebState(int index, |
base::MakeUnique<WebStateWrapper>(web_state, |
web_state_ownership_ == WebStateOwned)); |
+ if (active_index_ >= index) |
+ ++active_index_; |
+ |
if (opener) |
SetOpenerOfWebStateAt(index, opener); |
@@ -180,6 +190,16 @@ void WebStateList::MoveWebStateAt(int from_index, int to_index) { |
web_state_wrappers_.insert(web_state_wrappers_.begin() + to_index, |
std::move(web_state_wrapper)); |
+ if (active_index_ == from_index) { |
+ active_index_ = to_index; |
+ } else { |
+ int min = std::min(from_index, to_index); |
+ int max = std::max(from_index, to_index); |
+ int delta = from_index < to_index ? -1 : +1; |
+ if (min <= active_index_ && active_index_ <= max) |
+ active_index_ += delta; |
+ } |
+ |
for (auto& observer : observers_) |
observer.WebStateMoved(this, web_state, from_index, to_index); |
} |
@@ -206,11 +226,32 @@ void WebStateList::DetachWebStateAt(int index) { |
DCHECK(ContainsIndex(index)); |
FixOpenersReferencing(index); |
+ int new_active_index = order_controller_->DetermineNewActiveIndex(index); |
+ |
web::WebState* web_state = web_state_wrappers_[index]->web_state(); |
rohitrao (ping after 24h)
2017/02/22 15:13:43
What keeps ownership of this object so that it doe
sdefresne
2017/02/23 15:43:48
That's a really good remark. Fixed by https://code
|
web_state_wrappers_.erase(web_state_wrappers_.begin() + index); |
+ // Update the active index to prevent observer from seeing an invalid WebState |
+ // as the active one but only send the WebStateActivatedAt notification after |
+ // the WebStateDetachedAt one. |
+ bool active_web_state_was_closed = (index == active_index_); |
+ if (active_index_ > index) |
marq (ping after 24h)
2017/02/21 17:23:11
Use {} if there's an else clause.
sdefresne
2017/02/21 17:29:29
I checked the style guide [1] and it does not say
|
+ --active_index_; |
+ else if (active_index_ == index) |
+ active_index_ = new_active_index; |
+ |
for (auto& observer : observers_) |
observer.WebStateDetachedAt(this, web_state, index); |
+ |
+ if (active_web_state_was_closed) |
+ NotifyIfActiveWebStateChanged(web_state, false); |
+} |
+ |
+void WebStateList::ActivateWebStateAt(int index) { |
+ DCHECK(ContainsIndex(index)); |
+ web::WebState* old_web_state = GetActiveWebState(); |
+ active_index_ = index; |
+ NotifyIfActiveWebStateChanged(old_web_state, true); |
} |
void WebStateList::AddObserver(WebStateListObserver* observer) { |
@@ -229,6 +270,18 @@ void WebStateList::FixOpenersReferencing(int index) { |
} |
} |
+void WebStateList::NotifyIfActiveWebStateChanged(web::WebState* old_web_state, |
+ bool user_action) { |
+ web::WebState* new_web_state = GetActiveWebState(); |
+ if (old_web_state == new_web_state) |
+ return; |
+ |
+ for (auto& observer : observers_) { |
+ observer.WebStateActivatedAt(this, old_web_state, new_web_state, |
+ active_index_, user_action); |
+ } |
+} |
+ |
int WebStateList::GetIndexOfNthWebStateOpenedBy(const web::WebState* opener, |
int start_index, |
bool use_group, |