UNPKG

grommet

Version:

The most advanced UX framework for enterprise applications.

159 lines (140 loc) 4.67 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _reactDom = require('react-dom'); var _DOM = require('./DOM'); // Allow callers to use key labels instead of key code numbers. // This makes their code easier to read. // (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP var KEYS = { backspace: 8, tab: 9, enter: 13, esc: 27, escape: 27, space: 32, left: 37, up: 38, right: 39, down: 40, comma: 188, shift: 16 }; var _keyboardAccelerators = {}; var _listeners = []; var _isKeyboardAcceleratorListening = false; var _onKeyboardAcceleratorKeyPress = function _onKeyboardAcceleratorKeyPress(e) { var key = e.keyCode ? e.keyCode : e.which; _listeners.slice().reverse().some(function (listener) { if (_keyboardAccelerators[listener]) { var handlers = _keyboardAccelerators[listener].handlers; if (handlers.hasOwnProperty(key)) { if (handlers[key] && handlers[key](e)) { return true; } } } return false; }); }; // KeyboardAccelerators is a utility for handling keyboard events. // Add listeners using startListeningToKeyboard(). // Remove listeners using stopListeningToKeyboard(). exports.default = { _initKeyboardAccelerators: function _initKeyboardAccelerators(element) { var id = (0, _DOM.generateId)(element); _keyboardAccelerators[id] = { handlers: {} }; }, _getKeyboardAcceleratorHandlers: function _getKeyboardAcceleratorHandlers(element) { var id = (0, _DOM.generateId)(element); return _keyboardAccelerators[id].handlers; }, _getDowns: function _getDowns(element) { var id = (0, _DOM.generateId)(element); return _keyboardAccelerators[id].downs; }, _isComponentListening: function _isComponentListening(element) { var id = (0, _DOM.generateId)(element); return _listeners.some(function (listener) { return listener === id; }); }, _subscribeComponent: function _subscribeComponent(element) { var id = (0, _DOM.generateId)(element); _listeners.push(id); }, _unsubscribeComponent: function _unsubscribeComponent(element) { var id = (0, _DOM.generateId)(element); var removeListenerIndex = _listeners.indexOf(id); _listeners.splice(removeListenerIndex, 1); delete _keyboardAccelerators[id]; }, // Add handlers for specific keys. // This function can be called multiple times, existing handlers will // be replaced, new handlers will be added. startListeningToKeyboard: function startListeningToKeyboard(component, handlers) { var element = (0, _reactDom.findDOMNode)(component); if (element) { this._initKeyboardAccelerators(element); var keys = 0; for (var key in handlers) { if (handlers.hasOwnProperty(key)) { var keyCode = key; if (KEYS.hasOwnProperty(key)) { keyCode = KEYS[key]; } keys += 1; this._getKeyboardAcceleratorHandlers(element)[keyCode] = handlers[key]; } } if (keys > 0) { if (!_isKeyboardAcceleratorListening) { window.addEventListener("keydown", _onKeyboardAcceleratorKeyPress); _isKeyboardAcceleratorListening = true; } if (!this._isComponentListening(element)) { this._subscribeComponent(element); } } } }, // Remove handlers for all keys or specific keys. // If no argument is passed in, all handlers are removed. // This function can be called multiple times, only the handlers // specified will be removed. stopListeningToKeyboard: function stopListeningToKeyboard(component, handlers) { var element = (0, _reactDom.findDOMNode)(component); if (!this._isComponentListening(element)) { return; } if (handlers) { for (var key in handlers) { if (handlers.hasOwnProperty(key)) { var keyCode = key; if (KEYS.hasOwnProperty(key)) { keyCode = KEYS[key]; } delete this._getKeyboardAcceleratorHandlers(element)[keyCode]; } } } var keyCount = 0; for (var keyHandler in this._getKeyboardAcceleratorHandlers(element)) { if (this._getKeyboardAcceleratorHandlers(element).hasOwnProperty(keyHandler)) { keyCount += 1; } } if (!handlers || 0 === keyCount) { this._initKeyboardAccelerators(element); this._unsubscribeComponent(element); } if (_listeners.length === 0) { window.removeEventListener("keydown", _onKeyboardAcceleratorKeyPress); _isKeyboardAcceleratorListening = false; } } }; module.exports = exports['default'];