Merge pull request #2834 from preco21/master
authorCheng Zhao <zcbenz@gmail.com>
Mon, 21 Sep 2015 03:35:37 +0000 (11:35 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Mon, 21 Sep 2015 03:35:37 +0000 (11:35 +0800)
Update as upstream, change name the translation folder

33 files changed:
CONTRIBUTING.md
atom.gyp
atom/browser/api/atom_api_web_contents.cc
atom/browser/api/atom_api_web_contents.h
atom/browser/api/atom_api_window.cc
atom/browser/api/frame_subscriber.cc [new file with mode: 0644]
atom/browser/api/frame_subscriber.h [new file with mode: 0644]
atom/browser/native_window.cc
atom/browser/native_window.h
atom/browser/resources/mac/Info.plist
atom/browser/resources/win/atom.rc
atom/browser/ui/accelerator_util.cc
atom/common/atom_version.h
atom/common/keyboad_util.cc [new file with mode: 0644]
atom/common/keyboad_util.h [new file with mode: 0644]
atom/common/native_mate_converters/blink_converter.cc [new file with mode: 0644]
atom/common/native_mate_converters/blink_converter.h [new file with mode: 0644]
atom/renderer/lib/web-view/web-view.coffee
docs/api/browser-window.md
docs/api/remote.md
docs/api/web-contents.md
docs/api/web-view-tag.md
filenames.gypi
script/create-dist.py
spec/api-browser-window-spec.coffee
spec/fixtures/module/set-immediate.js [new file with mode: 0644]
spec/fixtures/pages/onkeyup.html [new file with mode: 0644]
spec/fixtures/pages/onmouseup.html [new file with mode: 0644]
spec/fixtures/pages/will-navigate.html
spec/node-spec.coffee
spec/webview-spec.coffee
vendor/brightray
vendor/node

index 516f628..6ca3ea5 100644 (file)
@@ -30,7 +30,7 @@ possible with your report. If you can, please include:
 * Follow the CoffeeScript, JavaScript, C++ and Python [coding style defined in docs](/docs/development/coding-style.md).
 * Write documentation in [Markdown](https://daringfireball.net/projects/markdown).
   See the [Documentation Styleguide](/docs/styleguide.md).
-* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages-styleguide).
+* Use short, present tense commit messages. See [Commit Message Styleguide](#git-commit-messages).
 
 ## Styleguides
 
index 63defa4..c9d5f92 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
@@ -4,7 +4,7 @@
     'product_name%': 'Electron',
     'company_name%': 'GitHub, Inc',
     'company_abbr%': 'github',
-    'version%': '0.32.3',
+    'version%': '0.33.0',
   },
   'includes': [
     'filenames.gypi',
index a24200e..9791a94 100644 (file)
@@ -15,6 +15,7 @@
 #include "atom/browser/web_view_guest_delegate.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"
 #include "atom/common/native_mate_converters/file_path_converter.h"
 #include "atom/common/native_mate_converters/gfx_converter.h"
 #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/native_web_keyboard_event.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/plugin_service.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/resource_request_details.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
@@ -44,6 +48,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/WebInputEvent.h"
 
 #include "atom/common/node_includes.h"
 
@@ -640,6 +645,21 @@ bool WebContents::IsDevToolsOpened() {
   return managed_web_contents()->IsDevToolsViewShowing();
 }
 
+void WebContents::EnableDeviceEmulation(
+    const blink::WebDeviceEmulationParams& params) {
+  if (type_ == REMOTE)
+    return;
+
+  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();
@@ -796,6 +816,56 @@ bool WebContents::SendIPCMessage(const base::string16& channel,
   return Send(new AtomViewMsg_Message(routing_id(), channel, args));
 }
 
+void WebContents::SendInputEvent(v8::Isolate* isolate,
+                                 v8::Local<v8::Value> input_event) {
+  const auto view = web_contents()->GetRenderWidgetHostView();
+  if (!view)
+    return;
+  const auto host = view->GetRenderWidgetHost();
+  if (!host)
+    return;
+
+  int type = mate::GetWebInputEventType(isolate, input_event);
+  if (blink::WebInputEvent::isMouseEventType(type)) {
+    blink::WebMouseEvent mouse_event;
+    if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) {
+      host->ForwardMouseEvent(mouse_event);
+      return;
+    }
+  } else if (blink::WebInputEvent::isKeyboardEventType(type)) {
+    content::NativeWebKeyboardEvent keyboard_event;;
+    if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) {
+      host->ForwardKeyboardEvent(keyboard_event);
+      return;
+    }
+  } else if (type == blink::WebInputEvent::MouseWheel) {
+    blink::WebMouseWheelEvent mouse_wheel_event;
+    if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) {
+      host->ForwardWheelEvent(mouse_wheel_event);
+      return;
+    }
+  }
+
+  isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
+      isolate, "Invalid event object")));
+}
+
+void WebContents::BeginFrameSubscription(
+    const FrameSubscriber::FrameCaptureCallback& callback) {
+  const auto view = web_contents()->GetRenderWidgetHostView();
+  if (view) {
+    scoped_ptr<FrameSubscriber> frame_subscriber(new FrameSubscriber(
+        isolate(), view->GetVisibleViewportSize(), callback));
+    view->BeginFrameSubscription(frame_subscriber.Pass());
+  }
+}
+
+void WebContents::EndFrameSubscription() {
+  const auto view = web_contents()->GetRenderWidgetHostView();
+  if (view)
+    view->EndFrameSubscription();
+}
+
 void WebContents::SetSize(const SetSizeParams& params) {
   if (guest_delegate_)
     guest_delegate_->SetSize(params);
@@ -836,6 +906,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)
@@ -854,6 +928,10 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
         .SetMethod("focus", &WebContents::Focus)
         .SetMethod("tabTraverse", &WebContents::TabTraverse)
         .SetMethod("_send", &WebContents::SendIPCMessage, true)
+        .SetMethod("sendInputEvent", &WebContents::SendInputEvent)
+        .SetMethod("beginFrameSubscription",
+                   &WebContents::BeginFrameSubscription)
+        .SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
         .SetMethod("setSize", &WebContents::SetSize)
         .SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
         .SetMethod("isGuest", &WebContents::IsGuest)
index 0001d3e..c8ea690 100644 (file)
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "atom/browser/api/frame_subscriber.h"
 #include "atom/browser/api/trackable_object.h"
 #include "atom/browser/common_web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "native_mate/handle.h"
 #include "ui/gfx/image/image.h"
 
+namespace blink {
+struct WebDeviceEmulationParams;
+}
+
 namespace brightray {
 class InspectableWebContents;
 }
@@ -74,6 +79,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
   void CloseDevTools();
   bool IsDevToolsOpened();
   void ToggleDevTools();
+  void EnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
+  void DisableDeviceEmulation();
   void InspectElement(int x, int y);
   void InspectServiceWorker();
   v8::Local<v8::Value> Session(v8::Isolate* isolate);
@@ -108,10 +115,18 @@ class WebContents : public mate::TrackableObject<WebContents>,
   void Focus();
   void TabTraverse(bool reverse);
 
-  // Sending messages to browser.
+  // Send messages to browser.
   bool SendIPCMessage(const base::string16& channel,
                       const base::ListValue& args);
 
+  // Send WebInputEvent to the page.
+  void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
+
+  // Subscribe to the frame updates.
+  void BeginFrameSubscription(
+      const FrameSubscriber::FrameCaptureCallback& callback);
+  void EndFrameSubscription();
+
   // Methods for creating <webview>.
   void SetSize(const SetSizeParams& params);
   void SetAllowTransparency(bool allow);
index 1a76c3e..3a44115 100644 (file)
@@ -13,6 +13,7 @@
 #include "atom/common/native_mate_converters/gurl_converter.h"
 #include "atom/common/native_mate_converters/image_converter.h"
 #include "atom/common/native_mate_converters/string16_converter.h"
+#include "atom/common/node_includes.h"
 #include "atom/common/options_switches.h"
 #include "content/public/browser/render_process_host.h"
 #include "native_mate/constructor.h"
@@ -24,8 +25,6 @@
 #include "atom/browser/ui/win/taskbar_host.h"
 #endif
 
-#include "atom/common/node_includes.h"
-
 #if defined(OS_WIN)
 namespace mate {
 
@@ -116,6 +115,9 @@ void Window::OnWindowClosed() {
   window_->RemoveObserver(this);
 
   Emit("closed");
+
+  // Clean up the resources after window has been closed.
+  base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
 }
 
 void Window::OnWindowBlur() {
@@ -220,10 +222,8 @@ bool Window::IsDestroyed() const {
 }
 
 void Window::Destroy() {
-  if (window_) {
+  if (window_)
     window_->CloseContents(nullptr);
-    window_.reset();
-  }
 }
 
 void Window::Close() {
diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc
new file mode 100644 (file)
index 0000000..526769f
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/api/frame_subscriber.h"
+
+#include "atom/common/node_includes.h"
+#include "base/bind.h"
+#include "media/base/video_frame.h"
+#include "media/base/yuv_convert.h"
+
+namespace atom {
+
+namespace api {
+
+FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
+                                 const gfx::Size& size,
+                                 const FrameCaptureCallback& callback)
+    : isolate_(isolate), size_(size), callback_(callback) {
+}
+
+bool FrameSubscriber::ShouldCaptureFrame(
+    const gfx::Rect& damage_rect,
+    base::TimeTicks present_time,
+    scoped_refptr<media::VideoFrame>* storage,
+    DeliverFrameCallback* callback) {
+  *storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
+                                            gfx::Rect(size_), size_,
+                                            base::TimeDelta());
+  *callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
+                         base::Unretained(this),
+                         *storage);
+  return true;
+}
+
+void FrameSubscriber::OnFrameDelivered(
+    scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool result) {
+  if (!result)
+    return;
+
+  gfx::Rect rect = frame->visible_rect();
+  size_t rgb_arr_size = rect.width() * rect.height() * 4;
+  v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
+  if (buffer.IsEmpty())
+    return;
+
+  // Convert a frame of YUV to 32 bit ARGB.
+  media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane),
+                           frame->data(media::VideoFrame::kUPlane),
+                           frame->data(media::VideoFrame::kVPlane),
+                           reinterpret_cast<uint8*>(
+                              node::Buffer::Data(buffer.ToLocalChecked())),
+                           rect.width(), rect.height(),
+                           frame->stride(media::VideoFrame::kYPlane),
+                           frame->stride(media::VideoFrame::kUVPlane),
+                           rect.width() * 4,
+                           media::YV12);
+
+  v8::Locker locker(isolate_);
+  v8::HandleScope handle_scope(isolate_);
+  callback_.Run(buffer.ToLocalChecked());
+}
+
+}  // namespace api
+
+}  // namespace atom
diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h
new file mode 100644 (file)
index 0000000..f7748aa
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
+#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
+
+#include "base/callback.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
+#include "ui/gfx/geometry/size.h"
+#include "v8/include/v8.h"
+
+namespace atom {
+
+namespace api {
+
+class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
+ public:
+  using FrameCaptureCallback = base::Callback<void(v8::Local<v8::Value>)>;
+
+  FrameSubscriber(v8::Isolate* isolate,
+                  const gfx::Size& size,
+                  const FrameCaptureCallback& callback);
+
+  bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
+                          base::TimeTicks present_time,
+                          scoped_refptr<media::VideoFrame>* storage,
+                          DeliverFrameCallback* callback) override;
+
+ private:
+  void OnFrameDelivered(
+      scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool);
+
+  v8::Isolate* isolate_;
+  gfx::Size size_;
+  FrameCaptureCallback callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
+};
+
+}  // namespace api
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
index f40f7de..4d5f273 100644 (file)
 #include "ui/gfx/screen.h"
 #include "ui/gl/gpu_switching_manager.h"
 
-using content::NavigationEntry;
-using content::RenderWidgetHostView;
-using content::RenderWidgetHost;
-
 DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay);
 
 namespace atom {
@@ -200,38 +196,6 @@ bool NativeWindow::IsDocumentEdited() {
 void NativeWindow::SetMenu(ui::MenuModel* menu) {
 }
 
-void NativeWindow::ShowDefinitionForSelection() {
-  NOTIMPLEMENTED();
-}
-
-void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
-}
-
-bool NativeWindow::IsMenuBarAutoHide() {
-  return false;
-}
-
-void NativeWindow::SetMenuBarVisibility(bool visible) {
-}
-
-bool NativeWindow::IsMenuBarVisible() {
-  return true;
-}
-
-double NativeWindow::GetAspectRatio() {
-  return aspect_ratio_;
-}
-
-gfx::Size NativeWindow::GetAspectRatioExtraSize() {
-  return aspect_ratio_extraSize_;
-}
-
-void NativeWindow::SetAspectRatio(double aspect_ratio,
-                                  const gfx::Size& extra_size) {
-  aspect_ratio_ = aspect_ratio;
-  aspect_ratio_extraSize_ = extra_size;
-}
-
 bool NativeWindow::HasModalDialog() {
   return has_dialog_attached_;
 }
@@ -286,6 +250,38 @@ void NativeWindow::CapturePage(const gfx::Rect& rect,
       kBGRA_8888_SkColorType);
 }
 
+void NativeWindow::ShowDefinitionForSelection() {
+  NOTIMPLEMENTED();
+}
+
+void NativeWindow::SetAutoHideMenuBar(bool auto_hide) {
+}
+
+bool NativeWindow::IsMenuBarAutoHide() {
+  return false;
+}
+
+void NativeWindow::SetMenuBarVisibility(bool visible) {
+}
+
+bool NativeWindow::IsMenuBarVisible() {
+  return true;
+}
+
+double NativeWindow::GetAspectRatio() {
+  return aspect_ratio_;
+}
+
+gfx::Size NativeWindow::GetAspectRatioExtraSize() {
+  return aspect_ratio_extraSize_;
+}
+
+void NativeWindow::SetAspectRatio(double aspect_ratio,
+                                  const gfx::Size& extra_size) {
+  aspect_ratio_ = aspect_ratio;
+  aspect_ratio_extraSize_ = extra_size;
+}
+
 void NativeWindow::RequestToClosePage() {
   bool prevent_default = false;
   FOR_EACH_OBSERVER(NativeWindowObserver,
index f09845a..e9a2b94 100644 (file)
@@ -296,7 +296,6 @@ class NativeWindow : public content::WebContentsObserver,
   DISALLOW_COPY_AND_ASSIGN(NativeWindow);
 };
 
-
 // This class provides a hook to get a NativeWindow from a WebContents.
 class NativeWindowRelay :
     public content::WebContentsUserData<NativeWindowRelay> {
index dd4e610..54ba354 100644 (file)
@@ -17,7 +17,7 @@
   <key>CFBundleIconFile</key>
   <string>atom.icns</string>
   <key>CFBundleVersion</key>
-  <string>0.32.3</string>
+  <string>0.33.0</string>
   <key>LSMinimumSystemVersion</key>
   <string>10.8.0</string>
   <key>NSMainNibFile</key>
index cf894f6..8863d8b 100644 (file)
@@ -56,8 +56,8 @@ END
 //\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 0,32,3,0\r
- PRODUCTVERSION 0,32,3,0\r
+ FILEVERSION 0,33,0,0\r
+ PRODUCTVERSION 0,33,0,0\r
  FILEFLAGSMASK 0x3fL\r
 #ifdef _DEBUG\r
  FILEFLAGS 0x1L\r
@@ -74,12 +74,12 @@ BEGIN
         BEGIN\r
             VALUE "CompanyName", "GitHub, Inc."\r
             VALUE "FileDescription", "Electron"\r
-            VALUE "FileVersion", "0.32.3"\r
+            VALUE "FileVersion", "0.33.0"\r
             VALUE "InternalName", "electron.exe"\r
             VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."\r
             VALUE "OriginalFilename", "electron.exe"\r
             VALUE "ProductName", "Electron"\r
-            VALUE "ProductVersion", "0.32.3"\r
+            VALUE "ProductVersion", "0.33.0"\r
             VALUE "SquirrelAwareVersion", "1"\r
         END\r
     END\r
index 41dde7a..e25e14b 100644 (file)
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "atom/common/keyboad_util.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 
 namespace accelerator_util {
 
-namespace {
-
-// Return key code of the char.
-ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) {
-  *shifted = false;
-  switch (c) {
-    case 8: case 0x7F: return ui::VKEY_BACK;
-    case 9: return ui::VKEY_TAB;
-    case 0xD: case 3: return ui::VKEY_RETURN;
-    case 0x1B: return ui::VKEY_ESCAPE;
-    case ' ': return ui::VKEY_SPACE;
-
-    case 'a': return ui::VKEY_A;
-    case 'b': return ui::VKEY_B;
-    case 'c': return ui::VKEY_C;
-    case 'd': return ui::VKEY_D;
-    case 'e': return ui::VKEY_E;
-    case 'f': return ui::VKEY_F;
-    case 'g': return ui::VKEY_G;
-    case 'h': return ui::VKEY_H;
-    case 'i': return ui::VKEY_I;
-    case 'j': return ui::VKEY_J;
-    case 'k': return ui::VKEY_K;
-    case 'l': return ui::VKEY_L;
-    case 'm': return ui::VKEY_M;
-    case 'n': return ui::VKEY_N;
-    case 'o': return ui::VKEY_O;
-    case 'p': return ui::VKEY_P;
-    case 'q': return ui::VKEY_Q;
-    case 'r': return ui::VKEY_R;
-    case 's': return ui::VKEY_S;
-    case 't': return ui::VKEY_T;
-    case 'u': return ui::VKEY_U;
-    case 'v': return ui::VKEY_V;
-    case 'w': return ui::VKEY_W;
-    case 'x': return ui::VKEY_X;
-    case 'y': return ui::VKEY_Y;
-    case 'z': return ui::VKEY_Z;
-
-    case ')': *shifted = true; case '0': return ui::VKEY_0;
-    case '!': *shifted = true; case '1': return ui::VKEY_1;
-    case '@': *shifted = true; case '2': return ui::VKEY_2;
-    case '#': *shifted = true; case '3': return ui::VKEY_3;
-    case '$': *shifted = true; case '4': return ui::VKEY_4;
-    case '%': *shifted = true; case '5': return ui::VKEY_5;
-    case '^': *shifted = true; case '6': return ui::VKEY_6;
-    case '&': *shifted = true; case '7': return ui::VKEY_7;
-    case '*': *shifted = true; case '8': return ui::VKEY_8;
-    case '(': *shifted = true; case '9': return ui::VKEY_9;
-
-    case ':': *shifted = true; case ';': return ui::VKEY_OEM_1;
-    case '+': *shifted = true; case '=': return ui::VKEY_OEM_PLUS;
-    case '<': *shifted = true; case ',': return ui::VKEY_OEM_COMMA;
-    case '_': *shifted = true; case '-': return ui::VKEY_OEM_MINUS;
-    case '>': *shifted = true; case '.': return ui::VKEY_OEM_PERIOD;
-    case '?': *shifted = true; case '/': return ui::VKEY_OEM_2;
-    case '~': *shifted = true; case '`': return ui::VKEY_OEM_3;
-    case '{': *shifted = true; case '[': return ui::VKEY_OEM_4;
-    case '|': *shifted = true; case '\\': return ui::VKEY_OEM_5;
-    case '}': *shifted = true; case ']': return ui::VKEY_OEM_6;
-    case '"': *shifted = true; case '\'': return ui::VKEY_OEM_7;
-
-    default: return ui::VKEY_UNKNOWN;
-  }
-}
-
-}  // namespace
-
 bool StringToAccelerator(const std::string& description,
                          ui::Accelerator* accelerator) {
   if (!base::IsStringASCII(description)) {
@@ -104,7 +37,7 @@ bool StringToAccelerator(const std::string& description,
     // to be correct and usually only uses few special tokens.
     if (tokens[i].size() == 1) {
       bool shifted = false;
-      key = KeyboardCodeFromCharCode(tokens[i][0], &shifted);
+      key = atom::KeyboardCodeFromCharCode(tokens[i][0], &shifted);
       if (shifted)
         modifiers |= ui::EF_SHIFT_DOWN;
     } else if (tokens[i] == "ctrl" || tokens[i] == "control") {
index 8d71e91..deb0958 100644 (file)
@@ -6,8 +6,8 @@
 #define ATOM_VERSION_H
 
 #define ATOM_MAJOR_VERSION 0
-#define ATOM_MINOR_VERSION 32
-#define ATOM_PATCH_VERSION 3
+#define ATOM_MINOR_VERSION 33
+#define ATOM_PATCH_VERSION 0
 
 #define ATOM_VERSION_IS_RELEASE 1
 
diff --git a/atom/common/keyboad_util.cc b/atom/common/keyboad_util.cc
new file mode 100644 (file)
index 0000000..1baa829
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/common/keyboad_util.h"
+
+namespace atom {
+
+// Return key code of the char.
+ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) {
+  *shifted = false;
+  switch (c) {
+    case 8: case 0x7F: return ui::VKEY_BACK;
+    case 9: return ui::VKEY_TAB;
+    case 0xD: case 3: return ui::VKEY_RETURN;
+    case 0x1B: return ui::VKEY_ESCAPE;
+    case ' ': return ui::VKEY_SPACE;
+
+    case 'a': return ui::VKEY_A;
+    case 'b': return ui::VKEY_B;
+    case 'c': return ui::VKEY_C;
+    case 'd': return ui::VKEY_D;
+    case 'e': return ui::VKEY_E;
+    case 'f': return ui::VKEY_F;
+    case 'g': return ui::VKEY_G;
+    case 'h': return ui::VKEY_H;
+    case 'i': return ui::VKEY_I;
+    case 'j': return ui::VKEY_J;
+    case 'k': return ui::VKEY_K;
+    case 'l': return ui::VKEY_L;
+    case 'm': return ui::VKEY_M;
+    case 'n': return ui::VKEY_N;
+    case 'o': return ui::VKEY_O;
+    case 'p': return ui::VKEY_P;
+    case 'q': return ui::VKEY_Q;
+    case 'r': return ui::VKEY_R;
+    case 's': return ui::VKEY_S;
+    case 't': return ui::VKEY_T;
+    case 'u': return ui::VKEY_U;
+    case 'v': return ui::VKEY_V;
+    case 'w': return ui::VKEY_W;
+    case 'x': return ui::VKEY_X;
+    case 'y': return ui::VKEY_Y;
+    case 'z': return ui::VKEY_Z;
+
+    case ')': *shifted = true; case '0': return ui::VKEY_0;
+    case '!': *shifted = true; case '1': return ui::VKEY_1;
+    case '@': *shifted = true; case '2': return ui::VKEY_2;
+    case '#': *shifted = true; case '3': return ui::VKEY_3;
+    case '$': *shifted = true; case '4': return ui::VKEY_4;
+    case '%': *shifted = true; case '5': return ui::VKEY_5;
+    case '^': *shifted = true; case '6': return ui::VKEY_6;
+    case '&': *shifted = true; case '7': return ui::VKEY_7;
+    case '*': *shifted = true; case '8': return ui::VKEY_8;
+    case '(': *shifted = true; case '9': return ui::VKEY_9;
+
+    case ':': *shifted = true; case ';': return ui::VKEY_OEM_1;
+    case '+': *shifted = true; case '=': return ui::VKEY_OEM_PLUS;
+    case '<': *shifted = true; case ',': return ui::VKEY_OEM_COMMA;
+    case '_': *shifted = true; case '-': return ui::VKEY_OEM_MINUS;
+    case '>': *shifted = true; case '.': return ui::VKEY_OEM_PERIOD;
+    case '?': *shifted = true; case '/': return ui::VKEY_OEM_2;
+    case '~': *shifted = true; case '`': return ui::VKEY_OEM_3;
+    case '{': *shifted = true; case '[': return ui::VKEY_OEM_4;
+    case '|': *shifted = true; case '\\': return ui::VKEY_OEM_5;
+    case '}': *shifted = true; case ']': return ui::VKEY_OEM_6;
+    case '"': *shifted = true; case '\'': return ui::VKEY_OEM_7;
+
+    default: return ui::VKEY_UNKNOWN;
+  }
+}
+
+}  // namespace atom
diff --git a/atom/common/keyboad_util.h b/atom/common/keyboad_util.h
new file mode 100644 (file)
index 0000000..0496886
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_COMMON_KEYBOAD_UTIL_H_
+#define ATOM_COMMON_KEYBOAD_UTIL_H_
+
+#include "ui/events/keycodes/keyboard_codes.h"
+
+namespace atom {
+
+// Return key code of the char, and also determine whether the SHIFT key is
+// pressed.
+ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted);
+
+}  // namespace atom
+
+#endif  // ATOM_COMMON_KEYBOAD_UTIL_H_
diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc
new file mode 100644 (file)
index 0000000..67c7e7e
--- /dev/null
@@ -0,0 +1,258 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/common/native_mate_converters/blink_converter.h"
+
+#include <string>
+#include <vector>
+
+#include "atom/common/keyboad_util.h"
+#include "base/strings/string_util.h"
+#include "content/public/browser/native_web_keyboard_event.h"
+#include "native_mate/dictionary.h"
+#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+
+namespace {
+
+template<typename T>
+int VectorToBitArray(const std::vector<T>& vec) {
+  int bits = 0;
+  for (const T& item : vec)
+    bits |= item;
+  return bits;
+}
+
+}  // namespace
+
+namespace mate {
+
+template<>
+struct Converter<char> {
+  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
+                     char* out) {
+    std::string code = base::StringToLowerASCII(V8ToString(val));
+    if (code.length() != 1)
+      return false;
+    *out = code[0];
+    return true;
+  }
+};
+
+template<>
+struct Converter<blink::WebInputEvent::Type> {
+  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
+                     blink::WebInputEvent::Type* out) {
+    std::string type = base::StringToLowerASCII(V8ToString(val));
+    if (type == "mousedown")
+      *out = blink::WebInputEvent::MouseDown;
+    else if (type == "mouseup")
+      *out = blink::WebInputEvent::MouseUp;
+    else if (type == "mousemove")
+      *out = blink::WebInputEvent::MouseMove;
+    else if (type == "mouseenter")
+      *out = blink::WebInputEvent::MouseEnter;
+    else if (type == "mouseleave")
+      *out = blink::WebInputEvent::MouseLeave;
+    else if (type == "contextmenu")
+      *out = blink::WebInputEvent::ContextMenu;
+    else if (type == "mousewheel")
+      *out = blink::WebInputEvent::MouseWheel;
+    else if (type == "keydown")
+      *out = blink::WebInputEvent::KeyDown;
+    else if (type == "keyup")
+      *out = blink::WebInputEvent::KeyUp;
+    else if (type == "char")
+      *out = blink::WebInputEvent::Char;
+    else if (type == "touchstart")
+      *out = blink::WebInputEvent::TouchStart;
+    else if (type == "touchmove")
+      *out = blink::WebInputEvent::TouchMove;
+    else if (type == "touchend")
+      *out = blink::WebInputEvent::TouchEnd;
+    else if (type == "touchcancel")
+      *out = blink::WebInputEvent::TouchCancel;
+    return true;
+  }
+};
+
+template<>
+struct Converter<blink::WebInputEvent::Modifiers> {
+  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
+                     blink::WebInputEvent::Modifiers* out) {
+    std::string modifier = base::StringToLowerASCII(V8ToString(val));
+    if (modifier == "shift")
+      *out = blink::WebInputEvent::ShiftKey;
+    else if (modifier == "control" || modifier == "ctrl")
+      *out = blink::WebInputEvent::ControlKey;
+    else if (modifier == "alt")
+      *out = blink::WebInputEvent::AltKey;
+    else if (modifier == "meta" || modifier == "command" || modifier == "cmd")
+      *out = blink::WebInputEvent::MetaKey;
+    else if (modifier == "iskeypad")
+      *out = blink::WebInputEvent::IsKeyPad;
+    else if (modifier == "isautorepeat")
+      *out = blink::WebInputEvent::IsAutoRepeat;
+    else if (modifier == "leftbuttondown")
+      *out = blink::WebInputEvent::LeftButtonDown;
+    else if (modifier == "middlebuttondown")
+      *out = blink::WebInputEvent::MiddleButtonDown;
+    else if (modifier == "rightbuttondown")
+      *out = blink::WebInputEvent::RightButtonDown;
+    else if (modifier == "capslock")
+      *out = blink::WebInputEvent::CapsLockOn;
+    else if (modifier == "numlock")
+      *out = blink::WebInputEvent::NumLockOn;
+    else if (modifier == "left")
+      *out = blink::WebInputEvent::IsLeft;
+    else if (modifier == "right")
+      *out = blink::WebInputEvent::IsRight;
+    return true;
+  }
+};
+
+int GetWebInputEventType(v8::Isolate* isolate, v8::Local<v8::Value> val) {
+  blink::WebInputEvent::Type type = blink::WebInputEvent::Undefined;
+  mate::Dictionary dict;
+  ConvertFromV8(isolate, val, &dict) && dict.Get("type", &type);
+  return type;
+}
+
+bool Converter<blink::WebInputEvent>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val,
+    blink::WebInputEvent* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  if (!dict.Get("type", &out->type))
+    return false;
+  std::vector<blink::WebInputEvent::Modifiers> modifiers;
+  if (dict.Get("modifiers", &modifiers))
+    out->modifiers = VectorToBitArray(modifiers);
+  out->timeStampSeconds = base::Time::Now().ToDoubleT();
+  return true;
+}
+
+bool Converter<blink::WebKeyboardEvent>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val,
+    blink::WebKeyboardEvent* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
+    return false;
+  char code;
+  if (!dict.Get("keyCode", &code))
+    return false;
+  bool shifted = false;
+  out->windowsKeyCode = atom::KeyboardCodeFromCharCode(code, &shifted);
+  if (out->windowsKeyCode == ui::VKEY_UNKNOWN)
+    return false;
+  if (shifted)
+    out->modifiers |= blink::WebInputEvent::ShiftKey;
+  out->setKeyIdentifierFromWindowsKeyCode();
+  return true;
+}
+
+bool Converter<content::NativeWebKeyboardEvent>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val,
+    content::NativeWebKeyboardEvent* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  if (!ConvertFromV8(isolate, val, static_cast<blink::WebKeyboardEvent*>(out)))
+    return false;
+  dict.Get("skipInBrowser", &out->skip_in_browser);
+  return true;
+}
+
+bool Converter<blink::WebMouseEvent>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val, blink::WebMouseEvent* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  if (!ConvertFromV8(isolate, val, static_cast<blink::WebInputEvent*>(out)))
+    return false;
+  if (!dict.Get("x", &out->x) || !dict.Get("y", &out->y))
+    return false;
+  dict.Get("globalX", &out->globalX);
+  dict.Get("globalY", &out->globalY);
+  dict.Get("movementX", &out->movementX);
+  dict.Get("movementY", &out->movementY);
+  dict.Get("clickCount", &out->clickCount);
+  return true;
+}
+
+bool Converter<blink::WebMouseWheelEvent>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val,
+    blink::WebMouseWheelEvent* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  if (!ConvertFromV8(isolate, val, static_cast<blink::WebMouseEvent*>(out)))
+    return false;
+  dict.Get("deltaX", &out->deltaX);
+  dict.Get("deltaY", &out->deltaY);
+  dict.Get("wheelTicksX", &out->wheelTicksX);
+  dict.Get("wheelTicksY", &out->wheelTicksY);
+  dict.Get("accelerationRatioX", &out->accelerationRatioX);
+  dict.Get("accelerationRatioY", &out->accelerationRatioY);
+  dict.Get("hasPreciseScrollingDeltas", &out->hasPreciseScrollingDeltas);
+  dict.Get("canScroll", &out->canScroll);
+  return true;
+}
+
+bool Converter<blink::WebFloatPoint>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val, blink::WebFloatPoint* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  return dict.Get("x", &out->x) && dict.Get("y", &out->y);
+}
+
+bool Converter<blink::WebPoint>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val, blink::WebPoint* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  return dict.Get("x", &out->x) && dict.Get("y", &out->y);
+}
+
+bool Converter<blink::WebSize>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val, blink::WebSize* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+  return dict.Get("width", &out->width) && dict.Get("height", &out->height);
+}
+
+bool Converter<blink::WebDeviceEmulationParams>::FromV8(
+    v8::Isolate* isolate, v8::Local<v8::Value> val,
+    blink::WebDeviceEmulationParams* out) {
+  mate::Dictionary dict;
+  if (!ConvertFromV8(isolate, val, &dict))
+    return false;
+
+  std::string screen_position;
+  if (dict.Get("screenPosition", &screen_position)) {
+    screen_position = base::StringToLowerASCII(screen_position);
+    if (screen_position == "mobile")
+      out->screenPosition = blink::WebDeviceEmulationParams::Mobile;
+    else if (screen_position == "desktop")
+      out->screenPosition = blink::WebDeviceEmulationParams::Desktop;
+    else
+      return false;
+  }
+
+  dict.Get("screenSize", &out->screenSize);
+  dict.Get("viewPosition", &out->viewPosition);
+  dict.Get("deviceScaleFactor", &out->deviceScaleFactor);
+  dict.Get("viewSize", &out->viewSize);
+  dict.Get("fitToView", &out->fitToView);
+  dict.Get("offset", &out->offset);
+  dict.Get("scale", &out->scale);
+  return true;
+}
+
+}  // namespace mate
diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h
new file mode 100644 (file)
index 0000000..17bb108
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2015 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
+#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
+
+#include "native_mate/converter.h"
+
+namespace blink {
+class WebInputEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+class WebKeyboardEvent;
+struct WebDeviceEmulationParams;
+struct WebFloatPoint;
+struct WebPoint;
+struct WebSize;
+}
+
+namespace content {
+struct NativeWebKeyboardEvent;
+}
+
+namespace mate {
+
+int GetWebInputEventType(v8::Isolate* isolate, v8::Local<v8::Value> val);
+
+template<>
+struct Converter<blink::WebInputEvent> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebInputEvent* out);
+};
+
+template<>
+struct Converter<blink::WebKeyboardEvent> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebKeyboardEvent* out);
+};
+
+template<>
+struct Converter<content::NativeWebKeyboardEvent> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     content::NativeWebKeyboardEvent* out);
+};
+
+template<>
+struct Converter<blink::WebMouseEvent> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebMouseEvent* out);
+};
+
+template<>
+struct Converter<blink::WebMouseWheelEvent> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebMouseWheelEvent* out);
+};
+
+template<>
+struct Converter<blink::WebFloatPoint> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebFloatPoint* out);
+};
+
+template<>
+struct Converter<blink::WebPoint> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebPoint* out);
+};
+
+template<>
+struct Converter<blink::WebSize> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebSize* out);
+};
+
+template<>
+struct Converter<blink::WebDeviceEmulationParams> {
+  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val,
+                     blink::WebDeviceEmulationParams* out);
+};
+
+}  // namespace mate
+
+#endif  // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
index f5bcf04..65e4501 100644 (file)
@@ -292,6 +292,7 @@ registerWebViewElement = ->
     "inspectServiceWorker"
     "print"
     "printToPDF"
+    "sendInputEvent"
   ]
 
   # Forward proto.foo* method calls to WebViewImpl.foo*.
index 29171a2..f1705c2 100644 (file)
@@ -244,7 +244,7 @@ Emitted when DevTools is closed.
 
 Emitted when DevTools is focused / opened.
 
-### Event: 'app-command' _Windows_
+### Event: 'app-command':
 
 Emitted when an [App Command](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275(v=vs.85).aspx)
 is invoked. These are typically related to keyboard media keys or browser
index 1c5c831..55893c6 100644 (file)
@@ -79,7 +79,7 @@ exports.withLocalCallback = function() {
 
 ```javascript
 // renderer process
-var mapNumbers = require("remote").require("mapNumbers");
+var mapNumbers = require("remote").require("./mapNumbers");
 
 var withRendererCb = mapNumbers.withRendererCallback(function(x) {
   return x + 1;
index 92d91d1..e8f72cd 100644 (file)
@@ -476,3 +476,92 @@ 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`.
+
+### `webContents.sendInputEvent(event)`
+
+* `event` Object
+  * `type` String (**required**) - The type of the event, can be `mouseDown`,
+    `mouseUp`, `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`,
+    `keyDown`, `keyUp`, `char`.
+  * `modifiers` Array - An array of modifiers of the event, can
+    include `shift`, `control`, `alt`, `meta`, `isKeypad`, `isAutoRepeat`,
+    `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, `capsLock`,
+    `numLock`, `left`, `right`.
+
+Sends an input `event` to the page.
+
+For keyboard events, the `event` object also have following properties:
+
+* `keyCode` String (**required**) - A single character that will be sent as
+  keyboard event. Can be any ASCII character on the keyboard, like `a`, `1`
+  and `=`.
+
+For mouse events, the `event` object also have following properties:
+
+* `x` Integer (**required**)
+* `y` Integer (**required**)
+* `globalX` Integer
+* `globalY` Integer
+* `movementX` Integer
+* `movementY` Integer
+* `clickCount` Integer
+
+For the `mouseWheel` event, the `event` object also have following properties:
+
+* `deltaX` Integer
+* `deltaY` Integer
+* `wheelTicksX` Integer
+* `wheelTicksY` Integer
+* `accelerationRatioX` Integer
+* `accelerationRatioY` Integer
+* `hasPreciseScrollingDeltas` Boolean
+* `canScroll` Boolean
+
+### `webContents.beginFrameSubscription(callback)`
+
+* `callback` Function
+
+Begin subscribing for presentation events and captured frames, the `callback`
+will be called with `callback(frameBuffer)` when there is a presentation event.
+
+The `frameBuffer` is a `Buffer` that contains raw pixel data, in the format of
+32bit ARGB.
+
+### `webContents.endFrameSubscription()`
+
+End subscribing for frame presentation events.
index 4647413..8eb3857 100644 (file)
@@ -358,6 +358,15 @@ page can handle it by listening to the `channel` event of `ipc` module.
 See [WebContents.send](web-contents.md#webcontentssendchannel-args) for
 examples.
 
+### `<webview>.sendInputEvent(event)`
+
+* `event` Object
+
+Sends an input `event` to the page.
+
+See [WebContents.sendInputEvent](web-contents.md##webcontentssendinputeventevent)
+for detailed description of `event` object.
+
 ## DOM events
 
 The following DOM events are available to the `webview` tag:
index 461c812..99d6bc6 100644 (file)
       'atom/browser/api/event_emitter.h',
       'atom/browser/api/trackable_object.cc',
       'atom/browser/api/trackable_object.h',
+      'atom/browser/api/frame_subscriber.cc',
+      'atom/browser/api/frame_subscriber.h',
       'atom/browser/auto_updater.cc',
       'atom/browser/auto_updater.h',
       'atom/browser/auto_updater_delegate.h',
       'atom/common/google_api_key.h',
       'atom/common/id_weak_map.cc',
       'atom/common/id_weak_map.h',
+      'atom/common/keyboad_util.cc',
+      'atom/common/keyboad_util.h',
       'atom/common/linux/application_info.cc',
       'atom/common/native_mate_converters/accelerator_converter.cc',
       'atom/common/native_mate_converters/accelerator_converter.h',
+      'atom/common/native_mate_converters/blink_converter.cc',
+      'atom/common/native_mate_converters/blink_converter.h',
       'atom/common/native_mate_converters/callback.h',
       'atom/common/native_mate_converters/file_path_converter.h',
       'atom/common/native_mate_converters/gfx_converter.cc',
index c978641..ca7e216 100755 (executable)
@@ -126,6 +126,8 @@ def copy_chrome_binary(binary):
 
 
 def copy_license():
+  shutil.copy2(os.path.join(CHROMIUM_DIR, '..', 'LICENSES.chromium.html'),
+               DIST_DIR)
   shutil.copy2(os.path.join(SOURCE_ROOT, 'LICENSE'), DIST_DIR)
 
 
index 3e4e2d5..64e6271 100644 (file)
@@ -295,11 +295,22 @@ describe 'browser-window module', ->
       w.minimize()
 
   describe 'will-navigate event', ->
-    return if isCI and process.platform is 'darwin'
+    @timeout 10000
     it 'emits when user starts a navigation', (done) ->
-      @timeout 10000
-      w.webContents.on 'will-navigate', (event, url) ->
+      url = "file://#{fixtures}/pages/will-navigate.html"
+      w.webContents.on 'will-navigate', (event, u) ->
         event.preventDefault()
-        assert.equal url, 'https://www.github.com/'
+        assert.equal u, url
+        done()
+      w.loadUrl url
+
+  describe 'beginFrameSubscription method', ->
+    it 'subscribes frame updates', (done) ->
+      called = false
+      w.loadUrl "file://#{fixtures}/api/blank.html"
+      w.webContents.beginFrameSubscription (data) ->
+        return if called
+        called = true
+        assert.notEqual data.length, 0
+        w.webContents.endFrameSubscription()
         done()
-      w.loadUrl "file://#{fixtures}/pages/will-navigate.html"
diff --git a/spec/fixtures/module/set-immediate.js b/spec/fixtures/module/set-immediate.js
new file mode 100644 (file)
index 0000000..e7d44a7
--- /dev/null
@@ -0,0 +1,11 @@
+process.on('uncaughtException', function(error) {
+  process.send(error.message);
+  process.exit(1);
+});
+
+process.on('message', function(msg) {
+  setImmediate(function() {
+    process.send('ok');
+    process.exit(0);
+  });
+});
diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html
new file mode 100644 (file)
index 0000000..99e6c3e
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<body>
+<script type="text/javascript" charset="utf-8">
+document.onkeyup = function(e) {
+  require('ipc').sendToHost('keyup', e.keyCode, e.shiftKey, e.ctrlKey);
+}
+</script>
+</body>
+</html>
diff --git a/spec/fixtures/pages/onmouseup.html b/spec/fixtures/pages/onmouseup.html
new file mode 100644 (file)
index 0000000..1fd38bc
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<body>
+<script type="text/javascript" charset="utf-8">
+document.onmouseup = function(e) {
+  require('ipc').sendToHost('mouseup', e.x, e.y, e.shiftKey, e.ctrlKey);
+}
+</script>
+</body>
+</html>
index bd2ebdc..8d0c9b7 100644 (file)
@@ -1,7 +1,7 @@
 <html>
 <body>
 <script type="text/javascript" charset="utf-8">
-  location = 'https://www.github.com'
+  location.reload();
 </script>
 </body>
 </html>
index 94174c3..c8d569e 100644 (file)
@@ -56,6 +56,13 @@ describe 'node feature', ->
           done()
         child.send 'message'
 
+      it 'has setImmediate working in script', (done) ->
+        child = child_process.fork path.join(fixtures, 'module', 'set-immediate.js')
+        child.on 'message', (msg) ->
+          assert.equal msg, 'ok'
+          done()
+        child.send 'message'
+
   describe 'contexts', ->
     describe 'setTimeout in fs callback', ->
       it 'does not crash', (done) ->
@@ -141,3 +148,7 @@ describe 'node feature', ->
     # Not reliable on some machines
     xit 'should have isTTY defined', ->
       assert.equal typeof(process.stdout.isTTY), 'boolean'
+
+  describe 'vm.createContext', ->
+    it 'should not crash', ->
+      require('vm').runInNewContext('')
index e4b40c2..b310b7b 100644 (file)
@@ -336,3 +336,26 @@ describe '<webview> tag', ->
       webview.addEventListener 'did-finish-load', listener2
       webview.src = "file://#{fixtures}/pages/fullscreen.html"
       document.body.appendChild webview
+
+  describe 'sendInputEvent', ->
+    it 'can send keyboard event', (done) ->
+      webview.addEventListener 'ipc-message', (e) ->
+        assert.equal e.channel, 'keyup'
+        assert.deepEqual e.args, [67, true, false]
+        done()
+      webview.addEventListener 'dom-ready', ->
+        webview.sendInputEvent type: 'keyup', keyCode: 'c', modifiers: ['shift']
+      webview.src = "file://#{fixtures}/pages/onkeyup.html"
+      webview.setAttribute 'nodeintegration', 'on'
+      document.body.appendChild webview
+
+    it 'can send mouse event', (done) ->
+      webview.addEventListener 'ipc-message', (e) ->
+        assert.equal e.channel, 'mouseup'
+        assert.deepEqual e.args, [10, 20, false, true]
+        done()
+      webview.addEventListener 'dom-ready', ->
+        webview.sendInputEvent type: 'mouseup', modifiers: ['ctrl'], x: 10, y: 20
+      webview.src = "file://#{fixtures}/pages/onmouseup.html"
+      webview.setAttribute 'nodeintegration', 'on'
+      document.body.appendChild webview
index d385c9b..25f3a9d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit d385c9b1b88da3ba1b5426861ec7c63e8c884135
+Subproject commit 25f3a9d0a5b73ec170a65f4e2e4c9ad91e23fc8c
index 4098d45..aa9c7a2 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 4098d45fbb822370c19d2fe7b88162759db4eb96
+Subproject commit aa9c7a2316ba7762f1d04d091585695be3e6be22