123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import {
- isFunction
- } from 'min-dash';
- import {
- event as domEvent,
- matches as domMatches
- } from 'min-dom';
- import {
- hasModifier,
- isCmd,
- isKey,
- isShift
- } from './KeyboardUtil';
- var KEYDOWN_EVENT = 'keyboard.keydown';
- var DEFAULT_PRIORITY = 1000;
- /**
- * A keyboard abstraction that may be activated and
- * deactivated by users at will, consuming key events
- * and triggering diagram actions.
- *
- * For keys pressed down, keyboard fires `keyboard.keydown` event.
- * The event context contains one field which is `KeyboardEvent` event.
- *
- * The implementation fires the following key events that allow
- * other components to hook into key handling:
- *
- * - keyboard.bind
- * - keyboard.unbind
- * - keyboard.init
- * - keyboard.destroy
- *
- * All events contain one field which is node.
- *
- * A default binding for the keyboard may be specified via the
- * `keyboard.bindTo` configuration option.
- *
- * @param {Config} config
- * @param {EventBus} eventBus
- */
- export default function Keyboard(config, eventBus) {
- var self = this;
- this._config = config || {};
- this._eventBus = eventBus;
- this._keyHandler = this._keyHandler.bind(this);
- // properly clean dom registrations
- eventBus.on('diagram.destroy', function() {
- self._fire('destroy');
- self.unbind();
- });
- eventBus.on('diagram.init', function() {
- self._fire('init');
- });
- eventBus.on('attach', function() {
- if (config && config.bindTo) {
- self.bind(config.bindTo);
- }
- });
- eventBus.on('detach', function() {
- self.unbind();
- });
- }
- Keyboard.$inject = [
- 'config.keyboard',
- 'eventBus'
- ];
- Keyboard.prototype._keyHandler = function(event) {
- var target = event.target,
- eventBusResult;
- if (isInput(target)) {
- return;
- }
- var context = {
- keyEvent: event
- };
- eventBusResult = this._eventBus.fire(KEYDOWN_EVENT, context);
- if (eventBusResult) {
- event.preventDefault();
- }
- };
- Keyboard.prototype.bind = function(node) {
- // make sure that the keyboard is only bound once to the DOM
- this.unbind();
- this._node = node;
- // bind key events
- domEvent.bind(node, 'keydown', this._keyHandler, true);
- this._fire('bind');
- };
- Keyboard.prototype.getBinding = function() {
- return this._node;
- };
- Keyboard.prototype.unbind = function() {
- var node = this._node;
- if (node) {
- this._fire('unbind');
- // unbind key events
- domEvent.unbind(node, 'keydown', this._keyHandler, true);
- }
- this._node = null;
- };
- Keyboard.prototype._fire = function(event) {
- this._eventBus.fire('keyboard.' + event, { node: this._node });
- };
- /**
- * Add a listener function that is notified with `KeyboardEvent` whenever
- * the keyboard is bound and the user presses a key. If no priority is
- * provided, the default value of 1000 is used.
- *
- * @param {Number} priority
- * @param {Function} listener
- */
- Keyboard.prototype.addListener = function(priority, listener) {
- if (isFunction(priority)) {
- listener = priority;
- priority = DEFAULT_PRIORITY;
- }
- this._eventBus.on(KEYDOWN_EVENT, priority, listener);
- };
- Keyboard.prototype.hasModifier = hasModifier;
- Keyboard.prototype.isCmd = isCmd;
- Keyboard.prototype.isShift = isShift;
- Keyboard.prototype.isKey = isKey;
- // helpers ///////
- function isInput(target) {
- return target && (domMatches(target, 'input, textarea') || target.contentEditable === 'true');
- }
|