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 |