Fake key release for iOS hardware keyboards
iOS sends decent key down events, but junk key up events when a hardware keyboard is used. This confuses the key tracking as a corresponding release is then never detected. To work around this we'll treat the hardware keyboard like the virtual ones and send the key release right away.
This commit is contained in:
parent
637a282be5
commit
9e99ce126c
|
@ -44,6 +44,12 @@ function isMac() {
|
||||||
function isWindows() {
|
function isWindows() {
|
||||||
return navigator && !!(/win/i).exec(navigator.platform);
|
return navigator && !!(/win/i).exec(navigator.platform);
|
||||||
}
|
}
|
||||||
|
function isIOS() {
|
||||||
|
return navigator &&
|
||||||
|
(!!(/ipad/i).exec(navigator.platform) ||
|
||||||
|
!!(/iphone/i).exec(navigator.platform) ||
|
||||||
|
!!(/ipod/i).exec(navigator.platform));
|
||||||
|
}
|
||||||
|
|
||||||
Keyboard.prototype = {
|
Keyboard.prototype = {
|
||||||
// private methods
|
// private methods
|
||||||
|
@ -106,13 +112,15 @@ Keyboard.prototype = {
|
||||||
|
|
||||||
// We cannot handle keys we cannot track, but we also need
|
// We cannot handle keys we cannot track, but we also need
|
||||||
// to deal with virtual keyboards which omit key info
|
// to deal with virtual keyboards which omit key info
|
||||||
if (code === 'Unidentified') {
|
// (iOS omits tracking info on keyup events, which forces us to
|
||||||
|
// special treat that platform here)
|
||||||
|
if ((code === 'Unidentified') || isIOS()) {
|
||||||
if (keysym) {
|
if (keysym) {
|
||||||
// If it's a virtual keyboard then it should be
|
// If it's a virtual keyboard then it should be
|
||||||
// sufficient to just send press and release right
|
// sufficient to just send press and release right
|
||||||
// after each other
|
// after each other
|
||||||
this._sendKeyEvent(keysym, 'Unidentified', true);
|
this._sendKeyEvent(keysym, code, true);
|
||||||
this._sendKeyEvent(keysym, 'Unidentified', false);
|
this._sendKeyEvent(keysym, code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopEvent(e);
|
stopEvent(e);
|
||||||
|
|
|
@ -124,6 +124,77 @@ describe('Key Event Handling', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Fake keyup', function() {
|
||||||
|
it('should fake keyup events for virtual keyboards', function(done) {
|
||||||
|
if (isIE() || isEdge()) this.skip();
|
||||||
|
var count = 0;
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
switch (count++) {
|
||||||
|
case 0:
|
||||||
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
expect(code).to.be.equal('Unidentified');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
expect(code).to.be.equal('Unidentified');
|
||||||
|
expect(down).to.be.equal(false);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'Unidentified', key: 'a'}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('iOS', function() {
|
||||||
|
var origNavigator;
|
||||||
|
beforeEach(function () {
|
||||||
|
// window.navigator is a protected read-only property in many
|
||||||
|
// environments, so we need to redefine it whilst running these
|
||||||
|
// tests.
|
||||||
|
origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
|
||||||
|
if (origNavigator === undefined) {
|
||||||
|
// Object.getOwnPropertyDescriptor() doesn't work
|
||||||
|
// properly in any version of IE
|
||||||
|
this.skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(window, "navigator", {value: {}});
|
||||||
|
if (window.navigator.platform !== undefined) {
|
||||||
|
// Object.defineProperty() doesn't work properly in old
|
||||||
|
// versions of Chrome
|
||||||
|
this.skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.navigator.platform = "iPhone 9.0";
|
||||||
|
});
|
||||||
|
afterEach(function () {
|
||||||
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fake keyup events on iOS', function(done) {
|
||||||
|
if (isIE() || isEdge()) this.skip();
|
||||||
|
var count = 0;
|
||||||
|
var kbd = new Keyboard({
|
||||||
|
onKeyEvent: function(keysym, code, down) {
|
||||||
|
switch (count++) {
|
||||||
|
case 0:
|
||||||
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
expect(code).to.be.equal('KeyA');
|
||||||
|
expect(down).to.be.equal(true);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
expect(keysym).to.be.equal(0x61);
|
||||||
|
expect(code).to.be.equal('KeyA');
|
||||||
|
expect(down).to.be.equal(false);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', key: 'a'}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Track Key State', function() {
|
describe('Track Key State', function() {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
if (isIE() || isEdge()) this.skip();
|
if (isIE() || isEdge()) this.skip();
|
||||||
|
|
Loading…
Reference in New Issue