'use strict'; /*@ Ox.Keyboard Basic keyboard handler @*/ Ox.Keyboard = (function() { var buffer = '', bound = [], resetTimeout, triggerTimeout; Ox.UI.ready(function() { Ox.$document.keydown(keydown) }); function keydown(event) { var focused = Ox.Focus.focused(), key, keyName = Ox.KEYS[event.keyCode] || '', keyNames = keyName ? [keyName] : [], keyBasename = keyName.split('.')[0], ret = true; Ox.forEach(Ox.MODIFIER_KEYS, function(v, k) { // avoid pushing modifier twice // using event.originalEvent since jquery always sets // event.metaKey to event.ctrlKey if (event.originalEvent[k] && keyBasename != v) { keyNames.splice(-1, 0, v); } }); key = keyNames.join('_'); if (focused === null || !Ox.UI.elements[focused].hasClass('OxInput')) { bound.forEach(function(id) { Ox.UI.elements[id].triggerEvent('key_' + key); }); } if (focused !== null && bound.indexOf(focused) == -1) { Ox.UI.elements[focused].triggerEvent('key_' + key); // prevent Chrome from scrolling, or going back in history if ( [ 'backspace', 'down', 'left', 'right', 'space', 'up' ].indexOf(key) > -1 && !Ox.UI.elements[focused].hasClass('OxInput') && !Ox.UI.elements[focused].hasClass('OxAutocompleteMenu') ) { ret = false; } // prevent cursor in input field from moving to start or end if ( ['down', 'up'].indexOf(key) > -1 && Ox.UI.elements[focused].hasClass('OxAutocompleteMenu') ) { ret = false; } } if (/^[\w\d](\.numpad)?$|^space$/.test(key)) { // don't register leading spaces or trailing double spaces if (!(keyName == 'space' && (buffer == '' || / $/.test(buffer)))) { buffer += keyName == 'space' ? ' ' : keyBasename; // clear the trigger timeout only if the key went into the buffer clearTimeout(triggerTimeout); triggerTimeout = setTimeout(function() { focused !== null && Ox.UI.elements[focused].triggerEvent('keys', { keys: buffer }); }, 25); // fixme: used to be 250, but seemed too much. // if it stays at 25, we may not need a timeout at all } } // clear the reset timeout even if the key didn't go into the buffer clearTimeout(resetTimeout); resetTimeout = setTimeout(function() { buffer = ''; }, 1000); return ret; } return { /*@ bind bind (id) -> bind id @*/ bind: function(id) { var index = bound.indexOf(id); index == -1 && bound.push(id); }, /*@ unbind unbind (id) -> unbind id @*/ unbind: function(id) { var index = bound.indexOf(id); index > -1 && bound.splice(index, 1); } }; })();