Allow only one bookmark to be added for multiple fast starring
[chromium-blink-merge.git] / components / ui / zoom / zoom_controller.h
blobf317b406c51d7ce5f5ca340cffe7890f9daf89af
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 COMPONENTS_UI_ZOOM_ZOOM_CONTROLLER_H_
6 #define COMPONENTS_UI_ZOOM_ZOOM_CONTROLLER_H_
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/observer_list.h"
14 #include "base/prefs/pref_member.h"
15 #include "content/public/browser/host_zoom_map.h"
16 #include "content/public/browser/web_contents_observer.h"
17 #include "content/public/browser/web_contents_user_data.h"
19 class ZoomControllerTest;
21 namespace content {
22 class WebContents;
25 namespace ui_zoom {
26 class ZoomObserver;
28 class ZoomRequestClient : public base::RefCounted<ZoomRequestClient> {
29 public:
30 ZoomRequestClient() {}
32 protected:
33 virtual ~ZoomRequestClient() {}
35 private:
36 friend class base::RefCounted<ZoomRequestClient>;
38 DISALLOW_COPY_AND_ASSIGN(ZoomRequestClient);
41 // Per-tab class to manage zoom changes and the Omnibox zoom icon.
42 class ZoomController : public content::WebContentsObserver,
43 public content::WebContentsUserData<ZoomController> {
44 public:
45 // Defines how zoom changes are handled.
46 enum ZoomMode {
47 // Results in default zoom behavior, i.e. zoom changes are handled
48 // automatically and on a per-origin basis, meaning that other tabs
49 // navigated to the same origin will also zoom.
50 ZOOM_MODE_DEFAULT,
51 // Results in zoom changes being handled automatically, but on a per-tab
52 // basis. Tabs in this zoom mode will not be affected by zoom changes in
53 // other tabs, and vice versa.
54 ZOOM_MODE_ISOLATED,
55 // Overrides the automatic handling of zoom changes. The |onZoomChange|
56 // event will still be dispatched, but the page will not actually be zoomed.
57 // These zoom changes can be handled manually by listening for the
58 // |onZoomChange| event. Zooming in this mode is also on a per-tab basis.
59 ZOOM_MODE_MANUAL,
60 // Disables all zooming in this tab. The tab will revert to the default
61 // zoom level, and all attempted zoom changes will be ignored.
62 ZOOM_MODE_DISABLED,
65 enum RelativeZoom {
66 ZOOM_BELOW_DEFAULT_ZOOM,
67 ZOOM_AT_DEFAULT_ZOOM,
68 ZOOM_ABOVE_DEFAULT_ZOOM
71 struct ZoomChangedEventData {
72 ZoomChangedEventData(content::WebContents* web_contents,
73 double old_zoom_level,
74 double new_zoom_level,
75 ZoomController::ZoomMode zoom_mode,
76 bool can_show_bubble)
77 : web_contents(web_contents),
78 old_zoom_level(old_zoom_level),
79 new_zoom_level(new_zoom_level),
80 zoom_mode(zoom_mode),
81 can_show_bubble(can_show_bubble) {}
82 content::WebContents* web_contents;
83 double old_zoom_level;
84 double new_zoom_level;
85 ZoomController::ZoomMode zoom_mode;
86 bool can_show_bubble;
89 // Since it's possible for a WebContents to not have a ZoomController, provide
90 // a simple, safe and reliable method to find the current zoom level for a
91 // given WebContents*.
92 static double GetZoomLevelForWebContents(
93 const content::WebContents* web_contents);
95 ~ZoomController() override;
97 ZoomMode zoom_mode() const { return zoom_mode_; }
99 // Convenience method to get default zoom level. Implemented here for
100 // inlining.
101 double GetDefaultZoomLevel() const {
102 return content::HostZoomMap::GetForWebContents(web_contents())
103 ->GetDefaultZoomLevel();
106 // Convenience method to quickly check if the tab's at default zoom.
107 bool IsAtDefaultZoom() const;
109 // Returns which image should be loaded for the current zoom level.
110 RelativeZoom GetZoomRelativeToDefault() const;
112 const ZoomRequestClient* last_client() const { return last_client_.get(); }
114 void AddObserver(ZoomObserver* observer);
115 void RemoveObserver(ZoomObserver* observer);
117 // Used to set whether the zoom notification bubble can be shown when the
118 // zoom level is changed for this controller. Default behavior is to show
119 // the bubble.
120 void SetShowsNotificationBubble(bool can_show_bubble) {
121 can_show_bubble_ = can_show_bubble;
124 // Gets the current zoom level by querying HostZoomMap (if not in manual zoom
125 // mode) or from the ZoomController local value otherwise.
126 double GetZoomLevel() const;
127 // Calls GetZoomLevel() then converts the returned value to a percentage
128 // zoom factor.
129 // Virtual for testing.
130 virtual int GetZoomPercent() const;
132 // Sets the zoom level through HostZoomMap.
133 // Returns true on success.
134 bool SetZoomLevel(double zoom_level);
136 // Sets the zoom level via HostZoomMap (or stores it locally if in manual zoom
137 // mode), and attributes the zoom to |client|. Returns true on success.
138 bool SetZoomLevelByClient(
139 double zoom_level,
140 const scoped_refptr<const ZoomRequestClient>& client);
142 // Sets the zoom mode, which defines zoom behavior (see enum ZoomMode).
143 void SetZoomMode(ZoomMode zoom_mode);
145 // Set and query whether or not the page scale factor is one.
146 void SetPageScaleFactorIsOneForTesting(bool is_one);
147 bool PageScaleFactorIsOne() const;
149 // content::WebContentsObserver overrides:
150 void DidNavigateMainFrame(
151 const content::LoadCommittedDetails& details,
152 const content::FrameNavigateParams& params) override;
153 void WebContentsDestroyed() override;
154 void RenderFrameHostChanged(content::RenderFrameHost* old_host,
155 content::RenderFrameHost* new_host) override;
157 protected:
158 // Protected for testing.
159 explicit ZoomController(content::WebContents* web_contents);
161 private:
162 friend class content::WebContentsUserData<ZoomController>;
163 friend class ::ZoomControllerTest;
165 void ResetZoomModeOnNavigationIfNeeded(const GURL& url);
166 void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change);
168 // Updates the zoom icon and zoom percentage based on current values and
169 // notifies the observer if changes have occurred. |host| may be empty,
170 // meaning the change should apply to ~all sites. If it is not empty, the
171 // change only affects sites with the given host.
172 void UpdateState(const std::string& host);
174 // True if changes to zoom level can trigger the zoom notification bubble.
175 bool can_show_bubble_;
177 // The current zoom mode.
178 ZoomMode zoom_mode_;
180 // Current zoom level.
181 double zoom_level_;
183 scoped_ptr<ZoomChangedEventData> event_data_;
185 // Keeps track of the extension (if any) that initiated the last zoom change
186 // that took effect.
187 scoped_refptr<const ZoomRequestClient> last_client_;
189 // Observer receiving notifications on state changes.
190 base::ObserverList<ZoomObserver> observers_;
192 content::BrowserContext* browser_context_;
193 // Keep track of the HostZoomMap we're currently subscribed to.
194 content::HostZoomMap* host_zoom_map_;
196 scoped_ptr<content::HostZoomMap::Subscription> zoom_subscription_;
198 DISALLOW_COPY_AND_ASSIGN(ZoomController);
201 } // namespace ui_zoom
203 #endif // COMPONENTS_UI_ZOOM_ZOOM_CONTROLLER_H_