From d69367aa9bf60594d00ac0b6ec7e10c746b35f73 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Oct 2016 14:44:35 -0700 Subject: [PATCH 1/6] Add keydown sendInputEvent specs --- spec/api-web-contents-spec.js | 58 +++++++++++++++++++++++++++++- spec/fixtures/pages/onkeydown.html | 9 +++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 spec/fixtures/pages/onkeydown.html diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 7e77c39bdb55..3a28ff36dd56 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -5,7 +5,7 @@ const path = require('path') const {closeWindow} = require('./window-helpers') const {remote} = require('electron') -const {BrowserWindow, webContents} = remote +const {BrowserWindow, webContents, ipcMain} = remote const isCi = remote.getGlobal('isCi') @@ -97,4 +97,60 @@ describe('webContents module', function () { }) }) }) + + describe('sendInputEvent(event)', function () { + it('can send keydown events', function (done) { + w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) + + ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { + assert.equal(key, '') + assert.equal(code, '') + assert.equal(keyCode, 65) + assert.equal(shiftKey, false) + assert.equal(ctrlKey, false) + assert.equal(altKey, false) + done() + }) + + w.webContents.once('did-finish-load', function () { + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'}) + }) + }) + + it('can send keydown events with modifiers', function (done) { + w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) + + ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { + assert.equal(key, '') + assert.equal(code, '') + assert.equal(keyCode, 90) + assert.equal(shiftKey, true) + assert.equal(ctrlKey, true) + assert.equal(altKey, false) + done() + }) + + w.webContents.once('did-finish-load', function () { + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl']}) + }) + }) + + it('can send keydown events with special keys', function (done) { + w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) + + ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { + assert.equal(key, '') + assert.equal(code, '') + assert.equal(keyCode, 9) + assert.equal(shiftKey, false) + assert.equal(ctrlKey, false) + assert.equal(altKey, true) + done() + }) + + w.webContents.once('did-finish-load', function () { + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Tab', modifiers: ['alt']}) + }) + }) + }) }) diff --git a/spec/fixtures/pages/onkeydown.html b/spec/fixtures/pages/onkeydown.html new file mode 100644 index 000000000000..859893efd7ec --- /dev/null +++ b/spec/fixtures/pages/onkeydown.html @@ -0,0 +1,9 @@ + + + + + From 6fac14ad3f6e0037cff2387340c09cce4c32f27e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Oct 2016 12:46:33 -0700 Subject: [PATCH 2/6] Set key and code on keyboard events --- atom/common/keyboard_util.cc | 31 +++++++++++++++++++ atom/common/keyboard_util.h | 2 ++ .../native_mate_converters/blink_converter.cc | 19 +++++++++--- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/atom/common/keyboard_util.cc b/atom/common/keyboard_util.cc index c8e9628f3bcc..541cacbcf8c1 100644 --- a/atom/common/keyboard_util.cc +++ b/atom/common/keyboard_util.cc @@ -7,6 +7,8 @@ #include "atom/common/keyboard_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "third_party/WebKit/public/web/WebInputEvent.h" +#include "ui/events/event_constants.h" namespace atom { @@ -174,4 +176,33 @@ ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted) { return KeyboardCodeFromKeyIdentifier(str, shifted); } +int WebEventModifiersToEventFlags(int modifiers) { + int flags = 0; + + if (modifiers & blink::WebInputEvent::ShiftKey) + flags |= ui::EF_SHIFT_DOWN; + if (modifiers & blink::WebInputEvent::ControlKey) + flags |= ui::EF_CONTROL_DOWN; + if (modifiers & blink::WebInputEvent::AltKey) + flags |= ui::EF_ALT_DOWN; + if (modifiers & blink::WebInputEvent::MetaKey) + flags |= ui::EF_COMMAND_DOWN; + if (modifiers & blink::WebInputEvent::CapsLockOn) + flags |= ui::EF_CAPS_LOCK_ON; + if (modifiers & blink::WebInputEvent::NumLockOn) + flags |= ui::EF_NUM_LOCK_ON; + if (modifiers & blink::WebInputEvent::ScrollLockOn) + flags |= ui::EF_SCROLL_LOCK_ON; + if (modifiers & blink::WebInputEvent::LeftButtonDown) + flags |= ui::EF_LEFT_MOUSE_BUTTON; + if (modifiers & blink::WebInputEvent::MiddleButtonDown) + flags |= ui::EF_MIDDLE_MOUSE_BUTTON; + if (modifiers & blink::WebInputEvent::RightButtonDown) + flags |= ui::EF_RIGHT_MOUSE_BUTTON; + if (modifiers & blink::WebInputEvent::IsAutoRepeat) + flags |= ui::EF_IS_REPEAT; + + return flags; +} + } // namespace atom diff --git a/atom/common/keyboard_util.h b/atom/common/keyboard_util.h index c9d1b809e8f7..f16584b2bb0b 100644 --- a/atom/common/keyboard_util.h +++ b/atom/common/keyboard_util.h @@ -15,6 +15,8 @@ namespace atom { // pressed. ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted); +int WebEventModifiersToEventFlags(int modifiers); + } // namespace atom #endif // ATOM_COMMON_KEYBOARD_UTIL_H_ diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 9adb03d4cde3..07971e78dd43 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -18,6 +18,7 @@ #include "third_party/WebKit/public/web/WebFindOptions.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/base/clipboard/clipboard.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" namespace { @@ -166,15 +167,25 @@ bool Converter::FromV8( return false; std::string str; - bool shifted = false; - if (dict.Get("keyCode", &str)) - out->windowsKeyCode = atom::KeyboardCodeFromStr(str, &shifted); - else + if (!dict.Get("keyCode", &str)) return false; + bool shifted = false; + ui::KeyboardCode keyCode = atom::KeyboardCodeFromStr(str, &shifted); + out->windowsKeyCode = keyCode; if (shifted) out->modifiers |= blink::WebInputEvent::ShiftKey; out->setKeyIdentifierFromWindowsKeyCode(); + + ui::DomCode domCode = ui::UsLayoutKeyboardCodeToDomCode(keyCode); + out->domCode = static_cast(domCode); + + ui::DomKey domKey; + ui::KeyboardCode dummy_code; + int flags = atom::WebEventModifiersToEventFlags(out->modifiers); + if (ui::DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &dummy_code)) + out->domKey = static_cast(domKey); + if ((out->type == blink::WebInputEvent::Char || out->type == blink::WebInputEvent::RawKeyDown)) { // Make sure to not read beyond the buffer in case some bad code doesn't From 424afd3faf010e277320dfe25fa9af85d8b14186 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Oct 2016 14:49:21 -0700 Subject: [PATCH 3/6] Update expected key and code values --- spec/api-web-contents-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 3a28ff36dd56..97e0ed232f87 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -103,8 +103,8 @@ describe('webContents module', function () { w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { - assert.equal(key, '') - assert.equal(code, '') + assert.equal(key, 'a') + assert.equal(code, 'KeyA') assert.equal(keyCode, 65) assert.equal(shiftKey, false) assert.equal(ctrlKey, false) @@ -121,8 +121,8 @@ describe('webContents module', function () { w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { - assert.equal(key, '') - assert.equal(code, '') + assert.equal(key, 'Z') + assert.equal(code, 'KeyZ') assert.equal(keyCode, 90) assert.equal(shiftKey, true) assert.equal(ctrlKey, true) @@ -139,8 +139,8 @@ describe('webContents module', function () { w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { - assert.equal(key, '') - assert.equal(code, '') + assert.equal(key, 'Tab') + assert.equal(code, 'Tab') assert.equal(keyCode, 9) assert.equal(shiftKey, false) assert.equal(ctrlKey, false) From e4b0577cb00adb51242c4e49b0ee4b7bc1b6b575 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Oct 2016 14:57:31 -0700 Subject: [PATCH 4/6] Assert key and code in keyup input event spec --- atom/common/keyboard_util.h | 1 + spec/fixtures/pages/onkeyup.html | 2 +- spec/webview-spec.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/atom/common/keyboard_util.h b/atom/common/keyboard_util.h index f16584b2bb0b..651cf6a92024 100644 --- a/atom/common/keyboard_util.h +++ b/atom/common/keyboard_util.h @@ -15,6 +15,7 @@ namespace atom { // pressed. ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted); +// Ported from ui/events/blink/blink_event_util.h int WebEventModifiersToEventFlags(int modifiers); } // namespace atom diff --git a/spec/fixtures/pages/onkeyup.html b/spec/fixtures/pages/onkeyup.html index 4e75dbb1e4ac..0ff0f3d449cf 100644 --- a/spec/fixtures/pages/onkeyup.html +++ b/spec/fixtures/pages/onkeyup.html @@ -2,7 +2,7 @@ diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 1eb14442adaa..1c49688adeb8 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -776,7 +776,7 @@ describe(' tag', function () { it('can send keyboard event', function (done) { webview.addEventListener('ipc-message', function (e) { assert.equal(e.channel, 'keyup') - assert.deepEqual(e.args, [67, true, false]) + assert.deepEqual(e.args, ['C', 'KeyC', 67, true, false]) done() }) webview.addEventListener('dom-ready', function () { From 99414065a9b4620796ccb0e652c5f515439a5e3a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 7 Oct 2016 15:12:35 -0700 Subject: [PATCH 5/6] Add char/keypress event tests --- spec/api-web-contents-spec.js | 50 +++++++++++++------ .../pages/{onkeydown.html => key-events.html} | 3 ++ 2 files changed, 37 insertions(+), 16 deletions(-) rename spec/fixtures/pages/{onkeydown.html => key-events.html} (61%) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 97e0ed232f87..784c387ca751 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -99,9 +99,14 @@ describe('webContents module', function () { }) describe('sendInputEvent(event)', function () { - it('can send keydown events', function (done) { - w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) + beforeEach(function (done) { + w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'key-events.html')) + w.webContents.once('did-finish-load', function () { + done() + }) + }) + it('can send keydown events', function (done) { ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { assert.equal(key, 'a') assert.equal(code, 'KeyA') @@ -111,15 +116,10 @@ describe('webContents module', function () { assert.equal(altKey, false) done() }) - - w.webContents.once('did-finish-load', function () { - w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'}) - }) + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'}) }) it('can send keydown events with modifiers', function (done) { - w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) - ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { assert.equal(key, 'Z') assert.equal(code, 'KeyZ') @@ -129,15 +129,10 @@ describe('webContents module', function () { assert.equal(altKey, false) done() }) - - w.webContents.once('did-finish-load', function () { - w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl']}) - }) + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl']}) }) it('can send keydown events with special keys', function (done) { - w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'onkeydown.html')) - ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { assert.equal(key, 'Tab') assert.equal(code, 'Tab') @@ -147,10 +142,33 @@ describe('webContents module', function () { assert.equal(altKey, true) done() }) + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Tab', modifiers: ['alt']}) + }) - w.webContents.once('did-finish-load', function () { - w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Tab', modifiers: ['alt']}) + it('can send char events', function (done) { + ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { + assert.equal(key, 'a') + assert.equal(code, 'KeyA') + assert.equal(keyCode, 65) + assert.equal(shiftKey, false) + assert.equal(ctrlKey, false) + assert.equal(altKey, false) + done() }) + w.webContents.sendInputEvent({type: 'char', keyCode: 'A'}) + }) + + it('can send char events with modifiers', function (done) { + ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) { + assert.equal(key, 'Z') + assert.equal(code, 'KeyZ') + assert.equal(keyCode, 90) + assert.equal(shiftKey, true) + assert.equal(ctrlKey, true) + assert.equal(altKey, false) + done() + }) + w.webContents.sendInputEvent({type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl']}) }) }) }) diff --git a/spec/fixtures/pages/onkeydown.html b/spec/fixtures/pages/key-events.html similarity index 61% rename from spec/fixtures/pages/onkeydown.html rename to spec/fixtures/pages/key-events.html index 859893efd7ec..7402daf5e999 100644 --- a/spec/fixtures/pages/onkeydown.html +++ b/spec/fixtures/pages/key-events.html @@ -4,6 +4,9 @@ document.onkeydown = function (e) { require('electron').ipcRenderer.send('keydown', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey) } +document.onkeypress = function (e) { + require('electron').ipcRenderer.send('keypress', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey) +} From 987579d3917aeb12cf138b88d0085285c961c3d6 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 10 Oct 2016 09:34:15 -0700 Subject: [PATCH 6/6] Send initial keyDown before char event --- spec/api-web-contents-spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 784c387ca751..d7a2ae50f3cf 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -155,6 +155,7 @@ describe('webContents module', function () { assert.equal(altKey, false) done() }) + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'}) w.webContents.sendInputEvent({type: 'char', keyCode: 'A'}) }) @@ -168,6 +169,7 @@ describe('webContents module', function () { assert.equal(altKey, false) done() }) + w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z'}) w.webContents.sendInputEvent({type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl']}) }) })