Greasy Fork is available in English.
jQuery Simulate Key-Sequence Plugin
此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @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);