diff --git a/src/hotkeys.js b/src/hotkeys.js index d6ada81..15c8b9a 100644 --- a/src/hotkeys.js +++ b/src/hotkeys.js @@ -580,31 +580,61 @@ }) - .directive('hotkey', function (hotkeys) { + .directive('hotkey', function (hotkeys, $timeout) { + function addHotKey (key, attrs, func) { + hotkeys.add({ + combo: key, + description: attrs.hotkeyDescription, + callback: func, + action: attrs.hotkeyAction, + allowIn: typeof attrs.hotkeyAllowIn === "string" ? attrs.hotkeyAllowIn.split(/[\s,]+/) : [] + }); + } + + function removeHotKeyOnElementDestroy (el, key) { + // remove the hotkey if the directive is destroyed: + el.bind('$destroy', function() { + hotkeys.del(key); + }); + } + + function shortcutClickHandler (el, key, attrs) { + addHotKey(key, attrs, function (e) { + e.preventDefault(); + + if (!el.attr('disabled')) { + //$timout avoid "[$rootScope: inprog]: $apply already in progress" + $timeout(function(){ + el[0].click(); + }); + } + }); + + removeHotKeyOnElementDestroy(el, key); + } + + function multilpleHotkeysHandler (el, keys, attrs) { + var key; + + angular.forEach(keys, function (func, hotkey) { + key = hotkey; + + addHotKey(key, attrs, func); + }); + + removeHotKeyOnElementDestroy(el, key); + } + return { restrict: 'A', link: function (scope, el, attrs) { - var key, allowIn; - - angular.forEach(scope.$eval(attrs.hotkey), function (func, hotkey) { - // split and trim the hotkeys string into array - allowIn = typeof attrs.hotkeyAllowIn === "string" ? attrs.hotkeyAllowIn.split(/[\s,]+/) : []; - - key = hotkey; - - hotkeys.add({ - combo: hotkey, - description: attrs.hotkeyDescription, - callback: func, - action: attrs.hotkeyAction, - allowIn: allowIn - }); - }); - - // remove the hotkey if the directive is destroyed: - el.bind('$destroy', function() { - hotkeys.del(key); - }); + var keys = scope.$eval(attrs.hotkey); + + if (!keys) { + shortcutClickHandler(el, attrs.hotkey, attrs); + } else { + multilpleHotkeysHandler(el, keys, attrs); + } } }; }) diff --git a/test/hotkeys.coffee b/test/hotkeys.coffee index 4792444..9494033 100644 --- a/test/hotkeys.coffee +++ b/test/hotkeys.coffee @@ -431,24 +431,32 @@ describe 'Angular Hotkeys', -> describe 'hotkey directive', -> - elSimple = elAllowIn = scope = hotkeys = $compile = $document = executedSimple = executedAllowIn = null + elSimple = elAllowIn = scope = hotkeys = $compile = $document = $timeout = executedSimple = executedAllowIn = executedClickHandler = buttonDisabled = null beforeEach -> module('cfp.hotkeys') executedSimple = no executedAllowIn = no - - inject ($rootScope, _$compile_, _$document_, _hotkeys_) -> + executedClickHandler = no + + inject ($rootScope, _$compile_, _$document_, _$timeout_, _hotkeys_) -> hotkeys = _hotkeys_ $compile = _$compile_ + $timeout = _$timeout_ # el = angular.element() scope = $rootScope.$new() scope.callmeSimple = () -> executedSimple = yes scope.callmeAllowIn = () -> executedAllowIn = yes + scope.clickHandler = () -> + executedClickHandler = yes + + scope.buttonDisabled = no + elSimple = $compile('
')(scope) elAllowIn = $compile('')(scope) + elButton = $compile('')(scope) scope.$digest() it 'should allow hotkey binding via directive', -> @@ -461,6 +469,20 @@ describe 'hotkey directive', -> expect(executedSimple).toBe yes expect(executedAllowIn).toBe yes + it 'should accept hotkey to bind click event', -> + expect(hotkeys.get('q').combo).toEqual ['q'] + expect(executedClickHandler).toBe no + KeyEvent.simulate('q'.charCodeAt(0), 90) + $timeout.flush() # //flush $timout to avoid error "[$rootScope: inprog]: $apply already in progress" + expect(executedClickHandler).toBe yes + + it 'should not trigger clickHandler when element is disabled', -> + scope.buttonDisabled = yes + expect(executedClickHandler).toBe no + KeyEvent.simulate('q'.charCodeAt(0), 90) + $timeout.flush() + expect(executedClickHandler).toBe no + it 'should accept allowIn arguments', -> $body = angular.element document.body @@ -471,7 +493,7 @@ describe 'hotkey directive', -> KeyEvent.simulate('w'.charCodeAt(0), 90) expect(executedAllowIn).toBe yes expect(hotkeys.get('w').allowIn).toEqual ['INPUT', 'TEXTAREA'] - + it 'should unbind the hotkey when the directive is destroyed', -> expect(hotkeys.get('e').combo).toEqual ['e'] expect(hotkeys.get('w').combo).toEqual ['w']