Skrip ini tidak untuk dipasang secara langsung. Ini adalah pustaka skrip lain untuk disertakan dengan direktif meta // @require https://update.greasyfork.org/scripts/14095/88783/jQuery%20Simulate%20Key-Sequence%20Plugin%20130.js
/*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 bililiteRange:true */
/* jQuery Simulate Key-Sequence 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).
*
* The plugin is an extension and modification of the jQuery sendkeys plugin by Daniel Wachsstock.
* Therefore, the original copyright notice and license follow below.
*/
// insert characters in a textarea or text input field
// special characters are enclosed in {}; use {{} for the { character itself
// documentation: http://bililite.com/blog/2008/08/20/the-fnsendkeys-plugin/
// Version: 2.0
// Copyright (c) 2010 Daniel Wachsstock
// MIT license:
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
;(function($, undefined){
"use strict";
$.simulate.prototype.quirks = $.simulate.prototype.quirks || {};
$.extend($.simulate.prototype.quirks,
/**
* @lends $.simulate.prototype.quirks
*/
{
/**
* When simulating with delay in non-input elements,
* all spaces are simulated at the end of the sequence instead
* of the correct position.
* @see {@link https://github.com/j-ulrich/jquery-simulate-ext/issues/6|issues #6}
*/
delayedSpacesInNonInputGlitchToEnd: undefined
});
$.extend($.simulate.prototype,
/**
* @lends $.simulate.prototype
*/
{
/**
* Simulates sequencial key strokes.
*
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/key-sequence.md
* @public
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
simulateKeySequence: function() {
var target = this.target,
$target = $(target),
opts = $.extend({
sequence: "",
triggerKeyEvents: true,
eventProps: {},
delay: 0,
callback: undefined
}, this.options),
sequence = opts.sequence;
opts.delay = parseInt(opts.delay,10);
var localkeys = {};
// Fix for #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6)
if ($.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd && !$target.is('input,textarea')) {
$.extend(localkeys, {
' ': function(rng, s, opts) {
var internalOpts = $.extend({}, opts, {
triggerKeyEvents: false,
delay: 0,
callback: undefined
});
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '\xA0', internalOpts);
$.simulate.prototype.simulateKeySequence.defaults['{leftarrow}'](rng, s, internalOpts);
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, s, opts);
$.simulate.prototype.simulateKeySequence.defaults['{del}'](rng, s, internalOpts);
}
});
}
$.extend(localkeys, opts, $target.data('simulate-keySequence')); // allow for element-specific key functions
// most elements to not keep track of their selection when they lose focus, so we have to do it for them
var rng = $.data (target, 'simulate-keySequence.selection');
if (!rng){
rng = bililiteRange(target).bounds('selection');
$.data(target, 'simulate-keySequence.selection', rng);
$target.bind('mouseup.simulate-keySequence', function(){
// we have to update the saved range. The routines here update the bounds with each press, but actual keypresses and mouseclicks do not
$.data(target, 'simulate-keySequence.selection').bounds('selection');
}).bind('keyup.simulate-keySequence', function(evt){
// restore the selection if we got here with a tab (a click should select what was clicked on)
if (evt.which === 9){
// there's a flash of selection when we restore the focus, but I don't know how to avoid that.
$.data(target, 'simulate-keySequence.selection').select();
}else{
$.data(target, 'simulate-keySequence.selection').bounds('selection');
}
});
}
$target.focus();
if (typeof sequence === 'undefined') { // no string, so we just set up the event handlers
return;
}
sequence = sequence.replace(/\n/g, '{enter}'); // turn line feeds into explicit break insertions
/**
* Informs the rest of the world that the sequences is finished.
* @fires simulate-keySequence
* @requires target
* @requires sequence
* @requires opts
* @inner
* @author julrich
* @since 1.0
*/
function sequenceFinished() {
$target.trigger({type: 'simulate-keySequence', sequence: sequence});
if ($.isFunction(opts.callback)) {
opts.callback.apply(target, [{
sequence: sequence
}]);
}
}
/**
* Simulates the key stroke for one character (or special sequence) and sleeps for
* <code>opts.delay</code> milliseconds.
* @requires lastTime
* @requires now()
* @requires tokenRegExp
* @requires opts
* @requires rng
* @inner
* @author julrich
* @since 1.0
*/
function processNextToken() {
var timeElapsed = now() - lastTime; // Work-around for Firefox "bug": setTimeout can fire before the timeout
if (timeElapsed >= opts.delay) {
var match = tokenRegExp.exec(sequence);
if ( match !== null ) {
var s = match[0];
(localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts);
setTimeout(processNextToken, opts.delay);
}
else {
sequenceFinished();
}
lastTime = now();
}
else {
setTimeout(processNextToken, opts.delay - timeElapsed);
}
}
if (!opts.delay || opts.delay <= 0) {
// Run as fast as possible
sequence.replace(/\{[^}]*\}|[^{]+/g, function(s){
(localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts);
});
sequenceFinished();
}
else {
var tokenRegExp = /\{[^}]*\}|[^{]/g; // This matches curly bracket expressions or single characters
var now = Date.now || function() { return new Date().getTime(); },
lastTime = now();
processNextToken();
}
}
});
$.extend($.simulate.prototype.simulateKeySequence.prototype,
/**
* @lends $.simulate.prototype.simulateKeySequence.prototype
*/
{
/**
* Maps special character char codes to IE key codes (covers IE and Webkit)
* @author julrich
* @since 1.0
*/
IEKeyCodeTable: {
33: 49, // ! -> 1
64: 50, // @ -> 2
35: 51, // # -> 3
36: 52, // $ -> 4
37: 53, // % -> 5
94: 54, // ^ -> 6
38: 55, // & -> 7
42: 56, // * -> 8
40: 57, // ( -> 9
41: 48, // ) -> 0
59: 186, // ; -> 186
58: 186, // : -> 186
61: 187, // = -> 187
43: 187, // + -> 187
44: 188, // , -> 188
60: 188, // < -> 188
45: 189, // - -> 189
95: 189, // _ -> 189
46: 190, // . -> 190
62: 190, // > -> 190
47: 191, // / -> 191
63: 191, // ? -> 191
96: 192, // ` -> 192
126: 192, // ~ -> 192
91: 219, // [ -> 219
123: 219, // { -> 219
92: 220, // \ -> 220
124: 220, // | -> 220
93: 221, // ] -> 221
125: 221, // } -> 221
39: 222, // ' -> 222
34: 222 // " -> 222
},
/**
* Tries to convert character codes to key codes.
* @param {Numeric} character - A character code
* @returns {Numeric} The key code corresponding to the given character code,
* based on the key code table of InternetExplorer. If no corresponding key code
* could be found (which will be the case for all special characters except the common
* ones), the character code itself is returned. However, <code>keyCode === charCode</code>
* does not imply that no key code was found because some key codes are identical to the
* character codes (e.g. for uppercase characters).
* @requires $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable
* @see $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable
* @author julrich
* @since 1.0
*/
charToKeyCode: function(character) {
var specialKeyCodeTable = $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable;
var charCode = character.charCodeAt(0);
if (charCode >= 64 && charCode <= 90 || charCode >= 48 && charCode <= 57) {
// A-Z and 0-9
return charCode;
}
else if (charCode >= 97 && charCode <= 122) {
// a-z -> A-Z
return character.toUpperCase().charCodeAt(0);
}
else if (specialKeyCodeTable[charCode] !== undefined) {
return specialKeyCodeTable[charCode];
}
else {
return charCode;
}
}
});
// add the functions publicly so they can be overridden
$.simulate.prototype.simulateKeySequence.defaults = {
/**
* Simulates key strokes of "normal" characters (i.e. non-special sequences).
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - String of (simple) characters to be simulated.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
simplechar: function (rng, s, opts){
rng.text(s, 'end');
if (opts.triggerKeyEvents) {
for (var i =0; i < s.length; i += 1){
var charCode = s.charCodeAt(i);
var keyCode = $.simulate.prototype.simulateKeySequence.prototype.charToKeyCode(s.charAt(i));
// a bit of cheating: rng._el is the element associated with rng.
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: keyCode}));
$(rng._el).simulate('keypress', $.extend({}, opts.eventProps,{keyCode: charCode, which: charCode, charCode: charCode}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: keyCode}));
}
}
},
/**
* Simulates key strokes of a curly opening bracket.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{{}': function (rng, s, opts){
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '{', opts);
},
/**
* Simulates hitting the enter button.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{enter}': function (rng, s, opts){
rng.insertEOL();
rng.select();
if (opts.triggerKeyEvents === true) {
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 13}));
$(rng._el).simulate('keypress', $.extend({}, opts.eventProps, {keyCode: 13, which: 13, charCode: 13}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 13}));
}
},
/**
* Simulates hitting the backspace button.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{backspace}': function (rng, s, opts){
var b = rng.bounds();
if (b[0] === b[1]) { rng.bounds([b[0]-1, b[0]]); } // no characters selected; it's just an insertion point. Remove the previous character
rng.text('', 'end'); // delete the characters and update the selection
if (opts.triggerKeyEvents === true) {
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 8}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 8}));
}
},
/**
* Simulates hitting the delete button.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{del}': function (rng, s, opts){
var b = rng.bounds();
if (b[0] === b[1]) { rng.bounds([b[0], b[0]+1]); } // no characters selected; it's just an insertion point. Remove the next character
rng.text('', 'end'); // delete the characters and update the selection
if (opts.triggerKeyEvents === true) {
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 46}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 46}));
}
},
/**
* Simulates hitting the right arrow button.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{rightarrow}': function (rng, s, opts){
var b = rng.bounds();
if (b[0] === b[1]) { b[1] += 1; } // no characters selected; it's just an insertion point. Move to the right
rng.bounds([b[1], b[1]]).select();
if (opts.triggerKeyEvents === true) {
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 39}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 39}));
}
},
/**
* Simulates hitting the left arrow button.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @param {String} s - Ignored.
* @param {Object} opts - The key-sequence options.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{leftarrow}': function (rng, s, opts){
var b = rng.bounds();
if (b[0] === b[1]) { b[0] -= 1; } // no characters selected; it's just an insertion point. Move to the left
rng.bounds([b[0], b[0]]).select();
if (opts.triggerKeyEvents === true) {
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 37}));
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 37}));
}
},
/**
* Selects all characters in the target element.
* @param {Object} rng - bililiteRange object of the simulation target element.
* @author Daniel Wachsstock, julrich
* @since 1.0
*/
'{selectall}' : function (rng){
rng.bounds('all').select();
}
};
//####### Quirk detection #######
if ($.simulate.ext_disableQuirkDetection !== true) { // Fixes issue #9 (https://github.com/j-ulrich/jquery-simulate-ext/issues/9)
$(document).ready(function() {
// delayedSpacesInNonInputGlitchToEnd
// See issues #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6)
/* Append a div to the document (bililiteRange needs the element to be in the document), simulate
* a delayed sequence containing a space in the middle and check if the space moves to the end.
*/
var $testDiv = $('<div/>').css({height: 1, width: 1, position: 'absolute', left: -1000, top: -1000}).appendTo('body');
$testDiv.simulate('key-sequence', {sequence: '\xA0 \xA0', delay:1, callback: function() {
$.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd = ($testDiv.text() === '\xA0\xA0 ');
$testDiv.remove();
}});
});
}
})(jQuery);