| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ | 5 #ifndef CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ |
| 6 #define CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ | 6 #define CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/observer_list.h" | 11 #include "base/observer_list.h" |
| 12 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" | 12 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
| 13 #include "chrome/browser/ui/tabs/tab_strip_selection_model.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_selection_model.h" |
| 14 #include "content/public/browser/notification_observer.h" | 14 #include "content/public/browser/notification_observer.h" |
| 15 #include "content/public/browser/notification_registrar.h" | 15 #include "content/public/browser/notification_registrar.h" |
| 16 #include "content/public/common/page_transition_types.h" | 16 #include "content/public/common/page_transition_types.h" |
| 17 | 17 |
| 18 class Profile; | 18 class Profile; |
| 19 class TabContents; | 19 class TabContents; |
| 20 typedef TabContents TabContentsWrapper; | |
| 21 class TabStripModelDelegate; | 20 class TabStripModelDelegate; |
| 22 class TabStripModelOrderController; | 21 class TabStripModelOrderController; |
| 23 | 22 |
| 24 namespace content { | 23 namespace content { |
| 25 class NavigationController; | 24 class NavigationController; |
| 26 class WebContents; | 25 class WebContents; |
| 27 } | 26 } |
| 28 | 27 |
| 29 //////////////////////////////////////////////////////////////////////////////// | 28 //////////////////////////////////////////////////////////////////////////////// |
| 30 // | 29 // |
| 31 // TabStripModel | 30 // TabStripModel |
| 32 // | 31 // |
| 33 // A model & low level controller of a Browser Window tabstrip. Holds a vector | 32 // A model & low level controller of a Browser Window tabstrip. Holds a vector |
| 34 // of TabContentsWrappers, and provides an API for adding, removing and | 33 // of TabContentses, and provides an API for adding, removing and |
| 35 // shuffling them, as well as a higher level API for doing specific Browser- | 34 // shuffling them, as well as a higher level API for doing specific Browser- |
| 36 // related tasks like adding new Tabs from just a URL, etc. | 35 // related tasks like adding new Tabs from just a URL, etc. |
| 37 // | 36 // |
| 38 // Each tab may be any one of the following states: | 37 // Each tab may be any one of the following states: |
| 39 // . Mini-tab. Mini tabs are locked to the left side of the tab strip and | 38 // . Mini-tab. Mini tabs are locked to the left side of the tab strip and |
| 40 // rendered differently (small tabs with only a favicon). The model makes | 39 // rendered differently (small tabs with only a favicon). The model makes |
| 41 // sure all mini-tabs are at the beginning of the tab strip. For example, | 40 // sure all mini-tabs are at the beginning of the tab strip. For example, |
| 42 // if a non-mini tab is added it is forced to be with non-mini tabs. Requests | 41 // if a non-mini tab is added it is forced to be with non-mini tabs. Requests |
| 43 // to move tabs outside the range of the tab type are ignored. For example, | 42 // to move tabs outside the range of the tab type are ignored. For example, |
| 44 // a request to move a mini-tab after non-mini-tabs is ignored. | 43 // a request to move a mini-tab after non-mini-tabs is ignored. |
| 45 // You'll notice there is no explicit api for making a tab a mini-tab, rather | 44 // You'll notice there is no explicit api for making a tab a mini-tab, rather |
| 46 // there are two tab types that are implicitly mini-tabs: | 45 // there are two tab types that are implicitly mini-tabs: |
| 47 // . App. Corresponds to an extension that wants an app tab. App tabs are | 46 // . App. Corresponds to an extension that wants an app tab. App tabs are |
| 48 // identified by TabContentsWrapper::extension_tab_helper()::is_app(). | 47 // identified by TabContents::extension_tab_helper()::is_app(). |
| 49 // App tabs are always pinned (you can't unpin them). | 48 // App tabs are always pinned (you can't unpin them). |
| 50 // . Pinned. Any tab can be pinned. Non-app tabs whose pinned state is changed | 49 // . Pinned. Any tab can be pinned. Non-app tabs whose pinned state is changed |
| 51 // are moved to be with other mini-tabs or non-mini tabs. | 50 // are moved to be with other mini-tabs or non-mini tabs. |
| 52 // | 51 // |
| 53 // A TabStripModel has one delegate that it relies on to perform certain tasks | 52 // A TabStripModel has one delegate that it relies on to perform certain tasks |
| 54 // like creating new TabStripModels (probably hosted in Browser windows) when | 53 // like creating new TabStripModels (probably hosted in Browser windows) when |
| 55 // required. See TabStripDelegate above for more information. | 54 // required. See TabStripDelegate above for more information. |
| 56 // | 55 // |
| 57 // A TabStripModel also has N observers (see TabStripModelObserver above), | 56 // A TabStripModel also has N observers (see TabStripModelObserver above), |
| 58 // which can be registered via Add/RemoveObserver. An Observer is notified of | 57 // which can be registered via Add/RemoveObserver. An Observer is notified of |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // Used to indicate nothing special should happen to the newly inserted | 90 // Used to indicate nothing special should happen to the newly inserted |
| 92 // tab. | 91 // tab. |
| 93 ADD_NONE = 0, | 92 ADD_NONE = 0, |
| 94 | 93 |
| 95 // The tab should be active. | 94 // The tab should be active. |
| 96 ADD_ACTIVE = 1 << 0, | 95 ADD_ACTIVE = 1 << 0, |
| 97 | 96 |
| 98 // The tab should be pinned. | 97 // The tab should be pinned. |
| 99 ADD_PINNED = 1 << 1, | 98 ADD_PINNED = 1 << 1, |
| 100 | 99 |
| 101 // If not set the insertion index of the TabContentsWrapper is left up to | 100 // If not set the insertion index of the TabContents is left up to |
| 102 // the Order Controller associated, so the final insertion index may differ | 101 // the Order Controller associated, so the final insertion index may differ |
| 103 // from the specified index. Otherwise the index supplied is used. | 102 // from the specified index. Otherwise the index supplied is used. |
| 104 ADD_FORCE_INDEX = 1 << 2, | 103 ADD_FORCE_INDEX = 1 << 2, |
| 105 | 104 |
| 106 // If set the newly inserted tab inherits the group of the currently | 105 // If set the newly inserted tab inherits the group of the currently |
| 107 // selected tab. If not set the tab may still inherit the group under | 106 // selected tab. If not set the tab may still inherit the group under |
| 108 // certain situations. | 107 // certain situations. |
| 109 ADD_INHERIT_GROUP = 1 << 3, | 108 ADD_INHERIT_GROUP = 1 << 3, |
| 110 | 109 |
| 111 // If set the newly inserted tab's opener is set to the active tab. If not | 110 // If set the newly inserted tab's opener is set to the active tab. If not |
| (...skipping 16 matching lines...) Expand all Loading... |
| 128 void AddObserver(TabStripModelObserver* observer); | 127 void AddObserver(TabStripModelObserver* observer); |
| 129 void RemoveObserver(TabStripModelObserver* observer); | 128 void RemoveObserver(TabStripModelObserver* observer); |
| 130 | 129 |
| 131 // Retrieve the number of TabContentses/emptiness of the TabStripModel. | 130 // Retrieve the number of TabContentses/emptiness of the TabStripModel. |
| 132 int count() const { return static_cast<int>(contents_data_.size()); } | 131 int count() const { return static_cast<int>(contents_data_.size()); } |
| 133 bool empty() const { return contents_data_.empty(); } | 132 bool empty() const { return contents_data_.empty(); } |
| 134 | 133 |
| 135 // Retrieve the Profile associated with this TabStripModel. | 134 // Retrieve the Profile associated with this TabStripModel. |
| 136 Profile* profile() const { return profile_; } | 135 Profile* profile() const { return profile_; } |
| 137 | 136 |
| 138 // Retrieve the index of the currently active TabContentsWrapper. | 137 // Retrieve the index of the currently active TabContents. |
| 139 int active_index() const { return selection_model_.active(); } | 138 int active_index() const { return selection_model_.active(); } |
| 140 | 139 |
| 141 // Returns true if the tabstrip is currently closing all open tabs (via a | 140 // Returns true if the tabstrip is currently closing all open tabs (via a |
| 142 // call to CloseAllTabs). As tabs close, the selection in the tabstrip | 141 // call to CloseAllTabs). As tabs close, the selection in the tabstrip |
| 143 // changes which notifies observers, which can use this as an optimization to | 142 // changes which notifies observers, which can use this as an optimization to |
| 144 // avoid doing meaningless or unhelpful work. | 143 // avoid doing meaningless or unhelpful work. |
| 145 bool closing_all() const { return closing_all_; } | 144 bool closing_all() const { return closing_all_; } |
| 146 | 145 |
| 147 // Access the order controller. Exposed only for unit tests. | 146 // Access the order controller. Exposed only for unit tests. |
| 148 TabStripModelOrderController* order_controller() const { | 147 TabStripModelOrderController* order_controller() const { |
| 149 return order_controller_; | 148 return order_controller_; |
| 150 } | 149 } |
| 151 | 150 |
| 152 // Sets the insertion policy. Default is INSERT_AFTER. | 151 // Sets the insertion policy. Default is INSERT_AFTER. |
| 153 void SetInsertionPolicy(InsertionPolicy policy); | 152 void SetInsertionPolicy(InsertionPolicy policy); |
| 154 InsertionPolicy insertion_policy() const; | 153 InsertionPolicy insertion_policy() const; |
| 155 | 154 |
| 156 // Returns true if |observer| is in the list of observers. This is intended | 155 // Returns true if |observer| is in the list of observers. This is intended |
| 157 // for debugging. | 156 // for debugging. |
| 158 bool HasObserver(TabStripModelObserver* observer); | 157 bool HasObserver(TabStripModelObserver* observer); |
| 159 | 158 |
| 160 // Basic API ///////////////////////////////////////////////////////////////// | 159 // Basic API ///////////////////////////////////////////////////////////////// |
| 161 | 160 |
| 162 // Determines if the specified index is contained within the TabStripModel. | 161 // Determines if the specified index is contained within the TabStripModel. |
| 163 bool ContainsIndex(int index) const; | 162 bool ContainsIndex(int index) const; |
| 164 | 163 |
| 165 // Adds the specified TabContentsWrapper in the default location. Tabs opened | 164 // Adds the specified TabContents in the default location. Tabs opened |
| 166 // in the foreground inherit the group of the previously active tab. | 165 // in the foreground inherit the group of the previously active tab. |
| 167 void AppendTabContents(TabContentsWrapper* contents, bool foreground); | 166 void AppendTabContents(TabContents* contents, bool foreground); |
| 168 | 167 |
| 169 // Adds the specified TabContentsWrapper at the specified location. | 168 // Adds the specified TabContents at the specified location. |
| 170 // |add_types| is a bitmask of AddTypes; see it for details. | 169 // |add_types| is a bitmask of AddTypes; see it for details. |
| 171 // | 170 // |
| 172 // All append/insert methods end up in this method. | 171 // All append/insert methods end up in this method. |
| 173 // | 172 // |
| 174 // NOTE: adding a tab using this method does NOT query the order controller, | 173 // NOTE: adding a tab using this method does NOT query the order controller, |
| 175 // as such the ADD_FORCE_INDEX AddType is meaningless here. The only time the | 174 // as such the ADD_FORCE_INDEX AddType is meaningless here. The only time the |
| 176 // |index| is changed is if using the index would result in breaking the | 175 // |index| is changed is if using the index would result in breaking the |
| 177 // constraint that all mini-tabs occur before non-mini-tabs. | 176 // constraint that all mini-tabs occur before non-mini-tabs. |
| 178 // See also AddTabContents. | 177 // See also AddTabContents. |
| 179 void InsertTabContentsAt(int index, | 178 void InsertTabContentsAt(int index, |
| 180 TabContentsWrapper* contents, | 179 TabContents* contents, |
| 181 int add_types); | 180 int add_types); |
| 182 | 181 |
| 183 // Closes the TabContentsWrapper at the specified index. This causes the | 182 // Closes the TabContents at the specified index. This causes the |
| 184 // TabContentsWrapper to be destroyed, but it may not happen immediately. | 183 // TabContents to be destroyed, but it may not happen immediately. |
| 185 // |close_types| is a bitmask of CloseTypes. Returns true if the | 184 // |close_types| is a bitmask of CloseTypes. Returns true if the |
| 186 // TabContentsWrapper was closed immediately, false if it was not closed (we | 185 // TabContents was closed immediately, false if it was not closed (we |
| 187 // may be waiting for a response from an onunload handler, or waiting for the | 186 // may be waiting for a response from an onunload handler, or waiting for the |
| 188 // user to confirm closure). | 187 // user to confirm closure). |
| 189 bool CloseTabContentsAt(int index, uint32 close_types); | 188 bool CloseTabContentsAt(int index, uint32 close_types); |
| 190 | 189 |
| 191 // Replaces the entire state of a the tab at index by switching in a | 190 // Replaces the entire state of a the tab at index by switching in a |
| 192 // different NavigationController. This is used through the recently | 191 // different NavigationController. This is used through the recently |
| 193 // closed tabs list, which needs to replace a tab's current state | 192 // closed tabs list, which needs to replace a tab's current state |
| 194 // and history with another set of contents and history. | 193 // and history with another set of contents and history. |
| 195 // | 194 // |
| 196 // The old NavigationController is deallocated and this object takes | 195 // The old NavigationController is deallocated and this object takes |
| 197 // ownership of the passed in controller. | 196 // ownership of the passed in controller. |
| 198 // XXXPINK This API is weird and wrong. Remove it or change it or rename it? | 197 // XXXPINK This API is weird and wrong. Remove it or change it or rename it? |
| 199 void ReplaceNavigationControllerAt(int index, | 198 void ReplaceNavigationControllerAt(int index, |
| 200 TabContentsWrapper* contents); | 199 TabContents* contents); |
| 201 | 200 |
| 202 // Replaces the tab contents at |index| with |new_contents|. The | 201 // Replaces the tab contents at |index| with |new_contents|. The |
| 203 // TabContentsWrapper that was at |index| is returned and ownership returns | 202 // TabContents that was at |index| is returned and ownership returns |
| 204 // to the caller. | 203 // to the caller. |
| 205 TabContentsWrapper* ReplaceTabContentsAt(int index, | 204 TabContents* ReplaceTabContentsAt(int index, |
| 206 TabContentsWrapper* new_contents); | 205 TabContents* new_contents); |
| 207 | 206 |
| 208 // Destroys the TabContentsWrapper at the specified index, but keeps the tab | 207 // Destroys the TabContents at the specified index, but keeps the tab |
| 209 // visible in the tab strip. Used to free memory in low-memory conditions, | 208 // visible in the tab strip. Used to free memory in low-memory conditions, |
| 210 // especially on Chrome OS. The tab reloads if the user clicks on it. | 209 // especially on Chrome OS. The tab reloads if the user clicks on it. |
| 211 // Returns an empty TabContentsWrapper, used only for testing. | 210 // Returns an empty TabContents, used only for testing. |
| 212 TabContentsWrapper* DiscardTabContentsAt(int index); | 211 TabContents* DiscardTabContentsAt(int index); |
| 213 | 212 |
| 214 // Detaches the TabContentsWrapper at the specified index from this strip. The | 213 // Detaches the TabContents at the specified index from this strip. The |
| 215 // TabContentsWrapper is not destroyed, just removed from display. The caller | 214 // TabContents is not destroyed, just removed from display. The caller |
| 216 // is responsible for doing something with it (e.g. stuffing it into another | 215 // is responsible for doing something with it (e.g. stuffing it into another |
| 217 // strip). | 216 // strip). |
| 218 TabContentsWrapper* DetachTabContentsAt(int index); | 217 TabContents* DetachTabContentsAt(int index); |
| 219 | 218 |
| 220 // Makes the tab at the specified index the active tab. |user_gesture| is true | 219 // Makes the tab at the specified index the active tab. |user_gesture| is true |
| 221 // if the user actually clicked on the tab or navigated to it using a keyboard | 220 // if the user actually clicked on the tab or navigated to it using a keyboard |
| 222 // command, false if the tab was activated as a by-product of some other | 221 // command, false if the tab was activated as a by-product of some other |
| 223 // action. | 222 // action. |
| 224 void ActivateTabAt(int index, bool user_gesture); | 223 void ActivateTabAt(int index, bool user_gesture); |
| 225 | 224 |
| 226 // Adds tab at |index| to the currently selected tabs, without changing the | 225 // Adds tab at |index| to the currently selected tabs, without changing the |
| 227 // active tab index. | 226 // active tab index. |
| 228 void AddTabAtToSelection(int index); | 227 void AddTabAtToSelection(int index); |
| 229 | 228 |
| 230 // Move the TabContentsWrapper at the specified index to another index. This | 229 // Move the TabContents at the specified index to another index. This |
| 231 // method does NOT send Detached/Attached notifications, rather it moves the | 230 // method does NOT send Detached/Attached notifications, rather it moves the |
| 232 // TabContentsWrapper inline and sends a Moved notification instead. | 231 // TabContents inline and sends a Moved notification instead. |
| 233 // If |select_after_move| is false, whatever tab was selected before the move | 232 // If |select_after_move| is false, whatever tab was selected before the move |
| 234 // will still be selected, but it's index may have incremented or decremented | 233 // will still be selected, but it's index may have incremented or decremented |
| 235 // one slot. | 234 // one slot. |
| 236 // NOTE: this does nothing if the move would result in app tabs and non-app | 235 // NOTE: this does nothing if the move would result in app tabs and non-app |
| 237 // tabs mixing. | 236 // tabs mixing. |
| 238 void MoveTabContentsAt(int index, int to_position, bool select_after_move); | 237 void MoveTabContentsAt(int index, int to_position, bool select_after_move); |
| 239 | 238 |
| 240 // Moves the selected tabs to |index|. |index| is treated as if the tab strip | 239 // Moves the selected tabs to |index|. |index| is treated as if the tab strip |
| 241 // did not contain any of the selected tabs. For example, if the tabstrip | 240 // did not contain any of the selected tabs. For example, if the tabstrip |
| 242 // contains [A b c D E f] (upper case selected) and this is invoked with 1 the | 241 // contains [A b c D E f] (upper case selected) and this is invoked with 1 the |
| 243 // result is [b A D E c f]. | 242 // result is [b A D E c f]. |
| 244 // This method maintains that all mini-tabs occur before non-mini-tabs. When | 243 // This method maintains that all mini-tabs occur before non-mini-tabs. When |
| 245 // mini-tabs are selected the move is processed in two chunks: first mini-tabs | 244 // mini-tabs are selected the move is processed in two chunks: first mini-tabs |
| 246 // are moved, then non-mini-tabs are moved. If the index is after | 245 // are moved, then non-mini-tabs are moved. If the index is after |
| 247 // (mini-tab-count - selected-mini-tab-count), then the index the non-mini | 246 // (mini-tab-count - selected-mini-tab-count), then the index the non-mini |
| 248 // selected tabs are moved to is (index + selected-mini-tab-count). For | 247 // selected tabs are moved to is (index + selected-mini-tab-count). For |
| 249 // example, if the model consists of [A b c D E f] (A b c are mini) and this | 248 // example, if the model consists of [A b c D E f] (A b c are mini) and this |
| 250 // is inokved with 2, the result is [b c A D E f]. In this example nothing | 249 // is inokved with 2, the result is [b c A D E f]. In this example nothing |
| 251 // special happened because the target index was <= (mini-tab-count - | 250 // special happened because the target index was <= (mini-tab-count - |
| 252 // selected-mini-tab-count). If the target index were 3, then the result would | 251 // selected-mini-tab-count). If the target index were 3, then the result would |
| 253 // be [b c A f D F]. A, being mini, can move no further than index 2. The | 252 // be [b c A f D F]. A, being mini, can move no further than index 2. The |
| 254 // non-mini-tabs are moved to the target index + selected-mini-tab-count (3 + | 253 // non-mini-tabs are moved to the target index + selected-mini-tab-count (3 + |
| 255 // 1) | 254 // 1) |
| 256 void MoveSelectedTabsTo(int index); | 255 void MoveSelectedTabsTo(int index); |
| 257 | 256 |
| 258 // Returns the currently active TabContentsWrapper, or NULL if there is none. | 257 // Returns the currently active TabContents, or NULL if there is none. |
| 259 TabContentsWrapper* GetActiveTabContents() const; | 258 TabContents* GetActiveTabContents() const; |
| 260 | 259 |
| 261 // Returns the TabContentsWrapper at the specified index, or NULL if there is | 260 // Returns the TabContents at the specified index, or NULL if there is |
| 262 // none. | 261 // none. |
| 263 TabContentsWrapper* GetTabContentsAt(int index) const; | 262 TabContents* GetTabContentsAt(int index) const; |
| 264 | 263 |
| 265 // Returns the index of the specified TabContentsWrapper, or | 264 // Returns the index of the specified TabContents, or |
| 266 // TabStripModel::kNoTab if the TabContentsWrapper is not in this | 265 // TabStripModel::kNoTab if the TabContents is not in this |
| 267 // TabStripModel. | 266 // TabStripModel. |
| 268 int GetIndexOfTabContents(const TabContentsWrapper* contents) const; | 267 int GetIndexOfTabContents(const TabContents* contents) const; |
| 269 | 268 |
| 270 // Returns the index of the specified TabContentsWrapper given its raw | 269 // Returns the index of the specified TabContents given its raw |
| 271 // WebContents, or TabStripModel::kNoTab if the WebContents is not in this | 270 // WebContents, or TabStripModel::kNoTab if the WebContents is not in this |
| 272 // TabStripModel. Note: This is only needed in rare cases where the wrapper | 271 // TabStripModel. Note: This is only needed in rare cases where the |
| 273 // is not already present (such as implementing WebContentsDelegate methods, | 272 // TabContents is not already present (such as implementing |
| 274 // which don't know about the wrapper. Returns NULL if |contents| is not | 273 // WebContentsDelegate methods, which don't know about TabContents). Returns |
| 275 // associated with any TabContentsWrapper in the model. | 274 // NULL if |contents| is not associated with any TabContents in the |
| 276 int GetWrapperIndex(const content::WebContents* contents) const; | 275 // model. |
| 276 int GetIndexOfWebContents(const content::WebContents* contents) const; |
| 277 | 277 |
| 278 // Returns the index of the specified NavigationController, or kNoTab if it is | 278 // Returns the index of the specified NavigationController, or kNoTab if it is |
| 279 // not in this TabStripModel. | 279 // not in this TabStripModel. |
| 280 int GetIndexOfController( | 280 int GetIndexOfController( |
| 281 const content::NavigationController* controller) const; | 281 const content::NavigationController* controller) const; |
| 282 | 282 |
| 283 // Notify any observers that the TabContentsWrapper at the specified index has | 283 // Notify any observers that the TabContents at the specified index has |
| 284 // changed in some way. See TabChangeType for details of |change_type|. | 284 // changed in some way. See TabChangeType for details of |change_type|. |
| 285 void UpdateTabContentsStateAt( | 285 void UpdateTabContentsStateAt( |
| 286 int index, | 286 int index, |
| 287 TabStripModelObserver::TabChangeType change_type); | 287 TabStripModelObserver::TabChangeType change_type); |
| 288 | 288 |
| 289 // Make sure there is an auto-generated New Tab tab in the TabStripModel. | 289 // Make sure there is an auto-generated New Tab tab in the TabStripModel. |
| 290 // If |force_create| is true, the New Tab will be created even if the | 290 // If |force_create| is true, the New Tab will be created even if the |
| 291 // preference is set to false (used by startup). | 291 // preference is set to false (used by startup). |
| 292 void EnsureNewTabVisible(bool force_create); | 292 void EnsureNewTabVisible(bool force_create); |
| 293 | 293 |
| 294 // Close all tabs at once. Code can use closing_all() above to defer | 294 // Close all tabs at once. Code can use closing_all() above to defer |
| 295 // operations that might otherwise by invoked by the flurry of detach/select | 295 // operations that might otherwise by invoked by the flurry of detach/select |
| 296 // notifications this method causes. | 296 // notifications this method causes. |
| 297 void CloseAllTabs(); | 297 void CloseAllTabs(); |
| 298 | 298 |
| 299 // Returns true if there are any TabContentsWrappers that are currently | 299 // Returns true if there are any TabContentses that are currently loading. |
| 300 // loading. | |
| 301 bool TabsAreLoading() const; | 300 bool TabsAreLoading() const; |
| 302 | 301 |
| 303 // Returns the controller controller that opened the TabContentsWrapper at | 302 // Returns the controller controller that opened the TabContents at |
| 304 // |index|. | 303 // |index|. |
| 305 content::NavigationController* GetOpenerOfTabContentsAt(int index); | 304 content::NavigationController* GetOpenerOfTabContentsAt(int index); |
| 306 | 305 |
| 307 // Changes the |opener| of the TabContentsWrapper at |index|. | 306 // Changes the |opener| of the TabContents at |index|. |
| 308 // Note: |opener| must be in this tab strip. | 307 // Note: |opener| must be in this tab strip. |
| 309 void SetOpenerOfTabContentsAt( | 308 void SetOpenerOfTabContentsAt( |
| 310 int index, | 309 int index, |
| 311 content::NavigationController* opener); | 310 content::NavigationController* opener); |
| 312 | 311 |
| 313 // Returns the index of the next TabContentsWrapper in the sequence of | 312 // Returns the index of the next TabContents in the sequence of |
| 314 // TabContentsWrappers spawned by the specified NavigationController after | 313 // TabContentses spawned by the specified NavigationController after |
| 315 // |start_index|. If |use_group| is true, the group property of the tab is | 314 // |start_index|. If |use_group| is true, the group property of the tab is |
| 316 // used instead of the opener to find the next tab. Under some circumstances | 315 // used instead of the opener to find the next tab. Under some circumstances |
| 317 // the group relationship may exist but the opener may not. | 316 // the group relationship may exist but the opener may not. |
| 318 int GetIndexOfNextTabContentsOpenedBy( | 317 int GetIndexOfNextTabContentsOpenedBy( |
| 319 const content::NavigationController* opener, | 318 const content::NavigationController* opener, |
| 320 int start_index, | 319 int start_index, |
| 321 bool use_group) const; | 320 bool use_group) const; |
| 322 | 321 |
| 323 // Returns the index of the first TabContentsWrapper in the model opened by | 322 // Returns the index of the first TabContents in the model opened by |
| 324 // the specified opener. | 323 // the specified opener. |
| 325 int GetIndexOfFirstTabContentsOpenedBy( | 324 int GetIndexOfFirstTabContentsOpenedBy( |
| 326 const content::NavigationController* opener, | 325 const content::NavigationController* opener, |
| 327 int start_index) const; | 326 int start_index) const; |
| 328 | 327 |
| 329 // Returns the index of the last TabContentsWrapper in the model opened by the | 328 // Returns the index of the last TabContents in the model opened by the |
| 330 // specified opener, starting at |start_index|. | 329 // specified opener, starting at |start_index|. |
| 331 int GetIndexOfLastTabContentsOpenedBy( | 330 int GetIndexOfLastTabContentsOpenedBy( |
| 332 const content::NavigationController* opener, | 331 const content::NavigationController* opener, |
| 333 int start_index) const; | 332 int start_index) const; |
| 334 | 333 |
| 335 // Called by the Browser when a navigation is about to occur in the specified | 334 // Called by the Browser when a navigation is about to occur in the specified |
| 336 // TabContentsWrapper. Depending on the tab, and the transition type of the | 335 // TabContents. Depending on the tab, and the transition type of the |
| 337 // navigation, the TabStripModel may adjust its selection and grouping | 336 // navigation, the TabStripModel may adjust its selection and grouping |
| 338 // behavior. | 337 // behavior. |
| 339 void TabNavigating(TabContentsWrapper* contents, | 338 void TabNavigating(TabContents* contents, |
| 340 content::PageTransition transition); | 339 content::PageTransition transition); |
| 341 | 340 |
| 342 // Forget all Opener relationships that are stored (but _not_ group | 341 // Forget all Opener relationships that are stored (but _not_ group |
| 343 // relationships!) This is to reduce unpredictable tab switching behavior | 342 // relationships!) This is to reduce unpredictable tab switching behavior |
| 344 // in complex session states. The exact circumstances under which this method | 343 // in complex session states. The exact circumstances under which this method |
| 345 // is called are left up to the implementation of the selected | 344 // is called are left up to the implementation of the selected |
| 346 // TabStripModelOrderController. | 345 // TabStripModelOrderController. |
| 347 void ForgetAllOpeners(); | 346 void ForgetAllOpeners(); |
| 348 | 347 |
| 349 // Forgets the group affiliation of the specified TabContentsWrapper. This | 348 // Forgets the group affiliation of the specified TabContents. This |
| 350 // should be called when a TabContentsWrapper that is part of a logical group | 349 // should be called when a TabContents that is part of a logical group |
| 351 // of tabs is moved to a new logical context by the user (e.g. by typing a new | 350 // of tabs is moved to a new logical context by the user (e.g. by typing a new |
| 352 // URL or selecting a bookmark). This also forgets the opener, which is | 351 // URL or selecting a bookmark). This also forgets the opener, which is |
| 353 // considered a weaker relationship than group. | 352 // considered a weaker relationship than group. |
| 354 void ForgetGroup(TabContentsWrapper* contents); | 353 void ForgetGroup(TabContents* contents); |
| 355 | 354 |
| 356 // Returns true if the group/opener relationships present for |contents| | 355 // Returns true if the group/opener relationships present for |contents| |
| 357 // should be reset when _any_ selection change occurs in the model. | 356 // should be reset when _any_ selection change occurs in the model. |
| 358 bool ShouldResetGroupOnSelect(TabContentsWrapper* contents) const; | 357 bool ShouldResetGroupOnSelect(TabContents* contents) const; |
| 359 | 358 |
| 360 // Changes the blocked state of the tab at |index|. | 359 // Changes the blocked state of the tab at |index|. |
| 361 void SetTabBlocked(int index, bool blocked); | 360 void SetTabBlocked(int index, bool blocked); |
| 362 | 361 |
| 363 // Changes the pinned state of the tab at |index|. See description above | 362 // Changes the pinned state of the tab at |index|. See description above |
| 364 // class for details on this. | 363 // class for details on this. |
| 365 void SetTabPinned(int index, bool pinned); | 364 void SetTabPinned(int index, bool pinned); |
| 366 | 365 |
| 367 // Returns true if the tab at |index| is pinned. | 366 // Returns true if the tab at |index| is pinned. |
| 368 // See description above class for details on pinned tabs. | 367 // See description above class for details on pinned tabs. |
| 369 bool IsTabPinned(int index) const; | 368 bool IsTabPinned(int index) const; |
| 370 | 369 |
| 371 // Is the tab a mini-tab? | 370 // Is the tab a mini-tab? |
| 372 // See description above class for details on this. | 371 // See description above class for details on this. |
| 373 bool IsMiniTab(int index) const; | 372 bool IsMiniTab(int index) const; |
| 374 | 373 |
| 375 // Is the tab at |index| an app? | 374 // Is the tab at |index| an app? |
| 376 // See description above class for details on app tabs. | 375 // See description above class for details on app tabs. |
| 377 bool IsAppTab(int index) const; | 376 bool IsAppTab(int index) const; |
| 378 | 377 |
| 379 // Returns true if the tab at |index| is blocked by a tab modal dialog. | 378 // Returns true if the tab at |index| is blocked by a tab modal dialog. |
| 380 bool IsTabBlocked(int index) const; | 379 bool IsTabBlocked(int index) const; |
| 381 | 380 |
| 382 // Returns true if the TabContentsWrapper at |index| has been discarded to | 381 // Returns true if the TabContents at |index| has been discarded to |
| 383 // save memory. See DiscardTabContentsAt() for details. | 382 // save memory. See DiscardTabContentsAt() for details. |
| 384 bool IsTabDiscarded(int index) const; | 383 bool IsTabDiscarded(int index) const; |
| 385 | 384 |
| 386 // Returns the index of the first tab that is not a mini-tab. This returns | 385 // Returns the index of the first tab that is not a mini-tab. This returns |
| 387 // |count()| if all of the tabs are mini-tabs, and 0 if none of the tabs are | 386 // |count()| if all of the tabs are mini-tabs, and 0 if none of the tabs are |
| 388 // mini-tabs. | 387 // mini-tabs. |
| 389 int IndexOfFirstNonMiniTab() const; | 388 int IndexOfFirstNonMiniTab() const; |
| 390 | 389 |
| 391 // Returns a valid index for inserting a new tab into this model. |index| is | 390 // Returns a valid index for inserting a new tab into this model. |index| is |
| 392 // the proposed index and |mini_tab| is true if inserting a tab will become | 391 // the proposed index and |mini_tab| is true if inserting a tab will become |
| (...skipping 18 matching lines...) Expand all Loading... |
| 411 | 410 |
| 412 // Sets the selection to match that of |source|. | 411 // Sets the selection to match that of |source|. |
| 413 void SetSelectionFromModel(const TabStripSelectionModel& source); | 412 void SetSelectionFromModel(const TabStripSelectionModel& source); |
| 414 | 413 |
| 415 const TabStripSelectionModel& selection_model() const { | 414 const TabStripSelectionModel& selection_model() const { |
| 416 return selection_model_; | 415 return selection_model_; |
| 417 } | 416 } |
| 418 | 417 |
| 419 // Command level API ///////////////////////////////////////////////////////// | 418 // Command level API ///////////////////////////////////////////////////////// |
| 420 | 419 |
| 421 // Adds a TabContentsWrapper at the best position in the TabStripModel given | 420 // Adds a TabContents at the best position in the TabStripModel given |
| 422 // the specified insertion index, transition, etc. |add_types| is a bitmask of | 421 // the specified insertion index, transition, etc. |add_types| is a bitmask of |
| 423 // AddTypes; see it for details. This method ends up calling into | 422 // AddTypes; see it for details. This method ends up calling into |
| 424 // InsertTabContentsAt to do the actual insertion. | 423 // InsertTabContentsAt to do the actual insertion. |
| 425 void AddTabContents(TabContentsWrapper* contents, | 424 void AddTabContents(TabContents* contents, |
| 426 int index, | 425 int index, |
| 427 content::PageTransition transition, | 426 content::PageTransition transition, |
| 428 int add_types); | 427 int add_types); |
| 429 | 428 |
| 430 // Closes the selected tabs. | 429 // Closes the selected tabs. |
| 431 void CloseSelectedTabs(); | 430 void CloseSelectedTabs(); |
| 432 | 431 |
| 433 // Select adjacent tabs | 432 // Select adjacent tabs |
| 434 void SelectNextTab(); | 433 void SelectNextTab(); |
| 435 void SelectPreviousTab(); | 434 void SelectPreviousTab(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 | 508 |
| 510 // Gets the set of tab indices that have the same opener as the tab at | 509 // Gets the set of tab indices that have the same opener as the tab at |
| 511 // |index|. | 510 // |index|. |
| 512 void GetIndicesWithSameOpener(int index, std::vector<int>* indices); | 511 void GetIndicesWithSameOpener(int index, std::vector<int>* indices); |
| 513 | 512 |
| 514 // If |index| is selected all the selected indices are returned, otherwise a | 513 // If |index| is selected all the selected indices are returned, otherwise a |
| 515 // vector with |index| is returned. This is used when executing commands to | 514 // vector with |index| is returned. This is used when executing commands to |
| 516 // determine which indices the command applies to. | 515 // determine which indices the command applies to. |
| 517 std::vector<int> GetIndicesForCommand(int index) const; | 516 std::vector<int> GetIndicesForCommand(int index) const; |
| 518 | 517 |
| 519 // Returns true if the specified TabContentsWrapper is a New Tab at the end of | 518 // Returns true if the specified TabContents is a New Tab at the end of |
| 520 // the TabStrip. We check for this because opener relationships are _not_ | 519 // the TabStrip. We check for this because opener relationships are _not_ |
| 521 // forgotten for the New Tab page opened as a result of a New Tab gesture | 520 // forgotten for the New Tab page opened as a result of a New Tab gesture |
| 522 // (e.g. Ctrl+T, etc) since the user may open a tab transiently to look up | 521 // (e.g. Ctrl+T, etc) since the user may open a tab transiently to look up |
| 523 // something related to their current activity. | 522 // something related to their current activity. |
| 524 bool IsNewTabAtEndOfTabStrip(TabContentsWrapper* contents) const; | 523 bool IsNewTabAtEndOfTabStrip(TabContents* contents) const; |
| 525 | 524 |
| 526 // Closes the TabContentsWrappers at the specified indices. This causes the | 525 // Closes the TabContentses at the specified indices. This causes the |
| 527 // TabContentsWrappers to be destroyed, but it may not happen immediately. If | 526 // TabContentses to be destroyed, but it may not happen immediately. If |
| 528 // the page in question has an unload event the WebContents will not be | 527 // the page in question has an unload event the WebContents will not be |
| 529 // destroyed until after the event has completed, which will then call back | 528 // destroyed until after the event has completed, which will then call back |
| 530 // into this method. | 529 // into this method. |
| 531 // | 530 // |
| 532 // Returns true if the TabContentsWrapper were closed immediately, false if we | 531 // Returns true if the TabContentses were closed immediately, false if we |
| 533 // are waiting for the result of an onunload handler. | 532 // are waiting for the result of an onunload handler. |
| 534 bool InternalCloseTabs(const std::vector<int>& in_indices, | 533 bool InternalCloseTabs(const std::vector<int>& in_indices, |
| 535 uint32 close_types); | 534 uint32 close_types); |
| 536 | 535 |
| 537 // Invoked from InternalCloseTabs and when an extension is removed for an app | 536 // Invoked from InternalCloseTabs and when an extension is removed for an app |
| 538 // tab. Notifies observers of TabClosingAt and deletes |contents|. If | 537 // tab. Notifies observers of TabClosingAt and deletes |contents|. If |
| 539 // |create_historical_tabs| is true, CreateHistoricalTab is invoked on the | 538 // |create_historical_tabs| is true, CreateHistoricalTab is invoked on the |
| 540 // delegate. | 539 // delegate. |
| 541 // | 540 // |
| 542 // The boolean parameter create_historical_tab controls whether to | 541 // The boolean parameter create_historical_tab controls whether to |
| 543 // record these tabs and their history for reopening recently closed | 542 // record these tabs and their history for reopening recently closed |
| 544 // tabs. | 543 // tabs. |
| 545 void InternalCloseTab(TabContentsWrapper* contents, | 544 void InternalCloseTab(TabContents* contents, |
| 546 int index, | 545 int index, |
| 547 bool create_historical_tabs); | 546 bool create_historical_tabs); |
| 548 | 547 |
| 549 TabContentsWrapper* GetContentsAt(int index) const; | 548 TabContents* GetContentsAt(int index) const; |
| 550 | 549 |
| 551 // Notifies the observers if the active tab is being deactivated. | 550 // Notifies the observers if the active tab is being deactivated. |
| 552 void NotifyIfTabDeactivated(TabContentsWrapper* contents); | 551 void NotifyIfTabDeactivated(TabContents* contents); |
| 553 | 552 |
| 554 // Notifies the observers if the active tab has changed. | 553 // Notifies the observers if the active tab has changed. |
| 555 void NotifyIfActiveTabChanged(TabContentsWrapper* old_contents, | 554 void NotifyIfActiveTabChanged(TabContents* old_contents, |
| 556 NotifyTypes notify_types); | 555 NotifyTypes notify_types); |
| 557 | 556 |
| 558 // Notifies the observers if the active tab or the tab selection has changed. | 557 // Notifies the observers if the active tab or the tab selection has changed. |
| 559 // |old_model| is a snapshot of |selection_model_| before the change. | 558 // |old_model| is a snapshot of |selection_model_| before the change. |
| 560 // Note: This function might end up sending 0 to 2 notifications in the | 559 // Note: This function might end up sending 0 to 2 notifications in the |
| 561 // following order: ActiveTabChanged, TabSelectionChanged. | 560 // following order: ActiveTabChanged, TabSelectionChanged. |
| 562 void NotifyIfActiveOrSelectionChanged( | 561 void NotifyIfActiveOrSelectionChanged( |
| 563 TabContentsWrapper* old_contents, | 562 TabContents* old_contents, |
| 564 NotifyTypes notify_types, | 563 NotifyTypes notify_types, |
| 565 const TabStripSelectionModel& old_model); | 564 const TabStripSelectionModel& old_model); |
| 566 | 565 |
| 567 // Sets the selection to |new_model| and notifies any observers. | 566 // Sets the selection to |new_model| and notifies any observers. |
| 568 // Note: This function might end up sending 0 to 3 notifications in the | 567 // Note: This function might end up sending 0 to 3 notifications in the |
| 569 // following order: TabDeactivated, ActiveTabChanged, TabSelectionChanged. | 568 // following order: TabDeactivated, ActiveTabChanged, TabSelectionChanged. |
| 570 void SetSelection(const TabStripSelectionModel& new_model, | 569 void SetSelection(const TabStripSelectionModel& new_model, |
| 571 NotifyTypes notify_types); | 570 NotifyTypes notify_types); |
| 572 | 571 |
| 573 // Returns the number of New Tab tabs in the TabStripModel. | 572 // Returns the number of New Tab tabs in the TabStripModel. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 595 const content::NavigationController* opener, | 594 const content::NavigationController* opener, |
| 596 bool use_group); | 595 bool use_group); |
| 597 | 596 |
| 598 // Sets the group/opener of any tabs that reference |tab| to NULL. | 597 // Sets the group/opener of any tabs that reference |tab| to NULL. |
| 599 void ForgetOpenersAndGroupsReferencing( | 598 void ForgetOpenersAndGroupsReferencing( |
| 600 const content::NavigationController* tab); | 599 const content::NavigationController* tab); |
| 601 | 600 |
| 602 // Our delegate. | 601 // Our delegate. |
| 603 TabStripModelDelegate* delegate_; | 602 TabStripModelDelegate* delegate_; |
| 604 | 603 |
| 605 // A hunk of data representing a TabContentsWrapper and (optionally) the | 604 // A hunk of data representing a TabContents and (optionally) the |
| 606 // NavigationController that spawned it. This memory only sticks around while | 605 // NavigationController that spawned it. This memory only sticks around while |
| 607 // the TabContentsWrapper is in the current TabStripModel, unless otherwise | 606 // the TabContents is in the current TabStripModel, unless otherwise |
| 608 // specified in code. | 607 // specified in code. |
| 609 struct TabContentsData { | 608 struct TabContentsData { |
| 610 explicit TabContentsData(TabContentsWrapper* a_contents) | 609 explicit TabContentsData(TabContents* a_contents) |
| 611 : contents(a_contents), | 610 : contents(a_contents), |
| 612 reset_group_on_select(false), | 611 reset_group_on_select(false), |
| 613 pinned(false), | 612 pinned(false), |
| 614 blocked(false), | 613 blocked(false), |
| 615 discarded(false) { | 614 discarded(false) { |
| 616 SetGroup(NULL); | 615 SetGroup(NULL); |
| 617 } | 616 } |
| 618 | 617 |
| 619 // Create a relationship between this TabContentsWrapper and other | 618 // Create a relationship between this TabContents and other |
| 620 // TabContentsWrappers. Used to identify which TabContentsWrapper to select | 619 // TabContentses. Used to identify which TabContents to select |
| 621 // next after one is closed. | 620 // next after one is closed. |
| 622 void SetGroup(content::NavigationController* a_group) { | 621 void SetGroup(content::NavigationController* a_group) { |
| 623 group = a_group; | 622 group = a_group; |
| 624 opener = a_group; | 623 opener = a_group; |
| 625 } | 624 } |
| 626 | 625 |
| 627 // Forget the opener relationship so that when this TabContentsWrapper is | 626 // Forget the opener relationship so that when this TabContents is |
| 628 // closed unpredictable re-selection does not occur. | 627 // closed unpredictable re-selection does not occur. |
| 629 void ForgetOpener() { | 628 void ForgetOpener() { |
| 630 opener = NULL; | 629 opener = NULL; |
| 631 } | 630 } |
| 632 | 631 |
| 633 TabContentsWrapper* contents; | 632 TabContents* contents; |
| 634 // We use NavigationControllers here since they more closely model the | 633 // We use NavigationControllers here since they more closely model the |
| 635 // "identity" of a Tab, TabContentsWrappers can change depending on the URL | 634 // "identity" of a Tab, TabContentses can change depending on the URL |
| 636 // loaded in the Tab. | 635 // loaded in the Tab. |
| 637 // The group is used to model a set of tabs spawned from a single parent | 636 // The group is used to model a set of tabs spawned from a single parent |
| 638 // tab. This value is preserved for a given tab as long as the tab remains | 637 // tab. This value is preserved for a given tab as long as the tab remains |
| 639 // navigated to the link it was initially opened at or some navigation from | 638 // navigated to the link it was initially opened at or some navigation from |
| 640 // that page (i.e. if the user types or visits a bookmark or some other | 639 // that page (i.e. if the user types or visits a bookmark or some other |
| 641 // navigation within that tab, the group relationship is lost). This | 640 // navigation within that tab, the group relationship is lost). This |
| 642 // property can safely be used to implement features that depend on a | 641 // property can safely be used to implement features that depend on a |
| 643 // logical group of related tabs. | 642 // logical group of related tabs. |
| 644 content::NavigationController* group; | 643 content::NavigationController* group; |
| 645 // The owner models the same relationship as group, except it is more | 644 // The owner models the same relationship as group, except it is more |
| (...skipping 12 matching lines...) Expand all Loading... |
| 658 // Is the tab pinned? | 657 // Is the tab pinned? |
| 659 bool pinned; | 658 bool pinned; |
| 660 | 659 |
| 661 // Is the tab interaction blocked by a modal dialog? | 660 // Is the tab interaction blocked by a modal dialog? |
| 662 bool blocked; | 661 bool blocked; |
| 663 | 662 |
| 664 // Has the tab data been discarded to save memory? | 663 // Has the tab data been discarded to save memory? |
| 665 bool discarded; | 664 bool discarded; |
| 666 }; | 665 }; |
| 667 | 666 |
| 668 // The TabContentsWrapper data currently hosted within this TabStripModel. | 667 // The TabContents data currently hosted within this TabStripModel. |
| 669 typedef std::vector<TabContentsData*> TabContentsDataVector; | 668 typedef std::vector<TabContentsData*> TabContentsDataVector; |
| 670 TabContentsDataVector contents_data_; | 669 TabContentsDataVector contents_data_; |
| 671 | 670 |
| 672 // A profile associated with this TabStripModel, used when creating new Tabs. | 671 // A profile associated with this TabStripModel, used when creating new Tabs. |
| 673 Profile* profile_; | 672 Profile* profile_; |
| 674 | 673 |
| 675 // True if all tabs are currently being closed via CloseAllTabs. | 674 // True if all tabs are currently being closed via CloseAllTabs. |
| 676 bool closing_all_; | 675 bool closing_all_; |
| 677 | 676 |
| 678 // An object that determines where new Tabs should be inserted and where | 677 // An object that determines where new Tabs should be inserted and where |
| 679 // selection should move when a Tab is closed. | 678 // selection should move when a Tab is closed. |
| 680 TabStripModelOrderController* order_controller_; | 679 TabStripModelOrderController* order_controller_; |
| 681 | 680 |
| 682 // Our observers. | 681 // Our observers. |
| 683 typedef ObserverList<TabStripModelObserver> TabStripModelObservers; | 682 typedef ObserverList<TabStripModelObserver> TabStripModelObservers; |
| 684 TabStripModelObservers observers_; | 683 TabStripModelObservers observers_; |
| 685 | 684 |
| 686 // A scoped container for notification registries. | 685 // A scoped container for notification registries. |
| 687 content::NotificationRegistrar registrar_; | 686 content::NotificationRegistrar registrar_; |
| 688 | 687 |
| 689 TabStripSelectionModel selection_model_; | 688 TabStripSelectionModel selection_model_; |
| 690 | 689 |
| 691 DISALLOW_IMPLICIT_CONSTRUCTORS(TabStripModel); | 690 DISALLOW_IMPLICIT_CONSTRUCTORS(TabStripModel); |
| 692 }; | 691 }; |
| 693 | 692 |
| 694 #endif // CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ | 693 #endif // CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_ |
| OLD | NEW |