1/*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 */ 2/*jslint white: true vars: true browser: true todo: true */ 3/*global jQuery:true $:true bililiteRange:true */ 4 5/* jQuery Simulate Key-Sequence Plugin 1.2.0 6 * http://github.com/j-ulrich/jquery-simulate-ext 7 * 8 * Copyright (c) 2013 Jochen Ulrich 9 * Licensed under the MIT license (MIT-LICENSE.txt). 10 * 11 * The plugin is an extension and modification of the jQuery sendkeys plugin by Daniel Wachsstock. 12 * Therefore, the original copyright notice and license follow below. 13 */ 14 15// insert characters in a textarea or text input field 16// special characters are enclosed in {}; use {{} for the { character itself 17// documentation: http://bililite.com/blog/2008/08/20/the-fnsendkeys-plugin/ 18// Version: 2.0 19// Copyright (c) 2010 Daniel Wachsstock 20// MIT license: 21// Permission is hereby granted, free of charge, to any person 22// obtaining a copy of this software and associated documentation 23// files (the "Software"), to deal in the Software without 24// restriction, including without limitation the rights to use, 25// copy, modify, merge, publish, distribute, sublicense, and/or sell 26// copies of the Software, and to permit persons to whom the 27// Software is furnished to do so, subject to the following 28// conditions: 29// 30// The above copyright notice and this permission notice shall be 31// included in all copies or substantial portions of the Software. 32// 33// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40// OTHER DEALINGS IN THE SOFTWARE. 41 42;(function($, undefined){ 43 "use strict"; 44 45 $.simulate.prototype.quirks = $.simulate.prototype.quirks || {}; 46 47 $.extend($.simulate.prototype.quirks, 48 49 /** 50 * @lends $.simulate.prototype.quirks 51 */ 52 { 53 /** 54 * When simulating with delay in non-input elements, 55 * all spaces are simulated at the end of the sequence instead 56 * of the correct position. 57 * @see {@link https://github.com/j-ulrich/jquery-simulate-ext/issues/6|issues #6} 58 */ 59 delayedSpacesInNonInputGlitchToEnd: undefined 60 61 }); 62 63 $.extend($.simulate.prototype, 64 65 /** 66 * @lends $.simulate.prototype 67 */ 68 { 69 70 /** 71 * Simulates sequencial key strokes. 72 * 73 * @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/key-sequence.md 74 * @public 75 * @author Daniel Wachsstock, julrich 76 * @since 1.0 77 */ 78 simulateKeySequence: function() { 79 var target = this.target, 80 $target = $(target), 81 opts = $.extend({ 82 sequence: "", 83 triggerKeyEvents: true, 84 delay: 0, 85 callback: undefined 86 }, this.options), 87 sequence = opts.sequence; 88 89 opts.delay = parseInt(opts.delay,10); 90 91 var localkeys = {}; 92 93 // Fix for #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6) 94 if ($.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd && !$target.is('input,textarea')) { 95 $.extend(localkeys, { 96 ' ': function(rng, s, opts) { 97 var internalOpts = $.extend({}, opts, { 98 triggerKeyEvents: false, 99 delay: 0, 100 callback: undefined 101 }); 102 $.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '\xA0', internalOpts); 103 $.simulate.prototype.simulateKeySequence.defaults['{leftarrow}'](rng, s, internalOpts); 104 $.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, s, opts); 105 $.simulate.prototype.simulateKeySequence.defaults['{del}'](rng, s, internalOpts); 106 } 107 }); 108 } 109 110 $.extend(localkeys, opts, $target.data('simulate-keySequence')); // allow for element-specific key functions 111 112 // most elements to not keep track of their selection when they lose focus, so we have to do it for them 113 var rng = $.data (target, 'simulate-keySequence.selection'); 114 if (!rng){ 115 rng = bililiteRange(target).bounds('selection'); 116 $.data(target, 'simulate-keySequence.selection', rng); 117 $target.bind('mouseup.simulate-keySequence', function(){ 118 // we have to update the saved range. The routines here update the bounds with each press, but actual keypresses and mouseclicks do not 119 $.data(target, 'simulate-keySequence.selection').bounds('selection'); 120 }).bind('keyup.simulate-keySequence', function(evt){ 121 // restore the selection if we got here with a tab (a click should select what was clicked on) 122 if (evt.which === 9){ 123 // there's a flash of selection when we restore the focus, but I don't know how to avoid that. 124 $.data(target, 'simulate-keySequence.selection').select(); 125 }else{ 126 $.data(target, 'simulate-keySequence.selection').bounds('selection'); 127 } 128 }); 129 }
130 target.focus(); 131 if (typeof sequence === 'undefined') { // no string, so we just set up the event handlers 132 return; 133 } 134 sequence = sequence.replace(/\n/g, '{enter}'); // turn line feeds into explicit break insertions 135 136 /** 137 * Informs the rest of the world that the sequences is finished. 138 * @fires simulate-keySequence 139 * @requires target 140 * @requires sequence 141 * @requires opts 142 * @inner 143 * @author julrich 144 * @since 1.0 145 */ 146 function sequenceFinished() { 147 $target.trigger({type: 'simulate-keySequence', sequence: sequence}); 148 if ($.isFunction(opts.callback)) { 149 opts.callback.apply(target, [{ 150 sequence: sequence 151 }]); 152 } 153 } 154 155 /** 156 * Simulates the key stroke for one character (or special sequence) and sleeps for 157 * <code>opts.delay</code> milliseconds. 158 * @requires lastTime 159 * @requires now() 160 * @requires tokenRegExp 161 * @requires opts 162 * @requires rng 163 * @inner 164 * @author julrich 165 * @since 1.0 166 */ 167 function processNextToken() { 168 var timeElapsed = now() - lastTime; // Work-around for Firefox "bug": setTimeout can fire before the timeout 169 if (timeElapsed >= opts.delay) { 170 var match = tokenRegExp.exec(sequence); 171 if ( match !== null ) { 172 var s = match[0]; 173 (localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts); 174 setTimeout(processNextToken, opts.delay); 175 } 176 else { 177 sequenceFinished(); 178 } 179 lastTime = now(); 180 } 181 else { 182 setTimeout(processNextToken, opts.delay - timeElapsed); 183 } 184 } 185 186 if (!opts.delay || opts.delay <= 0) { 187 // Run as fast as possible 188 sequence.replace(/\{[^}]*\}|[^{]+/g, function(s){ 189 (localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts); 190 }); 191 sequenceFinished(); 192 } 193 else { 194 var tokenRegExp = /\{[^}]*\}|[^{]/g; // This matches curly bracket expressions or single characters 195 var now = Date.now || function() { return new Date().getTime(); }, 196 lastTime = now(); 197 198 processNextToken(); 199 } 200 201 } 202 }); 203 204 $.extend($.simulate.prototype.simulateKeySequence.prototype, 205 206 /** 207 * @lends $.simulate.prototype.simulateKeySequence.prototype 208 */ 209 { 210 211 /** 212 * Maps special character char codes to IE key codes (covers IE and Webkit) 213 * @author julrich 214 * @since 1.0 215 */ 216 IEKeyCodeTable: { 217 33: 49, // ! -> 1 218 64: 50, // @ -> 2 219 35: 51, // # -> 3 220 36: 52, // $ -> 4 221 37: 53, // % -> 5 222 94: 54, // ^ -> 6 223 38: 55, // & -> 7 224 42: 56, // * -> 8 225 40: 57, // ( -> 9 226 41: 48, // ) -> 0 227 228 59: 186, // ; -> 186 229 58: 186, // : -> 186 230 61: 187, // = -> 187 231 43: 187, // + -> 187 232 44: 188, // , -> 188 233 60: 188, // < -> 188 234 45: 189, // - -> 189 235 95: 189, // _ -> 189 236 46: 190, // . -> 190 237 62: 190, // > -> 190 238 47: 191, // / -> 191 239 63: 191, // ? -> 191 240 96: 192, // ` -> 192 241 126: 192, // ~ -> 192 242 91: 219, // [ -> 219 243 123: 219, // { -> 219 244 92: 220, // \ -> 220 245 124: 220, // | -> 220 246 93: 221, // ] -> 221 247 125: 221, // } -> 221 248 39: 222, // ' -> 222 249 34: 222 // " -> 222 250 }, 251 252 /** 253 * Tries to convert character codes to key codes. 254 * @param {Numeric} character - A character code 255 * @returns {Numeric} The key code corresponding to the given character code, 256 * based on the key code table of InternetExplorer. If no corresponding key code 257 * could be found (which will be the case for all special characters except the common 258 * ones), the character code itself is returned. However, <code>keyCode === charCode</code> 259 * does not imply that no key code was found because some key codes are identical to the 260 * character codes (e.g. for uppercase characters). 261 * @requires $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable 262 * @see $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable 263 * @author julrich 264 * @since 1.0 265 */
266 charToKeyCode: function(character) { 267 var specialKeyCodeTable = $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable; 268 var charCode = character.charCodeAt(0); 269 270 if (charCode >= 64 && charCode <= 90 || charCode >= 48 && charCode <= 57) { 271 // A-Z and 0-9 272 return charCode; 273 } 274 else if (charCode >= 97 && charCode <= 122) { 275 // a-z -> A-Z 276 return character.toUpperCase().charCodeAt(0); 277 } 278 else if (specialKeyCodeTable[charCode] !== undefined) { 279 return specialKeyCodeTable[charCode]; 280 } 281 else { 282 return charCode; 283 } 284 } 285 }); 286 287 // add the functions publicly so they can be overridden 288 $.simulate.prototype.simulateKeySequence.defaults = { 289 290 /** 291 * Simulates key strokes of "normal" characters (i.e. non-special sequences). 292 * @param {Object} rng - bililiteRange object of the simulation target element. 293 * @param {String} s - String of (simple) characters to be simulated. 294 * @param {Object} opts - The key-sequence options. 295 * @author Daniel Wachsstock, julrich 296 * @since 1.0 297 */ 298 simplechar: function (rng, s, opts){ 299 rng.text(s, 'end'); 300 if (opts.triggerKeyEvents) { 301 for (var i =0; i < s.length; i += 1){ 302 var charCode = s.charCodeAt(i); 303 var keyCode = $.simulate.prototype.simulateKeySequence.prototype.charToKeyCode(s.charAt(i)); 304 // a bit of cheating: rng._el is the element associated with rng. 305 $(rng._el).simulate('keydown', {keyCode: keyCode}); 306 $(rng._el).simulate('keypress', {keyCode: charCode, which: charCode, charCode: charCode}); 307 $(rng._el).simulate('keyup', {keyCode: keyCode}); 308 } 309 } 310 }, 311 312 /** 313 * Simulates key strokes of a curly opening bracket. 314 * @param {Object} rng - bililiteRange object of the simulation target element. 315 * @param {String} s - Ignored. 316 * @param {Object} opts - The key-sequence options. 317 * @author Daniel Wachsstock, julrich 318 * @since 1.0 319 */ 320 '{{}': function (rng, s, opts){ 321 $.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '{', opts); 322 }, 323 324 /** 325 * Simulates hitting the enter button. 326 * @param {Object} rng - bililiteRange object of the simulation target element. 327 * @param {String} s - Ignored. 328 * @param {Object} opts - The key-sequence options. 329 * @author Daniel Wachsstock, julrich 330 * @since 1.0 331 */ 332 '{enter}': function (rng, s, opts){ 333 rng.insertEOL(); 334 rng.select(); 335 if (opts.triggerKeyEvents === true) { 336 $(rng._el).simulate('keydown', {keyCode: 13}); 337 $(rng._el).simulate('keypress', {keyCode: 13, which: 13, charCode: 13}); 338 $(rng._el).simulate('keyup', {keyCode: 13}); 339 } 340 }, 341 342 /** 343 * Simulates hitting the backspace button. 344 * @param {Object} rng - bililiteRange object of the simulation target element. 345 * @param {String} s - Ignored. 346 * @param {Object} opts - The key-sequence options. 347 * @author Daniel Wachsstock, julrich 348 * @since 1.0 349 */ 350 '{backspace}': function (rng, s, opts){ 351 var b = rng.bounds(); 352 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 353 rng.text('', 'end'); // delete the characters and update the selection 354 if (opts.triggerKeyEvents === true) { 355 $(rng._el).simulate('keydown', {keyCode: 8}); 356 $(rng._el).simulate('keyup', {keyCode: 8}); 357 } 358 }, 359 360 /** 361 * Simulates hitting the delete button. 362 * @param {Object} rng - bililiteRange object of the simulation target element. 363 * @param {String} s - Ignored. 364 * @param {Object} opts - The key-sequence options. 365 * @author Daniel Wachsstock, julrich 366 * @since 1.0 367 */ 368 '{del}': function (rng, s, opts){ 369 var b = rng.bounds(); 370 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 371 rng.text('', 'end'); // delete the characters and update the selection 372 if (opts.triggerKeyEvents === true) { 373 $(rng._el).simulate('keydown', {keyCode: 46}); 374 $(rng._el).simulate('keyup', {keyCode: 46}); 375 } 376 }, 377 378 /** 379 * Simulates hitting the right arrow button. 380 * @param {Object} rng - bililiteRange object of the simulation target element. 381 * @param {String} s - Ignored. 382 * @param {Object} opts - The key-sequence options. 383 * @author Daniel Wachsstock, julrich 384 * @since 1.0 385 */ 386 '{rightarrow}': function (rng, s, opts){ 387 var b = rng.bounds(); 388 if (b[0] === b[1]) { b[1] += 1; } // no characters selected; it's just an insertion point. Move to the right 389 rng.bounds([b[1], b[1]]).select(); 390 if (opts.triggerKeyEvents === true) { 391 $(rng._el).simulate('keydown', {keyCode: 39}); 392 $(rng._el).simulate('keyup', {keyCode: 39}); 393 } 394 }, 395 396 /** 397 * Simulates hitting the left arrow button. 398 * @param {Object} rng - bililiteRange object of the simulation target element. 399 * @param {String} s - Ignored. 400 * @param {Object} opts - The key-sequence options. 401 * @author Daniel Wachsstock, julrich 402 * @since 1.0 403 */ 404 '{leftarrow}': function (rng, s, opts){ 405 var b = rng.bounds(); 406 if (b[0] === b[1]) { b[0] -= 1; } // no characters selected; it's just an insertion point. Move to the left 407 rng.bounds([b[0], b[0]]).select(); 408 if (opts.triggerKeyEvents === true) { 409 $(rng._el).simulate('keydown', {keyCode: 37}); 410 $(rng._el).simulate('keyup', {keyCode: 37}); 411 } 412 }, 413 414 /** 415 * Selects all characters in the target element. 416 * @param {Object} rng - bililiteRange object of the simulation target element. 417 * @author Daniel Wachsstock, julrich 418 * @since 1.0 419 */ 420 '{selectall}' : function (rng){ 421 rng.bounds('all').select(); 422 } 423 }; 424 425 426 427 428 //####### Quirk detection ####### 429 if ($.simulate.ext_disableQuirkDetection !== true) { // Fixes issue #9 (https://github.com/j-ulrich/jquery-simulate-ext/issues/9) 430 $(document).ready(function() { 431 // delayedSpacesInNonInputGlitchToEnd 432 // See issues #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6) 433 /* Append a div to the document (bililiteRange needs the element to be in the document), simulate 434 * a delayed sequence containing a space in the middle and check if the space moves to the end. 435 */
436 var testDiv = $('<div/>').css({height: 1, width: 1, position: 'absolute', left: -1000, top: -1000}).appendTo('body'); 437 testDiv.simulate('key-sequence', {sequence: '\xA0 \xA0', delay:1, callback: function() { 438 $.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd = (testDiv.text().indexOf(' ') > 1); 439 testDiv.remove(); 440 }}); 441 }); 442 } 443 444})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.