Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/shared/chrome/browser/tabs/web_state_list.h" | 5 #import "ios/shared/chrome/browser/tabs/web_state_list.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 7 #include <utility> | 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" | 12 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" |
| 12 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h" | 13 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h" |
| 13 #import "ios/web/public/navigation_manager.h" | 14 #import "ios/web/public/navigation_manager.h" |
| 14 #import "ios/web/public/web_state/web_state.h" | 15 #import "ios/web/public/web_state/web_state.h" |
| 15 | 16 |
| 16 #if !defined(__has_feature) || !__has_feature(objc_arc) | 17 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 WebStateList::WebStateList(WebStateOwnership ownership) | 99 WebStateList::WebStateList(WebStateOwnership ownership) |
| 99 : web_state_ownership_(ownership), | 100 : web_state_ownership_(ownership), |
| 100 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {} | 101 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {} |
| 101 | 102 |
| 102 WebStateList::~WebStateList() = default; | 103 WebStateList::~WebStateList() = default; |
| 103 | 104 |
| 104 bool WebStateList::ContainsIndex(int index) const { | 105 bool WebStateList::ContainsIndex(int index) const { |
| 105 return 0 <= index && index < count(); | 106 return 0 <= index && index < count(); |
| 106 } | 107 } |
| 107 | 108 |
| 109 web::WebState* WebStateList::GetActiveWebState() const { | |
| 110 if (active_index_ != kInvalidIndex) | |
| 111 return GetWebStateAt(active_index_); | |
| 112 return nullptr; | |
| 113 } | |
| 114 | |
| 108 web::WebState* WebStateList::GetWebStateAt(int index) const { | 115 web::WebState* WebStateList::GetWebStateAt(int index) const { |
| 109 DCHECK(ContainsIndex(index)); | 116 DCHECK(ContainsIndex(index)); |
| 110 return web_state_wrappers_[index]->web_state(); | 117 return web_state_wrappers_[index]->web_state(); |
| 111 } | 118 } |
| 112 | 119 |
| 113 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const { | 120 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const { |
| 114 for (int index = 0; index < count(); ++index) { | 121 for (int index = 0; index < count(); ++index) { |
| 115 if (web_state_wrappers_[index]->web_state() == web_state) | 122 if (web_state_wrappers_[index]->web_state() == web_state) |
| 116 return index; | 123 return index; |
| 117 } | 124 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 143 | 150 |
| 144 void WebStateList::InsertWebState(int index, | 151 void WebStateList::InsertWebState(int index, |
| 145 web::WebState* web_state, | 152 web::WebState* web_state, |
| 146 web::WebState* opener) { | 153 web::WebState* opener) { |
| 147 DCHECK(ContainsIndex(index) || index == count()); | 154 DCHECK(ContainsIndex(index) || index == count()); |
| 148 web_state_wrappers_.insert( | 155 web_state_wrappers_.insert( |
| 149 web_state_wrappers_.begin() + index, | 156 web_state_wrappers_.begin() + index, |
| 150 base::MakeUnique<WebStateWrapper>(web_state, | 157 base::MakeUnique<WebStateWrapper>(web_state, |
| 151 web_state_ownership_ == WebStateOwned)); | 158 web_state_ownership_ == WebStateOwned)); |
| 152 | 159 |
| 160 if (active_index_ >= index) | |
| 161 ++active_index_; | |
| 162 | |
| 153 if (opener) | 163 if (opener) |
| 154 SetOpenerOfWebStateAt(index, opener); | 164 SetOpenerOfWebStateAt(index, opener); |
| 155 | 165 |
| 156 for (auto& observer : observers_) | 166 for (auto& observer : observers_) |
| 157 observer.WebStateInsertedAt(this, web_state, index); | 167 observer.WebStateInsertedAt(this, web_state, index); |
| 158 } | 168 } |
| 159 | 169 |
| 160 void WebStateList::AppendWebState(ui::PageTransition transition, | 170 void WebStateList::AppendWebState(ui::PageTransition transition, |
| 161 web::WebState* web_state, | 171 web::WebState* web_state, |
| 162 web::WebState* opener) { | 172 web::WebState* opener) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 173 if (from_index == to_index) | 183 if (from_index == to_index) |
| 174 return; | 184 return; |
| 175 | 185 |
| 176 std::unique_ptr<WebStateWrapper> web_state_wrapper = | 186 std::unique_ptr<WebStateWrapper> web_state_wrapper = |
| 177 std::move(web_state_wrappers_[from_index]); | 187 std::move(web_state_wrappers_[from_index]); |
| 178 web::WebState* web_state = web_state_wrapper->web_state(); | 188 web::WebState* web_state = web_state_wrapper->web_state(); |
| 179 web_state_wrappers_.erase(web_state_wrappers_.begin() + from_index); | 189 web_state_wrappers_.erase(web_state_wrappers_.begin() + from_index); |
| 180 web_state_wrappers_.insert(web_state_wrappers_.begin() + to_index, | 190 web_state_wrappers_.insert(web_state_wrappers_.begin() + to_index, |
| 181 std::move(web_state_wrapper)); | 191 std::move(web_state_wrapper)); |
| 182 | 192 |
| 193 if (active_index_ == from_index) { | |
| 194 active_index_ = to_index; | |
| 195 } else { | |
| 196 int min = std::min(from_index, to_index); | |
| 197 int max = std::max(from_index, to_index); | |
| 198 int delta = from_index < to_index ? -1 : +1; | |
| 199 if (min <= active_index_ && active_index_ <= max) | |
| 200 active_index_ += delta; | |
| 201 } | |
| 202 | |
| 183 for (auto& observer : observers_) | 203 for (auto& observer : observers_) |
| 184 observer.WebStateMoved(this, web_state, from_index, to_index); | 204 observer.WebStateMoved(this, web_state, from_index, to_index); |
| 185 } | 205 } |
| 186 | 206 |
| 187 web::WebState* WebStateList::ReplaceWebStateAt(int index, | 207 web::WebState* WebStateList::ReplaceWebStateAt(int index, |
| 188 web::WebState* web_state, | 208 web::WebState* web_state, |
| 189 web::WebState* opener) { | 209 web::WebState* opener) { |
| 190 DCHECK(ContainsIndex(index)); | 210 DCHECK(ContainsIndex(index)); |
| 191 FixOpenersReferencing(index); | 211 FixOpenersReferencing(index); |
| 192 | 212 |
| 193 auto& web_state_wrapper = web_state_wrappers_[index]; | 213 auto& web_state_wrapper = web_state_wrappers_[index]; |
| 194 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state); | 214 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state); |
| 195 | 215 |
| 196 if (opener && opener != old_web_state) | 216 if (opener && opener != old_web_state) |
| 197 SetOpenerOfWebStateAt(index, opener); | 217 SetOpenerOfWebStateAt(index, opener); |
| 198 | 218 |
| 199 for (auto& observer : observers_) | 219 for (auto& observer : observers_) |
| 200 observer.WebStateReplacedAt(this, old_web_state, web_state, index); | 220 observer.WebStateReplacedAt(this, old_web_state, web_state, index); |
| 201 | 221 |
| 202 return old_web_state; | 222 return old_web_state; |
| 203 } | 223 } |
| 204 | 224 |
| 205 void WebStateList::DetachWebStateAt(int index) { | 225 void WebStateList::DetachWebStateAt(int index) { |
| 206 DCHECK(ContainsIndex(index)); | 226 DCHECK(ContainsIndex(index)); |
| 207 FixOpenersReferencing(index); | 227 FixOpenersReferencing(index); |
| 208 | 228 |
| 229 int new_active_index = order_controller_->DetermineNewActiveIndex(index); | |
| 230 | |
| 209 web::WebState* web_state = web_state_wrappers_[index]->web_state(); | 231 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
| |
| 210 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); | 232 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); |
| 211 | 233 |
| 234 // Update the active index to prevent observer from seeing an invalid WebState | |
| 235 // as the active one but only send the WebStateActivatedAt notification after | |
| 236 // the WebStateDetachedAt one. | |
| 237 bool active_web_state_was_closed = (index == active_index_); | |
| 238 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
| |
| 239 --active_index_; | |
| 240 else if (active_index_ == index) | |
| 241 active_index_ = new_active_index; | |
| 242 | |
| 212 for (auto& observer : observers_) | 243 for (auto& observer : observers_) |
| 213 observer.WebStateDetachedAt(this, web_state, index); | 244 observer.WebStateDetachedAt(this, web_state, index); |
| 245 | |
| 246 if (active_web_state_was_closed) | |
| 247 NotifyIfActiveWebStateChanged(web_state, false); | |
| 248 } | |
| 249 | |
| 250 void WebStateList::ActivateWebStateAt(int index) { | |
| 251 DCHECK(ContainsIndex(index)); | |
| 252 web::WebState* old_web_state = GetActiveWebState(); | |
| 253 active_index_ = index; | |
| 254 NotifyIfActiveWebStateChanged(old_web_state, true); | |
| 214 } | 255 } |
| 215 | 256 |
| 216 void WebStateList::AddObserver(WebStateListObserver* observer) { | 257 void WebStateList::AddObserver(WebStateListObserver* observer) { |
| 217 observers_.AddObserver(observer); | 258 observers_.AddObserver(observer); |
| 218 } | 259 } |
| 219 | 260 |
| 220 void WebStateList::RemoveObserver(WebStateListObserver* observer) { | 261 void WebStateList::RemoveObserver(WebStateListObserver* observer) { |
| 221 observers_.RemoveObserver(observer); | 262 observers_.RemoveObserver(observer); |
| 222 } | 263 } |
| 223 | 264 |
| 224 void WebStateList::FixOpenersReferencing(int index) { | 265 void WebStateList::FixOpenersReferencing(int index) { |
| 225 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); | 266 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); |
| 226 for (auto& web_state_wrapper : web_state_wrappers_) { | 267 for (auto& web_state_wrapper : web_state_wrappers_) { |
| 227 if (web_state_wrapper->opener() == old_web_state) | 268 if (web_state_wrapper->opener() == old_web_state) |
| 228 web_state_wrapper->SetOpener(nullptr); | 269 web_state_wrapper->SetOpener(nullptr); |
| 229 } | 270 } |
| 230 } | 271 } |
| 231 | 272 |
| 273 void WebStateList::NotifyIfActiveWebStateChanged(web::WebState* old_web_state, | |
| 274 bool user_action) { | |
| 275 web::WebState* new_web_state = GetActiveWebState(); | |
| 276 if (old_web_state == new_web_state) | |
| 277 return; | |
| 278 | |
| 279 for (auto& observer : observers_) { | |
| 280 observer.WebStateActivatedAt(this, old_web_state, new_web_state, | |
| 281 active_index_, user_action); | |
| 282 } | |
| 283 } | |
| 284 | |
| 232 int WebStateList::GetIndexOfNthWebStateOpenedBy(const web::WebState* opener, | 285 int WebStateList::GetIndexOfNthWebStateOpenedBy(const web::WebState* opener, |
| 233 int start_index, | 286 int start_index, |
| 234 bool use_group, | 287 bool use_group, |
| 235 int n) const { | 288 int n) const { |
| 236 DCHECK_GT(n, 0); | 289 DCHECK_GT(n, 0); |
| 237 if (!opener || !ContainsIndex(start_index) || start_index == INT_MAX) | 290 if (!opener || !ContainsIndex(start_index) || start_index == INT_MAX) |
| 238 return kInvalidIndex; | 291 return kInvalidIndex; |
| 239 | 292 |
| 240 const int opener_navigation_index = | 293 const int opener_navigation_index = |
| 241 use_group ? opener->GetNavigationManager()->GetCurrentItemIndex() : -1; | 294 use_group ? opener->GetNavigationManager()->GetCurrentItemIndex() : -1; |
| 242 | 295 |
| 243 int found_index = kInvalidIndex; | 296 int found_index = kInvalidIndex; |
| 244 for (int index = start_index + 1; index < count() && n; ++index) { | 297 for (int index = start_index + 1; index < count() && n; ++index) { |
| 245 if (web_state_wrappers_[index]->WasOpenedBy(opener, opener_navigation_index, | 298 if (web_state_wrappers_[index]->WasOpenedBy(opener, opener_navigation_index, |
| 246 use_group)) { | 299 use_group)) { |
| 247 found_index = index; | 300 found_index = index; |
| 248 --n; | 301 --n; |
| 249 } else if (found_index != kInvalidIndex) { | 302 } else if (found_index != kInvalidIndex) { |
| 250 return found_index; | 303 return found_index; |
| 251 } | 304 } |
| 252 } | 305 } |
| 253 | 306 |
| 254 return found_index; | 307 return found_index; |
| 255 } | 308 } |
| 256 | 309 |
| 257 // static | 310 // static |
| 258 const int WebStateList::kInvalidIndex; | 311 const int WebStateList::kInvalidIndex; |
| OLD | NEW |