-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
Copy pathkeyboard_utils.coffee
113 lines (98 loc) · 3.82 KB
/
keyboard_utils.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
mapKeyRegistry = {}
# NOTE: "?" here for the tests.
Utils?.monitorChromeStorage "mapKeyRegistry", (value) => mapKeyRegistry = value
KeyboardUtils =
# This maps event.key key names to Vimium key names.
keyNames:
"ArrowLeft": "left", "ArrowUp": "up", "ArrowRight": "right", "ArrowDown": "down", " ": "space"
init: ->
if (navigator.userAgent.indexOf("Mac") != -1)
@platform = "Mac"
else if (navigator.userAgent.indexOf("Linux") != -1)
@platform = "Linux"
else
@platform = "Windows"
getKeyChar: (event) ->
unless Settings.get "ignoreKeyboardLayout"
key = event.key
else unless event.code
key = event.key ? "" # Fall back to event.key (see #3099).
else if event.code[...6] == "Numpad"
# We cannot correctly emulate the numpad, so fall back to event.key; see #2626.
key = event.key
else
# The logic here is from the vim-like-key-notation project (https://github.com/lydell/vim-like-key-notation).
key = event.code
key = key[3..] if key[...3] == "Key"
# Translate some special keys to event.key-like strings and handle <Shift>.
if @enUsTranslations[key]
key = if event.shiftKey then @enUsTranslations[key][1] else @enUsTranslations[key][0]
else if key.length == 1 and not event.shiftKey
key = key.toLowerCase()
# It appears that key is not always defined (see #2453).
unless key
""
else if key of @keyNames
@keyNames[key]
else if @isModifier event
"" # Don't resolve modifier keys.
else if key.length == 1
key
else
key.toLowerCase()
getKeyCharString: (event) ->
if keyChar = @getKeyChar event
modifiers = []
keyChar = keyChar.toUpperCase() if event.shiftKey and keyChar.length == 1
# These must be in alphabetical order (to match the sorted modifier order in Commands.normalizeKey).
modifiers.push "a" if event.altKey
modifiers.push "c" if event.ctrlKey
modifiers.push "m" if event.metaKey
keyChar = [modifiers..., keyChar].join "-"
keyChar = "<#{keyChar}>" if 1 < keyChar.length
keyChar = mapKeyRegistry[keyChar] ? keyChar
keyChar
isEscape: do ->
useVimLikeEscape = true
Utils.monitorChromeStorage "useVimLikeEscape", (value) -> useVimLikeEscape = value
(event) ->
# <c-[> is mapped to Escape in Vim by default.
# Escape with a keyCode 229 means that this event comes from IME, and should not be treated as a
# direct/normal Escape event. IME will handle the event, not vimium.
# See https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html
(event.key == "Escape" and event.keyCode != 229) or
(useVimLikeEscape and @getKeyCharString(event) == "<c-[>")
isBackspace: (event) ->
event.key in ["Backspace", "Delete"]
isPrintable: (event) ->
@getKeyCharString(event)?.length == 1
isModifier: (event) ->
event.key in ["Control", "Shift", "Alt", "OS", "AltGraph", "Meta"]
enUsTranslations:
"Backquote": ["`", "~"]
"Minus": ["-", "_"]
"Equal": ["=", "+"]
"Backslash": ["\\","|"]
"IntlBackslash": ["\\","|"]
"BracketLeft": ["[", "{"]
"BracketRight": ["]", "}"]
"Semicolon": [";", ":"]
"Quote": ["'", '"']
"Comma": [",", "<"]
"Period": [".", ">"]
"Slash": ["/", "?"]
"Space": [" ", " "]
"Digit1": ["1", "!"]
"Digit2": ["2", "@"]
"Digit3": ["3", "#"]
"Digit4": ["4", "$"]
"Digit5": ["5", "%"]
"Digit6": ["6", "^"]
"Digit7": ["7", "&"]
"Digit8": ["8", "*"]
"Digit9": ["9", "("]
"Digit0": ["0", ")"]
KeyboardUtils.init()
root = exports ? (window.root ?= {})
root.KeyboardUtils = KeyboardUtils
extend window, root unless exports?