Add device emulation API
authorGohy Leandre <leandre.gohy@hexeo.be>
Mon, 31 Aug 2015 09:19:19 +0000 (11:19 +0200)
committerGohy Leandre <leandre.gohy@hexeo.be>
Thu, 17 Sep 2015 11:50:36 +0000 (13:50 +0200)
atom/browser/api/atom_api_web_contents.cc
atom/browser/api/atom_api_web_contents.h
docs/api/web-contents.md

index a24200e..2231a59 100644 (file)
@@ -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", &params.screenSize.width))
+      return;
+    if (!dict.GetInteger("screenSize.height", &params.screenSize.height))
+      return;
+  }
+
+  if (dict.HasKey("viewPosition")) {
+    if (!dict.GetInteger("viewPosition.x", &params.viewPosition.x))
+      return;
+    if (!dict.GetInteger("viewPosition.y", &params.viewPosition.y))
+      return;
+  }
+
+  if (dict.HasKey("deviceScaleFactor")) {
+    double device_scale_factor;
+    if (!dict.GetDouble("deviceScaleFactor", &device_scale_factor))
+      return;
+    params.deviceScaleFactor = static_cast<float>(device_scale_factor);
+  }
+
+  if (dict.HasKey("viewSize")) {
+    if (!dict.GetInteger("viewSize.width", &params.viewSize.width))
+      return;
+    if (!dict.GetInteger("viewSize.height", &params.viewSize.height))
+      return;
+  }
+
+  if (dict.HasKey("fitToView")) {
+    if (!dict.GetBoolean("fitToView", &params.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<float>(x);
+    params.offset.y = static_cast<float>(y);
+  }
+
+  if (dict.HasKey("scale")) {
+    double scale;
+    if (!dict.GetDouble("scale", &scale))
+      return;
+    params.scale = static_cast<float>(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)
index 0001d3e..c765e5c 100644 (file)
@@ -74,6 +74,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
   void CloseDevTools();
   bool IsDevToolsOpened();
   void ToggleDevTools();
+  void EnableDeviceEmulation(const base::DictionaryValue&);
+  void DisableDeviceEmulation();
   void InspectElement(int x, int y);
   void InspectServiceWorker();
   v8::Local<v8::Value> Session(v8::Isolate* isolate);
index 92d91d1..8b4ebcc 100644 (file)
@@ -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`.