Remoto - VFS: keyboard.js Source File
Remoto - VFS
keyboard.js
Go to the documentation of this file.
1 
3 // Keyboard Handler //
5 
6 define( [
7  'jquery/jquery'
8  ],
9  function()
10  {
11 
111  function keyboard(obj,_defaultHandler)
112  {
113  this._commands = [];
114 
115  obj.bind( "keydown keyup", this.keyHandler.bind(this) );
116 
117  this._defaultHandler = _defaultHandler;
118  }
119 
120  //http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/javascript-char-codes-key-codes.aspx
121  keyboard.codes = { "CTRL": 17, //null,
122  "ALT": 18, //null
123  "META": 91, //null,
124  "SHIFT": 16, //null,
125  "LEFT": 37,
126  "UP": 38,
127  "RIGHT": 39,
128  "DOWN": 40,
129  "DEL": 46,
130  "DELETE": 46,
131  "BACKSPACE": 8,
132  "SPACE": 32,
133  "ENTER": 13,
134  "ESCAPE": 27,
135  "F1": 112,
136  "F2": 113,
137  "F3": 114,
138  "F4": 115,
139  "F5": 116,
140  "F6": 117,
141  "F7": 118,
142  "F8": 119,
143  "F9": 120,
144  "F10": 121,
145  "F11": 122,
146  "F12": 123,
147  "-": 189,
148  "=": 187,
149  "[": 219,
150  "]": 221,
151  ".": 190,
152  };
153 
154  keyboard.ignore = ["TEXTAREA","INPUT","SELECT"];
155 
171  keyboard.init = function()
172  {
173  //console.log( "KEYBOARD INIT!" );
174 
175  //var _keyboard = new keyboard($(document),keyboard,function(e) { keyboard.preventDefault(e); return false; } );
176  var _keyboard = new keyboard($(document));
177 
178  _keyboard.registerCommand("Meta-a", false ); //kill apple-A (select all)
179  //_keyboard.registerCommand("DEL, BACKSPACE", false ); //kill delete as back button
180  _keyboard.registerCommand("DEL,BACKSPACE",false,false,false,1); //prevent delete/backspace from causing the back button to trigger
181  _keyboard.registerCommand("Meta-s,Ctrl-s,Alt-s",false,false,false,1); //prevent accidental saves
182 
183  return _keyboard;
184  }
185 
196  keyboard.preventDefault = function(e)
197  {
198  //console.log("PREVENT DEFAULT");
199  e.preventDefault();
200  e.stopPropagation();
201  return true; //return true to keyHandler, which will in turn return false...
202  }
203 
204  keyboard.prototype = {
205 
225  registerCommand: function(c,f,l,r,p) //Command, Functor, aLways, Releaseonly, Priority(1=first)
226  {
227  var cs = c.split(",");
228  p = Math.max( (p || this._commands.length)-1, 0 );
229 
230  for(var i=0;i<cs.length;i++)
231  {
232  var cc = jQuery.trim(cs[i]).toLowerCase();
233  this._commands.splice(p, 0, new keyboardCommand(cc,f,l,r) );
234  }
235  },
236 
252  unregisterCommand: function(c,r)
253  {
254  var cs = c.split(",");
255  var all = true;
256 
257  for (var j=0;j<cs.length;j++)
258  {
259  c = jQuery.trim(cs[j]).toLowerCase();
260 
261  var found=false;
262  for (var i=0;i<this._commands.length;i++)
263  {
264  var m = this._commands[i];
265  if ((m._command === c) && (m._releaseOnly === r))
266  {
267  var cc = this._commands.splice(i,1);
268  found = true;
269  }
270  }
271 
272  all = all && found;
273  }
274 
275  return all;
276  },
277 
288  keyHandler: function(e)
289  {
290  //console.log("handler!");
291  //console.log(e);
292 
293  //if (keyboard.ignore.indexOf( e.target.nodeName.toUpperCase() ) != -1)
294  // return false;
295 
296  var x = false;
297 
298  for (var i=0; i<this._commands.length; i++)
299  {
300  if ( (e.type === "keydown" && !this._commands[i]._releaseOnly) ||
301  (e.type === "keyup" && this._commands[i]._releaseOnly) )
302  {
303  //console.log(e.type);
304  //console.log(this._commands[i]._always);
305  if (!this._commands[i]._always && keyboard.ignore.indexOf( e.target.nodeName.toUpperCase() ) != -1)
306  continue;
307 
308  x |= this._commands[i].exec(e);
309  }
310 
311  if (x) //first true kills the loop
312  {
314  //console.log("found key for "+e.type);
315  return false;
316  }
317  }
318 
319  //console.log("not found... default for "+e.type);
320  //console.trace();
321 
322  if (this._defaultHandler) //if a default handler is present, call it...
323  return this._defaultHandler(e) // return its value
324  },
325 
337  listen: function(jq,_defaultHandler)
338  {
339  return new keyboard(jq,_defaultHandler);
340  },
341 
351  destroy: function()
352  {
353  this._commands = [];
354  },
355  }
356 
357 
359  // Key Command Handler //
361 
382  function keyboardCommand(command, functor, always, releaseOnly)
383  {
384  this._function = functor || keyboard.preventDefault;
385 
386  this._releaseOnly = releaseOnly;
387  this._always = always;
388  this._command = command; //used to match for un-register
389 
390  this._meta = false;
391  this._shift = false;
392  this._alt = false;
393  this._ctrl = false;
394 
395  this._keyChar = null;
396 
397  this.parse(jQuery.trim(command));
398  }
399 
400  keyboardCommand.prototype = {
401 
412  exec: function(e)
413  {
414  var ubers = (
415  this._meta == e.metaKey &&
416  this._shift == e.shiftKey &&
417  this._alt == e.altKey &&
418  this._ctrl == e.ctrlKey
419  );
420 
421  //console.log("code: "+e.keyCode);
422  //console.log(ubers+" :: "+this._keyChar+" :: "+String.fromCharCode(e.keyCode));
423  //console.log(e);
424 
425  if (ubers || this._releaseOnly) //FIXME: release only won't have any ubers if it's only an uber. Really the or clause shouldn't be here
426  {
427  if (this._keyChar)
428  {
429  if (String.fromCharCode(e.keyCode) === this._keyChar || e.keyCode === this._keyChar)
430  {
431  if (this._function)
432  { this._function(e);
433  return true;
434  }
435  }
436  }
437  else
438  {
439  if (this._function)
440  { this._function(e);
441  return true;
442  }
443  }
444  }
445 
446  return false;
447  },
448 
458  parse: //expects something like ctrl+a or ctrl+shift+alt+x
459  function(c)
460  {
461  c = c.toLowerCase();
462  c = c.replace(" ","");
463 
464  this._ctrl = (c.indexOf("ctrl")>-1) ? true : false;
465  this._alt = (c.indexOf("alt")>-1) ? true : false;
466  this._meta = ((c.indexOf("meta")>-1) || (c.indexOf("apple")>-1)) ? true : false;
467  this._shift = (c.indexOf("shift")>-1) ? true : false;
468 
469  if (c==="-" || c==="+")
470  this._keyChar = c;
471  else
472  this._keyChar = c.split(/[+-]/).pop().toUpperCase();
473 
474  if (this._keyChar in keyboard.codes)
475  this._keyChar = keyboard.codes[this._keyChar];
476 
477  //console.log(this);
478  //console.trace();
479  },
480  }
481 
482  return keyboard.init();
483  }
484 );
485 
keyboardCommand(command, functor, always, releaseOnly)
This library creates convenient methods for adding keyboard shortcuts to an application.
registerCommand(c, f, l, r, p)
Register a command with a keyboard listener.
preventDefault(e)
init()
Return a new instance of a keyboard handler.
listen(jq, _defaultHandler)
unregisterCommand(c, r)
Unregister a command from a keyboard listener.
keyboard(obj, _defaultHandler)
getter x
a getter DOCME