Fallback for missing keypress events
IE and Edge have some corner cases (e.g. Ctrl+key) where we get insufficient information in the keydown event, and we never get a keypress event. Try to make a guess of the key in those cases.
This commit is contained in:
parent
7e79dfe425
commit
7cac5c8e9f
|
@ -187,6 +187,10 @@ Keyboard.prototype = {
|
||||||
// just check for the presence of that field)
|
// just check for the presence of that field)
|
||||||
if (!keysym && (!e.key || isIE() || isEdge())) {
|
if (!keysym && (!e.key || isIE() || isEdge())) {
|
||||||
this._pendingKey = code;
|
this._pendingKey = code;
|
||||||
|
// However we might not get a keypress event if the key
|
||||||
|
// is non-printable, which needs some special fallback
|
||||||
|
// handling
|
||||||
|
setTimeout(this._handleKeyPressTimeout.bind(this), 10, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,6 +233,43 @@ Keyboard.prototype = {
|
||||||
|
|
||||||
this._sendKeyEvent(keysym, code, true);
|
this._sendKeyEvent(keysym, code, true);
|
||||||
},
|
},
|
||||||
|
_handleKeyPressTimeout: function (e) {
|
||||||
|
if (!this._focused) { return; }
|
||||||
|
|
||||||
|
// Did someone manage to sort out the key already?
|
||||||
|
if (this._pendingKey === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var code, keysym;
|
||||||
|
|
||||||
|
code = this._pendingKey;
|
||||||
|
this._pendingKey = null;
|
||||||
|
|
||||||
|
// We have no way of knowing the proper keysym with the
|
||||||
|
// information given, but the following are true for most
|
||||||
|
// layouts
|
||||||
|
if ((e.keyCode >= 0x30) && (e.keyCode <= 0x39)) {
|
||||||
|
// Digit
|
||||||
|
keysym = e.keyCode;
|
||||||
|
} else if ((e.keyCode >= 0x41) && (e.keyCode <= 0x5a)) {
|
||||||
|
// Character (A-Z)
|
||||||
|
var char = String.fromCharCode(e.keyCode);
|
||||||
|
// A feeble attempt at the correct case
|
||||||
|
if (e.shiftKey)
|
||||||
|
char = char.toUpperCase();
|
||||||
|
else
|
||||||
|
char = char.toLowerCase();
|
||||||
|
keysym = char.charCodeAt();
|
||||||
|
} else {
|
||||||
|
// Unknown, give up
|
||||||
|
keysym = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._keyDownList[code] = keysym;
|
||||||
|
|
||||||
|
this._sendKeyEvent(keysym, code, true);
|
||||||
|
},
|
||||||
|
|
||||||
_handleKeyUp: function (e) {
|
_handleKeyUp: function (e) {
|
||||||
if (!this._focused) { return; }
|
if (!this._focused) { return; }
|
||||||
|
|
|
@ -92,6 +92,46 @@ describe('Key Event Handling', function() {
|
||||||
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
|
||||||
kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61}));
|
kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61}));
|
||||||
});
|
});
|
||||||
|
it('should guess key if no keypress and numeric key', function(done) {
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
expect(keysym).to.be.equal(0x32);
|
||||||
|
expect(code).to.be.equal('Digit2');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
done();
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'Digit2', keyCode: 0x32}));
|
||||||
|
});
|
||||||
|
it('should guess key if no keypress and alpha key', function(done) {
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
expect(code).to.be.equal('KeyA');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
done();
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: false}));
|
||||||
|
});
|
||||||
|
it('should guess key if no keypress and alpha key (with shift)', function(done) {
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
expect(keysym).to.be.equal(0x41);
|
||||||
|
expect(code).to.be.equal('KeyA');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
done();
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41, shiftKey: true}));
|
||||||
|
});
|
||||||
|
it('should not guess key if no keypress and unknown key', function(done) {
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
expect(keysym).to.be.equal(0);
|
||||||
|
expect(code).to.be.equal('KeyA');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
done();
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x09}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('suppress the right events at the right time', function() {
|
describe('suppress the right events at the right time', function() {
|
||||||
|
|
Loading…
Reference in New Issue