2016-05-06 08:05:51 +08:00
|
|
|
/* eslint-disable */
|
|
|
|
/**
|
|
|
|
* mapping of special keycodes to their corresponding keys
|
|
|
|
*
|
|
|
|
* everything in this dictionary cannot use keypress events
|
|
|
|
* so it has to be here to map to the correct keycodes for
|
|
|
|
* keyup/keydown events
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
var _MAP = {
|
2016-10-19 02:06:55 +08:00
|
|
|
'8': 'backspace',
|
|
|
|
'9': 'tab',
|
|
|
|
'13': 'enter',
|
|
|
|
'16': 'shift',
|
|
|
|
'17': 'ctrl',
|
|
|
|
'18': 'alt',
|
|
|
|
'20': 'capslock',
|
|
|
|
'27': 'esc',
|
|
|
|
'32': 'space',
|
|
|
|
'33': 'pageup',
|
|
|
|
'34': 'pagedown',
|
|
|
|
'35': 'end',
|
|
|
|
'36': 'home',
|
|
|
|
'37': 'left',
|
|
|
|
'38': 'up',
|
|
|
|
'39': 'right',
|
|
|
|
'40': 'down',
|
|
|
|
'45': 'ins',
|
|
|
|
'46': 'del',
|
|
|
|
'91': 'meta',
|
|
|
|
'93': 'meta',
|
|
|
|
'224': 'meta'
|
2016-05-06 08:05:51 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mapping for special characters so they can support
|
|
|
|
*
|
|
|
|
* this dictionary is only used incase you want to bind a
|
|
|
|
* keyup or keydown event to one of these keys
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
var _KEYCODE_MAP = {
|
2016-10-19 02:06:55 +08:00
|
|
|
'106': '*',
|
|
|
|
'107': '+',
|
|
|
|
'109': '-',
|
|
|
|
'110': '.',
|
|
|
|
'111' : '/',
|
|
|
|
'186': ';',
|
|
|
|
'187': '=',
|
|
|
|
'188': ',',
|
|
|
|
'189': '-',
|
|
|
|
'190': '.',
|
|
|
|
'191': '/',
|
|
|
|
'192': '`',
|
|
|
|
'219': '[',
|
|
|
|
'220': '\\',
|
|
|
|
'221': ']',
|
|
|
|
'222': '\''
|
2016-05-06 08:05:51 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this is a mapping of keys that require shift on a US keypad
|
|
|
|
* back to the non shift equivelents
|
|
|
|
*
|
|
|
|
* this is so you can use keyup events with these keys
|
|
|
|
*
|
|
|
|
* note that this will only work reliably on US keyboards
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
var _SHIFT_MAP = {
|
|
|
|
'~': '`',
|
|
|
|
'!': '1',
|
|
|
|
'@': '2',
|
|
|
|
'#': '3',
|
|
|
|
'$': '4',
|
|
|
|
'%': '5',
|
|
|
|
'^': '6',
|
|
|
|
'&': '7',
|
|
|
|
'*': '8',
|
|
|
|
'(': '9',
|
|
|
|
')': '0',
|
|
|
|
'_': '-',
|
|
|
|
'+': '=',
|
|
|
|
':': ';',
|
|
|
|
'\"': '\'',
|
|
|
|
'<': ',',
|
|
|
|
'>': '.',
|
|
|
|
'?': '/',
|
|
|
|
'|': '\\'
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this is a list of special strings you can use to map
|
|
|
|
* to modifier keys when you specify your keyboard shortcuts
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
var _SPECIAL_ALIASES = {
|
|
|
|
'option': 'alt',
|
|
|
|
'command': 'meta',
|
|
|
|
'return': 'enter',
|
|
|
|
'escape': 'esc',
|
|
|
|
'plus': '+',
|
|
|
|
'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* variable to store the flipped version of _MAP from above
|
|
|
|
* needed to check if we should use keypress or not when no action
|
|
|
|
* is specified
|
|
|
|
*
|
|
|
|
* @type {Object|undefined}
|
|
|
|
*/
|
|
|
|
var _REVERSE_SHIFT_MAP = {};
|
|
|
|
for (var key of Object.keys(_SHIFT_MAP)) {
|
|
|
|
_REVERSE_SHIFT_MAP[_SHIFT_MAP[key]] = key;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* loop through the f keys, f1 to f19 and add them to the map
|
|
|
|
* programatically
|
|
|
|
*/
|
|
|
|
for (var i = 1; i < 20; ++i) {
|
|
|
|
_MAP[111 + i] = 'f' + i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* loop through to map numbers on the numeric keypad
|
|
|
|
*/
|
|
|
|
for (i = 0; i <= 9; ++i) {
|
|
|
|
_MAP[i + 96] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
function characterFromEvent(e) {
|
|
|
|
// for keypress events we should return the character as is
|
|
|
|
if (e.type == 'keypress') {
|
|
|
|
var character = String.fromCharCode(e.which);
|
|
|
|
|
|
|
|
// if the shift key is not pressed then it is safe to assume
|
|
|
|
// that we want the character to be lowercase. this means if
|
|
|
|
// you accidentally have caps lock on then your key bindings
|
|
|
|
// will continue to work
|
|
|
|
//
|
|
|
|
// the only side effect that might not be desired is if you
|
|
|
|
// bind something like 'A' cause you want to trigger an
|
|
|
|
// event when capital A is pressed caps lock will no longer
|
|
|
|
// trigger the event. shift+a will though.
|
|
|
|
if (!e.shiftKey) {
|
|
|
|
character = character.toLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
return character;
|
|
|
|
}
|
|
|
|
|
|
|
|
// for non keypress events the special maps are needed
|
|
|
|
if (_MAP[e.which]) {
|
|
|
|
return _MAP[e.which];
|
|
|
|
}
|
|
|
|
|
2016-10-19 02:06:55 +08:00
|
|
|
if (_KEYCODE_MAP[`${e.which}`]) {
|
|
|
|
return _KEYCODE_MAP[`${e.which}`];
|
2016-05-06 08:05:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// if it is not in the special map
|
|
|
|
|
|
|
|
// with keydown and keyup events the character seems to always
|
|
|
|
// come in as an uppercase character whether you are pressing shift
|
|
|
|
// or not. we should make sure it is always lowercase for comparisons
|
|
|
|
return String.fromCharCode(e.which).toLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* takes a key event and figures out what the modifiers are
|
|
|
|
*
|
|
|
|
* @param {Event} e
|
|
|
|
* @returns {Array}
|
|
|
|
*/
|
|
|
|
function eventModifiers(e) {
|
|
|
|
var modifiers = [];
|
|
|
|
|
|
|
|
if (e.shiftKey) {
|
|
|
|
modifiers.push('shift');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.altKey) {
|
|
|
|
modifiers.push('alt');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.ctrlKey) {
|
|
|
|
modifiers.push('ctrl');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.metaKey) {
|
|
|
|
modifiers.push('meta');
|
|
|
|
}
|
|
|
|
|
|
|
|
return modifiers;
|
|
|
|
}
|
|
|
|
|
|
|
|
function keyAndModifiersForEvent(e) {
|
|
|
|
var eventKey = characterFromEvent(e);
|
|
|
|
var eventMods = eventModifiers(e);
|
|
|
|
if (_REVERSE_SHIFT_MAP[eventKey] && (eventMods.indexOf('shift') !== -1)) {
|
|
|
|
eventKey = _REVERSE_SHIFT_MAP[eventKey];
|
|
|
|
eventMods = eventMods.filter((k) => k !== 'shift');
|
|
|
|
}
|
|
|
|
return [eventKey, eventMods];
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {characterFromEvent, eventModifiers, keyAndModifiersForEvent};
|