From 6b875110ed8b20c0da142c56b96d0d61b1564c3b Mon Sep 17 00:00:00 2001 From: Gohy Leandre Date: Mon, 31 Aug 2015 11:19:19 +0200 Subject: [PATCH] Add device emulation API --- atom/browser/api/atom_api_web_contents.cc | 88 +++++++++++++++++++++++ atom/browser/api/atom_api_web_contents.h | 2 + docs/api/web-contents.md | 35 +++++++++ 3 files changed, 125 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a24200e5a87d..2231a591f732 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -27,6 +27,7 @@ #include "brightray/browser/inspectable_web_contents.h" #include "chrome/browser/printing/print_view_manager_basic.h" #include "chrome/browser/printing/print_preview_message_handler.h" +#include "content/common/view_messages.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" @@ -44,6 +45,7 @@ #include "net/http/http_response_headers.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" +#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h" #include "atom/common/node_includes.h" @@ -640,6 +642,88 @@ bool WebContents::IsDevToolsOpened() { return managed_web_contents()->IsDevToolsViewShowing(); } +void WebContents::EnableDeviceEmulation(const base::DictionaryValue& dict) { + if (type_ == REMOTE) + return; + + blink::WebDeviceEmulationParams params; + + if (dict.HasKey("screenPosition")) { + std::string screen_position; + if (!dict.GetString("screenPosition", &screen_position)) + return; + + screen_position = base::StringToLowerASCII(screen_position); + + if (screen_position == "mobile") { + params.screenPosition = blink::WebDeviceEmulationParams::Mobile; + } else if (screen_position == "desktop") { + params.screenPosition = blink::WebDeviceEmulationParams::Desktop; + } else { + return; + } + } + + if (dict.HasKey("screenSize")) { + if (!dict.GetInteger("screenSize.width", ¶ms.screenSize.width)) + return; + if (!dict.GetInteger("screenSize.height", ¶ms.screenSize.height)) + return; + } + + if (dict.HasKey("viewPosition")) { + if (!dict.GetInteger("viewPosition.x", ¶ms.viewPosition.x)) + return; + if (!dict.GetInteger("viewPosition.y", ¶ms.viewPosition.y)) + return; + } + + if (dict.HasKey("deviceScaleFactor")) { + double device_scale_factor; + if (!dict.GetDouble("deviceScaleFactor", &device_scale_factor)) + return; + params.deviceScaleFactor = static_cast(device_scale_factor); + } + + if (dict.HasKey("viewSize")) { + if (!dict.GetInteger("viewSize.width", ¶ms.viewSize.width)) + return; + if (!dict.GetInteger("viewSize.height", ¶ms.viewSize.height)) + return; + } + + if (dict.HasKey("fitToView")) { + if (!dict.GetBoolean("fitToView", ¶ms.fitToView)) + return; + } + + if (dict.HasKey("offset")) { + double x, y; + if (!dict.GetDouble("offset.x", &x)) + return; + if (!dict.GetDouble("offset.y", &y)) + return; + params.offset.x = static_cast(x); + params.offset.y = static_cast(y); + } + + if (dict.HasKey("scale")) { + double scale; + if (!dict.GetDouble("scale", &scale)) + return; + params.scale = static_cast(scale); + } + + Send(new ViewMsg_EnableDeviceEmulation(routing_id(), params)); +} + +void WebContents::DisableDeviceEmulation() { + if (type_ == REMOTE) + return; + + Send(new ViewMsg_DisableDeviceEmulation(routing_id())); +} + void WebContents::ToggleDevTools() { if (IsDevToolsOpened()) CloseDevTools(); @@ -836,6 +920,10 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("openDevTools", &WebContents::OpenDevTools) .SetMethod("closeDevTools", &WebContents::CloseDevTools) .SetMethod("isDevToolsOpened", &WebContents::IsDevToolsOpened) + .SetMethod("enableDeviceEmulation", + &WebContents::EnableDeviceEmulation) + .SetMethod("disableDeviceEmulation", + &WebContents::DisableDeviceEmulation) .SetMethod("toggleDevTools", &WebContents::ToggleDevTools) .SetMethod("inspectElement", &WebContents::InspectElement) .SetMethod("setAudioMuted", &WebContents::SetAudioMuted) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0001d3e8ef75..c765e5cbf4e4 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -74,6 +74,8 @@ class WebContents : public mate::TrackableObject, void CloseDevTools(); bool IsDevToolsOpened(); void ToggleDevTools(); + void EnableDeviceEmulation(const base::DictionaryValue&); + void DisableDeviceEmulation(); void InspectElement(int x, int y); void InspectServiceWorker(); v8::Local Session(v8::Isolate* isolate); diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 92d91d170e4a..8b4ebcc33784 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -476,3 +476,38 @@ app.on('ready', function() { which is different from the handlers in the main process. 2. There is no way to send synchronous messages from the main process to a renderer process, because it would be very easy to cause dead locks. + +### `webContents.enableDeviceEmulation(parameters)` + +`parameters` Object, properties: + +* `screenPosition` String - Specify the screen type to emulate + (default: `desktop`) + * `desktop` + * `mobile` +* `screenSize` Object - Set the emulated screen size (screenPosition == mobile) + * `width` Integer - Set the emulated screen width + * `height` Integer - Set the emulated screen height +* `viewPosition` Object - Position the view on the screen + (screenPosition == mobile) (default: `{x: 0, y: 0}`) + * `x` Integer - Set the x axis offset from top left corner + * `y` Integer - Set the y axis offset from top left corner +* `deviceScaleFactor` Integer - Set the device scale factor (if zero defaults to + original device scale factor) (default: `0`) +* `viewSize` Object - Set the emulated view size (empty means no override) + * `width` Integer - Set the emulated view width + * `height` Integer - Set the emulated view height +* `fitToView` Boolean - Whether emulated view should be scaled down if + necessary to fit into available space (default: `false`) +* `offset` Object - Offset of the emulated view inside available space (not in + fit to view mode) (default: `{x: 0, y: 0}`) + * `x` Float - Set the x axis offset from top left corner + * `y` Float - Set the y axis offset from top left corner +* `scale` Float - Scale of emulated view inside available space (not in fit to + view mode) (default: `1`) + +Enable device emulation with the given parameters. + +### `webContents.disableDeviceEmulation()` + +Disable device emulation enabled by `webContents.enableDeviceEmulation`.