Hotkeys комбинация клавиш

Будет в виде модуля, для евентовой модели.

Основная суть здесь вот в чем, имеем массив, в который будем добавлять клавиши по keydown, и удалять по keyup, то есть пока клавиша зажата она будет в массиве и мы можем посмотреть какая комбинация сейчас нажата.

ZERO, для бага в хроме.

APP.hotKeys = function () {
    'use strict';
    var init = function () {
            $(document).bind('keydown', hotKeyHandler);
            $(document).bind('keyup', removeKeyUp);
        },

        ZERO = 0,

        ESC_KEY = 27,

        CTRL_KEY = 17,

        ALT_KEY = 18,

        SHIFT_KEY = 16,

        ENTER_KEY = 13,

        SPACE = 32,

        RIGHT_KEY = 39,

        LEFT_KEY = 37,

        UP_KEY = 38,

        DOWN_KEY = 40,

        M = 77,

        A = 65,

        S = 83,

        F = 70,

        keys = [],

        hotKeyHandler = function (e) {
            e = e || window.event;
            var codeKey = e.which || e.keyCode;
            keys[codeKey] = true;
            //esc
            if (codeKey === ESC_KEY) {
                $('body').trigger('escKeyUp');
                e.preventDefault();
                //enter
            } else if (codeKey === ENTER_KEY) {
                 $('body').trigger('enterKeyUp');
                // e.preventDefault();
                //CTRL + SHIFT + M
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[SHIFT_KEY] || keys[ZERO]) && keys[M]) {
                $('body').trigger('comboCtrlShiftMKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //CTRL + SHIFT + A
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[SHIFT_KEY] || keys[ZERO]) && keys[A]) {
                 $('body').trigger('comboCtrlShiftAKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //CTRL + SHIFT + F
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[SHIFT_KEY] || keys[ZERO]) && keys[F]) {
                $('body').trigger('comboCtrlShiftFKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //CTRL + UPKEY
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[UP_KEY] || keys[ZERO])) {
                 $('body').trigger('comboCtrlUpKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //CTRL + DOWNKEY
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[DOWN_KEY] || keys[ZERO])) {
                 $('body').trigger('comboCtrlDownKeyUp', {codeKey: codeKey});
                e.preventDefault();
               //CTRL + LEFTKEY
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[LEFT_KEY] || keys[ZERO])) {
                 $('body').trigger('comboCtrlLeftKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //CTRL + RIGHTKEY
            } else if ((keys[CTRL_KEY] || keys[ZERO]) && (keys[RIGHT_KEY] || keys[ZERO])) {
                $('body').trigger('comboCtrlRightKeyUp', {codeKey: codeKey});
                e.preventDefault();
                //SPACE
            }
            codeKey = null;
        },

        removeKeyUp = function(e) {
            var codeKey = e.which || e.keyCode;
            if (keys[ZERO]) {
                delete keys[ZERO];
            }
            delete keys[codeKey];
        };

    return {
        init: init
    };
}();