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

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

Issue 2766413004: [ios] Change API to inform WebStateList of opener-opened relationship. (Closed)
Patch Set: Address comments. 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 <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h" 12 #import "ios/shared/chrome/browser/tabs/web_state_list_delegate.h"
13 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" 13 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
14 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h" 14 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h"
15 #import "ios/shared/chrome/browser/tabs/web_state_opener.h"
15 #import "ios/web/public/navigation_manager.h" 16 #import "ios/web/public/navigation_manager.h"
16 #import "ios/web/public/web_state/web_state.h" 17 #import "ios/web/public/web_state/web_state.h"
17 18
18 #if !defined(__has_feature) || !__has_feature(objc_arc) 19 #if !defined(__has_feature) || !__has_feature(objc_arc)
19 #error "This file requires ARC support." 20 #error "This file requires ARC support."
20 #endif 21 #endif
21 22
22 // Wrapper around a WebState stored in a WebStateList. 23 // Wrapper around a WebState stored in a WebStateList.
23 class WebStateList::WebStateWrapper { 24 class WebStateList::WebStateWrapper {
24 public: 25 public:
25 explicit WebStateWrapper(web::WebState* web_state); 26 explicit WebStateWrapper(web::WebState* web_state);
26 ~WebStateWrapper(); 27 ~WebStateWrapper();
27 28
28 web::WebState* web_state() const { return web_state_; } 29 web::WebState* web_state() const { return web_state_; }
29 web::WebState* opener() const { return opener_; }
30 30
31 // Replaces the wrapped WebState (and clear associated state) and returns the 31 // Replaces the wrapped WebState (and clear associated state) and returns the
32 // old WebState after forfeiting ownership. 32 // old WebState after forfeiting ownership.
33 web::WebState* ReplaceWebState(web::WebState* web_state); 33 web::WebState* ReplaceWebState(web::WebState* web_state);
34 34
35 // Sets the opener for the wrapped WebState and record the opener navigation 35 // Gets and sets information about this WebState opener. The navigation index
36 // index to allow detecting navigation changes during the same session. 36 // is used to detect navigation changes during the same session.
37 void SetOpener(web::WebState* opener); 37 WebStateOpener opener() const { return opener_; }
38 void set_opener(WebStateOpener opener) { opener_ = opener; }
38 39
39 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is 40 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is
40 // true, also use the opener navigation index to detect navigation changes 41 // true, also use the opener navigation index to detect navigation changes
41 // during the same session. 42 // during the same session.
42 bool WasOpenedBy(const web::WebState* opener, 43 bool WasOpenedBy(const web::WebState* opener,
43 int opener_navigation_index, 44 int opener_navigation_index,
44 bool use_group) const; 45 bool use_group) const;
45 46
46 private: 47 private:
47 web::WebState* web_state_; 48 web::WebState* web_state_;
48 web::WebState* opener_ = nullptr; 49 WebStateOpener opener_;
49 int opener_last_committed_index_;
50 50
51 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper); 51 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper);
52 }; 52 };
53 53
54 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state) 54 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state)
55 : web_state_(web_state) { 55 : web_state_(web_state), opener_(nullptr) {
56 DCHECK(web_state_); 56 DCHECK(web_state_);
57 } 57 }
58 58
59 WebStateList::WebStateWrapper::~WebStateWrapper() = default; 59 WebStateList::WebStateWrapper::~WebStateWrapper() = default;
60 60
61 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState( 61 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState(
62 web::WebState* web_state) { 62 web::WebState* web_state) {
63 DCHECK(web_state); 63 DCHECK(web_state);
64 DCHECK_NE(web_state, web_state_); 64 DCHECK_NE(web_state, web_state_);
65 std::swap(web_state, web_state_); 65 std::swap(web_state, web_state_);
66 opener_ = nullptr; 66 opener_ = WebStateOpener(nullptr);
67 return web_state; 67 return web_state;
68 } 68 }
69 69
70 void WebStateList::WebStateWrapper::SetOpener(web::WebState* opener) {
71 opener_ = opener;
72 if (opener_) {
73 opener_last_committed_index_ =
74 opener_->GetNavigationManager()->GetLastCommittedItemIndex();
75 }
76 }
77
78 bool WebStateList::WebStateWrapper::WasOpenedBy(const web::WebState* opener, 70 bool WebStateList::WebStateWrapper::WasOpenedBy(const web::WebState* opener,
79 int opener_navigation_index, 71 int opener_navigation_index,
80 bool use_group) const { 72 bool use_group) const {
81 DCHECK(opener); 73 DCHECK(opener);
82 if (opener_ != opener) 74 if (opener_.opener != opener)
83 return false; 75 return false;
84 76
85 if (!use_group) 77 if (!use_group)
86 return true; 78 return true;
87 79
88 return opener_last_committed_index_ == opener_navigation_index; 80 return opener_.navigation_index == opener_navigation_index;
89 } 81 }
90 82
91 WebStateList::WebStateList(WebStateListDelegate* delegate, 83 WebStateList::WebStateList(WebStateListDelegate* delegate,
92 WebStateOwnership ownership) 84 WebStateOwnership ownership)
93 : delegate_(delegate), 85 : delegate_(delegate),
94 web_state_ownership_(ownership), 86 web_state_ownership_(ownership),
95 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) { 87 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {
96 DCHECK(delegate_); 88 DCHECK(delegate_);
97 } 89 }
98 90
(...skipping 25 matching lines...) Expand all
124 } 116 }
125 117
126 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const { 118 int WebStateList::GetIndexOfWebState(const web::WebState* web_state) const {
127 for (int index = 0; index < count(); ++index) { 119 for (int index = 0; index < count(); ++index) {
128 if (web_state_wrappers_[index]->web_state() == web_state) 120 if (web_state_wrappers_[index]->web_state() == web_state)
129 return index; 121 return index;
130 } 122 }
131 return kInvalidIndex; 123 return kInvalidIndex;
132 } 124 }
133 125
134 web::WebState* WebStateList::GetOpenerOfWebStateAt(int index) const { 126 WebStateOpener WebStateList::GetOpenerOfWebStateAt(int index) const {
135 DCHECK(ContainsIndex(index)); 127 DCHECK(ContainsIndex(index));
136 return web_state_wrappers_[index]->opener(); 128 return web_state_wrappers_[index]->opener();
137 } 129 }
138 130
139 void WebStateList::SetOpenerOfWebStateAt(int index, web::WebState* opener) { 131 void WebStateList::SetOpenerOfWebStateAt(int index, WebStateOpener opener) {
140 DCHECK(ContainsIndex(index)); 132 DCHECK(ContainsIndex(index));
141 DCHECK(ContainsIndex(GetIndexOfWebState(opener))); 133 DCHECK(ContainsIndex(GetIndexOfWebState(opener.opener)));
142 web_state_wrappers_[index]->SetOpener(opener); 134 web_state_wrappers_[index]->set_opener(opener);
143 } 135 }
144 136
145 int WebStateList::GetIndexOfNextWebStateOpenedBy(const web::WebState* opener, 137 int WebStateList::GetIndexOfNextWebStateOpenedBy(const web::WebState* opener,
146 int start_index, 138 int start_index,
147 bool use_group) const { 139 bool use_group) const {
148 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, 1); 140 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, 1);
149 } 141 }
150 142
151 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener, 143 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener,
152 int start_index, 144 int start_index,
153 bool use_group) const { 145 bool use_group) const {
154 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX); 146 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX);
155 } 147 }
156 148
157 void WebStateList::InsertWebState(int index, 149 void WebStateList::InsertWebState(int index, web::WebState* web_state) {
158 web::WebState* web_state,
159 web::WebState* opener) {
160 DCHECK(ContainsIndex(index) || index == count()); 150 DCHECK(ContainsIndex(index) || index == count());
161 delegate_->WillAddWebState(web_state); 151 delegate_->WillAddWebState(web_state);
162 152
163 web_state_wrappers_.insert(web_state_wrappers_.begin() + index, 153 web_state_wrappers_.insert(web_state_wrappers_.begin() + index,
164 base::MakeUnique<WebStateWrapper>(web_state)); 154 base::MakeUnique<WebStateWrapper>(web_state));
165 155
166 if (active_index_ >= index) 156 if (active_index_ >= index)
167 ++active_index_; 157 ++active_index_;
168 158
169 if (opener)
170 SetOpenerOfWebStateAt(index, opener);
171
172 for (auto& observer : observers_) 159 for (auto& observer : observers_)
173 observer.WebStateInsertedAt(this, web_state, index); 160 observer.WebStateInsertedAt(this, web_state, index);
174 } 161 }
175 162
176 void WebStateList::AppendWebState(ui::PageTransition transition, 163 void WebStateList::AppendWebState(ui::PageTransition transition,
177 web::WebState* web_state, 164 web::WebState* web_state,
178 web::WebState* opener) { 165 WebStateOpener opener) {
179 int index = order_controller_->DetermineInsertionIndex(transition, opener); 166 int index =
167 order_controller_->DetermineInsertionIndex(transition, opener.opener);
180 if (index < 0 || count() < index) 168 if (index < 0 || count() < index)
181 index = count(); 169 index = count();
182 170
183 InsertWebState(index, web_state, opener); 171 InsertWebState(index, web_state);
172
173 if (opener.opener)
174 SetOpenerOfWebStateAt(index, opener);
184 } 175 }
185 176
186 void WebStateList::MoveWebStateAt(int from_index, int to_index) { 177 void WebStateList::MoveWebStateAt(int from_index, int to_index) {
187 DCHECK(ContainsIndex(from_index)); 178 DCHECK(ContainsIndex(from_index));
188 DCHECK(ContainsIndex(to_index)); 179 DCHECK(ContainsIndex(to_index));
189 if (from_index == to_index) 180 if (from_index == to_index)
190 return; 181 return;
191 182
192 std::unique_ptr<WebStateWrapper> web_state_wrapper = 183 std::unique_ptr<WebStateWrapper> web_state_wrapper =
193 std::move(web_state_wrappers_[from_index]); 184 std::move(web_state_wrappers_[from_index]);
(...skipping 10 matching lines...) Expand all
204 int delta = from_index < to_index ? -1 : +1; 195 int delta = from_index < to_index ? -1 : +1;
205 if (min <= active_index_ && active_index_ <= max) 196 if (min <= active_index_ && active_index_ <= max)
206 active_index_ += delta; 197 active_index_ += delta;
207 } 198 }
208 199
209 for (auto& observer : observers_) 200 for (auto& observer : observers_)
210 observer.WebStateMoved(this, web_state, from_index, to_index); 201 observer.WebStateMoved(this, web_state, from_index, to_index);
211 } 202 }
212 203
213 web::WebState* WebStateList::ReplaceWebStateAt(int index, 204 web::WebState* WebStateList::ReplaceWebStateAt(int index,
214 web::WebState* web_state, 205 web::WebState* web_state) {
215 web::WebState* opener) {
216 DCHECK(ContainsIndex(index)); 206 DCHECK(ContainsIndex(index));
217 delegate_->WillAddWebState(web_state); 207 delegate_->WillAddWebState(web_state);
218 208
219 ClearOpenersReferencing(index); 209 ClearOpenersReferencing(index);
220 210
221 auto& web_state_wrapper = web_state_wrappers_[index]; 211 auto& web_state_wrapper = web_state_wrappers_[index];
222 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state); 212 web::WebState* old_web_state = web_state_wrapper->ReplaceWebState(web_state);
223 213
224 if (opener && opener != old_web_state)
225 SetOpenerOfWebStateAt(index, opener);
226
227 for (auto& observer : observers_) 214 for (auto& observer : observers_)
228 observer.WebStateReplacedAt(this, old_web_state, web_state, index); 215 observer.WebStateReplacedAt(this, old_web_state, web_state, index);
229 216
230 return old_web_state; 217 return old_web_state;
231 } 218 }
232 219
233 web::WebState* WebStateList::DetachWebStateAt(int index) { 220 web::WebState* WebStateList::DetachWebStateAt(int index) {
234 DCHECK(ContainsIndex(index)); 221 DCHECK(ContainsIndex(index));
235 ClearOpenersReferencing(index);
236
237 int new_active_index = order_controller_->DetermineNewActiveIndex(index); 222 int new_active_index = order_controller_->DetermineNewActiveIndex(index);
238 223
239 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); 224 web::WebState* old_web_state = web_state_wrappers_[index]->web_state();
225
226 ClearOpenersReferencing(index);
240 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); 227 web_state_wrappers_.erase(web_state_wrappers_.begin() + index);
241 228
242 // Update the active index to prevent observer from seeing an invalid WebState 229 // Update the active index to prevent observer from seeing an invalid WebState
243 // as the active one but only send the WebStateActivatedAt notification after 230 // as the active one but only send the WebStateActivatedAt notification after
244 // the WebStateDetachedAt one. 231 // the WebStateDetachedAt one.
245 bool active_web_state_was_closed = (index == active_index_); 232 bool active_web_state_was_closed = (index == active_index_);
246 if (active_index_ > index) 233 if (active_index_ > index)
247 --active_index_; 234 --active_index_;
248 else if (active_index_ == index) 235 else if (active_index_ == index)
249 active_index_ = new_active_index; 236 active_index_ = new_active_index;
(...skipping 18 matching lines...) Expand all
268 observers_.AddObserver(observer); 255 observers_.AddObserver(observer);
269 } 256 }
270 257
271 void WebStateList::RemoveObserver(WebStateListObserver* observer) { 258 void WebStateList::RemoveObserver(WebStateListObserver* observer) {
272 observers_.RemoveObserver(observer); 259 observers_.RemoveObserver(observer);
273 } 260 }
274 261
275 void WebStateList::ClearOpenersReferencing(int index) { 262 void WebStateList::ClearOpenersReferencing(int index) {
276 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); 263 web::WebState* old_web_state = web_state_wrappers_[index]->web_state();
277 for (auto& web_state_wrapper : web_state_wrappers_) { 264 for (auto& web_state_wrapper : web_state_wrappers_) {
278 if (web_state_wrapper->opener() == old_web_state) 265 if (web_state_wrapper->opener().opener == old_web_state)
279 web_state_wrapper->SetOpener(nullptr); 266 web_state_wrapper->set_opener(WebStateOpener(nullptr));
280 } 267 }
281 } 268 }
282 269
283 void WebStateList::NotifyIfActiveWebStateChanged(web::WebState* old_web_state, 270 void WebStateList::NotifyIfActiveWebStateChanged(web::WebState* old_web_state,
284 bool user_action) { 271 bool user_action) {
285 web::WebState* new_web_state = GetActiveWebState(); 272 web::WebState* new_web_state = GetActiveWebState();
286 if (old_web_state == new_web_state) 273 if (old_web_state == new_web_state)
287 return; 274 return;
288 275
289 for (auto& observer : observers_) { 276 for (auto& observer : observers_) {
(...skipping 23 matching lines...) Expand all
313 } else if (found_index != kInvalidIndex) { 300 } else if (found_index != kInvalidIndex) {
314 return found_index; 301 return found_index;
315 } 302 }
316 } 303 }
317 304
318 return found_index; 305 return found_index;
319 } 306 }
320 307
321 // static 308 // static
322 const int WebStateList::kInvalidIndex; 309 const int WebStateList::kInvalidIndex;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698