puppeteer-ruby 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +36 -0
  5. data/.travis.yml +7 -0
  6. data/Dockerfile +6 -0
  7. data/Gemfile +6 -0
  8. data/README.md +41 -0
  9. data/Rakefile +1 -0
  10. data/bin/console +11 -0
  11. data/bin/setup +8 -0
  12. data/docker-compose.yml +15 -0
  13. data/example.rb +7 -0
  14. data/lib/puppeteer.rb +192 -0
  15. data/lib/puppeteer/async_await_behavior.rb +34 -0
  16. data/lib/puppeteer/browser.rb +240 -0
  17. data/lib/puppeteer/browser_context.rb +90 -0
  18. data/lib/puppeteer/browser_fetcher.rb +6 -0
  19. data/lib/puppeteer/browser_runner.rb +142 -0
  20. data/lib/puppeteer/cdp_session.rb +78 -0
  21. data/lib/puppeteer/concurrent_ruby_utils.rb +37 -0
  22. data/lib/puppeteer/connection.rb +254 -0
  23. data/lib/puppeteer/console_message.rb +24 -0
  24. data/lib/puppeteer/debug_print.rb +20 -0
  25. data/lib/puppeteer/device.rb +12 -0
  26. data/lib/puppeteer/devices.rb +885 -0
  27. data/lib/puppeteer/dom_world.rb +447 -0
  28. data/lib/puppeteer/element_handle.rb +433 -0
  29. data/lib/puppeteer/emulation_manager.rb +46 -0
  30. data/lib/puppeteer/errors.rb +4 -0
  31. data/lib/puppeteer/event_callbackable.rb +88 -0
  32. data/lib/puppeteer/execution_context.rb +230 -0
  33. data/lib/puppeteer/frame.rb +278 -0
  34. data/lib/puppeteer/frame_manager.rb +380 -0
  35. data/lib/puppeteer/if_present.rb +18 -0
  36. data/lib/puppeteer/js_handle.rb +142 -0
  37. data/lib/puppeteer/keyboard.rb +183 -0
  38. data/lib/puppeteer/keyboard/key_description.rb +19 -0
  39. data/lib/puppeteer/keyboard/us_keyboard_layout.rb +283 -0
  40. data/lib/puppeteer/launcher.rb +26 -0
  41. data/lib/puppeteer/launcher/base.rb +48 -0
  42. data/lib/puppeteer/launcher/browser_options.rb +41 -0
  43. data/lib/puppeteer/launcher/chrome.rb +165 -0
  44. data/lib/puppeteer/launcher/chrome_arg_options.rb +49 -0
  45. data/lib/puppeteer/launcher/launch_options.rb +68 -0
  46. data/lib/puppeteer/lifecycle_watcher.rb +168 -0
  47. data/lib/puppeteer/mouse.rb +120 -0
  48. data/lib/puppeteer/network_manager.rb +122 -0
  49. data/lib/puppeteer/page.rb +1001 -0
  50. data/lib/puppeteer/page/screenshot_options.rb +78 -0
  51. data/lib/puppeteer/remote_object.rb +124 -0
  52. data/lib/puppeteer/target.rb +150 -0
  53. data/lib/puppeteer/timeout_settings.rb +15 -0
  54. data/lib/puppeteer/touch_screen.rb +43 -0
  55. data/lib/puppeteer/version.rb +3 -0
  56. data/lib/puppeteer/viewport.rb +36 -0
  57. data/lib/puppeteer/wait_task.rb +6 -0
  58. data/lib/puppeteer/web_socket.rb +117 -0
  59. data/lib/puppeteer/web_socket_transport.rb +49 -0
  60. data/puppeteer-ruby.gemspec +29 -0
  61. metadata +213 -0
@@ -0,0 +1,183 @@
1
+ require_relative './keyboard/key_description'
2
+ require_relative './keyboard/us_keyboard_layout'
3
+
4
+ class Puppeteer::Keyboard
5
+ using Puppeteer::AsyncAwaitBehavior
6
+
7
+ # @param {!Puppeteer.CDPSession} client
8
+ def initialize(client)
9
+ @client = client
10
+ @modifiers = 0
11
+ @pressed_keys = Set.new
12
+ end
13
+
14
+ attr_reader :modifiers
15
+
16
+ # @param key [String]
17
+ # @param text [String]
18
+ def down(key, text: nil)
19
+ description = key_description_for_string(key)
20
+
21
+ auto_repeat = @pressed_keys.include?(description.code)
22
+ @pressed_keys << description.code
23
+ @modifiers |= modifier_bit(description.key)
24
+
25
+ sending_text = text || description.text
26
+ params = {
27
+ type: sending_text ? 'keyDown' : 'rawKeyDown',
28
+ modifiers: @modifiers,
29
+ windowsVirtualKeyCode: description.key_code,
30
+ code: description.code,
31
+ key: description.key,
32
+ text: sending_text,
33
+ unmodifiedText: sending_text,
34
+ autoRepeat: auto_repeat,
35
+ location: description.location,
36
+ isKeypad: description.location == 3,
37
+ }.compact
38
+ @client.send_message('Input.dispatchKeyEvent', params);
39
+ end
40
+
41
+ # @param key [String]
42
+ # @param text [String]
43
+ # @return [Future]
44
+ async def async_down(key, text: nil)
45
+ down(key, text)
46
+ end
47
+
48
+ # @param {string} key
49
+ # @return {number}
50
+ private def modifier_bit(key)
51
+ case key
52
+ when 'Alt'
53
+ 1
54
+ when 'Control'
55
+ 2
56
+ when 'Meta'
57
+ 4
58
+ when 'Shift'
59
+ 8
60
+ else
61
+ 0
62
+ end
63
+ end
64
+
65
+ # @param {string} keyString
66
+ # @return {KeyDescription}
67
+ private def key_description_for_string(key_string)
68
+ shift = (@modifiers & 8) != 0
69
+ description = {}
70
+ definition = KEY_DEFINITIONS[key_string.to_sym]
71
+ if !definition
72
+ raise ArgumentError.new("Unknown key: \"#{key_string}\"")
73
+ end
74
+
75
+ if definition.key
76
+ description[:key] = definition.key
77
+ end
78
+ if shift && definition.shift_key
79
+ description[:key] = definition.shift_key
80
+ end
81
+
82
+ description[:key_code] = definition.key_code || 0
83
+
84
+ if shift && definition.shift_key_code
85
+ description[:key_code] = definition.shift_key_code
86
+ end
87
+
88
+ if definition.code
89
+ description[:code] = definition.code
90
+ end
91
+
92
+ description[:location] = definition.location || 0
93
+
94
+ if description[:key].length == 1
95
+ description[:text] = description[:key]
96
+ end
97
+
98
+ if definition.text
99
+ description[:text] = definition.text
100
+ end
101
+ if shift && definition.shift_text
102
+ description[:text] = definition.shift_text
103
+ end
104
+
105
+ # if any modifiers besides shift are pressed, no text should be sent
106
+ if (@modifiers & ~8) != 0
107
+ description[:text] = ''
108
+ end
109
+
110
+ KeyDescription.new(**description)
111
+ end
112
+
113
+ # @param key [String]
114
+ def up(key)
115
+ description = key_description_for_string(key)
116
+
117
+ @modifiers &= ~(modifier_bit(description.key))
118
+ @pressed_keys.delete(description.code)
119
+
120
+ @client.send_message('Input.dispatchKeyEvent',
121
+ type: 'keyUp',
122
+ modifiers: @modifiers,
123
+ key: description.key,
124
+ windowsVirtualKeyCode: description.key_code,
125
+ code: description.code,
126
+ location: description.location,
127
+ )
128
+ end
129
+
130
+ # @param key [String]
131
+ # @return [Future]
132
+ async def async_up(key)
133
+ up(key)
134
+ end
135
+
136
+ # @param char [string]
137
+ def send_character(char)
138
+ @client.send_message('Input.insertText', text: char)
139
+ end
140
+
141
+ # @param char [string]
142
+ # @return [Future]
143
+ async def async_send_character(char)
144
+ send_character(char)
145
+ end
146
+
147
+ # @param text [String]
148
+ # @return [Future]
149
+ def type_text(text, delay: nil)
150
+ text.each_char do |char|
151
+ if KEY_DEFINITIONS.include?(char.to_sym)
152
+ press(char, delay: delay)
153
+ else
154
+ if delay
155
+ sleep(delay.to_i / 1000.0)
156
+ end
157
+ send_character(char)
158
+ end
159
+ end
160
+ end
161
+
162
+ # @param text [String]
163
+ # @return [Future]
164
+ async def async_type_text(text, delay: nil)
165
+ type_text(text, delay)
166
+ end
167
+
168
+ # @param key [String]
169
+ # @return [Future]
170
+ def press(key, delay: nil)
171
+ down(key)
172
+ if delay
173
+ sleep(delay.to_i / 1000.0)
174
+ end
175
+ up(key)
176
+ end
177
+
178
+ # @param key [String]
179
+ # @return [Future]
180
+ async def async_press(key, delay: nil)
181
+ press(key, delay)
182
+ end
183
+ end
@@ -0,0 +1,19 @@
1
+ class Puppeteer::Keyboard
2
+ # * @typedef {Object} KeyDescription
3
+ # * @property {number} keyCode
4
+ # * @property {string} key
5
+ # * @property {string} text
6
+ # * @property {string} code
7
+ # * @property {number} location
8
+ class KeyDescription
9
+ def initialize(key_code: nil, key: nil, text: nil, code: nil, location: nil)
10
+ @key_code = key_code
11
+ @key = key
12
+ @text = text
13
+ @code = code
14
+ @location = location
15
+ end
16
+
17
+ attr_reader :key_code, :key, :text, :code, :location
18
+ end
19
+ end
@@ -0,0 +1,283 @@
1
+ class Puppeteer::Keyboard
2
+ # * @typedef {Object} KeyDefinition
3
+ # * @property {number=} keyCode
4
+ # * @property {number=} shiftKeyCode
5
+ # * @property {string=} key
6
+ # * @property {string=} shiftKey
7
+ # * @property {string=} code
8
+ # * @property {string=} text
9
+ # * @property {string=} shiftText
10
+ # * @property {number=} location
11
+ class KeyDefinition
12
+ def initialize(hash)
13
+ @key_code = hash[:keyCode]
14
+ @shift_key_code = hash[:shiftKeyCode]
15
+ @key = hash[:key]
16
+ @shift_key = hash[:shiftKey]
17
+ @code = hash[:code]
18
+ @text = hash[:text]
19
+ @shift_text = hash[:shiftText]
20
+ @location = hash[:location]
21
+ end
22
+
23
+ attr_reader :key_code, :key, :code, :text, :shift_key_code, :shift_key, :shift_text, :location
24
+ end
25
+
26
+ KEY_DEFINITIONS = {
27
+ '0': KeyDefinition.new({'keyCode': 48, 'key': '0', 'code': 'Digit0'}),
28
+ '1': KeyDefinition.new({'keyCode': 49, 'key': '1', 'code': 'Digit1'}),
29
+ '2': KeyDefinition.new({'keyCode': 50, 'key': '2', 'code': 'Digit2'}),
30
+ '3': KeyDefinition.new({'keyCode': 51, 'key': '3', 'code': 'Digit3'}),
31
+ '4': KeyDefinition.new({'keyCode': 52, 'key': '4', 'code': 'Digit4'}),
32
+ '5': KeyDefinition.new({'keyCode': 53, 'key': '5', 'code': 'Digit5'}),
33
+ '6': KeyDefinition.new({'keyCode': 54, 'key': '6', 'code': 'Digit6'}),
34
+ '7': KeyDefinition.new({'keyCode': 55, 'key': '7', 'code': 'Digit7'}),
35
+ '8': KeyDefinition.new({'keyCode': 56, 'key': '8', 'code': 'Digit8'}),
36
+ '9': KeyDefinition.new({'keyCode': 57, 'key': '9', 'code': 'Digit9'}),
37
+ 'Power': KeyDefinition.new({'key': 'Power', 'code': 'Power'}),
38
+ 'Eject': KeyDefinition.new({'key': 'Eject', 'code': 'Eject'}),
39
+ 'Abort': KeyDefinition.new({'keyCode': 3, 'code': 'Abort', 'key': 'Cancel'}),
40
+ 'Help': KeyDefinition.new({'keyCode': 6, 'code': 'Help', 'key': 'Help'}),
41
+ 'Backspace': KeyDefinition.new({'keyCode': 8, 'code': 'Backspace', 'key': 'Backspace'}),
42
+ 'Tab': KeyDefinition.new({'keyCode': 9, 'code': 'Tab', 'key': 'Tab'}),
43
+ 'Numpad5': KeyDefinition.new({'keyCode': 12, 'shiftKeyCode': 101, 'key': 'Clear', 'code': 'Numpad5', 'shiftKey': '5', 'location': 3}),
44
+ 'NumpadEnter': KeyDefinition.new({'keyCode': 13, 'code': 'NumpadEnter', 'key': 'Enter', 'text': '\r', 'location': 3}),
45
+ 'Enter': KeyDefinition.new({'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'}),
46
+ '\r': KeyDefinition.new({'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'}),
47
+ '\n': KeyDefinition.new({'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r'}),
48
+ 'ShiftLeft': KeyDefinition.new({'keyCode': 16, 'code': 'ShiftLeft', 'key': 'Shift', 'location': 1}),
49
+ 'ShiftRight': KeyDefinition.new({'keyCode': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2}),
50
+ 'ControlLeft': KeyDefinition.new({'keyCode': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1}),
51
+ 'ControlRight': KeyDefinition.new({'keyCode': 17, 'code': 'ControlRight', 'key': 'Control', 'location': 2}),
52
+ 'AltLeft': KeyDefinition.new({'keyCode': 18, 'code': 'AltLeft', 'key': 'Alt', 'location': 1}),
53
+ 'AltRight': KeyDefinition.new({'keyCode': 18, 'code': 'AltRight', 'key': 'Alt', 'location': 2}),
54
+ 'Pause': KeyDefinition.new({'keyCode': 19, 'code': 'Pause', 'key': 'Pause'}),
55
+ 'CapsLock': KeyDefinition.new({'keyCode': 20, 'code': 'CapsLock', 'key': 'CapsLock'}),
56
+ 'Escape': KeyDefinition.new({'keyCode': 27, 'code': 'Escape', 'key': 'Escape'}),
57
+ 'Convert': KeyDefinition.new({'keyCode': 28, 'code': 'Convert', 'key': 'Convert'}),
58
+ 'NonConvert': KeyDefinition.new({'keyCode': 29, 'code': 'NonConvert', 'key': 'NonConvert'}),
59
+ 'Space': KeyDefinition.new({'keyCode': 32, 'code': 'Space', 'key': ' '}),
60
+ 'Numpad9': KeyDefinition.new({'keyCode': 33, 'shiftKeyCode': 105, 'key': 'PageUp', 'code': 'Numpad9', 'shiftKey': '9', 'location': 3}),
61
+ 'PageUp': KeyDefinition.new({'keyCode': 33, 'code': 'PageUp', 'key': 'PageUp'}),
62
+ 'Numpad3': KeyDefinition.new({'keyCode': 34, 'shiftKeyCode': 99, 'key': 'PageDown', 'code': 'Numpad3', 'shiftKey': '3', 'location': 3}),
63
+ 'PageDown': KeyDefinition.new({'keyCode': 34, 'code': 'PageDown', 'key': 'PageDown'}),
64
+ 'End': KeyDefinition.new({'keyCode': 35, 'code': 'End', 'key': 'End'}),
65
+ 'Numpad1': KeyDefinition.new({'keyCode': 35, 'shiftKeyCode': 97, 'key': 'End', 'code': 'Numpad1', 'shiftKey': '1', 'location': 3}),
66
+ 'Home': KeyDefinition.new({'keyCode': 36, 'code': 'Home', 'key': 'Home'}),
67
+ 'Numpad7': KeyDefinition.new({'keyCode': 36, 'shiftKeyCode': 103, 'key': 'Home', 'code': 'Numpad7', 'shiftKey': '7', 'location': 3}),
68
+ 'ArrowLeft': KeyDefinition.new({'keyCode': 37, 'code': 'ArrowLeft', 'key': 'ArrowLeft'}),
69
+ 'Numpad4': KeyDefinition.new({'keyCode': 37, 'shiftKeyCode': 100, 'key': 'ArrowLeft', 'code': 'Numpad4', 'shiftKey': '4', 'location': 3}),
70
+ 'Numpad8': KeyDefinition.new({'keyCode': 38, 'shiftKeyCode': 104, 'key': 'ArrowUp', 'code': 'Numpad8', 'shiftKey': '8', 'location': 3}),
71
+ 'ArrowUp': KeyDefinition.new({'keyCode': 38, 'code': 'ArrowUp', 'key': 'ArrowUp'}),
72
+ 'ArrowRight': KeyDefinition.new({'keyCode': 39, 'code': 'ArrowRight', 'key': 'ArrowRight'}),
73
+ 'Numpad6': KeyDefinition.new({'keyCode': 39, 'shiftKeyCode': 102, 'key': 'ArrowRight', 'code': 'Numpad6', 'shiftKey': '6', 'location': 3}),
74
+ 'Numpad2': KeyDefinition.new({'keyCode': 40, 'shiftKeyCode': 98, 'key': 'ArrowDown', 'code': 'Numpad2', 'shiftKey': '2', 'location': 3}),
75
+ 'ArrowDown': KeyDefinition.new({'keyCode': 40, 'code': 'ArrowDown', 'key': 'ArrowDown'}),
76
+ 'Select': KeyDefinition.new({'keyCode': 41, 'code': 'Select', 'key': 'Select'}),
77
+ 'Open': KeyDefinition.new({'keyCode': 43, 'code': 'Open', 'key': 'Execute'}),
78
+ 'PrintScreen': KeyDefinition.new({'keyCode': 44, 'code': 'PrintScreen', 'key': 'PrintScreen'}),
79
+ 'Insert': KeyDefinition.new({'keyCode': 45, 'code': 'Insert', 'key': 'Insert'}),
80
+ 'Numpad0': KeyDefinition.new({'keyCode': 45, 'shiftKeyCode': 96, 'key': 'Insert', 'code': 'Numpad0', 'shiftKey': '0', 'location': 3}),
81
+ 'Delete': KeyDefinition.new({'keyCode': 46, 'code': 'Delete', 'key': 'Delete'}),
82
+ 'NumpadDecimal': KeyDefinition.new({'keyCode': 46, 'shiftKeyCode': 110, 'code': 'NumpadDecimal', 'key': '\u0000', 'shiftKey': '.', 'location': 3}),
83
+ 'Digit0': KeyDefinition.new({'keyCode': 48, 'code': 'Digit0', 'shiftKey': ')', 'key': '0'}),
84
+ 'Digit1': KeyDefinition.new({'keyCode': 49, 'code': 'Digit1', 'shiftKey': '!', 'key': '1'}),
85
+ 'Digit2': KeyDefinition.new({'keyCode': 50, 'code': 'Digit2', 'shiftKey': '@', 'key': '2'}),
86
+ 'Digit3': KeyDefinition.new({'keyCode': 51, 'code': 'Digit3', 'shiftKey': '#', 'key': '3'}),
87
+ 'Digit4': KeyDefinition.new({'keyCode': 52, 'code': 'Digit4', 'shiftKey': '$', 'key': '4'}),
88
+ 'Digit5': KeyDefinition.new({'keyCode': 53, 'code': 'Digit5', 'shiftKey': '%', 'key': '5'}),
89
+ 'Digit6': KeyDefinition.new({'keyCode': 54, 'code': 'Digit6', 'shiftKey': '^', 'key': '6'}),
90
+ 'Digit7': KeyDefinition.new({'keyCode': 55, 'code': 'Digit7', 'shiftKey': '&', 'key': '7'}),
91
+ 'Digit8': KeyDefinition.new({'keyCode': 56, 'code': 'Digit8', 'shiftKey': '*', 'key': '8'}),
92
+ 'Digit9': KeyDefinition.new({'keyCode': 57, 'code': 'Digit9', 'shiftKey': '\(', 'key': '9'}),
93
+ 'KeyA': KeyDefinition.new({'keyCode': 65, 'code': 'KeyA', 'shiftKey': 'A', 'key': 'a'}),
94
+ 'KeyB': KeyDefinition.new({'keyCode': 66, 'code': 'KeyB', 'shiftKey': 'B', 'key': 'b'}),
95
+ 'KeyC': KeyDefinition.new({'keyCode': 67, 'code': 'KeyC', 'shiftKey': 'C', 'key': 'c'}),
96
+ 'KeyD': KeyDefinition.new({'keyCode': 68, 'code': 'KeyD', 'shiftKey': 'D', 'key': 'd'}),
97
+ 'KeyE': KeyDefinition.new({'keyCode': 69, 'code': 'KeyE', 'shiftKey': 'E', 'key': 'e'}),
98
+ 'KeyF': KeyDefinition.new({'keyCode': 70, 'code': 'KeyF', 'shiftKey': 'F', 'key': 'f'}),
99
+ 'KeyG': KeyDefinition.new({'keyCode': 71, 'code': 'KeyG', 'shiftKey': 'G', 'key': 'g'}),
100
+ 'KeyH': KeyDefinition.new({'keyCode': 72, 'code': 'KeyH', 'shiftKey': 'H', 'key': 'h'}),
101
+ 'KeyI': KeyDefinition.new({'keyCode': 73, 'code': 'KeyI', 'shiftKey': 'I', 'key': 'i'}),
102
+ 'KeyJ': KeyDefinition.new({'keyCode': 74, 'code': 'KeyJ', 'shiftKey': 'J', 'key': 'j'}),
103
+ 'KeyK': KeyDefinition.new({'keyCode': 75, 'code': 'KeyK', 'shiftKey': 'K', 'key': 'k'}),
104
+ 'KeyL': KeyDefinition.new({'keyCode': 76, 'code': 'KeyL', 'shiftKey': 'L', 'key': 'l'}),
105
+ 'KeyM': KeyDefinition.new({'keyCode': 77, 'code': 'KeyM', 'shiftKey': 'M', 'key': 'm'}),
106
+ 'KeyN': KeyDefinition.new({'keyCode': 78, 'code': 'KeyN', 'shiftKey': 'N', 'key': 'n'}),
107
+ 'KeyO': KeyDefinition.new({'keyCode': 79, 'code': 'KeyO', 'shiftKey': 'O', 'key': 'o'}),
108
+ 'KeyP': KeyDefinition.new({'keyCode': 80, 'code': 'KeyP', 'shiftKey': 'P', 'key': 'p'}),
109
+ 'KeyQ': KeyDefinition.new({'keyCode': 81, 'code': 'KeyQ', 'shiftKey': 'Q', 'key': 'q'}),
110
+ 'KeyR': KeyDefinition.new({'keyCode': 82, 'code': 'KeyR', 'shiftKey': 'R', 'key': 'r'}),
111
+ 'KeyS': KeyDefinition.new({'keyCode': 83, 'code': 'KeyS', 'shiftKey': 'S', 'key': 's'}),
112
+ 'KeyT': KeyDefinition.new({'keyCode': 84, 'code': 'KeyT', 'shiftKey': 'T', 'key': 't'}),
113
+ 'KeyU': KeyDefinition.new({'keyCode': 85, 'code': 'KeyU', 'shiftKey': 'U', 'key': 'u'}),
114
+ 'KeyV': KeyDefinition.new({'keyCode': 86, 'code': 'KeyV', 'shiftKey': 'V', 'key': 'v'}),
115
+ 'KeyW': KeyDefinition.new({'keyCode': 87, 'code': 'KeyW', 'shiftKey': 'W', 'key': 'w'}),
116
+ 'KeyX': KeyDefinition.new({'keyCode': 88, 'code': 'KeyX', 'shiftKey': 'X', 'key': 'x'}),
117
+ 'KeyY': KeyDefinition.new({'keyCode': 89, 'code': 'KeyY', 'shiftKey': 'Y', 'key': 'y'}),
118
+ 'KeyZ': KeyDefinition.new({'keyCode': 90, 'code': 'KeyZ', 'shiftKey': 'Z', 'key': 'z'}),
119
+ 'MetaLeft': KeyDefinition.new({'keyCode': 91, 'code': 'MetaLeft', 'key': 'Meta', 'location': 1}),
120
+ 'MetaRight': KeyDefinition.new({'keyCode': 92, 'code': 'MetaRight', 'key': 'Meta', 'location': 2}),
121
+ 'ContextMenu': KeyDefinition.new({'keyCode': 93, 'code': 'ContextMenu', 'key': 'ContextMenu'}),
122
+ 'NumpadMultiply': KeyDefinition.new({'keyCode': 106, 'code': 'NumpadMultiply', 'key': '*', 'location': 3}),
123
+ 'NumpadAdd': KeyDefinition.new({'keyCode': 107, 'code': 'NumpadAdd', 'key': '+', 'location': 3}),
124
+ 'NumpadSubtract': KeyDefinition.new({'keyCode': 109, 'code': 'NumpadSubtract', 'key': '-', 'location': 3}),
125
+ 'NumpadDivide': KeyDefinition.new({'keyCode': 111, 'code': 'NumpadDivide', 'key': '/', 'location': 3}),
126
+ 'F1': KeyDefinition.new({'keyCode': 112, 'code': 'F1', 'key': 'F1'}),
127
+ 'F2': KeyDefinition.new({'keyCode': 113, 'code': 'F2', 'key': 'F2'}),
128
+ 'F3': KeyDefinition.new({'keyCode': 114, 'code': 'F3', 'key': 'F3'}),
129
+ 'F4': KeyDefinition.new({'keyCode': 115, 'code': 'F4', 'key': 'F4'}),
130
+ 'F5': KeyDefinition.new({'keyCode': 116, 'code': 'F5', 'key': 'F5'}),
131
+ 'F6': KeyDefinition.new({'keyCode': 117, 'code': 'F6', 'key': 'F6'}),
132
+ 'F7': KeyDefinition.new({'keyCode': 118, 'code': 'F7', 'key': 'F7'}),
133
+ 'F8': KeyDefinition.new({'keyCode': 119, 'code': 'F8', 'key': 'F8'}),
134
+ 'F9': KeyDefinition.new({'keyCode': 120, 'code': 'F9', 'key': 'F9'}),
135
+ 'F10': KeyDefinition.new({'keyCode': 121, 'code': 'F10', 'key': 'F10'}),
136
+ 'F11': KeyDefinition.new({'keyCode': 122, 'code': 'F11', 'key': 'F11'}),
137
+ 'F12': KeyDefinition.new({'keyCode': 123, 'code': 'F12', 'key': 'F12'}),
138
+ 'F13': KeyDefinition.new({'keyCode': 124, 'code': 'F13', 'key': 'F13'}),
139
+ 'F14': KeyDefinition.new({'keyCode': 125, 'code': 'F14', 'key': 'F14'}),
140
+ 'F15': KeyDefinition.new({'keyCode': 126, 'code': 'F15', 'key': 'F15'}),
141
+ 'F16': KeyDefinition.new({'keyCode': 127, 'code': 'F16', 'key': 'F16'}),
142
+ 'F17': KeyDefinition.new({'keyCode': 128, 'code': 'F17', 'key': 'F17'}),
143
+ 'F18': KeyDefinition.new({'keyCode': 129, 'code': 'F18', 'key': 'F18'}),
144
+ 'F19': KeyDefinition.new({'keyCode': 130, 'code': 'F19', 'key': 'F19'}),
145
+ 'F20': KeyDefinition.new({'keyCode': 131, 'code': 'F20', 'key': 'F20'}),
146
+ 'F21': KeyDefinition.new({'keyCode': 132, 'code': 'F21', 'key': 'F21'}),
147
+ 'F22': KeyDefinition.new({'keyCode': 133, 'code': 'F22', 'key': 'F22'}),
148
+ 'F23': KeyDefinition.new({'keyCode': 134, 'code': 'F23', 'key': 'F23'}),
149
+ 'F24': KeyDefinition.new({'keyCode': 135, 'code': 'F24', 'key': 'F24'}),
150
+ 'NumLock': KeyDefinition.new({'keyCode': 144, 'code': 'NumLock', 'key': 'NumLock'}),
151
+ 'ScrollLock': KeyDefinition.new({'keyCode': 145, 'code': 'ScrollLock', 'key': 'ScrollLock'}),
152
+ 'AudioVolumeMute': KeyDefinition.new({'keyCode': 173, 'code': 'AudioVolumeMute', 'key': 'AudioVolumeMute'}),
153
+ 'AudioVolumeDown': KeyDefinition.new({'keyCode': 174, 'code': 'AudioVolumeDown', 'key': 'AudioVolumeDown'}),
154
+ 'AudioVolumeUp': KeyDefinition.new({'keyCode': 175, 'code': 'AudioVolumeUp', 'key': 'AudioVolumeUp'}),
155
+ 'MediaTrackNext': KeyDefinition.new({'keyCode': 176, 'code': 'MediaTrackNext', 'key': 'MediaTrackNext'}),
156
+ 'MediaTrackPrevious': KeyDefinition.new({'keyCode': 177, 'code': 'MediaTrackPrevious', 'key': 'MediaTrackPrevious'}),
157
+ 'MediaStop': KeyDefinition.new({'keyCode': 178, 'code': 'MediaStop', 'key': 'MediaStop'}),
158
+ 'MediaPlayPause': KeyDefinition.new({'keyCode': 179, 'code': 'MediaPlayPause', 'key': 'MediaPlayPause'}),
159
+ 'Semicolon': KeyDefinition.new({'keyCode': 186, 'code': 'Semicolon', 'shiftKey': ':', 'key': ';'}),
160
+ 'Equal': KeyDefinition.new({'keyCode': 187, 'code': 'Equal', 'shiftKey': '+', 'key': '='}),
161
+ 'NumpadEqual': KeyDefinition.new({'keyCode': 187, 'code': 'NumpadEqual', 'key': '=', 'location': 3}),
162
+ 'Comma': KeyDefinition.new({'keyCode': 188, 'code': 'Comma', 'shiftKey': '\<', 'key': ','}),
163
+ 'Minus': KeyDefinition.new({'keyCode': 189, 'code': 'Minus', 'shiftKey': '_', 'key': '-'}),
164
+ 'Period': KeyDefinition.new({'keyCode': 190, 'code': 'Period', 'shiftKey': '>', 'key': '.'}),
165
+ 'Slash': KeyDefinition.new({'keyCode': 191, 'code': 'Slash', 'shiftKey': '?', 'key': '/'}),
166
+ 'Backquote': KeyDefinition.new({'keyCode': 192, 'code': 'Backquote', 'shiftKey': '~', 'key': '`'}),
167
+ 'BracketLeft': KeyDefinition.new({'keyCode': 219, 'code': 'BracketLeft', 'shiftKey': '{', 'key': '['}),
168
+ 'Backslash': KeyDefinition.new({'keyCode': 220, 'code': 'Backslash', 'shiftKey': '|', 'key': '\\'}),
169
+ 'BracketRight': KeyDefinition.new({'keyCode': 221, 'code': 'BracketRight', 'shiftKey': '}', 'key': ']'}),
170
+ 'Quote': KeyDefinition.new({'keyCode': 222, 'code': 'Quote', 'shiftKey': '"', 'key': '\''}),
171
+ 'AltGraph': KeyDefinition.new({'keyCode': 225, 'code': 'AltGraph', 'key': 'AltGraph'}),
172
+ 'Props': KeyDefinition.new({'keyCode': 247, 'code': 'Props', 'key': 'CrSel'}),
173
+ 'Cancel': KeyDefinition.new({'keyCode': 3, 'key': 'Cancel', 'code': 'Abort'}),
174
+ 'Clear': KeyDefinition.new({'keyCode': 12, 'key': 'Clear', 'code': 'Numpad5', 'location': 3}),
175
+ 'Shift': KeyDefinition.new({'keyCode': 16, 'key': 'Shift', 'code': 'ShiftLeft', 'location': 1}),
176
+ 'Control': KeyDefinition.new({'keyCode': 17, 'key': 'Control', 'code': 'ControlLeft', 'location': 1}),
177
+ 'Alt': KeyDefinition.new({'keyCode': 18, 'key': 'Alt', 'code': 'AltLeft', 'location': 1}),
178
+ 'Accept': KeyDefinition.new({'keyCode': 30, 'key': 'Accept'}),
179
+ 'ModeChange': KeyDefinition.new({'keyCode': 31, 'key': 'ModeChange'}),
180
+ ' ': KeyDefinition.new({'keyCode': 32, 'key': ' ', 'code': 'Space'}),
181
+ 'Print': KeyDefinition.new({'keyCode': 42, 'key': 'Print'}),
182
+ 'Execute': KeyDefinition.new({'keyCode': 43, 'key': 'Execute', 'code': 'Open'}),
183
+ '\u0000': KeyDefinition.new({'keyCode': 46, 'key': '\u0000', 'code': 'NumpadDecimal', 'location': 3}),
184
+ 'a': KeyDefinition.new({'keyCode': 65, 'key': 'a', 'code': 'KeyA'}),
185
+ 'b': KeyDefinition.new({'keyCode': 66, 'key': 'b', 'code': 'KeyB'}),
186
+ 'c': KeyDefinition.new({'keyCode': 67, 'key': 'c', 'code': 'KeyC'}),
187
+ 'd': KeyDefinition.new({'keyCode': 68, 'key': 'd', 'code': 'KeyD'}),
188
+ 'e': KeyDefinition.new({'keyCode': 69, 'key': 'e', 'code': 'KeyE'}),
189
+ 'f': KeyDefinition.new({'keyCode': 70, 'key': 'f', 'code': 'KeyF'}),
190
+ 'g': KeyDefinition.new({'keyCode': 71, 'key': 'g', 'code': 'KeyG'}),
191
+ 'h': KeyDefinition.new({'keyCode': 72, 'key': 'h', 'code': 'KeyH'}),
192
+ 'i': KeyDefinition.new({'keyCode': 73, 'key': 'i', 'code': 'KeyI'}),
193
+ 'j': KeyDefinition.new({'keyCode': 74, 'key': 'j', 'code': 'KeyJ'}),
194
+ 'k': KeyDefinition.new({'keyCode': 75, 'key': 'k', 'code': 'KeyK'}),
195
+ 'l': KeyDefinition.new({'keyCode': 76, 'key': 'l', 'code': 'KeyL'}),
196
+ 'm': KeyDefinition.new({'keyCode': 77, 'key': 'm', 'code': 'KeyM'}),
197
+ 'n': KeyDefinition.new({'keyCode': 78, 'key': 'n', 'code': 'KeyN'}),
198
+ 'o': KeyDefinition.new({'keyCode': 79, 'key': 'o', 'code': 'KeyO'}),
199
+ 'p': KeyDefinition.new({'keyCode': 80, 'key': 'p', 'code': 'KeyP'}),
200
+ 'q': KeyDefinition.new({'keyCode': 81, 'key': 'q', 'code': 'KeyQ'}),
201
+ 'r': KeyDefinition.new({'keyCode': 82, 'key': 'r', 'code': 'KeyR'}),
202
+ 's': KeyDefinition.new({'keyCode': 83, 'key': 's', 'code': 'KeyS'}),
203
+ 't': KeyDefinition.new({'keyCode': 84, 'key': 't', 'code': 'KeyT'}),
204
+ 'u': KeyDefinition.new({'keyCode': 85, 'key': 'u', 'code': 'KeyU'}),
205
+ 'v': KeyDefinition.new({'keyCode': 86, 'key': 'v', 'code': 'KeyV'}),
206
+ 'w': KeyDefinition.new({'keyCode': 87, 'key': 'w', 'code': 'KeyW'}),
207
+ 'x': KeyDefinition.new({'keyCode': 88, 'key': 'x', 'code': 'KeyX'}),
208
+ 'y': KeyDefinition.new({'keyCode': 89, 'key': 'y', 'code': 'KeyY'}),
209
+ 'z': KeyDefinition.new({'keyCode': 90, 'key': 'z', 'code': 'KeyZ'}),
210
+ 'Meta': KeyDefinition.new({'keyCode': 91, 'key': 'Meta', 'code': 'MetaLeft', 'location': 1}),
211
+ '*': KeyDefinition.new({'keyCode': 106, 'key': '*', 'code': 'NumpadMultiply', 'location': 3}),
212
+ '+': KeyDefinition.new({'keyCode': 107, 'key': '+', 'code': 'NumpadAdd', 'location': 3}),
213
+ '-': KeyDefinition.new({'keyCode': 109, 'key': '-', 'code': 'NumpadSubtract', 'location': 3}),
214
+ '/': KeyDefinition.new({'keyCode': 111, 'key': '/', 'code': 'NumpadDivide', 'location': 3}),
215
+ ';': KeyDefinition.new({'keyCode': 186, 'key': ';', 'code': 'Semicolon'}),
216
+ '=': KeyDefinition.new({'keyCode': 187, 'key': '=', 'code': 'Equal'}),
217
+ ',': KeyDefinition.new({'keyCode': 188, 'key': ',', 'code': 'Comma'}),
218
+ '.': KeyDefinition.new({'keyCode': 190, 'key': '.', 'code': 'Period'}),
219
+ '`': KeyDefinition.new({'keyCode': 192, 'key': '`', 'code': 'Backquote'}),
220
+ '[': KeyDefinition.new({'keyCode': 219, 'key': '[', 'code': 'BracketLeft'}),
221
+ '\\': KeyDefinition.new({'keyCode': 220, 'key': '\\', 'code': 'Backslash'}),
222
+ ']': KeyDefinition.new({'keyCode': 221, 'key': ']', 'code': 'BracketRight'}),
223
+ '\'': KeyDefinition.new({'keyCode': 222, 'key': '\'', 'code': 'Quote'}),
224
+ 'Attn': KeyDefinition.new({'keyCode': 246, 'key': 'Attn'}),
225
+ 'CrSel': KeyDefinition.new({'keyCode': 247, 'key': 'CrSel', 'code': 'Props'}),
226
+ 'ExSel': KeyDefinition.new({'keyCode': 248, 'key': 'ExSel'}),
227
+ 'EraseEof': KeyDefinition.new({'keyCode': 249, 'key': 'EraseEof'}),
228
+ 'Play': KeyDefinition.new({'keyCode': 250, 'key': 'Play'}),
229
+ 'ZoomOut': KeyDefinition.new({'keyCode': 251, 'key': 'ZoomOut'}),
230
+ ')': KeyDefinition.new({'keyCode': 48, 'key': ')', 'code': 'Digit0'}),
231
+ '!': KeyDefinition.new({'keyCode': 49, 'key': '!', 'code': 'Digit1'}),
232
+ '@': KeyDefinition.new({'keyCode': 50, 'key': '@', 'code': 'Digit2'}),
233
+ '#': KeyDefinition.new({'keyCode': 51, 'key': '#', 'code': 'Digit3'}),
234
+ '$': KeyDefinition.new({'keyCode': 52, 'key': '$', 'code': 'Digit4'}),
235
+ '%': KeyDefinition.new({'keyCode': 53, 'key': '%', 'code': 'Digit5'}),
236
+ '^': KeyDefinition.new({'keyCode': 54, 'key': '^', 'code': 'Digit6'}),
237
+ '&': KeyDefinition.new({'keyCode': 55, 'key': '&', 'code': 'Digit7'}),
238
+ '(': KeyDefinition.new({'keyCode': 57, 'key': '\(', 'code': 'Digit9'}),
239
+ 'A': KeyDefinition.new({'keyCode': 65, 'key': 'A', 'code': 'KeyA'}),
240
+ 'B': KeyDefinition.new({'keyCode': 66, 'key': 'B', 'code': 'KeyB'}),
241
+ 'C': KeyDefinition.new({'keyCode': 67, 'key': 'C', 'code': 'KeyC'}),
242
+ 'D': KeyDefinition.new({'keyCode': 68, 'key': 'D', 'code': 'KeyD'}),
243
+ 'E': KeyDefinition.new({'keyCode': 69, 'key': 'E', 'code': 'KeyE'}),
244
+ 'F': KeyDefinition.new({'keyCode': 70, 'key': 'F', 'code': 'KeyF'}),
245
+ 'G': KeyDefinition.new({'keyCode': 71, 'key': 'G', 'code': 'KeyG'}),
246
+ 'H': KeyDefinition.new({'keyCode': 72, 'key': 'H', 'code': 'KeyH'}),
247
+ 'I': KeyDefinition.new({'keyCode': 73, 'key': 'I', 'code': 'KeyI'}),
248
+ 'J': KeyDefinition.new({'keyCode': 74, 'key': 'J', 'code': 'KeyJ'}),
249
+ 'K': KeyDefinition.new({'keyCode': 75, 'key': 'K', 'code': 'KeyK'}),
250
+ 'L': KeyDefinition.new({'keyCode': 76, 'key': 'L', 'code': 'KeyL'}),
251
+ 'M': KeyDefinition.new({'keyCode': 77, 'key': 'M', 'code': 'KeyM'}),
252
+ 'N': KeyDefinition.new({'keyCode': 78, 'key': 'N', 'code': 'KeyN'}),
253
+ 'O': KeyDefinition.new({'keyCode': 79, 'key': 'O', 'code': 'KeyO'}),
254
+ 'P': KeyDefinition.new({'keyCode': 80, 'key': 'P', 'code': 'KeyP'}),
255
+ 'Q': KeyDefinition.new({'keyCode': 81, 'key': 'Q', 'code': 'KeyQ'}),
256
+ 'R': KeyDefinition.new({'keyCode': 82, 'key': 'R', 'code': 'KeyR'}),
257
+ 'S': KeyDefinition.new({'keyCode': 83, 'key': 'S', 'code': 'KeyS'}),
258
+ 'T': KeyDefinition.new({'keyCode': 84, 'key': 'T', 'code': 'KeyT'}),
259
+ 'U': KeyDefinition.new({'keyCode': 85, 'key': 'U', 'code': 'KeyU'}),
260
+ 'V': KeyDefinition.new({'keyCode': 86, 'key': 'V', 'code': 'KeyV'}),
261
+ 'W': KeyDefinition.new({'keyCode': 87, 'key': 'W', 'code': 'KeyW'}),
262
+ 'X': KeyDefinition.new({'keyCode': 88, 'key': 'X', 'code': 'KeyX'}),
263
+ 'Y': KeyDefinition.new({'keyCode': 89, 'key': 'Y', 'code': 'KeyY'}),
264
+ 'Z': KeyDefinition.new({'keyCode': 90, 'key': 'Z', 'code': 'KeyZ'}),
265
+ ':': KeyDefinition.new({'keyCode': 186, 'key': ':', 'code': 'Semicolon'}),
266
+ '<': KeyDefinition.new({'keyCode': 188, 'key': '\<', 'code': 'Comma'}),
267
+ '_': KeyDefinition.new({'keyCode': 189, 'key': '_', 'code': 'Minus'}),
268
+ '>': KeyDefinition.new({'keyCode': 190, 'key': '>', 'code': 'Period'}),
269
+ '?': KeyDefinition.new({'keyCode': 191, 'key': '?', 'code': 'Slash'}),
270
+ '~': KeyDefinition.new({'keyCode': 192, 'key': '~', 'code': 'Backquote'}),
271
+ '{': KeyDefinition.new({'keyCode': 219, 'key': '{', 'code': 'BracketLeft'}),
272
+ '|': KeyDefinition.new({'keyCode': 220, 'key': '|', 'code': 'Backslash'}),
273
+ '}': KeyDefinition.new({'keyCode': 221, 'key': '}', 'code': 'BracketRight'}),
274
+ '"': KeyDefinition.new({'keyCode': 222, 'key': '"', 'code': 'Quote'}),
275
+ 'SoftLeft': KeyDefinition.new({'key': 'SoftLeft', 'code': 'SoftLeft', 'location': 4}),
276
+ 'SoftRight': KeyDefinition.new({'key': 'SoftRight', 'code': 'SoftRight', 'location': 4}),
277
+ 'Camera': KeyDefinition.new({'keyCode': 44, 'key': 'Camera', 'code': 'Camera', 'location': 4}),
278
+ 'Call': KeyDefinition.new({'key': 'Call', 'code': 'Call', 'location': 4}),
279
+ 'EndCall': KeyDefinition.new({'keyCode': 95, 'key': 'EndCall', 'code': 'EndCall', 'location': 4}),
280
+ 'VolumeDown': KeyDefinition.new({'keyCode': 182, 'key': 'VolumeDown', 'code': 'VolumeDown', 'location': 4}),
281
+ 'VolumeUp': KeyDefinition.new({'keyCode': 183, 'key': 'VolumeUp', 'code': 'VolumeUp', 'location': 4}),
282
+ }
283
+ end