Skip to content

Commit

Permalink
feature(map/keycode): adding alphanumeric keycodes and aliasing
Browse files Browse the repository at this point in the history
  • Loading branch information
rodneyrehm committed Dec 5, 2015
1 parent a06814c commit 28e91fb
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -29,6 +29,7 @@ The following lists show the changes to the library grouped by domain.
#### Keyboard support

* changing [`ally.when.key`][ally/when/key] to handle modifier keys - [issue #59](https://github.com/medialize/ally.js/issues/59)
* changing [`ally.map.keycode`][ally/map/keycode] to provide alphanumeric keys and aliasing

#### Internals

Expand Down
47 changes: 45 additions & 2 deletions docs/api/map/keycode.md
Expand Up @@ -5,7 +5,7 @@ tags: data

# ally.map.keycode

Map of control [`event.keyCode`](https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode)s.
Map human readable names for [`event.keyCode`](https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode)s.


## Description
Expand All @@ -26,19 +26,62 @@ var map = {
enter: 13,
escape: 27,
space: 32,

// Function keys
f1: 112,
// ...

// Numeric keys
0: 48,
1: 49,
// ...
"num-0": 96,
"num-1": 97,
// ...

// Latin characters
a: 65,
// ...
z: 90,
}
```

The map knows the following keys:

* `a` - `z`
* `0` - `9`
* `num-0` - `num-9` (number block)
* `f1` - `f25` (function keys)
* `down`, `left`, `right`, `up` (arrow keys)
* `end`, `home`, `pageDown`, `page-down`, `pageUp`, `page-up`
* `enter`, `escape`, `space`, `tab`
* `alt`, `capsLock`, `caps-lock`, `ctrl`, `meta`, `shift`
* `pause`, `insert`, `delete`, `backspace`


## Usage

```js
console.log(ally.map.keycode.enter);
console.log("keycode of enter", ally.map.keycode.enter);
```


## Changes

* `v#master` replaced the key `command` by `meta`.
* `v#master` added `a` - `z`, `0` - `9`, `num-0` - `num-9`, `f13` - `f25`, `page-down`, `page-up`, `caps-lock`.
* `v#master` added `_alias` to resolve multiple keyCodes for the same logical key.


## Notes

* **NOTE:** The key `meta` is known by different keyCodes: `91`, `92`, `93`, `224` - which `ally.map.keycodes.alias.91` helps to resolve. The same is true for numeric keys (0-9) and their counterparts on the numblock.


## Related resources

* [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) may help deal with this mess in the future.


## Contributing

Expand Down
58 changes: 42 additions & 16 deletions src/map/keycode.js
@@ -1,7 +1,11 @@

// https://github.com/keithamus/jwerty/blob/master/jwerty.js
// codes mostly cloned from https://github.com/keithamus/jwerty/blob/master/jwerty.js
// deliberately not exposing characters like <,.-#* because they vary *wildly*
// across keyboard layouts and may cause various problems
// (e.g. "*" is "Shift +" on a German Mac keyboard)
// (e.g. "@" is "Alt L" on a German Mac keyboard)

export default {
const keycode = {
// Element Focus
tab: 9,

Expand All @@ -11,7 +15,9 @@ export default {
right: 39,
down: 40,
pageUp: 33,
'page-up': 33,
pageDown: 34,
'page-down': 34,
end: 35,
home: 36,

Expand All @@ -23,27 +29,47 @@ export default {
// Modifier
shift: 16,
capsLock: 20,
'caps-lock': 20,
ctrl: 17,
alt: 18,
command: 224,
meta: 91,
// in firefox: 224
// on mac (chrome): meta-left=91, meta-right=93
// on win (IE11): meta-left=91, meta-right=92
pause: 19,

// Content Manipulation
insert: 45,
'delete': 46,
backspace: 8,

// Special Function
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
// the same logical key may be identified through different keyCodes
_alias: {
91: [92, 93, 224],
},
};

// Function keys (112 - 137)
// NOTE: not every keyboard knows F13+
for (let n = 1; n < 26; n++) {
keycode['f' + n] = n + 111;
}

// Number keys (48-57, numpad 96-105)
// NOTE: not every keyboard knows num-0+
for (let n = 0; n < 10; n++) {
const code = n + 48;
const numCode = n + 96;
keycode[n] = code;
keycode['num-' + n] = numCode;
keycode._alias[code] = [numCode];
}

// Latin characters (65 - 90)
for (let n = 0; n < 26; n++) {
const code = n + 65;
const name = String.fromCharCode(code).toLowerCase();
keycode[name] = code;
}

export default keycode;
10 changes: 5 additions & 5 deletions src/when/key.binding.js
Expand Up @@ -4,8 +4,8 @@
returns an array of objects:
{
// translated key name
keyCode: <number>,
// key name translated to keyCode (possibly more than one)
keyCodes: [<number>],
// translated modifiers
modifiers: {
altKey: null, // ignore
Expand Down Expand Up @@ -83,7 +83,7 @@ function resolveKey(key) {
throw new TypeError('Unknown key "' + key + '"');
}

return code;
return [code].concat(keycode._alias[code] || []);
}

function matchModifiers(expected, event) {
Expand All @@ -98,9 +98,9 @@ export default function(text) {
return text.split(/\s+/).map(function(_text) {
const tokens = _text.split('+');
const _modifiers = resolveModifiers(tokens.slice(0, -1));
const _key = resolveKey(tokens.slice(-1));
const _keyCodes = resolveKey(tokens.slice(-1));
return {
keyCode: _key,
keyCodes: _keyCodes,
modifiers: _modifiers,
matchModifiers: matchModifiers.bind(null, _modifiers),
};
Expand Down
10 changes: 6 additions & 4 deletions src/when/key.js
Expand Up @@ -14,11 +14,13 @@ export default function(map = {}) {
}

const registerBinding = function(event) {
if (!bindings[event.keyCode]) {
bindings[event.keyCode] = [];
}
event.keyCodes.forEach(function(code) {
if (!bindings[code]) {
bindings[code] = [];
}

bindings[event.keyCode].push(event);
bindings[code].push(event);
});
};

mapKeys.forEach(function(text) {
Expand Down
24 changes: 16 additions & 8 deletions test/unit/when.key.test.js
Expand Up @@ -239,7 +239,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13, 'keyCode');
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(false, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(false, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(false, 'meta modifier');
Expand All @@ -250,7 +250,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(false, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(false, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(false, 'meta modifier');
Expand All @@ -261,7 +261,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(null, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(null, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(null, 'meta modifier');
Expand All @@ -272,7 +272,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(null, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(null, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(null, 'meta modifier');
Expand All @@ -283,7 +283,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(null, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(false, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(null, 'meta modifier');
Expand All @@ -294,7 +294,7 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(1);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(false, 'alt modifier');
expect(events[0].modifiers.ctrlKey).to.equal(false, 'ctrl modifier');
expect(events[0].modifiers.metaKey).to.equal(null, 'meta modifier');
Expand All @@ -305,18 +305,26 @@ define([
expect(events).to.be.a('array');
expect(events.length).to.equal(2);

expect(events[0].keyCode).to.equal(13);
expect(events[0].keyCodes.join(',')).to.equal('13', 'keyCode');
expect(events[0].modifiers.altKey).to.equal(false, 'alt modifier for enter');
expect(events[0].modifiers.ctrlKey).to.equal(false, 'ctrl modifier for enter');
expect(events[0].modifiers.metaKey).to.equal(null, 'meta modifier for enter');
expect(events[0].modifiers.shiftKey).to.equal(false, 'shift modifier for enter');

expect(events[1].keyCode).to.equal(32);
expect(events[1].keyCodes.join(',')).to.equal('32', 'keyCode');
expect(events[1].modifiers.altKey).to.equal(false, 'alt modifier for space');
expect(events[1].modifiers.ctrlKey).to.equal(false, 'ctrl modifier for space');
expect(events[1].modifiers.metaKey).to.equal(false, 'meta modifier for space');
expect(events[1].modifiers.shiftKey).to.equal(true, 'shift modifier for space');
},
'parse token with aliased codes': function() {
var events = keyBinding('0 meta');
expect(events).to.be.a('array');
expect(events.length).to.equal(2);

expect(events[0].keyCodes.join(',')).to.equal('48,96', 'keyCode');
expect(events[1].keyCodes.join(',')).to.equal('91,92,93,224', 'keyCode');
},
};
});
});

0 comments on commit 28e91fb

Please sign in to comment.