Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / back_forward_menu_model.h
blob5036ac87609c0e2dda7ec5ed3c18f72dbc74e6f6
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.
5 #ifndef CHROME_BROWSER_UI_TOOLBAR_BACK_FORWARD_MENU_MODEL_H_
6 #define CHROME_BROWSER_UI_TOOLBAR_BACK_FORWARD_MENU_MODEL_H_
8 #include <set>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/strings/string16.h"
14 #include "base/task/cancelable_task_tracker.h"
15 #include "components/favicon/core/favicon_service.h"
16 #include "ui/base/models/menu_model.h"
17 #include "ui/base/window_open_disposition.h"
19 class Browser;
21 namespace favicon_base {
22 struct FaviconImageResult;
25 namespace content {
26 class NavigationEntry;
27 class WebContents;
30 namespace gfx {
31 class Image;
34 ///////////////////////////////////////////////////////////////////////////////
36 // BackForwardMenuModel
38 // Interface for the showing of the dropdown menu for the Back/Forward buttons.
39 // Actual implementations are platform-specific.
40 ///////////////////////////////////////////////////////////////////////////////
41 class BackForwardMenuModel : public ui::MenuModel {
42 public:
43 // These are IDs used to identify individual UI elements within the
44 // browser window using View::GetViewByID.
45 enum ModelType {
46 FORWARD_MENU = 1,
47 BACKWARD_MENU = 2
50 BackForwardMenuModel(Browser* browser, ModelType model_type);
51 ~BackForwardMenuModel() override;
53 // MenuModel implementation.
54 bool HasIcons() const override;
55 // Returns how many items the menu should show, including history items,
56 // chapter-stops, separators and the Show Full History link. This function
57 // uses GetHistoryItemCount() and GetChapterStopCount() internally to figure
58 // out the total number of items to show.
59 int GetItemCount() const override;
60 ItemType GetTypeAt(int index) const override;
61 ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override;
62 int GetCommandIdAt(int index) const override;
63 base::string16 GetLabelAt(int index) const override;
64 bool IsItemDynamicAt(int index) const override;
65 bool GetAcceleratorAt(int index, ui::Accelerator* accelerator) const override;
66 bool IsItemCheckedAt(int index) const override;
67 int GetGroupIdAt(int index) const override;
68 bool GetIconAt(int index, gfx::Image* icon) override;
69 ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override;
70 bool IsEnabledAt(int index) const override;
71 MenuModel* GetSubmenuModelAt(int index) const override;
72 void HighlightChangedTo(int index) override;
73 void ActivatedAt(int index) override;
74 void ActivatedAt(int index, int event_flags) override;
75 void MenuWillShow() override;
77 // Is the item at |index| a separator?
78 bool IsSeparator(int index) const;
80 // Set the delegate for triggering OnIconChanged.
81 void SetMenuModelDelegate(
82 ui::MenuModelDelegate* menu_model_delegate) override;
83 ui::MenuModelDelegate* GetMenuModelDelegate() const override;
85 protected:
86 ui::MenuModelDelegate* menu_model_delegate() { return menu_model_delegate_; }
88 private:
89 friend class BackFwdMenuModelTest;
90 FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, BasicCase);
91 FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, MaxItemsTest);
92 FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, ChapterStops);
93 FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, EscapeLabel);
94 FRIEND_TEST_ALL_PREFIXES(BackFwdMenuModelTest, FaviconLoadTest);
96 // Requests a favicon from the FaviconService. Called by GetIconAt if the
97 // NavigationEntry has an invalid favicon.
98 void FetchFavicon(content::NavigationEntry* entry);
100 // Callback from the favicon service.
101 void OnFavIconDataAvailable(
102 int navigation_entry_unique_id,
103 const favicon_base::FaviconImageResult& image_result);
105 // Allows the unit test to use its own dummy tab contents.
106 void set_test_web_contents(content::WebContents* test_web_contents) {
107 test_web_contents_ = test_web_contents;
110 // Returns how many history items the menu should show. For example, if the
111 // navigation controller of the current tab has a current entry index of 5 and
112 // forward_direction_ is false (we are the back button delegate) then this
113 // function will return 5 (representing 0-4). If forward_direction_ is
114 // true (we are the forward button delegate), then this function will return
115 // the number of entries after 5. Note, though, that in either case it will
116 // not report more than kMaxHistoryItems. The number returned also does not
117 // include the separator line after the history items (nor the separator for
118 // the "Show Full History" link).
119 int GetHistoryItemCount() const;
121 // Returns how many chapter-stop items the menu should show. For the
122 // definition of a chapter-stop, see GetIndexOfNextChapterStop(). The number
123 // returned does not include the separator lines before and after the
124 // chapter-stops.
125 int GetChapterStopCount(int history_items) const;
127 // Finds the next chapter-stop in the NavigationEntryList starting from
128 // the index specified in |start_from| and continuing in the direction
129 // specified (|forward|) until either a chapter-stop is found or we reach the
130 // end, in which case -1 is returned. If |start_from| is out of bounds, -1
131 // will also be returned. A chapter-stop is defined as the last page the user
132 // browsed to within the same domain. For example, if the user's homepage is
133 // Google and she navigates to Google pages G1, G2 and G3 before heading over
134 // to WikiPedia for pages W1 and W2 and then back to Google for pages G4 and
135 // G5 then G3, W2 and G5 are considered chapter-stops. The return value from
136 // this function is an index into the NavigationEntryList vector.
137 int GetIndexOfNextChapterStop(int start_from, bool forward) const;
139 // Finds a given chapter-stop starting at the currently active entry in the
140 // NavigationEntryList vector advancing first forward or backward by |offset|
141 // (depending on the direction specified in parameter |forward|). It also
142 // allows you to skip chapter-stops by specifying a positive value for |skip|.
143 // Example: FindChapterStop(5, false, 3) starts with the currently active
144 // index, subtracts 5 from it and then finds the fourth chapter-stop before
145 // that index (skipping the first 3 it finds).
146 // Example: FindChapterStop(0, true, 0) is functionally equivalent to
147 // calling GetIndexOfNextChapterStop(GetCurrentEntryIndex(), true).
149 // NOTE: Both |offset| and |skip| must be non-negative. The return value from
150 // this function is an index into the NavigationEntryList vector. If |offset|
151 // is out of bounds or if we skip too far (run out of chapter-stops) this
152 // function returns -1.
153 int FindChapterStop(int offset, bool forward, int skip) const;
155 // How many items (max) to show in the back/forward history menu dropdown.
156 static const int kMaxHistoryItems;
158 // How many chapter-stops (max) to show in the back/forward dropdown list.
159 static const int kMaxChapterStops;
161 // Takes a menu item index as passed in through one of the menu delegate
162 // functions and converts it into an index into the NavigationEntryList
163 // vector. |index| can point to a separator, or the
164 // "Show Full History" link in which case this function returns -1.
165 int MenuIndexToNavEntryIndex(int index) const;
167 // Does the item have a command associated with it?
168 bool ItemHasCommand(int index) const;
170 // Returns true if there is an icon for this menu item.
171 bool ItemHasIcon(int index) const;
173 // Allow the unit test to use the "Show Full History" label.
174 base::string16 GetShowFullHistoryLabel() const;
176 // Looks up a NavigationEntry by menu id.
177 content::NavigationEntry* GetNavigationEntry(int index) const;
179 // Retrieves the WebContents pointer to use, which is either the one that
180 // the unit test sets (using set_test_web_contents) or the one from
181 // the browser window.
182 content::WebContents* GetWebContents() const;
184 // Build a string version of a user action on this menu, used as an
185 // identifier for logging user behavior.
186 // E.g. BuildActionName("Click", 2) returns "BackMenu_Click2".
187 // An index of -1 means no index.
188 std::string BuildActionName(const std::string& name, int index) const;
190 Browser* browser_;
192 // The unit tests will provide their own WebContents to use.
193 content::WebContents* test_web_contents_;
195 // Represents whether this is the delegate for the forward button or the
196 // back button.
197 ModelType model_type_;
199 // Keeps track of which favicons have already been requested from the history
200 // to prevent duplicate requests, identified by
201 // NavigationEntry->GetUniqueID().
202 std::set<int> requested_favicons_;
204 // Used for loading favicons.
205 base::CancelableTaskTracker cancelable_task_tracker_;
207 // Used for receiving notifications when an icon is changed.
208 ui::MenuModelDelegate* menu_model_delegate_;
210 DISALLOW_COPY_AND_ASSIGN(BackForwardMenuModel);
213 #endif // CHROME_BROWSER_UI_TOOLBAR_BACK_FORWARD_MENU_MODEL_H_