diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 16a005cd35706..859b1876a1669 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -652,18 +652,36 @@ The following app commands are explicitly supported on Linux: * `browser-backward` * `browser-forward` -#### Event: 'scroll-touch-begin' _macOS_ +#### Event: 'scroll-touch-begin' _macOS_ _Deprecated_ Emitted when scroll wheel event phase has begun. -#### Event: 'scroll-touch-end' _macOS_ +> **Note** +> This event is deprecated beginning in Electron 22.0.0. See [Breaking +> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events) +> for details of how to migrate to using the [WebContents +> `input-event`](api/web-contents.md#event-input-event) event. + +#### Event: 'scroll-touch-end' _macOS_ _Deprecated_ Emitted when scroll wheel event phase has ended. -#### Event: 'scroll-touch-edge' _macOS_ +> **Note** +> This event is deprecated beginning in Electron 22.0.0. See [Breaking +> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events) +> for details of how to migrate to using the [WebContents +> `input-event`](api/web-contents.md#event-input-event) event. + +#### Event: 'scroll-touch-edge' _macOS_ _Deprecated_ Emitted when scroll wheel event phase filed upon reaching the edge of element. +> **Note** +> This event is deprecated beginning in Electron 22.0.0. See [Breaking +> Changes](breaking-changes.md#deprecated-browserwindow-scroll-touch--events) +> for details of how to migrate to using the [WebContents +> `input-event`](api/web-contents.md#event-input-event) event. + #### Event: 'swipe' _macOS_ Returns: diff --git a/docs/api/structures/input-event.md b/docs/api/structures/input-event.md index 21efec36d3e41..a68a9304dfca1 100644 --- a/docs/api/structures/input-event.md +++ b/docs/api/structures/input-event.md @@ -1,5 +1,16 @@ # InputEvent Object +* `type` string - Can be `undefined`, `mouseDown`, `mouseUp`, `mouseMove`, + `mouseEnter`, `mouseLeave`, `contextMenu`, `mouseWheel`, `rawKeyDown`, + `keyDown`, `keyUp`, `char`, `gestureScrollBegin`, `gestureScrollEnd`, + `gestureScrollUpdate`, `gestureFlingStart`, `gestureFlingCancel`, + `gesturePinchBegin`, `gesturePinchEnd`, `gesturePinchUpdate`, + `gestureTapDown`, `gestureShowPress`, `gestureTap`, `gestureTapCancel`, + `gestureShortPress`, `gestureLongPress`, `gestureLongTap`, + `gestureTwoFingerTap`, `gestureTapUnconfirmed`, `gestureDoubleTap`, + `touchStart`, `touchMove`, `touchEnd`, `touchCancel`, `touchScrollStarted`, + `pointerDown`, `pointerUp`, `pointerMove`, `pointerRawUpdate`, + `pointerCancel` or `pointerCausedUaAction`. * `modifiers` string[] (optional) - An array of modifiers of the event, can be `shift`, `control`, `ctrl`, `alt`, `meta`, `command`, `cmd`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`, `middleButtonDown`, `rightButtonDown`, diff --git a/docs/api/structures/keyboard-input-event.md b/docs/api/structures/keyboard-input-event.md index de7bef2d770f6..3f8b4b5e8d3af 100644 --- a/docs/api/structures/keyboard-input-event.md +++ b/docs/api/structures/keyboard-input-event.md @@ -1,6 +1,6 @@ # KeyboardInputEvent Object extends `InputEvent` -* `type` string - The type of the event, can be `keyDown`, `keyUp` or `char`. +* `type` string - The type of the event, can be `rawKeyDown`, `keyDown`, `keyUp` or `char`. * `keyCode` string - The character that will be sent as the keyboard event. Should only use the valid key codes in [Accelerator](../accelerator.md). diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 1f0df82f98420..17084a7c7c30f 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -411,6 +411,16 @@ Emitted when a plugin process has crashed. Emitted when `webContents` is destroyed. +#### Event: 'input-event' + +Returns: + +* `event` Event +* `inputEvent` [InputEvent](structures/input-event.md) + +Emitted when an input event is sent to the WebContents. See +[InputEvent](structures/input-event.md) for details. + #### Event: 'before-input-event' Returns: diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index f7bea50260f1d..03d12a6232b08 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -12,6 +12,32 @@ This document uses the following convention to categorize breaking changes: * **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release. * **Removed:** An API or feature was removed, and is no longer supported by Electron. +## Planned Breaking API Changes (23.0) + +### Removed: BrowserWindow `scroll-touch-*` events + +The deprecated `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` +events on BrowserWindow have been removed. Instead, use the newly available +[`input-event` event](api/web-contents.md#event-input-event) on WebContents. + +```js +// Removed in Electron 23.0 +win.on('scroll-touch-begin', scrollTouchBegin) +win.on('scroll-touch-edge', scrollTouchEdge) +win.on('scroll-touch-end', scrollTouchEnd) + +// Replace with +win.webContents.on('input-event', (_, event) => { + if (event.type === 'gestureScrollBegin') { + scrollTouchBegin() + } else if (event.type === 'gestureScrollUpdate') { + scrollTouchEdge() + } else if (event.type === 'gestureScrollEnd') { + scrollTouchEnd() + } +}) +``` + ## Planned Breaking API Changes (22.0) ### Removed: WebContents `new-window` event @@ -30,6 +56,30 @@ webContents.setWindowOpenHandler((details) => { }) ``` +### Deprecated: BrowserWindow `scroll-touch-*` events + +The `scroll-touch-begin`, `scroll-touch-end` and `scroll-touch-edge` events on +BrowserWindow are deprecated. Instead, use the newly available [`input-event` +event](api/web-contents.md#event-input-event) on WebContents. + +```js +// Deprecated +win.on('scroll-touch-begin', scrollTouchBegin) +win.on('scroll-touch-edge', scrollTouchEdge) +win.on('scroll-touch-end', scrollTouchEnd) + +// Replace with +win.webContents.on('input-event', (_, event) => { + if (event.type === 'gestureScrollBegin') { + scrollTouchBegin() + } else if (event.type === 'gestureScrollUpdate') { + scrollTouchEdge() + } else if (event.type === 'gestureScrollEnd') { + scrollTouchEnd() + } +}) +``` + ## Planned Breaking API Changes (20.0) ### Behavior Changed: V8 Memory Cage enabled diff --git a/lib/browser/api/browser-window.ts b/lib/browser/api/browser-window.ts index 053e09ab63690..605c65e2ff220 100644 --- a/lib/browser/api/browser-window.ts +++ b/lib/browser/api/browser-window.ts @@ -1,5 +1,6 @@ import { BaseWindow, WebContents, Event, BrowserView, TouchBar } from 'electron/main'; import type { BrowserWindow as BWT } from 'electron/main'; +import * as deprecate from '@electron/internal/common/deprecate'; const { BrowserWindow } = process._linkedBinding('electron_browser_window') as { BrowserWindow: typeof BWT }; Object.setPrototypeOf(BrowserWindow.prototype, BaseWindow.prototype); @@ -44,6 +45,28 @@ BrowserWindow.prototype._init = function (this: BWT) { this.on(event as any, visibilityChanged); } + const warn = deprecate.warnOnceMessage('\'scroll-touch-{begin,end,edge}\' are deprecated and will be removed. Please use the WebContents \'input-event\' event instead.'); + this.webContents.on('input-event', (_, e) => { + if (e.type === 'gestureScrollBegin') { + if (this.listenerCount('scroll-touch-begin') !== 0) { + warn(); + this.emit('scroll-touch-edge'); + this.emit('scroll-touch-begin'); + } + } else if (e.type === 'gestureScrollUpdate') { + if (this.listenerCount('scroll-touch-edge') !== 0) { + warn(); + this.emit('scroll-touch-edge'); + } + } else if (e.type === 'gestureScrollEnd') { + if (this.listenerCount('scroll-touch-end') !== 0) { + warn(); + this.emit('scroll-touch-edge'); + this.emit('scroll-touch-end'); + } + } + }); + // Notify the creation of the window. const event = process._linkedBinding('electron_browser_event').createEmpty(); app.emit('browser-window-created', event, this); diff --git a/lib/common/deprecate.ts b/lib/common/deprecate.ts index b9c42c3cc0b9e..dc6d9d0eb9815 100644 --- a/lib/common/deprecate.ts +++ b/lib/common/deprecate.ts @@ -3,10 +3,13 @@ type DeprecationHandler = (message: string) => void; let deprecationHandler: DeprecationHandler | null = null; export function warnOnce (oldName: string, newName?: string) { - let warned = false; - const msg = newName + return warnOnceMessage(newName ? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.` - : `'${oldName}' is deprecated and will be removed.`; + : `'${oldName}' is deprecated and will be removed.`); +} + +export function warnOnceMessage (msg: string) { + let warned = false; return () => { if (!warned && !process.noDeprecation) { warned = true; diff --git a/shell/browser/api/electron_api_base_window.cc b/shell/browser/api/electron_api_base_window.cc index 0a933a048766e..6aa498923e94c 100644 --- a/shell/browser/api/electron_api_base_window.cc +++ b/shell/browser/api/electron_api_base_window.cc @@ -247,14 +247,6 @@ void BaseWindow::OnWindowLeaveFullScreen() { Emit("leave-full-screen"); } -void BaseWindow::OnWindowScrollTouchBegin() { - Emit("scroll-touch-begin"); -} - -void BaseWindow::OnWindowScrollTouchEnd() { - Emit("scroll-touch-end"); -} - void BaseWindow::OnWindowSwipe(const std::string& direction) { Emit("swipe", direction); } diff --git a/shell/browser/api/electron_api_base_window.h b/shell/browser/api/electron_api_base_window.h index 8ec83b0947407..5500006939b91 100644 --- a/shell/browser/api/electron_api_base_window.h +++ b/shell/browser/api/electron_api_base_window.h @@ -68,8 +68,6 @@ class BaseWindow : public gin_helper::TrackableObject, bool* prevent_default) override; void OnWindowMove() override; void OnWindowMoved() override; - void OnWindowScrollTouchBegin() override; - void OnWindowScrollTouchEnd() override; void OnWindowSwipe(const std::string& direction) override; void OnWindowRotateGesture(float rotation) override; void OnWindowSheetBegin() override; diff --git a/shell/browser/api/electron_api_browser_window.cc b/shell/browser/api/electron_api_browser_window.cc index 422512af1e957..ea30dba67fd7d 100644 --- a/shell/browser/api/electron_api_browser_window.cc +++ b/shell/browser/api/electron_api_browser_window.cc @@ -106,10 +106,6 @@ BrowserWindow::BrowserWindow(gin::Arguments* args, // Associate with BrowserWindow. web_contents->SetOwnerWindow(window()); - auto* host = web_contents->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->AddInputEventObserver(this); - InitWithArgs(args); // Install the content view after BaseWindow's JS code is initialized. @@ -128,9 +124,6 @@ BrowserWindow::~BrowserWindow() { if (api_web_contents_) { // Cleanup the observers if user destroyed this instance directly instead of // gracefully closing content::WebContents. - auto* host = web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->RemoveInputEventObserver(this); api_web_contents_->RemoveObserver(this); // Destroy the WebContents. OnCloseContents(); @@ -138,26 +131,6 @@ BrowserWindow::~BrowserWindow() { } } -void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) { - switch (event.GetType()) { - case blink::WebInputEvent::Type::kGestureScrollBegin: - case blink::WebInputEvent::Type::kGestureScrollUpdate: - case blink::WebInputEvent::Type::kGestureScrollEnd: - Emit("scroll-touch-edge"); - break; - default: - break; - } -} - -void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host, - content::RenderViewHost* new_host) { - if (old_host) - old_host->GetWidget()->RemoveInputEventObserver(this); - if (new_host) - new_host->GetWidget()->AddInputEventObserver(this); -} - void BrowserWindow::BeforeUnloadDialogCancelled() { WindowList::WindowCloseCancelled(window()); // Cancel unresponsive event when window close is cancelled. diff --git a/shell/browser/api/electron_api_browser_window.h b/shell/browser/api/electron_api_browser_window.h index 94a21f813dfbb..83ea70bbb59f9 100644 --- a/shell/browser/api/electron_api_browser_window.h +++ b/shell/browser/api/electron_api_browser_window.h @@ -17,7 +17,6 @@ namespace electron::api { class BrowserWindow : public BaseWindow, - public content::RenderWidgetHost::InputEventObserver, public content::WebContentsObserver, public ExtendedWebContentsObserver { public: @@ -43,12 +42,7 @@ class BrowserWindow : public BaseWindow, BrowserWindow(gin::Arguments* args, const gin_helper::Dictionary& options); ~BrowserWindow() override; - // content::RenderWidgetHost::InputEventObserver: - void OnInputEvent(const blink::WebInputEvent& event) override; - // content::WebContentsObserver: - void RenderViewHostChanged(content::RenderViewHost* old_host, - content::RenderViewHost* new_host) override; void BeforeUnloadDialogCancelled() override; void OnRendererUnresponsive(content::RenderProcessHost*) override; void OnRendererResponsive( diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 3349fb7a2d3bc..a5c9a93c0f125 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -820,6 +820,12 @@ void WebContents::InitZoomController(content::WebContents* web_contents, double zoom_factor; if (options.Get(options::kZoomFactor, &zoom_factor)) zoom_controller_->SetDefaultZoomFactor(zoom_factor); + + // Nothing to do with ZoomController, but this function gets called in all + // init cases! + content::RenderViewHost* host = web_contents->GetRenderViewHost(); + if (host) + host->GetWidget()->AddInputEventObserver(this); } void WebContents::InitWithSessionAndOptions( @@ -957,6 +963,12 @@ void WebContents::InitWithWebContents( } WebContents::~WebContents() { + if (web_contents()) { + content::RenderViewHost* host = web_contents()->GetRenderViewHost(); + if (host) + host->GetWidget()->RemoveInputEventObserver(this); + } + if (!inspectable_web_contents_) { WebContentsDestroyed(); return; @@ -1273,7 +1285,12 @@ content::KeyboardEventProcessingResult WebContents::PreHandleKeyboardEvent( if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown || event.GetType() == blink::WebInputEvent::Type::kKeyUp) { - bool prevent_default = Emit("before-input-event", event); + // For backwards compatibility, pretend that `kRawKeyDown` events are + // actually `kKeyDown`. + content::NativeWebKeyboardEvent tweaked_event(event); + if (event.GetType() == blink::WebInputEvent::Type::kRawKeyDown) + tweaked_event.SetType(blink::WebInputEvent::Type::kKeyDown); + bool prevent_default = Emit("before-input-event", tweaked_event); if (prevent_default) { return content::KeyboardEventProcessingResult::HANDLED; } @@ -1684,6 +1701,14 @@ void WebContents::OnWebContentsLostFocus( Emit("blur"); } +void WebContents::RenderViewHostChanged(content::RenderViewHost* old_host, + content::RenderViewHost* new_host) { + if (old_host) + old_host->GetWidget()->RemoveInputEventObserver(this); + if (new_host) + new_host->GetWidget()->AddInputEventObserver(this); +} + void WebContents::DOMContentLoaded( content::RenderFrameHost* render_frame_host) { auto* web_frame = WebFrameMain::FromRenderFrameHost(render_frame_host); @@ -3060,6 +3085,9 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, blink::WebKeyboardEvent::Type::kRawKeyDown, blink::WebInputEvent::Modifiers::kNoModifiers, ui::EventTimeForNow()); if (gin::ConvertFromV8(isolate, input_event, &keyboard_event)) { + // For backwards compatibility, convert `kKeyDown` to `kRawKeyDown`. + if (keyboard_event.GetType() == blink::WebKeyboardEvent::Type::kKeyDown) + keyboard_event.SetType(blink::WebKeyboardEvent::Type::kRawKeyDown); rwh->ForwardKeyboardEvent(keyboard_event); return; } @@ -3466,6 +3494,10 @@ void WebContents::SetImageAnimationPolicy(const std::string& new_policy) { web_contents()->OnWebPreferencesChanged(); } +void WebContents::OnInputEvent(const blink::WebInputEvent& event) { + Emit("input-event", event); +} + v8::Local WebContents::GetProcessMemoryInfo(v8::Isolate* isolate) { gin_helper::Promise promise(isolate); v8::Local handle = promise.GetHandle(); diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index 6aeb8b9375a28..79f1182672a00 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -103,6 +103,7 @@ class WebContents : public ExclusiveAccessContext, public gin_helper::CleanedUpAtExit, public content::WebContentsObserver, public content::WebContentsDelegate, + public content::RenderWidgetHost::InputEventObserver, public InspectableWebContentsDelegate, public InspectableWebContentsViewDelegate { public: @@ -433,6 +434,9 @@ class WebContents : public ExclusiveAccessContext, void SetImageAnimationPolicy(const std::string& new_policy); + // content::RenderWidgetHost::InputEventObserver: + void OnInputEvent(const blink::WebInputEvent& event) override; + // disable copy WebContents(const WebContents&) = delete; WebContents& operator=(const WebContents&) = delete; @@ -616,6 +620,8 @@ class WebContents : public ExclusiveAccessContext, content::RenderWidgetHost* render_widget_host) override; void OnWebContentsLostFocus( content::RenderWidgetHost* render_widget_host) override; + void RenderViewHostChanged(content::RenderViewHost* old_host, + content::RenderViewHost* new_host) override; // InspectableWebContentsDelegate: void DevToolsReloadPage() override; diff --git a/shell/browser/native_window.cc b/shell/browser/native_window.cc index 2440658ba11e8..37aff64f5726e 100755 --- a/shell/browser/native_window.cc +++ b/shell/browser/native_window.cc @@ -603,16 +603,6 @@ void NativeWindow::NotifyWindowEnterFullScreen() { observer.OnWindowEnterFullScreen(); } -void NativeWindow::NotifyWindowScrollTouchBegin() { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowScrollTouchBegin(); -} - -void NativeWindow::NotifyWindowScrollTouchEnd() { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowScrollTouchEnd(); -} - void NativeWindow::NotifyWindowSwipe(const std::string& direction) { for (NativeWindowObserver& observer : observers_) observer.OnWindowSwipe(direction); diff --git a/shell/browser/native_window.h b/shell/browser/native_window.h index 6568f03127bf3..e81da9619ee90 100644 --- a/shell/browser/native_window.h +++ b/shell/browser/native_window.h @@ -291,8 +291,6 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowResized(); void NotifyWindowWillMove(const gfx::Rect& new_bounds, bool* prevent_default); void NotifyWindowMoved(); - void NotifyWindowScrollTouchBegin(); - void NotifyWindowScrollTouchEnd(); void NotifyWindowSwipe(const std::string& direction); void NotifyWindowRotateGesture(float rotation); void NotifyWindowSheetBegin(); diff --git a/shell/browser/native_window_mac.h b/shell/browser/native_window_mac.h index ef5ab1b10e12b..390c2997b2211 100644 --- a/shell/browser/native_window_mac.h +++ b/shell/browser/native_window_mac.h @@ -228,9 +228,6 @@ class NativeWindowMac : public NativeWindow, base::scoped_nsobject preview_item_; base::scoped_nsobject touch_bar_; - // Event monitor for scroll wheel event. - id wheel_event_monitor_; - // The NSView that used as contentView of window. // // For frameless window it would fill the whole window. diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm index 2bb5e3a4c5064..e66745a547b70 100644 --- a/shell/browser/native_window_mac.mm +++ b/shell/browser/native_window_mac.mm @@ -418,32 +418,6 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { options.Get(options::kDisableAutoHideCursor, &disableAutoHideCursor); [window_ setDisableAutoHideCursor:disableAutoHideCursor]; - // Use an NSEvent monitor to listen for the wheel event. - BOOL __block began = NO; - wheel_event_monitor_ = [NSEvent - addLocalMonitorForEventsMatchingMask:NSEventMaskScrollWheel - handler:^(NSEvent* event) { - if ([[event window] windowNumber] != - [window_ windowNumber]) - return event; - - if (!began && (([event phase] == - NSEventPhaseMayBegin) || - ([event phase] == - NSEventPhaseBegan))) { - this->NotifyWindowScrollTouchBegin(); - began = YES; - } else if (began && - (([event phase] == - NSEventPhaseEnded) || - ([event phase] == - NSEventPhaseCancelled))) { - this->NotifyWindowScrollTouchEnd(); - began = NO; - } - return event; - }]; - // Set maximizable state last to ensure zoom button does not get reset // by calls to other APIs. SetMaximizable(maximizable); @@ -1725,10 +1699,6 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { DCHECK(!IsClosed()); ui::NativeTheme::GetInstanceForNativeUi()->RemoveObserver(this); display::Screen::GetScreen()->RemoveObserver(this); - if (wheel_event_monitor_) { - [NSEvent removeMonitor:wheel_event_monitor_]; - wheel_event_monitor_ = nil; - } } void NativeWindowMac::OverrideNSWindowContentView() { diff --git a/shell/browser/native_window_observer.h b/shell/browser/native_window_observer.h index 6cbc941450642..2c24406375b4a 100644 --- a/shell/browser/native_window_observer.h +++ b/shell/browser/native_window_observer.h @@ -81,8 +81,6 @@ class NativeWindowObserver : public base::CheckedObserver { bool* prevent_default) {} virtual void OnWindowMove() {} virtual void OnWindowMoved() {} - virtual void OnWindowScrollTouchBegin() {} - virtual void OnWindowScrollTouchEnd() {} virtual void OnWindowSwipe(const std::string& direction) {} virtual void OnWindowRotateGesture(float rotation) {} virtual void OnWindowSheetBegin() {} diff --git a/shell/common/gin_converters/blink_converter.cc b/shell/common/gin_converters/blink_converter.cc index 68ba0307dc004..bda0113c05cd3 100644 --- a/shell/common/gin_converters/blink_converter.cc +++ b/shell/common/gin_converters/blink_converter.cc @@ -11,6 +11,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "gin/converter.h" +#include "gin/data_object_builder.h" #include "shell/common/gin_converters/gfx_converter.h" #include "shell/common/gin_converters/gurl_converter.h" #include "shell/common/gin_converters/value_converter.h" @@ -56,43 +57,73 @@ struct Converter { } }; -template <> -struct Converter { - static bool FromV8(v8::Isolate* isolate, - v8::Handle val, - blink::WebInputEvent::Type* out) { - std::string type = base::ToLowerASCII(gin::V8ToString(isolate, val)); - if (type == "mousedown") - *out = blink::WebInputEvent::Type::kMouseDown; - else if (type == "mouseup") - *out = blink::WebInputEvent::Type::kMouseUp; - else if (type == "mousemove") - *out = blink::WebInputEvent::Type::kMouseMove; - else if (type == "mouseenter") - *out = blink::WebInputEvent::Type::kMouseEnter; - else if (type == "mouseleave") - *out = blink::WebInputEvent::Type::kMouseLeave; - else if (type == "contextmenu") - *out = blink::WebInputEvent::Type::kContextMenu; - else if (type == "mousewheel") - *out = blink::WebInputEvent::Type::kMouseWheel; - else if (type == "keydown") - *out = blink::WebInputEvent::Type::kRawKeyDown; - else if (type == "keyup") - *out = blink::WebInputEvent::Type::kKeyUp; - else if (type == "char") - *out = blink::WebInputEvent::Type::kChar; - else if (type == "touchstart") - *out = blink::WebInputEvent::Type::kTouchStart; - else if (type == "touchmove") - *out = blink::WebInputEvent::Type::kTouchMove; - else if (type == "touchend") - *out = blink::WebInputEvent::Type::kTouchEnd; - else if (type == "touchcancel") - *out = blink::WebInputEvent::Type::kTouchCancel; - return true; +#define BLINK_EVENT_TYPES() \ + CASE_TYPE(kUndefined, "undefined") \ + CASE_TYPE(kMouseDown, "mouseDown") \ + CASE_TYPE(kMouseUp, "mouseUp") \ + CASE_TYPE(kMouseMove, "mouseMove") \ + CASE_TYPE(kMouseEnter, "mouseEnter") \ + CASE_TYPE(kMouseLeave, "mouseLeave") \ + CASE_TYPE(kContextMenu, "contextMenu") \ + CASE_TYPE(kMouseWheel, "mouseWheel") \ + CASE_TYPE(kRawKeyDown, "rawKeyDown") \ + CASE_TYPE(kKeyDown, "keyDown") \ + CASE_TYPE(kKeyUp, "keyUp") \ + CASE_TYPE(kChar, "char") \ + CASE_TYPE(kGestureScrollBegin, "gestureScrollBegin") \ + CASE_TYPE(kGestureScrollEnd, "gestureScrollEnd") \ + CASE_TYPE(kGestureScrollUpdate, "gestureScrollUpdate") \ + CASE_TYPE(kGestureFlingStart, "gestureFlingStart") \ + CASE_TYPE(kGestureFlingCancel, "gestureFlingCancel") \ + CASE_TYPE(kGesturePinchBegin, "gesturePinchBegin") \ + CASE_TYPE(kGesturePinchEnd, "gesturePinchEnd") \ + CASE_TYPE(kGesturePinchUpdate, "gesturePinchUpdate") \ + CASE_TYPE(kGestureTapDown, "gestureTapDown") \ + CASE_TYPE(kGestureShowPress, "gestureShowPress") \ + CASE_TYPE(kGestureTap, "gestureTap") \ + CASE_TYPE(kGestureTapCancel, "gestureTapCancel") \ + CASE_TYPE(kGestureShortPress, "gestureShortPress") \ + CASE_TYPE(kGestureLongPress, "gestureLongPress") \ + CASE_TYPE(kGestureLongTap, "gestureLongTap") \ + CASE_TYPE(kGestureTwoFingerTap, "gestureTwoFingerTap") \ + CASE_TYPE(kGestureTapUnconfirmed, "gestureTapUnconfirmed") \ + CASE_TYPE(kGestureDoubleTap, "gestureDoubleTap") \ + CASE_TYPE(kTouchStart, "touchStart") \ + CASE_TYPE(kTouchMove, "touchMove") \ + CASE_TYPE(kTouchEnd, "touchEnd") \ + CASE_TYPE(kTouchCancel, "touchCancel") \ + CASE_TYPE(kTouchScrollStarted, "touchScrollStarted") \ + CASE_TYPE(kPointerDown, "pointerDown") \ + CASE_TYPE(kPointerUp, "pointerUp") \ + CASE_TYPE(kPointerMove, "pointerMove") \ + CASE_TYPE(kPointerRawUpdate, "pointerRawUpdate") \ + CASE_TYPE(kPointerCancel, "pointerCancel") \ + CASE_TYPE(kPointerCausedUaAction, "pointerCausedUaAction") + +bool Converter::FromV8( + v8::Isolate* isolate, + v8::Handle val, + blink::WebInputEvent::Type* out) { + std::string type = gin::V8ToString(isolate, val); +#define CASE_TYPE(event_type, js_name) \ + if (base::EqualsCaseInsensitiveASCII(type, js_name)) { \ + *out = blink::WebInputEvent::Type::event_type; \ + return true; \ } -}; + BLINK_EVENT_TYPES() +#undef CASE_TYPE + return false; +} + +v8::Local Converter::ToV8( + v8::Isolate* isolate, + const blink::WebInputEvent::Type& in) { +#define CASE_TYPE(event_type, js_name) \ + case blink::WebInputEvent::Type::event_type: \ + return StringToV8(isolate, js_name); + switch (in) { BLINK_EVENT_TYPES() } +#undef CASE_TYPE +} template <> struct Converter { @@ -207,6 +238,19 @@ bool Converter::FromV8(v8::Isolate* isolate, return true; } +v8::Local Converter::ToV8( + v8::Isolate* isolate, + const blink::WebInputEvent& in) { + if (blink::WebInputEvent::IsKeyboardEventType(in.GetType())) + return gin::ConvertToV8(isolate, + *static_cast(&in)); + return gin::DataObjectBuilder(isolate) + .Set("type", in.GetType()) + .Set("modifiers", ModifiersToArray(in.GetModifiers())) + .Set("_modifiers", in.GetModifiers()) + .Build(); +} + bool Converter::FromV8(v8::Isolate* isolate, v8::Local val, blink::WebKeyboardEvent* out) { @@ -276,10 +320,7 @@ v8::Local Converter::ToV8( const blink::WebKeyboardEvent& in) { gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(isolate); - if (in.GetType() == blink::WebInputEvent::Type::kRawKeyDown) - dict.Set("type", "keyDown"); - else if (in.GetType() == blink::WebInputEvent::Type::kKeyUp) - dict.Set("type", "keyUp"); + dict.Set("type", in.GetType()); dict.Set("key", ui::KeycodeConverter::DomKeyToKeyString(in.dom_key)); dict.Set("code", ui::KeycodeConverter::DomCodeToCodeString( static_cast(in.dom_code))); diff --git a/shell/common/gin_converters/blink_converter.h b/shell/common/gin_converters/blink_converter.h index 8ae85d7506005..38017310fb8f2 100644 --- a/shell/common/gin_converters/blink_converter.h +++ b/shell/common/gin_converters/blink_converter.h @@ -24,11 +24,22 @@ namespace gin { blink::WebInputEvent::Type GetWebInputEventType(v8::Isolate* isolate, v8::Local val); +template <> +struct Converter { + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + blink::WebInputEvent::Type* out); + static v8::Local ToV8(v8::Isolate* isolate, + const blink::WebInputEvent::Type& in); +}; + template <> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, blink::WebInputEvent* out); + static v8::Local ToV8(v8::Isolate* isolate, + const blink::WebInputEvent& in); }; template <>