|
@@ -21,6 +21,8 @@ namespace atom {
|
|
|
WebContentsZoomController::WebContentsZoomController(
|
|
|
content::WebContents* web_contents)
|
|
|
: content::WebContentsObserver(web_contents),
|
|
|
+ zoom_mode_(ZOOM_MODE_DEFAULT),
|
|
|
+ zoom_level_(1.0),
|
|
|
old_process_id_(-1),
|
|
|
old_view_id_(-1),
|
|
|
embedder_zoom_controller_(nullptr) {
|
|
@@ -47,24 +49,44 @@ void WebContentsZoomController::SetEmbedderZoomController(
|
|
|
|
|
|
void WebContentsZoomController::SetZoomLevel(double level) {
|
|
|
if (!web_contents()->GetRenderViewHost()->IsRenderViewLive() ||
|
|
|
- content::ZoomValuesEqual(GetZoomLevel(), level))
|
|
|
+ content::ZoomValuesEqual(GetZoomLevel(), level) ||
|
|
|
+ zoom_mode_ == ZOOM_MODE_DISABLED)
|
|
|
return;
|
|
|
|
|
|
int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
|
|
|
int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID();
|
|
|
- if (host_zoom_map_->UsesTemporaryZoomLevel(render_process_id,
|
|
|
- render_view_id)) {
|
|
|
- host_zoom_map_->ClearTemporaryZoomLevel(render_process_id, render_view_id);
|
|
|
+
|
|
|
+ if (zoom_mode_ == ZOOM_MODE_MANUAL) {
|
|
|
+ zoom_level_ = level;
|
|
|
+
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), level, true);
|
|
|
+
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- content::HostZoomMap::SetZoomLevel(web_contents(), level);
|
|
|
- // Notify observers of zoom level changes.
|
|
|
- for (Observer& observer : observers_)
|
|
|
- observer.OnZoomLevelChanged(web_contents(), level, false);
|
|
|
+ content::HostZoomMap* zoom_map =
|
|
|
+ content::HostZoomMap::GetForWebContents(web_contents());
|
|
|
+ if (zoom_mode_ == ZOOM_MODE_ISOLATED ||
|
|
|
+ zoom_map->UsesTemporaryZoomLevel(render_process_id, render_view_id)) {
|
|
|
+ zoom_map->SetTemporaryZoomLevel(
|
|
|
+ render_process_id, render_view_id, level);
|
|
|
+ // Notify observers of zoom level changes.
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), level, true);
|
|
|
+ } else {
|
|
|
+ content::HostZoomMap::SetZoomLevel(web_contents(), level);
|
|
|
+
|
|
|
+ // Notify observers of zoom level changes.
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), level, false);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
double WebContentsZoomController::GetZoomLevel() {
|
|
|
- return content::HostZoomMap::GetZoomLevel(web_contents());
|
|
|
+ return zoom_mode_ == ZOOM_MODE_MANUAL
|
|
|
+ ? zoom_level_
|
|
|
+ : content::HostZoomMap::GetZoomLevel(web_contents());
|
|
|
}
|
|
|
|
|
|
void WebContentsZoomController::SetDefaultZoomFactor(double factor) {
|
|
@@ -91,6 +113,110 @@ bool WebContentsZoomController::UsesTemporaryZoomLevel() {
|
|
|
render_view_id);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+void WebContentsZoomController::SetZoomMode(ZoomMode new_mode) {
|
|
|
+ if (new_mode == zoom_mode_)
|
|
|
+ return;
|
|
|
+
|
|
|
+ content::HostZoomMap* zoom_map =
|
|
|
+ content::HostZoomMap::GetForWebContents(web_contents());
|
|
|
+ int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
|
|
|
+ int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID();
|
|
|
+ double original_zoom_level = GetZoomLevel();
|
|
|
+
|
|
|
+ switch (new_mode) {
|
|
|
+ case ZOOM_MODE_DEFAULT: {
|
|
|
+ content::NavigationEntry* entry =
|
|
|
+ web_contents()->GetController().GetLastCommittedEntry();
|
|
|
+
|
|
|
+ if (entry) {
|
|
|
+ GURL url = content::HostZoomMap::GetURLFromEntry(entry);
|
|
|
+ std::string host = net::GetHostOrSpecFromURL(url);
|
|
|
+
|
|
|
+ if (zoom_map->HasZoomLevel(url.scheme(), host)) {
|
|
|
+ // If there are other tabs with the same origin, then set this tab's
|
|
|
+ // zoom level to match theirs. The temporary zoom level will be
|
|
|
+ // cleared below, but this call will make sure this tab re-draws at
|
|
|
+ // the correct zoom level.
|
|
|
+ double origin_zoom_level =
|
|
|
+ zoom_map->GetZoomLevelForHostAndScheme(url.scheme(), host);
|
|
|
+ zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id,
|
|
|
+ origin_zoom_level);
|
|
|
+ } else {
|
|
|
+ // The host will need a level prior to removing the temporary level.
|
|
|
+ // We don't want the zoom level to change just because we entered
|
|
|
+ // default mode.
|
|
|
+ zoom_map->SetZoomLevelForHost(host, original_zoom_level);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Remove per-tab zoom data for this tab. No event callback expected.
|
|
|
+ zoom_map->ClearTemporaryZoomLevel(render_process_id, render_view_id);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case ZOOM_MODE_ISOLATED: {
|
|
|
+ // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the
|
|
|
+ // page needs an initial isolated zoom back to the same level it was at
|
|
|
+ // in the other mode.
|
|
|
+ if (zoom_mode_ != ZOOM_MODE_DISABLED) {
|
|
|
+ zoom_map->SetTemporaryZoomLevel(render_process_id, render_view_id,
|
|
|
+ original_zoom_level);
|
|
|
+ } else {
|
|
|
+ // When we don't call any HostZoomMap set functions, we send the event
|
|
|
+ // manually.
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), original_zoom_level,
|
|
|
+ false);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case ZOOM_MODE_MANUAL: {
|
|
|
+ // Unless the zoom mode was |ZOOM_MODE_DISABLED| before this call, the
|
|
|
+ // page needs to be resized to the default zoom. While in manual mode,
|
|
|
+ // the zoom level is handled independently.
|
|
|
+ if (zoom_mode_ != ZOOM_MODE_DISABLED) {
|
|
|
+ zoom_map->SetTemporaryZoomLevel(
|
|
|
+ render_process_id, render_view_id, GetDefaultZoomLevel());
|
|
|
+ zoom_level_ = original_zoom_level;
|
|
|
+ } else {
|
|
|
+ // When we don't call any HostZoomMap set functions, we send the event
|
|
|
+ // manually.
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), original_zoom_level,
|
|
|
+ false);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case ZOOM_MODE_DISABLED: {
|
|
|
+ // The page needs to be zoomed back to default before disabling the zoom
|
|
|
+ zoom_map->SetTemporaryZoomLevel(
|
|
|
+ render_process_id, render_view_id, GetDefaultZoomLevel());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ zoom_mode_ = new_mode;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void WebContentsZoomController::ResetZoomModeOnNavigationIfNeeded(
|
|
|
+ const GURL& url) {
|
|
|
+ if (zoom_mode_ != ZOOM_MODE_ISOLATED && zoom_mode_ != ZOOM_MODE_MANUAL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
|
|
|
+ int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID();
|
|
|
+ content::HostZoomMap* zoom_map =
|
|
|
+ content::HostZoomMap::GetForWebContents(web_contents());
|
|
|
+ zoom_level_ = zoom_map->GetDefaultZoomLevel();
|
|
|
+ double new_zoom_level = zoom_map->GetZoomLevelForHostAndScheme(
|
|
|
+ url.scheme(), net::GetHostOrSpecFromURL(url));
|
|
|
+ for (Observer& observer : observers_)
|
|
|
+ observer.OnZoomLevelChanged(web_contents(), new_zoom_level,
|
|
|
+ false);
|
|
|
+ zoom_map->ClearTemporaryZoomLevel(render_process_id, render_view_id);
|
|
|
+ zoom_mode_ = ZOOM_MODE_DEFAULT;
|
|
|
+}
|
|
|
+
|
|
|
void WebContentsZoomController::DidFinishNavigation(
|
|
|
content::NavigationHandle* navigation_handle) {
|
|
|
if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
|
|
@@ -101,6 +227,7 @@ void WebContentsZoomController::DidFinishNavigation(
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ ResetZoomModeOnNavigationIfNeeded(navigation_handle->GetURL());
|
|
|
SetZoomFactorOnNavigationIfNeeded(navigation_handle->GetURL());
|
|
|
}
|
|
|
|