Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: ios/shared/chrome/browser/tabs/web_state_list.mm

Issue 2703333006: Move the notion of current Tab from TabModel to WebStateList. (Closed)
Patch Set: Rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 web::WebState* web_state = web_state_wrapper->web_state(); 100 web::WebState* web_state = web_state_wrapper->web_state();
100 delete web_state; 101 delete web_state;
101 } 102 }
102 } 103 }
103 } 104 }
104 105
105 bool WebStateList::ContainsIndex(int index) const { 106 bool WebStateList::ContainsIndex(int index) const {
106 return 0 <= index && index < count(); 107 return 0 <= index && index < count();
107 } 108 }
108 109
110 web::WebState* WebStateList::GetActiveWebState() const {
111 if (active_index_ != kInvalidIndex)
112 return GetWebStateAt(active_index_);
113 return nullptr;
114 }
115
109 web::WebState* WebStateList::GetWebStateAt(int index) const { 116 web::WebState* WebStateList::GetWebStateAt(int index) const {
110 DCHECK(ContainsIndex(index)); 117 DCHECK(ContainsIndex(index));
111 return web_state_wrappers_[index]->web_state(); 118 return web_state_wrappers_[index]->web_state();
112 } 119 }
113 120
114 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const { 121 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const {
115 for (int index = 0; index < count(); ++index) { 122 for (int index = 0; index < count(); ++index) {
116 if (web_state_wrappers_[index]->web_state() == web_state) 123 if (web_state_wrappers_[index]->web_state() == web_state)
117 return index; 124 return index;
118 } 125 }
(...skipping 23 matching lines...) Expand all
142 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX); 149 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX);
143 } 150 }
144 151
145 void WebStateList::InsertWebState(int index, 152 void WebStateList::InsertWebState(int index,
146 web::WebState* web_state, 153 web::WebState* web_state,
147 web::WebState* opener) { 154 web::WebState* opener) {
148 DCHECK(ContainsIndex(index) || index == count()); 155 DCHECK(ContainsIndex(index) || index == count());
149 web_state_wrappers_.insert(web_state_wrappers_.begin() + index, 156 web_state_wrappers_.insert(web_state_wrappers_.begin() + index,
150 base::MakeUnique<WebStateWrapper>(web_state)); 157 base::MakeUnique<WebStateWrapper>(web_state));
151 158
159 if (active_index_ >= index)
160 ++active_index_;
161
152 if (opener) 162 if (opener)
153 SetOpenerOfWebStateAt(index, opener); 163 SetOpenerOfWebStateAt(index, opener);
154 164
155 for (auto& observer : observers_) 165 for (auto& observer : observers_)
156 observer.WebStateInsertedAt(this, web_state, index); 166 observer.WebStateInsertedAt(this, web_state, index);
157 } 167 }
158 168
159 void WebStateList::AppendWebState(ui::PageTransition transition, 169 void WebStateList::AppendWebState(ui::PageTransition transition,
160 web::WebState* web_state, 170 web::WebState* web_state,
161 web::WebState* opener) { 171 web::WebState* opener) {
(...skipping 10 matching lines...) Expand all
172 if (from_index == to_index) 182 if (from_index == to_index)
173 return; 183 return;
174 184
175 std::unique_ptr<WebStateWrapper> web_state_wrapper = 185 std::unique_ptr<WebStateWrapper> web_state_wrapper =
176 std::move(web_state_wrappers_[from_index]); 186 std::move(web_state_wrappers_[from_index]);
177 web::WebState* web_state = web_state_wrapper->web_state(); 187 web::WebState* web_state = web_state_wrapper->web_state();
178 web_state_wrappers_.erase(web_state_wrappers_.begin() + from_index); 188 web_state_wrappers_.erase(web_state_wrappers_.begin() + from_index);
179 web_state_wrappers_.insert(web_state_wrappers_.begin() + to_index, 189 web_state_wrappers_.insert(web_state_wrappers_.begin() + to_index,
180 std::move(web_state_wrapper)); 190 std::move(web_state_wrapper));
181 191
192 if (active_index_ == from_index) {
193 active_index_ = to_index;
194 } else {
195 int min = std::min(from_index, to_index);
196 int max = std::max(from_index, to_index);
197 int delta = from_index < to_index ? -1 : +1;
198 if (min <= active_index_ && active_index_ <= max)
199 active_index_ += delta;
200 }
201
182 for (auto& observer : observers_) 202 for (auto& observer : observers_)
183 observer.WebStateMoved(this, web_state, from_index, to_index); 203 observer.WebStateMoved(this, web_state, from_index, to_index);
184 } 204 }
185 205
186 web::WebState* WebStateList::ReplaceWebStateAt(int index, 206 web::WebState* WebStateList::ReplaceWebStateAt(int index,
187 web::WebState* web_state, 207 web::WebState* web_state,
188 web::WebState* opener) { 208 web::WebState* opener) {
189 DCHECK(ContainsIndex(index)); 209 DCHECK(ContainsIndex(index));
190 ClearOpenersReferencing(index); 210 ClearOpenersReferencing(index);
191 211
192 auto& web_state_wrapper = web_state_wrappers_[index]; 212 auto& web_state_wrapper = web_state_wrappers_[index];
193 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state); 213 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state);
194 214
195 if (opener && opener != old_web_state) 215 if (opener && opener != old_web_state)
196 SetOpenerOfWebStateAt(index, opener); 216 SetOpenerOfWebStateAt(index, opener);
197 217
198 for (auto& observer : observers_) 218 for (auto& observer : observers_)
199 observer.WebStateReplacedAt(this, old_web_state, web_state, index); 219 observer.WebStateReplacedAt(this, old_web_state, web_state, index);
200 220
201 return old_web_state; 221 return old_web_state;
202 } 222 }
203 223
204 web::WebState* WebStateList::DetachWebStateAt(int index) { 224 web::WebState* WebStateList::DetachWebStateAt(int index) {
205 DCHECK(ContainsIndex(index)); 225 DCHECK(ContainsIndex(index));
206 ClearOpenersReferencing(index); 226 ClearOpenersReferencing(index);
207 227
228 int new_active_index = order_controller_->DetermineNewActiveIndex(index);
229
208 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); 230 web::WebState* old_web_state = web_state_wrappers_[index]->web_state();
209 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); 231 web_state_wrappers_.erase(web_state_wrappers_.begin() + index);
210 232
233 // Update the active index to prevent observer from seeing an invalid WebState
234 // as the active one but only send the WebStateActivatedAt notification after
235 // the WebStateDetachedAt one.
236 bool active_web_state_was_closed = (index == active_index_);
237 if (active_index_ > index)
238 --active_index_;
239 else if (active_index_ == index)
240 active_index_ = new_active_index;
241
211 for (auto& observer : observers_) 242 for (auto& observer : observers_)
212 observer.WebStateDetachedAt(this, old_web_state, index); 243 observer.WebStateDetachedAt(this, old_web_state, index);
213 244
245 if (active_web_state_was_closed)
246 NotifyIfActiveWebStateChanged(old_web_state, false);
247
214 return old_web_state; 248 return old_web_state;
215 } 249 }
216 250
251 void WebStateList::ActivateWebStateAt(int index) {
252 DCHECK(ContainsIndex(index));
253 web::WebState* old_web_state = GetActiveWebState();
254 active_index_ = index;
255 NotifyIfActiveWebStateChanged(old_web_state, true);
256 }
257
217 void WebStateList::AddObserver(WebStateListObserver* observer) { 258 void WebStateList::AddObserver(WebStateListObserver* observer) {
218 observers_.AddObserver(observer); 259 observers_.AddObserver(observer);
219 } 260 }
220 261
221 void WebStateList::RemoveObserver(WebStateListObserver* observer) { 262 void WebStateList::RemoveObserver(WebStateListObserver* observer) {
222 observers_.RemoveObserver(observer); 263 observers_.RemoveObserver(observer);
223 } 264 }
224 265
225 void WebStateList::ClearOpenersReferencing(int index) { 266 void WebStateList::ClearOpenersReferencing(int index) {
226 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); 267 web::WebState* old_web_state = web_state_wrappers_[index]->web_state();
227 for (auto& web_state_wrapper : web_state_wrappers_) { 268 for (auto& web_state_wrapper : web_state_wrappers_) {
228 if (web_state_wrapper->opener() == old_web_state) 269 if (web_state_wrapper->opener() == old_web_state)
229 web_state_wrapper->SetOpener(nullptr); 270 web_state_wrapper->SetOpener(nullptr);
230 } 271 }
231 } 272 }
232 273
274 void WebStateList::NotifyIfActiveWebStateChanged(web::WebState* old_web_state,
275 bool user_action) {
276 web::WebState* new_web_state = GetActiveWebState();
277 if (old_web_state == new_web_state)
278 return;
279
280 for (auto& observer : observers_) {
281 observer.WebStateActivatedAt(this, old_web_state, new_web_state,
282 active_index_, user_action);
283 }
284 }
285
233 int WebStateList::GetIndexOfNthWebStateOpenedBy(const web::WebState* opener, 286 int WebStateList::GetIndexOfNthWebStateOpenedBy(const web::WebState* opener,
234 int start_index, 287 int start_index,
235 bool use_group, 288 bool use_group,
236 int n) const { 289 int n) const {
237 DCHECK_GT(n, 0); 290 DCHECK_GT(n, 0);
238 if (!opener || !ContainsIndex(start_index) || start_index == INT_MAX) 291 if (!opener || !ContainsIndex(start_index) || start_index == INT_MAX)
239 return kInvalidIndex; 292 return kInvalidIndex;
240 293
241 const int opener_navigation_index = 294 const int opener_navigation_index =
242 use_group ? opener->GetNavigationManager()->GetCurrentItemIndex() : -1; 295 use_group ? opener->GetNavigationManager()->GetCurrentItemIndex() : -1;
243 296
244 int found_index = kInvalidIndex; 297 int found_index = kInvalidIndex;
245 for (int index = start_index + 1; index < count() && n; ++index) { 298 for (int index = start_index + 1; index < count() && n; ++index) {
246 if (web_state_wrappers_[index]->WasOpenedBy(opener, opener_navigation_index, 299 if (web_state_wrappers_[index]->WasOpenedBy(opener, opener_navigation_index,
247 use_group)) { 300 use_group)) {
248 found_index = index; 301 found_index = index;
249 --n; 302 --n;
250 } else if (found_index != kInvalidIndex) { 303 } else if (found_index != kInvalidIndex) {
251 return found_index; 304 return found_index;
252 } 305 }
253 } 306 }
254 307
255 return found_index; 308 return found_index;
256 } 309 }
257 310
258 // static 311 // static
259 const int WebStateList::kInvalidIndex; 312 const int WebStateList::kInvalidIndex;
OLDNEW
« no previous file with comments | « ios/shared/chrome/browser/tabs/web_state_list.h ('k') | ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698