diff --git a/keymaster.js b/keymaster.js index ee85d32..625f9c5 100644 --- a/keymaster.js +++ b/keymaster.js @@ -125,9 +125,40 @@ for(k in _MODIFIERS) assignKey[k] = false; } - // parse and assign shortcut - function assignKey(key, scope, method){ - var keys, mods, i, mi; + function storeKey(keyCode, key, mods, scope, method) { + if (!(keyCode in _handlers)) _handlers[keyCode] = []; + _handlers[keyCode].push({ shortcut: key, scope: scope, method: method, key: key, mods: mods }); + } + + function createKeyEvent(keyCode, mods, view, type) { + var i; + var keyboardEvent = document.createEventObject ? document.createEventObject() : document.createEvent("Events"); + keyboardEvent.initEvent(type, true, true); + keyboardEvent.view = view; + keyboardEvent.keyCode = keyCode; + keyboardEvent.which = keyCode; + + for(i = 0; i < mods.length; i++) { + keyboardEvent[modifierMap[mods[i]]] = true; + } + + return keyboardEvent; + } + + function dispatchKey(keyCode, key, mods, view, element) { + var keyboardEvent; + view = view === 'all' ? window : view; + keyboardEvent = createKeyEvent(keyCode, mods, view, 'keydown'); + element.dispatchEvent(keyboardEvent); + keyboardEvent = createKeyEvent(keyCode, mods, view, 'keypress'); + element.dispatchEvent(keyboardEvent); + keyboardEvent = createKeyEvent(keyCode, mods, view, 'keyup'); + element.dispatchEvent(keyboardEvent); + } + + // parse and assign shortcut or dispatch keyEvent + function assignKey(key, scope, method) { + var keys, mods, i, mi, keyCode; if (method === undefined) { method = scope; scope = 'all'; @@ -148,13 +179,12 @@ mods[mi] = _MODIFIERS[mods[mi]]; key = [key[key.length-1]]; } - // convert to keycode and... - key = key[0] - key = code(key); - // ...store handler - if (!(key in _handlers)) _handlers[key] = []; - _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods }); - } + keyCode = code(key[0]); + if (typeof method === 'function') // ...store handler + storeKey(keyCode, keys[i], mods, scope, method); + else // ... dispatch event + dispatchKey(keyCode, keys[i], mods, scope, method); + } }; // Returns true if the key with code 'keyCode' is currently down diff --git a/selftest.html b/selftest.html new file mode 100644 index 0000000..ea2b8a6 --- /dev/null +++ b/selftest.html @@ -0,0 +1,137 @@ + + + The Keymaster + + + + + +

+ The Keymaster Self Test. +

+ + + + + +

The Self Test simulated the first five items on this manual test list:

+
    +
  1. Press 'c'. Nothing should be logged on console.
  2. +
  3. Press 'o' or Enter or Cursor ←. Console should log function call.
  4. +
  5. Press 'i'. Switches scope to 'issues'.
  6. +
  7. Press 'c'. Console should log function call.
  8. +
  9. Press 'o' or Enter or Cursor ←. Console should log function call.
  10. +
  11. Press and hold 'm'. Console should log a message every second.
  12. +
  13. Every second console should log a message listing all the currently pressed keycodes.
  14. +
+ +

+ At any time, try pressing ⌘+right, shift+left or ctrl+shift+alt+d. +

+ +

+ When a input, a select or a textarea element is focused, key inputs should be ignored. +

+ + + +