redux-vendors.js (46241B)
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 = ' … '; 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, '&' ).replace( /"/g, '"' ).replace( /</g, '<' ).replace( />/g, '>' ) : ''; 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 }