Skip to content

Commit

Permalink
feat(keyboard): specify which keys are handled
Browse files Browse the repository at this point in the history
  • Loading branch information
marstamm committed Oct 12, 2021
1 parent 9dff2ab commit 253dc34
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
29 changes: 28 additions & 1 deletion lib/features/keyboard/Keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
var KEYDOWN_EVENT = 'keyboard.keydown',
KEYUP_EVENT = 'keyboard.keyup';

var HANDLE_MODIFIER_ATTRIBUTE = 'input-handle-modified-keys';

var DEFAULT_PRIORITY = 1000;

/**
Expand Down Expand Up @@ -106,7 +108,32 @@ Keyboard.prototype._keyHandler = function(event, type) {
};

Keyboard.prototype._isEventIgnored = function(event) {
return isInput(event.target) && !isCmd(event);
return isInput(event.target) && this._isModifiedKeyIgnored(event);
};

Keyboard.prototype._isModifiedKeyIgnored = function(event) {
if (!isCmd(event)) {
return true;
}

var allowedModifiers = this._getAllowedModifiers(event.target);
return !allowedModifiers.includes(event.key);
};

Keyboard.prototype._getAllowedModifiers = function(element) {
if (!element || element === document) {
return [];
}

if (element.hasAttribute(HANDLE_MODIFIER_ATTRIBUTE)) {
return element.getAttribute(HANDLE_MODIFIER_ATTRIBUTE).split(',');
}

if (element === this._node) {
return [];
}

return this._getAllowedModifiers(element.parentElement || element.parentNode);
};

Keyboard.prototype.bind = function(node) {
Expand Down
69 changes: 68 additions & 1 deletion test/spec/features/keyboard/KeyboardSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import TestContainer from 'mocha-test-container-support';
import {
assign
} from 'min-dash';
import {
domify
} from 'min-dom';

import modelingModule from 'lib/features/modeling';
import keyboardModule from 'lib/features/keyboard';
Expand Down Expand Up @@ -154,7 +157,7 @@ describe('features/keyboard', function() {
);


it('should fire modifier event if target is input field', inject(
it('should not fire modifier event if target is input field', inject(
function(keyboard, eventBus) {

// given
Expand All @@ -167,11 +170,75 @@ describe('features/keyboard', function() {
keyboard._keyHandler({ key: TEST_KEY, metaKey: true, target: inputField });
keyboard._keyHandler({ key: TEST_KEY, ctrlKey: true, target: inputField });

// then
expect(eventBusSpy).to.not.be.called;
})
);


it('should fire modifier event if target is input field and requesting it', inject(
function(keyboard, eventBus) {

// given
var eventBusSpy = sinon.spy(eventBus, 'fire');

var inputField = domify('<input></input>');
testDiv.appendChild(inputField);
testDiv.setAttribute('input-handle-modified-keys', 'a');

// when
keyboard._keyHandler({ key: 'a', metaKey: true, target: inputField });
keyboard._keyHandler({ key: 'a', ctrlKey: true, target: inputField });

// then
expect(eventBusSpy).to.have.been.calledTwice;
})
);


it('should not fire modifier event if target is input field and not requesting it', inject(
function(keyboard, eventBus) {

// given
var eventBusSpy = sinon.spy(eventBus, 'fire');

var inputField = domify('<input></input>');
testDiv.appendChild(inputField);
testDiv.setAttribute('input-handle-modified-keys', 'a');

// when
keyboard._keyHandler({ key: 'b', metaKey: true, target: inputField });
keyboard._keyHandler({ key: 'b', ctrlKey: true, target: inputField });

// then
expect(eventBusSpy).to.not.be.called;
})
);


it('should not fire modifier event if the requesting element is outside of binding', inject(
function(keyboard, eventBus) {

// given
var inputContainer = domify('<div class="container"><input /></div>'),
inputField = inputContainer.querySelector('input');

testDiv.appendChild(inputContainer);
testDiv.setAttribute('input-handle-modified-keys', 'a');

keyboard.bind(inputContainer);

var eventBusSpy = sinon.spy(eventBus, 'fire');

// when
keyboard._keyHandler({ key: 'a', metaKey: true, target: inputField });
keyboard._keyHandler({ key: 'a', ctrlKey: true, target: inputField });

// then
expect(eventBusSpy).to.not.be.called;
})
);

});


Expand Down

0 comments on commit 253dc34

Please sign in to comment.