mirror of
https://github.com/wahyd4/cdnjs.git
synced 2026-08-13 23:06:20 +10:00
@@ -0,0 +1,316 @@
|
||||
// keymage.js - Javascript keyboard event handling
|
||||
// http://github.com/piranha/keymage
|
||||
//
|
||||
// (c) 2012 Alexander Solovyov
|
||||
// under terms of ISC License
|
||||
|
||||
(function(define, undefined) {
|
||||
define(function() {
|
||||
var VERSION = '1.0.1';
|
||||
|
||||
// Defining all keys
|
||||
var MODPROPS = ['shiftKey', 'ctrlKey', 'altKey', 'metaKey'];
|
||||
var MODS = {
|
||||
'shift': 'shift',
|
||||
'ctrl': 'ctrl', 'control': 'ctrl',
|
||||
'alt': 'alt', 'option': 'alt',
|
||||
'win': 'meta', 'cmd': 'meta', 'super': 'meta',
|
||||
'meta': 'meta',
|
||||
// default modifier for os x is cmd and for others is ctrl
|
||||
'defmod': ~navigator.userAgent.indexOf('Mac OS X') ?
|
||||
'meta' : 'ctrl'
|
||||
};
|
||||
var MODORDER = ['shift', 'ctrl', 'alt', 'meta'];
|
||||
var MODNUMS = [16, 17, 18, 91];
|
||||
|
||||
var KEYS = {
|
||||
'backspace': 8,
|
||||
'tab': 9,
|
||||
'enter': 13, 'return': 13,
|
||||
'pause': 19,
|
||||
'caps': 20, 'capslock': 20,
|
||||
'escape': 27, 'esc': 27,
|
||||
'space': 32,
|
||||
'pgup': 33, 'pageup': 33,
|
||||
'pgdown': 34, 'pagedown': 34,
|
||||
'end': 35,
|
||||
'home': 36,
|
||||
'ins': 45, 'insert': 45,
|
||||
'del': 46, 'delete': 46,
|
||||
|
||||
'left': 37,
|
||||
'up': 38,
|
||||
'right': 39,
|
||||
'down': 40,
|
||||
|
||||
'*': 106,
|
||||
'+': 107, 'plus': 107,
|
||||
'-': 109, 'minus': 109,
|
||||
';': 186,
|
||||
'=': 187,
|
||||
',': 188,
|
||||
'.': 190,
|
||||
'/': 191,
|
||||
'`': 192,
|
||||
'[': 219,
|
||||
'\\': 220,
|
||||
']': 221,
|
||||
"'": 222
|
||||
};
|
||||
|
||||
var i;
|
||||
// numpad
|
||||
for (i = 0; i < 10; i++) {
|
||||
KEYS['num-' + i] = i + 95;
|
||||
}
|
||||
// top row 0-9
|
||||
for (i = 0; i < 10; i++) {
|
||||
KEYS[i.toString()] = i + 48;
|
||||
}
|
||||
// f1-f24
|
||||
for (i = 1; i < 25; i++) {
|
||||
KEYS['f' + i] = i + 111;
|
||||
}
|
||||
// alphabet
|
||||
for (i = 65; i < 91; i++) {
|
||||
KEYS[String.fromCharCode(i).toLowerCase()] = i;
|
||||
}
|
||||
|
||||
// Reverse key codes
|
||||
var KEYREV = {};
|
||||
for (var k in KEYS) {
|
||||
var val = KEYS[k];
|
||||
if (!KEYREV[val] || KEYREV[val].length < k.length) {
|
||||
KEYREV[val] = k;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------
|
||||
// Actual work is done here
|
||||
|
||||
var currentScope = '';
|
||||
var allChains = {};
|
||||
|
||||
function parseKeyString(keystring) {
|
||||
var bits = keystring.split('-');
|
||||
var button = bits[bits.length - 1];
|
||||
var key = {code: KEYS[button]};
|
||||
|
||||
if (!key.code) {
|
||||
throw 'Unknown key "' + button + '" in keystring "' +
|
||||
keystring + '"';
|
||||
}
|
||||
|
||||
var mod;
|
||||
for (var i = 0; i < bits.length - 1; i++) {
|
||||
button = bits[i];
|
||||
mod = MODS[button];
|
||||
if (!mod) {
|
||||
throw 'Unknown modifier "' + button + '" in keystring "' +
|
||||
keystring + '"';
|
||||
}
|
||||
key[mod] = true;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
function stringifyKey(key) {
|
||||
var s = '';
|
||||
for (var i = 0; i < MODORDER.length; i++) {
|
||||
if (key[MODORDER[i]]) {
|
||||
s += MODORDER[i] + '-';
|
||||
}
|
||||
}
|
||||
s += KEYREV[key.code];
|
||||
return s;
|
||||
}
|
||||
|
||||
function normalizeKeyChain(keychainString) {
|
||||
var keychain = [];
|
||||
var keys = keychainString.split(' ');
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = parseKeyString(keys[i]);
|
||||
key = stringifyKey(key);
|
||||
keychain.push(key);
|
||||
}
|
||||
|
||||
keychain.original = keychainString;
|
||||
return keychain;
|
||||
}
|
||||
|
||||
function eventKeyString(e) {
|
||||
var key = {code: e.keyCode};
|
||||
for (var i = 0; i < MODPROPS.length; i++) {
|
||||
var mod = MODPROPS[i];
|
||||
if (e[mod]) {
|
||||
key[mod.slice(0, mod.length - 3)] = true;
|
||||
}
|
||||
}
|
||||
return stringifyKey(key);
|
||||
}
|
||||
|
||||
function getNestedChains(chains, scope) {
|
||||
for (var i = 0; i < scope.length; i++) {
|
||||
var bit = scope[i];
|
||||
|
||||
if (bit) {
|
||||
chains = chains[bit];
|
||||
}
|
||||
|
||||
if (!chains) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return chains;
|
||||
}
|
||||
|
||||
var sequence = [];
|
||||
function dispatch(e) {
|
||||
// Skip all modifiers
|
||||
if (~MODNUMS.indexOf(e.keyCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var seq = sequence.slice();
|
||||
seq.push(eventKeyString(e));
|
||||
var scope = currentScope.split('.');
|
||||
var matched, chains, key;
|
||||
|
||||
for (var i = scope.length; i >= 0; i--) {
|
||||
chains = getNestedChains(allChains, scope.slice(0, i));
|
||||
if (!chains) {
|
||||
continue;
|
||||
}
|
||||
matched = true;
|
||||
for (var j = 0; j < seq.length; j++) {
|
||||
key = seq[j];
|
||||
if (!chains[key]) {
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
chains = chains[key];
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var definitionScope = scope.slice(0, i).join('.');
|
||||
var preventDefault = chains.preventDefault;
|
||||
|
||||
// partial match, save the sequence
|
||||
if (matched && !chains.handlers) {
|
||||
sequence = seq;
|
||||
if (preventDefault) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
for (i = 0; i < chains.handlers.length; i++) {
|
||||
var handler = chains.handlers[i];
|
||||
var options = handler._keymage;
|
||||
|
||||
var res = handler.call(options.context, e, {
|
||||
shortcut: options.original,
|
||||
scope: currentScope,
|
||||
definitionScope: definitionScope
|
||||
});
|
||||
|
||||
if (res === false || preventDefault) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// either matched or not, drop the sequence
|
||||
sequence = [];
|
||||
}
|
||||
|
||||
function assignKey(scope, keychain, fn) {
|
||||
var bits = scope.split('.');
|
||||
var chains = allChains;
|
||||
|
||||
bits = bits.concat(keychain);
|
||||
|
||||
for (var i = 0, l = bits.length; i < l; i++) {
|
||||
var bit = bits[i];
|
||||
if (!bit) continue;
|
||||
|
||||
chains = chains[bit] || (chains[bit] = {});
|
||||
if (fn._keymage.preventDefault) {
|
||||
chains.preventDefault = true;
|
||||
}
|
||||
|
||||
if (i === l - 1) {
|
||||
var handlers = chains.handlers || (chains.handlers = []);
|
||||
handlers.push(fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// optional arguments: scope, options.
|
||||
function keymage(scope, keychain, fn, options) {
|
||||
if (keychain === undefined && fn === undefined) {
|
||||
return function(keychain, fn) {
|
||||
return keymage(scope, keychain, fn);
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof keychain === 'function') {
|
||||
options = fn;
|
||||
fn = keychain;
|
||||
keychain = scope;
|
||||
scope = '';
|
||||
}
|
||||
|
||||
var normalized = normalizeKeyChain(keychain);
|
||||
fn._keymage = options || {};
|
||||
fn._keymage.original = keychain;
|
||||
assignKey(scope, normalized, fn);
|
||||
}
|
||||
|
||||
keymage.parse = parseKeyString;
|
||||
keymage.stringify = stringifyKey;
|
||||
|
||||
keymage.bindings = allChains;
|
||||
|
||||
keymage.setScope = function(scope) {
|
||||
currentScope = scope ? scope : '';
|
||||
};
|
||||
|
||||
keymage.getScope = function() { return currentScope; };
|
||||
|
||||
keymage.pushScope = function(scope) {
|
||||
currentScope = (currentScope ? currentScope + '.' : '') + scope;
|
||||
return currentScope;
|
||||
};
|
||||
|
||||
keymage.popScope = function(scope) {
|
||||
var i;
|
||||
|
||||
if (!scope) {
|
||||
i = currentScope.lastIndexOf('.');
|
||||
scope = currentScope.slice(i + 1);
|
||||
currentScope = i == -1 ? '' : currentScope.slice(0, i);
|
||||
return scope;
|
||||
}
|
||||
|
||||
currentScope = currentScope.replace(
|
||||
new RegExp('(^|\\.)' + scope + '(\\.|$).*'), '');
|
||||
return scope;
|
||||
};
|
||||
|
||||
keymage.version = VERSION;
|
||||
|
||||
window.addEventListener('keydown', dispatch, false);
|
||||
|
||||
return keymage;
|
||||
});
|
||||
})(typeof define !== 'undefined' ? define : function(factory) {
|
||||
window.keymage = factory();
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// keymage.js - Javascript keyboard event handling
|
||||
// http://github.com/piranha/keymage
|
||||
//
|
||||
// (c) 2012 Alexander Solovyov
|
||||
// under terms of ISC License
|
||||
(function(a,b){a(function(){function n(a){var b=a.split("-"),c=b[b.length-1],e={code:g[c]};if(!e.code)throw'Unknown key "'+c+'" in keystring "'+a+'"';var f;for(var h=0;h<b.length-1;h++){c=b[h],f=d[c];if(!f)throw'Unknown modifier "'+c+'" in keystring "'+a+'"';e[f]=!0}return e}function o(a){var b="";for(var c=0;c<e.length;c++)a[e[c]]&&(b+=e[c]+"-");return b+=i[a.code],b}function p(a){var b=[],c=a.split(" ");for(var d=0;d<c.length;d++){var e=n(c[d]);e=o(e),b.push(e)}return b.original=a,b}function q(a){var b={code:a.keyCode};for(var d=0;d<c.length;d++){var e=c[d];a[e]&&(b[e.slice(0,e.length-3)]=!0)}return o(b)}function r(a,b){for(var c=0;c<b.length;c++){var d=b[c];d&&(a=a[d]);if(!a)break}return a}function t(a){if(~f.indexOf(a.keyCode))return;var b=s.slice();b.push(q(a));var c=l.split("."),d,e,g;for(var h=c.length;h>=0;h--){e=r(m,c.slice(0,h));if(!e)continue;d=!0;for(var i=0;i<b.length;i++){g=b[i];if(!e[g]){d=!1;break}e=e[g]}if(d)break}var j=c.slice(0,h).join("."),k=e.preventDefault;if(d&&!e.handlers){s=b,k&&a.preventDefault();return}if(d)for(h=0;h<e.handlers.length;h++){var n=e.handlers[h],o=n._keymage,p=n.call(o.context,a,{shortcut:o.original,scope:l,definitionScope:j});(p===!1||k)&&a.preventDefault()}s=[]}function u(a,b,c){var d=a.split("."),e=m;d=d.concat(b);for(var f=0,g=d.length;f<g;f++){var h=d[f];if(!h)continue;e=e[h]||(e[h]={}),c._keymage.preventDefault&&(e.preventDefault=!0);if(f===g-1){var i=e.handlers||(e.handlers=[]);i.push(c)}}}function v(a,c,d,e){if(c===b&&d===b)return function(b,c){return v(a,b,c)};typeof c=="function"&&(e=d,d=c,c=a,a="");var f=p(c);d._keymage=e||{},d._keymage.original=c,u(a,f,d)}var a="1.0.1",c=["shiftKey","ctrlKey","altKey","metaKey"],d={shift:"shift",ctrl:"ctrl",control:"ctrl",alt:"alt",option:"alt",win:"meta",cmd:"meta","super":"meta",meta:"meta",defmod:~navigator.userAgent.indexOf("Mac OS X")?"meta":"ctrl"},e=["shift","ctrl","alt","meta"],f=[16,17,18,91],g={backspace:8,tab:9,enter:13,"return":13,pause:19,caps:20,capslock:20,escape:27,esc:27,space:32,pgup:33,pageup:33,pgdown:34,pagedown:34,end:35,home:36,ins:45,insert:45,del:46,"delete":46,left:37,up:38,right:39,down:40,"*":106,"+":107,plus:107,"-":109,minus:109,";":186,"=":187,",":188,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222},h;for(h=0;h<10;h++)g["num-"+h]=h+95;for(h=0;h<10;h++)g[h.toString()]=h+48;for(h=1;h<25;h++)g["f"+h]=h+111;for(h=65;h<91;h++)g[String.fromCharCode(h).toLowerCase()]=h;var i={};for(var j in g){var k=g[j];if(!i[k]||i[k].length<j.length)i[k]=j}var l="",m={},s=[];return v.parse=n,v.stringify=o,v.bindings=m,v.setScope=function(a){l=a?a:""},v.getScope=function(){return l},v.pushScope=function(a){return l=(l?l+".":"")+a,l},v.popScope=function(a){var b;return a?(l=l.replace(new RegExp("(^|\\.)"+a+"(\\.|$).*"),""),a):(b=l.lastIndexOf("."),a=l.slice(b+1),l=b==-1?"":l.slice(0,b),a)},v.version=a,window.addEventListener("keydown",t,!1),v})})(typeof define!="undefined"?define:function(a){window.keymage=a()});
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "keymage",
|
||||
"filename": "keymage.min.js",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "Yet Another JS Keybinding library",
|
||||
"homepage": "https://github.com/piranha/keymage",
|
||||
"keywords": [
|
||||
|
||||
Reference in New Issue
Block a user