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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_OBSERVER_H_
6#define CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_OBSERVER_H_
7
8class TabStripModel;
9
10namespace content {
11class WebContents;
12}
13
14namespace ui {
15class ListSelectionModel;
16}
17
18////////////////////////////////////////////////////////////////////////////////
19//
20// TabStripModelObserver
21//
22//  Objects implement this interface when they wish to be notified of changes
23//  to the TabStripModel.
24//
25//  Two major implementers are the TabStrip, which uses notifications sent
26//  via this interface to update the presentation of the strip, and the Browser
27//  object, which updates bookkeeping and shows/hides individual WebContentses.
28//
29//  Register your TabStripModelObserver with the TabStripModel using its
30//  Add/RemoveObserver methods.
31//
32////////////////////////////////////////////////////////////////////////////////
33class TabStripModelObserver {
34 public:
35  // Enumeration of the possible values supplied to TabChangedAt.
36  enum TabChangeType {
37    // Only the loading state changed.
38    LOADING_ONLY,
39
40    // Only the title changed and page isn't loading.
41    TITLE_NOT_LOADING,
42
43    // Change not characterized by LOADING_ONLY or TITLE_NOT_LOADING.
44    ALL
45  };
46
47  enum ChangeReason {
48    // Used to indicate that none of the reasons below are responsible for the
49    // active tab change.
50    CHANGE_REASON_NONE = 0,
51    // The active tab changed because the tab's web contents was replaced.
52    CHANGE_REASON_REPLACED = 1 << 0,
53    // The active tab changed due to a user input event.
54    CHANGE_REASON_USER_GESTURE = 1 << 1,
55  };
56
57  // A new WebContents was inserted into the TabStripModel at the
58  // specified index. |foreground| is whether or not it was opened in the
59  // foreground (selected).
60  virtual void TabInsertedAt(content::WebContents* contents,
61                             int index,
62                             bool foreground);
63
64  // The specified WebContents at |index| is being closed (and eventually
65  // destroyed). |tab_strip_model| is the TabStripModel that contained the tab.
66  virtual void TabClosingAt(TabStripModel* tab_strip_model,
67                            content::WebContents* contents,
68                            int index);
69
70  // The specified WebContents at |index| is being detached, perhaps to
71  // be inserted in another TabStripModel. The implementer should take whatever
72  // action is necessary to deal with the WebContents no longer being
73  // present.
74  virtual void TabDetachedAt(content::WebContents* contents, int index);
75
76  // The active WebContents is about to change from |old_contents|.
77  // This gives observers a chance to prepare for an impending switch before it
78  // happens.
79  virtual void TabDeactivated(content::WebContents* contents);
80
81  // Sent when the active tab changes. The previously active tab is identified
82  // by |old_contents| and the newly active tab by |new_contents|. |index| is
83  // the index of |new_contents|. If |reason| has CHANGE_REASON_REPLACED set
84  // then the web contents was replaced (see TabChangedAt). If |reason| has
85  // CHANGE_REASON_USER_GESTURE set then the web contents was changed due to a
86  // user input event (e.g. clicking on a tab, keystroke).
87  // Note: It is possible for the selection to change while the active tab
88  // remains unchanged. For example, control-click may not change the active tab
89  // but does change the selection. In this case |ActiveTabChanged| is not sent.
90  // If you care about any changes to the selection, override
91  // TabSelectionChanged.
92  // Note: |old_contents| will be NULL if there was no contents previously
93  // active.
94  virtual void ActiveTabChanged(content::WebContents* old_contents,
95                                content::WebContents* new_contents,
96                                int index,
97                                int reason);
98
99  // Sent when the selection changes in |tab_strip_model|. More precisely when
100  // selected tabs, anchor tab or active tab change. |old_model| is a snapshot
101  // of the selection model before the change. See also ActiveTabChanged for
102  // details.
103  virtual void TabSelectionChanged(TabStripModel* tab_strip_model,
104                                   const ui::ListSelectionModel& old_model);
105
106  // The specified WebContents at |from_index| was moved to |to_index|.
107  virtual void TabMoved(content::WebContents* contents,
108                        int from_index,
109                        int to_index);
110
111  // The specified WebContents at |index| changed in some way. |contents|
112  // may be an entirely different object and the old value is no longer
113  // available by the time this message is delivered.
114  //
115  // See TabChangeType for a description of |change_type|.
116  virtual void TabChangedAt(content::WebContents* contents,
117                            int index,
118                            TabChangeType change_type);
119
120  // The WebContents was replaced at the specified index. This is invoked
121  // when instant is enabled and the user navigates by way of instant or when
122  // prerendering swaps in a prerendered WebContents.
123  virtual void TabReplacedAt(TabStripModel* tab_strip_model,
124                             content::WebContents* old_contents,
125                             content::WebContents* new_contents,
126                             int index);
127
128  // Invoked when the pinned state of a tab changes. See note in
129  // TabMiniStateChanged as to how this relates to TabMiniStateChanged.
130  virtual void TabPinnedStateChanged(content::WebContents* contents, int index);
131
132  // Invoked if the mini state of a tab changes.
133  // NOTE: This is sent when the pinned state of a non-app tab changes and is
134  // sent in addition to TabPinnedStateChanged. UI code typically need not care
135  // about TabPinnedStateChanged, but instead this.
136  virtual void TabMiniStateChanged(content::WebContents* contents, int index);
137
138  // Invoked when the blocked state of a tab changes.
139  // NOTE: This is invoked when a tab becomes blocked/unblocked by a tab modal
140  // window.
141  virtual void TabBlockedStateChanged(content::WebContents* contents,
142                                      int index);
143
144  // The TabStripModel now no longer has any tabs. The implementer may
145  // use this as a trigger to try and close the window containing the
146  // TabStripModel, for example...
147  virtual void TabStripEmpty();
148
149  // Sent any time an attempt is made to close all the tabs. This is not
150  // necessarily the result of CloseAllTabs(). For example, if the user closes
151  // the last tab WillCloseAllTabs() is sent. If the close does not succeed
152  // during the current event (say unload handlers block it) then
153  // CloseAllTabsCanceled() is sent. Also note that if the last tab is detached
154  // (DetachWebContentsAt()) then this is not sent.
155  virtual void WillCloseAllTabs();
156  virtual void CloseAllTabsCanceled();
157
158  // Sent when the tabstrip model is about to be deleted and any reference held
159  // must be dropped.
160  virtual void TabStripModelDeleted();
161
162 protected:
163  virtual ~TabStripModelObserver() {}
164};
165
166#endif  // CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_OBSERVER_H_
167