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 #include "chrome/browser/ui/zoom/zoom_controller.h" | 5 #include "components/ui/zoom/zoom_controller.h" |
6 | 6 |
7 #include "chrome/browser/ui/sad_tab.h" | 7 #include "components/ui/zoom/zoom_event_manager.h" |
8 #include "chrome/browser/ui/zoom/zoom_event_manager.h" | 8 #include "components/ui/zoom/zoom_observer.h" |
9 #include "chrome/browser/ui/zoom/zoom_observer.h" | |
10 #include "content/public/browser/host_zoom_map.h" | 9 #include "content/public/browser/host_zoom_map.h" |
11 #include "content/public/browser/navigation_details.h" | 10 #include "content/public/browser/navigation_details.h" |
12 #include "content/public/browser/navigation_entry.h" | 11 #include "content/public/browser/navigation_entry.h" |
13 #include "content/public/browser/render_process_host.h" | 12 #include "content/public/browser/render_process_host.h" |
14 #include "content/public/browser/render_view_host.h" | 13 #include "content/public/browser/render_view_host.h" |
15 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
16 #include "content/public/common/page_type.h" | 15 #include "content/public/common/page_type.h" |
17 #include "content/public/common/page_zoom.h" | 16 #include "content/public/common/page_zoom.h" |
18 #include "extensions/common/extension.h" | |
19 #include "grit/theme_resources.h" | |
20 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" |
21 | 18 |
22 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ZoomController); | 19 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ui_zoom::ZoomController); |
| 20 |
| 21 namespace ui_zoom { |
23 | 22 |
24 ZoomController::ZoomController(content::WebContents* web_contents) | 23 ZoomController::ZoomController(content::WebContents* web_contents) |
25 : content::WebContentsObserver(web_contents), | 24 : content::WebContentsObserver(web_contents), |
26 can_show_bubble_(true), | 25 can_show_bubble_(true), |
27 zoom_mode_(ZOOM_MODE_DEFAULT), | 26 zoom_mode_(ZOOM_MODE_DEFAULT), |
28 zoom_level_(1.0), | 27 zoom_level_(1.0), |
29 browser_context_(web_contents->GetBrowserContext()) { | 28 browser_context_(web_contents->GetBrowserContext()) { |
30 content::HostZoomMap* host_zoom_map = | 29 content::HostZoomMap* host_zoom_map = |
31 content::HostZoomMap::GetForWebContents(web_contents); | 30 content::HostZoomMap::GetForWebContents(web_contents); |
32 zoom_level_ = host_zoom_map->GetDefaultZoomLevel(); | 31 zoom_level_ = host_zoom_map->GetDefaultZoomLevel(); |
33 | 32 |
34 zoom_subscription_ = host_zoom_map->AddZoomLevelChangedCallback( | 33 zoom_subscription_ = host_zoom_map->AddZoomLevelChangedCallback( |
35 base::Bind(&ZoomController::OnZoomLevelChanged, base::Unretained(this))); | 34 base::Bind(&ZoomController::OnZoomLevelChanged, base::Unretained(this))); |
36 | 35 |
37 UpdateState(std::string()); | 36 UpdateState(std::string()); |
38 } | 37 } |
39 | 38 |
40 ZoomController::~ZoomController() {} | 39 ZoomController::~ZoomController() { |
| 40 } |
41 | 41 |
42 bool ZoomController::IsAtDefaultZoom() const { | 42 bool ZoomController::IsAtDefaultZoom() const { |
43 return content::ZoomValuesEqual(GetZoomLevel(), GetDefaultZoomLevel()); | 43 return content::ZoomValuesEqual(GetZoomLevel(), GetDefaultZoomLevel()); |
44 } | 44 } |
45 | 45 |
46 int ZoomController::GetResourceForZoomLevel() const { | 46 ZoomController::RelativeZoom ZoomController::GetZoomRelativeToDefault() const { |
47 if (IsAtDefaultZoom()) | 47 double current_level = GetZoomLevel(); |
48 return IDR_ZOOM_NORMAL; | 48 double default_level = GetDefaultZoomLevel(); |
49 return GetZoomLevel() > GetDefaultZoomLevel() ? IDR_ZOOM_PLUS | 49 if (content::ZoomValuesEqual(current_level, default_level)) |
50 : IDR_ZOOM_MINUS; | 50 return ZOOM_AT_DEFAULT_ZOOM; |
| 51 else if (current_level > default_level) |
| 52 return ZOOM_ABOVE_DEFAULT_ZOOM; |
| 53 return ZOOM_BELOW_DEFAULT_ZOOM; |
51 } | 54 } |
52 | 55 |
53 void ZoomController::AddObserver(ZoomObserver* observer) { | 56 void ZoomController::AddObserver(ZoomObserver* observer) { |
54 observers_.AddObserver(observer); | 57 observers_.AddObserver(observer); |
55 } | 58 } |
56 | 59 |
57 void ZoomController::RemoveObserver(ZoomObserver* observer) { | 60 void ZoomController::RemoveObserver(ZoomObserver* observer) { |
58 observers_.RemoveObserver(observer); | 61 observers_.RemoveObserver(observer); |
59 } | 62 } |
60 | 63 |
61 double ZoomController::GetZoomLevel() const { | 64 double ZoomController::GetZoomLevel() const { |
62 return zoom_mode_ == ZOOM_MODE_MANUAL ? | 65 return zoom_mode_ == ZOOM_MODE_MANUAL |
63 zoom_level_: | 66 ? zoom_level_ |
64 content::HostZoomMap::GetZoomLevel(web_contents()); | 67 : content::HostZoomMap::GetZoomLevel(web_contents()); |
65 } | 68 } |
66 | 69 |
67 int ZoomController::GetZoomPercent() const { | 70 int ZoomController::GetZoomPercent() const { |
68 double zoom_factor = content::ZoomLevelToZoomFactor(GetZoomLevel()); | 71 double zoom_factor = content::ZoomLevelToZoomFactor(GetZoomLevel()); |
69 // Round double for return. | 72 // Round double for return. |
70 return static_cast<int>(zoom_factor * 100 + 0.5); | 73 return static_cast<int>(zoom_factor * 100 + 0.5); |
71 } | 74 } |
72 | 75 |
73 bool ZoomController::SetZoomLevel(double zoom_level) { | 76 bool ZoomController::SetZoomLevel(double zoom_level) { |
74 // An extension did not initiate this zoom change. | 77 // A client did not initiate this zoom change. |
75 return SetZoomLevelByExtension(zoom_level, NULL); | 78 return SetZoomLevelByClient(zoom_level, NULL); |
76 } | 79 } |
77 | 80 |
78 bool ZoomController::SetZoomLevelByExtension( | 81 bool ZoomController::SetZoomLevelByClient( |
79 double zoom_level, | 82 double zoom_level, |
80 const scoped_refptr<const extensions::Extension>& extension) { | 83 const scoped_refptr<const ZoomRequestClient>& client) { |
81 content::NavigationEntry* entry = | 84 content::NavigationEntry* entry = |
82 web_contents()->GetController().GetLastCommittedEntry(); | 85 web_contents()->GetController().GetLastCommittedEntry(); |
83 // Cannot zoom in disabled mode. Also, don't allow changing zoom level on | 86 // Cannot zoom in disabled mode. Also, don't allow changing zoom level on |
84 // a crashed tab, an error page or an interstitial page. | 87 // a crashed tab, an error page or an interstitial page. |
85 if (zoom_mode_ == ZOOM_MODE_DISABLED || | 88 if (zoom_mode_ == ZOOM_MODE_DISABLED || |
86 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) | 89 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) |
87 return false; | 90 return false; |
88 | 91 |
89 // Store extension data so that |extension| can be attributed when the zoom | 92 // Store client data so the |client| can be attributed when the zoom |
90 // change completes. We expect that by the time this function returns that | 93 // change completes. We expect that by the time this function returns that |
91 // any observers that require this information will have requested it. | 94 // any observers that require this information will have requested it. |
92 last_extension_ = extension; | 95 last_client_ = client; |
93 | 96 |
94 // Do not actually rescale the page in manual mode. | 97 // Do not actually rescale the page in manual mode. |
95 if (zoom_mode_ == ZOOM_MODE_MANUAL) { | 98 if (zoom_mode_ == ZOOM_MODE_MANUAL) { |
96 double old_zoom_level = zoom_level_; | 99 double old_zoom_level = zoom_level_; |
97 zoom_level_ = zoom_level; | 100 zoom_level_ = zoom_level; |
98 | 101 |
99 // TODO(wjmaclean) Do we care about filling in host/scheme here? | 102 // TODO(wjmaclean) Do we care about filling in host/scheme here? |
100 content::HostZoomMap::ZoomLevelChange change; | 103 content::HostZoomMap::ZoomLevelChange change; |
101 change.mode = content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM; | 104 change.mode = content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM; |
102 change.zoom_level = zoom_level; | 105 change.zoom_level = zoom_level; |
103 ZoomEventManager::GetForBrowserContext(browser_context_)-> | 106 ZoomEventManager::GetForBrowserContext(browser_context_) |
104 OnZoomLevelChanged(change); | 107 ->OnZoomLevelChanged(change); |
105 | 108 |
106 ZoomChangedEventData zoom_change_data(web_contents(), | 109 ZoomChangedEventData zoom_change_data(web_contents(), old_zoom_level, |
107 old_zoom_level, | 110 zoom_level_, zoom_mode_, |
108 zoom_level_, | |
109 zoom_mode_, | |
110 false /* can_show_bubble */); | 111 false /* can_show_bubble */); |
111 FOR_EACH_OBSERVER( | 112 FOR_EACH_OBSERVER(ZoomObserver, observers_, |
112 ZoomObserver, observers_, OnZoomChanged(zoom_change_data)); | 113 OnZoomChanged(zoom_change_data)); |
113 | 114 |
114 last_extension_ = NULL; | 115 last_client_ = NULL; |
115 return true; | 116 return true; |
116 } | 117 } |
117 | 118 |
118 content::HostZoomMap* zoom_map = | 119 content::HostZoomMap* zoom_map = |
119 content::HostZoomMap::GetForWebContents(web_contents()); | 120 content::HostZoomMap::GetForWebContents(web_contents()); |
120 DCHECK(zoom_map); | 121 DCHECK(zoom_map); |
121 DCHECK(!event_data_); | 122 DCHECK(!event_data_); |
122 event_data_.reset(new ZoomChangedEventData(web_contents(), | 123 event_data_.reset(new ZoomChangedEventData(web_contents(), GetZoomLevel(), |
123 GetZoomLevel(), | 124 zoom_level, zoom_mode_, |
124 zoom_level, | |
125 zoom_mode_, | |
126 false /* can_show_bubble */)); | 125 false /* can_show_bubble */)); |
127 int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); | 126 int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); |
128 int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); | 127 int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); |
129 if (zoom_mode_ == ZOOM_MODE_ISOLATED || | 128 if (zoom_mode_ == ZOOM_MODE_ISOLATED || |
130 zoom_map->UsesTemporaryZoomLevel(render_process_id, render_view_id)) { | 129 zoom_map->UsesTemporaryZoomLevel(render_process_id, render_view_id)) { |
131 zoom_map->SetTemporaryZoomLevel( | 130 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, |
132 render_process_id, render_view_id, zoom_level); | 131 zoom_level); |
133 } else { | 132 } else { |
134 if (!entry) { | 133 if (!entry) { |
135 last_extension_ = NULL; | 134 last_client_ = NULL; |
136 return false; | 135 return false; |
137 } | 136 } |
138 std::string host = | 137 std::string host = |
139 net::GetHostOrSpecFromURL(content::HostZoomMap::GetURLFromEntry(entry)); | 138 net::GetHostOrSpecFromURL(content::HostZoomMap::GetURLFromEntry(entry)); |
140 zoom_map->SetZoomLevelForHost(host, zoom_level); | 139 zoom_map->SetZoomLevelForHost(host, zoom_level); |
141 } | 140 } |
142 | 141 |
143 DCHECK(!event_data_); | 142 DCHECK(!event_data_); |
144 last_extension_ = NULL; | 143 last_client_ = NULL; |
145 return true; | 144 return true; |
146 } | 145 } |
147 | 146 |
148 void ZoomController::SetZoomMode(ZoomMode new_mode) { | 147 void ZoomController::SetZoomMode(ZoomMode new_mode) { |
149 if (new_mode == zoom_mode_) | 148 if (new_mode == zoom_mode_) |
150 return; | 149 return; |
151 | 150 |
152 content::HostZoomMap* zoom_map = | 151 content::HostZoomMap* zoom_map = |
153 content::HostZoomMap::GetForWebContents(web_contents()); | 152 content::HostZoomMap::GetForWebContents(web_contents()); |
154 DCHECK(zoom_map); | 153 DCHECK(zoom_map); |
155 int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); | 154 int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); |
156 int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); | 155 int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); |
157 double original_zoom_level = GetZoomLevel(); | 156 double original_zoom_level = GetZoomLevel(); |
158 | 157 |
159 DCHECK(!event_data_); | 158 DCHECK(!event_data_); |
160 event_data_.reset(new ZoomChangedEventData(web_contents(), | 159 event_data_.reset(new ZoomChangedEventData( |
161 original_zoom_level, | 160 web_contents(), original_zoom_level, original_zoom_level, new_mode, |
162 original_zoom_level, | 161 new_mode != ZOOM_MODE_DEFAULT)); |
163 new_mode, | |
164 new_mode != ZOOM_MODE_DEFAULT)); | |
165 | 162 |
166 switch (new_mode) { | 163 switch (new_mode) { |
167 case ZOOM_MODE_DEFAULT: { | 164 case ZOOM_MODE_DEFAULT: { |
168 content::NavigationEntry* entry = | 165 content::NavigationEntry* entry = |
169 web_contents()->GetController().GetLastCommittedEntry(); | 166 web_contents()->GetController().GetLastCommittedEntry(); |
170 | 167 |
171 if (entry) { | 168 if (entry) { |
172 GURL url = content::HostZoomMap::GetURLFromEntry(entry); | 169 GURL url = content::HostZoomMap::GetURLFromEntry(entry); |
173 std::string host = net::GetHostOrSpecFromURL(url); | 170 std::string host = net::GetHostOrSpecFromURL(url); |
174 | 171 |
175 if (zoom_map->HasZoomLevel(url.scheme(), host)) { | 172 if (zoom_map->HasZoomLevel(url.scheme(), host)) { |
176 // If there are other tabs with the same origin, then set this tab's | 173 // If there are other tabs with the same origin, then set this tab's |
177 // zoom level to match theirs. The temporary zoom level will be | 174 // zoom level to match theirs. The temporary zoom level will be |
178 // cleared below, but this call will make sure this tab re-draws at | 175 // cleared below, but this call will make sure this tab re-draws at |
179 // the correct zoom level. | 176 // the correct zoom level. |
180 double origin_zoom_level = | 177 double origin_zoom_level = |
181 zoom_map->GetZoomLevelForHostAndScheme(url.scheme(), host); | 178 zoom_map->GetZoomLevelForHostAndScheme(url.scheme(), host); |
182 event_data_->new_zoom_level = origin_zoom_level; | 179 event_data_->new_zoom_level = origin_zoom_level; |
183 zoom_map->SetTemporaryZoomLevel( | 180 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, |
184 render_process_id, render_view_id, origin_zoom_level); | 181 origin_zoom_level); |
185 } else { | 182 } else { |
186 // The host will need a level prior to removing the temporary level. | 183 // The host will need a level prior to removing the temporary level. |
187 // We don't want the zoom level to change just because we entered | 184 // We don't want the zoom level to change just because we entered |
188 // default mode. | 185 // default mode. |
189 zoom_map->SetZoomLevelForHost(host, original_zoom_level); | 186 zoom_map->SetZoomLevelForHost(host, original_zoom_level); |
190 } | 187 } |
191 } | 188 } |
192 // Remove per-tab zoom data for this tab. No event callback expected. | 189 // Remove per-tab zoom data for this tab. No event callback expected. |
193 zoom_map->ClearTemporaryZoomLevel(render_process_id, render_view_id); | 190 zoom_map->ClearTemporaryZoomLevel(render_process_id, render_view_id); |
194 break; | 191 break; |
195 } | 192 } |
196 case ZOOM_MODE_ISOLATED: { | 193 case ZOOM_MODE_ISOLATED: { |
197 // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the | 194 // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the |
198 // page needs an initial isolated zoom back to the same level it was at | 195 // page needs an initial isolated zoom back to the same level it was at |
199 // in the other mode. | 196 // in the other mode. |
200 if (zoom_mode_ != ZOOM_MODE_DISABLED) { | 197 if (zoom_mode_ != ZOOM_MODE_DISABLED) { |
201 zoom_map->SetTemporaryZoomLevel( | 198 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, |
202 render_process_id, render_view_id, original_zoom_level); | 199 original_zoom_level); |
203 } else { | 200 } else { |
204 // When we don't call any HostZoomMap set functions, we send the event | 201 // When we don't call any HostZoomMap set functions, we send the event |
205 // manually. | 202 // manually. |
206 FOR_EACH_OBSERVER( | 203 FOR_EACH_OBSERVER(ZoomObserver, observers_, |
207 ZoomObserver, observers_, OnZoomChanged(*event_data_)); | 204 OnZoomChanged(*event_data_)); |
208 event_data_.reset(); | 205 event_data_.reset(); |
209 } | 206 } |
210 break; | 207 break; |
211 } | 208 } |
212 case ZOOM_MODE_MANUAL: { | 209 case ZOOM_MODE_MANUAL: { |
213 // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the | 210 // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the |
214 // page needs to be resized to the default zoom. While in manual mode, | 211 // page needs to be resized to the default zoom. While in manual mode, |
215 // the zoom level is handled independently. | 212 // the zoom level is handled independently. |
216 if (zoom_mode_ != ZOOM_MODE_DISABLED) { | 213 if (zoom_mode_ != ZOOM_MODE_DISABLED) { |
217 zoom_map->SetTemporaryZoomLevel( | 214 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, |
218 render_process_id, render_view_id, GetDefaultZoomLevel()); | 215 GetDefaultZoomLevel()); |
219 zoom_level_ = original_zoom_level; | 216 zoom_level_ = original_zoom_level; |
220 } else { | 217 } else { |
221 // When we don't call any HostZoomMap set functions, we send the event | 218 // When we don't call any HostZoomMap set functions, we send the event |
222 // manually. | 219 // manually. |
223 FOR_EACH_OBSERVER( | 220 FOR_EACH_OBSERVER(ZoomObserver, observers_, |
224 ZoomObserver, observers_, OnZoomChanged(*event_data_)); | 221 OnZoomChanged(*event_data_)); |
225 event_data_.reset(); | 222 event_data_.reset(); |
226 } | 223 } |
227 break; | 224 break; |
228 } | 225 } |
229 case ZOOM_MODE_DISABLED: { | 226 case ZOOM_MODE_DISABLED: { |
230 // The page needs to be zoomed back to default before disabling the zoom | 227 // The page needs to be zoomed back to default before disabling the zoom |
231 zoom_map->SetTemporaryZoomLevel( | 228 zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id, |
232 render_process_id, render_view_id, GetDefaultZoomLevel()); | 229 GetDefaultZoomLevel()); |
233 break; | 230 break; |
234 } | 231 } |
235 } | 232 } |
236 // Any event data we've stored should have been consumed by this point. | 233 // Any event data we've stored should have been consumed by this point. |
237 DCHECK(!event_data_); | 234 DCHECK(!event_data_); |
238 | 235 |
239 zoom_mode_ = new_mode; | 236 zoom_mode_ = new_mode; |
240 } | 237 } |
241 | 238 |
242 void ZoomController::DidNavigateMainFrame( | 239 void ZoomController::DidNavigateMainFrame( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // The zoom bubble should not be shown for zoom changes where the host is | 275 // The zoom bubble should not be shown for zoom changes where the host is |
279 // empty. | 276 // empty. |
280 bool can_show_bubble = can_show_bubble_ && !host.empty(); | 277 bool can_show_bubble = can_show_bubble_ && !host.empty(); |
281 | 278 |
282 if (event_data_) { | 279 if (event_data_) { |
283 // For state changes initiated within the ZoomController, information about | 280 // For state changes initiated within the ZoomController, information about |
284 // the change should be sent. | 281 // the change should be sent. |
285 ZoomChangedEventData zoom_change_data = *event_data_; | 282 ZoomChangedEventData zoom_change_data = *event_data_; |
286 event_data_.reset(); | 283 event_data_.reset(); |
287 zoom_change_data.can_show_bubble = can_show_bubble; | 284 zoom_change_data.can_show_bubble = can_show_bubble; |
288 FOR_EACH_OBSERVER( | 285 FOR_EACH_OBSERVER(ZoomObserver, observers_, |
289 ZoomObserver, observers_, OnZoomChanged(zoom_change_data)); | 286 OnZoomChanged(zoom_change_data)); |
290 } else { | 287 } else { |
291 // TODO(wjmaclean) Should we consider having HostZoomMap send both old and | 288 // TODO(wjmaclean) Should we consider having HostZoomMap send both old and |
292 // new zoom levels here? | 289 // new zoom levels here? |
293 double zoom_level = GetZoomLevel(); | 290 double zoom_level = GetZoomLevel(); |
294 ZoomChangedEventData zoom_change_data( | 291 ZoomChangedEventData zoom_change_data( |
295 web_contents(), zoom_level, zoom_level, zoom_mode_, can_show_bubble); | 292 web_contents(), zoom_level, zoom_level, zoom_mode_, can_show_bubble); |
296 FOR_EACH_OBSERVER( | 293 FOR_EACH_OBSERVER(ZoomObserver, observers_, |
297 ZoomObserver, observers_, OnZoomChanged(zoom_change_data)); | 294 OnZoomChanged(zoom_change_data)); |
298 } | 295 } |
299 } | 296 } |
| 297 |
| 298 } // namespace ui_zoom |
OLD | NEW |