PluginProbe ʕ •ᴥ•ʔ
Redux Framework / 4.3.4
Redux Framework v4.3.4
4.5.13 trunk 4.3.0 4.3.1 4.3.10 4.3.11 4.3.12 4.3.13 4.3.14 4.3.15 4.3.16 4.3.17 4.3.18 4.3.19 4.3.2 4.3.20 4.3.21 4.3.22 4.3.24 4.3.25 4.3.26 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.4.10 4.4.11 4.4.12 4.4.13 4.4.14 4.4.15 4.4.16 4.4.17 4.4.18 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1 4.5.10 4.5.11 4.5.2 4.5.3 4.5.4 4.5.6 4.5.7 4.5.8 4.5.9
redux-framework / redux-core / assets / js / redux-vendors.js
redux-framework / redux-core / assets / js Last commit date
media 4 years ago redux 4 years ago vendor 4 years ago index.php 5 years ago redux-vendors.js 5 years ago redux-vendors.min.js 5 years ago redux.js 4 years ago redux.min.js 4 years ago
redux-vendors.js
1428 lines
1 // jscs:disable
2 // jshint ignore: start
3
4 /*!
5 * jQuery Cookie Plugin v1.4.1
6 * https://github.com/carhartl/jquery-cookie
7 *
8 * Copyright 2006, 2014 Klaus Hartl
9 * Released under the MIT license
10 */
11 (function( factory ) {
12 if ( typeof define === 'function' && define.amd ) {
13 // AMD (Register as an anonymous module)
14 define( ['jquery'], factory );
15 } else if ( typeof exports === 'object' ) {
16 // Node/CommonJS
17 module.exports = factory( require( 'jquery' ) );
18 } else {
19 // Browser globals
20 factory( jQuery );
21 }
22 }( function( $ ) {
23
24 var pluses = /\+/g;
25
26 function encode( s ) {
27 return config.raw ? s : encodeURIComponent( s );
28 }
29
30 function decode( s ) {
31 return config.raw ? s : decodeURIComponent( s );
32 }
33
34 function stringifyCookieValue( value ) {
35 return encode( config.json ? JSON.stringify( value ) : String( value ) );
36 }
37
38 function parseCookieValue( s ) {
39 if ( s.indexOf( '"' ) === 0 ) {
40 // This is a quoted cookie as according to RFC2068, unescape...
41 s = s.slice( 1, - 1 ).replace( /\\"/g, '"' ).replace( /\\\\/g, '\\' );
42 }
43
44 try {
45 // Replace server-side written pluses with spaces.
46 // If we can't decode the cookie, ignore it, it's unusable.
47 // If we can't parse the cookie, ignore it, it's unusable.
48 s = decodeURIComponent( s.replace( pluses, ' ' ) );
49 return config.json ? JSON.parse( s ) : s;
50 } catch ( e ) {
51 }
52 }
53
54 function read( s, converter ) {
55 var value = config.raw ? s : parseCookieValue( s );
56 return $.isFunction( converter ) ? converter( value ) : value;
57 }
58
59 var config = $.cookie = function( key, value, options ) {
60
61 // Write
62
63 if ( arguments.length > 1 && ! $.isFunction( value ) ) {
64 options = $.extend( {}, config.defaults, options );
65
66 if ( typeof options.expires === 'number' ) {
67 var days = options.expires, t = options.expires = new Date();
68 t.setMilliseconds( t.getMilliseconds() + days * 864e+5 );
69 }
70
71 return (document.cookie = [encode( key ), '=', stringifyCookieValue( value ), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
72 options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : ''].join( '' ));
73 }
74
75 // Read
76
77 var result = key ? undefined : {}, // To prevent the for loop in the first place assign an empty array
78 // in case there are no cookies at all. Also prevents odd result when
79 // calling $.cookie().
80 cookies = document.cookie ? document.cookie.split( '; ' ) : [], i = 0, l = cookies.length;
81
82 for ( ; i < l; i ++ ) {
83 var parts = cookies[i].split( '=' ), name = decode( parts.shift() ), cookie = parts.join( '=' );
84
85 if ( key === name ) {
86 // If second argument (value) is a function it's a converter...
87 result = read( cookie, value );
88 break;
89 }
90
91 // Prevent storing a cookie that we couldn't decode.
92 if ( ! key && (cookie = read( cookie )) !== undefined ) {
93 result[name] = cookie;
94 }
95 }
96
97 return result;
98 };
99
100 config.defaults = {};
101
102 $.removeCookie = function( key, options ) {
103 // Must not alter options, thus extending a fresh object...
104 $.cookie( key, '', $.extend( {}, options, {expires: - 1} ) );
105 return ! $.cookie( key );
106 };
107
108 } ));
109
110 // jscs:disable
111 // jshint ignore: start
112
113 /********************************************************************
114 * Limit the characters that may be entered in a text field
115 * Common options: alphanumeric, alphabetic or numeric
116 * Kevin Sheedy, 2012
117 * http://github.com/KevinSheedy/jquery.alphanum
118 *********************************************************************/
119
120 (function( $ ) {
121 // API ///////////////////////////////////////////////////////////////////
122 $.fn.alphanum = function( settings ) {
123
124 var combinedSettings = getCombinedSettingsAlphaNum( settings );
125
126 var $collection = this;
127
128 setupEventHandlers( $collection, trimAlphaNum, combinedSettings );
129
130 return this;
131 };
132
133 $.fn.alpha = function( settings ) {
134
135 var defaultAlphaSettings = getCombinedSettingsAlphaNum( "alpha" );
136 var combinedSettings = getCombinedSettingsAlphaNum( settings, defaultAlphaSettings );
137
138 var $collection = this;
139
140 setupEventHandlers( $collection, trimAlphaNum, combinedSettings );
141
142 return this;
143 };
144
145 $.fn.numeric = function( settings ) {
146
147 var combinedSettings = getCombinedSettingsNum( settings );
148 var $collection = this;
149
150 setupEventHandlers( $collection, trimNum, combinedSettings );
151
152 $collection.on(
153 'blur',
154 function() {
155 numericField_Blur( this, settings );
156 }
157 );
158
159 return this;
160 };
161
162 // End of API /////////////////////////////////////////////////////////////
163
164 // Start Settings ////////////////////////////////////////////////////////
165
166 var DEFAULT_SETTINGS_ALPHANUM = {
167 allow: '', // Allow extra characters
168 disallow: '', // Disallow extra characters
169 allowSpace: true, // Allow the space character
170 allowNumeric: true, // Allow digits 0-9
171 allowUpper: true, // Allow upper case characters
172 allowLower: true, // Allow lower case characters
173 allowCaseless: true, // Allow characters that don't have both upper & lower variants - eg Arabic or Chinese
174 allowLatin: true, // a-z A-Z
175 allowOtherCharSets: true, // eg �, �, Arabic, Chinese etc
176 maxLength: NaN // eg Max Length
177 }
178
179 var DEFAULT_SETTINGS_NUM = {
180 allowPlus: false, // Allow the + sign
181 allowMinus: true, // Allow the - sign
182 allowThouSep: true, // Allow the thousands separator, default is the comma eg 12,000
183 allowDecSep: true, // Allow the decimal separator, default is the fullstop eg 3.141
184 allowLeadingSpaces: false, maxDigits: NaN, // The max number of digits
185 maxDecimalPlaces: NaN, // The max number of decimal places
186 maxPreDecimalPlaces: NaN, // The max number digits before the decimal point
187 max: NaN, // The max numeric value allowed
188 min: NaN // The min numeric value allowed
189 }
190
191 // Some pre-defined groups of settings for convenience
192 var CONVENIENCE_SETTINGS_ALPHANUM = {
193 "alpha": {
194 allowNumeric: false
195 }, "upper": {
196 allowNumeric: false, allowUpper: true, allowLower: false, allowCaseless: true
197 }, "lower": {
198 allowNumeric: false, allowUpper: false, allowLower: true, allowCaseless: true
199 }
200 };
201
202 // Some pre-defined groups of settings for convenience
203 var CONVENIENCE_SETTINGS_NUMERIC = {
204 "integer": {
205 allowPlus: false, allowMinus: true, allowThouSep: false, allowDecSep: false
206 }, "positiveInteger": {
207 allowPlus: false, allowMinus: false, allowThouSep: false, allowDecSep: false
208 }
209 };
210
211 var BLACKLIST = getBlacklistAscii() + getBlacklistNonAscii();
212 var THOU_SEP = ",";
213 var DEC_SEP = ".";
214 var DIGITS = getDigitsMap();
215 var LATIN_CHARS = getLatinCharsSet();
216
217 // Return the blacklisted special chars that are encodable using 7-bit ascii
218 function getBlacklistAscii() {
219 var blacklist = '!@#$%^&*()+=[]\\\';,/{}|":<>?~`.-_';
220 blacklist += " "; // 'Space' is on the blacklist but can be enabled using the 'allowSpace' config entry
221 return blacklist;
222 }
223
224 // Return the blacklisted special chars that are NOT encodable using 7-bit ascii
225 // We want this .js file to be encoded using 7-bit ascii so it can reach the widest possible audience
226 // Higher order chars must be escaped eg "\xAC"
227 // Not too worried about comments containing higher order characters for now (let's wait and see if it becomes a problem)
228 function getBlacklistNonAscii() {
229 var blacklist = "\xAC" //
230 + "\u20AC" //
231 + "\xA3" //
232 + "\xA6" //
233 ;
234 return blacklist;
235 }
236
237 // End Settings ////////////////////////////////////////////////////////
238
239 // Implementation details go here ////////////////////////////////////////////////////////
240
241 function setupEventHandlers( $textboxes, trimFunction, settings ) {
242
243 $textboxes.each( function() {
244
245 var $textbox = $( this );
246
247 $textbox.on( "keyup change paste", function( e ) {
248
249 var pastedText = "";
250
251 if ( e.originalEvent && e.originalEvent.clipboardData && e.originalEvent.clipboardData.getData ) pastedText = e.originalEvent.clipboardData.getData( "text/plain" )
252
253 // setTimeout is necessary for handling the 'paste' event
254 setTimeout( function() {
255 trimTextbox( $textbox, trimFunction, settings, pastedText );
256 }, 0 );
257 } );
258
259 $textbox.on( "keypress", function( e ) {
260
261 // Determine which key is pressed.
262 // If it's a control key, then allow the event's default action to occur eg backspace, tab
263 var charCode = ! e.charCode ? e.which : e.charCode;
264 if ( isControlKey( charCode ) || e.ctrlKey || e.metaKey ) // cmd on MacOS
265 return;
266
267 var newChar = String.fromCharCode( charCode );
268
269 // Determine if some text was selected / highlighted when the key was pressed
270 var selectionObject = $textbox.selection();
271 var start = selectionObject.start;
272 var end = selectionObject.end;
273
274 var textBeforeKeypress = $textbox.val();
275
276 // The new char may be inserted:
277 // 1) At the start
278 // 2) In the middle
279 // 3) At the end
280 // 4) User highlights some text and then presses a key which would replace the highlighted text
281 //
282 // Here we build the string that would result after the keypress.
283 // If the resulting string is invalid, we cancel the event.
284 // Unfortunately, it isn't enough to just check if the new char is valid because some chars
285 // are position sensitive eg the decimal point '.'' or the minus sign '-'' are only valid in certain positions.
286 var potentialTextAfterKeypress = textBeforeKeypress.substring( 0, start ) + newChar + textBeforeKeypress.substring( end );
287 var validatedText = trimFunction( potentialTextAfterKeypress, settings );
288
289 // If the keypress would cause the textbox to contain invalid characters, then cancel the keypress event
290 if ( validatedText != potentialTextAfterKeypress ) e.preventDefault();
291 } );
292 } );
293
294 }
295
296 // Ensure the text is a valid number when focus leaves the textbox
297 // This catches the case where a user enters '-' or '.' without entering any digits
298 function numericField_Blur( inputBox, settings ) {
299 var fieldValueNumeric = parseFloat( $( inputBox ).val() );
300 var $inputBox = $( inputBox );
301
302 if ( isNaN( fieldValueNumeric ) ) {
303 $inputBox.val( "" );
304 return;
305 }
306
307 if ( isNumeric( settings.min ) && fieldValueNumeric < settings.min ) $inputBox.val( "" );
308
309 if ( isNumeric( settings.max ) && fieldValueNumeric > settings.max ) $inputBox.val( "" );
310 }
311
312 function isNumeric( value ) {
313 return ! isNaN( value );
314 }
315
316 function isControlKey( charCode ) {
317
318 if ( charCode >= 32 ) return false;
319 if ( charCode == 10 ) return false;
320 if ( charCode == 13 ) return false;
321
322 return true;
323 }
324
325 // One way to prevent a character being entered is to cancel the keypress event.
326 // However, this gets messy when you have to deal with things like copy paste which isn't a keypress.
327 // Which event gets fired first, keypress or keyup? What about IE6 etc etc?
328 // Instead, it's easier to allow the 'bad' character to be entered and then to delete it immediately after.
329
330 function trimTextbox( $textBox, trimFunction, settings, pastedText ) {
331
332 var inputString = $textBox.val();
333
334 if ( inputString == "" && pastedText.length > 0 ) inputString = pastedText;
335
336 var outputString = trimFunction( inputString, settings );
337
338 if ( inputString == outputString ) return;
339
340 var caretPos = $textBox.alphanum_caret();
341
342 $textBox.val( outputString );
343
344 //Reset the caret position
345 if ( inputString.length == (outputString.length + 1) ) $textBox.alphanum_caret( caretPos - 1 ); else $textBox.alphanum_caret( caretPos );
346 }
347
348 function getCombinedSettingsAlphaNum( settings, defaultSettings ) {
349 if ( typeof defaultSettings == "undefined" ) defaultSettings = DEFAULT_SETTINGS_ALPHANUM;
350 var userSettings, combinedSettings = {};
351 if ( typeof settings === "string" ) userSettings = CONVENIENCE_SETTINGS_ALPHANUM[settings]; else if ( typeof settings == "undefined" ) userSettings = {}; else userSettings = settings;
352
353 $.extend( combinedSettings, defaultSettings, userSettings );
354
355 if ( typeof combinedSettings.blacklist == 'undefined' ) combinedSettings.blacklistSet = getBlacklistSet( combinedSettings.allow, combinedSettings.disallow );
356
357 return combinedSettings;
358 }
359
360 function getCombinedSettingsNum( settings ) {
361 var userSettings, combinedSettings = {};
362 if ( typeof settings === "string" ) userSettings = CONVENIENCE_SETTINGS_NUMERIC[settings]; else if ( typeof settings == "undefined" ) userSettings = {}; else userSettings = settings;
363
364 $.extend( combinedSettings, DEFAULT_SETTINGS_NUM, userSettings );
365
366 return combinedSettings;
367 }
368
369 // This is the heart of the algorithm
370 function alphanum_allowChar( validatedStringFragment, Char, settings ) {
371
372 if ( settings.maxLength && validatedStringFragment.length >= settings.maxLength ) return false;
373
374 if ( settings.allow.indexOf( Char ) >= 0 ) return true;
375
376 if ( settings.allowSpace && (Char == " ") ) return true;
377
378 if ( settings.blacklistSet.contains( Char ) ) return false;
379
380 if ( ! settings.allowNumeric && DIGITS[Char] ) return false;
381
382 if ( ! settings.allowUpper && isUpper( Char ) ) return false;
383
384 if ( ! settings.allowLower && isLower( Char ) ) return false;
385
386 if ( ! settings.allowCaseless && isCaseless( Char ) ) return false;
387
388 if ( ! settings.allowLatin && LATIN_CHARS.contains( Char ) ) return false;
389
390 if ( ! settings.allowOtherCharSets ) {
391 if ( DIGITS[Char] || LATIN_CHARS.contains( Char ) ) return true; else return false;
392 }
393
394 return true;
395 }
396
397 function numeric_allowChar( validatedStringFragment, Char, settings ) {
398
399 if ( DIGITS[Char] ) {
400
401 if ( isMaxDigitsReached( validatedStringFragment, settings ) ) return false;
402
403 if ( isMaxPreDecimalsReached( validatedStringFragment, settings ) ) return false;
404
405 if ( isMaxDecimalsReached( validatedStringFragment, settings ) ) return false;
406
407 if ( isGreaterThanMax( validatedStringFragment + Char, settings ) ) return false;
408
409 if ( isLessThanMin( validatedStringFragment + Char, settings ) ) return false;
410
411 return true;
412 }
413
414 if ( settings.allowPlus && Char == '+' && validatedStringFragment == '' ) return true;
415
416 if ( settings.allowMinus && Char == '-' && validatedStringFragment == '' ) return true;
417
418 if ( Char == THOU_SEP && settings.allowThouSep && allowThouSep( validatedStringFragment, Char ) ) return true;
419
420 if ( Char == DEC_SEP ) {
421 // Only one decimal separator allowed
422 if ( validatedStringFragment.indexOf( DEC_SEP ) >= 0 ) return false;
423 if ( settings.allowDecSep ) return true;
424 }
425
426 return false;
427 }
428
429 function countDigits( string ) {
430
431 // Error handling, nulls etc
432 string = string + "";
433
434 // Count the digits
435 return string.replace( /[^0-9]/g, "" ).length;
436 }
437
438 function isMaxDigitsReached( string, settings ) {
439
440 var maxDigits = settings.maxDigits;
441
442 if ( maxDigits == "" || isNaN( maxDigits ) ) return false; // In this case, there is no maximum
443
444 var numDigits = countDigits( string );
445
446 if ( numDigits >= maxDigits ) return true;
447
448 return false;
449 }
450
451 function isMaxDecimalsReached( string, settings ) {
452
453 var maxDecimalPlaces = settings.maxDecimalPlaces;
454
455 if ( maxDecimalPlaces == "" || isNaN( maxDecimalPlaces ) ) return false; // In this case, there is no maximum
456
457 var indexOfDecimalPoint = string.indexOf( DEC_SEP );
458
459 if ( indexOfDecimalPoint == - 1 ) return false;
460
461 var decimalSubstring = string.substring( indexOfDecimalPoint );
462 var numDecimals = countDigits( decimalSubstring );
463
464 if ( numDecimals >= maxDecimalPlaces ) return true;
465
466 return false;
467 }
468
469 function isMaxPreDecimalsReached( string, settings ) {
470
471 var maxPreDecimalPlaces = settings.maxPreDecimalPlaces;
472
473 if ( maxPreDecimalPlaces == "" || isNaN( maxPreDecimalPlaces ) ) return false; // In this case, there is no maximum
474
475 var indexOfDecimalPoint = string.indexOf( DEC_SEP );
476
477 if ( indexOfDecimalPoint >= 0 ) return false;
478
479 var numPreDecimalDigits = countDigits( string );
480
481 if ( numPreDecimalDigits >= maxPreDecimalPlaces ) return true;
482
483 return false;
484 }
485
486 function isGreaterThanMax( numericString, settings ) {
487
488 if ( ! settings.max || settings.max < 0 ) return false;
489
490 var outputNumber = parseFloat( numericString );
491 if ( outputNumber > settings.max ) return true;
492
493 return false;
494 }
495
496 function isLessThanMin( numericString, settings ) {
497
498 if ( ! settings.min || settings.min > 0 ) return false;
499
500 var outputNumber = parseFloat( numericString );
501 if ( outputNumber < settings.min ) return true;
502
503 return false;
504 }
505
506 /********************************
507 * Trims a string according to the settings provided
508 ********************************/
509 function trimAlphaNum( inputString, settings ) {
510
511 if ( typeof inputString != "string" ) return inputString;
512
513 var inChars = inputString.split( "" );
514 var outChars = [];
515 var i = 0;
516 var Char;
517
518 for ( i = 0; i < inChars.length; i ++ ) {
519 Char = inChars[i];
520 var validatedStringFragment = outChars.join( "" );
521 if ( alphanum_allowChar( validatedStringFragment, Char, settings ) ) outChars.push( Char );
522 }
523
524 return outChars.join( "" );
525 }
526
527 function trimNum( inputString, settings ) {
528 if ( typeof inputString != "string" ) return inputString;
529
530 var inChars = inputString.split( "" );
531 var outChars = [];
532 var i = 0;
533 var Char;
534
535 for ( i = 0; i < inChars.length; i ++ ) {
536 Char = inChars[i];
537 var validatedStringFragment = outChars.join( "" );
538 if ( numeric_allowChar( validatedStringFragment, Char, settings ) ) outChars.push( Char );
539 }
540
541 return outChars.join( "" );
542 }
543
544 function removeUpperCase( inputString ) {
545 var charArray = inputString.split( '' );
546 var i = 0;
547 var outputArray = [];
548 var Char;
549
550 for ( i = 0; i < charArray.length; i ++ ) {
551 Char = charArray[i];
552 }
553 }
554
555 function removeLowerCase( inputString ) {
556
557 }
558
559 function isUpper( Char ) {
560 var upper = Char.toUpperCase();
561 var lower = Char.toLowerCase();
562
563 if ( (Char == upper) && (upper != lower) ) return true; else return false;
564 }
565
566 function isLower( Char ) {
567 var upper = Char.toUpperCase();
568 var lower = Char.toLowerCase();
569
570 if ( (Char == lower) && (upper != lower) ) return true; else return false;
571 }
572
573 function isCaseless( Char ) {
574 if ( Char.toUpperCase() == Char.toLowerCase() ) return true; else return false;
575 }
576
577 function getBlacklistSet( allow, disallow ) {
578
579 var setOfBadChars = new Set( BLACKLIST + disallow );
580 var setOfGoodChars = new Set( allow );
581
582 var blacklistSet = setOfBadChars.subtract( setOfGoodChars );
583
584 return blacklistSet;
585 }
586
587 function getDigitsMap() {
588 var array = "0123456789".split( "" );
589 var map = {};
590 var i = 0;
591 var digit;
592
593 for ( i = 0; i < array.length; i ++ ) {
594 digit = array[i];
595 map[digit] = true;
596 }
597
598 return map;
599 }
600
601 function getLatinCharsSet() {
602 var lower = "abcdefghijklmnopqrstuvwxyz";
603 var upper = lower.toUpperCase();
604 var azAZ = new Set( lower + upper );
605
606 return azAZ;
607 }
608
609 function allowThouSep( currentString, Char ) {
610
611 // Can't start with a THOU_SEP
612 if ( currentString.length == 0 ) return false;
613
614 // Can't have a THOU_SEP anywhere after a DEC_SEP
615 var posOfDecSep = currentString.indexOf( DEC_SEP );
616 if ( posOfDecSep >= 0 ) return false;
617
618 var posOfFirstThouSep = currentString.indexOf( THOU_SEP );
619
620 // Check if this is the first occurrence of a THOU_SEP
621 if ( posOfFirstThouSep < 0 ) return true;
622
623 var posOfLastThouSep = currentString.lastIndexOf( THOU_SEP );
624 var charsSinceLastThouSep = currentString.length - posOfLastThouSep - 1;
625
626 // Check if there has been 3 digits since the last THOU_SEP
627 if ( charsSinceLastThouSep < 3 ) return false;
628
629 var digitsSinceFirstThouSep = countDigits( currentString.substring( posOfFirstThouSep ) );
630
631 // Check if there has been a multiple of 3 digits since the first THOU_SEP
632 if ( (digitsSinceFirstThouSep % 3) > 0 ) return false;
633
634 return true;
635 }
636
637 ////////////////////////////////////////////////////////////////////////////////////
638 // Implementation of a Set
639 ////////////////////////////////////////////////////////////////////////////////////
640 function Set( elems ) {
641 if ( typeof elems == "string" ) this.map = stringToMap( elems ); else this.map = {};
642 }
643
644 Set.prototype.add = function( set ) {
645
646 var newSet = this.clone();
647
648 for ( var key in set.map ) newSet.map[key] = true;
649
650 return newSet;
651 }
652
653 Set.prototype.subtract = function( set ) {
654
655 var newSet = this.clone();
656
657 for ( var key in set.map ) delete newSet.map[key];
658
659 return newSet;
660 }
661
662 Set.prototype.contains = function( key ) {
663 if ( this.map[key] ) return true; else return false;
664 }
665
666 Set.prototype.clone = function() {
667 var newSet = new Set();
668
669 for ( var key in this.map ) newSet.map[key] = true;
670
671 return newSet;
672 }
673
674 ////////////////////////////////////////////////////////////////////////////////////
675
676 function stringToMap( string ) {
677 var map = {};
678 var array = string.split( "" );
679 var i = 0;
680 var Char;
681
682 for ( i = 0; i < array.length; i ++ ) {
683 Char = array[i];
684 map[Char] = true;
685 }
686
687 return map;
688 }
689
690 // Backdoor for testing
691 $.fn.alphanum.backdoorAlphaNum = function( inputString, settings ) {
692 var combinedSettings = getCombinedSettingsAlphaNum( settings );
693
694 return trimAlphaNum( inputString, combinedSettings );
695 };
696
697 $.fn.alphanum.backdoorNumeric = function( inputString, settings ) {
698 var combinedSettings = getCombinedSettingsNum( settings );
699
700 return trimNum( inputString, combinedSettings );
701 };
702
703 $.fn.alphanum.setNumericSeparators = function( settings ) {
704
705 if ( settings.thousandsSeparator.length != 1 ) return;
706
707 if ( settings.decimalSeparator.length != 1 ) return;
708
709 THOU_SEP = settings.thousandsSeparator;
710 DEC_SEP = settings.decimalSeparator;
711 }
712
713 })( jQuery );
714
715 //Include the 3rd party lib: jquery.caret.js
716
717 // Set caret position easily in jQuery
718 // Written by and Copyright of Luke Morton, 2011
719 // Licensed under MIT
720 (function( $ ) {
721 // Behind the scenes method deals with browser
722 // idiosyncrasies and such
723 function caretTo( el, index ) {
724 if ( el.createTextRange ) {
725 var range = el.createTextRange();
726 range.move( "character", index );
727 range.select();
728 } else if ( el.selectionStart != null ) {
729 el.focus();
730 el.setSelectionRange( index, index );
731 }
732 };
733
734 // Another behind the scenes that collects the
735 // current caret position for an element
736
737 // TODO: Get working with Opera
738 function caretPos( el ) {
739 if ( "selection" in document ) {
740 var range = el.createTextRange();
741 try {
742 range.setEndPoint( "EndToStart", document.selection.createRange() );
743 } catch ( e ) {
744 // Catch IE failure here, return 0 like
745 // other browsers
746 return 0;
747 }
748 return range.text.length;
749 } else if ( el.selectionStart != null ) {
750 return el.selectionStart;
751 }
752 };
753
754 // The following methods are queued under fx for more
755 // flexibility when combining with $.fn.delay() and
756 // jQuery effects.
757
758 // Set caret to a particular index
759 $.fn.alphanum_caret = function( index, offset ) {
760 if ( typeof (index) === "undefined" ) {
761 return caretPos( this.get( 0 ) );
762 }
763
764 return this.queue( function( next ) {
765 if ( isNaN( index ) ) {
766 var i = $( this ).val().indexOf( index );
767
768 if ( offset === true ) {
769 i += index.length;
770 } else if ( typeof (offset) !== "undefined" ) {
771 i += offset;
772 }
773
774 caretTo( this, i );
775 } else {
776 caretTo( this, index );
777 }
778
779 next();
780 } );
781 };
782 }( jQuery ));
783
784 /**********************************************************
785 * Selection Library
786 * Used to determine what text is highlighted in the textbox before a key is pressed.
787 * http://donejs.com/docs.html#!jQuery.fn.selection
788 * https://github.com/jupiterjs/jquerymx/blob/master/dom/selection/selection.js
789 ***********************************************************/
790 (function( $ ) {
791 var convertType = function( type ) {
792 return type.replace( /([a-z])([a-z]+)/gi, function( all, first, next ) {
793 return first + next.toLowerCase();
794 } ).replace( /_/g, "" );
795 }, reverse = function( type ) {
796 return type.replace( /^([a-z]+)_TO_([a-z]+)/i, function( all, first, last ) {
797 return last + "_TO_" + first;
798 } );
799 }, getWindow = function( element ) {
800 return element ? element.ownerDocument.defaultView || element.ownerDocument.parentWindow : window;
801 }, // A helper that uses range to abstract out getting the current start and endPos.
802 getElementsSelection = function( el, win ) {
803 var current = $.Range.current( el ).clone(), entireElement = $.Range( el ).select( el );
804
805 if ( ! current.overlaps( entireElement ) ) {
806 return null;
807 }
808 // we need to check if it starts before our element ...
809 if ( current.compare( "START_TO_START", entireElement ) < 1 ) {
810 var startPos = 0;
811 // we should move current ...
812 current.move( "START_TO_START", entireElement );
813 } else {
814 var fromElementToCurrent = entireElement.clone();
815 fromElementToCurrent.move( "END_TO_START", current );
816
817 startPos = fromElementToCurrent.toString().length;
818 }
819
820 // now we need to make sure current isn't to the right of us ...
821 var endPos;
822
823 if ( current.compare( "END_TO_END", entireElement ) >= 0 ) {
824 endPos = entireElement.toString().length;
825 } else {
826 endPos = startPos + current.toString().length;
827 }
828
829 return {
830 start: startPos, end: endPos
831 };
832 }, getSelection = function( el ) {
833 // use selectionStart if we can.
834 var win = getWindow( el );
835
836 if ( el.selectionStart !== undefined ) {
837 if ( document.activeElement && document.activeElement !== el && el.selectionStart === el.selectionEnd && el.selectionStart === 0 ) {
838 return {start: el.value.length, end: el.value.length};
839 }
840
841 return {start: el.selectionStart, end: el.selectionEnd};
842 } else if ( win.getSelection ) {
843 return getElementsSelection( el, win );
844 } else {
845 try {
846 //try 2 different methods that work differently
847 // one should only work for input elements, but sometimes doesn't
848 // I don't know why this is, or what to detect
849 if ( el.nodeName.toLowerCase() === 'input' ) {
850 var real = getWindow( el ).document.selection.createRange(), r = el.createTextRange();
851
852 r.setEndPoint( "EndToStart", real );
853
854 var start = r.text.length;
855
856 return {
857 start: start, end: start + real.text.length
858 };
859 } else {
860 var res = getElementsSelection( el, win );
861 if ( ! res ) {
862 return res;
863 }
864
865 // we have to clean up for ie's textareas
866 var current = $.Range.current().clone(), r2 = current.clone().collapse().range,
867 r3 = current.clone().collapse( false ).range;
868
869 r2.moveStart( 'character', - 1 );
870 r3.moveStart( 'character', - 1 );
871
872 // if we aren't at the start, but previous is empty, we are at start of newline
873 if ( res.startPos !== 0 && r2.text === "" ) {
874 res.startPos += 2;
875 }
876
877 // do a similar thing for the end of the textarea
878 if ( res.endPos !== 0 && r3.text === "" ) {
879 res.endPos += 2;
880 }
881
882 return res;
883 }
884 } catch ( e ) {
885 return {start: el.value.length, end: el.value.length};
886 }
887 }
888 }, select = function( el, start, end ) {
889 var win = getWindow( el );
890
891 if ( el.setSelectionRange ) {
892 if ( end === undefined ) {
893 el.focus();
894 el.setSelectionRange( start, start );
895 } else {
896 el.select();
897 el.selectionStart = start;
898 el.selectionEnd = end;
899 }
900 } else if ( el.createTextRange ) {
901 //el.focus();
902 var r = el.createTextRange();
903 r.moveStart( 'character', start );
904 end = end || start;
905 r.moveEnd( 'character', end - el.value.length );
906
907 r.select();
908 } else if ( win.getSelection ) {
909 var doc = win.document, sel = win.getSelection(), range = doc.createRange(),
910 ranges = [start, end !== undefined ? end : start];
911 getCharElement( [el], ranges );
912 range.setStart( ranges[0].el, ranges[0].count );
913 range.setEnd( ranges[1].el, ranges[1].count );
914
915 // removeAllRanges is suprisingly necessary for webkit ... BOOO!
916 sel.removeAllRanges();
917 sel.addRange( range );
918
919 } else if ( win.document.body.createTextRange ) { //IE's weirdness
920 var range = document.body.createTextRange();
921
922 range.moveToElementText( el );
923 range.collapse();
924 range.moveStart( 'character', start );
925 range.moveEnd( 'character', end !== undefined ? end : start );
926 range.select();
927 }
928 }, /*
929 * If one of the range values is within start and len, replace the range
930 * value with the element and its offset.
931 */
932 replaceWithLess = function( start, len, range, el ) {
933 if ( typeof range[0] === 'number' && range[0] < len ) {
934 range[0] = {
935 el: el, count: range[0] - start
936 };
937 }
938 if ( typeof range[1] === 'number' && range[1] <= len ) {
939 range[1] = {
940 el: el, count: range[1] - start
941 };
942 }
943 }, getCharElement = function( elems, range, len ) {
944 var elem, start;
945
946 len = len || 0;
947
948 for ( var i = 0; elems[i]; i ++ ) {
949 elem = elems[i];
950 // Get the text from text nodes and CDATA nodes
951 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
952 start = len;
953 len += elem.nodeValue.length;
954 //check if len is now greater than what's in counts
955 replaceWithLess( start, len, range, elem );
956 // Traverse everything else, except comment nodes
957 } else if ( elem.nodeType !== 8 ) {
958 len = getCharElement( elem.childNodes, range, len );
959 }
960 }
961
962 return len;
963 };
964
965 $.fn.selection = function( start, end ) {
966 if ( start !== undefined ) {
967 return this.each( function() {
968 select( this, start, end );
969 } );
970 } else {
971 return getSelection( this[0] );
972 }
973 };
974
975 // for testing
976 $.fn.selection.getCharElement = getCharElement;
977 })( jQuery );
978
979 // jscs:disable
980 // jshint ignore: start
981
982 /*
983 * serializeForm
984 * https://github.com/danheberden/serializeForm
985 *
986 * Copyright (c) 2012 Dan Heberden
987 * Licensed under the MIT, GPL licenses.
988 */
989 (function( $ ) {
990 $.fn.serializeForm = function() {
991
992 // don't do anything if we didn't get any elements.
993 if ( this.length < 1 ) {
994 return false;
995 }
996
997 var data = {};
998 var lookup = data; // current reference of data.
999 var selector = ':input[type!="checkbox"][type!="radio"], input:checked';
1000 var parse = function() {
1001
1002 // Ignore disabled elements.
1003 if ( this.disabled ) {
1004 return;
1005 }
1006
1007 // data[a][b] becomes [ data, a, b ].
1008 var named = this.name.replace( /\[([^\]]+)?\]/g, ',$1' ).split( ',' );
1009 var cap = named.length - 1;
1010 var $el = $( this );
1011
1012 // Ensure that only elements with valid `name` properties will be serialized.
1013 if ( named[0] ) {
1014 for ( var i = 0; i < cap; i ++ ) {
1015 // move down the tree - create objects or array if necessary.
1016 lookup = lookup[named[i]] = lookup[named[i]] || ((named[i + 1] === "" || named[i + 1] === '0') ? [] : {});
1017 }
1018
1019 // at the end, push or assign the value.
1020 if ( lookup.length !== undefined ) {
1021 lookup.push( $el.val() );
1022 } else {
1023 lookup[named[cap]] = $el.val();
1024 }
1025
1026 // assign the reference back to root.
1027 lookup = data;
1028 }
1029 };
1030
1031 // first, check for elements passed into this function.
1032 this.filter( selector ).each( parse );
1033
1034 // then parse possible child elements.
1035 this.find( selector ).each( parse );
1036
1037 // return data.
1038 return data;
1039 };
1040 }( jQuery ));
1041
1042 // jscs:disable
1043 // jshint ignore: start
1044
1045 /*
1046 * TypeWatch 3
1047 *
1048 * Examples/Docs: github.com/dennyferra/TypeWatch
1049 *
1050 * Dual licensed under the MIT and GPL licenses:
1051 * http://www.opensource.org/licenses/mit-license.php
1052 * http://www.gnu.org/licenses/gpl.html
1053 */
1054
1055 !function(root, factory) {
1056 if (typeof define === 'function' && define.amd) {
1057 define(['jquery'], factory);
1058 } else if (typeof exports === 'object') {
1059 factory(require('jquery'));
1060 } else {
1061 factory(root.jQuery);
1062 }
1063 }(this, function($) {
1064 'use strict';
1065 $.fn.typeWatch = function(o) {
1066 // The default input types that are supported
1067 var _supportedInputTypes =
1068 ['TEXT', 'TEXTAREA', 'PASSWORD', 'TEL', 'SEARCH', 'URL', 'EMAIL', 'DATETIME', 'DATE', 'MONTH', 'WEEK', 'TIME', 'DATETIME-LOCAL', 'NUMBER', 'RANGE', 'DIV'];
1069
1070 // Options
1071 var options = $.extend({
1072 wait: 750,
1073 callback: function() { },
1074 highlight: true,
1075 captureLength: 2,
1076 allowSubmit: false,
1077 inputTypes: _supportedInputTypes
1078 }, o);
1079
1080 function checkElement(timer, override) {
1081 var value = timer.type === 'DIV'
1082 ? jQuery(timer.el).html()
1083 : jQuery(timer.el).val();
1084
1085 // If has capture length and has changed value
1086 // Or override and has capture length or allowSubmit option is true
1087 // Or capture length is zero and changed value
1088 if ((value.length >= options.captureLength && value != timer.text)
1089 || (override && (value.length >= options.captureLength || options.allowSubmit))
1090 || (value.length == 0 && timer.text))
1091 {
1092 timer.text = value;
1093 timer.cb.call(timer.el, value);
1094 }
1095 };
1096
1097 function watchElement(elem) {
1098 var elementType = (elem.type || elem.nodeName).toUpperCase();
1099 if (jQuery.inArray(elementType, options.inputTypes) >= 0) {
1100
1101 // Allocate timer element
1102 var timer = {
1103 timer: null,
1104 text: (elementType === 'DIV') ? jQuery(elem).html() : jQuery(elem).val(),
1105 cb: options.callback,
1106 el: elem,
1107 type: elementType,
1108 wait: options.wait
1109 };
1110
1111 // Set focus action (highlight)
1112 if (options.highlight && elementType !== 'DIV')
1113 jQuery(elem).focus(function() { this.select(); });
1114
1115 // Key watcher / clear and reset the timer
1116 var startWatch = function(evt) {
1117 var timerWait = timer.wait;
1118 var overrideBool = false;
1119 var evtElementType = elementType;
1120
1121 // If enter key is pressed and not a TEXTAREA or DIV
1122 if (typeof evt.keyCode != 'undefined' && evt.keyCode == 13
1123 && evtElementType !== 'TEXTAREA' && elementType !== 'DIV') {
1124 timerWait = 1;
1125 overrideBool = true;
1126 }
1127
1128 var timerCallbackFx = function() {
1129 checkElement(timer, overrideBool)
1130 }
1131
1132 // Clear timer
1133 clearTimeout(timer.timer);
1134 timer.timer = setTimeout(timerCallbackFx, timerWait);
1135 };
1136
1137 jQuery(elem).on('keydown paste cut input', startWatch);
1138 }
1139 };
1140
1141 // Watch each element
1142 return this.each(function() {
1143 watchElement(this);
1144 });
1145 };
1146 });
1147
1148 // jscs:disable
1149 // jshint ignore: start
1150
1151 /* global console, jsonView */
1152
1153 /*
1154 * ViewJSON
1155 * Version 1.0
1156 * A Google Chrome extension to display JSON in a user-friendly format
1157 *
1158 * This is a chromeified version of the JSONView Firefox extension by Ben Hollis:
1159 * http://jsonview.com
1160 * http://code.google.com/p/jsonview
1161 *
1162 * Also based on the XMLTree Chrome extension by Moonty & alan.stroop
1163 * https://chrome.google.com/extensions/detail/gbammbheopgpmaagmckhpjbfgdfkpadb
1164 *
1165 * port by Jamie Wilkinson (@jamiew) | http://jamiedubs.com | http://github.com/jamiew
1166 * MIT license / copyfree (f) F.A.T. Lab http://fffff.at
1167 * Speed Project Approved: 2h
1168 */
1169
1170 function collapse( evt ) {
1171 var collapser = evt.target;
1172 var target = collapser.parentNode.getElementsByClassName( 'collapsible' );
1173 if ( ! target.length ) {
1174 return;
1175 }
1176 target = target[0];
1177 if ( target.style.display === 'none' ) {
1178 var ellipsis = target.parentNode.getElementsByClassName( 'ellipsis' )[0];
1179 target.parentNode.removeChild( ellipsis );
1180 target.style.display = '';
1181 } else {
1182 target.style.display = 'none';
1183 var ellipsis = document.createElement( 'span' );
1184 ellipsis.className = 'ellipsis';
1185 ellipsis.innerHTML = ' &hellip; ';
1186 target.parentNode.insertBefore( ellipsis, target );
1187 }
1188 collapser.innerHTML = (collapser.innerHTML === '-') ? '+' : '-';
1189 }
1190
1191 function addCollapser( item ) {
1192 // This mainly filters out the root object (which shouldn't be collapsible).
1193 if ( item.nodeName !== 'LI' ) {
1194 return;
1195 }
1196 var collapser = document.createElement( 'div' );
1197 collapser.className = 'collapser';
1198 collapser.innerHTML = '-';
1199 collapser.addEventListener( 'click', collapse, false );
1200 item.insertBefore( collapser, item.firstChild );
1201 }
1202
1203 function jsonView( id, target ) {
1204 this.debug = false;
1205 if ( id.indexOf( '#' ) !== - 1 ) {
1206 this.idType = 'id';
1207 this.id = id.replace( '#', '' );
1208 } else if ( id.indexOf( '.' ) !== - 1 ) {
1209 this.idType = 'class';
1210 this.id = id.replace( '.', '' );
1211 } else {
1212 if ( this.debug ) {
1213 console.log( 'Can\'t find that element' );
1214 }
1215 return;
1216 }
1217
1218 this.data = document.getElementById( this.id ).innerHTML;
1219 if ( typeof (target) !== undefined ) {
1220 if ( target.indexOf( '#' ) !== - 1 ) {
1221 this.targetType = 'id';
1222 this.target = target.replace( '#', '' );
1223 } else if ( id.indexOf( '.' ) !== - 1 ) {
1224 this.targetType = 'class';
1225 this.target = target.replace( '.', '' );
1226 } else {
1227 if ( this.debug ) {
1228 console.log( 'Can\'t find the target element' );
1229 }
1230 return;
1231 }
1232 }
1233 // Note: now using "*.json*" URI matching rather than these page regexes -- save CPU cycles!
1234 // var is_json = /^\s*(\{.*\})\s*$/.test(this.data);
1235 // var is_jsonp = /^.*\(\s*(\{.*\})\s*\)$/.test(this.data);
1236 // if(is_json || is_jsonp){
1237 // Our manifest specifies that we only do URLs matching '.json', so attempt to sanitize any HTML
1238 // added by Chrome's "text/plain" or "text/html" handlers.
1239 if ( /^\<pre.*\>(.*)\<\/pre\>$/.test( this.data ) ) {
1240 if ( this.debug ) {
1241 console.log( 'JSONView: data is wrapped in <pre>...</pre>, stripping HTML...' );
1242 }
1243 this.data = this.data.replace( /<(?:.|\s)*?>/g, '' ); // Aggressively strip HTML.
1244 }
1245 // Test if what remains is JSON or JSONp.
1246 var json_regex = /^\s*([\[\{].*[\}\]])\s*$/; // Ghetto, but it works.
1247 var jsonp_regex = /^[\s\u200B\uFEFF]*([\w$\[\]\.]+)[\s\u200B\uFEFF]*\([\s\u200B\uFEFF]*([\[{][\s\S]*[\]}])[\s\u200B\uFEFF]*\);?[\s\u200B\uFEFF]*$/;
1248 var jsonp_regex2 = /([\[\{][\s\S]*[\]\}])\)/; // more liberal support... this allows us to pass the jsonp.json & jsonp2.json tests.
1249 var is_json = json_regex.test( this.data );
1250 var is_jsonp = jsonp_regex.test( this.data );
1251 if ( this.debug ) {
1252 console.log( 'JSONView: is_json=' + is_json + ' is_jsonp=' + is_jsonp );
1253 }
1254 if ( is_json || is_jsonp ) {
1255 if ( this.debug ) {
1256 console.log( 'JSONView: sexytime!' );
1257 }
1258 // JSONFormatter json->HTML prototype straight from Firefox JSONView
1259 // For reference: http://code.google.com/p/jsonview.
1260 function JSONFormatter() {
1261 // No magic required.
1262 }
1263
1264 JSONFormatter.prototype = {
1265 htmlEncode: function( t ) {
1266 return t != null ? t.toString().replace( /&/g, '&amp;' ).replace( /"/g, '&quot;' ).replace( /</g, '&lt;' ).replace( />/g, '&gt;' ) : '';
1267 }, decorateWithSpan: function( value, className ) {
1268 return '<span class="' + className + '">' + this.htmlEncode( value ) + '</span>';
1269 }, // Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
1270 valueToHTML: function( value ) {
1271 var valueType = typeof value;
1272 var output = '';
1273 if ( value === null ) {
1274 output += this.decorateWithSpan( 'null', 'null' );
1275 } else if ( value && value.constructor === Array ) {
1276 output += this.arrayToHTML( value );
1277 } else if ( valueType === 'object' ) {
1278 output += this.objectToHTML( value );
1279 } else if ( valueType === 'number' ) {
1280 output += this.decorateWithSpan( value, 'num' );
1281 } else if ( valueType === 'string' ) {
1282 if ( /^(http|https):\/\/[^\s]+$/.test( value ) ) {
1283 output += '<a href="' + value + '">' + this.htmlEncode( value ) + '</a>';
1284 } else {
1285 output += this.decorateWithSpan( '"' + value + '"', 'string' );
1286 }
1287 } else if ( valueType === 'boolean' ) {
1288 output += this.decorateWithSpan( value, 'bool' );
1289 }
1290 return output;
1291 }, // Convert an array into an HTML fragment
1292 arrayToHTML: function( json ) {
1293 var output = '[<ul class="array collapsible">';
1294 var hasContents = false;
1295 for ( var prop in json ) {
1296 hasContents = true;
1297 output += '<li>';
1298 output += this.valueToHTML( json[prop] );
1299 output += '</li>';
1300 }
1301 output += '</ul>]';
1302 if ( ! hasContents ) {
1303 output = '[ ]';
1304 }
1305 return output;
1306 }, // Convert a JSON object to an HTML fragment
1307 objectToHTML: function( json ) {
1308 var output = '{<ul class="obj collapsible">';
1309 var hasContents = false;
1310 for ( var prop in json ) {
1311 hasContents = true;
1312 output += '<li>';
1313 output += '<span class="prop">' + this.htmlEncode( prop ) + '</span>: ';
1314 output += this.valueToHTML( json[prop] );
1315 output += '</li>';
1316 }
1317 output += '</ul>}';
1318 if ( ! hasContents ) {
1319 output = '{ }';
1320 }
1321 return output;
1322 }, // Convert a whole JSON object into a formatted HTML document.
1323 jsonToHTML: function( json, callback, uri ) {
1324 var output = '';
1325 if ( callback ) {
1326 output += '<div class="callback">' + callback + ' (</div>';
1327 output += '<div id="json">';
1328 } else {
1329 output += '<div id="json">';
1330 }
1331 output += this.valueToHTML( json );
1332 output += '</div>';
1333 if ( callback ) {
1334 output += '<div class="callback">)</div>';
1335 }
1336 return this.toHTML( output, uri );
1337 }, // Produce an error document for when parsing fails.
1338 errorPage: function( error, data, uri ) {
1339 // var output = '<div id="error">' + this.stringbundle.GetStringFromName('errorParsing') + '</div>';
1340 // output += '<h1>' + this.stringbundle.GetStringFromName('docContents') + ':</h1>';.
1341 var output = '<div id="error">Error parsing JSON: ' + error.message + '</div>';
1342 output += '<h1>' + error.stack + ':</h1>';
1343 output += '<div id="json">' + this.htmlEncode( data ) + '</div>';
1344 return this.toHTML( output, uri + ' - Error' );
1345 }, // Wrap the HTML fragment in a full document. Used by jsonToHTML and errorPage.
1346 toHTML: function( content ) {
1347 return content;
1348 }
1349 };
1350 // Sanitize & output -- all magic from JSONView Firefox.
1351 this.jsonFormatter = new JSONFormatter();
1352 // This regex attempts to match a JSONP structure:
1353 // * Any amount of whitespace (including unicode nonbreaking spaces) between the start of the file and the callback name.
1354 // * Callback name (any valid JavaScript function name according to ECMA-262 Edition 3 spec).
1355 // * Any amount of whitespace (including unicode nonbreaking spaces).
1356 // * Open parentheses.
1357 // * Any amount of whitespace (including unicode nonbreaking spaces).
1358 // * Either { or [, the only two valid characters to start a JSON string.
1359 // * Any character, any number of times.
1360 // * Either } or ], the only two valid closing characters of a JSON string.
1361 // * Any amount of whitespace (including unicode nonbreaking spaces).
1362 // * A closing parenthesis, an optional semicolon, and any amount of whitespace (including unicode nonbreaking spaces) until the end of the file.
1363 // This will miss anything that has comments, or more than one callback, or requires modification before use.
1364 var outputDoc = '';
1365 // text = text.match(jsonp_regex)[1]; .
1366 var cleanData = '', callback = '';
1367 var callback_results = jsonp_regex.exec( this.data );
1368 if ( callback_results && callback_results.length === 3 ) {
1369 if ( this.debug ) {
1370 console.log( 'THIS IS JSONp' );
1371 }
1372 callback = callback_results[1];
1373 cleanData = callback_results[2];
1374 } else {
1375 if ( this.debug ) {
1376 console.log( 'Vanilla JSON' );
1377 }
1378 cleanData = this.data;
1379 }
1380 if ( this.debug ) {
1381 console.log( cleanData );
1382 }
1383 // Covert, and catch exceptions on failure.
1384 try {
1385 // var jsonObj = this.nativeJSON.decode(cleanData); .
1386 var jsonObj = JSON.parse( cleanData );
1387 if ( jsonObj ) {
1388 outputDoc = this.jsonFormatter.jsonToHTML( jsonObj, callback );
1389 } else {
1390 throw 'There was no object!';
1391 }
1392 } catch ( e ) {
1393 if ( this.debug ) {
1394 console.log( e );
1395 }
1396 outputDoc = this.jsonFormatter.errorPage( e, this.data );
1397 }
1398 var links = '<style type="text/css">.jsonViewOutput .prop{font-weight:700;}.jsonViewOutput .null{color:red;}.jsonViewOutput .string{color:green;}.jsonViewOutput .collapser{position:absolute;left:-1em;cursor:pointer;}.jsonViewOutput li{position:relative;}.jsonViewOutput li:after{content:\',\';}.jsonViewOutput li:last-child:after{content:\'\';}.jsonViewOutput #error{-moz-border-radius:8px;border:1px solid #970000;background-color:#F7E8E8;margin:.5em;padding:.5em;}.jsonViewOutput .errormessage{font-family:monospace;}.jsonViewOutput #json{font-family:monospace;font-size:1.1em;}.jsonViewOutput ul{list-style:none;margin:0 0 0 2em;padding:0;}.jsonViewOutput h1{font-size:1.2em;}.jsonViewOutput .callback + #json{padding-left:1em;}.jsonViewOutput .callback{font-family:monospace;color:#A52A2A;}.jsonViewOutput .bool,.jsonViewOutput .num{color:blue;}</style>';
1399 if ( this.targetType !== undefined ) {
1400 this.idType = this.targetType;
1401 this.id = this.target;
1402 }
1403 var el;
1404 if ( this.idType === 'class' ) {
1405 el = document.getElementsByClassName( this.id );
1406 if ( el ) {
1407 el.className += el.className ? ' jsonViewOutput' : 'jsonViewOutput';
1408 el.innerHTML = links + outputDoc;
1409 }
1410 } else if ( this.idType === 'id' ) {
1411 el = document.getElementById( this.id );
1412 if ( el ) {
1413 el.className += el.className ? ' jsonViewOutput' : 'jsonViewOutput';
1414 el.innerHTML = links + outputDoc;
1415 }
1416 el.innerHTML = links + outputDoc;
1417 }
1418 var items = document.getElementsByClassName( 'collapsible' );
1419 var len = items.length;
1420
1421 for ( var i = 0; i < len; i ++ ) {
1422 addCollapser( items[i].parentNode );
1423 }
1424 } else {
1425 // console.log("JSONView: this is not json, not formatting."); .
1426 }
1427 }
1428