angular.module('ui.keypress',[]).
factory('keypressHelper', ['$parse', function keypress($parse){
var keysByCode = {
8: 'backspace',
9: 'tab',
13: 'enter',
27: 'esc',
32: 'space',
33: 'pageup',
34: 'pagedown',
35: 'end',
36: 'home',
37: 'left',
38: 'up',
39: 'right',
40: 'down',
45: 'insert',
46: 'delete'
};
var capitaliseFirstLetter = function (string) {
return string.charAt(0).toUpperCase() + string.slice(1);
};
return function(mode, scope, elm, attrs) {
var params, combinations = [];
params = scope.$eval(attrs['ui'+capitaliseFirstLetter(mode)]);
// Prepare combinations for simple checking
angular.forEach(params, function (v, k) {
var combination, expression;
expression = $parse(v);
angular.forEach(k.split(' '), function(variation) {
combination = {
expression: expression,
keys: {}
};
angular.forEach(variation.split('-'), function (value) {
combination.keys[value] = true;
});
combinations.push(combination);
});
});
// Check only matching of pressed keys one of the conditions
elm.bind(mode, function (event) {
// No need to do that inside the cycle
var metaPressed = !!(event.metaKey && !event.ctrlKey);
var altPressed = !!event.altKey;
var ctrlPressed = !!event.ctrlKey;
var shiftPressed = !!event.shiftKey;
var keyCode = event.keyCode;
// normalize keycodes
if (mode === 'keypress' && !shiftPressed && keyCode >= 97 && keyCode <= 122) {
keyCode = keyCode - 32;
}
// Iterate over prepared combinations
angular.forEach(combinations, function (combination) {
var mainKeyPressed = combination.keys[keysByCode[keyCode]] || combination.keys[keyCode.toString()];
var metaRequired = !!combination.keys.meta;
var altRequired = !!combination.keys.alt;
var ctrlRequired = !!combination.keys.ctrl;
var shiftRequired = !!combination.keys.shift;
if (
mainKeyPressed &&
( metaRequired === metaPressed ) &&
( altRequired === altPressed ) &&
( ctrlRequired === ctrlPressed ) &&
( shiftRequired === shiftPressed )
) {
// Run the function
scope.$apply(function () {
combination.expression(scope, { '$event': event });
});
}
});
});
};
}]);
/**
* Bind one or more handlers to particular keys or their combination
* @param hash {mixed} keyBindings Can be an object or string where keybinding expression of keys or keys combinations and AngularJS Exspressions are set. Object syntax: "{ keys1: expression1 [, keys2: expression2 [ , ... ]]}". String syntax: ""expression1 on keys1 [ and expression2 on keys2 [ and ... ]]"". Expression is an AngularJS Expression, and key(s) are dash-separated combinations of keys and modifiers (one or many, if any. Order does not matter). Supported modifiers are 'ctrl', 'shift', 'alt' and key can be used either via its keyCode (13 for Return) or name. Named keys are 'backspace', 'tab', 'enter', 'esc', 'space', 'pageup', 'pagedown', 'end', 'home', 'left', 'up', 'right', 'down', 'insert', 'delete'.
* @example
**/
angular.module('ui.keypress').directive('uiKeydown', ['keypressHelper', function(keypressHelper){
return {
link: function (scope, elm, attrs) {
keypressHelper('keydown', scope, elm, attrs);
}
};
}]);
angular.module('ui.keypress').directive('uiKeypress', ['keypressHelper', function(keypressHelper){
return {
link: function (scope, elm, attrs) {
keypressHelper('keypress', scope, elm, attrs);
}
};
}]);
angular.module('ui.keypress').directive('uiKeyup', ['keypressHelper', function(keypressHelper){
return {
link: function (scope, elm, attrs) {
keypressHelper('keyup', scope, elm, attrs);
}
};
}]);