- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
193 lines
4.9 KiB
JavaScript
193 lines
4.9 KiB
JavaScript
/*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)); |