UNPKG

spatial-navigation

Version:

A javascript-based implementation of Spatial Navigation.

195 lines (152 loc) 5.26 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _EventAggregator = require('./EventAggregator'); var _EventAggregator2 = _interopRequireDefault(_EventAggregator); var _constants = require('./util/constants'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Keyboard = function () { function Keyboard() { _classCallCheck(this, Keyboard); this.normalizedMap = {}; this.bindListeners(); } /** * * @param keyCode * @param {string|KeyboardEvent} modifier - cmdKey, ctrlKey * @returns {string} */ _createClass(Keyboard, [{ key: 'addToMap', /** * * @param mapping {Array|Object} * @returns {{}} */ value: function addToMap(mapping) { var _this = this; var normalizedMap = {}; if (!Boolean(mapping.constructor.name === 'Array')) { mapping = [mapping]; } mapping.forEach(function (map) { // TODO map doesn't contain modifier, so there is error in getEventKey var eventKey = Keyboard.getEventKey(map.keyCode, map.modifier); if (Boolean(eventKey in _this.normalizedMap)) { console.warn('Keymap ' + eventKey + ' already exists'); } _this.normalizedMap[eventKey] = map; normalizedMap[eventKey] = map; }); return normalizedMap; } /** * @static * @param {KeyboardEvent} event * @param {string} modifier */ }, { key: 'bindListeners', value: function bindListeners() { var thr = Keyboard.throttle(this.keyPress.bind(this), _constants.EVENT_DELAY); window.addEventListener('keydown', thr); window.addEventListener('keyup', thr.finish); } /** * * @param {KeyboardEvent} event * @returns {boolean} */ }, { key: 'keyPress', value: function keyPress(event) { var eventKey = Keyboard.getEventKey(event.keyCode, event); if (!Boolean(eventKey in this.normalizedMap) // this condition need for `throttle` method. If press `ctrl + F`, key up `F` throttling continue || !Boolean(Keyboard.getModifier(event, this.normalizedMap[eventKey].modifier))) { return true; } event.preventDefault(); _EventAggregator2.default.dispatchEvent(_constants.EVENT_PREFIX + 'keypress', eventKey); var eventName = this.normalizedMap[eventKey].name; if (Boolean(eventName)) { _EventAggregator2.default.dispatchEvent(_constants.EVENT_PREFIX + 'navigate', eventName); _EventAggregator2.default.dispatchEvent('' + _constants.EVENT_PREFIX + eventName); } return true; } }], [{ key: 'getEventKey', value: function getEventKey(keyCode, modifier) { var key = [keyCode]; if (modifier && modifier.constructor.name === 'KeyboardEvent') { if (modifier.metaKey) { key.push('meta'); } else if (modifier.ctrlKey) { key.push('ctrl'); } else if (modifier.shiftKey) { key.push('shift'); } else if (modifier.altKey) { key.push('alt'); } } else if (Boolean(modifier)) { key.push(modifier); } return key.join('|'); } }, { key: 'getModifier', value: function getModifier(event, modifier) { switch (modifier) { case 'meta': return event.metaKey; case 'ctrl': return event.ctrlKey; case 'shift': return event.shiftKey; case 'alt': return event.altKey; default: return true; } } }]); return Keyboard; }(); Keyboard.throttle = function (func, threshold) { var id = null; var isThrottled = false; var callTimer = void 0; var clearVariables = function clearVariables() { id = null; isThrottled = false; }; /** * @param {KeyboardEvent} event */ var wrapper = function wrapper(event) { var _this2 = this; var eventKey = Keyboard.getEventKey(event.keyCode, event); if (id !== eventKey || eventKey.match(/\|/)) { func.call(this, event); id = eventKey; } if (!isThrottled) { isThrottled = true; callTimer = setTimeout(function () { isThrottled = !func.call(_this2, event); }, threshold); } }; wrapper.__proto__.finish = function () { clearVariables(); clearTimeout(callTimer); }; return wrapper; }; exports.default = new Keyboard(); module.exports = exports['default'];