AngularJS: Keyboard Shorcut as a Service

by tchatel

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.js"></script>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<div style="padding:30px" ng-controller="MainCtrl">
  <div class="row-fluid">
    <h2>AngularJS and services</h2>
    <h3>Keyboard Shorcut Manager as a Service</h3>
  </div>
  <div class="row-fluid">
    <div class="span6">
      <p class="text-success">You can use the followin shortcut combination to test :</p>
      <ul>
        <li>a: there is two handler on a</li>
        <li>ctrl+a</li>
        <li>ctrl+shift+d</li>
        <li>z with handler disable when focus input or textarea</li>
      </ul>
      <hr />
      <input type="text" id="inputTest" placeholder="Try shorcut here" />
      <textarea id="textareaTest" placeholder="Try shorcut here"></textarea>
    </div>
    <div class="span6">
      <h3>Logs</h3>
      <ul>
        <li ng-repeat="log in logs" ng-cloak>
          {{log}}
        </li>
      </ul>
    </div>
  </div>
</div>

CSS

[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none;
}

JavaScript

var frAngular = angular.module('frAngular', []);

// This service was based on OpenJS library available in BSD License
// http://www.openjs.com/scripts/events/keyboard_shortcuts/index.php
frAngular.factory('keyboardManager', ['$window', '$rootScope', function ($window, $rootScope) {
	var keyboardManagerService = {};

	var defaultOpt = {
		'type':             'keydown',
		'propagate':        false,
		'inputDisabled':    false,
		'target':           $window.document,
		'keyCode':          false
	};
	// Store all keyboard combination shortcuts
	keyboardManagerService.keyboardEvent = {}
	// Add a new keyboard combination shortcut
	keyboardManagerService.bind = function (label, callback, opt) {
		var fct, elt, code, k;
		// Initialize opt object
		opt   = angular.extend({}, defaultOpt, opt);
		label = label.toLowerCase();
		elt   = opt.target;
		if(typeof opt.target == 'string') elt = document.getElementById(opt.target);

		fct = function (e) {
			e = e || $window.event;

			// Disable event handler when focus input and textarea
			if (opt['inputDisabled']) {
				var elt;
				if (e.target) elt = e.target;
				else if (e.srcElement) elt = e.srcElement;
				if (elt.nodeType == 3) elt = elt.parentNode;
				if (elt.tagName == 'INPUT' || elt.tagName == 'TEXTAREA') return;
			}

			// Find out which key is pressed
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			var character = String.fromCharCode(code).toLowerCase();

			if (code == 188) character = ","; // If the user presses , when the type is onkeydown
			if (code == 190) character = "."; // If the user presses , when the type is onkeydown

			var keys = label.split("+");
			// Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
			var kp = 0;
			// Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
			var shift_nums =...