Index: content/browser/web_contents/web_contents_impl.cc |
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc |
index a19fcd9921d563c334e361a83b4689aad1dc658e..0ce208b2acc8de1a9bbb535ef65c590ed518786a 100644 |
--- a/content/browser/web_contents/web_contents_impl.cc |
+++ b/content/browser/web_contents/web_contents_impl.cc |
@@ -338,7 +338,9 @@ WebContentsImpl::WebContentsImpl( |
color_chooser_identifier_(0), |
render_view_message_source_(NULL), |
fullscreen_widget_routing_id_(MSG_ROUTING_NONE), |
- is_subframe_(false) { |
+ is_subframe_(false), |
+ current_zoom_mode_(kZoomModeDefault), |
+ current_zoom_id_(1) { |
for (size_t i = 0; i < g_created_callbacks.Get().size(); i++) |
g_created_callbacks.Get().at(i).Run(this); |
frame_tree_.SetFrameRemoveListener( |
@@ -1986,7 +1988,14 @@ bool WebContentsImpl::GetClosedByUserGesture() const { |
return closed_by_user_gesture_; |
} |
+content::ZoomMode WebContentsImpl::GetZoomMode() const { |
+ return current_zoom_mode_; |
+} |
+ |
double WebContentsImpl::GetZoomLevel() const { |
+ if (current_zoom_mode_ == kZoomModeDisabled) |
+ return 0; |
+ |
HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>( |
HostZoomMap::GetForBrowserContext(GetBrowserContext())); |
if (!zoom_map) |
@@ -2086,10 +2095,86 @@ bool WebContentsImpl::IsSubframe() const { |
} |
void WebContentsImpl::SetZoomLevel(double level) { |
- Send(new ViewMsg_SetZoomLevel(GetRoutingID(), level)); |
+ if (current_zoom_mode_ == kZoomModeDisabled) |
+ return; |
+ |
+ Send(new ViewMsg_SetZoomLevel(GetRoutingID(), current_zoom_id_++, level, |
+ current_zoom_mode_)); |
BrowserPluginEmbedder* embedder = GetBrowserPluginEmbedder(); |
if (embedder) |
embedder->SetZoomLevel(level); |
+ |
+ // Notify observers about the initiated zoom change. |
+ FOR_EACH_OBSERVER(WebContentsObserver, observers_, |
+ DidSetZoomLevel(GetZoomLevel(), level, current_zoom_mode_)); |
+} |
+ |
+void WebContentsImpl::SetZoomLevel(double level, |
+ const base::Callback<void(void)>& callback) { |
+ if (current_zoom_mode_ == kZoomModeDisabled) |
+ return; |
+ |
+ // Add the callback to HostZoomMap so that it can be called after the zoom |
+ // change has completed. |
+ HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>( |
+ HostZoomMap::GetForBrowserContext(GetBrowserContext())); |
+ DCHECK(zoom_map); |
+ zoom_map->AddZoomCallback(current_zoom_id_, callback); |
+ SetZoomLevel(level); |
+} |
+ |
+void WebContentsImpl::SetZoomMode(ZoomMode mode) { |
+ if (mode == current_zoom_mode_) |
+ return; |
+ |
+ double original_zoom_level = GetZoomLevel(); |
+ switch (mode) { |
+ case kZoomModeDefault: { |
+ Send(new ViewMsg_SetZoomLevel(GetRoutingID(), 0, original_zoom_level, |
+ kZoomModeDefault)); |
+ // Remove per-tab zoom data for this tab. |
+ HostZoomMapImpl* zoom_map = static_cast<HostZoomMapImpl*>( |
+ HostZoomMap::GetForBrowserContext(GetBrowserContext())); |
+ DCHECK(zoom_map); |
+ int render_process_id = GetRenderProcessHost()->GetID(); |
+ int render_view_id = GetRenderViewHost()->GetRoutingID(); |
+ zoom_map->EraseTemporaryZoomLevel(render_process_id, render_view_id); |
+ break; |
+ } |
+ case kZoomModeIsolated: { |
+ // Unless the zoom mode was |kZoomModeDisabled| before this call, the page |
+ // needs an initial isolated zoom back to the same level it was at in the |
+ // other mode. |
+ if (current_zoom_mode_ != kZoomModeDisabled) { |
+ Send(new ViewMsg_SetZoomLevel(GetRoutingID(), 0, original_zoom_level, |
+ kZoomModeIsolated)); |
+ } |
+ break; |
+ } |
+ case kZoomModeManual: { |
+ // Unless the zoom mode was |kZoomModeDisabled| before this call, the page |
+ // needs to be resized to the default zoom before calling SetZoomLevel() |
+ // so that the page can be resized manually to the same zoom as before. |
+ if (current_zoom_mode_ != kZoomModeDisabled) { |
+ Send(new ViewMsg_SetZoomLevel(GetRoutingID(), 0, 0, kZoomModeIsolated)); |
+ current_zoom_mode_ = mode; |
+ SetZoomLevel(original_zoom_level); |
+ } |
+ break; |
+ } |
+ case kZoomModeDisabled: { |
+ // The page needs to be zoomed back to default before disabling the zoom |
+ // (unless it was just in |kZoomModeManual| mode, in which case this is |
+ // already done). |
+ if (current_zoom_mode_ != kZoomModeManual) { |
+ Send(new ViewMsg_SetZoomLevel(GetRoutingID(), 0, 0, kZoomModeIsolated)); |
+ } |
+ break; |
+ } |
+ } |
+ |
+ current_zoom_mode_ = mode; |
+ temporary_zoom_settings_ = mode != kZoomModeDefault; |
} |
void WebContentsImpl::Find(int request_id, |
@@ -2426,7 +2511,8 @@ void WebContentsImpl::OnUpdateZoomLimits(int minimum_percent, |
bool remember) { |
minimum_zoom_percent_ = minimum_percent; |
maximum_zoom_percent_ = maximum_percent; |
- temporary_zoom_settings_ = !remember; |
+ temporary_zoom_settings_ = !remember || |
+ current_zoom_mode_ != kZoomModeDefault; |
} |
void WebContentsImpl::OnEnumerateDirectory(int request_id, |
@@ -2826,6 +2912,12 @@ void WebContentsImpl::NotifyDisconnected() { |
void WebContentsImpl::NotifyNavigationEntryCommitted( |
const LoadCommittedDetails& load_details) { |
+ // The zoom mode resets on navigation to a different page. |
+ if (load_details.is_navigation_to_different_page()) { |
+ temporary_zoom_settings_ = false; |
+ SetZoomMode(kZoomModeDefault); |
+ } |
+ |
FOR_EACH_OBSERVER( |
WebContentsObserver, observers_, NavigationEntryCommitted(load_details)); |
} |