/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */ /*global jQuery:true $:true */ /* jQuery Simulate Key-Combo Plugin 1.3.0 * http://github.com/j-ulrich/jquery-simulate-ext * * Copyright (c) 2014 Jochen Ulrich * Licensed under the MIT license (MIT-LICENSE.txt). */ /** * * For details about key events, key codes, char codes etc. see http://unixpapa.com/js/key.html */ ;(function($,undefined) { "use strict"; /** * Key codes of special keys. * @private * @author julrich * @since 1.3.0 */ var SpecialKeyCodes = { // Modifier Keys SHIFT: 16, CONTROL: 17, ALTERNATIVE: 18, META: 91, // Arrow Keys LEFT_ARROW: 37, UP_ARROW: 38, RIGHT_ARROW: 39, DOWN_ARROW: 40, // Function Keys F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117, F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123, // Other ENTER: 13, TABULATOR: 9, ESCAPE: 27, BACKSPACE: 8, INSERT: 45, DELETE: 46, HOME: 36, END: 35, PAGE_UP: 33, PAGE_DOWN: 34, }; // SpecialKeyCode aliases SpecialKeyCodes.CTRL = SpecialKeyCodes.CONTROL; SpecialKeyCodes.ALT = SpecialKeyCodes.ALTERNATIVE; SpecialKeyCodes.COMMAND = SpecialKeyCodes.META; SpecialKeyCodes.TAB = SpecialKeyCodes.TABULATOR; SpecialKeyCodes.ESC = SpecialKeyCodes.ESCAPE; $.extend( $.simulate.prototype, /** * @lends $.simulate.prototype */ { /** * Simulates simultaneous key presses * * @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/key-combo.md * @public * @author julrich * @since 1.0 */ simulateKeyCombo: function() { var $target = $(this.target), options = $.extend({ combo: "", eventProps: {}, eventsOnly: false }, this.options), combo = options.combo, comboSplit = combo.split(/(\+)/), plusExpected = false, holdKeys = [], i; if (combo.length === 0) { return; } // Remove empty parts comboSplit = $.grep(comboSplit, function(part) { return (part !== ""); }); for (i=0; i < comboSplit.length; i+=1) { var key = comboSplit[i], keyLowered = key.toLowerCase(), keySpecial = key.toUpperCase().replace('-','_'); if (plusExpected) { if (key !== "+") { throw 'Syntax error: expected "+"'; } else { plusExpected = false; } } else { var keyCode; if ( key.length > 1) { // Assume a special key keyCode = SpecialKeyCodes[keySpecial]; if (keyCode === undefined) { throw 'Syntax error: unknown special key "'+key+'" (forgot "+" between keys?)'; } switch (keyCode) { case SpecialKeyCodes.CONTROL: case SpecialKeyCodes.ALT: case SpecialKeyCodes.SHIFT: case SpecialKeyCodes.META: options.eventProps[keyLowered+"Key"] = true; break; } holdKeys.unshift(keyCode); options.eventProps.keyCode = keyCode; options.eventProps.which = keyCode; options.eventProps.charCode = 0; $target.simulate("keydown", options.eventProps); } else { // "Normal" key keyCode = $.simulate.prototype.simulateKeySequence.prototype.charToKeyCode(key); holdKeys.unshift(keyCode); options.eventProps.keyCode = keyCode; options.eventProps.which = keyCode; options.eventProps.charCode = undefined; $target.simulate("keydown", options.eventProps); if (options.eventProps.shiftKey) { key = key.toUpperCase(); } options.eventProps.keyCode = key.charCodeAt(0); options.eventProps.charCode = options.eventProps.keyCode; options.eventProps.which = options.eventProps.keyCode; $target.simulate("keypress", options.eventProps); if (options.eventsOnly !== true && !options.eventProps.ctrlKey && !options.eventProps.altKey && !options.eventProps.metaKey) { $target.simulate('key-sequence', {sequence: key, triggerKeyEvents: false}); } } plusExpected = true; } } if (!plusExpected) { throw 'Syntax error: expected key (trailing "+"?)'; } // Release keys options.eventProps.charCode = undefined; for (i=0; i < holdKeys.length; i+=1) { options.eventProps.keyCode = holdKeys[i]; options.eventProps.which = holdKeys[i]; switch (options.eventProps.keyCode) { case SpecialKeyCodes.ALT: options.eventProps.altKey = false; break; case SpecialKeyCodes.SHIFT: options.eventProps.shiftKey = false; break; case SpecialKeyCodes.CONTROL: options.eventProps.ctrlKey = false; break; case SpecialKeyCodes.META: options.eventProps.metaKey = false; break; default: break; } $target.simulate("keyup", options.eventProps); } } }); }(jQuery));