Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #33 from dominictarr/keymaster

---

Ive moved the test for INPUT, SELECT and TEXTAREA into a property of `key`,
`key.prekeydown`

if the function assigned to `prekeydown` returns `false`, then keymaster ignores the key press.

you can also change scope in this function, so you can have a scope the shortcuts that work inside an input.

one quirk is that keys in the all scope still work when youve changed the scope.
so, if you want shortcuts that do not apply inside an input, you need to assign them to a particular scope.

Conflicts:
	keymaster.min.js
  • Loading branch information...
commit aed2b809d83efcd2897367be1f9985c21f949e4d 2 parents f2c1db0 + a7c27ef
@madrobby authored
View
11 README.markdown
@@ -83,10 +83,15 @@ key('o, enter', 'files', function(){ /* do something else */ });
key.setScope('issues'); // default scope is 'all'
```
-## Notes
+## Veto keypresses
+
+By default, when in an `INPUT`, `SELECT` or `TEXTAREA` element is focused, Keymaster doesn't process any shortcuts.
+
+You can change this by overwriting `key.prekeydown` with a new function.
-When an `INPUT`, `SELECT` or `TEXTAREA` element is focused, Keymaster
-doesn't process shortcuts.
+If your function returns false, then the no shortcuts will be processed. If you only want _some_ shortcuts to work while in a input element, you can change the scope in the key.prekeydown funtcion
+
+## Notes
Keymaster should work with any browser that fires `keyup` and `keydown` events,
and is tested with IE (6+), Safari, Firefox and Chrome.
View
17 keymaster.js
@@ -41,8 +41,7 @@
// handle keydown event
function dispatch(event){
- var key, tagName, handler, k, i, modifiersMatch;
- tagName = (event.target || event.srcElement).tagName;
+ var key, handler, k, i, modifiersMatch;
key = event.keyCode;
// if a modifier key, set the key.<modifierkeyname> property to true and return
@@ -54,8 +53,9 @@
return;
}
- // ignore keypressed in any elements that support keyboard data input
- if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') return;
+ // see if we need to ignore the keypress (ftiler() can can be overridden)
+ // by default ignore key presses if a select, textarea, or input is focused
+ if(!assignKey.filter.call(this, event)) return;
// abort if no potentially matching shortcuts found
if (!(key in _handlers)) return;
@@ -131,6 +131,12 @@
}
};
+ function filter(event){
+ var tagName = (event.target || event.srcElement).tagName;
+ // ignore keypressed in any elements that support keyboard data input
+ return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
+ }
+
// initialize key.<modifier> to false
for(k in _MODIFIERS) assignKey[k] = false;
@@ -166,11 +172,12 @@
// reset modifiers to false whenever the window is (re)focused.
addEvent(window, 'focus', resetModifiers);
- // set window.key and window.key.setScope
+ // set window.key and window.key.set/get/deleteScope, and the default filter
global.key = assignKey;
global.key.setScope = setScope;
global.key.getScope = getScope;
global.key.deleteScope = deleteScope;
+ global.key.filter = filter;
if(typeof module !== 'undefined') module.exports = key;
View
2  keymaster.min.js
@@ -1,4 +1,4 @@
// keymaster.js
// (c) 2011 Thomas Fuchs
// keymaster.js may be freely distributed under the MIT license.
-(function(a){function h(a,b){var c=a.length;while(c--)if(a[c]===b)return c;return-1}function i(a){var b,g,i,j,k,m;g=(a.target||a.srcElement).tagName,b=a.keyCode;if(b==93||b==224)b=91;if(b in d){d[b]=!0;for(j in f)f[j]==b&&(l[j]=!0);return}if(g=="INPUT"||g=="SELECT"||g=="TEXTAREA")return;if(!(b in c))return;for(k=0;k<c[b].length;k++){i=c[b][k];if(i.scope==e||i.scope=="all"){m=i.mods.length>0;for(j in d)if(!d[j]&&h(i.mods,+j)>-1||d[j]&&h(i.mods,+j)==-1)m=!1;(i.mods.length==0&&!d[16]&&!d[18]&&!d[17]&&!d[91]||m)&&i.method(a,i)===!1&&(a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation&&a.stopPropagation(),a.cancelBubble&&(a.cancelBubble=!0))}}}function j(a){var b=a.keyCode,c;if(b==93||b==224)b=91;if(b in d){d[b]=!1;for(c in f)f[c]==b&&(l[c]=!1)}}function k(){for(b in d)d[b]=!1;for(b in f)l[b]=!1}function l(a,b,d){var e,h,i,j;d===undefined&&(d=b,b="all"),a=a.replace(/\s/g,""),e=a.split(","),e[e.length-1]==""&&(e[e.length-2]+=",");for(i=0;i<e.length;i++){h=[],a=e[i].split("+");if(a.length>1){h=a.slice(0,a.length-1);for(j=0;j<h.length;j++)h[j]=f[h[j]];a=[a[a.length-1]]}a=a[0],a=g[a]||a.toUpperCase().charCodeAt(0),a in c||(c[a]=[]),c[a].push({shortcut:e[i],scope:b,method:d,key:e[i],mods:h})}}function m(a){e=a||"all"}function n(){return e||"all"}function o(a){var b,d,e;for(b in c){d=c[b];for(e=0;e<d.length;)d[e].scope===a?d.splice(e,1):e++}}function p(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,function(){c(window.event)})}var b,c={},d={16:!1,18:!1,17:!1,91:!1},e="all",f={"⇧":16,shift:16,"⌥":18,alt:18,option:18,"⌃":17,ctrl:17,control:17,"⌘":91,command:91},g={backspace:8,tab:9,clear:12,enter:13,"return":13,esc:27,escape:27,space:32,left:37,up:38,right:39,down:40,del:46,"delete":46,home:36,end:35,pageup:33,pagedown:34,",":188,".":190,"/":191,"`":192,"-":189,"=":187,";":186,"'":222,"[":219,"]":221,"\\":220};for(b=1;b<20;b++)f["f"+b]=111+b;for(b in f)l[b]=!1;p(document,"keydown",i),p(document,"keyup",j),p(window,"focus",k),a.key=l,a.key.setScope=m,a.key.getScope=n,a.key.deleteScope=o,typeof module!="undefined"&&(module.exports=key)})(this);
+(function(a){function h(a,b){var c=a.length;while(c--)if(a[c]===b)return c;return-1}function i(a){var b,g,i,j,k;b=a.keyCode;if(b==93||b==224)b=91;if(b in d){d[b]=!0;for(i in f)f[i]==b&&(l[i]=!0);return}if(!l.filter.call(this,a))return;if(!(b in c))return;for(j=0;j<c[b].length;j++){g=c[b][j];if(g.scope==e||g.scope=="all"){k=g.mods.length>0;for(i in d)if(!d[i]&&h(g.mods,+i)>-1||d[i]&&h(g.mods,+i)==-1)k=!1;(g.mods.length==0&&!d[16]&&!d[18]&&!d[17]&&!d[91]||k)&&g.method(a,g)===!1&&(a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation&&a.stopPropagation(),a.cancelBubble&&(a.cancelBubble=!0))}}}function j(a){var b=a.keyCode,c;if(b==93||b==224)b=91;if(b in d){d[b]=!1;for(c in f)f[c]==b&&(l[c]=!1)}}function k(){for(b in d)d[b]=!1;for(b in f)l[b]=!1}function l(a,b,d){var e,h,i,j;d===undefined&&(d=b,b="all"),a=a.replace(/\s/g,""),e=a.split(","),e[e.length-1]==""&&(e[e.length-2]+=",");for(i=0;i<e.length;i++){h=[],a=e[i].split("+");if(a.length>1){h=a.slice(0,a.length-1);for(j=0;j<h.length;j++)h[j]=f[h[j]];a=[a[a.length-1]]}a=a[0],a=g[a]||a.toUpperCase().charCodeAt(0),a in c||(c[a]=[]),c[a].push({shortcut:e[i],scope:b,method:d,key:e[i],mods:h})}}function m(a){var b=(a.target||a.srcElement).tagName;return b!="INPUT"&&b!="SELECT"&&b!="TEXTAREA"}function n(a){e=a||"all"}function o(){return e||"all"}function p(a){var b,d,e;for(b in c){d=c[b];for(e=0;e<d.length;)d[e].scope===a?d.splice(e,1):e++}}function q(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,function(){c(window.event)})}var b,c={},d={16:!1,18:!1,17:!1,91:!1},e="all",f={"⇧":16,shift:16,"⌥":18,alt:18,option:18,"⌃":17,ctrl:17,control:17,"⌘":91,command:91},g={backspace:8,tab:9,clear:12,enter:13,"return":13,esc:27,escape:27,space:32,left:37,up:38,right:39,down:40,del:46,"delete":46,home:36,end:35,pageup:33,pagedown:34,",":188,".":190,"/":191,"`":192,"-":189,"=":187,";":186,"'":222,"[":219,"]":221,"\\":220};for(b=1;b<20;b++)f["f"+b]=111+b;for(b in f)l[b]=!1;q(document,"keydown",i),q(document,"keyup",j),q(window,"focus",k),a.key=l,a.key.setScope=n,a.key.getScope=o,a.key.deleteScope=p,a.key.filter=m,typeof module!="undefined"&&(module.exports=key)})(this);
View
21 test/keymaster.html
@@ -195,6 +195,27 @@
testDoesntFireOnUserInputElements: function(t){
// TODO
+ },
+
+ testCallsFilterFunction: function(t){
+ var oldFilter = key.filter, filterCalls = 0, keyCalls = 0;
+
+ key.filter = function(event){
+ filterCalls++;
+ return false;
+ }
+
+ key('a', function(){ keyCalls++; });
+ keydown(65); keyup(65);
+
+ t.assertEqual(1, filterCalls);
+ t.assertEqual(0, keyCalls);
+
+ key.filter = oldFilter;
+ keydown(65); keyup(65);
+
+ t.assertEqual(1, filterCalls);
+ t.assertEqual(1, keyCalls);
}
});
</script>
Please sign in to comment.
Something went wrong with that request. Please try again.