Use standard DOM identifiers for physical keys
This commit is contained in:
parent
a5c8a755e8
commit
80cb8ffddd
|
@ -1,5 +1,6 @@
|
||||||
import KeyTable from "./keysym.js";
|
import KeyTable from "./keysym.js";
|
||||||
import keysyms from "./keysymdef.js";
|
import keysyms from "./keysymdef.js";
|
||||||
|
import vkeys from "./vkeys.js";
|
||||||
|
|
||||||
function isMac() {
|
function isMac() {
|
||||||
return navigator && !!(/mac/i).exec(navigator.platform);
|
return navigator && !!(/mac/i).exec(navigator.platform);
|
||||||
|
@ -131,18 +132,64 @@ export function ModifierSync(charModifier) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a key ID from a keyboard event
|
// Get 'KeyboardEvent.code', handling legacy browsers
|
||||||
// May be a string or an integer depending on the available properties
|
export function getKeycode(evt){
|
||||||
export function getKey(evt){
|
// Are we getting proper key identifiers?
|
||||||
if ('keyCode' in evt && 'key' in evt) {
|
// (unfortunately Firefox and Chrome are crappy here and gives
|
||||||
return evt.key + ':' + evt.keyCode;
|
// us an empty string on some platforms, rather than leaving it
|
||||||
|
// undefined)
|
||||||
|
if (evt.code) {
|
||||||
|
// Mozilla isn't fully in sync with the spec yet
|
||||||
|
switch (evt.code) {
|
||||||
|
case 'OSLeft': return 'MetaLeft';
|
||||||
|
case 'OSRight': return 'MetaRight';
|
||||||
|
}
|
||||||
|
|
||||||
|
return evt.code;
|
||||||
}
|
}
|
||||||
else if ('keyCode' in evt) {
|
|
||||||
return evt.keyCode;
|
// The de-facto standard is to use Windows Virtual-Key codes
|
||||||
}
|
// in the 'keyCode' field for non-printable characters. However
|
||||||
else {
|
// Webkit sets it to the same as charCode in 'keypress' events.
|
||||||
return evt.key;
|
if ((evt.type !== 'keypress') && (evt.keyCode in vkeys)) {
|
||||||
|
var code = vkeys[evt.keyCode];
|
||||||
|
|
||||||
|
// macOS has messed up this code for some reason
|
||||||
|
if (isMac() && (code === 'ContextMenu')) {
|
||||||
|
code = 'MetaRight';
|
||||||
|
}
|
||||||
|
|
||||||
|
// The keyCode doesn't distinguish between left and right
|
||||||
|
// for the standard modifiers
|
||||||
|
if (evt.location === 2) {
|
||||||
|
switch (code) {
|
||||||
|
case 'ShiftLeft': return 'ShiftRight';
|
||||||
|
case 'ControlLeft': return 'ControlRight';
|
||||||
|
case 'AltLeft': return 'AltRight';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nor a bunch of the numpad keys
|
||||||
|
if (evt.location === 3) {
|
||||||
|
switch (code) {
|
||||||
|
case 'Delete': return 'NumpadDecimal';
|
||||||
|
case 'Insert': return 'Numpad0';
|
||||||
|
case 'End': return 'Numpad1';
|
||||||
|
case 'ArrowDown': return 'Numpad2';
|
||||||
|
case 'PageDown': return 'Numpad3';
|
||||||
|
case 'ArrowLeft': return 'Numpad4';
|
||||||
|
case 'ArrowRight': return 'Numpad6';
|
||||||
|
case 'Home': return 'Numpad7';
|
||||||
|
case 'ArrowUp': return 'Numpad8';
|
||||||
|
case 'PageUp': return 'Numpad9';
|
||||||
|
case 'Enter': return 'NumpadEnter';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 'Unidentified';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the most reliable keysym value we can get from a key event
|
// Get the most reliable keysym value we can get from a key event
|
||||||
|
@ -290,7 +337,7 @@ export function QEMUKeyEventDecoder (modifierState, next) {
|
||||||
|
|
||||||
function process(evt, type) {
|
function process(evt, type) {
|
||||||
var result = {type: type};
|
var result = {type: type};
|
||||||
result.code = evt.code;
|
result.code = getKeycode(evt);
|
||||||
result.keysym = 0;
|
result.keysym = 0;
|
||||||
|
|
||||||
if (isNumPadMultiKey(evt)) {
|
if (isNumPadMultiKey(evt)) {
|
||||||
|
@ -298,7 +345,7 @@ export function QEMUKeyEventDecoder (modifierState, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
|
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
|
||||||
var isShift = evt.keyCode === 0x10 || evt.key === 'Shift';
|
var isShift = result.code === 'ShiftLeft' || result.code === 'ShiftRight';
|
||||||
|
|
||||||
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!nonCharacterKey(evt));
|
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!nonCharacterKey(evt));
|
||||||
|
|
||||||
|
@ -387,7 +434,7 @@ export function TrackQEMUKeyState (next) {
|
||||||
|
|
||||||
// Takes a DOM keyboard event and:
|
// Takes a DOM keyboard event and:
|
||||||
// - determines which keysym it represents
|
// - determines which keysym it represents
|
||||||
// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event)
|
// - determines a code identifying the key that was pressed (corresponding to the code/keyCode properties on the DOM event)
|
||||||
// - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down
|
// - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down
|
||||||
// - marks each event with an 'escape' property if a modifier was down which should be "escaped"
|
// - marks each event with an 'escape' property if a modifier was down which should be "escaped"
|
||||||
// - generates a "stall" event in cases where it might be necessary to wait and see if a keypress event follows a keydown
|
// - generates a "stall" event in cases where it might be necessary to wait and see if a keypress event follows a keydown
|
||||||
|
@ -401,10 +448,16 @@ export function KeyEventDecoder (modifierState, next) {
|
||||||
}
|
}
|
||||||
function process(evt, type) {
|
function process(evt, type) {
|
||||||
var result = {type: type};
|
var result = {type: type};
|
||||||
var keyId = getKey(evt);
|
var code = getKeycode(evt);
|
||||||
if (keyId) {
|
if (code === 'Unidentified') {
|
||||||
result.keyId = keyId;
|
// Unstable, but we don't have anything else to go on
|
||||||
|
// (don't use it for 'keypress' events thought since
|
||||||
|
// WebKit sets it to the same as charCode)
|
||||||
|
if (evt.keyCode && (evt.type !== 'keypress')) {
|
||||||
|
code = 'Platform' + evt.keyCode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
result.code = code;
|
||||||
|
|
||||||
var keysym = getKeysym(evt);
|
var keysym = getKeysym(evt);
|
||||||
|
|
||||||
|
@ -416,7 +469,7 @@ export function KeyEventDecoder (modifierState, next) {
|
||||||
result.keysym = keysym;
|
result.keysym = keysym;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isShift = evt.keyCode === 0x10 || evt.key === 'Shift';
|
var isShift = code === 'ShiftLeft' || code === 'ShiftRight';
|
||||||
|
|
||||||
// Should we prevent the browser from handling the event?
|
// Should we prevent the browser from handling the event?
|
||||||
// Doing so on a keydown (in most browsers) prevents keypress from being generated
|
// Doing so on a keydown (in most browsers) prevents keypress from being generated
|
||||||
|
@ -546,8 +599,8 @@ export function TrackKeyState (next) {
|
||||||
switch (evt.type) {
|
switch (evt.type) {
|
||||||
case 'keydown':
|
case 'keydown':
|
||||||
// insert a new entry if last seen key was different.
|
// insert a new entry if last seen key was different.
|
||||||
if (!last || !evt.keyId || last.keyId !== evt.keyId) {
|
if (!last || evt.code === 'Unidentified' || last.code !== evt.code) {
|
||||||
last = {keyId: evt.keyId, keysyms: {}};
|
last = {code: evt.code, keysyms: {}};
|
||||||
state.push(last);
|
state.push(last);
|
||||||
}
|
}
|
||||||
if (evt.keysym) {
|
if (evt.keysym) {
|
||||||
|
@ -560,7 +613,7 @@ export function TrackKeyState (next) {
|
||||||
break;
|
break;
|
||||||
case 'keypress':
|
case 'keypress':
|
||||||
if (!last) {
|
if (!last) {
|
||||||
last = {keyId: evt.keyId, keysyms: {}};
|
last = {code: evt.code, keysyms: {}};
|
||||||
state.push(last);
|
state.push(last);
|
||||||
}
|
}
|
||||||
if (!evt.keysym) {
|
if (!evt.keysym) {
|
||||||
|
@ -582,7 +635,7 @@ export function TrackKeyState (next) {
|
||||||
var idx = null;
|
var idx = null;
|
||||||
// do we have a matching key tracked as being down?
|
// do we have a matching key tracked as being down?
|
||||||
for (var i = 0; i !== state.length; ++i) {
|
for (var i = 0; i !== state.length; ++i) {
|
||||||
if (state[i].keyId === evt.keyId) {
|
if (state[i].code === evt.code) {
|
||||||
idx = i;
|
idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -609,7 +662,7 @@ export function TrackKeyState (next) {
|
||||||
for (var i = 0; i < state.length; ++i) {
|
for (var i = 0; i < state.length; ++i) {
|
||||||
for (var key in state[i].keysyms) {
|
for (var key in state[i].keysyms) {
|
||||||
var keysym = state[i].keysyms[key];
|
var keysym = state[i].keysyms[key];
|
||||||
next({keyId: 0, keysym: keysym, type: 'keyup'});
|
next({code: 'Unidentified', keysym: keysym, type: 'keyup'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* jshint shadow: false */
|
/* jshint shadow: false */
|
||||||
|
@ -629,14 +682,14 @@ export function EscapeModifiers (next) {
|
||||||
}
|
}
|
||||||
// undo modifiers
|
// undo modifiers
|
||||||
for (var i = 0; i < evt.escape.length; ++i) {
|
for (var i = 0; i < evt.escape.length; ++i) {
|
||||||
next({type: 'keyup', keyId: 0, keysym: evt.escape[i]});
|
next({type: 'keyup', code: 'Unidentified', keysym: evt.escape[i]});
|
||||||
}
|
}
|
||||||
// send the character event
|
// send the character event
|
||||||
next(evt);
|
next(evt);
|
||||||
// redo modifiers
|
// redo modifiers
|
||||||
/* jshint shadow: true */
|
/* jshint shadow: true */
|
||||||
for (var i = 0; i < evt.escape.length; ++i) {
|
for (var i = 0; i < evt.escape.length; ++i) {
|
||||||
next({type: 'keydown', keyId: 0, keysym: evt.escape[i]});
|
next({type: 'keydown', code: 'Unidentified', keysym: evt.escape[i]});
|
||||||
}
|
}
|
||||||
/* jshint shadow: false */
|
/* jshint shadow: false */
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* noVNC: HTML5 VNC client
|
||||||
|
* Copyright (C) 2017 Pierre Ossman for Cendio AB
|
||||||
|
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mapping between Microsoft® Windows® Virtual-Key codes and
|
||||||
|
* HTML key codes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
0x08: 'Backspace',
|
||||||
|
0x09: 'Tab',
|
||||||
|
0x0a: 'NumpadClear',
|
||||||
|
0x0d: 'Enter',
|
||||||
|
0x10: 'ShiftLeft',
|
||||||
|
0x11: 'ControlLeft',
|
||||||
|
0x12: 'AltLeft',
|
||||||
|
0x13: 'Pause',
|
||||||
|
0x14: 'CapsLock',
|
||||||
|
0x15: 'Lang1',
|
||||||
|
0x19: 'Lang2',
|
||||||
|
0x1b: 'Escape',
|
||||||
|
0x1c: 'Convert',
|
||||||
|
0x1d: 'NonConvert',
|
||||||
|
0x20: 'Space',
|
||||||
|
0x21: 'PageUp',
|
||||||
|
0x22: 'PageDown',
|
||||||
|
0x23: 'End',
|
||||||
|
0x24: 'Home',
|
||||||
|
0x25: 'ArrowLeft',
|
||||||
|
0x26: 'ArrowUp',
|
||||||
|
0x27: 'ArrowRight',
|
||||||
|
0x28: 'ArrowDown',
|
||||||
|
0x29: 'Select',
|
||||||
|
0x2c: 'PrintScreen',
|
||||||
|
0x2d: 'Insert',
|
||||||
|
0x2e: 'Delete',
|
||||||
|
0x2f: 'Help',
|
||||||
|
0x30: 'Digit0',
|
||||||
|
0x31: 'Digit1',
|
||||||
|
0x32: 'Digit2',
|
||||||
|
0x33: 'Digit3',
|
||||||
|
0x34: 'Digit4',
|
||||||
|
0x35: 'Digit5',
|
||||||
|
0x36: 'Digit6',
|
||||||
|
0x37: 'Digit7',
|
||||||
|
0x38: 'Digit8',
|
||||||
|
0x39: 'Digit9',
|
||||||
|
0x5b: 'MetaLeft',
|
||||||
|
0x5c: 'MetaRight',
|
||||||
|
0x5d: 'ContextMenu',
|
||||||
|
0x5f: 'Sleep',
|
||||||
|
0x60: 'Numpad0',
|
||||||
|
0x61: 'Numpad1',
|
||||||
|
0x62: 'Numpad2',
|
||||||
|
0x63: 'Numpad3',
|
||||||
|
0x64: 'Numpad4',
|
||||||
|
0x65: 'Numpad5',
|
||||||
|
0x66: 'Numpad6',
|
||||||
|
0x67: 'Numpad7',
|
||||||
|
0x68: 'Numpad8',
|
||||||
|
0x69: 'Numpad9',
|
||||||
|
0x6a: 'NumpadMultiply',
|
||||||
|
0x6b: 'NumpadAdd',
|
||||||
|
0x6c: 'NumpadDecimal',
|
||||||
|
0x6d: 'NumpadSubtract',
|
||||||
|
0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows
|
||||||
|
0x6f: 'NumpadDivide',
|
||||||
|
0x70: 'F1',
|
||||||
|
0x71: 'F2',
|
||||||
|
0x72: 'F3',
|
||||||
|
0x73: 'F4',
|
||||||
|
0x74: 'F5',
|
||||||
|
0x75: 'F6',
|
||||||
|
0x76: 'F7',
|
||||||
|
0x77: 'F8',
|
||||||
|
0x78: 'F9',
|
||||||
|
0x79: 'F10',
|
||||||
|
0x7a: 'F11',
|
||||||
|
0x7b: 'F12',
|
||||||
|
0x7c: 'F13',
|
||||||
|
0x7d: 'F14',
|
||||||
|
0x7e: 'F15',
|
||||||
|
0x7f: 'F16',
|
||||||
|
0x80: 'F17',
|
||||||
|
0x81: 'F18',
|
||||||
|
0x82: 'F19',
|
||||||
|
0x83: 'F20',
|
||||||
|
0x84: 'F21',
|
||||||
|
0x85: 'F22',
|
||||||
|
0x86: 'F23',
|
||||||
|
0x87: 'F24',
|
||||||
|
0x90: 'NumLock',
|
||||||
|
0x91: 'ScrollLock',
|
||||||
|
0xa6: 'BrowserBack',
|
||||||
|
0xa7: 'BrowserForward',
|
||||||
|
0xa8: 'BrowserRefresh',
|
||||||
|
0xa9: 'BrowserStop',
|
||||||
|
0xaa: 'BrowserSearch',
|
||||||
|
0xab: 'BrowserFavorites',
|
||||||
|
0xac: 'BrowserHome',
|
||||||
|
0xad: 'AudioVolumeMute',
|
||||||
|
0xae: 'AudioVolumeDown',
|
||||||
|
0xaf: 'AudioVolumeUp',
|
||||||
|
0xb0: 'MediaTrackNext',
|
||||||
|
0xb1: 'MediaTrackPrevious',
|
||||||
|
0xb2: 'MediaStop',
|
||||||
|
0xb3: 'MediaPlayPause',
|
||||||
|
0xb4: 'LaunchMail',
|
||||||
|
0xb5: 'MediaSelect',
|
||||||
|
0xb6: 'LaunchApp1',
|
||||||
|
0xb7: 'LaunchApp2',
|
||||||
|
0xe1: 'AltRight', // Only when it is AltGraph
|
||||||
|
};
|
|
@ -112,8 +112,6 @@ export default {
|
||||||
"Delete": 0xE053,
|
"Delete": 0xE053,
|
||||||
"MetaLeft": 0xE05B,
|
"MetaLeft": 0xE05B,
|
||||||
"MetaRight": 0xE05C,
|
"MetaRight": 0xE05C,
|
||||||
"OSLeft": 0xE05B, // OSLeft and OSRight are kept for compatability since
|
|
||||||
"OSRight": 0xE05C, // Firefox haven't updated to MetaLeft and MetaRight yet
|
|
||||||
"ContextMenu": 0xE05D,
|
"ContextMenu": 0xE05D,
|
||||||
"BrowserSearch": 0xE065,
|
"BrowserSearch": 0xE065,
|
||||||
"BrowserFavorites": 0xE066,
|
"BrowserFavorites": 0xE066,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<script src="../core/input/keysym.js"></script>
|
<script src="../core/input/keysym.js"></script>
|
||||||
<script src="../core/input/keysymdef.js"></script>
|
<script src="../core/input/keysymdef.js"></script>
|
||||||
<script src="../core/input/xtscancodes.js"></script>
|
<script src="../core/input/xtscancodes.js"></script>
|
||||||
|
<script src="../core/input/vkeys.js"></script>
|
||||||
<script src="../core/input/util.js"></script>
|
<script src="../core/input/util.js"></script>
|
||||||
<script src="../core/input/devices.js"></script>
|
<script src="../core/input/devices.js"></script>
|
||||||
<script src="../core/display.js"></script>
|
<script src="../core/display.js"></script>
|
||||||
|
|
|
@ -33,6 +33,71 @@ describe('Helpers', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getKeycode', function() {
|
||||||
|
it('should pass through proper code', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({code: 'Semicolon'})).to.be.equal('Semicolon');
|
||||||
|
});
|
||||||
|
it('should map legacy values', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({code: ''})).to.be.equal('Unidentified');
|
||||||
|
expect(KeyboardUtil.getKeycode({code: 'OSLeft'})).to.be.equal('MetaLeft');
|
||||||
|
});
|
||||||
|
it('should map keyCode to code when possible', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x14})).to.be.equal('CapsLock');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x5b})).to.be.equal('MetaLeft');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x35})).to.be.equal('Digit5');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x65})).to.be.equal('Numpad5');
|
||||||
|
});
|
||||||
|
it('should map keyCode left/right side', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 1})).to.be.equal('ShiftLeft');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x10, location: 2})).to.be.equal('ShiftRight');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 1})).to.be.equal('ControlLeft');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x11, location: 2})).to.be.equal('ControlRight');
|
||||||
|
});
|
||||||
|
it('should map keyCode on numpad', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 0})).to.be.equal('Enter');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x0d, location: 3})).to.be.equal('NumpadEnter');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 0})).to.be.equal('End');
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x23, location: 3})).to.be.equal('Numpad1');
|
||||||
|
});
|
||||||
|
it('should return Unidentified when it cannot map the keyCode', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({keycode: 0x42})).to.be.equal('Unidentified');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Fix Meta on macOS', 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 = "Mac x86_64";
|
||||||
|
});
|
||||||
|
afterEach(function () {
|
||||||
|
Object.defineProperty(window, "navigator", origNavigator);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respect ContextMenu on modern browser', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({code: 'ContextMenu', keyCode: 0x5d})).to.be.equal('ContextMenu');
|
||||||
|
});
|
||||||
|
it('should translate legacy ContextMenu to MetaRight', function() {
|
||||||
|
expect(KeyboardUtil.getKeycode({keyCode: 0x5d})).to.be.equal('MetaRight');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getKeysym', function() {
|
describe('getKeysym', function() {
|
||||||
it('should prefer char', function() {
|
it('should prefer char', function() {
|
||||||
expect(KeyboardUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x61);
|
expect(KeyboardUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.be.equal(0x61);
|
||||||
|
|
|
@ -12,26 +12,26 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.an.object;
|
expect(evt).to.be.an.object;
|
||||||
done();
|
done();
|
||||||
}).keydown({keyCode: 0x41});
|
}).keydown({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should pass the right keysym through', function(done) {
|
it('should pass the right keysym through', function(done) {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt.keysym).to.be.deep.equal(0x61);
|
expect(evt.keysym).to.be.deep.equal(0x61);
|
||||||
done();
|
done();
|
||||||
}).keypress({keyCode: 0x41});
|
}).keypress({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should pass the right keyid through', function(done) {
|
it('should pass the right keyid through', function(done) {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.have.property('keyId', 0x41);
|
expect(evt).to.have.property('code', 'KeyA');
|
||||||
done();
|
done();
|
||||||
}).keydown({keyCode: 0x41});
|
}).keydown({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should not sync modifiers on a keypress', function() {
|
it('should not sync modifiers on a keypress', function() {
|
||||||
// Firefox provides unreliable modifier state on keypress events
|
// Firefox provides unreliable modifier state on keypress events
|
||||||
var count = 0;
|
var count = 0;
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
++count;
|
++count;
|
||||||
}).keypress({keyCode: 0x41, ctrlKey: true});
|
}).keypress({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
|
||||||
expect(count).to.be.equal(1);
|
expect(count).to.be.equal(1);
|
||||||
});
|
});
|
||||||
it('should sync modifiers if necessary', function(done) {
|
it('should sync modifiers if necessary', function(done) {
|
||||||
|
@ -43,29 +43,29 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
++count;
|
++count;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown', keysym: 0x61});
|
expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown', keysym: 0x61});
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}).keydown({keyCode: 0x41, ctrlKey: true});
|
}).keydown({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
|
||||||
});
|
});
|
||||||
it('should forward keydown events with the right type', function(done) {
|
it('should forward keydown events with the right type', function(done) {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown'});
|
||||||
done();
|
done();
|
||||||
}).keydown({keyCode: 0x41});
|
}).keydown({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should forward keyup events with the right type', function(done) {
|
it('should forward keyup events with the right type', function(done) {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keyup'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keyup'});
|
||||||
done();
|
done();
|
||||||
}).keyup({keyCode: 0x41});
|
}).keyup({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should forward keypress events with the right type', function(done) {
|
it('should forward keypress events with the right type', function(done) {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keypress'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keypress'});
|
||||||
done();
|
done();
|
||||||
}).keypress({keyCode: 0x41});
|
}).keypress({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should generate stalls if a char modifier is down while a key is pressed', function(done) {
|
it('should generate stalls if a char modifier is down while a key is pressed', function(done) {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
@ -82,14 +82,14 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
case 2: // 'a'
|
case 2: // 'a'
|
||||||
expect(evt).to.be.deep.equal({
|
expect(evt).to.be.deep.equal({
|
||||||
type: 'keydown',
|
type: 'keydown',
|
||||||
keyId: 0x41,
|
code: 'KeyA',
|
||||||
keysym: 0x61
|
keysym: 0x61
|
||||||
});
|
});
|
||||||
|
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}).keydown({keyCode: 0x41, altGraphKey: true});
|
}).keydown({code: 'KeyA', keyCode: 0x41, altGraphKey: true});
|
||||||
|
|
||||||
});
|
});
|
||||||
describe('suppress the right events at the right time', function() {
|
describe('suppress the right events at the right time', function() {
|
||||||
|
@ -184,7 +184,7 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
obj.keydown({keyCode: 0xe1}); // press altgr
|
obj.keydown({keyCode: 0xe1}); // press altgr
|
||||||
obj.keydown({keyCode: 'A'.charCodeAt()});
|
obj.keydown({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should indicate on events if a single-key char modifier is down', function(done) {
|
it('should indicate on events if a single-key char modifier is down', function(done) {
|
||||||
|
@ -196,8 +196,8 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
case 1: // 'a'
|
case 1: // 'a'
|
||||||
expect(evt).to.be.deep.equal({
|
expect(evt).to.be.deep.equal({
|
||||||
type: 'keypress',
|
type: 'keypress',
|
||||||
keyId: 'A'.charCodeAt(),
|
code: 'KeyA',
|
||||||
keysym: 'a'.charCodeAt(),
|
keysym: 0x61,
|
||||||
escape: [0xfe03]
|
escape: [0xfe03]
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
|
@ -206,7 +206,7 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
obj.keydown({keyCode: 0xe1}); // press altgr
|
obj.keydown({keyCode: 0xe1}); // press altgr
|
||||||
obj.keypress({keyCode: 'A'.charCodeAt()});
|
obj.keypress({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should indicate on events if a multi-key char modifier is down', function(done) {
|
it('should indicate on events if a multi-key char modifier is down', function(done) {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
|
@ -219,8 +219,8 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
case 2: // 'a'
|
case 2: // 'a'
|
||||||
expect(evt).to.be.deep.equal({
|
expect(evt).to.be.deep.equal({
|
||||||
type: 'keypress',
|
type: 'keypress',
|
||||||
keyId: 'A'.charCodeAt(),
|
code: 'KeyA',
|
||||||
keysym: 'a'.charCodeAt(),
|
keysym: 0x61,
|
||||||
escape: [0xffe9, 0xffe3]
|
escape: [0xffe9, 0xffe3]
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
|
@ -230,7 +230,7 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
|
|
||||||
obj.keydown({keyCode: 0x11}); // press ctrl
|
obj.keydown({keyCode: 0x11}); // press ctrl
|
||||||
obj.keydown({keyCode: 0x12}); // press alt
|
obj.keydown({keyCode: 0x12}); // press alt
|
||||||
obj.keypress({keyCode: 'A'.charCodeAt()});
|
obj.keypress({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should not consider a char modifier to be down on the modifier key itself', function() {
|
it('should not consider a char modifier to be down on the modifier key itself', function() {
|
||||||
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
|
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
|
||||||
|
@ -244,18 +244,18 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
describe('add/remove keysym', function() {
|
describe('add/remove keysym', function() {
|
||||||
it('should remove keysym from keydown if a char key and no modifier', function() {
|
it('should remove keysym from keydown if a char key and no modifier', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', type: 'keydown'});
|
||||||
}).keydown({keyCode: 0x41});
|
}).keydown({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should not remove keysym from keydown if a shortcut modifier is down', function() {
|
it('should not remove keysym from keydown if a shortcut modifier is down', function() {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
switch (times_called++) {
|
switch (times_called++) {
|
||||||
case 1:
|
case 1:
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keydown'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keydown'});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}).keydown({keyCode: 0x41, ctrlKey: true});
|
}).keydown({code: 'KeyA', keyCode: 0x41, ctrlKey: true});
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
});
|
});
|
||||||
it('should not remove keysym from keydown if a char modifier is down', function() {
|
it('should not remove keysym from keydown if a char modifier is down', function() {
|
||||||
|
@ -263,30 +263,30 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
|
||||||
switch (times_called++) {
|
switch (times_called++) {
|
||||||
case 2:
|
case 2:
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keydown'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keydown'});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}).keydown({keyCode: 0x41, altGraphKey: true});
|
}).keydown({code: 'KeyA', keyCode: 0x41, altGraphKey: true});
|
||||||
expect(times_called).to.be.equal(3);
|
expect(times_called).to.be.equal(3);
|
||||||
});
|
});
|
||||||
it('should not remove keysym from keydown if key is noncharacter', function() {
|
it('should not remove keysym from keydown if key is noncharacter', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt, 'bacobjpace').to.be.deep.equal({keyId: 0x09, keysym: 0xff09, type: 'keydown'});
|
expect(evt, 'tab').to.be.deep.equal({code: 'Tab', keysym: 0xff09, type: 'keydown'});
|
||||||
}).keydown({keyCode: 0x09});
|
}).keydown({keyCode: 0x09});
|
||||||
|
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt, 'ctrl').to.be.deep.equal({keyId: 0x11, keysym: 0xffe3, type: 'keydown'});
|
expect(evt, 'ctrl').to.be.deep.equal({code: 'ControlLeft', keysym: 0xffe3, type: 'keydown'});
|
||||||
}).keydown({keyCode: 0x11});
|
}).keydown({keyCode: 0x11});
|
||||||
});
|
});
|
||||||
it('should never remove keysym from keypress', function() {
|
it('should never remove keysym from keypress', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keypress'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keypress'});
|
||||||
}).keypress({keyCode: 0x41});
|
}).keypress({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
it('should never remove keysym from keyup', function() {
|
it('should never remove keysym from keyup', function() {
|
||||||
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
|
||||||
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: 0x61, type: 'keyup'});
|
expect(evt).to.be.deep.equal({code: 'KeyA', keysym: 0x61, type: 'keyup'});
|
||||||
}).keyup({keyCode: 0x41});
|
}).keyup({code: 'KeyA', keyCode: 0x41});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// on keypress, keyup(?), always set keysym
|
// on keypress, keyup(?), always set keysym
|
||||||
|
@ -296,31 +296,31 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
describe('Verify that char modifiers are active', function() {
|
describe('Verify that char modifiers are active', function() {
|
||||||
it('should pass keydown events through if there is no stall', function(done) {
|
it('should pass keydown events through if there is no stall', function(done) {
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x41});
|
expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x41});
|
||||||
done();
|
done();
|
||||||
})({type: 'keydown', keyId: 0x41, keysym: 0x41});
|
})({type: 'keydown', code: 'KeyA', keysym: 0x41});
|
||||||
});
|
});
|
||||||
it('should pass keyup events through if there is no stall', function(done) {
|
it('should pass keyup events through if there is no stall', function(done) {
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
expect(evt).to.deep.equal({type: 'keyup', keyId: 0x41, keysym: 0x41});
|
expect(evt).to.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x41});
|
||||||
done();
|
done();
|
||||||
})({type: 'keyup', keyId: 0x41, keysym: 0x41});
|
})({type: 'keyup', code: 'KeyA', keysym: 0x41});
|
||||||
});
|
});
|
||||||
it('should pass keypress events through if there is no stall', function(done) {
|
it('should pass keypress events through if there is no stall', function(done) {
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
expect(evt).to.deep.equal({type: 'keypress', keyId: 0x41, keysym: 0x41});
|
expect(evt).to.deep.equal({type: 'keypress', code: 'KeyA', keysym: 0x41});
|
||||||
done();
|
done();
|
||||||
})({type: 'keypress', keyId: 0x41, keysym: 0x41});
|
})({type: 'keypress', code: 'KeyA', keysym: 0x41});
|
||||||
});
|
});
|
||||||
it('should not pass stall events through', function(done){
|
it('should not pass stall events through', function(done){
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
// should only be called once, for the keydown
|
// should only be called once, for the keydown
|
||||||
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x41});
|
expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x41});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'stall'});
|
obj({type: 'stall'});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x41});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x41});
|
||||||
});
|
});
|
||||||
it('should merge keydown and keypress events if they come after a stall', function(done) {
|
it('should merge keydown and keypress events if they come after a stall', function(done) {
|
||||||
var next_called = false;
|
var next_called = false;
|
||||||
|
@ -328,13 +328,13 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
// should only be called once, for the keydown
|
// should only be called once, for the keydown
|
||||||
expect(next_called).to.be.false;
|
expect(next_called).to.be.false;
|
||||||
next_called = true;
|
next_called = true;
|
||||||
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x44});
|
expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x44});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'stall'});
|
obj({type: 'stall'});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
obj({type: 'keypress', keyId: 0x43, keysym: 0x44});
|
obj({type: 'keypress', code: 'KeyC', keysym: 0x44});
|
||||||
expect(next_called).to.be.false;
|
expect(next_called).to.be.false;
|
||||||
});
|
});
|
||||||
it('should preserve modifier attribute when merging if keysyms differ', function(done) {
|
it('should preserve modifier attribute when merging if keysyms differ', function(done) {
|
||||||
|
@ -343,13 +343,13 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
// should only be called once, for the keydown
|
// should only be called once, for the keydown
|
||||||
expect(next_called).to.be.false;
|
expect(next_called).to.be.false;
|
||||||
next_called = true;
|
next_called = true;
|
||||||
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x44, escape: [0xffe3]});
|
expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x44, escape: [0xffe3]});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'stall'});
|
obj({type: 'stall'});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
obj({type: 'keypress', keyId: 0x43, keysym: 0x44, escape: [0xffe3]});
|
obj({type: 'keypress', code: 'KeyC', keysym: 0x44, escape: [0xffe3]});
|
||||||
expect(next_called).to.be.false;
|
expect(next_called).to.be.false;
|
||||||
});
|
});
|
||||||
it('should not preserve modifier attribute when merging if keysyms are the same', function() {
|
it('should not preserve modifier attribute when merging if keysyms are the same', function() {
|
||||||
|
@ -358,18 +358,18 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'stall'});
|
obj({type: 'stall'});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
obj({type: 'keypress', keyId: 0x43, keysym: 0x42, escape: [0xffe3]});
|
obj({type: 'keypress', code: 'KeyC', keysym: 0x42, escape: [0xffe3]});
|
||||||
});
|
});
|
||||||
it('should not merge keydown and keypress events if there is no stall', function(done) {
|
it('should not merge keydown and keypress events if there is no stall', function(done) {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
switch(times_called) {
|
switch(times_called) {
|
||||||
case 0:
|
case 0:
|
||||||
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
expect(evt).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
expect(evt).to.deep.equal({type: 'keypress', keyId: 0x43, keysym: 0x44});
|
expect(evt).to.deep.equal({type: 'keypress', code: 'KeyC', keysym: 0x44});
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -377,21 +377,21 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
++times_called;
|
++times_called;
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
obj({type: 'keypress', keyId: 0x43, keysym: 0x44});
|
obj({type: 'keypress', code: 'KeyC', keysym: 0x44});
|
||||||
});
|
});
|
||||||
it('should not merge keydown and keypress events if separated by another event', function(done) {
|
it('should not merge keydown and keypress events if separated by another event', function(done) {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
|
||||||
switch(times_called) {
|
switch(times_called) {
|
||||||
case 0:
|
case 0:
|
||||||
expect(evt,1).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
expect(evt,1).to.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
expect(evt,2).to.deep.equal({type: 'keyup', keyId: 0x43, keysym: 0x44});
|
expect(evt,2).to.deep.equal({type: 'keyup', code: 'KeyC', keysym: 0x44});
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
expect(evt,3).to.deep.equal({type: 'keypress', keyId: 0x45, keysym: 0x46});
|
expect(evt,3).to.deep.equal({type: 'keypress', code: 'KeyE', keysym: 0x46});
|
||||||
done();
|
done();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -400,9 +400,9 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'stall'});
|
obj({type: 'stall'});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
obj({type: 'keyup', keyId: 0x43, keysym: 0x44});
|
obj({type: 'keyup', code: 'KeyC', keysym: 0x44});
|
||||||
obj({type: 'keypress', keyId: 0x45, keysym: 0x46});
|
obj({type: 'keypress', code: 'KeyE', keysym: 0x46});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
||||||
expect(true).to.be.false;
|
expect(true).to.be.false;
|
||||||
});
|
});
|
||||||
obj({type: 'keyup', keyId: 0x41});
|
obj({type: 'keyup', code: 'KeyA'});
|
||||||
});
|
});
|
||||||
it('should insert into the queue on keydown if no keys are down', function() {
|
it('should insert into the queue on keydown if no keys are down', function() {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
|
@ -432,11 +432,11 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0x41, keysym: 0x42};
|
elem = {type: 'keydown', code: 'KeyA', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0x41};
|
elem = {type: 'keyup', code: 'KeyA'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
|
@ -460,16 +460,16 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keypress', keyId: 0x41, keysym: 0x42};
|
elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0x41};
|
elem = {type: 'keyup', code: 'KeyA'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
});
|
});
|
||||||
it('should add keysym to last key entry if keyId matches', function() {
|
it('should add keysym to last key entry if code matches', function() {
|
||||||
// this implies that a single keyup will release both keysyms
|
// this implies that a single keyup will release both keysyms
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -489,19 +489,19 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keypress', keyId: 0x41, keysym: 0x42};
|
elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keypress', keyId: 0x41, keysym: 0x43};
|
elem = {type: 'keypress', code: 'KeyA', keysym: 0x43};
|
||||||
keysymsdown[0x43] = true;
|
keysymsdown[0x43] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0x41};
|
elem = {type: 'keyup', code: 'KeyA'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
});
|
});
|
||||||
it('should create new key entry if keyId matches and keysym does not', function() {
|
it('should create new key entry if code matches and keysym does not', function() {
|
||||||
// this implies that a single keyup will release both keysyms
|
// this implies that a single keyup will release both keysyms
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -521,23 +521,23 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x42};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x43};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x43};
|
||||||
keysymsdown[0x43] = true;
|
keysymsdown[0x43] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0};
|
elem = {type: 'keyup', code: 'Unidentified'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(3);
|
expect(times_called).to.be.equal(3);
|
||||||
elem = {type: 'keyup', keyId: 0};
|
elem = {type: 'keyup', code: 'Unidentified'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
});
|
});
|
||||||
it('should merge key entry if keyIds are zero and keysyms match', function() {
|
it('should merge key entry if codes are zero and keysyms match', function() {
|
||||||
// this implies that a single keyup will release both keysyms
|
// this implies that a single keyup will release both keysyms
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -557,20 +557,20 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x42};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x42};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0};
|
elem = {type: 'keyup', code: 'Unidentified'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(3);
|
expect(times_called).to.be.equal(3);
|
||||||
});
|
});
|
||||||
it('should add keysym as separate entry if keyId does not match last event', function() {
|
it('should add keysym as separate entry if code does not match last event', function() {
|
||||||
// this implies that separate keyups are required
|
// this implies that separate keyups are required
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -590,22 +590,22 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keypress', keyId: 0x41, keysym: 0x42};
|
elem = {type: 'keypress', code: 'KeyA', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keypress', keyId: 0x42, keysym: 0x43};
|
elem = {type: 'keypress', code: 'KeyB', keysym: 0x43};
|
||||||
keysymsdown[0x43] = true;
|
keysymsdown[0x43] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0x41};
|
elem = {type: 'keyup', code: 'KeyA'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
elem = {type: 'keyup', keyId: 0x42};
|
elem = {type: 'keyup', code: 'KeyB'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
});
|
});
|
||||||
it('should add keysym as separate entry if keyId does not match last event and first is zero', function() {
|
it('should add keysym as separate entry if code does not match last event and first is zero', function() {
|
||||||
// this implies that separate keyups are required
|
// this implies that separate keyups are required
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -625,23 +625,23 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x42};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0x42, keysym: 0x43};
|
elem = {type: 'keydown', code: 'KeyB', keysym: 0x43};
|
||||||
keysymsdown[0x43] = true;
|
keysymsdown[0x43] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
elem = {type: 'keyup', keyId: 0};
|
elem = {type: 'keyup', code: 'Unidentified'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(3);
|
expect(times_called).to.be.equal(3);
|
||||||
elem = {type: 'keyup', keyId: 0x42};
|
elem = {type: 'keyup', code: 'KeyB'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
});
|
});
|
||||||
it('should add keysym as separate entry if keyId does not match last event and second is zero', function() {
|
it('should add keysym as separate entry if code does not match last event and second is zero', function() {
|
||||||
// this implies that a separate keyups are required
|
// this implies that a separate keyups are required
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var elem = null;
|
var elem = null;
|
||||||
|
@ -661,18 +661,18 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0x41, keysym: 0x42};
|
elem = {type: 'keydown', code: 'KeyA', keysym: 0x42};
|
||||||
keysymsdown[0x42] = true;
|
keysymsdown[0x42] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keydown', keyId: 0, keysym: 0x43};
|
elem = {type: 'keydown', code: 'Unidentified', keysym: 0x43};
|
||||||
keysymsdown[0x43] = true;
|
keysymsdown[0x43] = true;
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(elem).to.be.null;
|
expect(elem).to.be.null;
|
||||||
elem = {type: 'keyup', keyId: 0x41};
|
elem = {type: 'keyup', code: 'KeyA'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(3);
|
expect(times_called).to.be.equal(3);
|
||||||
elem = {type: 'keyup', keyId: 0};
|
elem = {type: 'keyup', code: 'Unidentified'};
|
||||||
obj(elem);
|
obj(elem);
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
});
|
});
|
||||||
|
@ -686,18 +686,18 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
expect(evt.type).to.be.equal('keydown');
|
expect(evt.type).to.be.equal('keydown');
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x42, keysym: 0x62});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyB', keysym: 0x62});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x61});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x61});
|
||||||
obj({type: 'keydown', keyId: 0x42, keysym: 0x62});
|
obj({type: 'keydown', code: 'KeyB', keysym: 0x62});
|
||||||
obj({type: 'keydown', keyId: 0x43, keysym: 0x63});
|
obj({type: 'keydown', code: 'KeyC', keysym: 0x63});
|
||||||
obj({type: 'keyup', keyId: 0x42});
|
obj({type: 'keyup', code: 'KeyB'});
|
||||||
expect(times_called).to.equal(4);
|
expect(times_called).to.equal(4);
|
||||||
});
|
});
|
||||||
it('should pop the first zero keyevent on keyup with zero keyId', function() {
|
it('should pop the first zero keyevent on keyup with zero code', function() {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
||||||
switch (times_called++) {
|
switch (times_called++) {
|
||||||
|
@ -707,18 +707,18 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
expect(evt.type).to.be.equal('keydown');
|
expect(evt.type).to.be.equal('keydown');
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: 0x61});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x61});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'keydown', keyId: 0, keysym: 0x61});
|
obj({type: 'keydown', code: 'Unidentified', keysym: 0x61});
|
||||||
obj({type: 'keydown', keyId: 0, keysym: 0x62});
|
obj({type: 'keydown', code: 'Unidentified', keysym: 0x62});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x63});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x63});
|
||||||
obj({type: 'keyup', keyId: 0x0});
|
obj({type: 'keyup', code: 'Unidentified'});
|
||||||
expect(times_called).to.equal(4);
|
expect(times_called).to.equal(4);
|
||||||
});
|
});
|
||||||
it('should pop the last keyevents keysym if no match is found for keyId', function() {
|
it('should pop the last keyevents keysym if no match is found for code', function() {
|
||||||
var times_called = 0;
|
var times_called = 0;
|
||||||
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
||||||
switch (times_called++) {
|
switch (times_called++) {
|
||||||
|
@ -728,15 +728,15 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
expect(evt.type).to.be.equal('keydown');
|
expect(evt.type).to.be.equal('keydown');
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x44, keysym: 0x63});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyD', keysym: 0x63});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x61});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x61});
|
||||||
obj({type: 'keydown', keyId: 0x42, keysym: 0x62});
|
obj({type: 'keydown', code: 'KeyB', keysym: 0x62});
|
||||||
obj({type: 'keydown', keyId: 0x43, keysym: 0x63});
|
obj({type: 'keydown', code: 'KeyC', keysym: 0x63});
|
||||||
obj({type: 'keyup', keyId: 0x44});
|
obj({type: 'keyup', code: 'KeyD'});
|
||||||
expect(times_called).to.equal(4);
|
expect(times_called).to.equal(4);
|
||||||
});
|
});
|
||||||
describe('Firefox sends keypress even when keydown is suppressed', function() {
|
describe('Firefox sends keypress even when keydown is suppressed', function() {
|
||||||
|
@ -747,9 +747,9 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
++times_called;
|
++times_called;
|
||||||
});
|
});
|
||||||
|
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
expect(times_called).to.be.equal(1);
|
expect(times_called).to.be.equal(1);
|
||||||
obj({type: 'keypress', keyId: 0x41, keysym: 0x43});
|
obj({type: 'keypress', code: 'KeyA', keysym: 0x43});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('releaseAll', function() {
|
describe('releaseAll', function() {
|
||||||
|
@ -766,15 +766,15 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
var obj = KeyboardUtil.TrackKeyState(function(evt) {
|
||||||
switch (times_called++) {
|
switch (times_called++) {
|
||||||
case 2:
|
case 2:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: 0x41});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x41});
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: 0x42});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0x42});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
obj({type: 'keydown', keyId: 0x41, keysym: 0x41});
|
obj({type: 'keydown', code: 'KeyA', keysym: 0x41});
|
||||||
obj({type: 'keydown', keyId: 0x42, keysym: 0x42});
|
obj({type: 'keydown', code: 'KeyB', keysym: 0x42});
|
||||||
expect(times_called).to.be.equal(2);
|
expect(times_called).to.be.equal(2);
|
||||||
obj({type: 'releaseall'});
|
obj({type: 'releaseall'});
|
||||||
expect(times_called).to.be.equal(4);
|
expect(times_called).to.be.equal(4);
|
||||||
|
@ -792,8 +792,8 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.EscapeModifiers(function(evt) {
|
KeyboardUtil.EscapeModifiers(function(evt) {
|
||||||
expect(times_called).to.be.equal(0);
|
expect(times_called).to.be.equal(0);
|
||||||
++times_called;
|
++times_called;
|
||||||
expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
expect(evt).to.be.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
})({type: 'keydown', keyId: 0x41, keysym: 0x42});
|
})({type: 'keydown', code: 'KeyA', keysym: 0x42});
|
||||||
expect(times_called).to.be.equal(1);
|
expect(times_called).to.be.equal(1);
|
||||||
});
|
});
|
||||||
it('should generate fake undo/redo events when a char modifier is down', function() {
|
it('should generate fake undo/redo events when a char modifier is down', function() {
|
||||||
|
@ -801,22 +801,22 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.EscapeModifiers(function(evt) {
|
KeyboardUtil.EscapeModifiers(function(evt) {
|
||||||
switch(times_called++) {
|
switch(times_called++) {
|
||||||
case 0:
|
case 0:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: 0xffe9});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0xffe9});
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: 0xffe3});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'Unidentified', keysym: 0xffe3});
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0x41, keysym: 0x42, escape: [0xffe9, 0xffe3]});
|
expect(evt).to.be.deep.equal({type: 'keydown', code: 'KeyA', keysym: 0x42, escape: [0xffe9, 0xffe3]});
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0, keysym: 0xffe9});
|
expect(evt).to.be.deep.equal({type: 'keydown', code: 'Unidentified', keysym: 0xffe9});
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0, keysym: 0xffe3});
|
expect(evt).to.be.deep.equal({type: 'keydown', code: 'Unidentified', keysym: 0xffe3});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})({type: 'keydown', keyId: 0x41, keysym: 0x42, escape: [0xffe9, 0xffe3]});
|
})({type: 'keydown', code: 'KeyA', keysym: 0x42, escape: [0xffe9, 0xffe3]});
|
||||||
expect(times_called).to.be.equal(5);
|
expect(times_called).to.be.equal(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -826,8 +826,8 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.EscapeModifiers(function(evt) {
|
KeyboardUtil.EscapeModifiers(function(evt) {
|
||||||
expect(times_called).to.be.equal(0);
|
expect(times_called).to.be.equal(0);
|
||||||
++times_called;
|
++times_called;
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: 0x42, escape: [0xfe03]});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x42, escape: [0xfe03]});
|
||||||
})({type: 'keyup', keyId: 0x41, keysym: 0x42, escape: [0xfe03]});
|
})({type: 'keyup', code: 'KeyA', keysym: 0x42, escape: [0xfe03]});
|
||||||
expect(times_called).to.be.equal(1);
|
expect(times_called).to.be.equal(1);
|
||||||
});
|
});
|
||||||
it('should pass through when a char modifier is not down', function() {
|
it('should pass through when a char modifier is not down', function() {
|
||||||
|
@ -835,8 +835,8 @@ describe('Key Event Pipeline Stages', function() {
|
||||||
KeyboardUtil.EscapeModifiers(function(evt) {
|
KeyboardUtil.EscapeModifiers(function(evt) {
|
||||||
expect(times_called).to.be.equal(0);
|
expect(times_called).to.be.equal(0);
|
||||||
++times_called;
|
++times_called;
|
||||||
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: 0x42});
|
expect(evt).to.be.deep.equal({type: 'keyup', code: 'KeyA', keysym: 0x42});
|
||||||
})({type: 'keyup', keyId: 0x41, keysym: 0x42});
|
})({type: 'keyup', code: 'KeyA', keysym: 0x42});
|
||||||
expect(times_called).to.be.equal(1);
|
expect(times_called).to.be.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,7 +50,8 @@
|
||||||
WebUtil.load_scripts({
|
WebUtil.load_scripts({
|
||||||
'core': ["base64.js", "websock.js", "des.js", "input/keysym.js",
|
'core': ["base64.js", "websock.js", "des.js", "input/keysym.js",
|
||||||
"input/keysymdef.js", "input/xtscancodes.js", "input/util.js",
|
"input/keysymdef.js", "input/xtscancodes.js", "input/util.js",
|
||||||
"input/devices.js", "display.js", "rfb.js", "inflator.js"],
|
"input/devices.js", "display.js", "rfb.js", "inflator.js",
|
||||||
|
"input/vkeys.js"],
|
||||||
'tests': ["playback.js"],
|
'tests': ["playback.js"],
|
||||||
'recordings': [fname]});
|
'recordings': [fname]});
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue