Merge branch 'master' into gh-pages
This commit is contained in:
commit
2ec8ebd11d
16 changed files with 895 additions and 520 deletions
|
|
@ -125,16 +125,57 @@ class Keyboard8080 extends Component {
|
|||
*
|
||||
* this.bindings[id] = control;
|
||||
*/
|
||||
control.onkeydown = function onKeyDown(event) {
|
||||
return kbd.onKeyDown(event, true);
|
||||
};
|
||||
control.onkeyup = function onKeyUp(event) {
|
||||
return kbd.onKeyDown(event, false);
|
||||
};
|
||||
control.onkeypress = function onKeyPress(event) {
|
||||
return kbd.onKeyPress(event);
|
||||
};
|
||||
control.onpaste = function onKeyPaste(event) {
|
||||
if (Web.isUserAgent("iOS")) {
|
||||
/*
|
||||
* For iOS devices, it's best to deal only with keypress events. The main reason is that we don't
|
||||
* get shift-key events, so we have no way of distinguishing between certain keys, such as ':' and
|
||||
* ';', unless we are monitoring key presses. Another reason is that, under certain poorly documented
|
||||
* conditions, an iOS keyup event will not contain any keyCode; this is most easily reproduced with
|
||||
* the iOS simulator and a physical keyboard (not the pop-up keyboard). When this happens, we think
|
||||
* the key is stuck. Finally, certain other problems that we have tried to resolve when using a physical
|
||||
* keyboard (eg, keeping the physical and virtual CAPS-LOCK states in sync) simply don't exist in the
|
||||
* iOS environment.
|
||||
*
|
||||
* So, with all that mind, it seems best to have a separate iOS keypress handler and forego keydown
|
||||
* and keyup events entirely. The iOS keypress handler must also perform some additional checks, such
|
||||
* as watching for keys that can only be typed on the emulated device when a shift key is down, and
|
||||
* simulating "fake" shift-key down and up events.
|
||||
*
|
||||
* Perhaps we can eventually standardize on this alternate keypress-centric approach for ALL devices,
|
||||
* but until then, it's safer to have these two code paths.
|
||||
*
|
||||
* UPDATE: So much for the best laid plans. iOS won't deliver BACKSPACE events to the keypress handler,
|
||||
* so we have to deal with keydown/keyup events after all.
|
||||
*/
|
||||
control.onkeypress = function oniOSKeyPress(event)
|
||||
{
|
||||
return kbd.oniOSKeyPress(event);
|
||||
};
|
||||
control.onkeydown = function oniOSKeyDown(event)
|
||||
{
|
||||
return kbd.oniOSKeyDown(event, true);
|
||||
};
|
||||
control.onkeyup = function oniOSKeyUp(event)
|
||||
{
|
||||
return kbd.oniOSKeyDown(event, false);
|
||||
};
|
||||
}
|
||||
else {
|
||||
control.onkeydown = function onKeyDown(event)
|
||||
{
|
||||
return kbd.onKeyDown(event, true);
|
||||
};
|
||||
control.onkeyup = function onKeyUp(event)
|
||||
{
|
||||
return kbd.onKeyDown(event, false);
|
||||
};
|
||||
control.onkeypress = function onKeyPress(event)
|
||||
{
|
||||
return kbd.onKeyPress(event);
|
||||
};
|
||||
}
|
||||
control.onpaste = function onKeyPaste(event)
|
||||
{
|
||||
return kbd.onPaste(event);
|
||||
};
|
||||
return true;
|
||||
|
|
@ -152,16 +193,25 @@ class Keyboard8080 extends Component {
|
|||
/*
|
||||
* TODO: Add some additional SOFTCODES configuration info that will tell us which soft
|
||||
* keys (eg, CTRL) should be treated as toggles, instead of hard-coding that knowledge below.
|
||||
*
|
||||
* Moreover, if a *real* CTRL or CAPS-LOCK key is pressed or released, it would be nice
|
||||
* to update the state of these on-screen controls, too (ie, not just when the controls are
|
||||
* clicked).
|
||||
*/
|
||||
var fDown = true;
|
||||
var fAutoRelease = (keyCode != Keys.KEYCODE.CTRL);
|
||||
if (!fAutoRelease) {
|
||||
var fDown = true, bit = 0;
|
||||
if (keyCode == Keys.KEYCODE.CTRL) {
|
||||
bit = Keyboard8080.STATE.CTRL;
|
||||
}
|
||||
else if (keyCode == Keys.KEYCODE.CAPS_LOCK) {
|
||||
bit = Keyboard8080.STATE.CAPS_LOCK;
|
||||
}
|
||||
if (bit) {
|
||||
control.style.fontWeight = "normal";
|
||||
fDown = !(kbd.bitsState & Keyboard8080.STATE.CTRL);
|
||||
fDown = !(kbd.bitsState & bit);
|
||||
if (fDown) control.style.fontWeight = "bold";
|
||||
kbd.checkModifierKeys(keyCode, fDown);
|
||||
}
|
||||
kbd.onSoftKeyDown(keyCode, fDown, fAutoRelease);
|
||||
kbd.onSoftKeyDown(keyCode, fDown, !bit);
|
||||
if (kbd.cmp) kbd.cmp.updateFocus();
|
||||
};
|
||||
}(this, this.config.SOFTCODES[sBinding]);
|
||||
|
|
@ -403,6 +453,7 @@ class Keyboard8080 extends Component {
|
|||
* @param {number} keyCode (ie, either a keycode or string ID)
|
||||
* @param {boolean} fDown (true if key going down, false if key going up)
|
||||
* @param {boolean} [fRight] (true if key is on the right, false if not or unknown or n/a)
|
||||
* @return {boolean} (fDown updated as needed for CAPS-LOCK weirdness)
|
||||
*/
|
||||
checkModifierKeys(keyCode, fDown, fRight)
|
||||
{
|
||||
|
|
@ -422,6 +473,16 @@ class Keyboard8080 extends Component {
|
|||
break;
|
||||
case Keys.KEYCODE.CAPS_LOCK:
|
||||
bit = Keyboard8080.STATE.CAPS_LOCK;
|
||||
/*
|
||||
* WARNING: You have an entered a browser weirdness zone. In Chrome, pressing-and-releasing
|
||||
* CAPS-LOCK generates a "down" event when it turns the lock on and an "up" event when it turns
|
||||
* the lock off. Firefox, OTOH, generates only "down" events, so we have to "manufacture"
|
||||
* the fDown parameter ourselves -- which means we also have to propagate it back to the caller.
|
||||
*
|
||||
* And, while this isn't necessary for Chrome, it doesn't appear to hurt anything in Chrome, so
|
||||
* we're not going to bother making it browser-specific.
|
||||
*/
|
||||
fDown = !(this.bitsState & bit);
|
||||
break;
|
||||
}
|
||||
if (bit) {
|
||||
|
|
@ -431,6 +492,7 @@ class Keyboard8080 extends Component {
|
|||
this.bitsState &= ~bit;
|
||||
}
|
||||
}
|
||||
return fDown;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -468,12 +530,23 @@ class Keyboard8080 extends Component {
|
|||
var fPass = true;
|
||||
var keyCode = event.keyCode;
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
this.printMessage("onKey" + (fDown? "Down" : "Up") + "(" + keyCode + ")", true);
|
||||
}
|
||||
|
||||
/*
|
||||
* A note about Firefox: it uses different keyCodes for certain keys; there's a logic to the differences
|
||||
* (they use ASCII codes), but since other browsers didn't follow suit, we must use a mapping table to
|
||||
* convert their keyCodes to the more traditional values.
|
||||
*/
|
||||
keyCode = Keys.FF_KEYCODES[keyCode] || keyCode;
|
||||
|
||||
/*
|
||||
* We now keep track of physical keyboard modifier keys. This makes it possible for new services
|
||||
* to eventually be implemented (simulateKeysDown() and simulateKeysUp()), to map special ALT-key
|
||||
* combinations to VT100 keys, etc.
|
||||
*/
|
||||
this.checkModifierKeys(keyCode, fDown, event.location == Keys.LOCATION.RIGHT);
|
||||
fDown = this.checkModifierKeys(keyCode, fDown, event.location == Keys.LOCATION.RIGHT);
|
||||
|
||||
var softCode = this.getSoftCode(keyCode);
|
||||
if (softCode) {
|
||||
|
|
@ -554,21 +627,125 @@ class Keyboard8080 extends Component {
|
|||
*/
|
||||
onKeyPress(event)
|
||||
{
|
||||
var keyCode = event.keyCode;
|
||||
if (keyCode >= Keys.ASCII.A && keyCode <= Keys.ASCII.Z) {
|
||||
/*
|
||||
* A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so
|
||||
* we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't
|
||||
* really go away.
|
||||
*
|
||||
* TODO: Consider "upgrading" this code to use the new 'key' property. Note, however, that it's a string,
|
||||
* not a number; for example; if the colon key is pressed, 'key' will be ":", whereas 'charCode' and 'which'
|
||||
* will be 58.
|
||||
*/
|
||||
var charCode = event.keyCode || event.charCode;
|
||||
|
||||
if (charCode >= Keys.ASCII.A && charCode <= Keys.ASCII.Z) {
|
||||
if (!(this.bitsState & (Keyboard8080.STATE.SHIFTS | Keyboard8080.STATE.CAPS_LOCK))) {
|
||||
this.bitsState |= Keyboard8080.STATE.CAPS_LOCK;
|
||||
this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, true);
|
||||
this.updateLEDs();
|
||||
}
|
||||
}
|
||||
else if (keyCode >= Keys.ASCII.a && keyCode <= Keys.ASCII.z) {
|
||||
else if (charCode >= Keys.ASCII.a && charCode <= Keys.ASCII.z) {
|
||||
if (this.bitsState & Keyboard8080.STATE.CAPS_LOCK) {
|
||||
this.bitsState &= ~Keyboard8080.STATE.CAPS_LOCK;
|
||||
this.onSoftKeyDown(Keys.KEYCODE.CAPS_LOCK, false);
|
||||
this.updateLEDs();
|
||||
}
|
||||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
this.printMessage("onKeyPress(" + charCode + ")", true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* oniOSKeyDown(event, fDown)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} event
|
||||
* @param {boolean} fDown is true for a keyDown event, false for up
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
oniOSKeyDown(event, fDown)
|
||||
{
|
||||
var fPass = true;
|
||||
/*
|
||||
* Because keydown/keyup events on iOS are inherently "fake", they can be delivered so quickly that
|
||||
* if we generated matching down/up events, then the emulated machine might not see the key transition.
|
||||
* So we now deliver only down events, with fAutoRelease always set (see below).
|
||||
*
|
||||
* Also, because of iOS weirdness discussed in setBinding() when using a physical keyboard, the keyup
|
||||
* event may not provide a valid keyCode, which is another reason we have no choice but to always deliver
|
||||
* keys with fAutoRelease set to true.
|
||||
*/
|
||||
if (fDown) {
|
||||
var keyCode = event.keyCode;
|
||||
var bMapping = this.config.KEYMAP[keyCode];
|
||||
if (bMapping) {
|
||||
/*
|
||||
* If this is a mappable key, but the mapping isn't in the CHARMAP table, then we have to process
|
||||
* it now; the most common reason is that the key doesn't generate a keypress event (eg, BACKSPACE).
|
||||
*/
|
||||
if (!this.indexOfCharMap(bMapping)) {
|
||||
fPass = this.onSoftKeyDown(keyCode, fDown, true);
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
this.printMessage("oniOSKey" + (fDown ? "Down" : "Up") + "(" + keyCode + "): pass=" + fPass, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* oniOSKeyPress(event)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {Object} event
|
||||
* @return {boolean} true to pass the event along, false to consume it
|
||||
*/
|
||||
oniOSKeyPress(event)
|
||||
{
|
||||
/*
|
||||
* A note about Firefox: the KeyboardEvent they pass to a keypress handler doesn't set 'keyCode', so
|
||||
* we have to fallback to 'charCode' (or 'which'), both of which are deprecated but realistically can't
|
||||
* really go away.
|
||||
*
|
||||
* TODO: Consider "upgrading" this code to use the new 'key' property. Note, however, that it's a string,
|
||||
* not a number; for example; if the colon key is pressed, 'key' will be ":", whereas 'charCode' and 'which'
|
||||
* will be 58.
|
||||
*/
|
||||
var charCode = event.keyCode || event.charCode;
|
||||
|
||||
var fShifted = false;
|
||||
var bMapping = this.config.CHARMAP[charCode];
|
||||
if (bMapping) {
|
||||
if (bMapping & 0x80) {
|
||||
bMapping &= 0x7f;
|
||||
fShifted = true;
|
||||
}
|
||||
/*
|
||||
* Since the rest of our code was built around keyCodes, not charCodes, we look up the CHARMAP byte
|
||||
* in the KEYMAP table to find a corresponding keyCode, and that's what we'll use to simulate the key
|
||||
* press/release.
|
||||
*/
|
||||
var softCode = this.indexOfKeyMap(bMapping);
|
||||
if (softCode) {
|
||||
if (!fShifted) {
|
||||
this.onSoftKeyDown(Keys.KEYCODE.SHIFT, false);
|
||||
} else {
|
||||
this.onSoftKeyDown(Keys.KEYCODE.SHIFT, true, true);
|
||||
}
|
||||
this.onSoftKeyDown(softCode, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!COMPILED && this.messageEnabled(Messages8080.KEYS)) {
|
||||
this.printMessage("oniOSKeyPress(" + charCode + ")", true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -606,6 +783,36 @@ class Keyboard8080 extends Component {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* indexOfKeyMap(bMapping)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} bMapping
|
||||
* @return {number}
|
||||
*/
|
||||
indexOfKeyMap(bMapping)
|
||||
{
|
||||
for (var keyCode in this.config.KEYMAP) {
|
||||
if (this.config.KEYMAP[keyCode] == bMapping) return +keyCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* indexOfCharMap(bMapping)
|
||||
*
|
||||
* @this {Keyboard8080}
|
||||
* @param {number} bMapping
|
||||
* @return {number}
|
||||
*/
|
||||
indexOfCharMap(bMapping)
|
||||
{
|
||||
for (var charCode in this.config.CHARMAP) {
|
||||
if (this.config.CHARMAP[charCode] == bMapping) return +charCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* indexOfSoftKey(softCode)
|
||||
*
|
||||
|
|
@ -935,6 +1142,7 @@ Keyboard8080.WASDCODES[Keys.ASCII.L] = Keys.KEYCODE.SPACE;
|
|||
Keyboard8080.SI1978 = {
|
||||
MODEL: 1978.1,
|
||||
KEYMAP: {},
|
||||
CHARMAP: {},
|
||||
ALTCODES: Keyboard8080.WASDCODES,
|
||||
LEDCODES: {},
|
||||
SOFTCODES: {
|
||||
|
|
@ -951,7 +1159,7 @@ Keyboard8080.VT100 = {
|
|||
MODEL: 100.0,
|
||||
KEYMAP: {
|
||||
/*
|
||||
* Map of host key codes to VT100 key addresses (7-bit values representing key positions on the VT100).
|
||||
* Map of host keyCodes to VT100 key addresses (7-bit values representing key positions on the VT100).
|
||||
*
|
||||
* NOTE: The VT100 keyboard has both BACKSPACE and DELETE keys, whereas modern keyboards generally only
|
||||
* have DELETE. And sadly, when you press DELETE, your modern keyboard and/or modern browser is reporting
|
||||
|
|
@ -1048,15 +1256,125 @@ Keyboard8080.VT100 = {
|
|||
[Keys.KEYCODE.F9]: 0x7B, // aka SET-UP
|
||||
[Keys.KEYCODE.CTRL]: 0x7C,
|
||||
[Keys.KEYCODE.SHIFT]: 0x7D, // either shift key (doesn't matter)
|
||||
[Keys.KEYCODE.CAPS_LOCK]: 0x7E
|
||||
[Keys.KEYCODE.CAPS_LOCK]:0x7E
|
||||
},
|
||||
CHARMAP: {
|
||||
/*
|
||||
* Map of host charCodes to VT100 key addresses (7-bit values representing key positions on the VT100);
|
||||
* the 8th bit (0x80) is set for keys that need to be shifted.
|
||||
*
|
||||
* This is currently used only with the iOS keypress handler, which receives character codes rather than
|
||||
* keyboard codes. As a result, this table is not as complete as the KEYMAP table, because certain keys
|
||||
* are delivered as key presses and/or are simply not present on the iOS keyboard; the arrow keys are a
|
||||
* good example.
|
||||
*
|
||||
* ES6 ALERT: As you can see below, I've finally started using computed property names.
|
||||
*/
|
||||
[Keys.ASCII.p]: 0x05,
|
||||
[Keys.ASCII.o]: 0x06,
|
||||
[Keys.ASCII.y]: 0x07,
|
||||
[Keys.ASCII.t]: 0x08,
|
||||
[Keys.ASCII.w]: 0x09,
|
||||
[Keys.ASCII.q]: 0x0A,
|
||||
[Keys.ASCII[']']]: 0x14,
|
||||
[Keys.ASCII['[']]: 0x15,
|
||||
[Keys.ASCII.i]: 0x16,
|
||||
[Keys.ASCII.u]: 0x17,
|
||||
[Keys.ASCII.r]: 0x18,
|
||||
[Keys.ASCII.e]: 0x19,
|
||||
[Keys.ASCII['1']]: 0x1A,
|
||||
[Keys.ASCII['`']]: 0x24,
|
||||
[Keys.ASCII['-']]: 0x25,
|
||||
[Keys.ASCII['9']]: 0x26,
|
||||
[Keys.ASCII['7']]: 0x27,
|
||||
[Keys.ASCII['4']]: 0x28,
|
||||
[Keys.ASCII['3']]: 0x29,
|
||||
[Keys.ASCII['=']]: 0x34,
|
||||
[Keys.ASCII['0']]: 0x35,
|
||||
[Keys.ASCII['8']]: 0x36,
|
||||
[Keys.ASCII['6']]: 0x37,
|
||||
[Keys.ASCII['5']]: 0x38,
|
||||
[Keys.ASCII['2']]: 0x39,
|
||||
[Keys.ASCII['\\']]: 0x45,
|
||||
[Keys.ASCII.l]: 0x46,
|
||||
[Keys.ASCII.k]: 0x47,
|
||||
[Keys.ASCII.g]: 0x48,
|
||||
[Keys.ASCII.f]: 0x49,
|
||||
[Keys.ASCII.a]: 0x4A,
|
||||
[Keys.ASCII["'"]]: 0x55,
|
||||
[Keys.ASCII[';']]: 0x56,
|
||||
[Keys.ASCII.j]: 0x57,
|
||||
[Keys.ASCII.h]: 0x58,
|
||||
[Keys.ASCII.d]: 0x59,
|
||||
[Keys.ASCII.s]: 0x5A,
|
||||
[Keys.KEYCODE.CR]: 0x64, // TODO: Figure out why the Technical Manual lists CR at both 0x04 and 0x64
|
||||
[Keys.ASCII['.']]: 0x65,
|
||||
[Keys.ASCII[',']]: 0x66,
|
||||
[Keys.ASCII.n]: 0x67,
|
||||
[Keys.ASCII.b]: 0x68,
|
||||
[Keys.ASCII.x]: 0x69,
|
||||
[Keys.ASCII['/']]: 0x75,
|
||||
[Keys.ASCII.m]: 0x76,
|
||||
[Keys.ASCII[' ']]: 0x77,
|
||||
[Keys.ASCII.v]: 0x78,
|
||||
[Keys.ASCII.c]: 0x79,
|
||||
[Keys.ASCII.z]: 0x7A,
|
||||
[Keys.ASCII.P]: 0x85,
|
||||
[Keys.ASCII.O]: 0x86,
|
||||
[Keys.ASCII.Y]: 0x87,
|
||||
[Keys.ASCII.T]: 0x88,
|
||||
[Keys.ASCII.W]: 0x89,
|
||||
[Keys.ASCII.Q]: 0x8A,
|
||||
[Keys.ASCII['}']]: 0x94,
|
||||
[Keys.ASCII['{']]: 0x95,
|
||||
[Keys.ASCII.I]: 0x96,
|
||||
[Keys.ASCII.U]: 0x97,
|
||||
[Keys.ASCII.R]: 0x98,
|
||||
[Keys.ASCII.E]: 0x99,
|
||||
[Keys.ASCII['!']]: 0x9A,
|
||||
[Keys.ASCII['~']]: 0xA4,
|
||||
[Keys.ASCII['_']]: 0xA5,
|
||||
[Keys.ASCII['(']]: 0xA6,
|
||||
[Keys.ASCII['&']]: 0xA7,
|
||||
[Keys.ASCII['$']]: 0xA8,
|
||||
[Keys.ASCII['#']]: 0xA9,
|
||||
[Keys.ASCII['+']]: 0xB4,
|
||||
[Keys.ASCII[')']]: 0xB5,
|
||||
[Keys.ASCII['*']]: 0xB6,
|
||||
[Keys.ASCII['^']]: 0xB7,
|
||||
[Keys.ASCII['%']]: 0xB8,
|
||||
[Keys.ASCII['@']]: 0xB9,
|
||||
[Keys.ASCII['|']]: 0xC5,
|
||||
[Keys.ASCII.L]: 0xC6,
|
||||
[Keys.ASCII.K]: 0xC7,
|
||||
[Keys.ASCII.G]: 0xC8,
|
||||
[Keys.ASCII.F]: 0xC9,
|
||||
[Keys.ASCII.A]: 0xCA,
|
||||
[Keys.ASCII['"']]: 0xD5,
|
||||
[Keys.ASCII[':']]: 0xD6,
|
||||
[Keys.ASCII.J]: 0xD7,
|
||||
[Keys.ASCII.H]: 0xD8,
|
||||
[Keys.ASCII.D]: 0xD9,
|
||||
[Keys.ASCII.S]: 0xDA,
|
||||
[Keys.ASCII['>']]: 0xE5,
|
||||
[Keys.ASCII['<']]: 0xE6,
|
||||
[Keys.ASCII.N]: 0xE7,
|
||||
[Keys.ASCII.B]: 0xE8,
|
||||
[Keys.ASCII.X]: 0xE9,
|
||||
[Keys.ASCII['?']]: 0xF5,
|
||||
[Keys.ASCII.M]: 0xF6,
|
||||
[Keys.ASCII.V]: 0xF8,
|
||||
[Keys.ASCII.C]: 0xF9,
|
||||
[Keys.ASCII.Z]: 0xFA
|
||||
},
|
||||
ALTCODES: {},
|
||||
LEDCODES: {},
|
||||
SOFTCODES: {
|
||||
'caps-lock': Keys.KEYCODE.CAPS_LOCK,
|
||||
'ctrl': Keys.KEYCODE.CTRL,
|
||||
'esc': Keys.KEYCODE.ESC,
|
||||
'tab': Keys.KEYCODE.TAB,
|
||||
'num-comma': Keys.KEYCODE.F5,// since modern keypads don't typically have a comma...
|
||||
'num-comma': Keys.KEYCODE.F5, // since modern keypads don't typically have a comma...
|
||||
'break': Keys.KEYCODE.F6,
|
||||
'line-feed': Keys.KEYCODE.F7,
|
||||
'no-scroll': Keys.KEYCODE.F8,
|
||||
|
|
|
|||
|
|
@ -1103,7 +1103,7 @@ Keyboard.prototype.findBinding = function(simCode, sType, fDown)
|
|||
for (var code in Keys.SHIFTED_KEYCODES) {
|
||||
if (simCode == Keys.SHIFTED_KEYCODES[code]) {
|
||||
simCode = +code;
|
||||
code = Keys.STUPID_KEYCODES[code];
|
||||
code = Keys.NONASCII_KEYCODES[code];
|
||||
if (code) simCode = code;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2045,7 +2045,7 @@ Keyboard.prototype.getSimCode = function(keyCode, fShifted)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (code = Keys.STUPID_KEYCODES[keyCode]) {
|
||||
if (code = Keys.NONASCII_KEYCODES[keyCode]) {
|
||||
simCode = code;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,10 +69,10 @@ var Keys = {
|
|||
* them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).
|
||||
*/
|
||||
KEYCODE: {
|
||||
/* 0x08 */ BS: 8, // BACKSPACE
|
||||
/* 0x09 */ TAB: 9,
|
||||
/* 0x0A */ LF: 10, // LINE FEED (TODO: Determine if any key actually generates this)
|
||||
/* 0x0D */ CR: 13, // CARRIAGE RETURN
|
||||
/* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)
|
||||
/* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)
|
||||
/* 0x0A */ LF: 10, // LINE FEED (ASCII.CTRL_J) (TODO: Determine if any key actually generates this)
|
||||
/* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)
|
||||
/* 0x10 */ SHIFT: 16,
|
||||
/* 0x11 */ CTRL: 17,
|
||||
/* 0x12 */ ALT: 18,
|
||||
|
|
@ -153,17 +153,17 @@ var Keys = {
|
|||
/* 0x90 */ NUM_LOCK: 144,
|
||||
/* 0x91 */ SCROLL_LOCK: 145,
|
||||
/* 0xAD */ FF_DASH: 173,
|
||||
/* 0xBA */ SEMI: 186, // Firefox: 59
|
||||
/* 0xBB */ EQUALS: 187, // Firefox: 61
|
||||
/* 0xBC */ COMMA: 188, // Firefox: 44
|
||||
/* 0xBD */ DASH: 189, // Firefox: 173
|
||||
/* 0xBE */ PERIOD: 190, // Firefox: 46
|
||||
/* 0xBF */ SLASH: 191, // Firefox: 47
|
||||
/* 0xC0 */ BQUOTE: 192, // Firefox: 96
|
||||
/* 0xDB */ LBRACK: 219, // Firefox: 91
|
||||
/* 0xDC */ BSLASH: 220, // Firefox: 92
|
||||
/* 0xDD */ RBRACK: 221, // Firefox: 93
|
||||
/* 0xDE */ QUOTE: 222, // Firefox: 39
|
||||
/* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)
|
||||
/* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)
|
||||
/* 0xBC */ COMMA: 188,
|
||||
/* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)
|
||||
/* 0xBE */ PERIOD: 190,
|
||||
/* 0xBF */ SLASH: 191,
|
||||
/* 0xC0 */ BQUOTE: 192,
|
||||
/* 0xDB */ LBRACK: 219,
|
||||
/* 0xDC */ BSLASH: 220,
|
||||
/* 0xDD */ RBRACK: 221,
|
||||
/* 0xDE */ QUOTE: 222,
|
||||
/* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)
|
||||
//
|
||||
// The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),
|
||||
|
|
@ -201,22 +201,43 @@ var Keys = {
|
|||
*/
|
||||
Keys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;
|
||||
|
||||
|
||||
/*
|
||||
* Maps "stupid" keyCodes to their "non-stupid" counterparts
|
||||
* Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table
|
||||
* are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I
|
||||
* simply extended this table to resolve additional differences in other browsers (ie, Opera), but without
|
||||
* browser-specific checks, it's not safe to perform all the mappings shown below.
|
||||
*/
|
||||
Keys.STUPID_KEYCODES = {};
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\']; // 220 -> 92
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII["'"]; // 222 -> 39
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-'];
|
||||
Keys.FF_KEYCODES = {};
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222
|
||||
|
||||
/*
|
||||
* Maps non-ASCII keyCodes to their ASCII counterparts
|
||||
*/
|
||||
Keys.NONASCII_KEYCODES = {};
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\']; // 220 -> 92
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII["'"]; // 222 -> 39
|
||||
|
||||
/*
|
||||
* Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.
|
||||
|
|
|
|||
|
|
@ -69,10 +69,10 @@ var Keys = {
|
|||
* them using ASCII codes (eg, the LEFT arrow key uses the ASCII code for '%' or 37).
|
||||
*/
|
||||
KEYCODE: {
|
||||
/* 0x08 */ BS: 8, // BACKSPACE
|
||||
/* 0x09 */ TAB: 9,
|
||||
/* 0x0A */ LF: 10, // LINE FEED (TODO: Determine if any key actually generates this)
|
||||
/* 0x0D */ CR: 13, // CARRIAGE RETURN
|
||||
/* 0x08 */ BS: 8, // BACKSPACE (ASCII.CTRL_H)
|
||||
/* 0x09 */ TAB: 9, // TAB (ASCII.CTRL_I)
|
||||
/* 0x0A */ LF: 10, // LINE FEED (ASCII.CTRL_J) (TODO: Determine if any key actually generates this)
|
||||
/* 0x0D */ CR: 13, // CARRIAGE RETURN (ASCII.CTRL_M)
|
||||
/* 0x10 */ SHIFT: 16,
|
||||
/* 0x11 */ CTRL: 17,
|
||||
/* 0x12 */ ALT: 18,
|
||||
|
|
@ -153,17 +153,17 @@ var Keys = {
|
|||
/* 0x90 */ NUM_LOCK: 144,
|
||||
/* 0x91 */ SCROLL_LOCK: 145,
|
||||
/* 0xAD */ FF_DASH: 173,
|
||||
/* 0xBA */ SEMI: 186, // Firefox: 59
|
||||
/* 0xBB */ EQUALS: 187, // Firefox: 61
|
||||
/* 0xBC */ COMMA: 188, // Firefox: 44
|
||||
/* 0xBD */ DASH: 189, // Firefox: 173
|
||||
/* 0xBE */ PERIOD: 190, // Firefox: 46
|
||||
/* 0xBF */ SLASH: 191, // Firefox: 47
|
||||
/* 0xC0 */ BQUOTE: 192, // Firefox: 96
|
||||
/* 0xDB */ LBRACK: 219, // Firefox: 91
|
||||
/* 0xDC */ BSLASH: 220, // Firefox: 92
|
||||
/* 0xDD */ RBRACK: 221, // Firefox: 93
|
||||
/* 0xDE */ QUOTE: 222, // Firefox: 39
|
||||
/* 0xBA */ SEMI: 186, // Firefox: 59 (FF_SEMI)
|
||||
/* 0xBB */ EQUALS: 187, // Firefox: 61 (FF_EQUALS)
|
||||
/* 0xBC */ COMMA: 188,
|
||||
/* 0xBD */ DASH: 189, // Firefox: 173 (FF_DASH)
|
||||
/* 0xBE */ PERIOD: 190,
|
||||
/* 0xBF */ SLASH: 191,
|
||||
/* 0xC0 */ BQUOTE: 192,
|
||||
/* 0xDB */ LBRACK: 219,
|
||||
/* 0xDC */ BSLASH: 220,
|
||||
/* 0xDD */ RBRACK: 221,
|
||||
/* 0xDE */ QUOTE: 222,
|
||||
/* 0xE0 */ FF_CMD: 224, // Firefox only (used for both CMD and RCMD)
|
||||
//
|
||||
// The following biases use what I'll call Decimal Coded Binary or DCB (the opposite of BCD),
|
||||
|
|
@ -202,21 +202,41 @@ var Keys = {
|
|||
Keys.KEYCODE.NUM_CR = Keys.KEYCODE.CR + Keys.KEYCODE.ONRIGHT;
|
||||
|
||||
/*
|
||||
* Maps "stupid" keyCodes to their "non-stupid" counterparts
|
||||
* Maps Firefox keyCodes to their more common keyCode counterparts; a number of entries in this table
|
||||
* are no longer valid (if indeed they ever were), so they've been commented out. It's likely that I
|
||||
* simply extended this table to resolve additional differences in other browsers (ie, Opera), but without
|
||||
* browser-specific checks, it's not safe to perform all the mappings shown below.
|
||||
*/
|
||||
Keys.STUPID_KEYCODES = {};
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\']; // 220 -> 92
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII["'"]; // 222 -> 39
|
||||
Keys.STUPID_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-'];
|
||||
Keys.FF_KEYCODES = {};
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_SEMI] = Keys.KEYCODE.SEMI; // 59 -> 186
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_EQUALS] = Keys.KEYCODE.EQUALS; // 61 -> 187
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.KEYCODE.DASH; // 173 -> 189
|
||||
Keys.FF_KEYCODES[Keys.KEYCODE.FF_CMD] = Keys.KEYCODE.CMD; // 224 -> 91
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_COMMA] = Keys.KEYCODE.COMMA; // 44 -> 188
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_PERIOD] = Keys.KEYCODE.PERIOD; // 46 -> 190
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_SLASH] = Keys.KEYCODE.SLASH; // 47 -> 191
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BQUOTE] = Keys.KEYCODE.BQUOTE; // 96 -> 192
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_LBRACK = Keys.KEYCODE.LBRACK; // 91 -> 219
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_BSLASH] = Keys.KEYCODE.BSLASH; // 92 -> 220
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_RBRACK] = Keys.KEYCODE.RBRACK; // 93 -> 221
|
||||
// Keys.FF_KEYCODES[Keys.KEYCODE.FF_QUOTE] = Keys.KEYCODE.QUOTE; // 39 -> 222
|
||||
|
||||
/*
|
||||
* Maps non-ASCII keyCodes to their ASCII counterparts
|
||||
*/
|
||||
Keys.NONASCII_KEYCODES = {};
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.FF_DASH] = Keys.ASCII['-']; // 173 -> 45
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.SEMI] = Keys.ASCII[';']; // 186 -> 59
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.EQUALS] = Keys.ASCII['=']; // 187 -> 61
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.DASH] = Keys.ASCII['-']; // 189 -> 45
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.COMMA] = Keys.ASCII[',']; // 188 -> 44
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.PERIOD] = Keys.ASCII['.']; // 190 -> 46
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.SLASH] = Keys.ASCII['/']; // 191 -> 47
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.BQUOTE] = Keys.ASCII['`']; // 192 -> 96
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.LBRACK] = Keys.ASCII['[']; // 219 -> 91
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.BSLASH] = Keys.ASCII['\\']; // 220 -> 92
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.RBRACK] = Keys.ASCII[']']; // 221 -> 93
|
||||
Keys.NONASCII_KEYCODES[Keys.KEYCODE.QUOTE] = Keys.ASCII["'"]; // 222 -> 39
|
||||
|
||||
/*
|
||||
* Maps unshifted keyCodes to their shifted counterparts; to be used when a shift-key is down.
|
||||
|
|
|
|||
Loading…
Reference in a new issue