Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

Commit

Permalink
Turn keyboard into true polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
inexorabletash committed Jan 23, 2014
1 parent adf23a5 commit 007919d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 68 deletions.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,26 +191,23 @@ URL objects have properties:
* `href`


W3C Keyboard Events (helper)
W3C Keyboard Events (polyfill)
----------------------------
[script](keyboard.js) -
[demo page](http://calormen.com/polyfill/demos/keyboard.html) -
[draft spec](https://dvcs.w3.org/hg/d4e/raw-file/tip/source_respec.htm#keyboard-events)

```javascript
// In your keydown/keyup handler, call:
window.identifyKey(keyboardEvent);

// Or listen during the capture phase (IE9+):
window.addEventListener('keydown', identifyKey, true);
window.addEventListener('keyup', identifyKey, true);

// This adds the following properties to each KeyboardEvent:
// Adds the following properties to each KeyboardEvent:
event.code
event.location

// You can get a label for the key using:
KeyboardEvent.queryKeyCap(code);

// IE7- only: In your keydown/keyup handler, call this in your handler
// before accessing the `code` or `location` properties:
window.identifyKey(keyboardEvent);
```

W3C Web Storage
Expand Down
8 changes: 2 additions & 6 deletions demos/keyboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
<meta charset="UTF-8">

<script type="text/javascript" src="../polyfill.js"></script>
<script>
var IDENTIFY_KEY_ASSIGN_KEY_IDENTIFIER = true;
var IDENTIFY_KEY_ASSIGN_KEY_LOCATION = true;
</script>
<script type="text/javascript" src="../harmony.js"></script>
<script type="text/javascript" src="../keyboard.js"></script>

<style>
Expand Down Expand Up @@ -222,8 +219,7 @@
<style>
.event { border: 1px solid black; margin: 10px; padding: 4px; }
</style>
<pre class="event">Raw Event:<br><span id="eventdata"></span></pre>
<pre class="event">Augmented Event:<br><span id="identifydata"></span></pre>
<pre class="event">Event:<br><span id="eventdata"></span></pre>

<script src="keyboard_test.js"></script>

Expand Down
32 changes: 9 additions & 23 deletions demos/keyboard_test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

function contains(s, ss) { return s.indexOf(ss) != -1; }
if (contains(navigator.platform, 'Win'))
getClassList(document.body).add('os-win');
document.body.classList.add('os-win');
if (contains(navigator.platform, 'Mac'))
getClassList(document.body).add('os-mac');
document.body.classList.add('os-mac');
if (contains(navigator.userAgent, 'CrOS'))
getClassList(document.body).add('os-cros');
document.body.classList.add('os-cros');

function select(event) {
var id = event.code;
Expand All @@ -14,14 +14,6 @@ function select(event) {

// Can't override |location| on KeyboardEvent in some browsers, so it
// may be wrong, e.g. NumLock in moz-mac

/*
if (event.keyLocation === KeyboardEvent.DOM_KEY_LOCATION_NUMPAD) {
return [].slice.call(document.querySelectorAll('.numpad .' + id));
} else {
return [].slice.call(document.querySelectorAll('.standard .' + id));
}
*/
}

var target = document.getElementById('target');
Expand All @@ -39,25 +31,23 @@ var lastKey = -1;

// Workaround for Opera which doesn't allow cancelling Tab, IE/Apps
target.addEventListener('blur', function (e) {
if (lastKey === 0x09 || lastKey === 0x5D) {
if (lastKey === 0x09 || lastKey === 0x5D)
target.focus();
}
lastKey = -1;
});

function hex(x, w) {
x = Number(x);
if (!w) { w = 2; }
var pad = new Array(w+1).join('0');
return '0x' + (pad + x.toString(16)).slice(-w);
w = Number(w) || 2;
return '0x' + ('0'.repeat(w) + x.toString(16)).slice(-w);
}

function show(selector, e) {
var elem = document.querySelector(selector),
data = {
code: e.code,
location: e.location,
cap: e.queryKeyCap ? e.queryKeyCap(e.code) : undefined,
cap: KeyboardEvent.queryKeyCap(e.code),
key: e.key,
char: e.char,
keyChar: e.keyChar,
Expand All @@ -73,9 +63,9 @@ function show(selector, e) {
shiftKey: e.shiftKey
};

while (elem.hasChildNodes()) {
while (elem.hasChildNodes())
elem.removeChild(elem.firstChild);
}

var s = Object.keys(data).filter(function(k){
return typeof data[k] !== 'undefined';
}).map(function(k){
Expand All @@ -88,8 +78,6 @@ target.addEventListener('keydown', function (e) {
lastKey = e.keyCode;

show('#eventdata', e);
identifyKey(e);
show('#identifydata', e);

select(e).forEach(
function (elem) {
Expand All @@ -105,8 +93,6 @@ target.addEventListener('keyup', function (e) {
if (lastKey == e.keyCode) { lastKey = -1; }

show('#eventdata', e);
identifyKey(e);
show('#identifydata', e);

select(e).forEach(
function (elem) {
Expand Down
78 changes: 48 additions & 30 deletions keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ window.KeyboardEvent.DOM_KEY_LOCATION_LEFT = 0x01; // e.g. Left Alt key
window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 0x02; // e.g. Right Alt key
window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 0x03; // e.g. Numpad 0 or +

// Optionally set these to true for properties from older proposals.
var IDENTIFY_KEY_ASSIGN_KEY_IDENTIFIER;
var IDENTIFY_KEY_ASSIGN_KEY_LOCATION;

(function(global) {

var STANDARD = window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
Expand Down Expand Up @@ -650,12 +646,8 @@ var IDENTIFY_KEY_ASSIGN_KEY_LOCATION;


var codeTable = remap(keyCodeToInfoTable, 'code');
global.identifyKey = function(event) {

if ('code' in event) {
return;
}

function keyInfoForEvent(event) {
var keyCode = 'keyCode' in event ? event.keyCode : 'which' in event ? event.which : 0;

var keyInfo = (function(){
Expand Down Expand Up @@ -687,31 +679,57 @@ var IDENTIFY_KEY_ASSIGN_KEY_LOCATION;
case 'U+001F': keyInfo = { code: 'ArrowDown' }; break;
}
}
return keyInfo;
}

if (!keyInfo)
return;
function queryKeyCap(code, locale) {
code = String(code);
if (!codeTable.hasOwnProperty(code)) return 'Undefined';
if (locale && String(locale).toLowerCase() !== 'en-us') throw Error('Unsupported locale');
var keyInfo = codeTable[code];
return keyInfo.keyCap || keyInfo.code || 'Undefined';
}

// Current version of the spec:
event.code = event.code || keyInfo.code || '';
event.location = ('location' in event) ? event.location :
('keyLocation' in event) ? event.keyLocation :
('location' in keyInfo) ? keyInfo.location : STANDARD;
event.queryKeyCap = event.queryKeyCap || function(code, locale) {
code = String(code);
if (!codeTable.hasOwnProperty(code)) {
return 'Undefined';
}
if (locale && String(locale).toLowerCase() !== 'en-us') {
throw Error('Unsupported locale');
if ('KeyboardEvent' in global && 'defineProperty' in Object) {
(function() {
function define(o, p, v) {
if (p in o) return;
Object.defineProperty(o, p, v);
}

var keyInfo = codeTable[code];
return keyInfo.keyCap || keyInfo.code || 'Undefined';
};
define(KeyboardEvent.prototype, 'code', { get: function() {
var keyInfo = keyInfoForEvent(this);
return (keyInfo && 'code' in keyInfo) ? keyInfo.code : '';
}});

define(KeyboardEvent.prototype, 'location', { get: function() {
var keyInfo = keyInfoForEvent(this);
return (keyInfo && 'location' in keyInfo) ? keyInfo.location : STANDARD;
}});

if (IDENTIFY_KEY_ASSIGN_KEY_IDENTIFIER)
event.keyIdentifier = event.keyIdentifier || event.code;
if (IDENTIFY_KEY_ASSIGN_KEY_LOCATION)
event.keyLocation = event.location;
define(KeyboardEvent.prototype, 'locale', { get: function() {
return 'en-US';
}});

define(KeyboardEvent, 'queryKeyCap', { value: queryKeyCap });
}());

} else {
// Shim for IE7-
global.KeyboardEvent = { queryKeyCap: queryKeyCap };
}

// Helper for IE7-
global.identifyKey = function(event) {
if ('code' in event)
return;

var keyInfo = keyInfoForEvent(event);
event.code = (keyInfo && 'code' in keyInfo) ? keyInfo.code : '';
event.location = ('location' in event) ? event.location :
('keyLocation' in event) ? event.keyLocation :
(keyInfo && 'location' in keyInfo) ? keyInfo.location : STANDARD;
event.locale = 'en-US';
};

} (window));

0 comments on commit 007919d

Please sign in to comment.