| 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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" | 11 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" |
| 12 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h" | 12 #import "ios/shared/chrome/browser/tabs/web_state_list_order_controller.h" |
| 13 #import "ios/web/public/navigation_manager.h" | 13 #import "ios/web/public/navigation_manager.h" |
| 14 #import "ios/web/public/web_state/web_state.h" | 14 #import "ios/web/public/web_state/web_state.h" |
| 15 | 15 |
| 16 #if !defined(__has_feature) || !__has_feature(objc_arc) | 16 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 17 #error "This file requires ARC support." | 17 #error "This file requires ARC support." |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 // Wrapper around a WebState stored in a WebStateList. May own the WebState | 20 // Wrapper around a WebState stored in a WebStateList. |
| 21 // dependending on the WebStateList ownership setting (should always be true | |
| 22 // once ownership of Tab is sane, see http://crbug.com/546222 for progress). | |
| 23 class WebStateList::WebStateWrapper { | 21 class WebStateList::WebStateWrapper { |
| 24 public: | 22 public: |
| 25 WebStateWrapper(web::WebState* web_state, bool assume_ownership); | 23 explicit WebStateWrapper(web::WebState* web_state); |
| 26 ~WebStateWrapper(); | 24 ~WebStateWrapper(); |
| 27 | 25 |
| 28 web::WebState* web_state() const { return web_state_; } | 26 web::WebState* web_state() const { return web_state_; } |
| 29 web::WebState* opener() const { return opener_; } | 27 web::WebState* opener() const { return opener_; } |
| 30 | 28 |
| 31 // Replaces the wrapped WebState (and clear associated state) and returns the | 29 // Replaces the wrapped WebState (and clear associated state) and returns the |
| 32 // old WebState after forfeiting ownership. | 30 // old WebState after forfeiting ownership. |
| 33 web::WebState* ReplaceWebState(web::WebState* web_state); | 31 web::WebState* ReplaceWebState(web::WebState* web_state); |
| 34 | 32 |
| 35 // Sets the opener for the wrapped WebState and record the opener navigation | 33 // Sets the opener for the wrapped WebState and record the opener navigation |
| 36 // index to allow detecting navigation changes during the same session. | 34 // index to allow detecting navigation changes during the same session. |
| 37 void SetOpener(web::WebState* opener); | 35 void SetOpener(web::WebState* opener); |
| 38 | 36 |
| 39 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is | 37 // Returns whether |opener| spawned the wrapped WebState. If |use_group| is |
| 40 // true, also use the opener navigation index to detect navigation changes | 38 // true, also use the opener navigation index to detect navigation changes |
| 41 // during the same session. | 39 // during the same session. |
| 42 bool WasOpenedBy(const web::WebState* opener, | 40 bool WasOpenedBy(const web::WebState* opener, |
| 43 int opener_navigation_index, | 41 int opener_navigation_index, |
| 44 bool use_group) const; | 42 bool use_group) const; |
| 45 | 43 |
| 46 private: | 44 private: |
| 47 web::WebState* web_state_; | 45 web::WebState* web_state_; |
| 48 web::WebState* opener_ = nullptr; | 46 web::WebState* opener_ = nullptr; |
| 49 int opener_last_committed_index_; | 47 int opener_last_committed_index_; |
| 50 const bool has_web_state_ownership_; | |
| 51 | 48 |
| 52 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper); | 49 DISALLOW_COPY_AND_ASSIGN(WebStateWrapper); |
| 53 }; | 50 }; |
| 54 | 51 |
| 55 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state, | 52 WebStateList::WebStateWrapper::WebStateWrapper(web::WebState* web_state) |
| 56 bool assume_ownership) | 53 : web_state_(web_state) { |
| 57 : web_state_(web_state), has_web_state_ownership_(assume_ownership) { | |
| 58 DCHECK(web_state_); | 54 DCHECK(web_state_); |
| 59 } | 55 } |
| 60 | 56 |
| 61 WebStateList::WebStateWrapper::~WebStateWrapper() { | 57 WebStateList::WebStateWrapper::~WebStateWrapper() = default; |
| 62 if (has_web_state_ownership_) | |
| 63 delete web_state_; | |
| 64 } | |
| 65 | 58 |
| 66 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState( | 59 web::WebState* WebStateList::WebStateWrapper::ReplaceWebState( |
| 67 web::WebState* web_state) { | 60 web::WebState* web_state) { |
| 68 DCHECK(web_state); | 61 DCHECK(web_state); |
| 69 DCHECK_NE(web_state, web_state_); | 62 DCHECK_NE(web_state, web_state_); |
| 70 std::swap(web_state, web_state_); | 63 std::swap(web_state, web_state_); |
| 71 opener_ = nullptr; | 64 opener_ = nullptr; |
| 72 return web_state; | 65 return web_state; |
| 73 } | 66 } |
| 74 | 67 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 90 if (!use_group) | 83 if (!use_group) |
| 91 return true; | 84 return true; |
| 92 | 85 |
| 93 return opener_last_committed_index_ == opener_navigation_index; | 86 return opener_last_committed_index_ == opener_navigation_index; |
| 94 } | 87 } |
| 95 | 88 |
| 96 WebStateList::WebStateList(WebStateOwnership ownership) | 89 WebStateList::WebStateList(WebStateOwnership ownership) |
| 97 : web_state_ownership_(ownership), | 90 : web_state_ownership_(ownership), |
| 98 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {} | 91 order_controller_(base::MakeUnique<WebStateListOrderController>(this)) {} |
| 99 | 92 |
| 100 WebStateList::~WebStateList() = default; | 93 WebStateList::~WebStateList() { |
| 94 // Once WebStateList owns the WebState and has a CloseWebStateAt() method, |
| 95 // then change this to close all the WebState. See http://crbug.com/546222 |
| 96 // for progress. |
| 97 if (web_state_ownership_ == WebStateOwned) { |
| 98 for (auto& web_state_wrapper : web_state_wrappers_) { |
| 99 web::WebState* web_state = web_state_wrapper->web_state(); |
| 100 delete web_state; |
| 101 } |
| 102 } |
| 103 } |
| 101 | 104 |
| 102 bool WebStateList::ContainsIndex(int index) const { | 105 bool WebStateList::ContainsIndex(int index) const { |
| 103 return 0 <= index && index < count(); | 106 return 0 <= index && index < count(); |
| 104 } | 107 } |
| 105 | 108 |
| 106 web::WebState* WebStateList::GetWebStateAt(int index) const { | 109 web::WebState* WebStateList::GetWebStateAt(int index) const { |
| 107 DCHECK(ContainsIndex(index)); | 110 DCHECK(ContainsIndex(index)); |
| 108 return web_state_wrappers_[index]->web_state(); | 111 return web_state_wrappers_[index]->web_state(); |
| 109 } | 112 } |
| 110 | 113 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 136 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener, | 139 int WebStateList::GetIndexOfLastWebStateOpenedBy(const web::WebState* opener, |
| 137 int start_index, | 140 int start_index, |
| 138 bool use_group) const { | 141 bool use_group) const { |
| 139 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX); | 142 return GetIndexOfNthWebStateOpenedBy(opener, start_index, use_group, INT_MAX); |
| 140 } | 143 } |
| 141 | 144 |
| 142 void WebStateList::InsertWebState(int index, | 145 void WebStateList::InsertWebState(int index, |
| 143 web::WebState* web_state, | 146 web::WebState* web_state, |
| 144 web::WebState* opener) { | 147 web::WebState* opener) { |
| 145 DCHECK(ContainsIndex(index) || index == count()); | 148 DCHECK(ContainsIndex(index) || index == count()); |
| 146 web_state_wrappers_.insert( | 149 web_state_wrappers_.insert(web_state_wrappers_.begin() + index, |
| 147 web_state_wrappers_.begin() + index, | 150 base::MakeUnique<WebStateWrapper>(web_state)); |
| 148 base::MakeUnique<WebStateWrapper>(web_state, | |
| 149 web_state_ownership_ == WebStateOwned)); | |
| 150 | 151 |
| 151 if (opener) | 152 if (opener) |
| 152 SetOpenerOfWebStateAt(index, opener); | 153 SetOpenerOfWebStateAt(index, opener); |
| 153 | 154 |
| 154 for (auto& observer : observers_) | 155 for (auto& observer : observers_) |
| 155 observer.WebStateInsertedAt(this, web_state, index); | 156 observer.WebStateInsertedAt(this, web_state, index); |
| 156 } | 157 } |
| 157 | 158 |
| 158 void WebStateList::AppendWebState(ui::PageTransition transition, | 159 void WebStateList::AppendWebState(ui::PageTransition transition, |
| 159 web::WebState* web_state, | 160 web::WebState* web_state, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 194 |
| 194 if (opener && opener != old_web_state) | 195 if (opener && opener != old_web_state) |
| 195 SetOpenerOfWebStateAt(index, opener); | 196 SetOpenerOfWebStateAt(index, opener); |
| 196 | 197 |
| 197 for (auto& observer : observers_) | 198 for (auto& observer : observers_) |
| 198 observer.WebStateReplacedAt(this, old_web_state, web_state, index); | 199 observer.WebStateReplacedAt(this, old_web_state, web_state, index); |
| 199 | 200 |
| 200 return old_web_state; | 201 return old_web_state; |
| 201 } | 202 } |
| 202 | 203 |
| 203 void WebStateList::DetachWebStateAt(int index) { | 204 web::WebState* WebStateList::DetachWebStateAt(int index) { |
| 204 DCHECK(ContainsIndex(index)); | 205 DCHECK(ContainsIndex(index)); |
| 205 ClearOpenersReferencing(index); | 206 ClearOpenersReferencing(index); |
| 206 | 207 |
| 207 web::WebState* web_state = web_state_wrappers_[index]->web_state(); | 208 web::WebState* old_web_state = web_state_wrappers_[index]->web_state(); |
| 208 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); | 209 web_state_wrappers_.erase(web_state_wrappers_.begin() + index); |
| 209 | 210 |
| 210 for (auto& observer : observers_) | 211 for (auto& observer : observers_) |
| 211 observer.WebStateDetachedAt(this, web_state, index); | 212 observer.WebStateDetachedAt(this, old_web_state, index); |
| 213 |
| 214 return old_web_state; |
| 212 } | 215 } |
| 213 | 216 |
| 214 void WebStateList::AddObserver(WebStateListObserver* observer) { | 217 void WebStateList::AddObserver(WebStateListObserver* observer) { |
| 215 observers_.AddObserver(observer); | 218 observers_.AddObserver(observer); |
| 216 } | 219 } |
| 217 | 220 |
| 218 void WebStateList::RemoveObserver(WebStateListObserver* observer) { | 221 void WebStateList::RemoveObserver(WebStateListObserver* observer) { |
| 219 observers_.RemoveObserver(observer); | 222 observers_.RemoveObserver(observer); |
| 220 } | 223 } |
| 221 | 224 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 247 } else if (found_index != kInvalidIndex) { | 250 } else if (found_index != kInvalidIndex) { |
| 248 return found_index; | 251 return found_index; |
| 249 } | 252 } |
| 250 } | 253 } |
| 251 | 254 |
| 252 return found_index; | 255 return found_index; |
| 253 } | 256 } |
| 254 | 257 |
| 255 // static | 258 // static |
| 256 const int WebStateList::kInvalidIndex; | 259 const int WebStateList::kInvalidIndex; |
| OLD | NEW |