diff --git a/atom/browser/ui/accelerator_util.cc b/atom/browser/ui/accelerator_util.cc index 41dde7acf73..e25e14b7968 100644 --- a/atom/browser/ui/accelerator_util.cc +++ b/atom/browser/ui/accelerator_util.cc @@ -9,6 +9,7 @@ #include #include +#include "atom/common/keyboad_util.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" @@ -17,74 +18,6 @@ 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") { diff --git a/atom/common/keyboad_util.cc b/atom/common/keyboad_util.cc new file mode 100644 index 00000000000..1baa829ff74 --- /dev/null +++ b/atom/common/keyboad_util.cc @@ -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 index 00000000000..0496886e40b --- /dev/null +++ b/atom/common/keyboad_util.h @@ -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 index 5d3ff62086c..afafa10b11d 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -5,13 +5,197 @@ #include "atom/common/native_mate_converters/blink_converter.h" #include +#include +#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 +int VectorToBitArray(const std::vector& vec) { + int bits = 0; + for (const T& item : vec) + bits |= item; + return bits; +} + +} // namespace namespace mate { +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + char* out) { + std::string code = base::StringToLowerASCII(V8ToString(val)); + if (code.length() != 1) + return false; + *out = code[0]; + return true; + } +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle 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 false; + } +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle 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 false; + } +}; + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebInputEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!dict.Get("type", &out->type)) + return false; + std::vector modifiers; + if (dict.Get("modifiers", &modifiers)) + out->modifiers = VectorToBitArray(modifiers); + out->timeStampSeconds = base::Time::Now().ToDoubleT(); + return true; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebKeyboardEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(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 false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + content::NativeWebKeyboardEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(out))) + return false; + dict.Get("skipInBrowser", &out->skip_in_browser); + return false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, blink::WebMouseEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(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 false; +} + +bool Converter::FromV8( + v8::Isolate* isolate, v8::Local val, + blink::WebMouseWheelEvent* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + if (!ConvertFromV8(isolate, val, static_cast(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 false; +} + bool Converter::FromV8( v8::Isolate* isolate, v8::Local val, blink::WebFloatPoint* out) { mate::Dictionary dict; diff --git a/atom/common/native_mate_converters/blink_converter.h b/atom/common/native_mate_converters/blink_converter.h index bbd2af0e679..fd631983d43 100644 --- a/atom/common/native_mate_converters/blink_converter.h +++ b/atom/common/native_mate_converters/blink_converter.h @@ -8,14 +8,52 @@ #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 { +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebInputEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebKeyboardEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + content::NativeWebKeyboardEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebMouseEvent* out); +}; + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Local val, + blink::WebMouseWheelEvent* out); +}; + template<> struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Local val, diff --git a/filenames.gypi b/filenames.gypi index 30668f20a72..acdea0c25e0 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -283,6 +283,8 @@ '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',