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