diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 9d5c8f8684..ae040be5c4 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -22,6 +22,7 @@ #include "atom/browser/ui/drag_util.h" #include "atom/browser/web_contents_permission_helper.h" #include "atom/browser/web_contents_preferences.h" +#include "atom/browser/web_contents_zoom_controller.h" #include "atom/browser/web_view_guest_delegate.h" #include "atom/common/api/api_messages.h" #include "atom/common/api/event_emitter_caller.h" @@ -248,11 +249,11 @@ WebContents::WebContents(v8::Isolate* isolate, Type type) : content::WebContentsObserver(web_contents), embedder_(nullptr), + zoom_controller_(nullptr), type_(type), request_id_(0), background_throttling_(true), enable_devtools_(true) { - if (type == REMOTE) { web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); Init(isolate); @@ -265,9 +266,9 @@ WebContents::WebContents(v8::Isolate* isolate, } } -WebContents::WebContents(v8::Isolate* isolate, - const mate::Dictionary& options) +WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) : embedder_(nullptr), + zoom_controller_(nullptr), type_(BROWSER_WINDOW), request_id_(0), background_throttling_(true), @@ -345,10 +346,16 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate, // Save the preferences in C++. new WebContentsPreferences(web_contents, options); - // Intialize permission helper. + // Initialize permission helper. WebContentsPermissionHelper::CreateForWebContents(web_contents); - // Intialize security state client. + // Initialize security state client. SecurityStateTabHelper::CreateForWebContents(web_contents); + // Initialize zoom controller. + WebContentsZoomController::CreateForWebContents(web_contents); + zoom_controller_ = WebContentsZoomController::FromWebContents(web_contents); + double zoom_factor; + if (options.Get(options::kZoomFactor, &zoom_factor)) + zoom_controller_->SetDefaultZoomFactor(zoom_factor); web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent()); @@ -812,6 +819,10 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage) IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync, OnRendererMessageSync) + IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_SetTemporaryZoomLevel, + OnSetTemporaryZoomLevel) + IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel, + OnGetZoomLevel) IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange, handled = false) IPC_MESSAGE_UNHANDLED(handled = false) @@ -1498,6 +1509,37 @@ void WebContents::Invalidate() { osr_rwhv->Invalidate(); } +void WebContents::SetZoomLevel(double level) { + zoom_controller_->SetZoomLevel(level); +} + +double WebContents::GetZoomLevel() { + return zoom_controller_->GetZoomLevel(); +} + +void WebContents::SetZoomFactor(double factor) { + auto level = content::ZoomFactorToZoomLevel(factor); + SetZoomLevel(level); +} + +double WebContents::GetZoomFactor() { + auto level = GetZoomLevel(); + return content::ZoomLevelToZoomFactor(level); +} + +void WebContents::OnSetTemporaryZoomLevel(double level, + IPC::Message* reply_msg) { + zoom_controller_->SetTemporaryZoomLevel(level); + double new_level = zoom_controller_->GetZoomLevel(); + AtomViewHostMsg_SetTemporaryZoomLevel::WriteReplyParams(reply_msg, new_level); + Send(reply_msg); +} + +void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) { + AtomViewHostMsg_GetZoomLevel::WriteReplyParams(reply_msg, GetZoomLevel()); + Send(reply_msg); +} + v8::Local WebContents::GetWebPreferences(v8::Isolate* isolate) { WebContentsPreferences* web_preferences = WebContentsPreferences::FromWebContents(web_contents()); @@ -1626,6 +1668,10 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, .SetMethod("setFrameRate", &WebContents::SetFrameRate) .SetMethod("getFrameRate", &WebContents::GetFrameRate) .SetMethod("invalidate", &WebContents::Invalidate) + .SetMethod("setZoomLevel", &WebContents::SetZoomLevel) + .SetMethod("getZoomLevel", &WebContents::GetZoomLevel) + .SetMethod("setZoomFactor", &WebContents::SetZoomFactor) + .SetMethod("getZoomFactor", &WebContents::GetZoomFactor) .SetMethod("getType", &WebContents::GetType) .SetMethod("getWebPreferences", &WebContents::GetWebPreferences) .SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 81472ccd97..a37fb8a91f 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -39,6 +39,7 @@ namespace atom { struct SetSizeParams; class AtomBrowserContext; +class WebContentsZoomController; class WebViewGuestDelegate; namespace api { @@ -174,6 +175,12 @@ class WebContents : public mate::TrackableObject, int GetFrameRate() const; void Invalidate(); + // Methods for zoom handling. + void SetZoomLevel(double level); + double GetZoomLevel(); + void SetZoomFactor(double factor); + double GetZoomFactor(); + // Callback triggered on permission response. void OnEnterFullscreenModeForTab(content::WebContents* source, const GURL& origin, @@ -200,6 +207,8 @@ class WebContents : public mate::TrackableObject, v8::Local DevToolsWebContents(v8::Isolate* isolate); v8::Local Debugger(v8::Isolate* isolate); + WebContentsZoomController* GetZoomController() { return zoom_controller_; } + protected: WebContents(v8::Isolate* isolate, content::WebContents* web_contents, @@ -343,6 +352,14 @@ class WebContents : public mate::TrackableObject, const base::ListValue& args, IPC::Message* message); + // Called when received a synchronous message from renderer to + // set temporary zoom level. + void OnSetTemporaryZoomLevel(double level, IPC::Message* reply_msg); + + // Called when received a synchronous message from renderer to + // get the zoom level. + void OnGetZoomLevel(IPC::Message* reply_msg); + v8::Global session_; v8::Global devtools_web_contents_; v8::Global debugger_; @@ -352,6 +369,9 @@ class WebContents : public mate::TrackableObject, // The host webcontents that may contain this webcontents. WebContents* embedder_; + // The zoom controller for this webContents. + WebContentsZoomController* zoom_controller_; + // The type of current WebContents. Type type_; diff --git a/atom/browser/api/atom_api_web_view_manager.cc b/atom/browser/api/atom_api_web_view_manager.cc index 1586c3a10d..961cb03220 100644 --- a/atom/browser/api/atom_api_web_view_manager.cc +++ b/atom/browser/api/atom_api_web_view_manager.cc @@ -3,10 +3,12 @@ // found in the LICENSE file. #include "atom/browser/web_contents_preferences.h" +#include "atom/browser/web_contents_zoom_controller.h" #include "atom/browser/web_view_manager.h" #include "atom/common/native_mate_converters/content_converter.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" +#include "atom/common/options_switches.h" #include "content/public/browser/browser_context.h" #include "native_mate/dictionary.h" @@ -24,6 +26,12 @@ void AddGuest(int guest_instance_id, manager->AddGuest(guest_instance_id, element_instance_id, embedder, guest_web_contents); + double zoom_factor; + if (options.GetDouble(atom::options::kZoomFactor, &zoom_factor)) { + atom::WebContentsZoomController::FromWebContents(guest_web_contents) + ->SetDefaultZoomFactor(zoom_factor); + } + WebContentsPreferences::FromWebContents(guest_web_contents)->Merge(options); } diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 1182e2859f..c6527dd6f6 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -130,13 +130,6 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( if (web_preferences.GetString(options::kBackgroundColor, &color)) command_line->AppendSwitchASCII(switches::kBackgroundColor, color); - // The zoom factor. - double zoom_factor = 1.0; - if (web_preferences.GetDouble(options::kZoomFactor, &zoom_factor) && - zoom_factor != 1.0) - command_line->AppendSwitchASCII(switches::kZoomFactor, - base::DoubleToString(zoom_factor)); - // --guest-instance-id, which is used to identify guest WebContents. int guest_instance_id = 0; if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id)) diff --git a/atom/browser/web_contents_zoom_controller.cc b/atom/browser/web_contents_zoom_controller.cc new file mode 100644 index 0000000000..92eb30fac8 --- /dev/null +++ b/atom/browser/web_contents_zoom_controller.cc @@ -0,0 +1,183 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/web_contents_zoom_controller.h" + +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/page_type.h" +#include "content/public/common/page_zoom.h" +#include "net/base/url_util.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsZoomController); + +namespace atom { + +WebContentsZoomController::WebContentsZoomController( + content::WebContents* web_contents) + : old_process_id_(-1), + old_view_id_(-1), + embedder_zoom_controller_(nullptr), + content::WebContentsObserver(web_contents) { + default_zoom_factor_ = content::kEpsilon; + host_zoom_map_ = content::HostZoomMap::GetForWebContents(web_contents); + zoom_subscription_ = host_zoom_map_->AddZoomLevelChangedCallback(base::Bind( + &WebContentsZoomController::OnZoomLevelChanged, base::Unretained(this))); +} + +WebContentsZoomController::~WebContentsZoomController() {} + +void WebContentsZoomController::AddObserver( + WebContentsZoomController::Observer* observer) { + observers_.AddObserver(observer); +} + +void WebContentsZoomController::RemoveObserver( + WebContentsZoomController::Observer* observer) { + observers_.RemoveObserver(observer); +} + +void WebContentsZoomController::SetEmbedderZoomController( + WebContentsZoomController* controller) { + embedder_zoom_controller_ = controller; +} + +void WebContentsZoomController::SetZoomLevel(double level) { + if (!web_contents()->GetRenderViewHost()->IsRenderViewLive() || + content::ZoomValuesEqual(GetZoomLevel(), level)) + 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); + } + + auto new_zoom_factor = content::ZoomLevelToZoomFactor(level); + content::NavigationEntry* entry = + web_contents()->GetController().GetLastCommittedEntry(); + if (entry) { + std::string host = net::GetHostOrSpecFromURL(entry->GetURL()); + // When new zoom level varies from kZoomFactor, it takes preference. + if (!content::ZoomValuesEqual(GetDefaultZoomFactor(), new_zoom_factor)) + host_zoom_factor_[host] = new_zoom_factor; + 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()); +} + +void WebContentsZoomController::SetDefaultZoomFactor(double factor) { + default_zoom_factor_ = factor; +} + +double WebContentsZoomController::GetDefaultZoomFactor() { + return default_zoom_factor_; +} + +void WebContentsZoomController::SetTemporaryZoomLevel(double level) { + old_process_id_ = web_contents()->GetRenderProcessHost()->GetID(); + old_view_id_ = web_contents()->GetRenderViewHost()->GetRoutingID(); + host_zoom_map_->SetTemporaryZoomLevel(old_process_id_, old_view_id_, level); + // Notify observers of zoom level changes. + for (Observer& observer : observers_) + observer.OnZoomLevelChanged(web_contents(), level, true); +} + +bool WebContentsZoomController::UsesTemporaryZoomLevel() { + int render_process_id = web_contents()->GetRenderProcessHost()->GetID(); + int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID(); + return host_zoom_map_->UsesTemporaryZoomLevel(render_process_id, + render_view_id); +} + +void WebContentsZoomController::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted()) + return; + + if (navigation_handle->IsErrorPage()) { + content::HostZoomMap::SendErrorPageZoomLevelRefresh(web_contents()); + return; + } + + if (!navigation_handle->IsSamePage()) + SetZoomFactorOnNavigationIfNeeded(navigation_handle->GetURL()); +} + +void WebContentsZoomController::WebContentsDestroyed() { + observers_.Clear(); + host_zoom_factor_.clear(); + embedder_zoom_controller_ = nullptr; +} + +void WebContentsZoomController::RenderFrameHostChanged( + content::RenderFrameHost* old_host, + content::RenderFrameHost* new_host) { + // If our associated HostZoomMap changes, update our event subscription. + content::HostZoomMap* new_host_zoom_map = + content::HostZoomMap::GetForWebContents(web_contents()); + if (new_host_zoom_map == host_zoom_map_) + return; + + host_zoom_map_ = new_host_zoom_map; + zoom_subscription_ = host_zoom_map_->AddZoomLevelChangedCallback(base::Bind( + &WebContentsZoomController::OnZoomLevelChanged, base::Unretained(this))); +} + +void WebContentsZoomController::SetZoomFactorOnNavigationIfNeeded( + const GURL& url) { + if (content::ZoomValuesEqual(GetDefaultZoomFactor(), content::kEpsilon)) + return; + + if (host_zoom_map_->UsesTemporaryZoomLevel(old_process_id_, old_view_id_)) { + host_zoom_map_->ClearTemporaryZoomLevel(old_process_id_, old_view_id_); + } + + if (embedder_zoom_controller_ && + embedder_zoom_controller_->UsesTemporaryZoomLevel()) { + double level = embedder_zoom_controller_->GetZoomLevel(); + SetTemporaryZoomLevel(level); + return; + } + + // When kZoomFactor is available, it takes precedence over + // pref store values but if the host has zoom factor set explicitly + // then it takes precendence. + // pref store < kZoomFactor < setZoomLevel + std::string host = net::GetHostOrSpecFromURL(url); + double zoom_factor = GetDefaultZoomFactor(); + auto it = host_zoom_factor_.find(host); + if (it != host_zoom_factor_.end()) + zoom_factor = it->second; + auto level = content::ZoomFactorToZoomLevel(zoom_factor); + if (content::ZoomValuesEqual(level, GetZoomLevel())) + return; + + SetZoomLevel(level); +} + +void WebContentsZoomController::OnZoomLevelChanged( + const content::HostZoomMap::ZoomLevelChange& change) { + if (change.mode == content::HostZoomMap::ZOOM_CHANGED_FOR_HOST) { + auto it = host_zoom_factor_.find(change.host); + if (it == host_zoom_factor_.end()) + return; + host_zoom_factor_.insert( + it, std::make_pair(change.host, + content::ZoomLevelToZoomFactor(change.zoom_level))); + } +} + +} // namespace atom diff --git a/atom/browser/web_contents_zoom_controller.h b/atom/browser/web_contents_zoom_controller.h new file mode 100644 index 0000000000..11db8745b3 --- /dev/null +++ b/atom/browser/web_contents_zoom_controller.h @@ -0,0 +1,87 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_WEB_CONTENTS_ZOOM_CONTROLLER_H_ +#define ATOM_BROWSER_WEB_CONTENTS_ZOOM_CONTROLLER_H_ + +#include +#include + +#include "content/public/browser/host_zoom_map.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace atom { + +// Manages the zoom changes of WebContents. +class WebContentsZoomController + : public content::WebContentsObserver, + public content::WebContentsUserData { + public: + class Observer { + public: + virtual void OnZoomLevelChanged(content::WebContents* web_contents, + double level, + bool is_temporary) {} + + protected: + virtual ~Observer() {} + }; + + explicit WebContentsZoomController(content::WebContents* web_contents); + ~WebContentsZoomController() override; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + void SetEmbedderZoomController(WebContentsZoomController* controller); + + // Methods for managing zoom levels. + void SetZoomLevel(double level); + double GetZoomLevel(); + void SetDefaultZoomFactor(double factor); + double GetDefaultZoomFactor(); + void SetTemporaryZoomLevel(double level); + bool UsesTemporaryZoomLevel(); + + protected: + // content::WebContentsObserver: + void DidFinishNavigation(content::NavigationHandle* handle) override; + void WebContentsDestroyed() override; + void RenderFrameHostChanged(content::RenderFrameHost* old_host, + content::RenderFrameHost* new_host) override; + + private: + friend class content::WebContentsUserData; + + // Called after a navigation has committed to set default zoom factor. + void SetZoomFactorOnNavigationIfNeeded(const GURL& url); + + // Track zoom changes of a host in other instances of a partition. + void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change); + + // kZoomFactor. + double default_zoom_factor_; + double temporary_zoom_level_; + + int old_process_id_; + int old_view_id_; + + WebContentsZoomController* embedder_zoom_controller_; + + // Map between zoom factor and hosts in this webContent. + std::map host_zoom_factor_; + + base::ObserverList observers_; + + content::HostZoomMap* host_zoom_map_; + + std::unique_ptr zoom_subscription_; + + DISALLOW_COPY_AND_ASSIGN(WebContentsZoomController); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_WEB_CONTENTS_ZOOM_CONTROLLER_H_ diff --git a/atom/browser/web_view_guest_delegate.cc b/atom/browser/web_view_guest_delegate.cc index cfb3264963..21b917ac61 100644 --- a/atom/browser/web_view_guest_delegate.cc +++ b/atom/browser/web_view_guest_delegate.cc @@ -23,11 +23,11 @@ const int kDefaultHeight = 300; } // namespace WebViewGuestDelegate::WebViewGuestDelegate() - : guest_host_(nullptr), + : embedder_zoom_controller_(nullptr), + guest_host_(nullptr), auto_size_enabled_(false), is_full_page_plugin_(false), - api_web_contents_(nullptr) { -} + api_web_contents_(nullptr) {} WebViewGuestDelegate::~WebViewGuestDelegate() { } @@ -39,6 +39,10 @@ void WebViewGuestDelegate::Initialize(api::WebContents* api_web_contents) { void WebViewGuestDelegate::Destroy() { // Give the content module an opportunity to perform some cleanup. + if (embedder_zoom_controller_) { + embedder_zoom_controller_->RemoveObserver(this); + embedder_zoom_controller_ = nullptr; + } guest_host_->WillDestroy(); guest_host_ = nullptr; } @@ -107,6 +111,11 @@ void WebViewGuestDelegate::DidFinishNavigation( void WebViewGuestDelegate::DidAttach(int guest_proxy_routing_id) { api_web_contents_->Emit("did-attach"); + embedder_zoom_controller_ = + WebContentsZoomController::FromWebContents(embedder_web_contents_); + auto zoom_controller = api_web_contents_->GetZoomController(); + embedder_zoom_controller_->AddObserver(this); + zoom_controller->SetEmbedderZoomController(embedder_zoom_controller_); } content::WebContents* WebViewGuestDelegate::GetOwnerWebContents() const { @@ -134,6 +143,22 @@ void WebViewGuestDelegate::WillAttach( completion_callback.Run(); } +void WebViewGuestDelegate::OnZoomLevelChanged( + content::WebContents* web_contents, + double level, + bool is_temporary) { + if (web_contents == GetOwnerWebContents()) { + if (is_temporary) { + api_web_contents_->GetZoomController()->SetTemporaryZoomLevel(level); + } else { + api_web_contents_->GetZoomController()->SetZoomLevel(level); + } + // Change the default zoom factor to match the embedders' new zoom level. + double zoom_factor = content::ZoomLevelToZoomFactor(level); + api_web_contents_->GetZoomController()->SetDefaultZoomFactor(zoom_factor); + } +} + void WebViewGuestDelegate::GuestSizeChangedDueToAutoSize( const gfx::Size& old_size, const gfx::Size& new_size) { api_web_contents_->Emit("size-changed", diff --git a/atom/browser/web_view_guest_delegate.h b/atom/browser/web_view_guest_delegate.h index eade31234c..329b7ec317 100644 --- a/atom/browser/web_view_guest_delegate.h +++ b/atom/browser/web_view_guest_delegate.h @@ -5,6 +5,7 @@ #ifndef ATOM_BROWSER_WEB_VIEW_GUEST_DELEGATE_H_ #define ATOM_BROWSER_WEB_VIEW_GUEST_DELEGATE_H_ +#include "atom/browser/web_contents_zoom_controller.h" #include "content/public/browser/browser_plugin_guest_delegate.h" #include "content/public/browser/web_contents_observer.h" @@ -31,7 +32,8 @@ struct SetSizeParams { }; class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, - public content::WebContentsObserver { + public content::WebContentsObserver, + public WebContentsZoomController::Observer { public: WebViewGuestDelegate(); ~WebViewGuestDelegate() override; @@ -63,6 +65,11 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, content::RenderWidgetHost* GetOwnerRenderWidgetHost() override; content::SiteInstance* GetOwnerSiteInstance() override; + // WebContentsZoomController::Observer: + void OnZoomLevelChanged(content::WebContents* web_contents, + double level, + bool is_temporary) override; + private: // This method is invoked when the contents auto-resized to give the container // an opportunity to match it if it wishes. @@ -78,6 +85,10 @@ class WebViewGuestDelegate : public content::BrowserPluginGuestDelegate, // The WebContents that attaches this guest view. content::WebContents* embedder_web_contents_; + // The zoom controller of the embedder that is used + // to subscribe for zoom changes. + WebContentsZoomController* embedder_zoom_controller_; + // The size of the container element. gfx::Size element_size_; diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index ab27d5a251..ef945d9eeb 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -41,3 +41,11 @@ IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, // Update renderer process preferences. IPC_MESSAGE_CONTROL1(AtomMsg_UpdatePreferences, base::ListValue) + +// Sent by renderer to set the temporary zoom level. +IPC_SYNC_MESSAGE_ROUTED1_1(AtomViewHostMsg_SetTemporaryZoomLevel, + double /* zoom level */, + double /* result */) + +// Sent by renderer to get the zoom level. +IPC_SYNC_MESSAGE_ROUTED0_1(AtomViewHostMsg_GetZoomLevel, double /* result */) diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 4729a28127..6db479ceb7 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -155,7 +155,6 @@ const char kAppUserModelId[] = "app-user-model-id"; // The command line switch versions of the options. const char kBackgroundColor[] = "background-color"; -const char kZoomFactor[] = "zoom-factor"; const char kPreloadScript[] = "preload"; const char kPreloadURL[] = "preload-url"; const char kNodeIntegration[] = "node-integration"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index c81ab529cf..abe3856cd8 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -81,7 +81,6 @@ extern const char kSecureSchemes[]; extern const char kAppUserModelId[]; extern const char kBackgroundColor[]; -extern const char kZoomFactor[]; extern const char kPreloadScript[]; extern const char kPreloadURL[]; extern const char kNodeIntegration[]; diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index c750a455de..f103b89391 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -4,6 +4,7 @@ #include "atom/renderer/api/atom_api_web_frame.h" +#include "atom/common/api/api_messages.h" #include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/blink_converter.h" #include "atom/common/native_mate_converters/callback.h" @@ -72,13 +73,21 @@ void WebFrame::SetName(const std::string& name) { } double WebFrame::SetZoomLevel(double level) { - double ret = web_frame_->view()->setZoomLevel(level); - mate::EmitEvent(isolate(), GetWrapper(), "zoom-level-changed", ret); - return ret; + double result = 0.0; + content::RenderView* render_view = + content::RenderView::FromWebView(web_frame_->view()); + render_view->Send(new AtomViewHostMsg_SetTemporaryZoomLevel( + render_view->GetRoutingID(), level, &result)); + return result; } double WebFrame::GetZoomLevel() const { - return web_frame_->view()->zoomLevel(); + double result = 0.0; + content::RenderView* render_view = + content::RenderView::FromWebView(web_frame_->view()); + render_view->Send( + new AtomViewHostMsg_GetZoomLevel(render_view->GetRoutingID(), &result)); + return result; } double WebFrame::SetZoomFactor(double factor) { diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index b96c6ea672..a68238ba4c 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -14,7 +14,6 @@ #include "atom/common/api/event_emitter_caller.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/node_includes.h" -#include "atom/common/options_switches.h" #include "atom/renderer/atom_renderer_client.h" #include "base/command_line.h" #include "base/strings/string_number_conversions.h" @@ -117,17 +116,6 @@ void AtomRenderViewObserver::EmitIPCEvent(blink::WebFrame* frame, void AtomRenderViewObserver::DidCreateDocumentElement( blink::WebLocalFrame* frame) { document_created_ = true; - - // Read --zoom-factor from command line. - std::string zoom_factor_str = base::CommandLine::ForCurrentProcess()-> - GetSwitchValueASCII(switches::kZoomFactor); - if (zoom_factor_str.empty()) - return; - double zoom_factor; - if (!base::StringToDouble(zoom_factor_str, &zoom_factor)) - return; - double zoom_level = blink::WebView::zoomFactorToZoomLevel(zoom_factor); - frame->view()->setZoomLevel(zoom_level); } void AtomRenderViewObserver::DraggableRegionsChanged(blink::WebFrame* frame) { diff --git a/filenames.gypi b/filenames.gypi index 5b16beaa91..d3dc7ed22c 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -341,6 +341,8 @@ 'atom/browser/web_contents_permission_helper.h', 'atom/browser/web_contents_preferences.cc', 'atom/browser/web_contents_preferences.h', + 'atom/browser/web_contents_zoom_controller.cc', + 'atom/browser/web_contents_zoom_controller.h', 'atom/browser/web_dialog_helper.cc', 'atom/browser/web_dialog_helper.h', 'atom/browser/web_view_guest_delegate.cc', diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index a92ef7603b..c94bd768c0 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -105,15 +105,10 @@ const webFrameMethods = [ 'insertText', 'setLayoutZoomLevelLimits', 'setVisualZoomLevelLimits', - 'setZoomFactor', - 'setZoomLevel', // TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings 'setZoomLevelLimits' ] -const webFrameMethodsWithResult = [ - 'getZoomFactor', - 'getZoomLevel' -] +const webFrameMethodsWithResult = [] const asyncWebFrameMethods = function (requestId, method, callback, ...args) { return new Promise((resolve, reject) => { diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index f1a460271b..e61b2574ad 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -184,7 +184,7 @@ const attachGuest = function (event, elementInstanceId, guestInstanceId, params) guestInstanceId: guestInstanceId, nodeIntegration: params.nodeintegration != null ? params.nodeintegration : false, plugins: params.plugins, - zoomFactor: params.zoomFactor, + zoomFactor: embedder.getZoomFactor(), webSecurity: !params.disablewebsecurity, blinkFeatures: params.blinkfeatures, disableBlinkFeatures: params.disableblinkfeatures diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index ba8ae32d46..c98b02d274 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -34,12 +34,6 @@ class WebViewImpl { this.viewInstanceId = getNextId() shadowRoot.appendChild(this.browserPluginNode) - // Subscribe to host's zoom level changes. - this.onZoomLevelChanged = (zoomLevel) => { - this.webviewNode.setZoomLevel(zoomLevel) - } - webFrame.on('zoom-level-changed', this.onZoomLevelChanged) - this.onVisibilityChanged = (event, visibilityState) => { this.webviewNode.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', visibilityState) } @@ -56,8 +50,6 @@ class WebViewImpl { // Resets some state upon reattaching element to the DOM. reset () { - // Unlisten the zoom-level-changed event. - webFrame.removeListener('zoom-level-changed', this.onZoomLevelChanged) ipcRenderer.removeListener('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', this.onVisibilityChanged) // If guestInstanceId is defined then the has navigated and has @@ -230,8 +222,7 @@ class WebViewImpl { buildParams () { const params = { instanceId: this.viewInstanceId, - userAgentOverride: this.userAgentOverride, - zoomFactor: webFrame.getZoomFactor() + userAgentOverride: this.userAgentOverride } for (const attributeName in this.attributes) { if (hasProp.call(this.attributes, attributeName)) {