Refactor ES6 module structure/split up Util
This commit restructures many of the ES6 modules, splitting them up to actual export multiple functions instead of a single object. It also splits up Util into multiple sub-modules, to make it easier to maintain. Finally, localisation is renamed to localization.
This commit is contained in:
+255
-273
@@ -1,293 +1,277 @@
|
||||
import KeyTable from "./keysym.js";
|
||||
import keysyms from "./keysymdef.js";
|
||||
|
||||
export function substituteCodepoint(cp) {
|
||||
// Any Unicode code points which do not have corresponding keysym entries
|
||||
// can be swapped out for another code point by adding them to this table
|
||||
var substitutions = {
|
||||
// {S,s} with comma below -> {S,s} with cedilla
|
||||
0x218 : 0x15e,
|
||||
0x219 : 0x15f,
|
||||
// {T,t} with comma below -> {T,t} with cedilla
|
||||
0x21a : 0x162,
|
||||
0x21b : 0x163
|
||||
};
|
||||
|
||||
var KeyboardUtil = {};
|
||||
var sub = substitutions[cp];
|
||||
return sub ? sub : cp;
|
||||
}
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
function isMac() {
|
||||
return navigator && !!(/mac/i).exec(navigator.platform);
|
||||
}
|
||||
function isWindows() {
|
||||
return navigator && !!(/win/i).exec(navigator.platform);
|
||||
}
|
||||
function isLinux() {
|
||||
return navigator && !!(/linux/i).exec(navigator.platform);
|
||||
}
|
||||
|
||||
function substituteCodepoint(cp) {
|
||||
// Any Unicode code points which do not have corresponding keysym entries
|
||||
// can be swapped out for another code point by adding them to this table
|
||||
var substitutions = {
|
||||
// {S,s} with comma below -> {S,s} with cedilla
|
||||
0x218 : 0x15e,
|
||||
0x219 : 0x15f,
|
||||
// {T,t} with comma below -> {T,t} with cedilla
|
||||
0x21a : 0x162,
|
||||
0x21b : 0x163
|
||||
};
|
||||
|
||||
var sub = substitutions[cp];
|
||||
return sub ? sub : cp;
|
||||
}
|
||||
|
||||
function isMac() {
|
||||
return navigator && !!(/mac/i).exec(navigator.platform);
|
||||
}
|
||||
function isWindows() {
|
||||
return navigator && !!(/win/i).exec(navigator.platform);
|
||||
}
|
||||
function isLinux() {
|
||||
return navigator && !!(/linux/i).exec(navigator.platform);
|
||||
}
|
||||
|
||||
// Return true if a modifier which is not the specified char modifier (and is not shift) is down
|
||||
function hasShortcutModifier(charModifier, currentModifiers) {
|
||||
var mods = {};
|
||||
for (var key in currentModifiers) {
|
||||
if (parseInt(key) !== KeyTable.XK_Shift_L) {
|
||||
mods[key] = currentModifiers[key];
|
||||
}
|
||||
// Return true if a modifier which is not the specified char modifier (and is not shift) is down
|
||||
export function hasShortcutModifier(charModifier, currentModifiers) {
|
||||
var mods = {};
|
||||
for (var key in currentModifiers) {
|
||||
if (parseInt(key) !== KeyTable.XK_Shift_L) {
|
||||
mods[key] = currentModifiers[key];
|
||||
}
|
||||
}
|
||||
|
||||
var sum = 0;
|
||||
for (var k in currentModifiers) {
|
||||
if (mods[k]) {
|
||||
++sum;
|
||||
}
|
||||
var sum = 0;
|
||||
for (var k in currentModifiers) {
|
||||
if (mods[k]) {
|
||||
++sum;
|
||||
}
|
||||
if (hasCharModifier(charModifier, mods)) {
|
||||
return sum > charModifier.length;
|
||||
}
|
||||
if (hasCharModifier(charModifier, mods)) {
|
||||
return sum > charModifier.length;
|
||||
}
|
||||
else {
|
||||
return sum > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the specified char modifier is currently down
|
||||
export function hasCharModifier(charModifier, currentModifiers) {
|
||||
if (charModifier.length === 0) { return false; }
|
||||
|
||||
for (var i = 0; i < charModifier.length; ++i) {
|
||||
if (!currentModifiers[charModifier[i]]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Helper object tracking modifier key state
|
||||
// and generates fake key events to compensate if it gets out of sync
|
||||
export function ModifierSync(charModifier) {
|
||||
if (!charModifier) {
|
||||
if (isMac()) {
|
||||
// on Mac, Option (AKA Alt) is used as a char modifier
|
||||
charModifier = [KeyTable.XK_Alt_L];
|
||||
}
|
||||
else if (isWindows()) {
|
||||
// on Windows, Ctrl+Alt is used as a char modifier
|
||||
charModifier = [KeyTable.XK_Alt_L, KeyTable.XK_Control_L];
|
||||
}
|
||||
else if (isLinux()) {
|
||||
// on Linux, ISO Level 3 Shift (AltGr) is used as a char modifier
|
||||
charModifier = [KeyTable.XK_ISO_Level3_Shift];
|
||||
}
|
||||
else {
|
||||
return sum > 0;
|
||||
charModifier = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the specified char modifier is currently down
|
||||
function hasCharModifier(charModifier, currentModifiers) {
|
||||
if (charModifier.length === 0) { return false; }
|
||||
var state = {};
|
||||
state[KeyTable.XK_Control_L] = false;
|
||||
state[KeyTable.XK_Alt_L] = false;
|
||||
state[KeyTable.XK_ISO_Level3_Shift] = false;
|
||||
state[KeyTable.XK_Shift_L] = false;
|
||||
state[KeyTable.XK_Meta_L] = false;
|
||||
|
||||
for (var i = 0; i < charModifier.length; ++i) {
|
||||
if (!currentModifiers[charModifier[i]]) {
|
||||
return false;
|
||||
}
|
||||
function sync(evt, keysym) {
|
||||
var result = [];
|
||||
function syncKey(keysym) {
|
||||
return {keysym: keysyms.lookup(keysym), type: state[keysym] ? 'keydown' : 'keyup'};
|
||||
}
|
||||
return true;
|
||||
|
||||
if (evt.ctrlKey !== undefined &&
|
||||
evt.ctrlKey !== state[KeyTable.XK_Control_L] && keysym !== KeyTable.XK_Control_L) {
|
||||
state[KeyTable.XK_Control_L] = evt.ctrlKey;
|
||||
result.push(syncKey(KeyTable.XK_Control_L));
|
||||
}
|
||||
if (evt.altKey !== undefined &&
|
||||
evt.altKey !== state[KeyTable.XK_Alt_L] && keysym !== KeyTable.XK_Alt_L) {
|
||||
state[KeyTable.XK_Alt_L] = evt.altKey;
|
||||
result.push(syncKey(KeyTable.XK_Alt_L));
|
||||
}
|
||||
if (evt.altGraphKey !== undefined &&
|
||||
evt.altGraphKey !== state[KeyTable.XK_ISO_Level3_Shift] && keysym !== KeyTable.XK_ISO_Level3_Shift) {
|
||||
state[KeyTable.XK_ISO_Level3_Shift] = evt.altGraphKey;
|
||||
result.push(syncKey(KeyTable.XK_ISO_Level3_Shift));
|
||||
}
|
||||
if (evt.shiftKey !== undefined &&
|
||||
evt.shiftKey !== state[KeyTable.XK_Shift_L] && keysym !== KeyTable.XK_Shift_L) {
|
||||
state[KeyTable.XK_Shift_L] = evt.shiftKey;
|
||||
result.push(syncKey(KeyTable.XK_Shift_L));
|
||||
}
|
||||
if (evt.metaKey !== undefined &&
|
||||
evt.metaKey !== state[KeyTable.XK_Meta_L] && keysym !== KeyTable.XK_Meta_L) {
|
||||
state[KeyTable.XK_Meta_L] = evt.metaKey;
|
||||
result.push(syncKey(KeyTable.XK_Meta_L));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function syncKeyEvent(evt, down) {
|
||||
var obj = getKeysym(evt);
|
||||
var keysym = obj ? obj.keysym : null;
|
||||
|
||||
// first, apply the event itself, if relevant
|
||||
if (keysym !== null && state[keysym] !== undefined) {
|
||||
state[keysym] = down;
|
||||
}
|
||||
return sync(evt, keysym);
|
||||
}
|
||||
|
||||
// Helper object tracking modifier key state
|
||||
// and generates fake key events to compensate if it gets out of sync
|
||||
function ModifierSync(charModifier) {
|
||||
if (!charModifier) {
|
||||
if (isMac()) {
|
||||
// on Mac, Option (AKA Alt) is used as a char modifier
|
||||
charModifier = [KeyTable.XK_Alt_L];
|
||||
}
|
||||
else if (isWindows()) {
|
||||
// on Windows, Ctrl+Alt is used as a char modifier
|
||||
charModifier = [KeyTable.XK_Alt_L, KeyTable.XK_Control_L];
|
||||
}
|
||||
else if (isLinux()) {
|
||||
// on Linux, ISO Level 3 Shift (AltGr) is used as a char modifier
|
||||
charModifier = [KeyTable.XK_ISO_Level3_Shift];
|
||||
}
|
||||
else {
|
||||
charModifier = [];
|
||||
}
|
||||
}
|
||||
return {
|
||||
// sync on the appropriate keyboard event
|
||||
keydown: function(evt) { return syncKeyEvent(evt, true);},
|
||||
keyup: function(evt) { return syncKeyEvent(evt, false);},
|
||||
// Call this with a non-keyboard event (such as mouse events) to use its modifier state to synchronize anyway
|
||||
syncAny: function(evt) { return sync(evt);},
|
||||
|
||||
var state = {};
|
||||
state[KeyTable.XK_Control_L] = false;
|
||||
state[KeyTable.XK_Alt_L] = false;
|
||||
state[KeyTable.XK_ISO_Level3_Shift] = false;
|
||||
state[KeyTable.XK_Shift_L] = false;
|
||||
state[KeyTable.XK_Meta_L] = false;
|
||||
// is a shortcut modifier down?
|
||||
hasShortcutModifier: function() { return hasShortcutModifier(charModifier, state); },
|
||||
// if a char modifier is down, return the keys it consists of, otherwise return null
|
||||
activeCharModifier: function() { return hasCharModifier(charModifier, state) ? charModifier : null; }
|
||||
};
|
||||
}
|
||||
|
||||
function sync(evt, keysym) {
|
||||
var result = [];
|
||||
function syncKey(keysym) {
|
||||
return {keysym: keysyms.lookup(keysym), type: state[keysym] ? 'keydown' : 'keyup'};
|
||||
}
|
||||
|
||||
if (evt.ctrlKey !== undefined &&
|
||||
evt.ctrlKey !== state[KeyTable.XK_Control_L] && keysym !== KeyTable.XK_Control_L) {
|
||||
state[KeyTable.XK_Control_L] = evt.ctrlKey;
|
||||
result.push(syncKey(KeyTable.XK_Control_L));
|
||||
}
|
||||
if (evt.altKey !== undefined &&
|
||||
evt.altKey !== state[KeyTable.XK_Alt_L] && keysym !== KeyTable.XK_Alt_L) {
|
||||
state[KeyTable.XK_Alt_L] = evt.altKey;
|
||||
result.push(syncKey(KeyTable.XK_Alt_L));
|
||||
}
|
||||
if (evt.altGraphKey !== undefined &&
|
||||
evt.altGraphKey !== state[KeyTable.XK_ISO_Level3_Shift] && keysym !== KeyTable.XK_ISO_Level3_Shift) {
|
||||
state[KeyTable.XK_ISO_Level3_Shift] = evt.altGraphKey;
|
||||
result.push(syncKey(KeyTable.XK_ISO_Level3_Shift));
|
||||
}
|
||||
if (evt.shiftKey !== undefined &&
|
||||
evt.shiftKey !== state[KeyTable.XK_Shift_L] && keysym !== KeyTable.XK_Shift_L) {
|
||||
state[KeyTable.XK_Shift_L] = evt.shiftKey;
|
||||
result.push(syncKey(KeyTable.XK_Shift_L));
|
||||
}
|
||||
if (evt.metaKey !== undefined &&
|
||||
evt.metaKey !== state[KeyTable.XK_Meta_L] && keysym !== KeyTable.XK_Meta_L) {
|
||||
state[KeyTable.XK_Meta_L] = evt.metaKey;
|
||||
result.push(syncKey(KeyTable.XK_Meta_L));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function syncKeyEvent(evt, down) {
|
||||
var obj = getKeysym(evt);
|
||||
var keysym = obj ? obj.keysym : null;
|
||||
|
||||
// first, apply the event itself, if relevant
|
||||
if (keysym !== null && state[keysym] !== undefined) {
|
||||
state[keysym] = down;
|
||||
}
|
||||
return sync(evt, keysym);
|
||||
}
|
||||
|
||||
return {
|
||||
// sync on the appropriate keyboard event
|
||||
keydown: function(evt) { return syncKeyEvent(evt, true);},
|
||||
keyup: function(evt) { return syncKeyEvent(evt, false);},
|
||||
// Call this with a non-keyboard event (such as mouse events) to use its modifier state to synchronize anyway
|
||||
syncAny: function(evt) { return sync(evt);},
|
||||
|
||||
// is a shortcut modifier down?
|
||||
hasShortcutModifier: function() { return hasShortcutModifier(charModifier, state); },
|
||||
// if a char modifier is down, return the keys it consists of, otherwise return null
|
||||
activeCharModifier: function() { return hasCharModifier(charModifier, state) ? charModifier : null; }
|
||||
};
|
||||
// Get a key ID from a keyboard event
|
||||
// May be a string or an integer depending on the available properties
|
||||
export function getKey(evt){
|
||||
if ('keyCode' in evt && 'key' in evt) {
|
||||
return evt.key + ':' + evt.keyCode;
|
||||
}
|
||||
|
||||
// Get a key ID from a keyboard event
|
||||
// May be a string or an integer depending on the available properties
|
||||
function getKey(evt){
|
||||
if ('keyCode' in evt && 'key' in evt) {
|
||||
return evt.key + ':' + evt.keyCode;
|
||||
}
|
||||
else if ('keyCode' in evt) {
|
||||
return evt.keyCode;
|
||||
}
|
||||
else {
|
||||
return evt.key;
|
||||
}
|
||||
else if ('keyCode' in evt) {
|
||||
return evt.keyCode;
|
||||
}
|
||||
else {
|
||||
return evt.key;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the most reliable keysym value we can get from a key event
|
||||
// if char/charCode is available, prefer those, otherwise fall back to key/keyCode/which
|
||||
function getKeysym(evt){
|
||||
var codepoint;
|
||||
if (evt.char && evt.char.length === 1) {
|
||||
codepoint = evt.char.charCodeAt();
|
||||
}
|
||||
else if (evt.charCode) {
|
||||
codepoint = evt.charCode;
|
||||
}
|
||||
else if (evt.keyCode && evt.type === 'keypress') {
|
||||
// IE10 stores the char code as keyCode, and has no other useful properties
|
||||
codepoint = evt.keyCode;
|
||||
}
|
||||
if (codepoint) {
|
||||
return keysyms.fromUnicode(substituteCodepoint(codepoint));
|
||||
}
|
||||
// we could check evt.key here.
|
||||
// Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list,
|
||||
// so we "just" need to map them to keysym, but AFAIK this is only available in IE10, which also provides evt.key
|
||||
// so we don't *need* it yet
|
||||
if (evt.keyCode) {
|
||||
return keysyms.lookup(keysymFromKeyCode(evt.keyCode, evt.shiftKey));
|
||||
}
|
||||
if (evt.which) {
|
||||
return keysyms.lookup(keysymFromKeyCode(evt.which, evt.shiftKey));
|
||||
}
|
||||
// Get the most reliable keysym value we can get from a key event
|
||||
// if char/charCode is available, prefer those, otherwise fall back to key/keyCode/which
|
||||
export function getKeysym(evt){
|
||||
var codepoint;
|
||||
if (evt.char && evt.char.length === 1) {
|
||||
codepoint = evt.char.charCodeAt();
|
||||
}
|
||||
else if (evt.charCode) {
|
||||
codepoint = evt.charCode;
|
||||
}
|
||||
else if (evt.keyCode && evt.type === 'keypress') {
|
||||
// IE10 stores the char code as keyCode, and has no other useful properties
|
||||
codepoint = evt.keyCode;
|
||||
}
|
||||
if (codepoint) {
|
||||
return keysyms.fromUnicode(substituteCodepoint(codepoint));
|
||||
}
|
||||
// we could check evt.key here.
|
||||
// Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list,
|
||||
// so we "just" need to map them to keysym, but AFAIK this is only available in IE10, which also provides evt.key
|
||||
// so we don't *need* it yet
|
||||
if (evt.keyCode) {
|
||||
return keysyms.lookup(keysymFromKeyCode(evt.keyCode, evt.shiftKey));
|
||||
}
|
||||
if (evt.which) {
|
||||
return keysyms.lookup(keysymFromKeyCode(evt.which, evt.shiftKey));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Given a keycode, try to predict which keysym it might be.
|
||||
// If the keycode is unknown, null is returned.
|
||||
export function keysymFromKeyCode(keycode, shiftPressed) {
|
||||
if (typeof(keycode) !== 'number') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Given a keycode, try to predict which keysym it might be.
|
||||
// If the keycode is unknown, null is returned.
|
||||
function keysymFromKeyCode(keycode, shiftPressed) {
|
||||
if (typeof(keycode) !== 'number') {
|
||||
return null;
|
||||
}
|
||||
// won't be accurate for azerty
|
||||
if (keycode >= 0x30 && keycode <= 0x39) {
|
||||
return keycode; // digit
|
||||
}
|
||||
if (keycode >= 0x41 && keycode <= 0x5a) {
|
||||
// remap to lowercase unless shift is down
|
||||
return shiftPressed ? keycode : keycode + 32; // A-Z
|
||||
}
|
||||
if (keycode >= 0x60 && keycode <= 0x69) {
|
||||
return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9
|
||||
}
|
||||
|
||||
switch(keycode) {
|
||||
case 0x20: return KeyTable.XK_space;
|
||||
case 0x6a: return KeyTable.XK_KP_Multiply;
|
||||
case 0x6b: return KeyTable.XK_KP_Add;
|
||||
case 0x6c: return KeyTable.XK_KP_Separator;
|
||||
case 0x6d: return KeyTable.XK_KP_Subtract;
|
||||
case 0x6e: return KeyTable.XK_KP_Decimal;
|
||||
case 0x6f: return KeyTable.XK_KP_Divide;
|
||||
case 0xbb: return KeyTable.XK_plus;
|
||||
case 0xbc: return KeyTable.XK_comma;
|
||||
case 0xbd: return KeyTable.XK_minus;
|
||||
case 0xbe: return KeyTable.XK_period;
|
||||
}
|
||||
|
||||
return nonCharacterKey({keyCode: keycode});
|
||||
// won't be accurate for azerty
|
||||
if (keycode >= 0x30 && keycode <= 0x39) {
|
||||
return keycode; // digit
|
||||
}
|
||||
if (keycode >= 0x41 && keycode <= 0x5a) {
|
||||
// remap to lowercase unless shift is down
|
||||
return shiftPressed ? keycode : keycode + 32; // A-Z
|
||||
}
|
||||
if (keycode >= 0x60 && keycode <= 0x69) {
|
||||
return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9
|
||||
}
|
||||
|
||||
// if the key is a known non-character key (any key which doesn't generate character data)
|
||||
// return its keysym value. Otherwise return null
|
||||
function nonCharacterKey(evt) {
|
||||
// evt.key not implemented yet
|
||||
if (!evt.keyCode) { return null; }
|
||||
var keycode = evt.keyCode;
|
||||
|
||||
if (keycode >= 0x70 && keycode <= 0x87) {
|
||||
return KeyTable.XK_F1 + keycode - 0x70; // F1-F24
|
||||
}
|
||||
switch (keycode) {
|
||||
|
||||
case 8 : return KeyTable.XK_BackSpace;
|
||||
case 13 : return KeyTable.XK_Return;
|
||||
|
||||
case 9 : return KeyTable.XK_Tab;
|
||||
|
||||
case 27 : return KeyTable.XK_Escape;
|
||||
case 46 : return KeyTable.XK_Delete;
|
||||
|
||||
case 36 : return KeyTable.XK_Home;
|
||||
case 35 : return KeyTable.XK_End;
|
||||
case 33 : return KeyTable.XK_Page_Up;
|
||||
case 34 : return KeyTable.XK_Page_Down;
|
||||
case 45 : return KeyTable.XK_Insert;
|
||||
|
||||
case 37 : return KeyTable.XK_Left;
|
||||
case 38 : return KeyTable.XK_Up;
|
||||
case 39 : return KeyTable.XK_Right;
|
||||
case 40 : return KeyTable.XK_Down;
|
||||
|
||||
case 16 : return KeyTable.XK_Shift_L;
|
||||
case 17 : return KeyTable.XK_Control_L;
|
||||
case 18 : return KeyTable.XK_Alt_L; // also: Option-key on Mac
|
||||
|
||||
case 224 : return KeyTable.XK_Meta_L;
|
||||
case 225 : return KeyTable.XK_ISO_Level3_Shift; // AltGr
|
||||
case 91 : return KeyTable.XK_Super_L; // also: Windows-key
|
||||
case 92 : return KeyTable.XK_Super_R; // also: Windows-key
|
||||
case 93 : return KeyTable.XK_Menu; // also: Windows-Menu, Command on Mac
|
||||
default: return null;
|
||||
}
|
||||
switch(keycode) {
|
||||
case 0x20: return KeyTable.XK_space;
|
||||
case 0x6a: return KeyTable.XK_KP_Multiply;
|
||||
case 0x6b: return KeyTable.XK_KP_Add;
|
||||
case 0x6c: return KeyTable.XK_KP_Separator;
|
||||
case 0x6d: return KeyTable.XK_KP_Subtract;
|
||||
case 0x6e: return KeyTable.XK_KP_Decimal;
|
||||
case 0x6f: return KeyTable.XK_KP_Divide;
|
||||
case 0xbb: return KeyTable.XK_plus;
|
||||
case 0xbc: return KeyTable.XK_comma;
|
||||
case 0xbd: return KeyTable.XK_minus;
|
||||
case 0xbe: return KeyTable.XK_period;
|
||||
}
|
||||
|
||||
KeyboardUtil.hasShortcutModifier = hasShortcutModifier;
|
||||
KeyboardUtil.hasCharModifier = hasCharModifier;
|
||||
KeyboardUtil.ModifierSync = ModifierSync;
|
||||
KeyboardUtil.getKey = getKey;
|
||||
KeyboardUtil.getKeysym = getKeysym;
|
||||
KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode;
|
||||
KeyboardUtil.nonCharacterKey = nonCharacterKey;
|
||||
KeyboardUtil.substituteCodepoint = substituteCodepoint;
|
||||
})();
|
||||
return nonCharacterKey({keyCode: keycode});
|
||||
}
|
||||
|
||||
KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
|
||||
// if the key is a known non-character key (any key which doesn't generate character data)
|
||||
// return its keysym value. Otherwise return null
|
||||
export function nonCharacterKey(evt) {
|
||||
// evt.key not implemented yet
|
||||
if (!evt.keyCode) { return null; }
|
||||
var keycode = evt.keyCode;
|
||||
|
||||
if (keycode >= 0x70 && keycode <= 0x87) {
|
||||
return KeyTable.XK_F1 + keycode - 0x70; // F1-F24
|
||||
}
|
||||
switch (keycode) {
|
||||
|
||||
case 8 : return KeyTable.XK_BackSpace;
|
||||
case 13 : return KeyTable.XK_Return;
|
||||
|
||||
case 9 : return KeyTable.XK_Tab;
|
||||
|
||||
case 27 : return KeyTable.XK_Escape;
|
||||
case 46 : return KeyTable.XK_Delete;
|
||||
|
||||
case 36 : return KeyTable.XK_Home;
|
||||
case 35 : return KeyTable.XK_End;
|
||||
case 33 : return KeyTable.XK_Page_Up;
|
||||
case 34 : return KeyTable.XK_Page_Down;
|
||||
case 45 : return KeyTable.XK_Insert;
|
||||
|
||||
case 37 : return KeyTable.XK_Left;
|
||||
case 38 : return KeyTable.XK_Up;
|
||||
case 39 : return KeyTable.XK_Right;
|
||||
case 40 : return KeyTable.XK_Down;
|
||||
|
||||
case 16 : return KeyTable.XK_Shift_L;
|
||||
case 17 : return KeyTable.XK_Control_L;
|
||||
case 18 : return KeyTable.XK_Alt_L; // also: Option-key on Mac
|
||||
|
||||
case 224 : return KeyTable.XK_Meta_L;
|
||||
case 225 : return KeyTable.XK_ISO_Level3_Shift; // AltGr
|
||||
case 91 : return KeyTable.XK_Super_L; // also: Windows-key
|
||||
case 92 : return KeyTable.XK_Super_R; // also: Windows-key
|
||||
case 93 : return KeyTable.XK_Menu; // also: Windows-Menu, Command on Mac
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function QEMUKeyEventDecoder (modifierState, next) {
|
||||
"use strict";
|
||||
|
||||
function sendAll(evts) {
|
||||
@@ -333,7 +317,7 @@ KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
|
||||
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
|
||||
var isShift = evt.keyCode === 0x10 || evt.key === 'Shift';
|
||||
|
||||
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt));
|
||||
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!nonCharacterKey(evt));
|
||||
|
||||
next(result);
|
||||
return suppress;
|
||||
@@ -357,7 +341,7 @@ KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
|
||||
};
|
||||
};
|
||||
|
||||
KeyboardUtil.TrackQEMUKeyState = function(next) {
|
||||
export function TrackQEMUKeyState (next) {
|
||||
"use strict";
|
||||
var state = [];
|
||||
|
||||
@@ -425,7 +409,7 @@ KeyboardUtil.TrackQEMUKeyState = function(next) {
|
||||
// - 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
|
||||
// This information is collected into an object which is passed to the next() function. (one call per event)
|
||||
KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
|
||||
export function KeyEventDecoder (modifierState, next) {
|
||||
"use strict";
|
||||
function sendAll(evts) {
|
||||
for (var i = 0; i < evts.length; ++i) {
|
||||
@@ -434,18 +418,18 @@ KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
|
||||
}
|
||||
function process(evt, type) {
|
||||
var result = {type: type};
|
||||
var keyId = KeyboardUtil.getKey(evt);
|
||||
var keyId = getKey(evt);
|
||||
if (keyId) {
|
||||
result.keyId = keyId;
|
||||
}
|
||||
|
||||
var keysym = KeyboardUtil.getKeysym(evt);
|
||||
var keysym = getKeysym(evt);
|
||||
|
||||
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
|
||||
// Is this a case where we have to decide on the keysym right away, rather than waiting for the keypress?
|
||||
// "special" keys like enter, tab or backspace don't send keypress events,
|
||||
// and some browsers don't send keypresses at all if a modifier is down
|
||||
if (keysym && (type !== 'keydown' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) {
|
||||
if (keysym && (type !== 'keydown' || nonCharacterKey(evt) || hasModifier)) {
|
||||
result.keysym = keysym;
|
||||
}
|
||||
|
||||
@@ -454,11 +438,11 @@ KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
|
||||
// Should we prevent the browser from handling the event?
|
||||
// Doing so on a keydown (in most browsers) prevents keypress from being generated
|
||||
// so only do that if we have to.
|
||||
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt));
|
||||
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!nonCharacterKey(evt));
|
||||
|
||||
// If a char modifier is down on a keydown, we need to insert a stall,
|
||||
// so VerifyCharModifier knows to wait and see if a keypress is comnig
|
||||
var stall = type === 'keydown' && modifierState.activeCharModifier() && !KeyboardUtil.nonCharacterKey(evt);
|
||||
var stall = type === 'keydown' && modifierState.activeCharModifier() && !nonCharacterKey(evt);
|
||||
|
||||
// if a char modifier is pressed, get the keys it consists of (on Windows, AltGr is equivalent to Ctrl+Alt)
|
||||
var active = modifierState.activeCharModifier();
|
||||
@@ -512,7 +496,7 @@ KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
|
||||
// so when used with the '2' key, Ctrl-Alt counts as a char modifier (and should be escaped), but when used with 'D', it does not.
|
||||
// The only way we can distinguish these cases is to wait and see if a keypress event arrives
|
||||
// When we receive a "stall" event, wait a few ms before processing the next keydown. If a keypress has also arrived, merge the two
|
||||
KeyboardUtil.VerifyCharModifier = function(next) {
|
||||
export function VerifyCharModifier (next) {
|
||||
"use strict";
|
||||
var queue = [];
|
||||
var timer = null;
|
||||
@@ -569,7 +553,7 @@ KeyboardUtil.VerifyCharModifier = function(next) {
|
||||
// in some cases, a single key may produce multiple keysyms, so the corresponding keyup event must release all of these chars
|
||||
// key repeat events should be merged into a single entry.
|
||||
// Because we can't always identify which entry a keydown or keyup event corresponds to, we sometimes have to guess
|
||||
KeyboardUtil.TrackKeyState = function(next) {
|
||||
export function TrackKeyState (next) {
|
||||
"use strict";
|
||||
var state = [];
|
||||
|
||||
@@ -653,7 +637,7 @@ KeyboardUtil.TrackKeyState = function(next) {
|
||||
|
||||
// Handles "escaping" of modifiers: if a char modifier is used to produce a keysym (such as AltGr-2 to generate an @),
|
||||
// then the modifier must be "undone" before sending the @, and "redone" afterwards.
|
||||
KeyboardUtil.EscapeModifiers = function(next) {
|
||||
export function EscapeModifiers (next) {
|
||||
"use strict";
|
||||
return function(evt) {
|
||||
if (evt.type !== 'keydown' || evt.escape === undefined) {
|
||||
@@ -674,5 +658,3 @@ KeyboardUtil.EscapeModifiers = function(next) {
|
||||
/* jshint shadow: false */
|
||||
};
|
||||
};
|
||||
|
||||
export default KeyboardUtil;
|
||||
|
||||
Reference in New Issue
Block a user