spatial-navigation
Version:
A javascript-based implementation of Spatial Navigation.
195 lines (152 loc) • 5.26 kB
JavaScript
;
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'];