From ac50af050913762263bbe63a61d502efd2d7dc38 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Wed, 24 Sep 2014 22:28:56 +0200 Subject: [PATCH] fix keyboard handler --- source/Ox.UI/js/Core/Event.js | 76 ++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/source/Ox.UI/js/Core/Event.js b/source/Ox.UI/js/Core/Event.js index b7fd97c5..309a5ad2 100644 --- a/source/Ox.UI/js/Core/Event.js +++ b/source/Ox.UI/js/Core/Event.js @@ -9,7 +9,7 @@ slash: '/', space: ' ' }, - hasCallback = {}, + keyboardCallbacks = {}, keyboardEventRegExp = /^key(\.[\w\d.]+)?$/, keys = '', keysEventRegExp = new RegExp( @@ -21,7 +21,8 @@ function bind(options) { var args = Ox.slice(arguments, 1), callbacks = options.callbacks, - that = this; + that = this, + oxid = that.oxid || 0; Ox.forEach( Ox.isFunction(args[0]) ? {'*': args[0]} : Ox.makeObject(args), function(originalCallback, event) { @@ -36,7 +37,9 @@ : originalCallback ); if (isKeyboardEvent(event)) { - hasCallback[event] = true; + keyboardCallbacks[oxid] = ( + keyboardCallbacks[oxid] || [] + ).concat(event); } } ); @@ -72,10 +75,8 @@ } function onKeydown(e) { - if (Ox.Focus.focusedElementIsInput()) { - return; - } - var $element = Ox.Focus.focusedElement(), + var $element = Ox.Focus.focusedElement() || Ox.$body, + isInput = Ox.Focus.focusedElementIsInput(), keyName = Ox.KEYS[e.keyCode], keyBasename = keyName.split('.')[0], key = Object.keys(Ox.MODIFIER_KEYS).filter(function(key) { @@ -85,35 +86,39 @@ }).concat(keyName).join('_'), event = 'key.' + key, triggerEvent = function() { - if ($element) { + if (Ox.Focus.focusedElement()) { $element.triggerEvent.apply($element, arguments); - } else { + } else if (!isInput) { Ox.Event.trigger.apply( - Ox.$body, [{}].concat(Ox.slice(arguments)) + $element, [{}].concat(Ox.slice(arguments)) ); } }; triggerEvent(event, e); - if (isKeysEventKey(key)) { - // don't register leading spaces or trailing double spaces - if (keyName != 'space' || ( - keys != '' && !Ox.endsWith(keys, ' ') - )) { - keys += chars[keyName] || keyBasename; - // clear the trigger timeout only if the key registered - clearTimeout(triggerTimeout); - triggerTimeout = setTimeout(function() { - triggerEvent('keys', Ox.extend(e, {keys: keys})); - }, 250); + if (!isInput) { + if (isKeysEventKey(key)) { + // don't register leading spaces or trailing double spaces + if (keyName != 'space' || ( + keys != '' && !Ox.endsWith(keys, ' ') + )) { + keys += chars[keyName] || keyBasename; + // clear the trigger timeout only if the key registered + clearTimeout(triggerTimeout); + triggerTimeout = setTimeout(function() { + triggerEvent('keys', Ox.extend(e, {keys: keys})); + }, 250); + } + } + // clear the reset timeout even if the key didn't register + clearTimeout(resetTimeout); + resetTimeout = setTimeout(function() { + keys = ''; + }, 1000); + if ( + Ox.contains(keyboardCallbacks[$element.oxid || 0] || [], event) + ) { + e.preventDefault(); } - } - // clear the reset timeout even if the key didn't register - clearTimeout(resetTimeout); - resetTimeout = setTimeout(function() { - keys = ''; - }, 1000); - if (hasCallback[event]) { - e.preventDefault(); } } @@ -138,7 +143,8 @@ function unbind(options) { var args = Ox.slice(arguments, 1), - callbacks = options.callbacks; + callbacks = options.callbacks, + oxid = this.oxid || 0; if (args.length == 0) { // unbind all handlers for all events callbacks = []; @@ -161,8 +167,14 @@ delete callbacks[event]; } } - if (isKeyboardEvent(event) && !callbacks[event]) { - delete hasCallback[event]; + if (isKeyboardEvent(event)) { + var index = keyboardCallbacks[oxid].indexOf(event); + keyboardCallbacks[oxid].splice( + keyboardCallbacks[oxid].indexOf(event), 1 + ) + if (keyboardCallbacks[oxid].length == 0) { + delete keyboardCallbacks[oxid]; + } } } );