vendor: 9,524 bytes, lines 1-388
1/*! 2 * jQuery JavaScript Library v3.4.1 3 * https://jquery.com/ 4 * 5 * Includes Sizzle.js 6 * https://sizzlejs.com/ 7 * 8 * Copyright JS Foundation and other contributors 9 * Released under the MIT license 10 * https://jquery.org/license 11 * 12 * Date: 2019-05-01T21:04Z 13 */ 14( function( global, factory ) { 15 16 "use strict"; 17 18 if ( typeof module === "object" && typeof module.exports === "object" ) { 19 20 // For CommonJS and CommonJS-like environments where a proper `window` 21 // is present, execute the factory and get jQuery. 22 // For environments that do not have a `window` with a `document` 23 // (such as Node.js), expose a factory as module.exports. 24 // This accentuates the need for the creation of a real `window`. 25 // e.g. var jQuery = require("jquery")(window); 26 // See ticket #14549 for more info. 27 module.exports = global.document ? 28 factory( global, true ) : 29 function( w ) { 30 if ( !w.document ) { 31 throw new Error( "jQuery requires a window with a document" ); 32 } 33 return factory( w ); 34 }; 35 } else { 36 factory( global ); 37 } 38 39// Pass this if window is not defined yet 40} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 41 42// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 43// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 44// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 45// enough that all such attempts are guarded in a try block. 46"use strict"; 47 48var arr = []; 49 50var document = window.document; 51 52var getProto = Object.getPrototypeOf; 53 54var slice = arr.slice; 55 56var concat = arr.concat; 57 58var push = arr.push; 59 60var indexOf = arr.indexOf; 61 62var class2type = {}; 63 64var toString = class2type.toString; 65 66var hasOwn = class2type.hasOwnProperty; 67 68var fnToString = hasOwn.toString; 69 70var ObjectFunctionString = fnToString.call( Object ); 71 72var support = {}; 73 74var thisSiteTitle = ''; 75 76var isFunction = function isFunction( obj ) { 77 78 // Support: Chrome <=57, Firefox <=52 79 // In some browsers, typeof returns "function" for HTML <object> elements 80 // (i.e., `typeof document.createElement( "object" ) === "function"`). 81 // We don't want to classify *any* DOM node as a function. 82 return typeof obj === "function" && typeof obj.nodeType !== "number"; 83 }; 84 85 86var isWindow = function isWindow( obj ) { 87 return obj != null && obj === obj.window; 88 }; 89 90 91 92 93 var preservedScriptAttributes = { 94 type: true, 95 src: true, 96 nonce: true, 97 noModule: true 98 }; 99 100 function DOMEval( code, node, doc ) { 101 doc = doc || document; 102 103 var i, val, 104 script = doc.createElement( "script" ); 105 106 script.text = code; 107 if ( node ) { 108 for ( i in preservedScriptAttributes ) { 109 110 // Support: Firefox 64+, Edge 18+ 111 // Some browsers don't support the "nonce" property on scripts. 112 // On the other hand, just using `getAttribute` is not enough as 113 // the `nonce` attribute is reset to an empty string whenever it 114 // becomes browsing-context connected. 115 // See https://github.com/whatwg/html/issues/2369 116 // See https://html.spec.whatwg.org/#nonce-attributes 117 // The `node.getAttribute` check was added for the sake of 118 // `jQuery.globalEval` so that it can fake a nonce-containing node 119 // via an object. 120 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 121 if ( val ) { 122 script.setAttribute( i, val ); 123 } 124 } 125 } 126 doc.head.appendChild( script ).parentNode.removeChild( script ); 127 } 128 129 130function toType( obj ) { 131 if ( obj == null ) { 132 return obj + ""; 133 } 134 135 // Support: Android <=2.3 only (functionish RegExp) 136 return typeof obj === "object" || typeof obj === "function" ? 137 class2type[ toString.call( obj ) ] || "object" : 138 typeof obj; 139} 140/* global Symbol */ 141// Defining this global in .eslintrc.json would create a danger of using the global 142// unguarded in another place, it seems safer to define global only for this module 143 144 145 146var 147 version = "3.4.1", 148 149 // Define a local copy of jQuery 150 /* 151 jQuery = function( selector, context ) { 152 153 // The jQuery object is actually just the init constructor 'enhanced' 154 // Need init if jQuery is called (just allow error to be thrown if not included) 155 return new jQuery.fn.init( selector, context ); 156 }, 157 */ 158 // Support: Android <=4.0 only 159 // Make sure we trim BOM and NBSP 160 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 161 162jQuery.fn = jQuery.prototype = { 163 164 // The current version of jQuery being used 165 jquery: version, 166 167 constructor: jQuery, 168 169 // The default length of a jQuery object is 0 170 length: 0, 171 172 toArray: function() { 173 return slice.call( this ); 174 }, 175 176 // Get the Nth element in the matched element set OR 177 // Get the whole matched element set as a clean array 178 get: function( num ) { 179 180 // Return all the elements in a clean array 181 if ( num == null ) { 182 return slice.call( this ); 183 } 184 185 // Return just the one element from the set 186 return num < 0 ? this[ num + this.length ] : this[ num ]; 187 }, 188 189 // Take an array of elements and push it onto the stack 190 // (returning the new matched element set) 191 pushStack: function( elems ) { 192 193 // Build a new jQuery matched element set 194 var ret = jQuery.merge( this.constructor(), elems ); 195 196 // Add the old object onto the stack (as a reference) 197 ret.prevObject = this; 198 199 // Return the newly-formed element set 200 return ret; 201 }, 202 203 // Execute a callback for every element in the matched set. 204 each: function( callback ) { 205 return jQuery.each( this, callback ); 206 }, 207 208 map: function( callback ) { 209 return this.pushStack( jQuery.map( this, function( elem, i ) { 210 return callback.call( elem, i, elem ); 211 } ) ); 212 }, 213 214 slice: function() { 215 return this.pushStack( slice.apply( this, arguments ) ); 216 }, 217 218 first: function() { 219 return this.eq( 0 ); 220 }, 221 222 last: function() { 223 return this.eq( -1 ); 224 }, 225 226 eq: function( i ) { 227 var len = this.length, 228 j = +i + ( i < 0 ? len : 0 ); 229 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 230 }, 231 232 end: function() { 233 return this.prevObject || this.constructor(); 234 }, 235 236 // For internal use only. 237 // Behaves like an Array's method, not like a jQuery method. 238 push: push, 239 sort: arr.sort, 240 splice: arr.splice 241}; 242 243jQuery.extend = jQuery.fn.extend = function() { 244 var options, name, src, copy, copyIsArray, clone, 245 target = arguments[ 0 ] || {}, 246 i = 1, 247 length = arguments.length, 248 deep = false; 249 250 // Handle a deep copy situation 251 if ( typeof target === "boolean" ) { 252 deep = target; 253 254 // Skip the boolean and the target 255 target = arguments[ i ] || {}; 256 i++; 257 } 258 259 // Handle case when target is a string or something (possible in deep copy) 260 if ( typeof target !== "object" && !isFunction( target ) ) { 261 target = {}; 262 } 263 264 // Extend jQuery itself if only one argument is passed 265 if ( i === length ) { 266 target = this; 267 i--; 268 } 269 270 for ( ; i < length; i++ ) { 271 272 // Only deal with non-null/undefined values 273 if ( ( options = arguments[ i ] ) != null ) { 274 275 // Extend the base object 276 for ( name in options ) { 277 copy = options[ name ]; 278 279 // Prevent Object.prototype pollution 280 // Prevent never-ending loop 281 if ( name === "__proto__" || target === copy ) { 282 continue; 283 } 284 285 // Recurse if we're merging plain objects or arrays 286 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 287 ( copyIsArray = Array.isArray( copy ) ) ) ) { 288 src = target[ name ]; 289 290 // Ensure proper type for the source value 291 if ( copyIsArray && !Array.isArray( src ) ) { 292 clone = []; 293 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 294 clone = {}; 295 } else { 296 clone = src; 297 } 298 copyIsArray = false; 299 300 // Never move original objects, clone them 301 target[ name ] = jQuery.extend( deep, clone, copy ); 302 303 // Don't bring in undefined values 304 } else if ( copy !== undefined ) { 305 target[ name ] = copy; 306 } 307 } 308 } 309 } 310 311 // Return the modified object 312 return target; 313}; 314 315jQuery.extend( { 316 317 // Unique for each copy of jQuery on the page 318 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 319 320 // Assume jQuery is ready without the ready module 321 isReady: true, 322 323 error: function( msg ) { 324 throw new Error( msg ); 325 }, 326 327 noop: function() {}, 328 329 isPlainObject: function( obj ) { 330 var proto, Ctor; 331 332 // Detect obvious negatives 333 // Use toString instead of jQuery.type to catch host objects 334 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 335 return false; 336 } 337 338 proto = getProto( obj ); 339 340 // Objects with no prototype (e.g., `Object.create( null )`) are plain 341 if ( !proto ) { 342 return true; 343 } 344 345 // Objects with prototype are plain iff they were constructed by a global Object function 346 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 347 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 348 }, 349 350 isEmptyObject: function( obj ) { 351 var name; 352 353 for ( name in obj ) { 354 return false; 355 } 356 return true; 357 }, 358 359 // Evaluates a script in a global context 360 globalEval: function( code, options ) { 361 DOMEval( code, { nonce: options && options.nonce } ); 362 }, 363 364 each: function( obj, callback ) { 365 var length, i = 0; 366 367 if ( isArrayLike( obj ) ) { 368 length = obj.length; 369 for ( ; i < length; i++ ) { 370 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 371 break; 372 } 373 } 374 } else { 375 for ( i in obj ) { 376 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 377 break; 378 } 379 } 380 } 381 382 return obj; 383 }, 384 385 // Support: Android <=4.0 only 386 trim: function( text ) { 387 return text == null ? 388 "" :
vendor: 5,066 bytes, lines 389-606
389 ( text + "" ).replace( rtrim, "" ); 390 }, 391 392 // results is for internal usage only 393 makeArray: function( arr, results ) { 394 var ret = results || []; 395 396 if ( arr != null ) { 397 if ( isArrayLike( Object( arr ) ) ) { 398 jQuery.merge( ret, 399 typeof arr === "string" ? 400 [ arr ] : arr 401 ); 402 } else { 403 push.call( ret, arr ); 404 } 405 } 406 407 return ret; 408 }, 409 410 inArray: function( elem, arr, i ) { 411 return arr == null ? -1 : indexOf.call( arr, elem, i ); 412 }, 413 414 // Support: Android <=4.0 only, PhantomJS 1 only 415 // push.apply(_, arraylike) throws on ancient WebKit 416 merge: function( first, second ) { 417 var len = +second.length, 418 j = 0, 419 i = first.length; 420 421 for ( ; j < len; j++ ) { 422 first[ i++ ] = second[ j ]; 423 } 424 425 first.length = i; 426 427 return first; 428 }, 429 430 grep: function( elems, callback, invert ) { 431 var callbackInverse, 432 matches = [], 433 i = 0, 434 length = elems.length, 435 callbackExpect = !invert; 436 437 // Go through the array, only saving the items 438 // that pass the validator function 439 for ( ; i < length; i++ ) { 440 callbackInverse = !callback( elems[ i ], i ); 441 if ( callbackInverse !== callbackExpect ) { 442 matches.push( elems[ i ] ); 443 } 444 } 445 446 return matches; 447 }, 448 449 // arg is for internal usage only 450 map: function( elems, callback, arg ) { 451 var length, value, 452 i = 0, 453 ret = []; 454 455 // Go through the array, translating each of the items to their new values 456 if ( isArrayLike( elems ) ) { 457 length = elems.length; 458 for ( ; i < length; i++ ) { 459 value = callback( elems[ i ], i, arg ); 460 461 if ( value != null ) { 462 ret.push( value ); 463 } 464 } 465 466 // Go through every key on the object, 467 } else { 468 for ( i in elems ) { 469 value = callback( elems[ i ], i, arg ); 470 471 if ( value != null ) { 472 ret.push( value ); 473 } 474 } 475 } 476 477 // Flatten any nested arrays 478 return concat.apply( [], ret ); 479 }, 480 481 // A global GUID counter for objects 482 guid: 1, 483 484 // jQuery.support is not used in Core but other projects attach their 485 // properties to it so it needs to exist. 486 support: support 487} ); 488 489if ( typeof Symbol === "function" ) { 490 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 491} 492 493// Populate the class2type map 494jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 495function( i, name ) { 496 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 497} ); 498 499function isArrayLike( obj ) { 500 501 // Support: real iOS 8.2 only (not reproducible in simulator) 502 // `in` check used to prevent JIT error (gh-2145) 503 // hasOwn isn't used here due to false negatives 504 // regarding Nodelist length in IE 505 var length = !!obj && "length" in obj && obj.length, 506 type = toType( obj ); 507 508 if ( isFunction( obj ) || isWindow( obj ) ) { 509 return false; 510 } 511 512 return type === "array" || length === 0 || 513 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 514} 515var Sizzle = 516/*! 517 * Sizzle CSS Selector Engine v2.3.4 518 * https://sizzlejs.com/ 519 * 520 * Copyright JS Foundation and other contributors 521 * Released under the MIT license 522 * https://js.foundation/ 523 * 524 * Date: 2019-04-08 525 */ 526(function( window ) { 527 528var i, 529 support, 530 Expr, 531 getText, 532 isXML, 533 tokenize, 534 compile, 535 select, 536 outermostContext, 537 sortInput, 538 hasDuplicate, 539 540 // Local document vars 541 setDocument, 542 document, 543 docElem, 544 documentIsHTML, 545 rbuggyQSA, 546 rbuggyMatches, 547 matches, 548 contains, 549 550 // Instance-specific data 551 expando = "sizzle" + 1 * new Date(), 552 preferredDoc = window.document, 553 dirruns = 0, 554 done = 0, 555 classCache = createCache(), 556 tokenCache = createCache(), 557 compilerCache = createCache(), 558 nonnativeSelectorCache = createCache(), 559 sortOrder = function( a, b ) { 560 if ( a === b ) { 561 hasDuplicate = true; 562 } 563 return 0; 564 }, 565 566 // Instance methods 567 hasOwn = ({}).hasOwnProperty, 568 arr = [], 569 pop = arr.pop, 570 push_native = arr.push, 571 push = arr.push, 572 slice = arr.slice, 573 // Use a stripped-down indexOf as it's faster than native 574 // https://jsperf.com/thor-indexof-vs-for/5 575 indexOf = function( list, elem ) { 576 var i = 0, 577 len = list.length; 578 for ( ; i < len; i++ ) { 579 if ( list[i] === elem ) { 580 return i; 581 } 582 } 583 return -1; 584 }, 585 586 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 587 588 // Regular expressions 589 590 // http://www.w3.org/TR/css3-selectors/#whitespace 591 whitespace = "[\\x20\\t\\r\\n\\f]", 592 593 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 594 identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", 595 596 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 597 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 598 // Operator (capture 2) 599 "*([*^$|!~]?=)" + whitespace + 600 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 601 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 602 "*\\]", 603 604 pseudos = ":(" + identifier + ")(?:\\((" + 605 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 606 // 1. quoted (capture 3; capture 4 or capture 5)
vendor: 4,396 bytes, lines 607-740
607 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 608 // 2. simple (capture 6) 609 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 610 // 3. anything else (capture 2) 611 ".*" + 612 ")\\)|)", 613 614 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 615 rwhitespace = new RegExp( whitespace + "+", "g" ), 616 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 617 618 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 619 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), 620 rdescend = new RegExp( whitespace + "|>" ), 621 622 rpseudo = new RegExp( pseudos ), 623 ridentifier = new RegExp( "^" + identifier + "$" ), 624 625 matchExpr = { 626 "ID": new RegExp( "^#(" + identifier + ")" ), 627 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 628 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 629 "ATTR": new RegExp( "^" + attributes ), 630 "PSEUDO": new RegExp( "^" + pseudos ), 631 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 632 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 633 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 634 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 635 // For use in libraries implementing .is() 636 // We use this for POS matching in `select` 637 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 638 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 639 }, 640 641 rhtml = /HTML$/i, 642 rinputs = /^(?:input|select|textarea|button)$/i, 643 rheader = /^h\d$/i, 644 645 rnative = /^[^{]+\{\s*\[native \w/, 646 647 // Easily-parseable/retrievable ID or TAG or CLASS selectors 648 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 649 650 rsibling = /[+~]/, 651 652 // CSS escapes 653 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 654 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 655 funescape = function( _, escaped, escapedWhitespace ) { 656 var high = "0x" + escaped - 0x10000; 657 // NaN means non-codepoint 658 // Support: Firefox<24 659 // Workaround erroneous numeric interpretation of +"0x" 660 return high !== high || escapedWhitespace ? 661 escaped : 662 high < 0 ? 663 // BMP codepoint 664 String.fromCharCode( high + 0x10000 ) : 665 // Supplemental Plane codepoint (surrogate pair) 666 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 667 }, 668 669 // CSS string/identifier serialization 670 // https://drafts.csswg.org/cssom/#common-serializing-idioms 671 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 672 fcssescape = function( ch, asCodePoint ) { 673 if ( asCodePoint ) { 674 675 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 676 if ( ch === "\0" ) { 677 return "\uFFFD"; 678 } 679 680 // Control characters and (dependent upon position) numbers get escaped as code points 681 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 682 } 683 684 // Other potentially-special ASCII characters get backslash-escaped 685 return "\\" + ch; 686 }, 687 688 // Used for iframes 689 // See setDocument() 690 // Removing the function wrapper causes a "Permission Denied" 691 // error in IE 692 unloadHandler = function() { 693 setDocument(); 694 }, 695 696 inDisabledFieldset = addCombinator( 697 function( elem ) { 698 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 699 }, 700 { dir: "parentNode", next: "legend" } 701 ); 702 703// Optimize for push.apply( _, NodeList ) 704try { 705 push.apply( 706 (arr = slice.call( preferredDoc.childNodes )), 707 preferredDoc.childNodes 708 ); 709 // Support: Android<4.0 710 // Detect silently failing push.apply 711 arr[ preferredDoc.childNodes.length ].nodeType; 712} catch ( e ) { 713 push = { apply: arr.length ? 714 715 // Leverage slice if possible 716 function( target, els ) { 717 push_native.apply( target, slice.call(els) ); 718 } : 719 720 // Support: IE<9 721 // Otherwise append directly 722 function( target, els ) { 723 var j = target.length, 724 i = 0; 725 // Can't trust NodeList.length 726 while ( (target[j++] = els[i++]) ) {} 727 target.length = j - 1; 728 } 729 }; 730} 731 732function Sizzle( selector, context, results, seed ) { 733 var m, i, elem, nid, match, groups, newSelector, 734 newContext = context && context.ownerDocument, 735 736 // nodeType defaults to 9, since context defaults to document 737 nodeType = context ? context.nodeType : 9; 738 739 results = results || []; 740
vendor: 4,664 bytes, lines 741-907
741 // Return early from calls with invalid selector or context 742 if ( typeof selector !== "string" || !selector || 743 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 744 745 return results; 746 } 747 748 // Try to shortcut find operations (as opposed to filters) in HTML documents 749 if ( !seed ) { 750 751 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 752 setDocument( context ); 753 } 754 context = context || document; 755 756 if ( documentIsHTML ) { 757 758 // If the selector is sufficiently simple, try using a "get*By*" DOM method 759 // (excepting DocumentFragment context, where the methods don't exist) 760 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 761 762 // ID selector 763 if ( (m = match[1]) ) { 764 765 // Document context 766 if ( nodeType === 9 ) { 767 if ( (elem = context.getElementById( m )) ) { 768 769 // Support: IE, Opera, Webkit 770 // TODO: identify versions 771 // getElementById can match elements by name instead of ID 772 if ( elem.id === m ) { 773 results.push( elem ); 774 return results; 775 } 776 } else { 777 return results; 778 } 779 780 // Element context 781 } else { 782 783 // Support: IE, Opera, Webkit 784 // TODO: identify versions 785 // getElementById can match elements by name instead of ID 786 if ( newContext && (elem = newContext.getElementById( m )) && 787 contains( context, elem ) && 788 elem.id === m ) { 789 790 results.push( elem ); 791 return results; 792 } 793 } 794 795 // Type selector 796 } else if ( match[2] ) { 797 push.apply( results, context.getElementsByTagName( selector ) ); 798 return results; 799 800 // Class selector 801 } else if ( (m = match[3]) && support.getElementsByClassName && 802 context.getElementsByClassName ) { 803 804 push.apply( results, context.getElementsByClassName( m ) ); 805 return results; 806 } 807 } 808 809 // Take advantage of querySelectorAll 810 if ( support.qsa && 811 !nonnativeSelectorCache[ selector + " " ] && 812 (!rbuggyQSA || !rbuggyQSA.test( selector )) && 813 814 // Support: IE 8 only 815 // Exclude object elements 816 (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { 817 818 newSelector = selector; 819 newContext = context; 820 821 // qSA considers elements outside a scoping root when evaluating child or 822 // descendant combinators, which is not what we want. 823 // In such cases, we work around the behavior by prefixing every selector in the 824 // list with an ID selector referencing the scope context. 825 // Thanks to Andrew Dupont for this technique. 826 if ( nodeType === 1 && rdescend.test( selector ) ) { 827 828 // Capture the context ID, setting it first if necessary 829 if ( (nid = context.getAttribute( "id" )) ) { 830 nid = nid.replace( rcssescape, fcssescape ); 831 } else { 832 context.setAttribute( "id", (nid = expando) ); 833 } 834 835 // Prefix every selector in the list 836 groups = tokenize( selector ); 837 i = groups.length; 838 while ( i-- ) { 839 groups[i] = "#" + nid + " " + toSelector( groups[i] ); 840 } 841 newSelector = groups.join( "," ); 842 843 // Expand context for sibling selectors 844 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 845 context; 846 } 847 848 try { 849 push.apply( results, 850 newContext.querySelectorAll( newSelector ) 851 ); 852 return results; 853 } catch ( qsaError ) { 854 nonnativeSelectorCache( selector, true ); 855 } finally { 856 if ( nid === expando ) { 857 context.removeAttribute( "id" ); 858 } 859 } 860 } 861 } 862 } 863 864 // All others 865 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 866} 867 868/** 869 * Create key-value caches of limited size 870 * @returns {function(string, object)} Returns the Object data after storing it on itself with 871 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 872 * deleting the oldest entry 873 */ 874function createCache() { 875 var keys = []; 876 877 function cache( key, value ) { 878 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 879 if ( keys.push( key + " " ) > Expr.cacheLength ) { 880 // Only keep the most recent entries 881 delete cache[ keys.shift() ]; 882 } 883 return (cache[ key + " " ] = value); 884 } 885 return cache; 886} 887 888/** 889 * Mark a function for special use by Sizzle 890 * @param {Function} fn The function to mark 891 */ 892function markFunction( fn ) { 893 fn[ expando ] = true; 894 return fn; 895} 896 897/** 898 * Support testing using an element 899 * @param {Function} fn Passed the created element and returns a boolean result 900 */ 901function assert( fn ) { 902 var el = document.createElement("fieldset"); 903 904 try { 905 return !!fn( el ); 906 } catch (e) { 907 return false;
vendor: 10,862 bytes, lines 908-1274
908 } finally { 909 // Remove from its parent by default 910 if ( el.parentNode ) { 911 el.parentNode.removeChild( el ); 912 } 913 // release memory in IE 914 el = null; 915 } 916} 917 918/** 919 * Adds the same handler for all of the specified attrs 920 * @param {String} attrs Pipe-separated list of attributes 921 * @param {Function} handler The method that will be applied 922 */ 923function addHandle( attrs, handler ) { 924 var arr = attrs.split("|"), 925 i = arr.length; 926 927 while ( i-- ) { 928 Expr.attrHandle[ arr[i] ] = handler; 929 } 930} 931 932/** 933 * Checks document order of two siblings 934 * @param {Element} a 935 * @param {Element} b 936 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 937 */ 938function siblingCheck( a, b ) { 939 var cur = b && a, 940 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 941 a.sourceIndex - b.sourceIndex; 942 943 // Use IE sourceIndex if available on both nodes 944 if ( diff ) { 945 return diff; 946 } 947 948 // Check if b follows a 949 if ( cur ) { 950 while ( (cur = cur.nextSibling) ) { 951 if ( cur === b ) { 952 return -1; 953 } 954 } 955 } 956 957 return a ? 1 : -1; 958} 959 960/** 961 * Returns a function to use in pseudos for input types 962 * @param {String} type 963 */ 964function createInputPseudo( type ) { 965 return function( elem ) { 966 var name = elem.nodeName.toLowerCase(); 967 return name === "input" && elem.type === type; 968 }; 969} 970 971/** 972 * Returns a function to use in pseudos for buttons 973 * @param {String} type 974 */ 975function createButtonPseudo( type ) { 976 return function( elem ) { 977 var name = elem.nodeName.toLowerCase(); 978 return (name === "input" || name === "button") && elem.type === type; 979 }; 980} 981 982/** 983 * Returns a function to use in pseudos for :enabled/:disabled 984 * @param {Boolean} disabled true for :disabled; false for :enabled 985 */ 986function createDisabledPseudo( disabled ) { 987 988 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 989 return function( elem ) { 990 991 // Only certain elements can match :enabled or :disabled 992 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 993 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 994 if ( "form" in elem ) { 995 996 // Check for inherited disabledness on relevant non-disabled elements: 997 // * listed form-associated elements in a disabled fieldset 998 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 999 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1000 // * option elements in a disabled optgroup 1001 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1002 // All such elements have a "form" property. 1003 if ( elem.parentNode && elem.disabled === false ) { 1004 1005 // Option elements defer to a parent optgroup if present 1006 if ( "label" in elem ) { 1007 if ( "label" in elem.parentNode ) { 1008 return elem.parentNode.disabled === disabled; 1009 } else { 1010 return elem.disabled === disabled; 1011 } 1012 } 1013 1014 // Support: IE 6 - 11 1015 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1016 return elem.isDisabled === disabled || 1017 1018 // Where there is no isDisabled, check manually 1019 /* jshint -W018 */ 1020 elem.isDisabled !== !disabled && 1021 inDisabledFieldset( elem ) === disabled; 1022 } 1023 1024 return elem.disabled === disabled; 1025 1026 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1027 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1028 // even exist on them, let alone have a boolean value. 1029 } else if ( "label" in elem ) { 1030 return elem.disabled === disabled; 1031 } 1032 1033 // Remaining elements are neither :enabled nor :disabled 1034 return false; 1035 }; 1036} 1037 1038/** 1039 * Returns a function to use in pseudos for positionals 1040 * @param {Function} fn 1041 */ 1042function createPositionalPseudo( fn ) { 1043 return markFunction(function( argument ) { 1044 argument = +argument; 1045 return markFunction(function( seed, matches ) { 1046 var j, 1047 matchIndexes = fn( [], seed.length, argument ), 1048 i = matchIndexes.length; 1049 1050 // Match elements found at the specified indexes 1051 while ( i-- ) { 1052 if ( seed[ (j = matchIndexes[i]) ] ) { 1053 seed[j] = !(matches[j] = seed[j]); 1054 } 1055 } 1056 }); 1057 }); 1058} 1059 1060/** 1061 * Checks a node for validity as a Sizzle context 1062 * @param {Element|Object=} context 1063 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1064 */ 1065function testContext( context ) { 1066 return context && typeof context.getElementsByTagName !== "undefined" && context; 1067} 1068 1069// Expose support vars for convenience 1070support = Sizzle.support = {}; 1071 1072/** 1073 * Detects XML nodes 1074 * @param {Element|Object} elem An element or a document 1075 * @returns {Boolean} True iff elem is a non-HTML XML node 1076 */ 1077isXML = Sizzle.isXML = function( elem ) { 1078 var namespace = elem.namespaceURI, 1079 docElem = (elem.ownerDocument || elem).documentElement; 1080 1081 // Support: IE <=8 1082 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 1083 // https://bugs.jquery.com/ticket/4833 1084 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 1085}; 1086 1087/** 1088 * Sets document-related variables once based on the current document 1089 * @param {Element|Object} [doc] An element or document object to use to set the document 1090 * @returns {Object} Returns the current document 1091 */ 1092setDocument = Sizzle.setDocument = function( node ) { 1093 var hasCompare, subWindow, 1094 doc = node ? node.ownerDocument || node : preferredDoc; 1095 1096 // Return early if doc is invalid or already selected 1097 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 1098 return document; 1099 } 1100 1101 // Update global variables 1102 document = doc; 1103 docElem = document.documentElement; 1104 documentIsHTML = !isXML( document ); 1105 1106 // Support: IE 9-11, Edge 1107 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 1108 if ( preferredDoc !== document && 1109 (subWindow = document.defaultView) && subWindow.top !== subWindow ) { 1110 1111 // Support: IE 11, Edge 1112 if ( subWindow.addEventListener ) { 1113 subWindow.addEventListener( "unload", unloadHandler, false ); 1114 1115 // Support: IE 9 - 10 only 1116 } else if ( subWindow.attachEvent ) { 1117 subWindow.attachEvent( "onunload", unloadHandler ); 1118 } 1119 } 1120 1121 /* Attributes 1122 ---------------------------------------------------------------------- */ 1123 1124 // Support: IE<8 1125 // Verify that getAttribute really returns attributes and not properties 1126 // (excepting IE8 booleans) 1127 support.attributes = assert(function( el ) { 1128 el.className = "i"; 1129 return !el.getAttribute("className"); 1130 }); 1131 1132 /* getElement(s)By* 1133 ---------------------------------------------------------------------- */ 1134 1135 // Check if getElementsByTagName("*") returns only elements 1136 support.getElementsByTagName = assert(function( el ) { 1137 el.appendChild( document.createComment("") ); 1138 return !el.getElementsByTagName("*").length; 1139 }); 1140 1141 // Support: IE<9 1142 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 1143 1144 // Support: IE<10 1145 // Check if getElementById returns elements by name 1146 // The broken getElementById methods don't pick up programmatically-set names, 1147 // so use a roundabout getElementsByName test 1148 support.getById = assert(function( el ) { 1149 docElem.appendChild( el ).id = expando; 1150 return !document.getElementsByName || !document.getElementsByName( expando ).length; 1151 }); 1152 1153 // ID filter and find 1154 if ( support.getById ) { 1155 Expr.filter["ID"] = function( id ) { 1156 var attrId = id.replace( runescape, funescape ); 1157 return function( elem ) { 1158 return elem.getAttribute("id") === attrId; 1159 }; 1160 }; 1161 Expr.find["ID"] = function( id, context ) { 1162 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1163 var elem = context.getElementById( id ); 1164 return elem ? [ elem ] : []; 1165 } 1166 }; 1167 } else { 1168 Expr.filter["ID"] = function( id ) { 1169 var attrId = id.replace( runescape, funescape ); 1170 return function( elem ) { 1171 var node = typeof elem.getAttributeNode !== "undefined" && 1172 elem.getAttributeNode("id"); 1173 return node && node.value === attrId; 1174 }; 1175 }; 1176 1177 // Support: IE 6 - 7 only 1178 // getElementById is not reliable as a find shortcut 1179 Expr.find["ID"] = function( id, context ) { 1180 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1181 var node, i, elems, 1182 elem = context.getElementById( id ); 1183 1184 if ( elem ) { 1185 1186 // Verify the id attribute 1187 node = elem.getAttributeNode("id"); 1188 if ( node && node.value === id ) { 1189 return [ elem ]; 1190 } 1191 1192 // Fall back on getElementsByName 1193 elems = context.getElementsByName( id ); 1194 i = 0; 1195 while ( (elem = elems[i++]) ) { 1196 node = elem.getAttributeNode("id"); 1197 if ( node && node.value === id ) { 1198 return [ elem ]; 1199 } 1200 } 1201 } 1202 1203 return []; 1204 } 1205 }; 1206 } 1207 1208 // Tag 1209 Expr.find["TAG"] = support.getElementsByTagName ? 1210 function( tag, context ) { 1211 if ( typeof context.getElementsByTagName !== "undefined" ) { 1212 return context.getElementsByTagName( tag ); 1213 1214 // DocumentFragment nodes don't have gEBTN 1215 } else if ( support.qsa ) { 1216 return context.querySelectorAll( tag ); 1217 } 1218 } : 1219 1220 function( tag, context ) { 1221 var elem, 1222 tmp = [], 1223 i = 0, 1224 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1225 results = context.getElementsByTagName( tag ); 1226 1227 // Filter out possible comments 1228 if ( tag === "*" ) { 1229 while ( (elem = results[i++]) ) { 1230 if ( elem.nodeType === 1 ) { 1231 tmp.push( elem ); 1232 } 1233 } 1234 1235 return tmp; 1236 } 1237 return results; 1238 }; 1239 1240 // Class 1241 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 1242 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1243 return context.getElementsByClassName( className ); 1244 } 1245 }; 1246 1247 /* QSA/matchesSelector 1248 ---------------------------------------------------------------------- */ 1249 1250 // QSA and matchesSelector support 1251 1252 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1253 rbuggyMatches = []; 1254 1255 // qSa(:focus) reports false when true (Chrome 21) 1256 // We allow this because of a bug in IE8/9 that throws an error 1257 // whenever `document.activeElement` is accessed on an iframe 1258 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1259 // See https://bugs.jquery.com/ticket/13378 1260 rbuggyQSA = []; 1261 1262 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { 1263 // Build QSA regex 1264 // Regex strategy adopted from Diego Perini 1265 assert(function( el ) { 1266 // Select is set to empty string on purpose 1267 // This is to test IE's treatment of not explicitly 1268 // setting a boolean content attribute, 1269 // since its presence should be enough 1270 // https://bugs.jquery.com/ticket/12359 1271 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 1272 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 1273 "<option selected=''></option></select>"; 1274
vendor: 8,268 bytes, lines 1275-1559
1275 // Support: IE8, Opera 11-12.16 1276 // Nothing should be selected when empty strings follow ^= or $= or *= 1277 // The test attribute must be unknown in Opera but "safe" for WinRT 1278 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1279 if ( el.querySelectorAll("[msallowcapture^='']").length ) { 1280 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 1281 } 1282 1283 // Support: IE8 1284 // Boolean attributes and "value" are not treated correctly 1285 if ( !el.querySelectorAll("[selected]").length ) { 1286 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1287 } 1288 1289 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 1290 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1291 rbuggyQSA.push("~="); 1292 } 1293 1294 // Webkit/Opera - :checked should return selected option elements 1295 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1296 // IE8 throws error here and will not see later tests 1297 if ( !el.querySelectorAll(":checked").length ) { 1298 rbuggyQSA.push(":checked"); 1299 } 1300 1301 // Support: Safari 8+, iOS 8+ 1302 // https://bugs.webkit.org/show_bug.cgi?id=136851 1303 // In-page `selector#id sibling-combinator selector` fails 1304 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 1305 rbuggyQSA.push(".#.+[+~]"); 1306 } 1307 }); 1308 1309 assert(function( el ) { 1310 el.innerHTML = "<a href='' disabled='disabled'></a>" + 1311 "<select disabled='disabled'><option/></select>"; 1312 1313 // Support: Windows 8 Native Apps 1314 // The type and name attributes are restricted during .innerHTML assignment 1315 var input = document.createElement("input"); 1316 input.setAttribute( "type", "hidden" ); 1317 el.appendChild( input ).setAttribute( "name", "D" ); 1318 1319 // Support: IE8 1320 // Enforce case-sensitivity of name attribute 1321 if ( el.querySelectorAll("[name=d]").length ) { 1322 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 1323 } 1324 1325 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1326 // IE8 throws error here and will not see later tests 1327 if ( el.querySelectorAll(":enabled").length !== 2 ) { 1328 rbuggyQSA.push( ":enabled", ":disabled" ); 1329 } 1330 1331 // Support: IE9-11+ 1332 // IE's :disabled selector does not pick up the children of disabled fieldsets 1333 docElem.appendChild( el ).disabled = true; 1334 if ( el.querySelectorAll(":disabled").length !== 2 ) { 1335 rbuggyQSA.push( ":enabled", ":disabled" ); 1336 } 1337 1338 // Opera 10-11 does not throw on post-comma invalid pseudos 1339 el.querySelectorAll("*,:x"); 1340 rbuggyQSA.push(",.*:"); 1341 }); 1342 } 1343 1344 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 1345 docElem.webkitMatchesSelector || 1346 docElem.mozMatchesSelector || 1347 docElem.oMatchesSelector || 1348 docElem.msMatchesSelector) )) ) { 1349 1350 assert(function( el ) { 1351 // Check to see if it's possible to do matchesSelector 1352 // on a disconnected node (IE 9) 1353 support.disconnectedMatch = matches.call( el, "*" ); 1354 1355 // This should fail with an exception 1356 // Gecko does not error, returns false instead 1357 matches.call( el, "[s!='']:x" ); 1358 rbuggyMatches.push( "!=", pseudos ); 1359 }); 1360 } 1361 1362 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 1363 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 1364 1365 /* Contains 1366 ---------------------------------------------------------------------- */ 1367 hasCompare = rnative.test( docElem.compareDocumentPosition ); 1368 1369 // Element contains another 1370 // Purposefully self-exclusive 1371 // As in, an element does not contain itself 1372 contains = hasCompare || rnative.test( docElem.contains ) ? 1373 function( a, b ) { 1374 var adown = a.nodeType === 9 ? a.documentElement : a, 1375 bup = b && b.parentNode; 1376 return a === bup || !!( bup && bup.nodeType === 1 && ( 1377 adown.contains ? 1378 adown.contains( bup ) : 1379 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1380 )); 1381 } : 1382 function( a, b ) { 1383 if ( b ) { 1384 while ( (b = b.parentNode) ) { 1385 if ( b === a ) { 1386 return true; 1387 } 1388 } 1389 } 1390 return false; 1391 }; 1392 1393 /* Sorting 1394 ---------------------------------------------------------------------- */ 1395 1396 // Document order sorting 1397 sortOrder = hasCompare ? 1398 function( a, b ) { 1399 1400 // Flag for duplicate removal 1401 if ( a === b ) { 1402 hasDuplicate = true; 1403 return 0; 1404 } 1405 1406 // Sort on method existence if only one input has compareDocumentPosition 1407 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1408 if ( compare ) { 1409 return compare; 1410 } 1411 1412 // Calculate position if both inputs belong to the same document 1413 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 1414 a.compareDocumentPosition( b ) : 1415 1416 // Otherwise we know they are disconnected 1417 1; 1418 1419 // Disconnected nodes 1420 if ( compare & 1 || 1421 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 1422 1423 // Choose the first element that is related to our preferred document 1424 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 1425 return -1; 1426 } 1427 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 1428 return 1; 1429 } 1430 1431 // Maintain original order 1432 return sortInput ? 1433 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1434 0; 1435 } 1436 1437 return compare & 4 ? -1 : 1; 1438 } : 1439 function( a, b ) { 1440 // Exit early if the nodes are identical 1441 if ( a === b ) { 1442 hasDuplicate = true; 1443 return 0; 1444 } 1445 1446 var cur, 1447 i = 0, 1448 aup = a.parentNode, 1449 bup = b.parentNode, 1450 ap = [ a ], 1451 bp = [ b ]; 1452 1453 // Parentless nodes are either documents or disconnected 1454 if ( !aup || !bup ) { 1455 return a === document ? -1 : 1456 b === document ? 1 : 1457 aup ? -1 : 1458 bup ? 1 : 1459 sortInput ? 1460 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 1461 0; 1462 1463 // If the nodes are siblings, we can do a quick check 1464 } else if ( aup === bup ) { 1465 return siblingCheck( a, b ); 1466 } 1467 1468 // Otherwise we need full lists of their ancestors for comparison 1469 cur = a; 1470 while ( (cur = cur.parentNode) ) { 1471 ap.unshift( cur ); 1472 } 1473 cur = b; 1474 while ( (cur = cur.parentNode) ) { 1475 bp.unshift( cur ); 1476 } 1477 1478 // Walk down the tree looking for a discrepancy 1479 while ( ap[i] === bp[i] ) { 1480 i++; 1481 } 1482 1483 return i ? 1484 // Do a sibling check if the nodes have a common ancestor 1485 siblingCheck( ap[i], bp[i] ) : 1486 1487 // Otherwise nodes in our document sort first 1488 ap[i] === preferredDoc ? -1 : 1489 bp[i] === preferredDoc ? 1 : 1490 0; 1491 }; 1492 1493 return document; 1494}; 1495 1496Sizzle.matches = function( expr, elements ) { 1497 return Sizzle( expr, null, null, elements ); 1498}; 1499 1500Sizzle.matchesSelector = function( elem, expr ) { 1501 // Set document vars if needed 1502 if ( ( elem.ownerDocument || elem ) !== document ) { 1503 setDocument( elem ); 1504 } 1505 1506 if ( support.matchesSelector && documentIsHTML && 1507 !nonnativeSelectorCache[ expr + " " ] && 1508 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 1509 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1510 1511 try { 1512 var ret = matches.call( elem, expr ); 1513 1514 // IE 9's matchesSelector returns false on disconnected nodes 1515 if ( ret || support.disconnectedMatch || 1516 // As well, disconnected nodes are said to be in a document 1517 // fragment in IE 9 1518 elem.document && elem.document.nodeType !== 11 ) { 1519 return ret; 1520 } 1521 } catch (e) { 1522 nonnativeSelectorCache( expr, true ); 1523 } 1524 } 1525 1526 return Sizzle( expr, document, null, [ elem ] ).length > 0; 1527}; 1528 1529Sizzle.contains = function( context, elem ) { 1530 // Set document vars if needed 1531 if ( ( context.ownerDocument || context ) !== document ) { 1532 setDocument( context ); 1533 } 1534 return contains( context, elem ); 1535}; 1536 1537Sizzle.attr = function( elem, name ) { 1538 // Set document vars if needed 1539 if ( ( elem.ownerDocument || elem ) !== document ) { 1540 setDocument( elem ); 1541 } 1542 1543 var fn = Expr.attrHandle[ name.toLowerCase() ], 1544 // Don't get fooled by Object.prototype properties (jQuery #13807) 1545 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1546 fn( elem, name, !documentIsHTML ) : 1547 undefined; 1548 1549 return val !== undefined ? 1550 val : 1551 support.attributes || !documentIsHTML ? 1552 elem.getAttribute( name ) : 1553 (val = elem.getAttributeNode(name)) && val.specified ? 1554 val.value : 1555 null; 1556}; 1557 1558Sizzle.escape = function( sel ) { 1559 return (sel + "").replace( rcssescape, fcssescape )
vendor: 11,991 bytes, lines 1559-1982
1559; 1560}; 1561 1562Sizzle.error = function( msg ) { 1563 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1564}; 1565 1566/** 1567 * Document sorting and removing duplicates 1568 * @param {ArrayLike} results 1569 */ 1570Sizzle.uniqueSort = function( results ) { 1571 var elem, 1572 duplicates = [], 1573 j = 0, 1574 i = 0; 1575 1576 // Unless we *know* we can detect duplicates, assume their presence 1577 hasDuplicate = !support.detectDuplicates; 1578 sortInput = !support.sortStable && results.slice( 0 ); 1579 results.sort( sortOrder ); 1580 1581 if ( hasDuplicate ) { 1582 while ( (elem = results[i++]) ) { 1583 if ( elem === results[ i ] ) { 1584 j = duplicates.push( i ); 1585 } 1586 } 1587 while ( j-- ) { 1588 results.splice( duplicates[ j ], 1 ); 1589 } 1590 } 1591 1592 // Clear input after sorting to release objects 1593 // See https://github.com/jquery/sizzle/pull/225 1594 sortInput = null; 1595 1596 return results; 1597}; 1598 1599/** 1600 * Utility function for retrieving the text value of an array of DOM nodes 1601 * @param {Array|Element} elem 1602 */ 1603getText = Sizzle.getText = function( elem ) { 1604 var node, 1605 ret = "", 1606 i = 0, 1607 nodeType = elem.nodeType; 1608 1609 if ( !nodeType ) { 1610 // If no nodeType, this is expected to be an array 1611 while ( (node = elem[i++]) ) { 1612 // Do not traverse comment nodes 1613 ret += getText( node ); 1614 } 1615 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 1616 // Use textContent for elements 1617 // innerText usage removed for consistency of new lines (jQuery #11153) 1618 if ( typeof elem.textContent === "string" ) { 1619 return elem.textContent; 1620 } else { 1621 // Traverse its children 1622 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1623 ret += getText( elem ); 1624 } 1625 } 1626 } else if ( nodeType === 3 || nodeType === 4 ) { 1627 return elem.nodeValue; 1628 } 1629 // Do not include comment or processing instruction nodes 1630 1631 return ret; 1632}; 1633 1634Expr = Sizzle.selectors = { 1635 1636 // Can be adjusted by the user 1637 cacheLength: 50, 1638 1639 createPseudo: markFunction, 1640 1641 match: matchExpr, 1642 1643 attrHandle: {}, 1644 1645 find: {}, 1646 1647 relative: { 1648 ">": { dir: "parentNode", first: true }, 1649 " ": { dir: "parentNode" }, 1650 "+": { dir: "previousSibling", first: true }, 1651 "~": { dir: "previousSibling" } 1652 }, 1653 1654 preFilter: { 1655 "ATTR": function( match ) { 1656 match[1] = match[1].replace( runescape, funescape ); 1657 1658 // Move the given value to match[3] whether quoted or unquoted 1659 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 1660 1661 if ( match[2] === "~=" ) { 1662 match[3] = " " + match[3] + " "; 1663 } 1664 1665 return match.slice( 0, 4 ); 1666 }, 1667 1668 "CHILD": function( match ) { 1669 /* matches from matchExpr["CHILD"] 1670 1 type (only|nth|...) 1671 2 what (child|of-type) 1672 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1673 4 xn-component of xn+y argument ([+-]?\d*n|) 1674 5 sign of xn-component 1675 6 x of xn-component 1676 7 sign of y-component 1677 8 y of y-component 1678 */ 1679 match[1] = match[1].toLowerCase(); 1680 1681 if ( match[1].slice( 0, 3 ) === "nth" ) { 1682 // nth-* requires argument 1683 if ( !match[3] ) { 1684 Sizzle.error( match[0] ); 1685 } 1686 1687 // numeric x and y parameters for Expr.filter.CHILD 1688 // remember that false/true cast respectively to 0/1 1689 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 1690 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 1691 1692 // other types prohibit arguments 1693 } else if ( match[3] ) { 1694 Sizzle.error( match[0] ); 1695 } 1696 1697 return match; 1698 }, 1699 1700 "PSEUDO": function( match ) { 1701 var excess, 1702 unquoted = !match[6] && match[2]; 1703 1704 if ( matchExpr["CHILD"].test( match[0] ) ) { 1705 return null; 1706 } 1707 1708 // Accept quoted arguments as-is 1709 if ( match[3] ) { 1710 match[2] = match[4] || match[5] || ""; 1711 1712 // Strip excess characters from unquoted arguments 1713 } else if ( unquoted && rpseudo.test( unquoted ) && 1714 // Get excess from tokenize (recursively) 1715 (excess = tokenize( unquoted, true )) && 1716 // advance to the next closing parenthesis 1717 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 1718 1719 // excess is a negative index 1720 match[0] = match[0].slice( 0, excess ); 1721 match[2] = unquoted.slice( 0, excess ); 1722 } 1723 1724 // Return only captures needed by the pseudo filter method (type and argument) 1725 return match.slice( 0, 3 ); 1726 } 1727 }, 1728 1729 filter: { 1730 1731 "TAG": function( nodeNameSelector ) { 1732 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1733 return nodeNameSelector === "*" ? 1734 function() { return true; } : 1735 function( elem ) { 1736 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1737 }; 1738 }, 1739 1740 "CLASS": function( className ) { 1741 var pattern = classCache[ className + " " ]; 1742 1743 return pattern || 1744 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 1745 classCache( className, function( elem ) { 1746 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 1747 }); 1748 }, 1749 1750 "ATTR": function( name, operator, check ) { 1751 return function( elem ) { 1752 var result = Sizzle.attr( elem, name ); 1753 1754 if ( result == null ) { 1755 return operator === "!="; 1756 } 1757 if ( !operator ) { 1758 return true; 1759 } 1760 1761 result += ""; 1762 1763 return operator === "=" ? result === check : 1764 operator === "!=" ? result !== check : 1765 operator === "^=" ? check && result.indexOf( check ) === 0 : 1766 operator === "*=" ? check && result.indexOf( check ) > -1 : 1767 operator === "$=" ? check && result.slice( -check.length ) === check : 1768 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 1769 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 1770 false; 1771 }; 1772 }, 1773 1774 "CHILD": function( type, what, argument, first, last ) { 1775 var simple = type.slice( 0, 3 ) !== "nth", 1776 forward = type.slice( -4 ) !== "last", 1777 ofType = what === "of-type"; 1778 1779 return first === 1 && last === 0 ? 1780 1781 // Shortcut for :nth-*(n) 1782 function( elem ) { 1783 return !!elem.parentNode; 1784 } : 1785 1786 function( elem, context, xml ) { 1787 var cache, uniqueCache, outerCache, node, nodeIndex, start, 1788 dir = simple !== forward ? "nextSibling" : "previousSibling", 1789 parent = elem.parentNode, 1790 name = ofType && elem.nodeName.toLowerCase(), 1791 useCache = !xml && !ofType, 1792 diff = false; 1793 1794 if ( parent ) { 1795 1796 // :(first|last|only)-(child|of-type) 1797 if ( simple ) { 1798 while ( dir ) { 1799 node = elem; 1800 while ( (node = node[ dir ]) ) { 1801 if ( ofType ? 1802 node.nodeName.toLowerCase() === name : 1803 node.nodeType === 1 ) { 1804 1805 return false; 1806 } 1807 } 1808 // Reverse direction for :only-* (if we haven't yet done so) 1809 start = dir = type === "only" && !start && "nextSibling"; 1810 } 1811 return true; 1812 } 1813 1814 start = [ forward ? parent.firstChild : parent.lastChild ]; 1815 1816 // non-xml :nth-child(...) stores cache data on `parent` 1817 if ( forward && useCache ) { 1818 1819 // Seek `elem` from a previously-cached index 1820 1821 // ...in a gzip-friendly way 1822 node = parent; 1823 outerCache = node[ expando ] || (node[ expando ] = {}); 1824 1825 // Support: IE <9 only 1826 // Defend against cloned attroperties (jQuery gh-1709) 1827 uniqueCache = outerCache[ node.uniqueID ] || 1828 (outerCache[ node.uniqueID ] = {}); 1829 1830 cache = uniqueCache[ type ] || []; 1831 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1832 diff = nodeIndex && cache[ 2 ]; 1833 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1834 1835 while ( (node = ++nodeIndex && node && node[ dir ] || 1836 1837 // Fallback to seeking `elem` from the start 1838 (diff = nodeIndex = 0) || start.pop()) ) { 1839 1840 // When found, cache indexes on `parent` and break 1841 if ( node.nodeType === 1 && ++diff && node === elem ) { 1842 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 1843 break; 1844 } 1845 } 1846 1847 } else { 1848 // Use previously-cached element index if available 1849 if ( useCache ) { 1850 // ...in a gzip-friendly way 1851 node = elem; 1852 outerCache = node[ expando ] || (node[ expando ] = {}); 1853 1854 // Support: IE <9 only 1855 // Defend against cloned attroperties (jQuery gh-1709) 1856 uniqueCache = outerCache[ node.uniqueID ] || 1857 (outerCache[ node.uniqueID ] = {}); 1858 1859 cache = uniqueCache[ type ] || []; 1860 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1861 diff = nodeIndex; 1862 } 1863 1864 // xml :nth-child(...) 1865 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1866 if ( diff === false ) { 1867 // Use the same loop as above to seek `elem` from the start 1868 while ( (node = ++nodeIndex && node && node[ dir ] || 1869 (diff = nodeIndex = 0) || start.pop()) ) { 1870 1871 if ( ( ofType ? 1872 node.nodeName.toLowerCase() === name : 1873 node.nodeType === 1 ) && 1874 ++diff ) { 1875 1876 // Cache the index of each encountered element 1877 if ( useCache ) { 1878 outerCache = node[ expando ] || (node[ expando ] = {}); 1879 1880 // Support: IE <9 only 1881 // Defend against cloned attroperties (jQuery gh-1709) 1882 uniqueCache = outerCache[ node.uniqueID ] || 1883 (outerCache[ node.uniqueID ] = {}); 1884 1885 uniqueCache[ type ] = [ dirruns, diff ]; 1886 } 1887 1888 if ( node === elem ) { 1889 break; 1890 } 1891 } 1892 } 1893 } 1894 } 1895 1896 // Incorporate the offset, then check against cycle size 1897 diff -= last; 1898 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1899 } 1900 }; 1901 }, 1902 1903 "PSEUDO": function( pseudo, argument ) { 1904 // pseudo-class names are case-insensitive 1905 // http://www.w3.org/TR/selectors/#pseudo-classes 1906 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1907 // Remember that setFilters inherits from pseudos 1908 var args, 1909 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1910 Sizzle.error( "unsupported pseudo: " + pseudo ); 1911 1912 // The user may use createPseudo to indicate that 1913 // arguments are needed to create the filter function 1914 // just as Sizzle does 1915 if ( fn[ expando ] ) { 1916 return fn( argument ); 1917 } 1918 1919 // But maintain support for old signatures 1920 if ( fn.length > 1 ) { 1921 args = [ pseudo, pseudo, "", argument ]; 1922 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1923 markFunction(function( seed, matches ) { 1924 var idx, 1925 matched = fn( seed, argument ), 1926 i = matched.length; 1927 while ( i-- ) { 1928 idx = indexOf( seed, matched[i] ); 1929 seed[ idx ] = !( matches[ idx ] = matched[i] ); 1930 } 1931 }) : 1932 function( elem ) { 1933 return fn( elem, 0, args ); 1934 }; 1935 } 1936 1937 return fn; 1938 } 1939 }, 1940 1941 pseudos: { 1942 // Potentially complex pseudos 1943 "not": markFunction(function( selector ) { 1944 // Trim the selector passed to compile 1945 // to avoid treating leading and trailing 1946 // spaces as combinators 1947 var input = [], 1948 results = [], 1949 matcher = compile( selector.replace( rtrim, "$1" ) ); 1950 1951 return matcher[ expando ] ? 1952 markFunction(function( seed, matches, context, xml ) { 1953 var elem, 1954 unmatched = matcher( seed, null, xml, [] ), 1955 i = seed.length; 1956 1957 // Match elements unmatched by `matcher` 1958 while ( i-- ) { 1959 if ( (elem = unmatched[i]) ) { 1960 seed[i] = !(matches[i] = elem); 1961 } 1962 } 1963 }) : 1964 function( elem, context, xml ) { 1965 input[0] = elem; 1966 matcher( input, null, xml, results ); 1967 // Don't keep the element (issue #299) 1968 input[0] = null; 1969 return !results.pop(); 1970 }; 1971 }), 1972 1973 "has": markFunction(function( selector ) { 1974 return function( elem ) { 1975 return Sizzle( selector, elem ).length > 0; 1976 }; 1977 }), 1978 1979 "contains": markFunction(function( text ) { 1980 text = text.replace( runescape, funescape ); 1981 return function( elem ) { 1982 return ( elem.textContent ||
vendor: 1,115 bytes, lines 1982-2010
1982getText( elem ) ).indexOf( text ) > -1; 1983 }; 1984 }), 1985 1986 // "Whether an element is represented by a :lang() selector 1987 // is based solely on the element's language value 1988 // being equal to the identifier C, 1989 // or beginning with the identifier C immediately followed by "-". 1990 // The matching of C against the element's language value is performed case-insensitively. 1991 // The identifier C does not have to be a valid language name." 1992 // http://www.w3.org/TR/selectors/#lang-pseudo 1993 "lang": markFunction( function( lang ) { 1994 // lang value must be a valid identifier 1995 if ( !ridentifier.test(lang || "") ) { 1996 Sizzle.error( "unsupported lang: " + lang ); 1997 } 1998 lang = lang.replace( runescape, funescape ).toLowerCase(); 1999 return function( elem ) { 2000 var elemLang; 2001 do { 2002 if ( (elemLang = documentIsHTML ? 2003 elem.lang : 2004 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 2005 2006 elemLang = elemLang.toLowerCase(); 2007 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 2008 } 2009 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 2010 return false;
vendor: 3,169 bytes, lines 2011-2125
2011 }; 2012 }), 2013 2014 // Miscellaneous 2015 "target": function( elem ) { 2016 var hash = window.location && window.location.hash; 2017 return hash && hash.slice( 1 ) === elem.id; 2018 }, 2019 2020 "root": function( elem ) { 2021 return elem === docElem; 2022 }, 2023 2024 "focus": function( elem ) { 2025 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 2026 }, 2027 2028 // Boolean properties 2029 "enabled": createDisabledPseudo( false ), 2030 "disabled": createDisabledPseudo( true ), 2031 2032 "checked": function( elem ) { 2033 // In CSS3, :checked should return both checked and selected elements 2034 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 2035 var nodeName = elem.nodeName.toLowerCase(); 2036 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 2037 }, 2038 2039 "selected": function( elem ) { 2040 // Accessing this property makes selected-by-default 2041 // options in Safari work properly 2042 if ( elem.parentNode ) { 2043 elem.parentNode.selectedIndex; 2044 } 2045 2046 return elem.selected === true; 2047 }, 2048 2049 // Contents 2050 "empty": function( elem ) { 2051 // http://www.w3.org/TR/selectors/#empty-pseudo 2052 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 2053 // but not by others (comment: 8; processing instruction: 7; etc.) 2054 // nodeType < 6 works because attributes (2) do not appear as children 2055 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 2056 if ( elem.nodeType < 6 ) { 2057 return false; 2058 } 2059 } 2060 return true; 2061 }, 2062 2063 "parent": function( elem ) { 2064 return !Expr.pseudos["empty"]( elem ); 2065 }, 2066 2067 // Element/input types 2068 "header": function( elem ) { 2069 return rheader.test( elem.nodeName ); 2070 }, 2071 2072 "input": function( elem ) { 2073 return rinputs.test( elem.nodeName ); 2074 }, 2075 2076 "button": function( elem ) { 2077 var name = elem.nodeName.toLowerCase(); 2078 return name === "input" && elem.type === "button" || name === "button"; 2079 }, 2080 2081 "text": function( elem ) { 2082 var attr; 2083 return elem.nodeName.toLowerCase() === "input" && 2084 elem.type === "text" && 2085 2086 // Support: IE<8 2087 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 2088 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 2089 }, 2090 2091 // Position-in-collection 2092 "first": createPositionalPseudo(function() { 2093 return [ 0 ]; 2094 }), 2095 2096 "last": createPositionalPseudo(function( matchIndexes, length ) { 2097 return [ length - 1 ]; 2098 }), 2099 2100 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 2101 return [ argument < 0 ? argument + length : argument ]; 2102 }), 2103 2104 "even": createPositionalPseudo(function( matchIndexes, length ) { 2105 var i = 0; 2106 for ( ; i < length; i += 2 ) { 2107 matchIndexes.push( i ); 2108 } 2109 return matchIndexes; 2110 }), 2111 2112 "odd": createPositionalPseudo(function( matchIndexes, length ) { 2113 var i = 1; 2114 for ( ; i < length; i += 2 ) { 2115 matchIndexes.push( i ); 2116 } 2117 return matchIndexes; 2118 }), 2119 2120 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2121 var i = argument < 0 ? 2122 argument + length : 2123 argument > length ? 2124 length : 2125
vendor: 20,845 bytes, lines 2125-2886
2125argument; 2126 for ( ; --i >= 0; ) { 2127 matchIndexes.push( i ); 2128 } 2129 return matchIndexes; 2130 }), 2131 2132 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 2133 var i = argument < 0 ? argument + length : argument; 2134 for ( ; ++i < length; ) { 2135 matchIndexes.push( i ); 2136 } 2137 return matchIndexes; 2138 }) 2139 } 2140}; 2141 2142Expr.pseudos["nth"] = Expr.pseudos["eq"]; 2143 2144// Add button/input type pseudos 2145for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2146 Expr.pseudos[ i ] = createInputPseudo( i ); 2147} 2148for ( i in { submit: true, reset: true } ) { 2149 Expr.pseudos[ i ] = createButtonPseudo( i ); 2150} 2151 2152// Easy API for creating new setFilters 2153function setFilters() {} 2154setFilters.prototype = Expr.filters = Expr.pseudos; 2155Expr.setFilters = new setFilters(); 2156 2157tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 2158 var matched, match, tokens, type, 2159 soFar, groups, preFilters, 2160 cached = tokenCache[ selector + " " ]; 2161 2162 if ( cached ) { 2163 return parseOnly ? 0 : cached.slice( 0 ); 2164 } 2165 2166 soFar = selector; 2167 groups = []; 2168 preFilters = Expr.preFilter; 2169 2170 while ( soFar ) { 2171 2172 // Comma and first run 2173 if ( !matched || (match = rcomma.exec( soFar )) ) { 2174 if ( match ) { 2175 // Don't consume trailing commas as valid 2176 soFar = soFar.slice( match[0].length ) || soFar; 2177 } 2178 groups.push( (tokens = []) ); 2179 } 2180 2181 matched = false; 2182 2183 // Combinators 2184 if ( (match = rcombinators.exec( soFar )) ) { 2185 matched = match.shift(); 2186 tokens.push({ 2187 value: matched, 2188 // Cast descendant combinators to space 2189 type: match[0].replace( rtrim, " " ) 2190 }); 2191 soFar = soFar.slice( matched.length ); 2192 } 2193 2194 // Filters 2195 for ( type in Expr.filter ) { 2196 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 2197 (match = preFilters[ type ]( match ))) ) { 2198 matched = match.shift(); 2199 tokens.push({ 2200 value: matched, 2201 type: type, 2202 matches: match 2203 }); 2204 soFar = soFar.slice( matched.length ); 2205 } 2206 } 2207 2208 if ( !matched ) { 2209 break; 2210 } 2211 } 2212 2213 // Return the length of the invalid excess 2214 // if we're just parsing 2215 // Otherwise, throw an error or return tokens 2216 return parseOnly ? 2217 soFar.length : 2218 soFar ? 2219 Sizzle.error( selector ) : 2220 // Cache the tokens 2221 tokenCache( selector, groups ).slice( 0 ); 2222}; 2223 2224function toSelector( tokens ) { 2225 var i = 0, 2226 len = tokens.length, 2227 selector = ""; 2228 for ( ; i < len; i++ ) { 2229 selector += tokens[i].value; 2230 } 2231 return selector; 2232} 2233 2234function addCombinator( matcher, combinator, base ) { 2235 var dir = combinator.dir, 2236 skip = combinator.next, 2237 key = skip || dir, 2238 checkNonElements = base && key === "parentNode", 2239 doneName = done++; 2240 2241 return combinator.first ? 2242 // Check against closest ancestor/preceding element 2243 function( elem, context, xml ) { 2244 while ( (elem = elem[ dir ]) ) { 2245 if ( elem.nodeType === 1 || checkNonElements ) { 2246 return matcher( elem, context, xml ); 2247 } 2248 } 2249 return false; 2250 } : 2251 2252 // Check against all ancestor/preceding elements 2253 function( elem, context, xml ) { 2254 var oldCache, uniqueCache, outerCache, 2255 newCache = [ dirruns, doneName ]; 2256 2257 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2258 if ( xml ) { 2259 while ( (elem = elem[ dir ]) ) { 2260 if ( elem.nodeType === 1 || checkNonElements ) { 2261 if ( matcher( elem, context, xml ) ) { 2262 return true; 2263 } 2264 } 2265 } 2266 } else { 2267 while ( (elem = elem[ dir ]) ) { 2268 if ( elem.nodeType === 1 || checkNonElements ) { 2269 outerCache = elem[ expando ] || (elem[ expando ] = {}); 2270 2271 // Support: IE <9 only 2272 // Defend against cloned attroperties (jQuery gh-1709) 2273 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); 2274 2275 if ( skip && skip === elem.nodeName.toLowerCase() ) { 2276 elem = elem[ dir ] || elem; 2277 } else if ( (oldCache = uniqueCache[ key ]) && 2278 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2279 2280 // Assign to newCache so results back-propagate to previous elements 2281 return (newCache[ 2 ] = oldCache[ 2 ]); 2282 } else { 2283 // Reuse newcache so results back-propagate to previous elements 2284 uniqueCache[ key ] = newCache; 2285 2286 // A match means we're done; a fail means we have to keep checking 2287 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 2288 return true; 2289 } 2290 } 2291 } 2292 } 2293 } 2294 return false; 2295 }; 2296} 2297 2298function elementMatcher( matchers ) { 2299 return matchers.length > 1 ? 2300 function( elem, context, xml ) { 2301 var i = matchers.length; 2302 while ( i-- ) { 2303 if ( !matchers[i]( elem, context, xml ) ) { 2304 return false; 2305 } 2306 } 2307 return true; 2308 } : 2309 matchers[0]; 2310} 2311 2312function multipleContexts( selector, contexts, results ) { 2313 var i = 0, 2314 len = contexts.length; 2315 for ( ; i < len; i++ ) { 2316 Sizzle( selector, contexts[i], results ); 2317 } 2318 return results; 2319} 2320 2321function condense( unmatched, map, filter, context, xml ) { 2322 var elem, 2323 newUnmatched = [], 2324 i = 0, 2325 len = unmatched.length, 2326 mapped = map != null; 2327 2328 for ( ; i < len; i++ ) { 2329 if ( (elem = unmatched[i]) ) { 2330 if ( !filter || filter( elem, context, xml ) ) { 2331 newUnmatched.push( elem ); 2332 if ( mapped ) { 2333 map.push( i ); 2334 } 2335 } 2336 } 2337 } 2338 2339 return newUnmatched; 2340} 2341 2342function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2343 if ( postFilter && !postFilter[ expando ] ) { 2344 postFilter = setMatcher( postFilter ); 2345 } 2346 if ( postFinder && !postFinder[ expando ] ) { 2347 postFinder = setMatcher( postFinder, postSelector ); 2348 } 2349 return markFunction(function( seed, results, context, xml ) { 2350 var temp, i, elem, 2351 preMap = [], 2352 postMap = [], 2353 preexisting = results.length, 2354 2355 // Get initial elements from seed or context 2356 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 2357 2358 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2359 matcherIn = preFilter && ( seed || !selector ) ? 2360 condense( elems, preMap, preFilter, context, xml ) : 2361 elems, 2362 2363 matcherOut = matcher ? 2364 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2365 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2366 2367 // ...intermediate processing is necessary 2368 [] : 2369 2370 // ...otherwise use results directly 2371 results : 2372 matcherIn; 2373 2374 // Find primary matches 2375 if ( matcher ) { 2376 matcher( matcherIn, matcherOut, context, xml ); 2377 } 2378 2379 // Apply postFilter 2380 if ( postFilter ) { 2381 temp = condense( matcherOut, postMap ); 2382 postFilter( temp, [], context, xml ); 2383 2384 // Un-match failing elements by moving them back to matcherIn 2385 i = temp.length; 2386 while ( i-- ) { 2387 if ( (elem = temp[i]) ) { 2388 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 2389 } 2390 } 2391 } 2392 2393 if ( seed ) { 2394 if ( postFinder || preFilter ) { 2395 if ( postFinder ) { 2396 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2397 temp = []; 2398 i = matcherOut.length; 2399 while ( i-- ) { 2400 if ( (elem = matcherOut[i]) ) { 2401 // Restore matcherIn since elem is not yet a final match 2402 temp.push( (matcherIn[i] = elem) ); 2403 } 2404 } 2405 postFinder( null, (matcherOut = []), temp, xml ); 2406 } 2407 2408 // Move matched elements from seed to results to keep them synchronized 2409 i = matcherOut.length; 2410 while ( i-- ) { 2411 if ( (elem = matcherOut[i]) && 2412 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 2413 2414 seed[temp] = !(results[temp] = elem); 2415 } 2416 } 2417 } 2418 2419 // Add elements to results, through postFinder if defined 2420 } else { 2421 matcherOut = condense( 2422 matcherOut === results ? 2423 matcherOut.splice( preexisting, matcherOut.length ) : 2424 matcherOut 2425 ); 2426 if ( postFinder ) { 2427 postFinder( null, results, matcherOut, xml ); 2428 } else { 2429 push.apply( results, matcherOut ); 2430 } 2431 } 2432 }); 2433} 2434 2435function matcherFromTokens( tokens ) { 2436 var checkContext, matcher, j, 2437 len = tokens.length, 2438 leadingRelative = Expr.relative[ tokens[0].type ], 2439 implicitRelative = leadingRelative || Expr.relative[" "], 2440 i = leadingRelative ? 1 : 0, 2441 2442 // The foundational matcher ensures that elements are reachable from top-level context(s) 2443 matchContext = addCombinator( function( elem ) { 2444 return elem === checkContext; 2445 }, implicitRelative, true ), 2446 matchAnyContext = addCombinator( function( elem ) { 2447 return indexOf( checkContext, elem ) > -1; 2448 }, implicitRelative, true ), 2449 matchers = [ function( elem, context, xml ) { 2450 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 2451 (checkContext = context).nodeType ? 2452 matchContext( elem, context, xml ) : 2453 matchAnyContext( elem, context, xml ) ); 2454 // Avoid hanging onto element (issue #299) 2455 checkContext = null; 2456 return ret; 2457 } ]; 2458 2459 for ( ; i < len; i++ ) { 2460 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 2461 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 2462 } else { 2463 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 2464 2465 // Return special upon seeing a positional matcher 2466 if ( matcher[ expando ] ) { 2467 // Find the next relative operator (if any) for proper handling 2468 j = ++i; 2469 for ( ; j < len; j++ ) { 2470 if ( Expr.relative[ tokens[j].type ] ) { 2471 break; 2472 } 2473 } 2474 return setMatcher( 2475 i > 1 && elementMatcher( matchers ), 2476 i > 1 && toSelector( 2477 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2478 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 2479 ).replace( rtrim, "$1" ), 2480 matcher, 2481 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2482 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 2483 j < len && toSelector( tokens ) 2484 ); 2485 } 2486 matchers.push( matcher ); 2487 } 2488 } 2489 2490 return elementMatcher( matchers ); 2491} 2492 2493function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2494 var bySet = setMatchers.length > 0, 2495 byElement = elementMatchers.length > 0, 2496 superMatcher = function( seed, context, xml, results, outermost ) { 2497 var elem, j, matcher, 2498 matchedCount = 0, 2499 i = "0", 2500 unmatched = seed && [], 2501 setMatched = [], 2502 contextBackup = outermostContext, 2503 // We must always have either seed elements or outermost context 2504 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 2505 // Use integer dirruns iff this is the outermost matcher 2506 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 2507 len = elems.length; 2508 2509 if ( outermost ) { 2510 outermostContext = context === document || context || outermost; 2511 } 2512 2513 // Add elements passing elementMatchers directly to results 2514 // Support: IE<9, Safari 2515 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2516 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 2517 if ( byElement && elem ) { 2518 j = 0; 2519 if ( !context && elem.ownerDocument !== document ) { 2520 setDocument( elem ); 2521 xml = !documentIsHTML; 2522 } 2523 while ( (matcher = elementMatchers[j++]) ) { 2524 if ( matcher( elem, context || document, xml) ) { 2525 results.push( elem ); 2526 break; 2527 } 2528 } 2529 if ( outermost ) { 2530 dirruns = dirrunsUnique; 2531 } 2532 } 2533 2534 // Track unmatched elements for set filters 2535 if ( bySet ) { 2536 // They will have gone through all possible matchers 2537 if ( (elem = !matcher && elem) ) { 2538 matchedCount--; 2539 } 2540 2541 // Lengthen the array for every element, matched or not 2542 if ( seed ) { 2543 unmatched.push( elem ); 2544 } 2545 } 2546 } 2547 2548 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2549 // makes the latter nonnegative. 2550 matchedCount += i; 2551 2552 // Apply set filters to unmatched elements 2553 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2554 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2555 // no element matchers and no seed. 2556 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2557 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2558 // numerically zero. 2559 if ( bySet && i !== matchedCount ) { 2560 j = 0; 2561 while ( (matcher = setMatchers[j++]) ) { 2562 matcher( unmatched, setMatched, context, xml ); 2563 } 2564 2565 if ( seed ) { 2566 // Reintegrate element matches to eliminate the need for sorting 2567 if ( matchedCount > 0 ) { 2568 while ( i-- ) { 2569 if ( !(unmatched[i] || setMatched[i]) ) { 2570 setMatched[i] = pop.call( results ); 2571 } 2572 } 2573 } 2574 2575 // Discard index placeholder values to get only actual matches 2576 setMatched = condense( setMatched ); 2577 } 2578 2579 // Add matches to results 2580 push.apply( results, setMatched ); 2581 2582 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2583 if ( outermost && !seed && setMatched.length > 0 && 2584 ( matchedCount + setMatchers.length ) > 1 ) { 2585 2586 Sizzle.uniqueSort( results ); 2587 } 2588 } 2589 2590 // Override manipulation of globals by nested matchers 2591 if ( outermost ) { 2592 dirruns = dirrunsUnique; 2593 outermostContext = contextBackup; 2594 } 2595 2596 return unmatched; 2597 }; 2598 2599 return bySet ? 2600 markFunction( superMatcher ) : 2601 superMatcher; 2602} 2603 2604compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 2605 var i, 2606 setMatchers = [], 2607 elementMatchers = [], 2608 cached = compilerCache[ selector + " " ]; 2609 2610 if ( !cached ) { 2611 // Generate a function of recursive functions that can be used to check each element 2612 if ( !match ) { 2613 match = tokenize( selector ); 2614 } 2615 i = match.length; 2616 while ( i-- ) { 2617 cached = matcherFromTokens( match[i] ); 2618 if ( cached[ expando ] ) { 2619 setMatchers.push( cached ); 2620 } else { 2621 elementMatchers.push( cached ); 2622 } 2623 } 2624 2625 // Cache the compiled function 2626 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2627 2628 // Save selector and tokenization 2629 cached.selector = selector; 2630 } 2631 return cached; 2632}; 2633 2634/** 2635 * A low-level selection function that works with Sizzle's compiled 2636 * selector functions 2637 * @param {String|Function} selector A selector or a pre-compiled 2638 * selector function built with Sizzle.compile 2639 * @param {Element} context 2640 * @param {Array} [results] 2641 * @param {Array} [seed] A set of elements to match against 2642 */ 2643select = Sizzle.select = function( selector, context, results, seed ) { 2644 var i, tokens, token, type, find, 2645 compiled = typeof selector === "function" && selector, 2646 match = !seed && tokenize( (selector = compiled.selector || selector) ); 2647 2648 results = results || []; 2649 2650 // Try to minimize operations if there is only one selector in the list and no seed 2651 // (the latter of which guarantees us context) 2652 if ( match.length === 1 ) { 2653 2654 // Reduce context if the leading compound selector is an ID 2655 tokens = match[0] = match[0].slice( 0 ); 2656 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 2657 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { 2658 2659 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 2660 if ( !context ) { 2661 return results; 2662 2663 // Precompiled matchers will still verify ancestry, so step up a level 2664 } else if ( compiled ) { 2665 context = context.parentNode; 2666 } 2667 2668 selector = selector.slice( tokens.shift().value.length ); 2669 } 2670 2671 // Fetch a seed set for right-to-left matching 2672 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 2673 while ( i-- ) { 2674 token = tokens[i]; 2675 2676 // Abort if we hit a combinator 2677 if ( Expr.relative[ (type = token.type) ] ) { 2678 break; 2679 } 2680 if ( (find = Expr.find[ type ]) ) { 2681 // Search, expanding context for leading sibling combinators 2682 if ( (seed = find( 2683 token.matches[0].replace( runescape, funescape ), 2684 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 2685 )) ) { 2686 2687 // If seed is empty or no tokens remain, we can return early 2688 tokens.splice( i, 1 ); 2689 selector = seed.length && toSelector( tokens ); 2690 if ( !selector ) { 2691 push.apply( results, seed ); 2692 return results; 2693 } 2694 2695 break; 2696 } 2697 } 2698 } 2699 } 2700 2701 // Compile and execute a filtering function if one is not provided 2702 // Provide `match` to avoid retokenization if we modified the selector above 2703 ( compiled || compile( selector, match ) )( 2704 seed, 2705 context, 2706 !documentIsHTML, 2707 results, 2708 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2709 ); 2710 return results; 2711}; 2712 2713// One-time assignments 2714 2715// Sort stability 2716support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 2717 2718// Support: Chrome 14-35+ 2719// Always assume duplicates if they aren't passed to the comparison function 2720support.detectDuplicates = !!hasDuplicate; 2721 2722// Initialize against the default document 2723setDocument(); 2724 2725// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 2726// Detached nodes confoundingly follow *each other* 2727support.sortDetached = assert(function( el ) { 2728 // Should return 1, but returns 4 (following) 2729 return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; 2730}); 2731 2732// Support: IE<8 2733// Prevent attribute/property "interpolation" 2734// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 2735if ( !assert(function( el ) { 2736 el.innerHTML = "<a href='#'></a>"; 2737 return el.firstChild.getAttribute("href") === "#" ; 2738}) ) { 2739 addHandle( "type|href|height|width", function( elem, name, isXML ) { 2740 if ( !isXML ) { 2741 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 2742 } 2743 }); 2744} 2745 2746// Support: IE<9 2747// Use defaultValue in place of getAttribute("value") 2748if ( !support.attributes || !assert(function( el ) { 2749 el.innerHTML = "<input/>"; 2750 el.firstChild.setAttribute( "value", "" ); 2751 return el.firstChild.getAttribute( "value" ) === ""; 2752}) ) { 2753 addHandle( "value", function( elem, name, isXML ) { 2754 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 2755 return elem.defaultValue; 2756 } 2757 }); 2758} 2759 2760// Support: IE<9 2761// Use getAttributeNode to fetch booleans when getAttribute lies 2762if ( !assert(function( el ) { 2763 return el.getAttribute("disabled") == null; 2764}) ) { 2765 addHandle( booleans, function( elem, name, isXML ) { 2766 var val; 2767 if ( !isXML ) { 2768 return elem[ name ] === true ? name.toLowerCase() : 2769 (val = elem.getAttributeNode( name )) && val.specified ? 2770 val.value : 2771 null; 2772 } 2773 }); 2774} 2775 2776return Sizzle; 2777 2778})( window ); 2779 2780 2781 2782jQuery.find = Sizzle; 2783jQuery.expr = Sizzle.selectors; 2784 2785// Deprecated 2786jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2787jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 2788jQuery.text = Sizzle.getText; 2789jQuery.isXMLDoc = Sizzle.isXML; 2790jQuery.contains = Sizzle.contains; 2791jQuery.escapeSelector = Sizzle.escape; 2792 2793 2794 2795 2796var dir = function( elem, dir, until ) { 2797 var matched = [], 2798 truncate = until !== undefined; 2799 2800 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 2801 if ( elem.nodeType === 1 ) { 2802 if ( truncate && jQuery( elem ).is( until ) ) { 2803 break; 2804 } 2805 matched.push( elem ); 2806 } 2807 } 2808 return matched; 2809}; 2810 2811 2812var siblings = function( n, elem ) { 2813 var matched = []; 2814 2815 for ( ; n; n = n.nextSibling ) { 2816 if ( n.nodeType === 1 && n !== elem ) { 2817 matched.push( n ); 2818 } 2819 } 2820 2821 return matched; 2822}; 2823 2824 2825var rneedsContext = jQuery.expr.match.needsContext; 2826 2827 2828 2829function nodeName( elem, name ) { 2830 2831 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 2832 2833}; 2834var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 2835 2836 2837 2838// Implement the identical functionality for filter and not 2839function winnow( elements, qualifier, not ) { 2840 if ( isFunction( qualifier ) ) { 2841 return jQuery.grep( elements, function( elem, i ) { 2842 return !!qualifier.call( elem, i, elem ) !== not; 2843 } ); 2844 } 2845 2846 // Single element 2847 if ( qualifier.nodeType ) { 2848 return jQuery.grep( elements, function( elem ) { 2849 return ( elem === qualifier ) !== not; 2850 } ); 2851 } 2852 2853 // Arraylike of elements (jQuery, arguments, Array) 2854 if ( typeof qualifier !== "string" ) { 2855 return jQuery.grep( elements, function( elem ) { 2856 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 2857 } ); 2858 } 2859 2860 // Filtered directly for both simple and complex selectors 2861 return jQuery.filter( qualifier, elements, not ); 2862} 2863 2864jQuery.filter = function( expr, elems, not ) { 2865 var elem = elems[ 0 ]; 2866 2867 if ( not ) { 2868 expr = ":not(" + expr + ")"; 2869 } 2870 2871 if ( elems.length === 1 && elem.nodeType === 1 ) { 2872 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 2873 } 2874 2875 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2876 return elem.nodeType === 1; 2877 } ) ); 2878}; 2879 2880jQuery.fn.extend( { 2881 find: function( selector ) { 2882 var i, ret, 2883 len = this.length, 2884 self = this; 2885 2886 if ( typeof selector !== "string" ) {
vendor: 6,536 bytes, lines 2887-3147
2887 return this.pushStack( jQuery( selector ).filter( function() { 2888 for ( i = 0; i < len; i++ ) { 2889 if ( jQuery.contains( self[ i ], this ) ) { 2890 return true; 2891 } 2892 } 2893 } ) ); 2894 } 2895 2896 ret = this.pushStack( [] ); 2897 2898 for ( i = 0; i < len; i++ ) { 2899 jQuery.find( selector, self[ i ], ret ); 2900 } 2901 2902 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 2903 }, 2904 filter: function( selector ) { 2905 return this.pushStack( winnow( this, selector || [], false ) ); 2906 }, 2907 not: function( selector ) { 2908 return this.pushStack( winnow( this, selector || [], true ) ); 2909 }, 2910 is: function( selector ) { 2911 return !!winnow( 2912 this, 2913 2914 // If this is a positional/relative selector, check membership in the returned set 2915 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2916 typeof selector === "string" && rneedsContext.test( selector ) ? 2917 jQuery( selector ) : 2918 selector || [], 2919 false 2920 ).length; 2921 } 2922} ); 2923 2924 2925// Initialize a jQuery object 2926 2927 2928// A central reference to the root jQuery(document) 2929var rootjQuery, 2930 2931 // A simple way to check for HTML strings 2932 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 2933 // Strict HTML recognition (#11290: must start with <) 2934 // Shortcut simple #id case for speed 2935 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 2936 2937 init = jQuery.fn.init = function( selector, context, root ) { 2938 var match, elem; 2939 2940 // HANDLE: $(""), $(null), $(undefined), $(false) 2941 if ( !selector ) { 2942 return this; 2943 } 2944 2945 // Method init() accepts an alternate rootjQuery 2946 // so migrate can support jQuery.sub (gh-2101) 2947 root = root || rootjQuery; 2948 2949 // Handle HTML strings 2950 if ( typeof selector === "string" ) { 2951 if ( selector[ 0 ] === "<" && 2952 selector[ selector.length - 1 ] === ">" && 2953 selector.length >= 3 ) { 2954 2955 // Assume that strings that start and end with <> are HTML and skip the regex check 2956 match = [ null, selector, null ]; 2957 2958 } else { 2959 match = rquickExpr.exec( selector ); 2960 } 2961 2962 // Match html or make sure no context is specified for #id 2963 if ( match && ( match[ 1 ] || !context ) ) { 2964 2965 // HANDLE: $(html) -> $(array) 2966 if ( match[ 1 ] ) { 2967 context = context instanceof jQuery ? context[ 0 ] : context; 2968 2969 // Option to run scripts is true for back-compat 2970 // Intentionally let the error be thrown if parseHTML is not present 2971 jQuery.merge( this, jQuery.parseHTML( 2972 match[ 1 ], 2973 context && context.nodeType ? context.ownerDocument || context : document, 2974 true 2975 ) ); 2976 2977 // HANDLE: $(html, props) 2978 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 2979 for ( match in context ) { 2980 2981 // Properties of context are called as methods if possible 2982 if ( isFunction( this[ match ] ) ) { 2983 this[ match ]( context[ match ] ); 2984 2985 // ...and otherwise set as attributes 2986 } else { 2987 this.attr( match, context[ match ] ); 2988 } 2989 } 2990 } 2991 2992 return this; 2993 2994 // HANDLE: $(#id) 2995 } else { 2996 elem = document.getElementById( match[ 2 ] ); 2997 2998 if ( elem ) { 2999 3000 // Inject the element directly into the jQuery object 3001 this[ 0 ] = elem; 3002 this.length = 1; 3003 } 3004 return this; 3005 } 3006 3007 // HANDLE: $(expr, $(...)) 3008 } else if ( !context || context.jquery ) { 3009 return ( context || root ).find( selector ); 3010 3011 // HANDLE: $(expr, context) 3012 // (which is just equivalent to: $(context).find(expr) 3013 } else { 3014 return this.constructor( context ).find( selector ); 3015 } 3016 3017 // HANDLE: $(DOMElement) 3018 } else if ( selector.nodeType ) { 3019 this[ 0 ] = selector; 3020 this.length = 1; 3021 return this; 3022 3023 // HANDLE: $(function) 3024 // Shortcut for document ready 3025 } else if ( isFunction( selector ) ) { 3026 return root.ready !== undefined ? 3027 root.ready( selector ) : 3028 3029 // Execute immediately if ready is not present 3030 selector( jQuery ); 3031 } 3032 3033 return jQuery.makeArray( selector, this ); 3034 }; 3035 3036// Give the init function the jQuery prototype for later instantiation 3037init.prototype = jQuery.fn; 3038 3039// Initialize central reference 3040rootjQuery = jQuery( document ); 3041 3042 3043var rparentsprev = /^(?:parents|prev(?:Until|All))/, 3044 3045 // Methods guaranteed to produce a unique set when starting from a unique set 3046 guaranteedUnique = { 3047 children: true, 3048 contents: true, 3049 next: true, 3050 prev: true 3051 }; 3052 3053jQuery.fn.extend( { 3054 has: function( target ) { 3055 var targets = jQuery( target, this ), 3056 l = targets.length; 3057 3058 return this.filter( function() { 3059 var i = 0; 3060 for ( ; i < l; i++ ) { 3061 if ( jQuery.contains( this, targets[ i ] ) ) { 3062 return true; 3063 } 3064 } 3065 } ); 3066 }, 3067 3068 closest: function( selectors, context ) { 3069 var cur, 3070 i = 0, 3071 l = this.length, 3072 matched = [], 3073 targets = typeof selectors !== "string" && jQuery( selectors ); 3074 3075 // Positional selectors never match, since there's no _selection_ context 3076 if ( !rneedsContext.test( selectors ) ) { 3077 for ( ; i < l; i++ ) { 3078 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3079 3080 // Always skip document fragments 3081 if ( cur.nodeType < 11 && ( targets ? 3082 targets.index( cur ) > -1 : 3083 3084 // Don't pass non-elements to Sizzle 3085 cur.nodeType === 1 && 3086 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3087 3088 matched.push( cur ); 3089 break; 3090 } 3091 } 3092 } 3093 } 3094 3095 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3096 }, 3097 3098 // Determine the position of an element within the set 3099 index: function( elem ) { 3100 3101 // No argument, return index in parent 3102 if ( !elem ) { 3103 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3104 } 3105 3106 // Index in selector 3107 if ( typeof elem === "string" ) { 3108 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3109 } 3110 3111 // Locate the position of the desired element 3112 return indexOf.call( this, 3113 3114 // If it receives a jQuery object, the first element is used 3115 elem.jquery ? elem[ 0 ] : elem 3116 ); 3117 }, 3118 3119 add: function( selector, context ) { 3120 return this.pushStack( 3121 jQuery.uniqueSort( 3122 jQuery.merge( this.get(), jQuery( selector, context ) ) 3123 ) 3124 ); 3125 }, 3126 3127 addBack: function( selector ) { 3128 return this.add( selector == null ? 3129 this.prevObject : this.prevObject.filter( selector ) 3130 ); 3131 } 3132} ); 3133 3134function sibling( cur, dir ) { 3135 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3136 return cur; 3137} 3138 3139jQuery.each( { 3140 parent: function( elem ) { 3141 var parent = elem.parentNode; 3142 return parent && parent.nodeType !== 11 ? parent : null; 3143 }, 3144 parents: function( elem ) { 3145 return dir( elem, "parentNode" ); 3146 }, 3147 parentsUntil: function( elem,
3147i, until ) { 3148 return dir( elem, "parentNode", until ); 3149 }, 3150 next: function( elem ) { 3151 return sibling( elem, "nextSibling" ); 3152 }, 3153 prev: function( elem ) { 3154 return sibling( elem, "previousSibling" ); 3155 }, 3156 nextAll: function( elem ) { 3157 return dir( elem, "nextSibling" ); 3158 }, 3159 prevAll: function( elem ) { 3160 return dir( elem, "previousSibling" ); 3161 }, 3162 nextUntil: function( elem, i, until ) { 3163 return dir( elem, "nextSibling", until ); 3164 }, 3165 prevUntil: function( elem, i, until ) { 3166 return dir( elem, "previousSibling", until ); 3167 }, 3168 siblings: function( elem ) { 3169 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3170 }, 3171 children: function( elem ) { 3172 return siblings( elem.firstChild ); 3173 }, 3174 contents: function( elem ) { 3175 if ( typeof elem.contentDocument !== "undefined" ) {
vendor: 8,211 bytes, lines 3175-3509
3175 3176 return elem.contentDocument; 3177 } 3178 3179 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3180 // Treat the template element as a regular one in browsers that 3181 // don't support it. 3182 if ( nodeName( elem, "template" ) ) { 3183 elem = elem.content || elem; 3184 } 3185 3186 return jQuery.merge( [], elem.childNodes ); 3187 } 3188}, function( name, fn ) { 3189 jQuery.fn[ name ] = function( until, selector ) { 3190 var matched = jQuery.map( this, fn, until ); 3191 3192 if ( name.slice( -5 ) !== "Until" ) { 3193 selector = until; 3194 } 3195 3196 if ( selector && typeof selector === "string" ) { 3197 matched = jQuery.filter( selector, matched ); 3198 } 3199 3200 if ( this.length > 1 ) { 3201 3202 // Remove duplicates 3203 if ( !guaranteedUnique[ name ] ) { 3204 jQuery.uniqueSort( matched ); 3205 } 3206 3207 // Reverse order for parents* and prev-derivatives 3208 if ( rparentsprev.test( name ) ) { 3209 matched.reverse(); 3210 } 3211 } 3212 3213 return this.pushStack( matched ); 3214 }; 3215} ); 3216var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 3217 3218 3219 3220// Convert String-formatted options into Object-formatted ones 3221function createOptions( options ) { 3222 var object = {}; 3223 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 3224 object[ flag ] = true; 3225 } ); 3226 return object; 3227} 3228 3229/* 3230 * Create a callback list using the following parameters: 3231 * 3232 * options: an optional list of space-separated options that will change how 3233 * the callback list behaves or a more traditional option object 3234 * 3235 * By default a callback list will act like an event callback list and can be 3236 * "fired" multiple times. 3237 * 3238 * Possible options: 3239 * 3240 * once: will ensure the callback list can only be fired once (like a Deferred) 3241 * 3242 * memory: will keep track of previous values and will call any callback added 3243 * after the list has been fired right away with the latest "memorized" 3244 * values (like a Deferred) 3245 * 3246 * unique: will ensure a callback can only be added once (no duplicate in the list) 3247 * 3248 * stopOnFalse: interrupt callings when a callback returns false 3249 * 3250 */ 3251jQuery.Callbacks = function( options ) { 3252 3253 // Convert options from String-formatted to Object-formatted if needed 3254 // (we check in cache first) 3255 options = typeof options === "string" ? 3256 createOptions( options ) : 3257 jQuery.extend( {}, options ); 3258 3259 var // Flag to know if list is currently firing 3260 firing, 3261 3262 // Last fire value for non-forgettable lists 3263 memory, 3264 3265 // Flag to know if list was already fired 3266 fired, 3267 3268 // Flag to prevent firing 3269 locked, 3270 3271 // Actual callback list 3272 list = [], 3273 3274 // Queue of execution data for repeatable lists 3275 queue = [], 3276 3277 // Index of currently firing callback (modified by add/remove as needed) 3278 firingIndex = -1, 3279 3280 // Fire callbacks 3281 fire = function() { 3282 3283 // Enforce single-firing 3284 locked = locked || options.once; 3285 3286 // Execute callbacks for all pending executions, 3287 // respecting firingIndex overrides and runtime changes 3288 fired = firing = true; 3289 for ( ; queue.length; firingIndex = -1 ) { 3290 memory = queue.shift(); 3291 while ( ++firingIndex < list.length ) { 3292 3293 // Run callback and check for early termination 3294 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3295 options.stopOnFalse ) { 3296 3297 // Jump to end and forget the data so .add doesn't re-fire 3298 firingIndex = list.length; 3299 memory = false; 3300 } 3301 } 3302 } 3303 3304 // Forget the data if we're done with it 3305 if ( !options.memory ) { 3306 memory = false; 3307 } 3308 3309 firing = false; 3310 3311 // Clean up if we're done firing for good 3312 if ( locked ) { 3313 3314 // Keep an empty list if we have data for future add calls 3315 if ( memory ) { 3316 list = []; 3317 3318 // Otherwise, this object is spent 3319 } else { 3320 list = ""; 3321 } 3322 } 3323 }, 3324 3325 // Actual Callbacks object 3326 self = { 3327 3328 // Add a callback or a collection of callbacks to the list 3329 add: function() { 3330 if ( list ) { 3331 3332 // If we have memory from a past run, we should fire after adding 3333 if ( memory && !firing ) { 3334 firingIndex = list.length - 1; 3335 queue.push( memory ); 3336 } 3337 3338 ( function add( args ) { 3339 jQuery.each( args, function( _, arg ) { 3340 if ( isFunction( arg ) ) { 3341 if ( !options.unique || !self.has( arg ) ) { 3342 list.push( arg ); 3343 } 3344 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 3345 3346 // Inspect recursively 3347 add( arg ); 3348 } 3349 } ); 3350 } )( arguments ); 3351 3352 if ( memory && !firing ) { 3353 fire(); 3354 } 3355 } 3356 return this; 3357 }, 3358 3359 // Remove a callback from the list 3360 remove: function() { 3361 jQuery.each( arguments, function( _, arg ) { 3362 var index; 3363 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3364 list.splice( index, 1 ); 3365 3366 // Handle firing indexes 3367 if ( index <= firingIndex ) { 3368 firingIndex--; 3369 } 3370 } 3371 } ); 3372 return this; 3373 }, 3374 3375 // Check if a given callback is in the list. 3376 // If no argument is given, return whether or not list has callbacks attached. 3377 has: function( fn ) { 3378 return fn ? 3379 jQuery.inArray( fn, list ) > -1 : 3380 list.length > 0; 3381 }, 3382 3383 // Remove all callbacks from the list 3384 empty: function() { 3385 if ( list ) { 3386 list = []; 3387 } 3388 return this; 3389 }, 3390 3391 // Disable .fire and .add 3392 // Abort any current/pending executions 3393 // Clear all callbacks and values 3394 disable: function() { 3395 locked = queue = []; 3396 list = memory = ""; 3397 return this; 3398 }, 3399 disabled: function() { 3400 return !list; 3401 }, 3402 3403 // Disable .fire 3404 // Also disable .add unless we have memory (since it would have no effect) 3405 // Abort any pending executions 3406 lock: function() { 3407 locked = queue = []; 3408 if ( !memory && !firing ) { 3409 list = memory = ""; 3410 } 3411 return this; 3412 }, 3413 locked: function() { 3414 return !!locked; 3415 }, 3416 3417 // Call all callbacks with the given context and arguments 3418 fireWith: function( context, args ) { 3419 if ( !locked ) { 3420 args = args || []; 3421 args = [ context, args.slice ? args.slice() : args ]; 3422 queue.push( args ); 3423 if ( !firing ) { 3424 fire(); 3425 } 3426 } 3427 return this; 3428 }, 3429 3430 // Call all the callbacks with the given arguments 3431 fire: function() { 3432 self.fireWith( this, arguments ); 3433 return this; 3434 }, 3435 3436 // To know if the callbacks have already been called at least once 3437 fired: function() { 3438 return !!fired; 3439 } 3440 }; 3441 3442 return self; 3443}; 3444 3445 3446function Identity( v ) { 3447 return v; 3448} 3449function Thrower( ex ) { 3450 throw ex; 3451} 3452 3453function adoptValue( value, resolve, reject, noValue ) { 3454 var method; 3455 3456 try { 3457 3458 // Check for promise aspect first to privilege synchronous behavior 3459 if ( value && isFunction( ( method = value.promise ) ) ) { 3460 method.call( value ).done( resolve ).fail( reject ); 3461 3462 // Other thenables 3463 } else if ( value && isFunction( ( method = value.then ) ) ) { 3464 method.call( value, resolve, reject ); 3465 3466 // Other non-thenables 3467 } else { 3468 3469 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 3470 // * false: [ value ].slice( 0 ) => resolve( value ) 3471 // * true: [ value ].slice( 1 ) => resolve() 3472 resolve.apply( undefined, [ value ].slice( noValue ) ); 3473 } 3474 3475 // For Promises/A+, convert exceptions into rejections 3476 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 3477 // Deferred#then to conditionally suppress rejection. 3478 } catch ( value ) { 3479 3480 // Support: Android 4.0 only 3481 // Strict mode functions invoked without .call/.apply get global-object context 3482 reject.apply( undefined, [ value ] ); 3483 } 3484} 3485 3486jQuery.extend( { 3487 3488 Deferred: function( func ) { 3489 var tuples = [ 3490 3491 // action, add listener, callbacks, 3492 // ... .then handlers, argument index, [final state] 3493 [ "notify", "progress", jQuery.Callbacks( "memory" ), 3494 jQuery.Callbacks( "memory" ), 2 ], 3495 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 3496 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 3497 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 3498 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 3499 ], 3500 state = "pending", 3501 promise = { 3502 state: function() { 3503 return state; 3504 }, 3505 always: function() { 3506 deferred.done( arguments ).fail( arguments ); 3507 return this; 3508 }, 3509 "catch": function( fn ) {
vendor: 15,167 bytes, lines 3510-4101
3510 return promise.then( null, fn ); 3511 }, 3512 3513 // Keep pipe for back-compat 3514 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 3515 var fns = arguments; 3516 3517 return jQuery.Deferred( function( newDefer ) { 3518 jQuery.each( tuples, function( i, tuple ) { 3519 3520 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 3521 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 3522 3523 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 3524 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 3525 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 3526 deferred[ tuple[ 1 ] ]( function() { 3527 var returned = fn && fn.apply( this, arguments ); 3528 if ( returned && isFunction( returned.promise ) ) { 3529 returned.promise() 3530 .progress( newDefer.notify ) 3531 .done( newDefer.resolve ) 3532 .fail( newDefer.reject ); 3533 } else { 3534 newDefer[ tuple[ 0 ] + "With" ]( 3535 this, 3536 fn ? [ returned ] : arguments 3537 ); 3538 } 3539 } ); 3540 } ); 3541 fns = null; 3542 } ).promise(); 3543 }, 3544 then: function( onFulfilled, onRejected, onProgress ) { 3545 var maxDepth = 0; 3546 function resolve( depth, deferred, handler, special ) { 3547 return function() { 3548 var that = this, 3549 args = arguments, 3550 mightThrow = function() { 3551 var returned, then; 3552 3553 // Support: Promises/A+ section 2.3.3.3.3 3554 // https://promisesaplus.com/#point-59 3555 // Ignore double-resolution attempts 3556 if ( depth < maxDepth ) { 3557 return; 3558 } 3559 3560 returned = handler.apply( that, args ); 3561 3562 // Support: Promises/A+ section 2.3.1 3563 // https://promisesaplus.com/#point-48 3564 if ( returned === deferred.promise() ) { 3565 throw new TypeError( "Thenable self-resolution" ); 3566 } 3567 3568 // Support: Promises/A+ sections 2.3.3.1, 3.5 3569 // https://promisesaplus.com/#point-54 3570 // https://promisesaplus.com/#point-75 3571 // Retrieve `then` only once 3572 then = returned && 3573 3574 // Support: Promises/A+ section 2.3.4 3575 // https://promisesaplus.com/#point-64 3576 // Only check objects and functions for thenability 3577 ( typeof returned === "object" || 3578 typeof returned === "function" ) && 3579 returned.then; 3580 3581 // Handle a returned thenable 3582 if ( isFunction( then ) ) { 3583 3584 // Special processors (notify) just wait for resolution 3585 if ( special ) { 3586 then.call( 3587 returned, 3588 resolve( maxDepth, deferred, Identity, special ), 3589 resolve( maxDepth, deferred, Thrower, special ) 3590 ); 3591 3592 // Normal processors (resolve) also hook into progress 3593 } else { 3594 3595 // ...and disregard older resolution values 3596 maxDepth++; 3597 3598 then.call( 3599 returned, 3600 resolve( maxDepth, deferred, Identity, special ), 3601 resolve( maxDepth, deferred, Thrower, special ), 3602 resolve( maxDepth, deferred, Identity, 3603 deferred.notifyWith ) 3604 ); 3605 } 3606 3607 // Handle all other returned values 3608 } else { 3609 3610 // Only substitute handlers pass on context 3611 // and multiple values (non-spec behavior) 3612 if ( handler !== Identity ) { 3613 that = undefined; 3614 args = [ returned ]; 3615 } 3616 3617 // Process the value(s) 3618 // Default process is resolve 3619 ( special || deferred.resolveWith )( that, args ); 3620 } 3621 }, 3622 3623 // Only normal processors (resolve) catch and reject exceptions 3624 process = special ? 3625 mightThrow : 3626 function() { 3627 try { 3628 mightThrow(); 3629 } catch ( e ) { 3630 3631 if ( jQuery.Deferred.exceptionHook ) { 3632 jQuery.Deferred.exceptionHook( e, 3633 process.stackTrace ); 3634 } 3635 3636 // Support: Promises/A+ section 2.3.3.3.4.1 3637 // https://promisesaplus.com/#point-61 3638 // Ignore post-resolution exceptions 3639 if ( depth + 1 >= maxDepth ) { 3640 3641 // Only substitute handlers pass on context 3642 // and multiple values (non-spec behavior) 3643 if ( handler !== Thrower ) { 3644 that = undefined; 3645 args = [ e ]; 3646 } 3647 3648 deferred.rejectWith( that, args ); 3649 } 3650 } 3651 }; 3652 3653 // Support: Promises/A+ section 2.3.3.3.1 3654 // https://promisesaplus.com/#point-57 3655 // Re-resolve promises immediately to dodge false rejection from 3656 // subsequent errors 3657 if ( depth ) { 3658 process(); 3659 } else { 3660 3661 // Call an optional hook to record the stack, in case of exception 3662 // since it's otherwise lost when execution goes async 3663 if ( jQuery.Deferred.getStackHook ) { 3664 process.stackTrace = jQuery.Deferred.getStackHook(); 3665 } 3666 window.setTimeout( process ); 3667 } 3668 }; 3669 } 3670 3671 return jQuery.Deferred( function( newDefer ) { 3672 3673 // progress_handlers.add( ... ) 3674 tuples[ 0 ][ 3 ].add( 3675 resolve( 3676 0, 3677 newDefer, 3678 isFunction( onProgress ) ? 3679 onProgress : 3680 Identity, 3681 newDefer.notifyWith 3682 ) 3683 ); 3684 3685 // fulfilled_handlers.add( ... ) 3686 tuples[ 1 ][ 3 ].add( 3687 resolve( 3688 0, 3689 newDefer, 3690 isFunction( onFulfilled ) ? 3691 onFulfilled : 3692 Identity 3693 ) 3694 ); 3695 3696 // rejected_handlers.add( ... ) 3697 tuples[ 2 ][ 3 ].add( 3698 resolve( 3699 0, 3700 newDefer, 3701 isFunction( onRejected ) ? 3702 onRejected : 3703 Thrower 3704 ) 3705 ); 3706 } ).promise(); 3707 }, 3708 3709 // Get a promise for this deferred 3710 // If obj is provided, the promise aspect is added to the object 3711 promise: function( obj ) { 3712 return obj != null ? jQuery.extend( obj, promise ) : promise; 3713 } 3714 }, 3715 deferred = {}; 3716 3717 // Add list-specific methods 3718 jQuery.each( tuples, function( i, tuple ) { 3719 var list = tuple[ 2 ], 3720 stateString = tuple[ 5 ]; 3721 3722 // promise.progress = list.add 3723 // promise.done = list.add 3724 // promise.fail = list.add 3725 promise[ tuple[ 1 ] ] = list.add; 3726 3727 // Handle state 3728 if ( stateString ) { 3729 list.add( 3730 function() { 3731 3732 // state = "resolved" (i.e., fulfilled) 3733 // state = "rejected" 3734 state = stateString; 3735 }, 3736 3737 // rejected_callbacks.disable 3738 // fulfilled_callbacks.disable 3739 tuples[ 3 - i ][ 2 ].disable, 3740 3741 // rejected_handlers.disable 3742 // fulfilled_handlers.disable 3743 tuples[ 3 - i ][ 3 ].disable, 3744 3745 // progress_callbacks.lock 3746 tuples[ 0 ][ 2 ].lock, 3747 3748 // progress_handlers.lock 3749 tuples[ 0 ][ 3 ].lock 3750 ); 3751 } 3752 3753 // progress_handlers.fire 3754 // fulfilled_handlers.fire 3755 // rejected_handlers.fire 3756 list.add( tuple[ 3 ].fire ); 3757 3758 // deferred.notify = function() { deferred.notifyWith(...) } 3759 // deferred.resolve = function() { deferred.resolveWith(...) } 3760 // deferred.reject = function() { deferred.rejectWith(...) } 3761 deferred[ tuple[ 0 ] ] = function() { 3762 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 3763 return this; 3764 }; 3765 3766 // deferred.notifyWith = list.fireWith 3767 // deferred.resolveWith = list.fireWith 3768 // deferred.rejectWith = list.fireWith 3769 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 3770 } ); 3771 3772 // Make the deferred a promise 3773 promise.promise( deferred ); 3774 3775 // Call given func if any 3776 if ( func ) { 3777 func.call( deferred, deferred ); 3778 } 3779 3780 // All done! 3781 return deferred; 3782 }, 3783 3784 // Deferred helper 3785 when: function( singleValue ) { 3786 var 3787 3788 // count of uncompleted subordinates 3789 remaining = arguments.length, 3790 3791 // count of unprocessed arguments 3792 i = remaining, 3793 3794 // subordinate fulfillment data 3795 resolveContexts = Array( i ), 3796 resolveValues = slice.call( arguments ), 3797 3798 // the master Deferred 3799 master = jQuery.Deferred(), 3800 3801 // subordinate callback factory 3802 updateFunc = function( i ) { 3803 return function( value ) { 3804 resolveContexts[ i ] = this; 3805 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3806 if ( !( --remaining ) ) { 3807 master.resolveWith( resolveContexts, resolveValues ); 3808 } 3809 }; 3810 }; 3811 3812 // Single- and empty arguments are adopted like Promise.resolve 3813 if ( remaining <= 1 ) { 3814 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, 3815 !remaining ); 3816 3817 // Use .then() to unwrap secondary thenables (cf. gh-3000) 3818 if ( master.state() === "pending" || 3819 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 3820 3821 return master.then(); 3822 } 3823 } 3824 3825 // Multiple arguments are aggregated like Promise.all array elements 3826 while ( i-- ) { 3827 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); 3828 } 3829 3830 return master.promise(); 3831 } 3832} ); 3833 3834 3835// These usually indicate a programmer mistake during development, 3836// warn about them ASAP rather than swallowing them by default. 3837var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 3838 3839jQuery.Deferred.exceptionHook = function( error, stack ) { 3840 3841 // Support: IE 8 - 9 only 3842 // Console exists when dev tools are open, which can happen at any time 3843 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 3844 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 3845 } 3846}; 3847 3848 3849 3850 3851jQuery.readyException = function( error ) { 3852 window.setTimeout( function() { 3853 throw error; 3854 } ); 3855}; 3856 3857 3858 3859 3860// The deferred used on DOM ready 3861var readyList = jQuery.Deferred(); 3862 3863jQuery.fn.ready = function( fn ) { 3864 3865 readyList 3866 .then( fn ) 3867 3868 // Wrap jQuery.readyException in a function so that the lookup 3869 // happens at the time of error handling instead of callback 3870 // registration. 3871 .catch( function( error ) { 3872 jQuery.readyException( error ); 3873 } ); 3874 3875 return this; 3876}; 3877 3878jQuery.extend( { 3879 3880 // Is the DOM ready to be used? Set to true once it occurs. 3881 isReady: false, 3882 3883 // A counter to track how many items to wait for before 3884 // the ready event fires. See #6781 3885 readyWait: 1, 3886 3887 // Handle when the DOM is ready 3888 ready: function( wait ) { 3889 3890 // Abort if there are pending holds or we're already ready 3891 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3892 return; 3893 } 3894 3895 // Remember that the DOM is ready 3896 jQuery.isReady = true; 3897 3898 // If a normal DOM Ready event fired, decrement, and wait if need be 3899 if ( wait !== true && --jQuery.readyWait > 0 ) { 3900 return; 3901 } 3902 3903 // If there are functions bound, to execute 3904 readyList.resolveWith( document, [ jQuery ] ); 3905 } 3906} ); 3907 3908jQuery.ready.then = readyList.then; 3909 3910// The ready event handler and self cleanup method 3911function completed() { 3912 document.removeEventListener( "DOMContentLoaded", completed ); 3913 window.removeEventListener( "load", completed ); 3914 jQuery.ready(); 3915} 3916 3917// Catch cases where $(document).ready() is called 3918// after the browser event has already occurred. 3919// Support: IE <=9 - 10 only 3920// Older IE sometimes signals "interactive" too soon 3921if ( document.readyState === "complete" || 3922 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 3923 3924 // Handle it asynchronously to allow scripts the opportunity to delay ready 3925 window.setTimeout( jQuery.ready ); 3926 3927} else { 3928 3929 // Use the handy event callback 3930 document.addEventListener( "DOMContentLoaded", completed ); 3931 3932 // A fallback to window.onload, that will always work 3933 window.addEventListener( "load", completed ); 3934} 3935 3936 3937 3938 3939// Multifunctional method to get and set values of a collection 3940// The value/s can optionally be executed if it's a function 3941var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 3942 var i = 0, 3943 len = elems.length, 3944 bulk = key == null; 3945 3946 // Sets many values 3947 if ( toType( key ) === "object" ) { 3948 chainable = true; 3949 for ( i in key ) { 3950 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 3951 } 3952 3953 // Sets one value 3954 } else if ( value !== undefined ) { 3955 chainable = true; 3956 3957 if ( !isFunction( value ) ) { 3958 raw = true; 3959 } 3960 3961 if ( bulk ) { 3962 3963 // Bulk operations run against the entire set 3964 if ( raw ) { 3965 fn.call( elems, value ); 3966 fn = null; 3967 3968 // ...except when executing function values 3969 } else { 3970 bulk = fn; 3971 fn = function( elem, key, value ) { 3972 return bulk.call( jQuery( elem ), value ); 3973 }; 3974 } 3975 } 3976 3977 if ( fn ) { 3978 for ( ; i < len; i++ ) { 3979 fn( 3980 elems[ i ], key, raw ? 3981 value : 3982 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 3983 ); 3984 } 3985 } 3986 } 3987 3988 if ( chainable ) { 3989 return elems; 3990 } 3991 3992 // Gets 3993 if ( bulk ) { 3994 return fn.call( elems ); 3995 } 3996 3997 return len ? fn( elems[ 0 ], key ) : emptyGet; 3998}; 3999 4000 4001// Matches dashed string for camelizing 4002var rmsPrefix = /^-ms-/, 4003 rdashAlpha = /-([a-z])/g; 4004 4005// Used by camelCase as callback to replace() 4006function fcamelCase( all, letter ) { 4007 return letter.toUpperCase(); 4008} 4009 4010// Convert dashed to camelCase; used by the css and data modules 4011// Support: IE <=9 - 11, Edge 12 - 15 4012// Microsoft forgot to hump their vendor prefix (#9572) 4013function camelCase( string ) { 4014 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 4015} 4016var acceptData = function( owner ) { 4017 4018 // Accepts only: 4019 // - Node 4020 // - Node.ELEMENT_NODE 4021 // - Node.DOCUMENT_NODE 4022 // - Object 4023 // - Any 4024 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 4025}; 4026 4027 4028 4029 4030function Data() { 4031 this.expando = jQuery.expando + Data.uid++; 4032} 4033 4034Data.uid = 1; 4035 4036Data.prototype = { 4037 4038 cache: function( owner ) { 4039 4040 // Check if the owner object already has a cache 4041 var value = owner[ this.expando ]; 4042 4043 // If not, create one 4044 if ( !value ) { 4045 value = {}; 4046 4047 // We can accept data for non-element nodes in modern browsers, 4048 // but we should not, see #8335. 4049 // Always return an empty object. 4050 if ( acceptData( owner ) ) { 4051 4052 // If it is a node unlikely to be stringify-ed or looped over 4053 // use plain assignment 4054 if ( owner.nodeType ) { 4055 owner[ this.expando ] = value; 4056 4057 // Otherwise secure it in a non-enumerable property 4058 // configurable must be true to allow the property to be 4059 // deleted when data is removed 4060 } else { 4061 Object.defineProperty( owner, this.expando, { 4062 value: value, 4063 configurable: true 4064 } ); 4065 } 4066 } 4067 } 4068 4069 return value; 4070 }, 4071 set: function( owner, data, value ) { 4072 var prop, 4073 cache = this.cache( owner ); 4074 4075 // Handle: [ owner, key, value ] args 4076 // Always use camelCase key (gh-2257) 4077 if ( typeof data === "string" ) { 4078 cache[ camelCase( data ) ] = value; 4079 4080 // Handle: [ owner, { properties } ] args 4081 } else { 4082 4083 // Copy the properties one-by-one to the cache object 4084 for ( prop in data ) { 4085 cache[ camelCase( prop ) ] = data[ prop ]; 4086 } 4087 } 4088 return cache; 4089 }, 4090 get: function( owner, key ) { 4091 return key === undefined ? 4092 this.cache( owner ) : 4093 4094 // Always use camelCase key (gh-2257) 4095 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 4096 }, 4097 access: function( owner, key, value ) { 4098 4099 // In cases where either: 4100 // 4101 // 1. No key was specified
vendor: 10,628 bytes, lines 4102-4533
4102 // 2. A string key was specified, but no value provided 4103 // 4104 // Take the "read" path and allow the get method to determine 4105 // which value to return, respectively either: 4106 // 4107 // 1. The entire cache object 4108 // 2. The data stored at the key 4109 // 4110 if ( key === undefined || 4111 ( ( key && typeof key === "string" ) && value === undefined ) ) { 4112 4113 return this.get( owner, key ); 4114 } 4115 4116 // When the key is not a string, or both a key and value 4117 // are specified, set or extend (existing objects) with either: 4118 // 4119 // 1. An object of properties 4120 // 2. A key and value 4121 // 4122 this.set( owner, key, value ); 4123 4124 // Since the "set" path can have two possible entry points 4125 // return the expected data based on which path was taken[*] 4126 return value !== undefined ? value : key; 4127 }, 4128 remove: function( owner, key ) { 4129 var i, 4130 cache = owner[ this.expando ]; 4131 4132 if ( cache === undefined ) { 4133 return; 4134 } 4135 4136 if ( key !== undefined ) { 4137 4138 // Support array or space separated string of keys 4139 if ( Array.isArray( key ) ) { 4140 4141 // If key is an array of keys... 4142 // We always set camelCase keys, so remove that. 4143 key = key.map( camelCase ); 4144 } else { 4145 key = camelCase( key ); 4146 4147 // If a key with the spaces exists, use it. 4148 // Otherwise, create an array by matching non-whitespace 4149 key = key in cache ? 4150 [ key ] : 4151 ( key.match( rnothtmlwhite ) || [] ); 4152 } 4153 4154 i = key.length; 4155 4156 while ( i-- ) { 4157 delete cache[ key[ i ] ]; 4158 } 4159 } 4160 4161 // Remove the expando if there's no more data 4162 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 4163 4164 // Support: Chrome <=35 - 45 4165 // Webkit & Blink performance suffers when deleting properties 4166 // from DOM nodes, so set to undefined instead 4167 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4168 if ( owner.nodeType ) { 4169 owner[ this.expando ] = undefined; 4170 } else { 4171 delete owner[ this.expando ]; 4172 } 4173 } 4174 }, 4175 hasData: function( owner ) { 4176 var cache = owner[ this.expando ]; 4177 return cache !== undefined && !jQuery.isEmptyObject( cache ); 4178 } 4179}; 4180var dataPriv = new Data(); 4181 4182var dataUser = new Data(); 4183 4184 4185 4186// Implementation Summary 4187// 4188// 1. Enforce API surface and semantic compatibility with 1.9.x branch 4189// 2. Improve the module's maintainability by reducing the storage 4190// paths to a single mechanism. 4191// 3. Use the same single mechanism to support "private" and "user" data. 4192// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 4193// 5. Avoid exposing implementation details on user objects (eg. expando properties) 4194// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 4195 4196var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 4197 rmultiDash = /[A-Z]/g; 4198 4199function getData( data ) { 4200 if ( data === "true" ) { 4201 return true; 4202 } 4203 4204 if ( data === "false" ) { 4205 return false; 4206 } 4207 4208 if ( data === "null" ) { 4209 return null; 4210 } 4211 4212 // Only convert to a number if it doesn't change the string 4213 if ( data === +data + "" ) { 4214 return +data; 4215 } 4216 4217 if ( rbrace.test( data ) ) { 4218 return JSON.parse( data ); 4219 } 4220 4221 return data; 4222} 4223 4224function dataAttr( elem, key, data ) { 4225 var name; 4226 4227 // If nothing was found internally, try to fetch any 4228 // data from the HTML5 data-* attribute 4229 if ( data === undefined && elem.nodeType === 1 ) { 4230 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 4231 data = elem.getAttribute( name ); 4232 4233 if ( typeof data === "string" ) { 4234 try { 4235 data = getData( data ); 4236 } catch ( e ) {} 4237 4238 // Make sure we set the data so it isn't changed later 4239 dataUser.set( elem, key, data ); 4240 } else { 4241 data = undefined; 4242 } 4243 } 4244 return data; 4245} 4246 4247jQuery.extend( { 4248 hasData: function( elem ) { 4249 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 4250 }, 4251 4252 data: function( elem, name, data ) { 4253 return dataUser.access( elem, name, data ); 4254 }, 4255 4256 removeData: function( elem, name ) { 4257 dataUser.remove( elem, name ); 4258 }, 4259 4260 // TODO: Now that all calls to _data and _removeData have been replaced 4261 // with direct calls to dataPriv methods, these can be deprecated. 4262 _data: function( elem, name, data ) { 4263 return dataPriv.access( elem, name, data ); 4264 }, 4265 4266 _removeData: function( elem, name ) { 4267 dataPriv.remove( elem, name ); 4268 } 4269} ); 4270 4271jQuery.fn.extend( { 4272 data: function( key, value ) { 4273 var i, name, data, 4274 elem = this[ 0 ], 4275 attrs = elem && elem.attributes; 4276 4277 // Gets all values 4278 if ( key === undefined ) { 4279 if ( this.length ) { 4280 data = dataUser.get( elem ); 4281 4282 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 4283 i = attrs.length; 4284 while ( i-- ) { 4285 4286 // Support: IE 11 only 4287 // The attrs elements can be null (#14894) 4288 if ( attrs[ i ] ) { 4289 name = attrs[ i ].name; 4290 if ( name.indexOf( "data-" ) === 0 ) { 4291 name = camelCase( name.slice( 5 ) ); 4292 dataAttr( elem, name, data[ name ] ); 4293 } 4294 } 4295 } 4296 dataPriv.set( elem, "hasDataAttrs", true ); 4297 } 4298 } 4299 4300 return data; 4301 } 4302 4303 // Sets multiple values 4304 if ( typeof key === "object" ) { 4305 return this.each( function() { 4306 dataUser.set( this, key ); 4307 } ); 4308 } 4309 4310 return access( this, function( value ) { 4311 var data; 4312 4313 // The calling jQuery object (element matches) is not empty 4314 // (and therefore has an element appears at this[ 0 ]) and the 4315 // `value` parameter was not undefined. An empty jQuery object 4316 // will result in `undefined` for elem = this[ 0 ] which will 4317 // throw an exception if an attempt to read a data cache is made. 4318 if ( elem && value === undefined ) { 4319 4320 // Attempt to get data from the cache 4321 // The key will always be camelCased in Data 4322 data = dataUser.get( elem, key ); 4323 if ( data !== undefined ) { 4324 return data; 4325 } 4326 4327 // Attempt to "discover" the data in 4328 // HTML5 custom data-* attrs 4329 data = dataAttr( elem, key ); 4330 if ( data !== undefined ) { 4331 return data; 4332 } 4333 4334 // We tried really hard, but the data doesn't exist. 4335 return; 4336 } 4337 4338 // Set the data... 4339 this.each( function() { 4340 4341 // We always store the camelCased key 4342 dataUser.set( this, key, value ); 4343 } ); 4344 }, null, value, arguments.length > 1, null, true ); 4345 }, 4346 4347 removeData: function( key ) { 4348 return this.each( function() { 4349 dataUser.remove( this, key ); 4350 } ); 4351 } 4352} ); 4353 4354 4355jQuery.extend( { 4356 queue: function( elem, type, data ) { 4357 var queue; 4358 4359 if ( elem ) { 4360 type = ( type || "fx" ) + "queue"; 4361 queue = dataPriv.get( elem, type ); 4362 4363 // Speed up dequeue by getting out quickly if this is just a lookup 4364 if ( data ) { 4365 if ( !queue || Array.isArray( data ) ) { 4366 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 4367 } else { 4368 queue.push( data ); 4369 } 4370 } 4371 return queue || []; 4372 } 4373 }, 4374 4375 dequeue: function( elem, type ) { 4376 type = type || "fx"; 4377 4378 var queue = jQuery.queue( elem, type ), 4379 startLength = queue.length, 4380 fn = queue.shift(), 4381 hooks = jQuery._queueHooks( elem, type ), 4382 next = function() { 4383 jQuery.dequeue( elem, type ); 4384 }; 4385 4386 // If the fx queue is dequeued, always remove the progress sentinel 4387 if ( fn === "inprogress" ) { 4388 fn = queue.shift(); 4389 startLength--; 4390 } 4391 4392 if ( fn ) { 4393 4394 // Add a progress sentinel to prevent the fx queue from being 4395 // automatically dequeued 4396 if ( type === "fx" ) { 4397 queue.unshift( "inprogress" ); 4398 } 4399 4400 // Clear up the last queue stop function 4401 delete hooks.stop; 4402 fn.call( elem, next, hooks ); 4403 } 4404 4405 if ( !startLength && hooks ) { 4406 hooks.empty.fire(); 4407 } 4408 }, 4409 4410 // Not public - generate a queueHooks object, or return the current one 4411 _queueHooks: function( elem, type ) { 4412 var key = type + "queueHooks"; 4413 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 4414 empty: jQuery.Callbacks( "once memory" ).add( function() { 4415 dataPriv.remove( elem, [ type + "queue", key ] ); 4416 } ) 4417 } ); 4418 } 4419} ); 4420 4421jQuery.fn.extend( { 4422 queue: function( type, data ) { 4423 var setter = 2; 4424 4425 if ( typeof type !== "string" ) { 4426 data = type; 4427 type = "fx"; 4428 setter--; 4429 } 4430 4431 if ( arguments.length < setter ) { 4432 return jQuery.queue( this[ 0 ], type ); 4433 } 4434 4435 return data === undefined ? 4436 this : 4437 this.each( function() { 4438 var queue = jQuery.queue( this, type, data ); 4439 4440 // Ensure a hooks for this queue 4441 jQuery._queueHooks( this, type ); 4442 4443 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4444 jQuery.dequeue( this, type ); 4445 } 4446 } ); 4447 }, 4448 dequeue: function( type ) { 4449 return this.each( function() { 4450 jQuery.dequeue( this, type ); 4451 } ); 4452 }, 4453 clearQueue: function( type ) { 4454 return this.queue( type || "fx", [] ); 4455 }, 4456 4457 // Get a promise resolved when queues of a certain type 4458 // are emptied (fx is the type by default) 4459 promise: function( type, obj ) { 4460 var tmp, 4461 count = 1, 4462 defer = jQuery.Deferred(), 4463 elements = this, 4464 i = this.length, 4465 resolve = function() { 4466 if ( !( --count ) ) { 4467 defer.resolveWith( elements, [ elements ] ); 4468 } 4469 }; 4470 4471 if ( typeof type !== "string" ) { 4472 obj = type; 4473 type = undefined; 4474 } 4475 type = type || "fx"; 4476 4477 while ( i-- ) { 4478 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 4479 if ( tmp && tmp.empty ) { 4480 count++; 4481 tmp.empty.add( resolve ); 4482 } 4483 } 4484 resolve(); 4485 return defer.promise( obj ); 4486 } 4487} ); 4488var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4489 4490var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4491 4492 4493var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4494 4495var documentElement = document.documentElement; 4496 4497 4498 4499 var isAttached = function( elem ) { 4500 return jQuery.contains( elem.ownerDocument, elem ); 4501 }, 4502 composed = { composed: true }; 4503 4504 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 4505 // Check attachment across shadow DOM boundaries when possible (gh-3504) 4506 // Support: iOS 10.0-10.2 only 4507 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 4508 // leading to errors. We need to check for `getRootNode`. 4509 if ( documentElement.getRootNode ) { 4510 isAttached = function( elem ) { 4511 return jQuery.contains( elem.ownerDocument, elem ) || 4512 elem.getRootNode( composed ) === elem.ownerDocument; 4513 }; 4514 } 4515var isHiddenWithinTree = function( elem, el ) { 4516 4517 // isHiddenWithinTree might be called from jQuery#filter function; 4518 // in that case, element will be second argument 4519 elem = el || elem; 4520 4521 // Inline style trumps all 4522 return elem.style.display === "none" || 4523 elem.style.display === "" && 4524 4525 // Otherwise, check computed style 4526 // Support: Firefox <=43 - 45 4527 // Disconnected elements can have computed display: none, so first confirm that elem is 4528 // in the document. 4529 isAttached( elem ) && 4530 4531 jQuery.css( elem, "display" ) === "none"; 4532 }; 4533
vendor: 2,487 bytes, lines 4534-4631
4534var swap = function( elem, options, callback, args ) { 4535 var ret, name, 4536 old = {}; 4537 4538 // Remember the old values, and insert the new ones 4539 for ( name in options ) { 4540 old[ name ] = elem.style[ name ]; 4541 elem.style[ name ] = options[ name ]; 4542 } 4543 4544 ret = callback.apply( elem, args || [] ); 4545 4546 // Revert the old values 4547 for ( name in options ) { 4548 elem.style[ name ] = old[ name ]; 4549 } 4550 4551 return ret; 4552}; 4553 4554 4555 4556 4557function adjustCSS( elem, prop, valueParts, tween ) { 4558 var adjusted, scale, 4559 maxIterations = 20, 4560 currentValue = tween ? 4561 function() { 4562 return tween.cur(); 4563 } : 4564 function() { 4565 return jQuery.css( elem, prop, "" ); 4566 }, 4567 initial = currentValue(), 4568 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4569 4570 // Starting value computation is required for potential unit mismatches 4571 initialInUnit = elem.nodeType && 4572 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4573 rcssNum.exec( jQuery.css( elem, prop ) ); 4574 4575 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4576 4577 // Support: Firefox <=54 4578 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 4579 initial = initial / 2; 4580 4581 // Trust units reported by jQuery.css 4582 unit = unit || initialInUnit[ 3 ]; 4583 4584 // Iteratively approximate from a nonzero starting point 4585 initialInUnit = +initial || 1; 4586 4587 while ( maxIterations-- ) { 4588 4589 // Evaluate and update our best guess (doubling guesses that zero out). 4590 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 4591 jQuery.style( elem, prop, initialInUnit + unit ); 4592 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 4593 maxIterations = 0; 4594 } 4595 initialInUnit = initialInUnit / scale; 4596 4597 } 4598 4599 initialInUnit = initialInUnit * 2; 4600 jQuery.style( elem, prop, initialInUnit + unit ); 4601 4602 // Make sure we update the tween properties later on 4603 valueParts = valueParts || []; 4604 } 4605 4606 if ( valueParts ) { 4607 initialInUnit = +initialInUnit || +initial || 0; 4608 4609 // Apply relative offset (+=/-=) if specified 4610 adjusted = valueParts[ 1 ] ? 4611 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4612 +valueParts[ 2 ]; 4613 if ( tween ) { 4614 tween.unit = unit; 4615 tween.start = initialInUnit; 4616 tween.end = adjusted; 4617 } 4618 } 4619 return adjusted; 4620} 4621 4622 4623var defaultDisplayMap = {}; 4624 4625function getDefaultDisplay( elem ) { 4626 var temp, 4627 doc = elem.ownerDocument, 4628 nodeName = elem.nodeName, 4629 display = defaultDisplayMap[ nodeName ]; 4630 4631 if ( display ) {
vendor: 4,818 bytes, lines 4632-4827
4632 return display; 4633 } 4634 4635 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 4636 display = jQuery.css( temp, "display" ); 4637 4638 temp.parentNode.removeChild( temp ); 4639 4640 if ( display === "none" ) { 4641 display = "block"; 4642 } 4643 defaultDisplayMap[ nodeName ] = display; 4644 4645 return display; 4646} 4647 4648function showHide( elements, show ) { 4649 var display, elem, 4650 values = [], 4651 index = 0, 4652 length = elements.length; 4653 4654 // Determine new display value for elements that need to change 4655 for ( ; index < length; index++ ) { 4656 elem = elements[ index ]; 4657 if ( !elem.style ) { 4658 continue; 4659 } 4660 4661 display = elem.style.display; 4662 if ( show ) { 4663 4664 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 4665 // check is required in this first loop unless we have a nonempty display value (either 4666 // inline or about-to-be-restored) 4667 if ( display === "none" ) { 4668 values[ index ] = dataPriv.get( elem, "display" ) || null; 4669 if ( !values[ index ] ) { 4670 elem.style.display = ""; 4671 } 4672 } 4673 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 4674 values[ index ] = getDefaultDisplay( elem ); 4675 } 4676 } else { 4677 if ( display !== "none" ) { 4678 values[ index ] = "none"; 4679 4680 // Remember what we're overwriting 4681 dataPriv.set( elem, "display", display ); 4682 } 4683 } 4684 } 4685 4686 // Set the display of the elements in a second loop to avoid constant reflow 4687 for ( index = 0; index < length; index++ ) { 4688 if ( values[ index ] != null ) { 4689 elements[ index ].style.display = values[ index ]; 4690 } 4691 } 4692 4693 return elements; 4694} 4695 4696jQuery.fn.extend( { 4697 show: function() { 4698 return showHide( this, true ); 4699 }, 4700 hide: function() { 4701 return showHide( this ); 4702 }, 4703 toggle: function( state ) { 4704 if ( typeof state === "boolean" ) { 4705 return state ? this.show() : this.hide(); 4706 } 4707 4708 return this.each( function() { 4709 if ( isHiddenWithinTree( this ) ) { 4710 jQuery( this ).show(); 4711 } else { 4712 jQuery( this ).hide(); 4713 } 4714 } ); 4715 } 4716} ); 4717var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4718 4719var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 4720 4721var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 4722 4723 4724 4725// We have to close these tags to support XHTML (#13200) 4726var wrapMap = { 4727 4728 // Support: IE <=9 only 4729 option: [ 1, "<select multiple='multiple'>", "</select>" ], 4730 4731 // XHTML parsers do not magically insert elements in the 4732 // same way that tag soup parsers do. So we cannot shorten 4733 // this by omitting <tbody> or other required elements. 4734 thead: [ 1, "<table>", "</table>" ], 4735 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 4736 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4737 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4738 4739 _default: [ 0, "", "" ] 4740}; 4741 4742// Support: IE <=9 only 4743wrapMap.optgroup = wrapMap.option; 4744 4745wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4746wrapMap.th = wrapMap.td; 4747 4748 4749function getAll( context, tag ) { 4750 4751 // Support: IE <=9 - 11 only 4752 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 4753 var ret; 4754 4755 if ( typeof context.getElementsByTagName !== "undefined" ) { 4756 ret = context.getElementsByTagName( tag || "*" ); 4757 4758 } else if ( typeof context.querySelectorAll !== "undefined" ) { 4759 ret = context.querySelectorAll( tag || "*" ); 4760 4761 } else { 4762 ret = []; 4763 } 4764 4765 if ( tag === undefined || tag && nodeName( context, tag ) ) { 4766 return jQuery.merge( [ context ], ret ); 4767 } 4768 4769 return ret; 4770} 4771 4772 4773// Mark scripts as having already been evaluated 4774function setGlobalEval( elems, refElements ) { 4775 var i = 0, 4776 l = elems.length; 4777 4778 for ( ; i < l; i++ ) { 4779 dataPriv.set( 4780 elems[ i ], 4781 "globalEval", 4782 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 4783 ); 4784 } 4785} 4786 4787 4788var rhtml = /<|&#?\w+;/; 4789 4790function buildFragment( elems, context, scripts, selection, ignored ) { 4791 var elem, tmp, tag, wrap, attached, j, 4792 fragment = context.createDocumentFragment(), 4793 nodes = [], 4794 i = 0, 4795 l = elems.length; 4796 4797 for ( ; i < l; i++ ) { 4798 elem = elems[ i ]; 4799 4800 if ( elem || elem === 0 ) { 4801 4802 // Add nodes directly 4803 if ( toType( elem ) === "object" ) { 4804 4805 // Support: Android <=4.0 only, PhantomJS 1 only 4806 // push.apply(_, arraylike) throws on ancient WebKit 4807 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 4808 4809 // Convert non-html into a text node 4810 } else if ( !rhtml.test( elem ) ) { 4811 nodes.push( context.createTextNode( elem ) ); 4812 4813 // Convert html into DOM nodes 4814 } else { 4815 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 4816 4817 // Deserialize a standard representation 4818 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 4819 wrap = wrapMap[ tag ] || wrapMap._default; 4820 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 4821 4822 // Descend through wrappers to the right content 4823 j = wrap[ 0 ]; 4824 while ( j-- ) { 4825 tmp = tmp.lastChild; 4826 } 4827
vendor: 1,252 bytes, lines 4828-4885
4828 // Support: Android <=4.0 only, PhantomJS 1 only 4829 // push.apply(_, arraylike) throws on ancient WebKit 4830 jQuery.merge( nodes, tmp.childNodes ); 4831 4832 // Remember the top-level container 4833 tmp = fragment.firstChild; 4834 4835 // Ensure the created nodes are orphaned (#12392) 4836 tmp.textContent = ""; 4837 } 4838 } 4839 } 4840 4841 // Remove wrapper from fragment 4842 fragment.textContent = ""; 4843 4844 i = 0; 4845 while ( ( elem = nodes[ i++ ] ) ) { 4846 4847 // Skip elements already in the context collection (trac-4087) 4848 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 4849 if ( ignored ) { 4850 ignored.push( elem ); 4851 } 4852 continue; 4853 } 4854 4855 attached = isAttached( elem ); 4856 4857 // Append to fragment 4858 tmp = getAll( fragment.appendChild( elem ), "script" ); 4859 4860 // Preserve script evaluation history 4861 if ( attached ) { 4862 setGlobalEval( tmp ); 4863 } 4864 4865 // Capture executables 4866 if ( scripts ) { 4867 j = 0; 4868 while ( ( elem = tmp[ j++ ] ) ) { 4869 if ( rscriptType.test( elem.type || "" ) ) { 4870 scripts.push( elem ); 4871 } 4872 } 4873 } 4874 } 4875 4876 return fragment; 4877} 4878 4879 4880( function() { 4881 var fragment = document.createDocumentFragment(), 4882 div = fragment.appendChild( document.createElement( "div" ) ), 4883 input = document.createElement( "input" ); 4884 4885 // Support: Android 4.0 - 4.3 only
vendor: 6,890 bytes, lines 4886-5132
4886 // Check state lost if the name is set (#11217) 4887 // Support: Windows Web Apps (WWA) 4888 // `name` and `type` must use .setAttribute for WWA (#14901) 4889 input.setAttribute( "type", "radio" ); 4890 input.setAttribute( "checked", "checked" ); 4891 input.setAttribute( "name", "t" ); 4892 4893 div.appendChild( input ); 4894 4895 // Support: Android <=4.1 only 4896 // Older WebKit doesn't clone checked state correctly in fragments 4897 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4898 4899 // Support: IE <=11 only 4900 // Make sure textarea (and checkbox) defaultValue is properly cloned 4901 div.innerHTML = "<textarea>x</textarea>"; 4902 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4903} )(); 4904 4905 4906var 4907 rkeyEvent = /^key/, 4908 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 4909 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4910 4911function returnTrue() { 4912 return true; 4913} 4914 4915function returnFalse() { 4916 return false; 4917} 4918 4919// Support: IE <=9 - 11+ 4920// focus() and blur() are asynchronous, except when they are no-op. 4921// So expect focus to be synchronous when the element is already active, 4922// and blur to be synchronous when the element is not already active. 4923// (focus and blur are always synchronous in other supported browsers, 4924// this just defines when we can count on it). 4925function expectSync( elem, type ) { 4926 return ( elem === safeActiveElement() ) === ( type === "focus" ); 4927} 4928 4929// Support: IE <=9 only 4930// Accessing document.activeElement can throw unexpectedly 4931// https://bugs.jquery.com/ticket/13393 4932function safeActiveElement() { 4933 try { 4934 return document.activeElement; 4935 } catch ( err ) { } 4936} 4937 4938function on( elem, types, selector, data, fn, one ) { 4939 var origFn, type; 4940 4941 // Types can be a map of types/handlers 4942 if ( typeof types === "object" ) { 4943 4944 // ( types-Object, selector, data ) 4945 if ( typeof selector !== "string" ) { 4946 4947 // ( types-Object, data ) 4948 data = data || selector; 4949 selector = undefined; 4950 } 4951 for ( type in types ) { 4952 on( elem, type, selector, data, types[ type ], one ); 4953 } 4954 return elem; 4955 } 4956 4957 if ( data == null && fn == null ) { 4958 4959 // ( types, fn ) 4960 fn = selector; 4961 data = selector = undefined; 4962 } else if ( fn == null ) { 4963 if ( typeof selector === "string" ) { 4964 4965 // ( types, selector, fn ) 4966 fn = data; 4967 data = undefined; 4968 } else { 4969 4970 // ( types, data, fn ) 4971 fn = data; 4972 data = selector; 4973 selector = undefined; 4974 } 4975 } 4976 if ( fn === false ) { 4977 fn = returnFalse; 4978 } else if ( !fn ) { 4979 return elem; 4980 } 4981 4982 if ( one === 1 ) { 4983 origFn = fn; 4984 fn = function( event ) { 4985 4986 // Can use an empty set, since event contains the info 4987 jQuery().off( event ); 4988 return origFn.apply( this, arguments ); 4989 }; 4990 4991 // Use same guid so caller can remove using origFn 4992 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4993 } 4994 return elem.each( function() { 4995 jQuery.event.add( this, types, fn, data, selector ); 4996 } ); 4997} 4998 4999/* 5000 * Helper functions for managing events -- not part of the public interface. 5001 * Props to Dean Edwards' addEvent library for many of the ideas. 5002 */ 5003jQuery.event = { 5004 5005 global: {}, 5006 5007 add: function( elem, types, handler, data, selector ) { 5008 5009 var handleObjIn, eventHandle, tmp, 5010 events, t, handleObj, 5011 special, handlers, type, namespaces, origType, 5012 elemData = dataPriv.get( elem ); 5013 5014 // Don't attach events to noData or text/comment nodes (but allow plain objects) 5015 if ( !elemData ) { 5016 return; 5017 } 5018 5019 // Caller can pass in an object of custom data in lieu of the handler 5020 if ( handler.handler ) { 5021 handleObjIn = handler; 5022 handler = handleObjIn.handler; 5023 selector = handleObjIn.selector; 5024 } 5025 5026 // Ensure that invalid selectors throw exceptions at attach time 5027 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 5028 if ( selector ) { 5029 jQuery.find.matchesSelector( documentElement, selector ); 5030 } 5031 5032 // Make sure that the handler has a unique ID, used to find/remove it later 5033 if ( !handler.guid ) { 5034 handler.guid = jQuery.guid++; 5035 } 5036 5037 // Init the element's event structure and main handler, if this is the first 5038 if ( !( events = elemData.events ) ) { 5039 events = elemData.events = {}; 5040 } 5041 if ( !( eventHandle = elemData.handle ) ) { 5042 eventHandle = elemData.handle = function( e ) { 5043 5044 // Discard the second event of a jQuery.event.trigger() and 5045 // when an event is called after a page has unloaded 5046 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 5047 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 5048 }; 5049 } 5050 5051 // Handle multiple events separated by a space 5052 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5053 t = types.length; 5054 while ( t-- ) { 5055 tmp = rtypenamespace.exec( types[ t ] ) || []; 5056 type = origType = tmp[ 1 ]; 5057 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5058 5059 // There *must* be a type, no attaching namespace-only handlers 5060 if ( !type ) { 5061 continue; 5062 } 5063 5064 // If event changes its type, use the special event handlers for the changed type 5065 special = jQuery.event.special[ type ] || {}; 5066 5067 // If selector defined, determine special event api type, otherwise given type 5068 type = ( selector ? special.delegateType : special.bindType ) || type; 5069 5070 // Update special based on newly reset type 5071 special = jQuery.event.special[ type ] || {}; 5072 5073 // handleObj is passed to all event handlers 5074 handleObj = jQuery.extend( { 5075 type: type, 5076 origType: origType, 5077 data: data, 5078 handler: handler, 5079 guid: handler.guid, 5080 selector: selector, 5081 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 5082 namespace: namespaces.join( "." ) 5083 }, handleObjIn ); 5084 5085 // Init the event handler queue if we're the first 5086 if ( !( handlers = events[ type ] ) ) { 5087 handlers = events[ type ] = []; 5088 handlers.delegateCount = 0; 5089 5090 // Only use addEventListener if the special events handler returns false 5091 if ( !special.setup || 5092 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 5093 5094 if ( elem.addEventListener ) { 5095 elem.addEventListener( type, eventHandle ); 5096 } 5097 } 5098 } 5099 5100 if ( special.add ) { 5101 special.add.call( elem, handleObj ); 5102 5103 if ( !handleObj.handler.guid ) { 5104 handleObj.handler.guid = handler.guid; 5105 } 5106 } 5107 5108 // Add to the element's handler list, delegates in front 5109 if ( selector ) { 5110 handlers.splice( handlers.delegateCount++, 0, handleObj ); 5111 } else { 5112 handlers.push( handleObj ); 5113 } 5114 5115 // Keep track of which events have ever been used, for event optimization 5116 jQuery.event.global[ type ] = true; 5117 } 5118 5119 }, 5120 5121 // Detach an event or set of events from an element 5122 remove: function( elem, types, handler, selector, mappedTypes ) { 5123 5124 var j, origCount, tmp, 5125 events, t, handleObj, 5126 special, handlers, type, namespaces, origType, 5127 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 5128 5129 if ( !elemData || !( events = elemData.events ) ) { 5130 return; 5131 } 5132
vendor: 4,172 bytes, lines 5133-5268
5133 // Once for each type.namespace in types; type may be omitted 5134 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5135 t = types.length; 5136 while ( t-- ) { 5137 tmp = rtypenamespace.exec( types[ t ] ) || []; 5138 type = origType = tmp[ 1 ]; 5139 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5140 5141 // Unbind all events (on this namespace, if provided) for the element 5142 if ( !type ) { 5143 for ( type in events ) { 5144 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 5145 } 5146 continue; 5147 } 5148 5149 special = jQuery.event.special[ type ] || {}; 5150 type = ( selector ? special.delegateType : special.bindType ) || type; 5151 handlers = events[ type ] || []; 5152 tmp = tmp[ 2 ] && 5153 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 5154 5155 // Remove matching events 5156 origCount = j = handlers.length; 5157 while ( j-- ) { 5158 handleObj = handlers[ j ]; 5159 5160 if ( ( mappedTypes || origType === handleObj.origType ) && 5161 ( !handler || handler.guid === handleObj.guid ) && 5162 ( !tmp || tmp.test( handleObj.namespace ) ) && 5163 ( !selector || selector === handleObj.selector || 5164 selector === "**" && handleObj.selector ) ) { 5165 handlers.splice( j, 1 ); 5166 5167 if ( handleObj.selector ) { 5168 handlers.delegateCount--; 5169 } 5170 if ( special.remove ) { 5171 special.remove.call( elem, handleObj ); 5172 } 5173 } 5174 } 5175 5176 // Remove generic event handler if we removed something and no more handlers exist 5177 // (avoids potential for endless recursion during removal of special event handlers) 5178 if ( origCount && !handlers.length ) { 5179 if ( !special.teardown || 5180 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5181 5182 jQuery.removeEvent( elem, type, elemData.handle ); 5183 } 5184 5185 delete events[ type ]; 5186 } 5187 } 5188 5189 // Remove data and the expando if it's no longer used 5190 if ( jQuery.isEmptyObject( events ) ) { 5191 dataPriv.remove( elem, "handle events" ); 5192 } 5193 }, 5194 5195 dispatch: function( nativeEvent ) { 5196 5197 // Make a writable jQuery.Event from the native event object 5198 var event = jQuery.event.fix( nativeEvent ); 5199 5200 var i, j, ret, matched, handleObj, handlerQueue, 5201 args = new Array( arguments.length ), 5202 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], 5203 special = jQuery.event.special[ event.type ] || {}; 5204 5205 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5206 args[ 0 ] = event; 5207 5208 for ( i = 1; i < arguments.length; i++ ) { 5209 args[ i ] = arguments[ i ]; 5210 } 5211 5212 event.delegateTarget = this; 5213 5214 // Call the preDispatch hook for the mapped type, and let it bail if desired 5215 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5216 return; 5217 } 5218 5219 // Determine handlers 5220 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 5221 5222 // Run delegates first; they may want to stop propagation beneath us 5223 i = 0; 5224 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 5225 event.currentTarget = matched.elem; 5226 5227 j = 0; 5228 while ( ( handleObj = matched.handlers[ j++ ] ) && 5229 !event.isImmediatePropagationStopped() ) { 5230 5231 // If the event is namespaced, then each handler is only invoked if it is 5232 // specially universal or its namespaces are a superset of the event's. 5233 if ( !event.rnamespace || handleObj.namespace === false || 5234 event.rnamespace.test( handleObj.namespace ) ) { 5235 5236 event.handleObj = handleObj; 5237 event.data = handleObj.data; 5238 5239 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 5240 handleObj.handler ).apply( matched.elem, args ); 5241 5242 if ( ret !== undefined ) { 5243 if ( ( event.result = ret ) === false ) { 5244 event.preventDefault(); 5245 event.stopPropagation(); 5246 } 5247 } 5248 } 5249 } 5250 } 5251 5252 // Call the postDispatch hook for the mapped type 5253 if ( special.postDispatch ) { 5254 special.postDispatch.call( this, event ); 5255 } 5256 5257 return event.result; 5258 }, 5259 5260 handlers: function( event, handlers ) { 5261 var i, handleObj, sel, matchedHandlers, matchedSelectors, 5262 handlerQueue = [], 5263 delegateCount = handlers.delegateCount, 5264 cur = event.target; 5265 5266 // Find delegate handlers 5267 if ( delegateCount && 5268
vendor: 5,718 bytes, lines 5269-5454
5269 // Support: IE <=9 5270 // Black-hole SVG <use> instance trees (trac-13180) 5271 cur.nodeType && 5272 5273 // Support: Firefox <=42 5274 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 5275 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 5276 // Support: IE 11 only 5277 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 5278 !( event.type === "click" && event.button >= 1 ) ) { 5279 5280 for ( ; cur !== this; cur = cur.parentNode || this ) { 5281 5282 // Don't check non-elements (#13208) 5283 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 5284 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 5285 matchedHandlers = []; 5286 matchedSelectors = {}; 5287 for ( i = 0; i < delegateCount; i++ ) { 5288 handleObj = handlers[ i ]; 5289 5290 // Don't conflict with Object.prototype properties (#13203) 5291 sel = handleObj.selector + " "; 5292 5293 if ( matchedSelectors[ sel ] === undefined ) { 5294 matchedSelectors[ sel ] = handleObj.needsContext ? 5295 jQuery( sel, this ).index( cur ) > -1 : 5296 jQuery.find( sel, this, null, [ cur ] ).length; 5297 } 5298 if ( matchedSelectors[ sel ] ) { 5299 matchedHandlers.push( handleObj ); 5300 } 5301 } 5302 if ( matchedHandlers.length ) { 5303 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 5304 } 5305 } 5306 } 5307 } 5308 5309 // Add the remaining (directly-bound) handlers 5310 cur = this; 5311 if ( delegateCount < handlers.length ) { 5312 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 5313 } 5314 5315 return handlerQueue; 5316 }, 5317 5318 addProp: function( name, hook ) { 5319 Object.defineProperty( jQuery.Event.prototype, name, { 5320 enumerable: true, 5321 configurable: true, 5322 5323 get: isFunction( hook ) ? 5324 function() { 5325 if ( this.originalEvent ) { 5326 return hook( this.originalEvent ); 5327 } 5328 } : 5329 function() { 5330 if ( this.originalEvent ) { 5331 return this.originalEvent[ name ]; 5332 } 5333 }, 5334 5335 set: function( value ) { 5336 Object.defineProperty( this, name, { 5337 enumerable: true, 5338 configurable: true, 5339 writable: true, 5340 value: value 5341 } ); 5342 } 5343 } ); 5344 }, 5345 5346 fix: function( originalEvent ) { 5347 return originalEvent[ jQuery.expando ] ? 5348 originalEvent : 5349 new jQuery.Event( originalEvent ); 5350 }, 5351 5352 special: { 5353 load: { 5354 5355 // Prevent triggered image.load events from bubbling to window.load 5356 noBubble: true 5357 }, 5358 click: { 5359 5360 // Utilize native event to ensure correct state for checkable inputs 5361 setup: function( data ) { 5362 5363 // For mutual compressibility with _default, replace `this` access with a local var. 5364 // `|| data` is dead code meant only to preserve the variable through minification. 5365 var el = this || data; 5366 5367 // Claim the first handler 5368 if ( rcheckableType.test( el.type ) && 5369 el.click && nodeName( el, "input" ) ) { 5370 5371 // dataPriv.set( el, "click", ... ) 5372 leverageNative( el, "click", returnTrue ); 5373 } 5374 5375 // Return false to allow normal processing in the caller 5376 return false; 5377 }, 5378 trigger: function( data ) { 5379 5380 // For mutual compressibility with _default, replace `this` access with a local var. 5381 // `|| data` is dead code meant only to preserve the variable through minification. 5382 var el = this || data; 5383 5384 // Force setup before triggering a click 5385 if ( rcheckableType.test( el.type ) && 5386 el.click && nodeName( el, "input" ) ) { 5387 5388 leverageNative( el, "click" ); 5389 } 5390 5391 // Return non-false to allow normal event-path propagation 5392 return true; 5393 }, 5394 5395 // For cross-browser consistency, suppress native .click() on links 5396 // Also prevent it if we're currently inside a leveraged native-event stack 5397 _default: function( event ) { 5398 var target = event.target; 5399 return rcheckableType.test( target.type ) && 5400 target.click && nodeName( target, "input" ) && 5401 dataPriv.get( target, "click" ) || 5402 nodeName( target, "a" ); 5403 } 5404 }, 5405 5406 beforeunload: { 5407 postDispatch: function( event ) { 5408 5409 // Support: Firefox 20+ 5410 // Firefox doesn't alert if the returnValue field is not set. 5411 if ( event.result !== undefined && event.originalEvent ) { 5412 event.originalEvent.returnValue = event.result; 5413 } 5414 } 5415 } 5416 } 5417}; 5418 5419// Ensure the presence of an event listener that handles manually-triggered 5420// synthetic events by interrupting progress until reinvoked in response to 5421// *native* events that it fires directly, ensuring that state changes have 5422// already occurred before other listeners are invoked. 5423function leverageNative( el, type, expectSync ) { 5424 5425 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 5426 if ( !expectSync ) { 5427 if ( dataPriv.get( el, type ) === undefined ) { 5428 jQuery.event.add( el, type, returnTrue ); 5429 } 5430 return; 5431 } 5432 5433 // Register the controller as a special universal handler for all event namespaces 5434 dataPriv.set( el, type, false ); 5435 jQuery.event.add( el, type, { 5436 namespace: false, 5437 handler: function( event ) { 5438 var notAsync, result, 5439 saved = dataPriv.get( this, type ); 5440 5441 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 5442 5443 // Interrupt processing of the outer synthetic .trigger()ed event 5444 // Saved data should be false in such cases, but might be a leftover capture object 5445 // from an async native handler (gh-4350) 5446 if ( !saved.length ) { 5447 5448 // Store arguments for use when handling the inner native event 5449 // There will always be at least one argument (an event object), so this array 5450 // will not be confused with a leftover capture object. 5451 saved = slice.call( arguments ); 5452 dataPriv.set( this, type, saved ); 5453 5454 // Trigger the native event and capture its result
5455 // Support: IE <=9 - 11+ 5456 // focus() and blur() are asynchronous 5457 notAsync = expectSync( this, type ); 5458 this[ type ](); 5459 result = dataPriv.get( this, type ); 5460 if ( saved !== result || notAsync ) { 5461 dataPriv.set( this, type, false ); 5462 } else { 5463 result = {}; 5464 } 5465 if ( saved !== result ) { 5466 5467 // Cancel the outer synthetic event 5468 event.stopImmediatePropagation(); 5469 event.preventDefault(); 5470 return result.value; 5471 } 5472 5473 // If this is an inner synthetic event for an event with a bubbling surrogate 5474 // (focus or blur), assume that the surrogate already propagated from triggering the 5475 // native event and prevent that from happening again here. 5476 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 5477 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 5478 // less bad than duplication. 5479 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 5480 event.stopPropagation(); 5481 } 5482 5483 // If this is a native event triggered above, everything is now in order 5484 // Fire an inner synthetic event with the original arguments 5485 } else if ( saved.length ) { 5486 5487 // ...and capture the result 5488 dataPriv.set( this, type, { 5489 value: jQuery.event.trigger( 5490 5491 // Support: IE <=9 - 11+ 5492 // Extend with the prototype to reset the above stopImmediatePropagation() 5493 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 5494 saved.slice( 1 ), 5495 this 5496 ) 5497 } ); 5498 5499 // Abort handling of the native event 5500 event.stopImmediatePropagation(); 5501 } 5502 } 5503 } ); 5504} 5505 5506jQuery.removeEvent = function( elem, type, handle ) { 5507 5508 // This "if" is needed for plain objects 5509 if ( elem.removeEventListener ) { 5510 elem.removeEventListener( type, handle ); 5511 } 5512}; 5513 5514jQuery.Event = function( src, props ) { 5515 5516 // Allow instantiation without the 'new' keyword 5517 if ( !( this instanceof jQuery.Event ) ) { 5518 return new jQuery.Event( src, props ); 5519 } 5520 5521 // Event object 5522 if ( src && src.type ) { 5523 this.originalEvent = src; 5524 this.type = src.type; 5525 5526 // Events bubbling up the document may have been marked as prevented 5527 // by a handler lower down the tree; reflect the correct value. 5528 this.isDefaultPrevented = src.defaultPrevented || 5529 src.defaultPrevented === undefined && 5530 5531 // Support: Android <=2.3 only 5532 src.returnValue === false ? 5533 returnTrue : 5534 returnFalse; 5535 5536 // Create target properties 5537 // Support: Safari <=6 - 7 only 5538 // Target should not be a text node (#504, #13143) 5539 this.target = ( src.target && src.target.nodeType === 3 ) ? 5540 src.target.parentNode : 5541 src.target; 5542 5543 this.currentTarget = src.currentTarget; 5544 this.relatedTarget = src.relatedTarget; 5545 5546 // Event type 5547 } else { 5548 this.type = src; 5549 } 5550 5551 // Put explicitly provided properties onto the event object 5552 if ( props ) { 5553 jQuery.extend( this, props ); 5554 } 5555 5556 // Create a timestamp if incoming event doesn't have one 5557 this.timeStamp = src && src.timeStamp || Date.now(); 5558 5559 // Mark it as fixed 5560 this[ jQuery.expando ] = true; 5561}; 5562 5563// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5564// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5565jQuery.Event.prototype = { 5566 constructor: jQuery.Event, 5567 isDefaultPrevented: returnFalse, 5568 isPropagationStopped: returnFalse, 5569 isImmediatePropagationStopped: returnFalse, 5570 isSimulated: false, 5571 5572 preventDefault: function() { 5573 var e = this.originalEvent; 5574 5575 this.isDefaultPrevented = returnTrue; 5576 5577 if ( e && !this.isSimulated ) { 5578 e.preventDefault(); 5579 } 5580 }, 5581 stopPropagation: function() { 5582 var e = this.originalEvent; 5583 5584 this.isPropagationStopped = returnTrue; 5585 5586 if ( e && !this.isSimulated ) { 5587 e.stopPropagation(); 5588 } 5589 }, 5590 stopImmediatePropagation: function() { 5591 var e = this.originalEvent; 5592 5593 this.isImmediatePropagationStopped = returnTrue; 5594 5595 if ( e && !this.isSimulated ) { 5596 e.stopImmediatePropagation(); 5597 } 5598 5599 this.stopPropagation(); 5600 } 5601}; 5602 5603// Includes all common event props including KeyEvent and MouseEvent specific props 5604jQuery.each( { 5605 altKey: true, 5606 bubbles: true, 5607 cancelable: true, 5608 changedTouches: true, 5609 ctrlKey: true, 5610 detail: true, 5611 eventPhase: true, 5612 metaKey: true, 5613 pageX: true, 5614 pageY: true, 5615 shiftKey: true, 5616 view: true, 5617 "char": true, 5618 code: true, 5619 charCode: true, 5620 key: true, 5621 keyCode: true, 5622 button: true, 5623 buttons: true, 5624 clientX: true, 5625 clientY: true, 5626 offsetX: true, 5627 offsetY: true, 5628 pointerId: true, 5629 pointerType: true, 5630 screenX: true, 5631 screenY: true, 5632 targetTouches: true, 5633 toElement: true, 5634 touches: true, 5635 5636 which: function( event ) { 5637 var button = event.button; 5638 5639 // Add which for key events 5640 if ( event.which == null && rkeyEvent.test( event.type ) ) { 5641 return event.charCode != null ? event.charCode : event.keyCode; 5642 } 5643 5644 // Add which for click: 1 === left; 2 === middle; 3 === right 5645 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { 5646 if ( button & 1 ) { 5647 return 1; 5648 } 5649 5650 if ( button & 2 ) { 5651 return 3; 5652 } 5653 5654 if ( button & 4 ) { 5655 return 2; 5656 } 5657 5658 return 0; 5659 } 5660 5661 return event.which; 5662 } 5663}, jQuery.event.addProp ); 5664 5665jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 5666 jQuery.event.special[ type ] = { 5667 5668 // Utilize native event if possible so blur/focus sequence is correct 5669 setup: function() { 5670 5671 // Claim the first handler 5672 // dataPriv.set( this, "focus", ... ) 5673 // dataPriv.set( this, "blur", ... ) 5674 leverageNative( this, type, expectSync ); 5675 5676 // Return false to allow normal processing in the caller 5677 return false;
vendor: 4,563 bytes, lines 5678-5854
5678 }, 5679 trigger: function() { 5680 5681 // Force setup before trigger 5682 leverageNative( this, type ); 5683 5684 // Return non-false to allow normal event-path propagation 5685 return true; 5686 }, 5687 5688 delegateType: delegateType 5689 }; 5690} ); 5691 5692// Create mouseenter/leave events using mouseover/out and event-time checks 5693// so that event delegation works in jQuery. 5694// Do the same for pointerenter/pointerleave and pointerover/pointerout 5695// 5696// Support: Safari 7 only 5697// Safari sends mouseenter too often; see: 5698// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 5699// for the description of the bug (it existed in older Chrome versions as well). 5700jQuery.each( { 5701 mouseenter: "mouseover", 5702 mouseleave: "mouseout", 5703 pointerenter: "pointerover", 5704 pointerleave: "pointerout" 5705}, function( orig, fix ) { 5706 jQuery.event.special[ orig ] = { 5707 delegateType: fix, 5708 bindType: fix, 5709 5710 handle: function( event ) { 5711 var ret, 5712 target = this, 5713 related = event.relatedTarget, 5714 handleObj = event.handleObj; 5715 5716 // For mouseenter/leave call the handler if related is outside the target. 5717 // NB: No relatedTarget if the mouse left/entered the browser window 5718 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5719 event.type = handleObj.origType; 5720 ret = handleObj.handler.apply( this, arguments ); 5721 event.type = fix; 5722 } 5723 return ret; 5724 } 5725 }; 5726} ); 5727 5728jQuery.fn.extend( { 5729 5730 on: function( types, selector, data, fn ) { 5731 return on( this, types, selector, data, fn ); 5732 }, 5733 one: function( types, selector, data, fn ) { 5734 return on( this, types, selector, data, fn, 1 ); 5735 }, 5736 off: function( types, selector, fn ) { 5737 var handleObj, type; 5738 if ( types && types.preventDefault && types.handleObj ) { 5739 5740 // ( event ) dispatched jQuery.Event 5741 handleObj = types.handleObj; 5742 jQuery( types.delegateTarget ).off( 5743 handleObj.namespace ? 5744 handleObj.origType + "." + handleObj.namespace : 5745 handleObj.origType, 5746 handleObj.selector, 5747 handleObj.handler 5748 ); 5749 return this; 5750 } 5751 if ( typeof types === "object" ) { 5752 5753 // ( types-object [, selector] ) 5754 for ( type in types ) { 5755 this.off( type, selector, types[ type ] ); 5756 } 5757 return this; 5758 } 5759 if ( selector === false || typeof selector === "function" ) { 5760 5761 // ( types [, fn] ) 5762 fn = selector; 5763 selector = undefined; 5764 } 5765 if ( fn === false ) { 5766 fn = returnFalse; 5767 } 5768 return this.each( function() { 5769 jQuery.event.remove( this, types, fn, selector ); 5770 } ); 5771 } 5772} ); 5773 5774 5775var 5776 5777 /* eslint-disable max-len */ 5778 5779 // See https://github.com/eslint/eslint/issues/3229 5780 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, 5781 5782 /* eslint-enable */ 5783 5784 // Support: IE <=10 - 11, Edge 12 - 13 only 5785 // In IE/Edge using regex groups here causes severe slowdowns. 5786 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5787 rnoInnerhtml = /<script|<style|<link/i, 5788 5789 // checked="checked" or checked 5790 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5791 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 5792 5793// Prefer a tbody over its parent table for containing new rows 5794function manipulationTarget( elem, content ) { 5795 if ( nodeName( elem, "table" ) && 5796 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 5797 5798 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 5799 } 5800 5801 return elem; 5802} 5803 5804// Replace/restore the type attribute of script elements for safe DOM manipulation 5805function disableScript( elem ) { 5806 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 5807 return elem; 5808} 5809function restoreScript( elem ) { 5810 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 5811 elem.type = elem.type.slice( 5 ); 5812 } else { 5813 elem.removeAttribute( "type" ); 5814 } 5815 5816 return elem; 5817} 5818 5819function cloneCopyEvent( src, dest ) { 5820 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; 5821 5822 if ( dest.nodeType !== 1 ) { 5823 return; 5824 } 5825 5826 // 1. Copy private data: events, handlers, etc. 5827 if ( dataPriv.hasData( src ) ) { 5828 pdataOld = dataPriv.access( src ); 5829 pdataCur = dataPriv.set( dest, pdataOld ); 5830 events = pdataOld.events; 5831 5832 if ( events ) { 5833 delete pdataCur.handle; 5834 pdataCur.events = {}; 5835 5836 for ( type in events ) { 5837 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5838 jQuery.event.add( dest, type, events[ type ][ i ] ); 5839 } 5840 } 5841 } 5842 } 5843 5844 // 2. Copy user data 5845 if ( dataUser.hasData( src ) ) { 5846 udataOld = dataUser.access( src ); 5847 udataCur = jQuery.extend( {}, udataOld ); 5848 5849 dataUser.set( dest, udataCur ); 5850 } 5851} 5852 5853// Fix IE bugs, see support tests 5854function fixInput( src, dest ) {
vendor: 3,609 bytes, lines 5855-5982
5855 var nodeName = dest.nodeName.toLowerCase(); 5856 5857 // Fails to persist the checked state of a cloned checkbox or radio button. 5858 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5859 dest.checked = src.checked; 5860 5861 // Fails to return the selected option to the default selected state when cloning options 5862 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5863 dest.defaultValue = src.defaultValue; 5864 } 5865} 5866 5867function domManip( collection, args, callback, ignored ) { 5868 5869 // Flatten any nested arrays 5870 args = concat.apply( [], args ); 5871 5872 var fragment, first, scripts, hasScripts, node, doc, 5873 i = 0, 5874 l = collection.length, 5875 iNoClone = l - 1, 5876 value = args[ 0 ], 5877 valueIsFunction = isFunction( value ); 5878 5879 // We can't cloneNode fragments that contain checked, in WebKit 5880 if ( valueIsFunction || 5881 ( l > 1 && typeof value === "string" && 5882 !support.checkClone && rchecked.test( value ) ) ) { 5883 return collection.each( function( index ) { 5884 var self = collection.eq( index ); 5885 if ( valueIsFunction ) { 5886 args[ 0 ] = value.call( this, index, self.html() ); 5887 } 5888 domManip( self, args, callback, ignored ); 5889 } ); 5890 } 5891 5892 if ( l ) { 5893 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 5894 first = fragment.firstChild; 5895 5896 if ( fragment.childNodes.length === 1 ) { 5897 fragment = first; 5898 } 5899 5900 // Require either new content or an interest in ignored elements to invoke the callback 5901 if ( first || ignored ) { 5902 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 5903 hasScripts = scripts.length; 5904 5905 // Use the original fragment for the last item 5906 // instead of the first because it can end up 5907 // being emptied incorrectly in certain situations (#8070). 5908 for ( ; i < l; i++ ) { 5909 node = fragment; 5910 5911 if ( i !== iNoClone ) { 5912 node = jQuery.clone( node, true, true ); 5913 5914 // Keep references to cloned scripts for later restoration 5915 if ( hasScripts ) { 5916 5917 // Support: Android <=4.0 only, PhantomJS 1 only 5918 // push.apply(_, arraylike) throws on ancient WebKit 5919 jQuery.merge( scripts, getAll( node, "script" ) ); 5920 } 5921 } 5922 5923 callback.call( collection[ i ], node, i ); 5924 } 5925 5926 if ( hasScripts ) { 5927 doc = scripts[ scripts.length - 1 ].ownerDocument; 5928 5929 // Reenable scripts 5930 jQuery.map( scripts, restoreScript ); 5931 5932 // Evaluate executable scripts on first document insertion 5933 for ( i = 0; i < hasScripts; i++ ) { 5934 node = scripts[ i ]; 5935 if ( rscriptType.test( node.type || "" ) && 5936 !dataPriv.access( node, "globalEval" ) && 5937 jQuery.contains( doc, node ) ) { 5938 5939 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 5940 5941 // Optional AJAX dependency, but won't run scripts if not present 5942 if ( jQuery._evalUrl && !node.noModule ) { 5943 jQuery._evalUrl( node.src, { 5944 nonce: node.nonce || node.getAttribute( "nonce" ) 5945 } ); 5946 } 5947 } else { 5948 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 5949 } 5950 } 5951 } 5952 } 5953 } 5954 } 5955 5956 return collection; 5957} 5958 5959function remove( elem, selector, keepData ) { 5960 var node, 5961 nodes = selector ? jQuery.filter( selector, elem ) : elem, 5962 i = 0; 5963 5964 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 5965 if ( !keepData && node.nodeType === 1 ) { 5966 jQuery.cleanData( getAll( node ) ); 5967 } 5968 5969 if ( node.parentNode ) { 5970 if ( keepData && isAttached( node ) ) { 5971 setGlobalEval( getAll( node, "script" ) ); 5972 } 5973 node.parentNode.removeChild( node ); 5974 } 5975 } 5976 5977 return elem; 5978} 5979 5980jQuery.extend( { 5981 htmlPrefilter: function( html ) { 5982 return html.replace( rxhtmlTag, "<$1></$2>" )
vendor: 2,889 bytes, lines 5982-6091
5982; 5983 }, 5984 5985 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5986 var i, l, srcElements, destElements, 5987 clone = elem.cloneNode( true ), 5988 inPage = isAttached( elem ); 5989 5990 // Fix IE cloning issues 5991 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 5992 !jQuery.isXMLDoc( elem ) ) { 5993 5994 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 5995 destElements = getAll( clone ); 5996 srcElements = getAll( elem ); 5997 5998 for ( i = 0, l = srcElements.length; i < l; i++ ) { 5999 fixInput( srcElements[ i ], destElements[ i ] ); 6000 } 6001 } 6002 6003 // Copy the events from the original to the clone 6004 if ( dataAndEvents ) { 6005 if ( deepDataAndEvents ) { 6006 srcElements = srcElements || getAll( elem ); 6007 destElements = destElements || getAll( clone ); 6008 6009 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6010 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 6011 } 6012 } else { 6013 cloneCopyEvent( elem, clone ); 6014 } 6015 } 6016 6017 // Preserve script evaluation history 6018 destElements = getAll( clone, "script" ); 6019 if ( destElements.length > 0 ) { 6020 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6021 } 6022 6023 // Return the cloned set 6024 return clone; 6025 }, 6026 6027 cleanData: function( elems ) { 6028 var data, elem, type, 6029 special = jQuery.event.special, 6030 i = 0; 6031 6032 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 6033 if ( acceptData( elem ) ) { 6034 if ( ( data = elem[ dataPriv.expando ] ) ) { 6035 if ( data.events ) { 6036 for ( type in data.events ) { 6037 if ( special[ type ] ) { 6038 jQuery.event.remove( elem, type ); 6039 6040 // This is a shortcut to avoid jQuery.event.remove's overhead 6041 } else { 6042 jQuery.removeEvent( elem, type, data.handle ); 6043 } 6044 } 6045 } 6046 6047 // Support: Chrome <=35 - 45+ 6048 // Assign undefined instead of using delete, see Data#remove 6049 elem[ dataPriv.expando ] = undefined; 6050 } 6051 if ( elem[ dataUser.expando ] ) { 6052 6053 // Support: Chrome <=35 - 45+ 6054 // Assign undefined instead of using delete, see Data#remove 6055 elem[ dataUser.expando ] = undefined; 6056 } 6057 } 6058 } 6059 } 6060} ); 6061 6062jQuery.fn.extend( { 6063 detach: function( selector ) { 6064 return remove( this, selector, true ); 6065 }, 6066 6067 remove: function( selector ) { 6068 return remove( this, selector ); 6069 }, 6070 6071 text: function( value ) { 6072 return access( this, function( value ) { 6073 return value === undefined ? 6074 jQuery.text( this ) : 6075 this.empty().each( function() { 6076 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6077 this.textContent = value; 6078 } 6079 } ); 6080 }, null, value, arguments.length ); 6081 }, 6082 6083 append: function() { 6084 return domManip( this, arguments, function( elem ) { 6085 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6086 var target = manipulationTarget( this, elem ); 6087 target.appendChild( elem ); 6088 } 6089 } ); 6090 }, 6091
vendor: 5,129 bytes, lines 6092-6284
6092 prepend: function() { 6093 return domManip( this, arguments, function( elem ) { 6094 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6095 var target = manipulationTarget( this, elem ); 6096 target.insertBefore( elem, target.firstChild ); 6097 } 6098 } ); 6099 }, 6100 6101 before: function() { 6102 return domManip( this, arguments, function( elem ) { 6103 if ( this.parentNode ) { 6104 this.parentNode.insertBefore( elem, this ); 6105 } 6106 } ); 6107 }, 6108 6109 after: function() { 6110 return domManip( this, arguments, function( elem ) { 6111 if ( this.parentNode ) { 6112 this.parentNode.insertBefore( elem, this.nextSibling ); 6113 } 6114 } ); 6115 }, 6116 6117 empty: function() { 6118 var elem, 6119 i = 0; 6120 6121 for ( ; ( elem = this[ i ] ) != null; i++ ) { 6122 if ( elem.nodeType === 1 ) { 6123 6124 // Prevent memory leaks 6125 jQuery.cleanData( getAll( elem, false ) ); 6126 6127 // Remove any remaining nodes 6128 elem.textContent = ""; 6129 } 6130 } 6131 6132 return this; 6133 }, 6134 6135 clone: function( dataAndEvents, deepDataAndEvents ) { 6136 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6137 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6138 6139 return this.map( function() { 6140 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 6141 } ); 6142 }, 6143 6144 html: function( value ) { 6145 return access( this, function( value ) { 6146 var elem = this[ 0 ] || {}, 6147 i = 0, 6148 l = this.length; 6149 6150 if ( value === undefined && elem.nodeType === 1 ) { 6151 return elem.innerHTML; 6152 } 6153 6154 // See if we can take a shortcut and just use innerHTML 6155 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 6156 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 6157 6158 value = jQuery.htmlPrefilter( value ); 6159 6160 try { 6161 for ( ; i < l; i++ ) { 6162 elem = this[ i ] || {}; 6163 6164 // Remove element nodes and prevent memory leaks 6165 if ( elem.nodeType === 1 ) { 6166 jQuery.cleanData( getAll( elem, false ) ); 6167 elem.innerHTML = value; 6168 } 6169 } 6170 6171 elem = 0; 6172 6173 // If using innerHTML throws an exception, use the fallback method 6174 } catch ( e ) {} 6175 } 6176 6177 if ( elem ) { 6178 this.empty().append( value ); 6179 } 6180 }, null, value, arguments.length ); 6181 }, 6182 6183 replaceWith: function() { 6184 var ignored = []; 6185 6186 // Make the changes, replacing each non-ignored context element with the new content 6187 return domManip( this, arguments, function( elem ) { 6188 var parent = this.parentNode; 6189 6190 if ( jQuery.inArray( this, ignored ) < 0 ) { 6191 jQuery.cleanData( getAll( this ) ); 6192 if ( parent ) { 6193 parent.replaceChild( elem, this ); 6194 } 6195 } 6196 6197 // Force callback invocation 6198 }, ignored ); 6199 } 6200} ); 6201 6202jQuery.each( { 6203 appendTo: "append", 6204 prependTo: "prepend", 6205 insertBefore: "before", 6206 insertAfter: "after", 6207 replaceAll: "replaceWith" 6208}, function( name, original ) { 6209 jQuery.fn[ name ] = function( selector ) { 6210 var elems, 6211 ret = [], 6212 insert = jQuery( selector ), 6213 last = insert.length - 1, 6214 i = 0; 6215 6216 for ( ; i <= last; i++ ) { 6217 elems = i === last ? this : this.clone( true ); 6218 jQuery( insert[ i ] )[ original ]( elems ); 6219 6220 // Support: Android <=4.0 only, PhantomJS 1 only 6221 // .get() because push.apply(_, arraylike) throws on ancient WebKit 6222 push.apply( ret, elems.get() ); 6223 } 6224 6225 return this.pushStack( ret ); 6226 }; 6227} ); 6228var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 6229 6230var getStyles = function( elem ) { 6231 6232 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 6233 // IE throws on elements created in popups 6234 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6235 var view = elem.ownerDocument.defaultView; 6236 6237 if ( !view || !view.opener ) { 6238 view = window; 6239 } 6240 6241 return view.getComputedStyle( elem ); 6242 }; 6243 6244var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 6245 6246 6247 6248( function() { 6249 6250 // Executing both pixelPosition & boxSizingReliable tests require only one layout 6251 // so they're executed at the same time to save the second computation. 6252 function computeStyleTests() { 6253 6254 // This is a singleton, we need to execute it only once 6255 if ( !div ) { 6256 return; 6257 } 6258 6259 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 6260 "margin-top:1px;padding:0;border:0"; 6261 div.style.cssText = 6262 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 6263 "margin:auto;border:1px;padding:1px;" + 6264 "width:60%;top:1%"; 6265 documentElement.appendChild( container ).appendChild( div ); 6266 6267 var divStyle = window.getComputedStyle( div ); 6268 pixelPositionVal = divStyle.top !== "1%"; 6269 6270 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 6271 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 6272 6273 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 6274 // Some styles come back with percentage values, even though they shouldn't 6275 div.style.right = "60%"; 6276 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 6277 6278 // Support: IE 9 - 11 only 6279 // Detect misreporting of content dimensions for box-sizing:border-box elements 6280 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 6281 6282 // Support: IE 9 only 6283 // Detect overflow:scroll screwiness (gh-3699) 6284
vendor: 8,298 bytes, lines 6284-6574
6284// Support: Chrome <=64 6285 // Don't get tricked when zoom affects offsetWidth (gh-4029) 6286 div.style.position = "absolute"; 6287 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 6288 6289 documentElement.removeChild( container ); 6290 6291 // Nullify the div so it wouldn't be stored in the memory and 6292 // it will also be a sign that checks already performed 6293 div = null; 6294 } 6295 6296 function roundPixelMeasures( measure ) { 6297 return Math.round( parseFloat( measure ) ); 6298 } 6299 6300 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 6301 reliableMarginLeftVal, 6302 container = document.createElement( "div" ), 6303 div = document.createElement( "div" ); 6304 6305 // Finish early in limited (non-browser) environments 6306 if ( !div.style ) { 6307 return; 6308 } 6309 6310 // Support: IE <=9 - 11 only 6311 // Style of cloned element affects source element cloned (#8908) 6312 div.style.backgroundClip = "content-box"; 6313 div.cloneNode( true ).style.backgroundClip = ""; 6314 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6315 6316 jQuery.extend( support, { 6317 boxSizingReliable: function() { 6318 computeStyleTests(); 6319 return boxSizingReliableVal; 6320 }, 6321 pixelBoxStyles: function() { 6322 computeStyleTests(); 6323 return pixelBoxStylesVal; 6324 }, 6325 pixelPosition: function() { 6326 computeStyleTests(); 6327 return pixelPositionVal; 6328 }, 6329 reliableMarginLeft: function() { 6330 computeStyleTests(); 6331 return reliableMarginLeftVal; 6332 }, 6333 scrollboxSize: function() { 6334 computeStyleTests(); 6335 return scrollboxSizeVal; 6336 } 6337 } ); 6338} )(); 6339 6340 6341function curCSS( elem, name, computed ) { 6342 var width, minWidth, maxWidth, ret, 6343 6344 // Support: Firefox 51+ 6345 // Retrieving style before computed somehow 6346 // fixes an issue with getting wrong values 6347 // on detached elements 6348 style = elem.style; 6349 6350 computed = computed || getStyles( elem ); 6351 6352 // getPropertyValue is needed for: 6353 // .css('filter') (IE 9 only, #12537) 6354 // .css('--customProperty) (#3144) 6355 if ( computed ) { 6356 ret = computed.getPropertyValue( name ) || computed[ name ]; 6357 6358 if ( ret === "" && !isAttached( elem ) ) { 6359 ret = jQuery.style( elem, name ); 6360 } 6361 6362 // A tribute to the "awesome hack by Dean Edwards" 6363 // Android Browser returns percentage for some values, 6364 // but width seems to be reliably pixels. 6365 // This is against the CSSOM draft spec: 6366 // https://drafts.csswg.org/cssom/#resolved-values 6367 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 6368 6369 // Remember the original values 6370 width = style.width; 6371 minWidth = style.minWidth; 6372 maxWidth = style.maxWidth; 6373 6374 // Put in the new values to get a computed value out 6375 style.minWidth = style.maxWidth = style.width = ret; 6376 ret = computed.width; 6377 6378 // Revert the changed values 6379 style.width = width; 6380 style.minWidth = minWidth; 6381 style.maxWidth = maxWidth; 6382 } 6383 } 6384 6385 return ret !== undefined ? 6386 6387 // Support: IE <=9 - 11 only 6388 // IE returns zIndex value as an integer. 6389 ret + "" : 6390 ret; 6391} 6392 6393 6394function addGetHookIf( conditionFn, hookFn ) { 6395 6396 // Define the hook, we'll check on the first run if it's really needed. 6397 return { 6398 get: function() { 6399 if ( conditionFn() ) { 6400 6401 // Hook not needed (or it's not possible to use it due 6402 // to missing dependency), remove it. 6403 delete this.get; 6404 return; 6405 } 6406 6407 // Hook needed; redefine it so that the support test is not executed again. 6408 return ( this.get = hookFn ).apply( this, arguments ); 6409 } 6410 }; 6411} 6412 6413 6414var cssPrefixes = [ "Webkit", "Moz", "ms" ], 6415 emptyStyle = document.createElement( "div" ).style, 6416 vendorProps = {}; 6417 6418// Return a vendor-prefixed property or undefined 6419function vendorPropName( name ) { 6420 6421 // Check for vendor prefixed names 6422 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 6423 i = cssPrefixes.length; 6424 6425 while ( i-- ) { 6426 name = cssPrefixes[ i ] + capName; 6427 if ( name in emptyStyle ) { 6428 return name; 6429 } 6430 } 6431} 6432 6433// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 6434function finalPropName( name ) { 6435 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 6436 6437 if ( final ) { 6438 return final; 6439 } 6440 if ( name in emptyStyle ) { 6441 return name; 6442 } 6443 return vendorProps[ name ] = vendorPropName( name ) || name; 6444} 6445 6446 6447var 6448 6449 // Swappable if display is none or starts with table 6450 // except "table", "table-cell", or "table-caption" 6451 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6452 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6453 rcustomProp = /^--/, 6454 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6455 cssNormalTransform = { 6456 letterSpacing: "0", 6457 fontWeight: "400" 6458 }; 6459 6460function setPositiveNumber( elem, value, subtract ) { 6461 6462 // Any relative (+/-) values have already been 6463 // normalized at this point 6464 var matches = rcssNum.exec( value ); 6465 return matches ? 6466 6467 // Guard against undefined "subtract", e.g., when used as in cssHooks 6468 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 6469 value; 6470} 6471 6472function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 6473 var i = dimension === "width" ? 1 : 0, 6474 extra = 0, 6475 delta = 0; 6476 6477 // Adjustment may not be necessary 6478 if ( box === ( isBorderBox ? "border" : "content" ) ) { 6479 return 0; 6480 } 6481 6482 for ( ; i < 4; i += 2 ) { 6483 6484 // Both box models exclude margin 6485 if ( box === "margin" ) { 6486 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 6487 } 6488 6489 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 6490 if ( !isBorderBox ) { 6491 6492 // Add padding 6493 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6494 6495 // For "border" or "margin", add border 6496 if ( box !== "padding" ) { 6497 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6498 6499 // But still keep track of it otherwise 6500 } else { 6501 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6502 } 6503 6504 // If we get here with a border-box (content + padding + border), we're seeking "content" or 6505 // "padding" or "margin" 6506 } else { 6507 6508 // For "content", subtract padding 6509 if ( box === "content" ) { 6510 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6511 } 6512 6513 // For "content" or "padding", subtract border 6514 if ( box !== "margin" ) { 6515 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6516 } 6517 } 6518 } 6519 6520 // Account for positive content-box scroll gutter when requested by providing computedVal 6521 if ( !isBorderBox && computedVal >= 0 ) { 6522 6523 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 6524 // Assuming integer scroll gutter, subtract the rest and round down 6525 delta += Math.max( 0, Math.ceil( 6526 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6527 computedVal - 6528 delta - 6529 extra - 6530 0.5 6531 6532 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 6533 // Use an explicit zero to avoid NaN (gh-3964) 6534 ) ) || 0; 6535 } 6536 6537 return delta; 6538} 6539 6540function getWidthOrHeight( elem, dimension, extra ) { 6541 6542 // Start with computed style 6543 var styles = getStyles( elem ), 6544 6545 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 6546 // Fake content-box until we know it's needed to know the true value. 6547 boxSizingNeeded = !support.boxSizingReliable() || extra, 6548 isBorderBox = boxSizingNeeded && 6549 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6550 valueIsBorderBox = isBorderBox, 6551 6552 val = curCSS( elem, dimension, styles ), 6553 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 6554 6555 // Support: Firefox <=54 6556 // Return a confounding non-pixel value or feign ignorance, as appropriate. 6557 if ( rnumnonpx.test( val ) ) { 6558 if ( !extra ) { 6559 return val; 6560 } 6561 val = "auto"; 6562 } 6563 6564 6565 // Fall back to offsetWidth/offsetHeight when value is "auto" 6566 // This happens for inline elements with no explicit setting (gh-3571) 6567 // Support: Android <=4.1 - 4.3 only 6568 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 6569 // Support: IE 9-11 only 6570 // Also use offsetWidth/offsetHeight for when box sizing is unreliable 6571 // We use getClientRects() to check for hidden/disconnected. 6572 // In those cases, the computed value can be trusted to be border-box 6573 if ( ( !support.boxSizingReliable() && isBorderBox || 6574 val === "auto" ||
vendor: 3,698 bytes, lines 6575-6705
6575 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 6576 elem.getClientRects().length ) { 6577 6578 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 6579 6580 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 6581 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 6582 // retrieved value as a content box dimension. 6583 valueIsBorderBox = offsetProp in elem; 6584 if ( valueIsBorderBox ) { 6585 val = elem[ offsetProp ]; 6586 } 6587 } 6588 6589 // Normalize "" and auto 6590 val = parseFloat( val ) || 0; 6591 6592 // Adjust for the element's box model 6593 return ( val + 6594 boxModelAdjustment( 6595 elem, 6596 dimension, 6597 extra || ( isBorderBox ? "border" : "content" ), 6598 valueIsBorderBox, 6599 styles, 6600 6601 // Provide the current computed size to request scroll gutter calculation (gh-3589) 6602 val 6603 ) 6604 ) + "px"; 6605} 6606 6607jQuery.extend( { 6608 6609 // Add in style property hooks for overriding the default 6610 // behavior of getting and setting a style property 6611 cssHooks: { 6612 opacity: { 6613 get: function( elem, computed ) { 6614 if ( computed ) { 6615 6616 // We should always get a number back from opacity 6617 var ret = curCSS( elem, "opacity" ); 6618 return ret === "" ? "1" : ret; 6619 } 6620 } 6621 } 6622 }, 6623 6624 // Don't automatically add "px" to these possibly-unitless properties 6625 cssNumber: { 6626 "animationIterationCount": true, 6627 "columnCount": true, 6628 "fillOpacity": true, 6629 "flexGrow": true, 6630 "flexShrink": true, 6631 "fontWeight": true, 6632 "gridArea": true, 6633 "gridColumn": true, 6634 "gridColumnEnd": true, 6635 "gridColumnStart": true, 6636 "gridRow": true, 6637 "gridRowEnd": true, 6638 "gridRowStart": true, 6639 "lineHeight": true, 6640 "opacity": true, 6641 "order": true, 6642 "orphans": true, 6643 "widows": true, 6644 "zIndex": true, 6645 "zoom": true 6646 }, 6647 6648 // Add in properties whose names you wish to fix before 6649 // setting or getting the value 6650 cssProps: {}, 6651 6652 // Get and set the style property on a DOM Node 6653 style: function( elem, name, value, extra ) { 6654 6655 // Don't set styles on text and comment nodes 6656 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6657 return; 6658 } 6659 6660 // Make sure that we're working with the right name 6661 var ret, type, hooks, 6662 origName = camelCase( name ), 6663 isCustomProp = rcustomProp.test( name ), 6664 style = elem.style; 6665 6666 // Make sure that we're working with the right name. We don't 6667 // want to query the value if it is a CSS custom property 6668 // since they are user-defined. 6669 if ( !isCustomProp ) { 6670 name = finalPropName( origName ); 6671 } 6672 6673 // Gets hook for the prefixed version, then unprefixed version 6674 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6675 6676 // Check if we're setting a value 6677 if ( value !== undefined ) { 6678 type = typeof value; 6679 6680 // Convert "+=" or "-=" to relative numbers (#7345) 6681 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 6682 value = adjustCSS( elem, name, ret ); 6683 6684 // Fixes bug #9237 6685 type = "number"; 6686 } 6687 6688 // Make sure that null and NaN values aren't set (#7116) 6689 if ( value == null || value !== value ) { 6690 return; 6691 } 6692 6693 // If a number was passed in, add the unit (except for certain CSS properties) 6694 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 6695 // "px" to a few hardcoded values. 6696 if ( type === "number" && !isCustomProp ) { 6697 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 6698 } 6699 6700 // background-* props affect original clone's values 6701 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 6702 style[ name ] = "inherit"; 6703 } 6704 6705 // If a hook was provided, use that value, otherwise just set the specified value
vendor: 7,976 bytes, lines 6706-6988
6706 if ( !hooks || !( "set" in hooks ) || 6707 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 6708 6709 if ( isCustomProp ) { 6710 style.setProperty( name, value ); 6711 } else { 6712 style[ name ] = value; 6713 } 6714 } 6715 6716 } else { 6717 6718 // If a hook was provided get the non-computed value from there 6719 if ( hooks && "get" in hooks && 6720 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 6721 6722 return ret; 6723 } 6724 6725 // Otherwise just get the value from the style object 6726 return style[ name ]; 6727 } 6728 }, 6729 6730 css: function( elem, name, extra, styles ) { 6731 var val, num, hooks, 6732 origName = camelCase( name ), 6733 isCustomProp = rcustomProp.test( name ); 6734 6735 // Make sure that we're working with the right name. We don't 6736 // want to modify the value if it is a CSS custom property 6737 // since they are user-defined. 6738 if ( !isCustomProp ) { 6739 name = finalPropName( origName ); 6740 } 6741 6742 // Try prefixed name followed by the unprefixed name 6743 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6744 6745 // If a hook was provided get the computed value from there 6746 if ( hooks && "get" in hooks ) { 6747 val = hooks.get( elem, true, extra ); 6748 } 6749 6750 // Otherwise, if a way to get the computed value exists, use that 6751 if ( val === undefined ) { 6752 val = curCSS( elem, name, styles ); 6753 } 6754 6755 // Convert "normal" to computed value 6756 if ( val === "normal" && name in cssNormalTransform ) { 6757 val = cssNormalTransform[ name ]; 6758 } 6759 6760 // Make numeric if forced or a qualifier was provided and val looks numeric 6761 if ( extra === "" || extra ) { 6762 num = parseFloat( val ); 6763 return extra === true || isFinite( num ) ? num || 0 : val; 6764 } 6765 6766 return val; 6767 } 6768} ); 6769 6770jQuery.each( [ "height", "width" ], function( i, dimension ) { 6771 jQuery.cssHooks[ dimension ] = { 6772 get: function( elem, computed, extra ) { 6773 if ( computed ) { 6774 6775 // Certain elements can have dimension info if we invisibly show them 6776 // but it must have a current display style that would benefit 6777 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 6778 6779 // Support: Safari 8+ 6780 // Table columns in Safari have non-zero offsetWidth & zero 6781 // getBoundingClientRect().width unless display is changed. 6782 // Support: IE <=11 only 6783 // Running getBoundingClientRect on a disconnected node 6784 // in IE throws an error. 6785 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 6786 swap( elem, cssShow, function() { 6787 return getWidthOrHeight( elem, dimension, extra ); 6788 } ) : 6789 getWidthOrHeight( elem, dimension, extra ); 6790 } 6791 }, 6792 6793 set: function( elem, value, extra ) { 6794 var matches, 6795 styles = getStyles( elem ), 6796 6797 // Only read styles.position if the test has a chance to fail 6798 // to avoid forcing a reflow. 6799 scrollboxSizeBuggy = !support.scrollboxSize() && 6800 styles.position === "absolute", 6801 6802 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 6803 boxSizingNeeded = scrollboxSizeBuggy || extra, 6804 isBorderBox = boxSizingNeeded && 6805 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6806 subtract = extra ? 6807 boxModelAdjustment( 6808 elem, 6809 dimension, 6810 extra, 6811 isBorderBox, 6812 styles 6813 ) : 6814 0; 6815 6816 // Account for unreliable border-box dimensions by comparing offset* to computed and 6817 // faking a content-box to get border and padding (gh-3699) 6818 if ( isBorderBox && scrollboxSizeBuggy ) { 6819 subtract -= Math.ceil( 6820 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6821 parseFloat( styles[ dimension ] ) - 6822 boxModelAdjustment( elem, dimension, "border", false, styles ) - 6823 0.5 6824 ); 6825 } 6826 6827 // Convert to pixels if value adjustment is needed 6828 if ( subtract && ( matches = rcssNum.exec( value ) ) && 6829 ( matches[ 3 ] || "px" ) !== "px" ) { 6830 6831 elem.style[ dimension ] = value; 6832 value = jQuery.css( elem, dimension ); 6833 } 6834 6835 return setPositiveNumber( elem, value, subtract ); 6836 } 6837 }; 6838} ); 6839 6840jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 6841 function( elem, computed ) { 6842 if ( computed ) { 6843 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 6844 elem.getBoundingClientRect().left - 6845 swap( elem, { marginLeft: 0 }, function() { 6846 return elem.getBoundingClientRect().left; 6847 } ) 6848 ) + "px"; 6849 } 6850 } 6851); 6852 6853// These hooks are used by animate to expand properties 6854jQuery.each( { 6855 margin: "", 6856 padding: "", 6857 border: "Width" 6858}, function( prefix, suffix ) { 6859 jQuery.cssHooks[ prefix + suffix ] = { 6860 expand: function( value ) { 6861 var i = 0, 6862 expanded = {}, 6863 6864 // Assumes a single number if not a string 6865 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 6866 6867 for ( ; i < 4; i++ ) { 6868 expanded[ prefix + cssExpand[ i ] + suffix ] = 6869 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6870 } 6871 6872 return expanded; 6873 } 6874 }; 6875 6876 if ( prefix !== "margin" ) { 6877 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 6878 } 6879} ); 6880 6881jQuery.fn.extend( { 6882 css: function( name, value ) { 6883 return access( this, function( elem, name, value ) { 6884 var styles, len, 6885 map = {}, 6886 i = 0; 6887 6888 if ( Array.isArray( name ) ) { 6889 styles = getStyles( elem ); 6890 len = name.length; 6891 6892 for ( ; i < len; i++ ) { 6893 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 6894 } 6895 6896 return map; 6897 } 6898 6899 return value !== undefined ? 6900 jQuery.style( elem, name, value ) : 6901 jQuery.css( elem, name ); 6902 }, name, value, arguments.length > 1 ); 6903 } 6904} ); 6905 6906 6907function Tween( elem, options, prop, end, easing ) { 6908 return new Tween.prototype.init( elem, options, prop, end, easing ); 6909} 6910jQuery.Tween = Tween; 6911 6912Tween.prototype = { 6913 constructor: Tween, 6914 init: function( elem, options, prop, end, easing, unit ) { 6915 this.elem = elem; 6916 this.prop = prop; 6917 this.easing = easing || jQuery.easing._default; 6918 this.options = options; 6919 this.start = this.now = this.cur(); 6920 this.end = end; 6921 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 6922 }, 6923 cur: function() { 6924 var hooks = Tween.propHooks[ this.prop ]; 6925 6926 return hooks && hooks.get ? 6927 hooks.get( this ) : 6928 Tween.propHooks._default.get( this ); 6929 }, 6930 run: function( percent ) { 6931 var eased, 6932 hooks = Tween.propHooks[ this.prop ]; 6933 6934 if ( this.options.duration ) { 6935 this.pos = eased = jQuery.easing[ this.easing ]( 6936 percent, this.options.duration * percent, 0, 1, this.options.duration 6937 ); 6938 } else { 6939 this.pos = eased = percent; 6940 } 6941 this.now = ( this.end - this.start ) * eased + this.start; 6942 6943 if ( this.options.step ) { 6944 this.options.step.call( this.elem, this.now, this ); 6945 } 6946 6947 if ( hooks && hooks.set ) { 6948 hooks.set( this ); 6949 } else { 6950 Tween.propHooks._default.set( this ); 6951 } 6952 return this; 6953 } 6954}; 6955 6956Tween.prototype.init.prototype = Tween.prototype; 6957 6958Tween.propHooks = { 6959 _default: { 6960 get: function( tween ) { 6961 var result; 6962 6963 // Use a property on the element directly when it is not a DOM element, 6964 // or when there is no matching style property that exists. 6965 if ( tween.elem.nodeType !== 1 || 6966 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 6967 return tween.elem[ tween.prop ]; 6968 } 6969 6970 // Passing an empty string as a 3rd parameter to .css will automatically 6971 // attempt a parseFloat and fallback to a string if the parse fails. 6972 // Simple values such as "10px" are parsed to Float; 6973 // complex values such as "rotate(1rad)" are returned as-is. 6974 result = jQuery.css( tween.elem, tween.prop, "" ); 6975 6976 // Empty strings, null, undefined and "auto" are converted to 0. 6977 return !result || result === "auto" ? 0 : result; 6978 }, 6979 set: function( tween ) { 6980 6981 // Use step hook for back compat. 6982 // Use cssHook if its there. 6983 // Use .style if available and use plain properties where available. 6984 if ( jQuery.fx.step[ tween.prop ] ) { 6985 jQuery.fx.step[ tween.prop ]( tween ); 6986 } else if ( tween.elem.nodeType === 1 && ( 6987 jQuery.cssHooks[ tween.prop ] || 6988 tween.elem.style[ finalPropName( tween.prop ) ] != null
vendor: 29,107 bytes, lines 6988-8185
6988 ) ) { 6989 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 6990 } else { 6991 tween.elem[ tween.prop ] = tween.now; 6992 } 6993 } 6994 } 6995}; 6996 6997// Support: IE <=9 only 6998// Panic based approach to setting things on disconnected nodes 6999Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7000 set: function( tween ) { 7001 if ( tween.elem.nodeType && tween.elem.parentNode ) { 7002 tween.elem[ tween.prop ] = tween.now; 7003 } 7004 } 7005}; 7006 7007jQuery.easing = { 7008 linear: function( p ) { 7009 return p; 7010 }, 7011 swing: function( p ) { 7012 return 0.5 - Math.cos( p * Math.PI ) / 2; 7013 }, 7014 _default: "swing" 7015}; 7016 7017jQuery.fx = Tween.prototype.init; 7018 7019// Back compat <1.8 extension point 7020jQuery.fx.step = {}; 7021 7022 7023 7024 7025var 7026 fxNow, inProgress, 7027 rfxtypes = /^(?:toggle|show|hide)$/, 7028 rrun = /queueHooks$/; 7029 7030function schedule() { 7031 if ( inProgress ) { 7032 if ( document.hidden === false && window.requestAnimationFrame ) { 7033 window.requestAnimationFrame( schedule ); 7034 } else { 7035 window.setTimeout( schedule, jQuery.fx.interval ); 7036 } 7037 7038 jQuery.fx.tick(); 7039 } 7040} 7041 7042// Animations created synchronously will run synchronously 7043function createFxNow() { 7044 window.setTimeout( function() { 7045 fxNow = undefined; 7046 } ); 7047 return ( fxNow = Date.now() ); 7048} 7049 7050// Generate parameters to create a standard animation 7051function genFx( type, includeWidth ) { 7052 var which, 7053 i = 0, 7054 attrs = { height: type }; 7055 7056 // If we include width, step value is 1 to do all cssExpand values, 7057 // otherwise step value is 2 to skip over Left and Right 7058 includeWidth = includeWidth ? 1 : 0; 7059 for ( ; i < 4; i += 2 - includeWidth ) { 7060 which = cssExpand[ i ]; 7061 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 7062 } 7063 7064 if ( includeWidth ) { 7065 attrs.opacity = attrs.width = type; 7066 } 7067 7068 return attrs; 7069} 7070 7071function createTween( value, prop, animation ) { 7072 var tween, 7073 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 7074 index = 0, 7075 length = collection.length; 7076 for ( ; index < length; index++ ) { 7077 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 7078 7079 // We're done with this property 7080 return tween; 7081 } 7082 } 7083} 7084 7085function defaultPrefilter( elem, props, opts ) { 7086 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 7087 isBox = "width" in props || "height" in props, 7088 anim = this, 7089 orig = {}, 7090 style = elem.style, 7091 hidden = elem.nodeType && isHiddenWithinTree( elem ), 7092 dataShow = dataPriv.get( elem, "fxshow" ); 7093 7094 // Queue-skipping animations hijack the fx hooks 7095 if ( !opts.queue ) { 7096 hooks = jQuery._queueHooks( elem, "fx" ); 7097 if ( hooks.unqueued == null ) { 7098 hooks.unqueued = 0; 7099 oldfire = hooks.empty.fire; 7100 hooks.empty.fire = function() { 7101 if ( !hooks.unqueued ) { 7102 oldfire(); 7103 } 7104 }; 7105 } 7106 hooks.unqueued++; 7107 7108 anim.always( function() { 7109 7110 // Ensure the complete handler is called before this completes 7111 anim.always( function() { 7112 hooks.unqueued--; 7113 if ( !jQuery.queue( elem, "fx" ).length ) { 7114 hooks.empty.fire(); 7115 } 7116 } ); 7117 } ); 7118 } 7119 7120 // Detect show/hide animations 7121 for ( prop in props ) { 7122 value = props[ prop ]; 7123 if ( rfxtypes.test( value ) ) { 7124 delete props[ prop ]; 7125 toggle = toggle || value === "toggle"; 7126 if ( value === ( hidden ? "hide" : "show" ) ) { 7127 7128 // Pretend to be hidden if this is a "show" and 7129 // there is still data from a stopped show/hide 7130 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 7131 hidden = true; 7132 7133 // Ignore all other no-op show/hide data 7134 } else { 7135 continue; 7136 } 7137 } 7138 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 7139 } 7140 } 7141 7142 // Bail out if this is a no-op like .hide().hide() 7143 propTween = !jQuery.isEmptyObject( props ); 7144 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 7145 return; 7146 } 7147 7148 // Restrict "overflow" and "display" styles during box animations 7149 if ( isBox && elem.nodeType === 1 ) { 7150 7151 // Support: IE <=9 - 11, Edge 12 - 15 7152 // Record all 3 overflow attributes because IE does not infer the shorthand 7153 // from identically-valued overflowX and overflowY and Edge just mirrors 7154 // the overflowX value there. 7155 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 7156 7157 // Identify a display type, preferring old show/hide data over the CSS cascade 7158 restoreDisplay = dataShow && dataShow.display; 7159 if ( restoreDisplay == null ) { 7160 restoreDisplay = dataPriv.get( elem, "display" ); 7161 } 7162 display = jQuery.css( elem, "display" ); 7163 if ( display === "none" ) { 7164 if ( restoreDisplay ) { 7165 display = restoreDisplay; 7166 } else { 7167 7168 // Get nonempty value(s) by temporarily forcing visibility 7169 showHide( [ elem ], true ); 7170 restoreDisplay = elem.style.display || restoreDisplay; 7171 display = jQuery.css( elem, "display" ); 7172 showHide( [ elem ] ); 7173 } 7174 } 7175 7176 // Animate inline elements as inline-block 7177 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 7178 if ( jQuery.css( elem, "float" ) === "none" ) { 7179 7180 // Restore the original display value at the end of pure show/hide animations 7181 if ( !propTween ) { 7182 anim.done( function() { 7183 style.display = restoreDisplay; 7184 } ); 7185 if ( restoreDisplay == null ) { 7186 display = style.display; 7187 restoreDisplay = display === "none" ? "" : display; 7188 } 7189 } 7190 style.display = "inline-block"; 7191 } 7192 } 7193 } 7194 7195 if ( opts.overflow ) { 7196 style.overflow = "hidden"; 7197 anim.always( function() { 7198 style.overflow = opts.overflow[ 0 ]; 7199 style.overflowX = opts.overflow[ 1 ]; 7200 style.overflowY = opts.overflow[ 2 ]; 7201 } ); 7202 } 7203 7204 // Implement show/hide animations 7205 propTween = false; 7206 for ( prop in orig ) { 7207 7208 // General show/hide setup for this element animation 7209 if ( !propTween ) { 7210 if ( dataShow ) { 7211 if ( "hidden" in dataShow ) { 7212 hidden = dataShow.hidden; 7213 } 7214 } else { 7215 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 7216 } 7217 7218 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 7219 if ( toggle ) { 7220 dataShow.hidden = !hidden; 7221 } 7222 7223 // Show elements before animating them 7224 if ( hidden ) { 7225 showHide( [ elem ], true ); 7226 } 7227 7228 /* eslint-disable no-loop-func */ 7229 7230 anim.done( function() { 7231 7232 /* eslint-enable no-loop-func */ 7233 7234 // The final step of a "hide" animation is actually hiding the element 7235 if ( !hidden ) { 7236 showHide( [ elem ] ); 7237 } 7238 dataPriv.remove( elem, "fxshow" ); 7239 for ( prop in orig ) { 7240 jQuery.style( elem, prop, orig[ prop ] ); 7241 } 7242 } ); 7243 } 7244 7245 // Per-property setup 7246 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 7247 if ( !( prop in dataShow ) ) { 7248 dataShow[ prop ] = propTween.start; 7249 if ( hidden ) { 7250 propTween.end = propTween.start; 7251 propTween.start = 0; 7252 } 7253 } 7254 } 7255} 7256 7257function propFilter( props, specialEasing ) { 7258 var index, name, easing, value, hooks; 7259 7260 // camelCase, specialEasing and expand cssHook pass 7261 for ( index in props ) { 7262 name = camelCase( index ); 7263 easing = specialEasing[ name ]; 7264 value = props[ index ]; 7265 if ( Array.isArray( value ) ) { 7266 easing = value[ 1 ]; 7267 value = props[ index ] = value[ 0 ]; 7268 } 7269 7270 if ( index !== name ) { 7271 props[ name ] = value; 7272 delete props[ index ]; 7273 } 7274 7275 hooks = jQuery.cssHooks[ name ]; 7276 if ( hooks && "expand" in hooks ) { 7277 value = hooks.expand( value ); 7278 delete props[ name ]; 7279 7280 // Not quite $.extend, this won't overwrite existing keys. 7281 // Reusing 'index' because we have the correct "name" 7282 for ( index in value ) { 7283 if ( !( index in props ) ) { 7284 props[ index ] = value[ index ]; 7285 specialEasing[ index ] = easing; 7286 } 7287 } 7288 } else { 7289 specialEasing[ name ] = easing; 7290 } 7291 } 7292} 7293 7294function Animation( elem, properties, options ) { 7295 var result, 7296 stopped, 7297 index = 0, 7298 length = Animation.prefilters.length, 7299 deferred = jQuery.Deferred().always( function() { 7300 7301 // Don't match elem in the :animated selector 7302 delete tick.elem; 7303 } ), 7304 tick = function() { 7305 if ( stopped ) { 7306 return false; 7307 } 7308 var currentTime = fxNow || createFxNow(), 7309 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 7310 7311 // Support: Android 2.3 only 7312 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 7313 temp = remaining / animation.duration || 0, 7314 percent = 1 - temp, 7315 index = 0, 7316 length = animation.tweens.length; 7317 7318 for ( ; index < length; index++ ) { 7319 animation.tweens[ index ].run( percent ); 7320 } 7321 7322 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 7323 7324 // If there's more to do, yield 7325 if ( percent < 1 && length ) { 7326 return remaining; 7327 } 7328 7329 // If this was an empty animation, synthesize a final progress notification 7330 if ( !length ) { 7331 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7332 } 7333 7334 // Resolve the animation and report its conclusion 7335 deferred.resolveWith( elem, [ animation ] ); 7336 return false; 7337 }, 7338 animation = deferred.promise( { 7339 elem: elem, 7340 props: jQuery.extend( {}, properties ), 7341 opts: jQuery.extend( true, { 7342 specialEasing: {}, 7343 easing: jQuery.easing._default 7344 }, options ), 7345 originalProperties: properties, 7346 originalOptions: options, 7347 startTime: fxNow || createFxNow(), 7348 duration: options.duration, 7349 tweens: [], 7350 createTween: function( prop, end ) { 7351 var tween = jQuery.Tween( elem, animation.opts, prop, end, 7352 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 7353 animation.tweens.push( tween ); 7354 return tween; 7355 }, 7356 stop: function( gotoEnd ) { 7357 var index = 0, 7358 7359 // If we are going to the end, we want to run all the tweens 7360 // otherwise we skip this part 7361 length = gotoEnd ? animation.tweens.length : 0; 7362 if ( stopped ) { 7363 return this; 7364 } 7365 stopped = true; 7366 for ( ; index < length; index++ ) { 7367 animation.tweens[ index ].run( 1 ); 7368 } 7369 7370 // Resolve when we played the last frame; otherwise, reject 7371 if ( gotoEnd ) { 7372 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7373 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 7374 } else { 7375 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 7376 } 7377 return this; 7378 } 7379 } ), 7380 props = animation.props; 7381 7382 propFilter( props, animation.opts.specialEasing ); 7383 7384 for ( ; index < length; index++ ) { 7385 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 7386 if ( result ) { 7387 if ( isFunction( result.stop ) ) { 7388 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 7389 result.stop.bind( result ); 7390 } 7391 return result; 7392 } 7393 } 7394 7395 jQuery.map( props, createTween, animation ); 7396 7397 if ( isFunction( animation.opts.start ) ) { 7398 animation.opts.start.call( elem, animation ); 7399 } 7400 7401 // Attach callbacks from options 7402 animation 7403 .progress( animation.opts.progress ) 7404 .done( animation.opts.done, animation.opts.complete ) 7405 .fail( animation.opts.fail ) 7406 .always( animation.opts.always ); 7407 7408 jQuery.fx.timer( 7409 jQuery.extend( tick, { 7410 elem: elem, 7411 anim: animation, 7412 queue: animation.opts.queue 7413 } ) 7414 ); 7415 7416 return animation; 7417} 7418 7419jQuery.Animation = jQuery.extend( Animation, { 7420 7421 tweeners: { 7422 "*": [ function( prop, value ) { 7423 var tween = this.createTween( prop, value ); 7424 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 7425 return tween; 7426 } ] 7427 }, 7428 7429 tweener: function( props, callback ) { 7430 if ( isFunction( props ) ) { 7431 callback = props; 7432 props = [ "*" ]; 7433 } else { 7434 props = props.match( rnothtmlwhite ); 7435 } 7436 7437 var prop, 7438 index = 0, 7439 length = props.length; 7440 7441 for ( ; index < length; index++ ) { 7442 prop = props[ index ]; 7443 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 7444 Animation.tweeners[ prop ].unshift( callback ); 7445 } 7446 }, 7447 7448 prefilters: [ defaultPrefilter ], 7449 7450 prefilter: function( callback, prepend ) { 7451 if ( prepend ) { 7452 Animation.prefilters.unshift( callback ); 7453 } else { 7454 Animation.prefilters.push( callback ); 7455 } 7456 } 7457} ); 7458 7459jQuery.speed = function( speed, easing, fn ) { 7460 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 7461 complete: fn || !fn && easing || 7462 isFunction( speed ) && speed, 7463 duration: speed, 7464 easing: fn && easing || easing && !isFunction( easing ) && easing 7465 }; 7466 7467 // Go to the end state if fx are off 7468 if ( jQuery.fx.off ) { 7469 opt.duration = 0; 7470 7471 } else { 7472 if ( typeof opt.duration !== "number" ) { 7473 if ( opt.duration in jQuery.fx.speeds ) { 7474 opt.duration = jQuery.fx.speeds[ opt.duration ]; 7475 7476 } else { 7477 opt.duration = jQuery.fx.speeds._default; 7478 } 7479 } 7480 } 7481 7482 // Normalize opt.queue - true/undefined/null -> "fx" 7483 if ( opt.queue == null || opt.queue === true ) { 7484 opt.queue = "fx"; 7485 } 7486 7487 // Queueing 7488 opt.old = opt.complete; 7489 7490 opt.complete = function() { 7491 if ( isFunction( opt.old ) ) { 7492 opt.old.call( this ); 7493 } 7494 7495 if ( opt.queue ) { 7496 jQuery.dequeue( this, opt.queue ); 7497 } 7498 }; 7499 7500 return opt; 7501}; 7502 7503jQuery.fn.extend( { 7504 fadeTo: function( speed, to, easing, callback ) { 7505 7506 // Show any hidden elements after setting opacity to 0 7507 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 7508 7509 // Animate to the value specified 7510 .end().animate( { opacity: to }, speed, easing, callback ); 7511 }, 7512 animate: function( prop, speed, easing, callback ) { 7513 var empty = jQuery.isEmptyObject( prop ), 7514 optall = jQuery.speed( speed, easing, callback ), 7515 doAnimation = function() { 7516 7517 // Operate on a copy of prop so per-property easing won't be lost 7518 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 7519 7520 // Empty animations, or finishing resolves immediately 7521 if ( empty || dataPriv.get( this, "finish" ) ) { 7522 anim.stop( true ); 7523 } 7524 }; 7525 doAnimation.finish = doAnimation; 7526 7527 return empty || optall.queue === false ? 7528 this.each( doAnimation ) : 7529 this.queue( optall.queue, doAnimation ); 7530 }, 7531 stop: function( type, clearQueue, gotoEnd ) { 7532 var stopQueue = function( hooks ) { 7533 var stop = hooks.stop; 7534 delete hooks.stop; 7535 stop( gotoEnd ); 7536 }; 7537 7538 if ( typeof type !== "string" ) { 7539 gotoEnd = clearQueue; 7540 clearQueue = type; 7541 type = undefined; 7542 } 7543 if ( clearQueue && type !== false ) { 7544 this.queue( type || "fx", [] ); 7545 } 7546 7547 return this.each( function() { 7548 var dequeue = true, 7549 index = type != null && type + "queueHooks", 7550 timers = jQuery.timers, 7551 data = dataPriv.get( this ); 7552 7553 if ( index ) { 7554 if ( data[ index ] && data[ index ].stop ) { 7555 stopQueue( data[ index ] ); 7556 } 7557 } else { 7558 for ( index in data ) { 7559 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 7560 stopQueue( data[ index ] ); 7561 } 7562 } 7563 } 7564 7565 for ( index = timers.length; index--; ) { 7566 if ( timers[ index ].elem === this && 7567 ( type == null || timers[ index ].queue === type ) ) { 7568 7569 timers[ index ].anim.stop( gotoEnd ); 7570 dequeue = false; 7571 timers.splice( index, 1 ); 7572 } 7573 } 7574 7575 // Start the next in the queue if the last step wasn't forced. 7576 // Timers currently will call their complete callbacks, which 7577 // will dequeue but only if they were gotoEnd. 7578 if ( dequeue || !gotoEnd ) { 7579 jQuery.dequeue( this, type ); 7580 } 7581 } ); 7582 }, 7583 finish: function( type ) { 7584 if ( type !== false ) { 7585 type = type || "fx"; 7586 } 7587 return this.each( function() { 7588 var index, 7589 data = dataPriv.get( this ), 7590 queue = data[ type + "queue" ], 7591 hooks = data[ type + "queueHooks" ], 7592 timers = jQuery.timers, 7593 length = queue ? queue.length : 0; 7594 7595 // Enable finishing flag on private data 7596 data.finish = true; 7597 7598 // Empty the queue first 7599 jQuery.queue( this, type, [] ); 7600 7601 if ( hooks && hooks.stop ) { 7602 hooks.stop.call( this, true ); 7603 } 7604 7605 // Look for any active animations, and finish them 7606 for ( index = timers.length; index--; ) { 7607 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 7608 timers[ index ].anim.stop( true ); 7609 timers.splice( index, 1 ); 7610 } 7611 } 7612 7613 // Look for any animations in the old queue and finish them 7614 for ( index = 0; index < length; index++ ) { 7615 if ( queue[ index ] && queue[ index ].finish ) { 7616 queue[ index ].finish.call( this ); 7617 } 7618 } 7619 7620 // Turn off finishing flag 7621 delete data.finish; 7622 } ); 7623 } 7624} ); 7625 7626jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { 7627 var cssFn = jQuery.fn[ name ]; 7628 jQuery.fn[ name ] = function( speed, easing, callback ) { 7629 return speed == null || typeof speed === "boolean" ? 7630 cssFn.apply( this, arguments ) : 7631 this.animate( genFx( name, true ), speed, easing, callback ); 7632 }; 7633} ); 7634 7635// Generate shortcuts for custom animations 7636jQuery.each( { 7637 slideDown: genFx( "show" ), 7638 slideUp: genFx( "hide" ), 7639 slideToggle: genFx( "toggle" ), 7640 fadeIn: { opacity: "show" }, 7641 fadeOut: { opacity: "hide" }, 7642 fadeToggle: { opacity: "toggle" } 7643}, function( name, props ) { 7644 jQuery.fn[ name ] = function( speed, easing, callback ) { 7645 return this.animate( props, speed, easing, callback ); 7646 }; 7647} ); 7648 7649jQuery.timers = []; 7650jQuery.fx.tick = function() { 7651 var timer, 7652 i = 0, 7653 timers = jQuery.timers; 7654 7655 fxNow = Date.now(); 7656 7657 for ( ; i < timers.length; i++ ) { 7658 timer = timers[ i ]; 7659 7660 // Run the timer and safely remove it when done (allowing for external removal) 7661 if ( !timer() && timers[ i ] === timer ) { 7662 timers.splice( i--, 1 ); 7663 } 7664 } 7665 7666 if ( !timers.length ) { 7667 jQuery.fx.stop(); 7668 } 7669 fxNow = undefined; 7670}; 7671 7672jQuery.fx.timer = function( timer ) { 7673 jQuery.timers.push( timer ); 7674 jQuery.fx.start(); 7675}; 7676 7677jQuery.fx.interval = 13; 7678jQuery.fx.start = function() { 7679 if ( inProgress ) { 7680 return; 7681 } 7682 7683 inProgress = true; 7684 schedule(); 7685}; 7686 7687jQuery.fx.stop = function() { 7688 inProgress = null; 7689}; 7690 7691jQuery.fx.speeds = { 7692 slow: 600, 7693 fast: 200, 7694 7695 // Default speed 7696 _default: 400 7697}; 7698 7699 7700// Based off of the plugin by Clint Helfers, with permission. 7701// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 7702jQuery.fn.delay = function( time, type ) { 7703 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 7704 type = type || "fx"; 7705 7706 return this.queue( type, function( next, hooks ) { 7707 var timeout = window.setTimeout( next, time ); 7708 hooks.stop = function() { 7709 window.clearTimeout( timeout ); 7710 }; 7711 } ); 7712}; 7713 7714 7715( function() { 7716 var input = document.createElement( "input" ), 7717 select = document.createElement( "select" ), 7718 opt = select.appendChild( document.createElement( "option" ) ); 7719 7720 input.type = "checkbox"; 7721 7722 // Support: Android <=4.3 only 7723 // Default value for a checkbox should be "on" 7724 support.checkOn = input.value !== ""; 7725 7726 // Support: IE <=11 only 7727 // Must access selectedIndex to make default options select 7728 support.optSelected = opt.selected; 7729 7730 // Support: IE <=11 only 7731 // An input loses its value after becoming a radio 7732 input = document.createElement( "input" ); 7733 input.value = "t"; 7734 input.type = "radio"; 7735 support.radioValue = input.value === "t"; 7736} )(); 7737 7738 7739var boolHook, 7740 attrHandle = jQuery.expr.attrHandle; 7741 7742jQuery.fn.extend( { 7743 attr: function( name, value ) { 7744 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 7745 }, 7746 7747 removeAttr: function( name ) { 7748 return this.each( function() { 7749 jQuery.removeAttr( this, name ); 7750 } ); 7751 } 7752} ); 7753 7754jQuery.extend( { 7755 attr: function( elem, name, value ) { 7756 var ret, hooks, 7757 nType = elem.nodeType; 7758 7759 // Don't get/set attributes on text, comment and attribute nodes 7760 if ( nType === 3 || nType === 8 || nType === 2 ) { 7761 return; 7762 } 7763 7764 // Fallback to prop when attributes are not supported 7765 if ( typeof elem.getAttribute === "undefined" ) { 7766 return jQuery.prop( elem, name, value ); 7767 } 7768 7769 // Attribute hooks are determined by the lowercase version 7770 // Grab necessary hook if one is defined 7771 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7772 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 7773 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 7774 } 7775 7776 if ( value !== undefined ) { 7777 if ( value === null ) { 7778 jQuery.removeAttr( elem, name ); 7779 return; 7780 } 7781 7782 if ( hooks && "set" in hooks && 7783 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7784 return ret; 7785 } 7786 7787 elem.setAttribute( name, value + "" ); 7788 return value; 7789 } 7790 7791 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7792 return ret; 7793 } 7794 7795 ret = jQuery.find.attr( elem, name ); 7796 7797 // Non-existent attributes return null, we normalize to undefined 7798 return ret == null ? undefined : ret; 7799 }, 7800 7801 attrHooks: { 7802 type: { 7803 set: function( elem, value ) { 7804 if ( !support.radioValue && value === "radio" && 7805 nodeName( elem, "input" ) ) { 7806 var val = elem.value; 7807 elem.setAttribute( "type", value ); 7808 if ( val ) { 7809 elem.value = val; 7810 } 7811 return value; 7812 } 7813 } 7814 } 7815 }, 7816 7817 removeAttr: function( elem, value ) { 7818 var name, 7819 i = 0, 7820 7821 // Attribute names can contain non-HTML whitespace characters 7822 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 7823 attrNames = value && value.match( rnothtmlwhite ); 7824 7825 if ( attrNames && elem.nodeType === 1 ) { 7826 while ( ( name = attrNames[ i++ ] ) ) { 7827 elem.removeAttribute( name ); 7828 } 7829 } 7830 } 7831} ); 7832 7833// Hooks for boolean attributes 7834boolHook = { 7835 set: function( elem, value, name ) { 7836 if ( value === false ) { 7837 7838 // Remove boolean attributes when set to false 7839 jQuery.removeAttr( elem, name ); 7840 } else { 7841 elem.setAttribute( name, name ); 7842 } 7843 return name; 7844 } 7845}; 7846 7847jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 7848 var getter = attrHandle[ name ] || jQuery.find.attr; 7849 7850 attrHandle[ name ] = function( elem, name, isXML ) { 7851 var ret, handle, 7852 lowercaseName = name.toLowerCase(); 7853 7854 if ( !isXML ) { 7855 7856 // Avoid an infinite loop by temporarily removing this function from the getter 7857 handle = attrHandle[ lowercaseName ]; 7858 attrHandle[ lowercaseName ] = ret; 7859 ret = getter( elem, name, isXML ) != null ? 7860 lowercaseName : 7861 null; 7862 attrHandle[ lowercaseName ] = handle; 7863 } 7864 return ret; 7865 }; 7866} ); 7867 7868 7869 7870 7871var rfocusable = /^(?:input|select|textarea|button)$/i, 7872 rclickable = /^(?:a|area)$/i; 7873 7874jQuery.fn.extend( { 7875 prop: function( name, value ) { 7876 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 7877 }, 7878 7879 removeProp: function( name ) { 7880 return this.each( function() { 7881 delete this[ jQuery.propFix[ name ] || name ]; 7882 } ); 7883 } 7884} ); 7885 7886jQuery.extend( { 7887 prop: function( elem, name, value ) { 7888 var ret, hooks, 7889 nType = elem.nodeType; 7890 7891 // Don't get/set properties on text, comment and attribute nodes 7892 if ( nType === 3 || nType === 8 || nType === 2 ) { 7893 return; 7894 } 7895 7896 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7897 7898 // Fix name and attach hooks 7899 name = jQuery.propFix[ name ] || name; 7900 hooks = jQuery.propHooks[ name ]; 7901 } 7902 7903 if ( value !== undefined ) { 7904 if ( hooks && "set" in hooks && 7905 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7906 return ret; 7907 } 7908 7909 return ( elem[ name ] = value ); 7910 } 7911 7912 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7913 return ret; 7914 } 7915 7916 return elem[ name ]; 7917 }, 7918 7919 propHooks: { 7920 tabIndex: { 7921 get: function( elem ) { 7922 7923 // Support: IE <=9 - 11 only 7924 // elem.tabIndex doesn't always return the 7925 // correct value when it hasn't been explicitly set 7926 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 7927 // Use proper attribute retrieval(#12072) 7928 var tabindex = jQuery.find.attr( elem, "tabindex" ); 7929 7930 if ( tabindex ) { 7931 return parseInt( tabindex, 10 ); 7932 } 7933 7934 if ( 7935 rfocusable.test( elem.nodeName ) || 7936 rclickable.test( elem.nodeName ) && 7937 elem.href 7938 ) { 7939 return 0; 7940 } 7941 7942 return -1; 7943 } 7944 } 7945 }, 7946 7947 propFix: { 7948 "for": "htmlFor", 7949 "class": "className" 7950 } 7951} ); 7952 7953// Support: IE <=11 only 7954// Accessing the selectedIndex property 7955// forces the browser to respect setting selected 7956// on the option 7957// The getter ensures a default option is selected 7958// when in an optgroup 7959// eslint rule "no-unused-expressions" is disabled for this code 7960// since it considers such accessions noop 7961if ( !support.optSelected ) { 7962 jQuery.propHooks.selected = { 7963 get: function( elem ) { 7964 7965 /* eslint no-unused-expressions: "off" */ 7966 7967 var parent = elem.parentNode; 7968 if ( parent && parent.parentNode ) { 7969 parent.parentNode.selectedIndex; 7970 } 7971 return null; 7972 }, 7973 set: function( elem ) { 7974 7975 /* eslint no-unused-expressions: "off" */ 7976 7977 var parent = elem.parentNode; 7978 if ( parent ) { 7979 parent.selectedIndex; 7980 7981 if ( parent.parentNode ) { 7982 parent.parentNode.selectedIndex; 7983 } 7984 } 7985 } 7986 }; 7987} 7988 7989jQuery.each( [ 7990 "tabIndex", 7991 "readOnly", 7992 "maxLength", 7993 "cellSpacing", 7994 "cellPadding", 7995 "rowSpan", 7996 "colSpan", 7997 "useMap", 7998 "frameBorder", 7999 "contentEditable" 8000], function() { 8001 jQuery.propFix[ this.toLowerCase() ] = this; 8002} ); 8003 8004 8005 8006 8007 // Strip and collapse whitespace according to HTML spec 8008 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 8009 function stripAndCollapse( value ) { 8010 var tokens = value.match( rnothtmlwhite ) || []; 8011 return tokens.join( " " ); 8012 } 8013 8014 8015function getClass( elem ) { 8016 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 8017} 8018 8019function classesToArray( value ) { 8020 if ( Array.isArray( value ) ) { 8021 return value; 8022 } 8023 if ( typeof value === "string" ) { 8024 return value.match( rnothtmlwhite ) || []; 8025 } 8026 return []; 8027} 8028 8029jQuery.fn.extend( { 8030 addClass: function( value ) { 8031 var classes, elem, cur, curValue, clazz, j, finalValue, 8032 i = 0; 8033 8034 if ( isFunction( value ) ) { 8035 return this.each( function( j ) { 8036 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 8037 } ); 8038 } 8039 8040 classes = classesToArray( value ); 8041 8042 if ( classes.length ) { 8043 while ( ( elem = this[ i++ ] ) ) { 8044 curValue = getClass( elem ); 8045 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8046 8047 if ( cur ) { 8048 j = 0; 8049 while ( ( clazz = classes[ j++ ] ) ) { 8050 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 8051 cur += clazz + " "; 8052 } 8053 } 8054 8055 // Only assign if different to avoid unneeded rendering. 8056 finalValue = stripAndCollapse( cur ); 8057 if ( curValue !== finalValue ) { 8058 elem.setAttribute( "class", finalValue ); 8059 } 8060 } 8061 } 8062 } 8063 8064 return this; 8065 }, 8066 8067 removeClass: function( value ) { 8068 var classes, elem, cur, curValue, clazz, j, finalValue, 8069 i = 0; 8070 8071 if ( isFunction( value ) ) { 8072 return this.each( function( j ) { 8073 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 8074 } ); 8075 } 8076 8077 if ( !arguments.length ) { 8078 return this.attr( "class", "" ); 8079 } 8080 8081 classes = classesToArray( value ); 8082 8083 if ( classes.length ) { 8084 while ( ( elem = this[ i++ ] ) ) { 8085 curValue = getClass( elem ); 8086 8087 // This expression is here for better compressibility (see addClass) 8088 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8089 8090 if ( cur ) { 8091 j = 0; 8092 while ( ( clazz = classes[ j++ ] ) ) { 8093 8094 // Remove *all* instances 8095 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 8096 cur = cur.replace( " " + clazz + " ", " " ); 8097 } 8098 } 8099 8100 // Only assign if different to avoid unneeded rendering. 8101 finalValue = stripAndCollapse( cur ); 8102 if ( curValue !== finalValue ) { 8103 elem.setAttribute( "class", finalValue ); 8104 } 8105 } 8106 } 8107 } 8108 8109 return this; 8110 }, 8111 8112 toggleClass: function( value, stateVal ) { 8113 var type = typeof value, 8114 isValidValue = type === "string" || Array.isArray( value ); 8115 8116 if ( typeof stateVal === "boolean" && isValidValue ) { 8117 return stateVal ? this.addClass( value ) : this.removeClass( value ); 8118 } 8119 8120 if ( isFunction( value ) ) { 8121 return this.each( function( i ) { 8122 jQuery( this ).toggleClass( 8123 value.call( this, i, getClass( this ), stateVal ), 8124 stateVal 8125 ); 8126 } ); 8127 } 8128 8129 return this.each( function() { 8130 var className, i, self, classNames; 8131 8132 if ( isValidValue ) { 8133 8134 // Toggle individual class names 8135 i = 0; 8136 self = jQuery( this ); 8137 classNames = classesToArray( value ); 8138 8139 while ( ( className = classNames[ i++ ] ) ) { 8140 8141 // Check each className given, space separated list 8142 if ( self.hasClass( className ) ) { 8143 self.removeClass( className ); 8144 } else { 8145 self.addClass( className ); 8146 } 8147 } 8148 8149 // Toggle whole class name 8150 } else if ( value === undefined || type === "boolean" ) { 8151 className = getClass( this ); 8152 if ( className ) { 8153 8154 // Store className if set 8155 dataPriv.set( this, "__className__", className ); 8156 } 8157 8158 // If the element has a class name or if we're passed `false`, 8159 // then remove the whole classname (if there was one, the above saved it). 8160 // Otherwise bring back whatever was previously saved (if anything), 8161 // falling back to the empty string if nothing was stored. 8162 if ( this.setAttribute ) { 8163 this.setAttribute( "class", 8164 className || value === false ? 8165 "" : 8166 dataPriv.get( this, "__className__" ) || "" 8167 ); 8168 } 8169 } 8170 } ); 8171 }, 8172 8173 hasClass: function( selector ) { 8174 var className, elem, 8175 i = 0; 8176 8177 className = " " + selector + " "; 8178 while ( ( elem = this[ i++ ] ) ) { 8179 if ( elem.nodeType === 1 && 8180 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 8181 return true; 8182 } 8183 } 8184 8185 return false;
vendor: 5,544 bytes, lines 8186-8421
8186 } 8187} ); 8188 8189 8190 8191 8192var rreturn = /\r/g; 8193 8194jQuery.fn.extend( { 8195 val: function( value ) { 8196 var hooks, ret, valueIsFunction, 8197 elem = this[ 0 ]; 8198 8199 if ( !arguments.length ) { 8200 if ( elem ) { 8201 hooks = jQuery.valHooks[ elem.type ] || 8202 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 8203 8204 if ( hooks && 8205 "get" in hooks && 8206 ( ret = hooks.get( elem, "value" ) ) !== undefined 8207 ) { 8208 return ret; 8209 } 8210 8211 ret = elem.value; 8212 8213 // Handle most common string cases 8214 if ( typeof ret === "string" ) { 8215 return ret.replace( rreturn, "" ); 8216 } 8217 8218 // Handle cases where value is null/undef or number 8219 return ret == null ? "" : ret; 8220 } 8221 8222 return; 8223 } 8224 8225 valueIsFunction = isFunction( value ); 8226 8227 return this.each( function( i ) { 8228 var val; 8229 8230 if ( this.nodeType !== 1 ) { 8231 return; 8232 } 8233 8234 if ( valueIsFunction ) { 8235 val = value.call( this, i, jQuery( this ).val() ); 8236 } else { 8237 val = value; 8238 } 8239 8240 // Treat null/undefined as ""; convert numbers to string 8241 if ( val == null ) { 8242 val = ""; 8243 8244 } else if ( typeof val === "number" ) { 8245 val += ""; 8246 8247 } else if ( Array.isArray( val ) ) { 8248 val = jQuery.map( val, function( value ) { 8249 return value == null ? "" : value + ""; 8250 } ); 8251 } 8252 8253 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 8254 8255 // If set returns undefined, fall back to normal setting 8256 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 8257 this.value = val; 8258 } 8259 } ); 8260 } 8261} ); 8262 8263jQuery.extend( { 8264 valHooks: { 8265 option: { 8266 get: function( elem ) { 8267 8268 var val = jQuery.find.attr( elem, "value" ); 8269 return val != null ? 8270 val : 8271 8272 // Support: IE <=10 - 11 only 8273 // option.text throws exceptions (#14686, #14858) 8274 // Strip and collapse whitespace 8275 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8276 stripAndCollapse( jQuery.text( elem ) ); 8277 } 8278 }, 8279 select: { 8280 get: function( elem ) { 8281 var value, option, i, 8282 options = elem.options, 8283 index = elem.selectedIndex, 8284 one = elem.type === "select-one", 8285 values = one ? null : [], 8286 max = one ? index + 1 : options.length; 8287 8288 if ( index < 0 ) { 8289 i = max; 8290 8291 } else { 8292 i = one ? index : 0; 8293 } 8294 8295 // Loop through all the selected options 8296 for ( ; i < max; i++ ) { 8297 option = options[ i ]; 8298 8299 // Support: IE <=9 only 8300 // IE8-9 doesn't update selected after form reset (#2551) 8301 if ( ( option.selected || i === index ) && 8302 8303 // Don't return options that are disabled or in a disabled optgroup 8304 !option.disabled && 8305 ( !option.parentNode.disabled || 8306 !nodeName( option.parentNode, "optgroup" ) ) ) { 8307 8308 // Get the specific value for the option 8309 value = jQuery( option ).val(); 8310 8311 // We don't need an array for one selects 8312 if ( one ) { 8313 return value; 8314 } 8315 8316 // Multi-Selects return an array 8317 values.push( value ); 8318 } 8319 } 8320 8321 return values; 8322 }, 8323 8324 set: function( elem, value ) { 8325 var optionSet, option, 8326 options = elem.options, 8327 values = jQuery.makeArray( value ), 8328 i = options.length; 8329 8330 while ( i-- ) { 8331 option = options[ i ]; 8332 8333 /* eslint-disable no-cond-assign */ 8334 8335 if ( option.selected = 8336 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 8337 ) { 8338 optionSet = true; 8339 } 8340 8341 /* eslint-enable no-cond-assign */ 8342 } 8343 8344 // Force browsers to behave consistently when non-matching value is set 8345 if ( !optionSet ) { 8346 elem.selectedIndex = -1; 8347 } 8348 return values; 8349 } 8350 } 8351 } 8352} ); 8353 8354// Radios and checkboxes getter/setter 8355jQuery.each( [ "radio", "checkbox" ], function() { 8356 jQuery.valHooks[ this ] = { 8357 set: function( elem, value ) { 8358 if ( Array.isArray( value ) ) { 8359 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 8360 } 8361 } 8362 }; 8363 if ( !support.checkOn ) { 8364 jQuery.valHooks[ this ].get = function( elem ) { 8365 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 8366 }; 8367 } 8368} ); 8369 8370 8371 8372 8373// Return jQuery for attributes-only inclusion 8374 8375 8376support.focusin = "onfocusin" in window; 8377 8378 8379var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 8380 stopPropagationCallback = function( e ) { 8381 e.stopPropagation(); 8382 }; 8383 8384jQuery.extend( jQuery.event, { 8385 8386 trigger: function( event, data, elem, onlyHandlers ) { 8387 8388 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 8389 eventPath = [ elem || document ], 8390 type = hasOwn.call( event, "type" ) ? event.type : event, 8391 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 8392 8393 cur = lastElement = tmp = elem = elem || document; 8394 8395 // Don't do events on text and comment nodes 8396 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 8397 return; 8398 } 8399 8400 // focus/blur morphs to focusin/out; ensure we're not firing them right now 8401 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 8402 return; 8403 } 8404 8405 if ( type.indexOf( "." ) > -1 ) { 8406 8407 // Namespaced trigger; create a regexp to match event type in handle() 8408 namespaces = type.split( "." ); 8409 type = namespaces.shift(); 8410 namespaces.sort(); 8411 } 8412 ontype = type.indexOf( ":" ) < 0 && "on" + type; 8413 8414 // Caller can pass in a jQuery.Event object, Object, or just an event type string 8415 event = event[ jQuery.expando ] ? 8416 event : 8417 new jQuery.Event( type, typeof event === "object" && event ); 8418 8419 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 8420 event.isTrigger = onlyHandlers ? 2 : 3; 8421 event.namespace = namespaces.join( "." );
vendor: 7,012 bytes, lines 8422-8695
8422 event.rnamespace = event.namespace ? 8423 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 8424 null; 8425 8426 // Clean up the event in case it is being reused 8427 event.result = undefined; 8428 if ( !event.target ) { 8429 event.target = elem; 8430 } 8431 8432 // Clone any incoming data and prepend the event, creating the handler arg list 8433 data = data == null ? 8434 [ event ] : 8435 jQuery.makeArray( data, [ event ] ); 8436 8437 // Allow special events to draw outside the lines 8438 special = jQuery.event.special[ type ] || {}; 8439 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 8440 return; 8441 } 8442 8443 // Determine event propagation path in advance, per W3C events spec (#9951) 8444 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 8445 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 8446 8447 bubbleType = special.delegateType || type; 8448 if ( !rfocusMorph.test( bubbleType + type ) ) { 8449 cur = cur.parentNode; 8450 } 8451 for ( ; cur; cur = cur.parentNode ) { 8452 eventPath.push( cur ); 8453 tmp = cur; 8454 } 8455 8456 // Only add window if we got to document (e.g., not plain obj or detached DOM) 8457 if ( tmp === ( elem.ownerDocument || document ) ) { 8458 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 8459 } 8460 } 8461 8462 // Fire handlers on the event path 8463 i = 0; 8464 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 8465 lastElement = cur; 8466 event.type = i > 1 ? 8467 bubbleType : 8468 special.bindType || type; 8469 8470 // jQuery handler 8471 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && 8472 dataPriv.get( cur, "handle" ); 8473 if ( handle ) { 8474 handle.apply( cur, data ); 8475 } 8476 8477 // Native handler 8478 handle = ontype && cur[ ontype ]; 8479 if ( handle && handle.apply && acceptData( cur ) ) { 8480 event.result = handle.apply( cur, data ); 8481 if ( event.result === false ) { 8482 event.preventDefault(); 8483 } 8484 } 8485 } 8486 event.type = type; 8487 8488 // If nobody prevented the default action, do it now 8489 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 8490 8491 if ( ( !special._default || 8492 special._default.apply( eventPath.pop(), data ) === false ) && 8493 acceptData( elem ) ) { 8494 8495 // Call a native DOM method on the target with the same name as the event. 8496 // Don't do default actions on window, that's where global variables be (#6170) 8497 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 8498 8499 // Don't re-trigger an onFOO event when we call its FOO() method 8500 tmp = elem[ ontype ]; 8501 8502 if ( tmp ) { 8503 elem[ ontype ] = null; 8504 } 8505 8506 // Prevent re-triggering of the same event, since we already bubbled it above 8507 jQuery.event.triggered = type; 8508 8509 if ( event.isPropagationStopped() ) { 8510 lastElement.addEventListener( type, stopPropagationCallback ); 8511 } 8512 8513 elem[ type ](); 8514 8515 if ( event.isPropagationStopped() ) { 8516 lastElement.removeEventListener( type, stopPropagationCallback ); 8517 } 8518 8519 jQuery.event.triggered = undefined; 8520 8521 if ( tmp ) { 8522 elem[ ontype ] = tmp; 8523 } 8524 } 8525 } 8526 } 8527 8528 return event.result; 8529 }, 8530 8531 // Piggyback on a donor event to simulate a different one 8532 // Used only for `focus(in | out)` events 8533 simulate: function( type, elem, event ) { 8534 var e = jQuery.extend( 8535 new jQuery.Event(), 8536 event, 8537 { 8538 type: type, 8539 isSimulated: true 8540 } 8541 ); 8542 8543 jQuery.event.trigger( e, null, elem ); 8544 } 8545 8546} ); 8547 8548jQuery.fn.extend( { 8549 8550 trigger: function( type, data ) { 8551 return this.each( function() { 8552 jQuery.event.trigger( type, data, this ); 8553 } ); 8554 }, 8555 triggerHandler: function( type, data ) { 8556 var elem = this[ 0 ]; 8557 if ( elem ) { 8558 return jQuery.event.trigger( type, data, elem, true ); 8559 } 8560 } 8561} ); 8562 8563 8564// Support: Firefox <=44 8565// Firefox doesn't have focus(in | out) events 8566// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 8567// 8568// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 8569// focus(in | out) events fire after focus & blur events, 8570// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 8571// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 8572if ( !support.focusin ) { 8573 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 8574 8575 // Attach a single capturing handler on the document while someone wants focusin/focusout 8576 var handler = function( event ) { 8577 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 8578 }; 8579 8580 jQuery.event.special[ fix ] = { 8581 setup: function() { 8582 var doc = this.ownerDocument || this, 8583 attaches = dataPriv.access( doc, fix ); 8584 8585 if ( !attaches ) { 8586 doc.addEventListener( orig, handler, true ); 8587 } 8588 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 8589 }, 8590 teardown: function() { 8591 var doc = this.ownerDocument || this, 8592 attaches = dataPriv.access( doc, fix ) - 1; 8593 8594 if ( !attaches ) { 8595 doc.removeEventListener( orig, handler, true ); 8596 dataPriv.remove( doc, fix ); 8597 8598 } else { 8599 dataPriv.access( doc, fix, attaches ); 8600 } 8601 } 8602 }; 8603 } ); 8604} 8605var location = window.location; 8606 8607var nonce = Date.now(); 8608 8609var rquery = ( /\?/ ); 8610 8611 8612 8613// Cross-browser xml parsing 8614jQuery.parseXML = function( data ) { 8615 var xml; 8616 if ( !data || typeof data !== "string" ) { 8617 return null; 8618 } 8619 8620 // Support: IE 9 - 11 only 8621 // IE throws on parseFromString with invalid input. 8622 try { 8623 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 8624 } catch ( e ) { 8625 xml = undefined; 8626 } 8627 8628 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 8629 jQuery.error( "Invalid XML: " + data ); 8630 } 8631 return xml; 8632}; 8633 8634 8635var 8636 rbracket = /\[\]$/, 8637 rCRLF = /\r?\n/g, 8638 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8639 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8640 8641function buildParams( prefix, obj, traditional, add ) { 8642 var name; 8643 8644 if ( Array.isArray( obj ) ) { 8645 8646 // Serialize array item. 8647 jQuery.each( obj, function( i, v ) { 8648 if ( traditional || rbracket.test( prefix ) ) { 8649 8650 // Treat each array item as a scalar. 8651 add( prefix, v ); 8652 8653 } else { 8654 8655 // Item is non-scalar (array or object), encode its numeric index. 8656 buildParams( 8657 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 8658 v, 8659 traditional, 8660 add 8661 ); 8662 } 8663 } ); 8664 8665 } else if ( !traditional && toType( obj ) === "object" ) { 8666 8667 // Serialize object item. 8668 for ( name in obj ) { 8669 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 8670 } 8671 8672 } else { 8673 8674 // Serialize scalar item. 8675 add( prefix, obj ); 8676 } 8677} 8678 8679// Serialize an array of form elements or a set of 8680// key/values into a query string 8681jQuery.param = function( a, traditional ) { 8682 var prefix, 8683 s = [], 8684 add = function( key, valueOrFunction ) { 8685 8686 // If value is a function, invoke it and use its return value 8687 var value = isFunction( valueOrFunction ) ? 8688 valueOrFunction() : 8689 valueOrFunction; 8690 8691 s[ s.length ] = encodeURIComponent( key ) + "=" + 8692 encodeURIComponent( value == null ? "" : value ); 8693 }; 8694 8695
8695if ( a == null ) { 8696 return ""; 8697 }
vendor: 12,730 bytes, lines 8697-9201
8697 8698 8699 // If an array was passed in, assume that it is an array of form elements. 8700 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 8701 8702 // Serialize the form elements 8703 jQuery.each( a, function() { 8704 add( this.name, this.value ); 8705 } ); 8706 8707 } else { 8708 8709 // If traditional, encode the "old" way (the way 1.3.2 or older 8710 // did it), otherwise encode params recursively. 8711 for ( prefix in a ) { 8712 buildParams( prefix, a[ prefix ], traditional, add ); 8713 } 8714 } 8715 8716 // Return the resulting serialization 8717 return s.join( "&" ); 8718}; 8719 8720jQuery.fn.extend( { 8721 serialize: function() { 8722 return jQuery.param( this.serializeArray() ); 8723 }, 8724 serializeArray: function() { 8725 return this.map( function() { 8726 8727 // Can add propHook for "elements" to filter or add form elements 8728 var elements = jQuery.prop( this, "elements" ); 8729 return elements ? jQuery.makeArray( elements ) : this; 8730 } ) 8731 .filter( function() { 8732 var type = this.type; 8733 8734 // Use .is( ":disabled" ) so that fieldset[disabled] works 8735 return this.name && !jQuery( this ).is( ":disabled" ) && 8736 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 8737 ( this.checked || !rcheckableType.test( type ) ); 8738 } ) 8739 .map( function( i, elem ) { 8740 var val = jQuery( this ).val(); 8741 8742 if ( val == null ) { 8743 return null; 8744 } 8745 8746 if ( Array.isArray( val ) ) { 8747 return jQuery.map( val, function( val ) { 8748 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8749 } ); 8750 } 8751 8752 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8753 } ).get(); 8754 } 8755} ); 8756 8757 8758var 8759 r20 = /%20/g, 8760 rhash = /#.*$/, 8761 rantiCache = /([?&])_=[^&]*/, 8762 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 8763 8764 // #7653, #8125, #8152: local protocol detection 8765 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8766 rnoContent = /^(?:GET|HEAD)$/, 8767 rprotocol = /^\/\//, 8768 8769 /* Prefilters 8770 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8771 * 2) These are called: 8772 * - BEFORE asking for a transport 8773 * - AFTER param serialization (s.data is a string if s.processData is true) 8774 * 3) key is the dataType 8775 * 4) the catchall symbol "*" can be used 8776 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8777 */ 8778 prefilters = {}, 8779 8780 /* Transports bindings 8781 * 1) key is the dataType 8782 * 2) the catchall symbol "*" can be used 8783 * 3) selection will start with transport dataType and THEN go to "*" if needed 8784 */ 8785 transports = {}, 8786 8787 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 8788 allTypes = "*/".concat( "*" ), 8789 8790 // Anchor tag for parsing the document origin 8791 originAnchor = document.createElement( "a" ); 8792 originAnchor.href = location.href; 8793 8794// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8795function addToPrefiltersOrTransports( structure ) { 8796 8797 // dataTypeExpression is optional and defaults to "*" 8798 return function( dataTypeExpression, func ) { 8799 8800 if ( typeof dataTypeExpression !== "string" ) { 8801 func = dataTypeExpression; 8802 dataTypeExpression = "*"; 8803 } 8804 8805 var dataType, 8806 i = 0, 8807 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 8808 8809 if ( isFunction( func ) ) { 8810 8811 // For each dataType in the dataTypeExpression 8812 while ( ( dataType = dataTypes[ i++ ] ) ) { 8813 8814 // Prepend if requested 8815 if ( dataType[ 0 ] === "+" ) { 8816 dataType = dataType.slice( 1 ) || "*"; 8817 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 8818 8819 // Otherwise append 8820 } else { 8821 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 8822 } 8823 } 8824 } 8825 }; 8826} 8827 8828// Base inspection function for prefilters and transports 8829function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 8830 8831 var inspected = {}, 8832 seekingTransport = ( structure === transports ); 8833 8834 function inspect( dataType ) { 8835 var selected; 8836 inspected[ dataType ] = true; 8837 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 8838 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 8839 if ( typeof dataTypeOrTransport === "string" && 8840 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 8841 8842 options.dataTypes.unshift( dataTypeOrTransport ); 8843 inspect( dataTypeOrTransport ); 8844 return false; 8845 } else if ( seekingTransport ) { 8846 return !( selected = dataTypeOrTransport ); 8847 } 8848 } ); 8849 return selected; 8850 } 8851 8852 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 8853} 8854 8855// A special extend for ajax options 8856// that takes "flat" options (not to be deep extended) 8857// Fixes #9887 8858function ajaxExtend( target, src ) { 8859 var key, deep, 8860 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8861 8862 for ( key in src ) { 8863 if ( src[ key ] !== undefined ) { 8864 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 8865 } 8866 } 8867 if ( deep ) { 8868 jQuery.extend( true, target, deep ); 8869 } 8870 8871 return target; 8872} 8873 8874/* Handles responses to an ajax request: 8875 * - finds the right dataType (mediates between content-type and expected dataType) 8876 * - returns the corresponding response 8877 */ 8878function ajaxHandleResponses( s, jqXHR, responses ) { 8879 8880 var ct, type, finalDataType, firstDataType, 8881 contents = s.contents, 8882 dataTypes = s.dataTypes; 8883 8884 // Remove auto dataType and get content-type in the process 8885 while ( dataTypes[ 0 ] === "*" ) { 8886 dataTypes.shift(); 8887 if ( ct === undefined ) { 8888 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 8889 } 8890 } 8891 8892 // Check if we're dealing with a known content-type 8893 if ( ct ) { 8894 for ( type in contents ) { 8895 if ( contents[ type ] && contents[ type ].test( ct ) ) { 8896 dataTypes.unshift( type ); 8897 break; 8898 } 8899 } 8900 } 8901 8902 // Check to see if we have a response for the expected dataType 8903 if ( dataTypes[ 0 ] in responses ) { 8904 finalDataType = dataTypes[ 0 ]; 8905 } else { 8906 8907 // Try convertible dataTypes 8908 for ( type in responses ) { 8909 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 8910 finalDataType = type; 8911 break; 8912 } 8913 if ( !firstDataType ) { 8914 firstDataType = type; 8915 } 8916 } 8917 8918 // Or just use first one 8919 finalDataType = finalDataType || firstDataType; 8920 } 8921 8922 // If we found a dataType 8923 // We add the dataType to the list if needed 8924 // and return the corresponding response 8925 if ( finalDataType ) { 8926 if ( finalDataType !== dataTypes[ 0 ] ) { 8927 dataTypes.unshift( finalDataType ); 8928 } 8929 return responses[ finalDataType ]; 8930 } 8931} 8932 8933/* Chain conversions given the request and the original response 8934 * Also sets the responseXXX fields on the jqXHR instance 8935 */ 8936function ajaxConvert( s, response, jqXHR, isSuccess ) { 8937 var conv2, current, conv, tmp, prev, 8938 converters = {}, 8939 8940 // Work with a copy of dataTypes in case we need to modify it for conversion 8941 dataTypes = s.dataTypes.slice(); 8942 8943 // Create converters map with lowercased keys 8944 if ( dataTypes[ 1 ] ) { 8945 for ( conv in s.converters ) { 8946 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 8947 } 8948 } 8949 8950 current = dataTypes.shift(); 8951 8952 // Convert to each sequential dataType 8953 while ( current ) { 8954 8955 if ( s.responseFields[ current ] ) { 8956 jqXHR[ s.responseFields[ current ] ] = response; 8957 } 8958 8959 // Apply the dataFilter if provided 8960 if ( !prev && isSuccess && s.dataFilter ) { 8961 response = s.dataFilter( response, s.dataType ); 8962 } 8963 8964 prev = current; 8965 current = dataTypes.shift(); 8966 8967 if ( current ) { 8968 8969 // There's only work to do if current dataType is non-auto 8970 if ( current === "*" ) { 8971 8972 current = prev; 8973 8974 // Convert response if prev dataType is non-auto and differs from current 8975 } else if ( prev !== "*" && prev !== current ) { 8976 8977 // Seek a direct converter 8978 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 8979 8980 // If none found, seek a pair 8981 if ( !conv ) { 8982 for ( conv2 in converters ) { 8983 8984 // If conv2 outputs current 8985 tmp = conv2.split( " " ); 8986 if ( tmp[ 1 ] === current ) { 8987 8988 // If prev can be converted to accepted input 8989 conv = converters[ prev + " " + tmp[ 0 ] ] || 8990 converters[ "* " + tmp[ 0 ] ]; 8991 if ( conv ) { 8992 8993 // Condense equivalence converters 8994 if ( conv === true ) { 8995 conv = converters[ conv2 ]; 8996 8997 // Otherwise, insert the intermediate dataType 8998 } else if ( converters[ conv2 ] !== true ) { 8999 current = tmp[ 0 ]; 9000 dataTypes.unshift( tmp[ 1 ] ); 9001 } 9002 break; 9003 } 9004 } 9005 } 9006 } 9007 9008 // Apply converter (if not an equivalence) 9009 if ( conv !== true ) { 9010 9011 // Unless errors are allowed to bubble, catch and return them 9012 if ( conv && s.throws ) { 9013 response = conv( response ); 9014 } else { 9015 try { 9016 response = conv( response ); 9017 } catch ( e ) { 9018 return { 9019 state: "parsererror", 9020 error: conv ? e : "No conversion from " + prev + " to " + current 9021 }; 9022 } 9023 } 9024 } 9025 } 9026 } 9027 } 9028 9029 return { state: "success", data: response }; 9030} 9031 9032jQuery.extend( { 9033 9034 // Counter for holding the number of active queries 9035 active: 0, 9036 9037 // Last-Modified header cache for next request 9038 lastModified: {}, 9039 etag: {}, 9040 9041 ajaxSettings: { 9042 url: location.href, 9043 type: "GET", 9044 isLocal: rlocalProtocol.test( location.protocol ), 9045 global: true, 9046 processData: true, 9047 async: true, 9048 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9049 9050 /* 9051 timeout: 0, 9052 data: null, 9053 dataType: null, 9054 username: null, 9055 password: null, 9056 cache: null, 9057 throws: false, 9058 traditional: false, 9059 headers: {}, 9060 */ 9061 9062 accepts: { 9063 "*": allTypes, 9064 text: "text/plain", 9065 html: "text/html", 9066 xml: "application/xml, text/xml", 9067 json: "application/json, text/javascript" 9068 }, 9069 9070 contents: { 9071 xml: /\bxml\b/, 9072 html: /\bhtml/, 9073 json: /\bjson\b/ 9074 }, 9075 9076 responseFields: { 9077 xml: "responseXML", 9078 text: "responseText", 9079 json: "responseJSON" 9080 }, 9081 9082 // Data converters 9083 // Keys separate source (or catchall "*") and destination types with a single space 9084 converters: { 9085 9086 // Convert anything to text 9087 "* text": String, 9088 9089 // Text to html (true = no transformation) 9090 "text html": true, 9091 9092 // Evaluate text as a json expression 9093 "text json": JSON.parse, 9094 9095 // Parse text as xml 9096 "text xml": jQuery.parseXML 9097 }, 9098 9099 // For options that shouldn't be deep extended: 9100 // you can add your own custom options here if 9101 // and when you create one that shouldn't be 9102 // deep extended (see ajaxExtend) 9103 flatOptions: { 9104 url: true, 9105 context: true 9106 } 9107 }, 9108 9109 // Creates a full fledged settings object into target 9110 // with both ajaxSettings and settings fields. 9111 // If target is omitted, writes into ajaxSettings. 9112 ajaxSetup: function( target, settings ) { 9113 return settings ? 9114 9115 // Building a settings object 9116 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 9117 9118 // Extending ajaxSettings 9119 ajaxExtend( jQuery.ajaxSettings, target ); 9120 }, 9121 9122 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 9123 ajaxTransport: addToPrefiltersOrTransports( transports ), 9124 9125 // Main method 9126 ajax: function( url, options ) { 9127 9128 // If url is an object, simulate pre-1.5 signature 9129 if ( typeof url === "object" ) { 9130 options = url; 9131 url = undefined; 9132 } 9133 9134 // Force options to be an object 9135 options = options || {}; 9136 9137 var transport, 9138 9139 // URL without anti-cache param 9140 cacheURL, 9141 9142 // Response headers 9143 responseHeadersString, 9144 responseHeaders, 9145 9146 // timeout handle 9147 timeoutTimer, 9148 9149 // Url cleanup var 9150 urlAnchor, 9151 9152 // Request state (becomes false upon send and true upon completion) 9153 completed, 9154 9155 // To know if global events are to be dispatched 9156 fireGlobals, 9157 9158 // Loop variable 9159 i, 9160 9161 // uncached part of the url 9162 uncached, 9163 9164 // Create the final options object 9165 s = jQuery.ajaxSetup( {}, options ), 9166 9167 // Callbacks context 9168 callbackContext = s.context || s, 9169 9170 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9171 globalEventContext = s.context && 9172 ( callbackContext.nodeType || callbackContext.jquery ) ? 9173 jQuery( callbackContext ) : 9174 jQuery.event, 9175 9176 // Deferreds 9177 deferred = jQuery.Deferred(), 9178 completeDeferred = jQuery.Callbacks( "once memory" ), 9179 9180 // Status-dependent callbacks 9181 statusCode = s.statusCode || {}, 9182 9183 // Headers (they are sent all at once) 9184 requestHeaders = {}, 9185 requestHeadersNames = {}, 9186 9187 // Default abort message 9188 strAbort = "canceled", 9189 9190 // Fake xhr 9191 jqXHR = { 9192 readyState: 0, 9193 9194 // Builds headers hashtable if needed 9195 getResponseHeader: function( key ) { 9196 var match; 9197 if ( completed ) { 9198 if ( !responseHeaders ) { 9199 responseHeaders = {}; 9200 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 9201 responseHeaders[ match[ 1 ].toLowerCase()
9201+ " " ] = 9202 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 9203 .concat( match[ 2 ] ); 9204 } 9205 } 9206 match = responseHeaders[ key.toLowerCase() + " " ]; 9207 } 9208 return match == null ? null : match.join( ", " )
vendor: 10,702 bytes, lines 9208-9597
9208; 9209 }, 9210 9211 // Raw string 9212 getAllResponseHeaders: function() { 9213 return completed ? responseHeadersString : null; 9214 }, 9215 9216 // Caches the header 9217 setRequestHeader: function( name, value ) { 9218 if ( completed == null ) { 9219 name = requestHeadersNames[ name.toLowerCase() ] = 9220 requestHeadersNames[ name.toLowerCase() ] || name; 9221 requestHeaders[ name ] = value; 9222 } 9223 return this; 9224 }, 9225 9226 // Overrides response content-type header 9227 overrideMimeType: function( type ) { 9228 if ( completed == null ) { 9229 s.mimeType = type; 9230 } 9231 return this; 9232 }, 9233 9234 // Status-dependent callbacks 9235 statusCode: function( map ) { 9236 var code; 9237 if ( map ) { 9238 if ( completed ) { 9239 9240 // Execute the appropriate callbacks 9241 jqXHR.always( map[ jqXHR.status ] ); 9242 } else { 9243 9244 // Lazy-add the new callbacks in a way that preserves old ones 9245 for ( code in map ) { 9246 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 9247 } 9248 } 9249 } 9250 return this; 9251 }, 9252 9253 // Cancel the request 9254 abort: function( statusText ) { 9255 var finalText = statusText || strAbort; 9256 if ( transport ) { 9257 transport.abort( finalText ); 9258 } 9259 done( 0, finalText ); 9260 return this; 9261 } 9262 }; 9263 9264 // Attach deferreds 9265 deferred.promise( jqXHR ); 9266 9267 // Add protocol if not provided (prefilters might expect it) 9268 // Handle falsy url in the settings object (#10093: consistency with old signature) 9269 // We also use the url parameter if available 9270 s.url = ( ( url || s.url || location.href ) + "" ) 9271 .replace( rprotocol, location.protocol + "//" ); 9272 9273 // Alias method option to type as per ticket #12004 9274 s.type = options.method || options.type || s.method || s.type; 9275 9276 // Extract dataTypes list 9277 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 9278 9279 // A cross-domain request is in order when the origin doesn't match the current origin. 9280 if ( s.crossDomain == null ) { 9281 urlAnchor = document.createElement( "a" ); 9282 9283 // Support: IE <=8 - 11, Edge 12 - 15 9284 // IE throws exception on accessing the href property if url is malformed, 9285 // e.g. http://example.com:80x/ 9286 try { 9287 urlAnchor.href = s.url; 9288 9289 // Support: IE <=8 - 11 only 9290 // Anchor's host property isn't correctly set when s.url is relative 9291 urlAnchor.href = urlAnchor.href; 9292 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 9293 urlAnchor.protocol + "//" + urlAnchor.host; 9294 } catch ( e ) { 9295 9296 // If there is an error parsing the URL, assume it is crossDomain, 9297 // it can be rejected by the transport if it is invalid 9298 s.crossDomain = true; 9299 } 9300 } 9301 9302 // Convert data if not already a string 9303 if ( s.data && s.processData && typeof s.data !== "string" ) { 9304 s.data = jQuery.param( s.data, s.traditional ); 9305 } 9306 9307 // Apply prefilters 9308 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 9309 9310 // If request was aborted inside a prefilter, stop there 9311 if ( completed ) { 9312 return jqXHR; 9313 } 9314 9315 // We can fire global events as of now if asked to 9316 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 9317 fireGlobals = jQuery.event && s.global; 9318 9319 // Watch for a new set of requests 9320 if ( fireGlobals && jQuery.active++ === 0 ) { 9321 jQuery.event.trigger( "ajaxStart" ); 9322 } 9323 9324 // Uppercase the type 9325 s.type = s.type.toUpperCase(); 9326 9327 // Determine if request has content 9328 s.hasContent = !rnoContent.test( s.type ); 9329 9330 // Save the URL in case we're toying with the If-Modified-Since 9331 // and/or If-None-Match header later on 9332 // Remove hash to simplify url manipulation 9333 cacheURL = s.url.replace( rhash, "" ); 9334 9335 // More options handling for requests with no content 9336 if ( !s.hasContent ) { 9337 9338 // Remember the hash so we can put it back 9339 uncached = s.url.slice( cacheURL.length ); 9340 9341 // If data is available and should be processed, append data to url 9342 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 9343 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 9344 9345 // #9682: remove data so that it's not used in an eventual retry 9346 delete s.data; 9347 } 9348 9349 // Add or update anti-cache param if needed 9350 if ( s.cache === false ) { 9351 cacheURL = cacheURL.replace( rantiCache, "$1" ); 9352 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; 9353 } 9354 9355 // Put hash and anti-cache on the URL that will be requested (gh-1732) 9356 s.url = cacheURL + uncached; 9357 9358 // Change '%20' to '+' if this is encoded form body content (gh-2658) 9359 } else if ( s.data && s.processData && 9360 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 9361 s.data = s.data.replace( r20, "+" ); 9362 } 9363 9364 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9365 if ( s.ifModified ) { 9366 if ( jQuery.lastModified[ cacheURL ] ) { 9367 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 9368 } 9369 if ( jQuery.etag[ cacheURL ] ) { 9370 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 9371 } 9372 } 9373 9374 // Set the correct header, if data is being sent 9375 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 9376 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 9377 } 9378 9379 // Set the Accepts header for the server, depending on the dataType 9380 jqXHR.setRequestHeader( 9381 "Accept", 9382 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 9383 s.accepts[ s.dataTypes[ 0 ] ] + 9384 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 9385 s.accepts[ "*" ] 9386 ); 9387 9388 // Check for headers option 9389 for ( i in s.headers ) { 9390 jqXHR.setRequestHeader( i, s.headers[ i ] ); 9391 } 9392 9393 // Allow custom headers/mimetypes and early abort 9394 if ( s.beforeSend && 9395 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 9396 9397 // Abort if not done already and return 9398 return jqXHR.abort(); 9399 } 9400 9401 // Aborting is no longer a cancellation 9402 strAbort = "abort"; 9403 9404 // Install callbacks on deferreds 9405 completeDeferred.add( s.complete ); 9406 jqXHR.done( s.success ); 9407 jqXHR.fail( s.error ); 9408 9409 // Get transport 9410 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 9411 9412 // If no transport, we auto-abort 9413 if ( !transport ) { 9414 done( -1, "No Transport" ); 9415 } else { 9416 jqXHR.readyState = 1; 9417 9418 // Send global event 9419 if ( fireGlobals ) { 9420 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 9421 } 9422 9423 // If request was aborted inside ajaxSend, stop there 9424 if ( completed ) { 9425 return jqXHR; 9426 } 9427 9428 // Timeout 9429 if ( s.async && s.timeout > 0 ) { 9430 timeoutTimer = window.setTimeout( function() { 9431 jqXHR.abort( "timeout" ); 9432 }, s.timeout ); 9433 } 9434 9435 try { 9436 completed = false; 9437 transport.send( requestHeaders, done ); 9438 } catch ( e ) { 9439 9440 // Rethrow post-completion exceptions 9441 if ( completed ) { 9442 throw e; 9443 } 9444 9445 // Propagate others as results 9446 done( -1, e ); 9447 } 9448 } 9449 9450 // Callback for when everything is done 9451 function done( status, nativeStatusText, responses, headers ) { 9452 var isSuccess, success, error, response, modified, 9453 statusText = nativeStatusText; 9454 9455 // Ignore repeat invocations 9456 if ( completed ) { 9457 return; 9458 } 9459 9460 completed = true; 9461 9462 // Clear timeout if it exists 9463 if ( timeoutTimer ) { 9464 window.clearTimeout( timeoutTimer ); 9465 } 9466 9467 // Dereference transport for early garbage collection 9468 // (no matter how long the jqXHR object will be used) 9469 transport = undefined; 9470 9471 // Cache response headers 9472 responseHeadersString = headers || ""; 9473 9474 // Set readyState 9475 jqXHR.readyState = status > 0 ? 4 : 0; 9476 9477 // Determine if successful 9478 isSuccess = status >= 200 && status < 300 || status === 304; 9479 9480 // Get response data 9481 if ( responses ) { 9482 response = ajaxHandleResponses( s, jqXHR, responses ); 9483 } 9484 9485 // Convert no matter what (that way responseXXX fields are always set) 9486 response = ajaxConvert( s, response, jqXHR, isSuccess ); 9487 9488 // If successful, handle type chaining 9489 if ( isSuccess ) { 9490 9491 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9492 if ( s.ifModified ) { 9493 modified = jqXHR.getResponseHeader( "Last-Modified" ); 9494 if ( modified ) { 9495 jQuery.lastModified[ cacheURL ] = modified; 9496 } 9497 modified = jqXHR.getResponseHeader( "etag" ); 9498 if ( modified ) { 9499 jQuery.etag[ cacheURL ] = modified; 9500 } 9501 } 9502 9503 // if no content 9504 if ( status === 204 || s.type === "HEAD" ) { 9505 statusText = "nocontent"; 9506 9507 // if not modified 9508 } else if ( status === 304 ) { 9509 statusText = "notmodified"; 9510 9511 // If we have data, let's convert it 9512 } else { 9513 statusText = response.state; 9514 success = response.data; 9515 error = response.error; 9516 isSuccess = !error; 9517 } 9518 } else { 9519 9520 // Extract error from statusText and normalize for non-aborts 9521 error = statusText; 9522 if ( status || !statusText ) { 9523 statusText = "error"; 9524 if ( status < 0 ) { 9525 status = 0; 9526 } 9527 } 9528 } 9529 9530 // Set data for the fake xhr object 9531 jqXHR.status = status; 9532 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 9533 9534 // Success/Error 9535 if ( isSuccess ) { 9536 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 9537 } else { 9538 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 9539 } 9540 9541 // Status-dependent callbacks 9542 jqXHR.statusCode( statusCode ); 9543 statusCode = undefined; 9544 9545 if ( fireGlobals ) { 9546 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 9547 [ jqXHR, s, isSuccess ? success : error ] ); 9548 } 9549 9550 // Complete 9551 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 9552 9553 if ( fireGlobals ) { 9554 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 9555 9556 // Handle the global AJAX counter 9557 if ( !( --jQuery.active ) ) { 9558 jQuery.event.trigger( "ajaxStop" ); 9559 } 9560 } 9561 } 9562 9563 return jqXHR; 9564 }, 9565 9566 getJSON: function( url, data, callback ) { 9567 return jQuery.get( url, data, callback, "json" ); 9568 }, 9569 9570 getScript: function( url, callback ) { 9571 return jQuery.get( url, undefined, callback, "script" ); 9572 } 9573} ); 9574 9575jQuery.each( [ "get", "post" ], function( i, method ) { 9576 jQuery[ method ] = function( url, data, callback, type ) { 9577 9578 // Shift arguments if data argument was omitted 9579 if ( isFunction( data ) ) { 9580 type = type || callback; 9581 callback = data; 9582 data = undefined; 9583 } 9584 9585 // The url can be an options object (which then must have .url) 9586 return jQuery.ajax( jQuery.extend( { 9587 url: url, 9588 type: method, 9589 dataType: type, 9590 data: data, 9591 success: callback 9592 }, jQuery.isPlainObject( url ) && url ) ); 9593 }; 9594} ); 9595 9596 9597jQuery._evalUrl = function( url
9597, options ) { 9598 return jQuery.ajax( { 9599 url: url, 9600 9601 // Make this explicit, since user can override this through ajaxSetup (#11264) 9602 type: "GET", 9603 dataType: "script", 9604 cache: true, 9605 async: false, 9606 global: false, 9607 9608 // Only evaluate the response if it is successful (gh-4126) 9609 // dataFilter is not invoked for failure responses, so using it instead 9610 // of the default converter is kludgy but it works. 9611 converters: { 9612 "text script": function() {} 9613 }, 9614 dataFilter: function( response ) { 9615 jQuery.globalEval( response, options
vendor: 11,651 bytes, lines 9615-10080
9615 ); 9616 } 9617 } ); 9618}; 9619 9620 9621jQuery.fn.extend( { 9622 wrapAll: function( html ) { 9623 var wrap; 9624 9625 if ( this[ 0 ] ) { 9626 if ( isFunction( html ) ) { 9627 html = html.call( this[ 0 ] ); 9628 } 9629 9630 // The elements to wrap the target around 9631 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 9632 9633 if ( this[ 0 ].parentNode ) { 9634 wrap.insertBefore( this[ 0 ] ); 9635 } 9636 9637 wrap.map( function() { 9638 var elem = this; 9639 9640 while ( elem.firstElementChild ) { 9641 elem = elem.firstElementChild; 9642 } 9643 9644 return elem; 9645 } ).append( this ); 9646 } 9647 9648 return this; 9649 }, 9650 9651 wrapInner: function( html ) { 9652 if ( isFunction( html ) ) { 9653 return this.each( function( i ) { 9654 jQuery( this ).wrapInner( html.call( this, i ) ); 9655 } ); 9656 } 9657 9658 return this.each( function() { 9659 var self = jQuery( this ), 9660 contents = self.contents(); 9661 9662 if ( contents.length ) { 9663 contents.wrapAll( html ); 9664 9665 } else { 9666 self.append( html ); 9667 } 9668 } ); 9669 }, 9670 9671 wrap: function( html ) { 9672 var htmlIsFunction = isFunction( html ); 9673 9674 return this.each( function( i ) { 9675 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 9676 } ); 9677 }, 9678 9679 unwrap: function( selector ) { 9680 this.parent( selector ).not( "body" ).each( function() { 9681 jQuery( this ).replaceWith( this.childNodes ); 9682 } ); 9683 return this; 9684 } 9685} ); 9686 9687 9688jQuery.expr.pseudos.hidden = function( elem ) { 9689 return !jQuery.expr.pseudos.visible( elem ); 9690}; 9691jQuery.expr.pseudos.visible = function( elem ) { 9692 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 9693}; 9694 9695 9696 9697 9698jQuery.ajaxSettings.xhr = function() { 9699 try { 9700 return new window.XMLHttpRequest(); 9701 } catch ( e ) {} 9702}; 9703 9704var xhrSuccessStatus = { 9705 9706 // File protocol always yields status code 0, assume 200 9707 0: 200, 9708 9709 // Support: IE <=9 only 9710 // #1450: sometimes IE returns 1223 when it should be 204 9711 1223: 204 9712 }, 9713 xhrSupported = jQuery.ajaxSettings.xhr(); 9714 9715support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 9716support.ajax = xhrSupported = !!xhrSupported; 9717 9718jQuery.ajaxTransport( function( options ) { 9719 var callback, errorCallback; 9720 9721 // Cross domain only allowed if supported through XMLHttpRequest 9722 if ( support.cors || xhrSupported && !options.crossDomain ) { 9723 return { 9724 send: function( headers, complete ) { 9725 var i, 9726 xhr = options.xhr(); 9727 9728 xhr.open( 9729 options.type, 9730 options.url, 9731 options.async, 9732 options.username, 9733 options.password 9734 ); 9735 9736 // Apply custom fields if provided 9737 if ( options.xhrFields ) { 9738 for ( i in options.xhrFields ) { 9739 xhr[ i ] = options.xhrFields[ i ]; 9740 } 9741 } 9742 9743 // Override mime type if needed 9744 if ( options.mimeType && xhr.overrideMimeType ) { 9745 xhr.overrideMimeType( options.mimeType ); 9746 } 9747 9748 // X-Requested-With header 9749 // For cross-domain requests, seeing as conditions for a preflight are 9750 // akin to a jigsaw puzzle, we simply never set it to be sure. 9751 // (it can always be set on a per-request basis or even using ajaxSetup) 9752 // For same-domain requests, won't change header if already provided. 9753 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 9754 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 9755 } 9756 9757 // Set headers 9758 for ( i in headers ) { 9759 xhr.setRequestHeader( i, headers[ i ] ); 9760 } 9761 9762 // Callback 9763 callback = function( type ) { 9764 return function() { 9765 if ( callback ) { 9766 callback = errorCallback = xhr.onload = 9767 xhr.onerror = xhr.onabort = xhr.ontimeout = 9768 xhr.onreadystatechange = null; 9769 9770 if ( type === "abort" ) { 9771 xhr.abort(); 9772 } else if ( type === "error" ) { 9773 9774 // Support: IE <=9 only 9775 // On a manual native abort, IE9 throws 9776 // errors on any property access that is not readyState 9777 if ( typeof xhr.status !== "number" ) { 9778 complete( 0, "error" ); 9779 } else { 9780 complete( 9781 9782 // File: protocol always yields status 0; see #8605, #14207 9783 xhr.status, 9784 xhr.statusText 9785 ); 9786 } 9787 } else { 9788 complete( 9789 xhrSuccessStatus[ xhr.status ] || xhr.status, 9790 xhr.statusText, 9791 9792 // Support: IE <=9 only 9793 // IE9 has no XHR2 but throws on binary (trac-11426) 9794 // For XHR2 non-text, let the caller handle it (gh-2498) 9795 ( xhr.responseType || "text" ) !== "text" || 9796 typeof xhr.responseText !== "string" ? 9797 { binary: xhr.response } : 9798 { text: xhr.responseText }, 9799 xhr.getAllResponseHeaders() 9800 ); 9801 } 9802 } 9803 }; 9804 }; 9805 9806 // Listen to events 9807 xhr.onload = callback(); 9808 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 9809 9810 // Support: IE 9 only 9811 // Use onreadystatechange to replace onabort 9812 // to handle uncaught aborts 9813 if ( xhr.onabort !== undefined ) { 9814 xhr.onabort = errorCallback; 9815 } else { 9816 xhr.onreadystatechange = function() { 9817 9818 // Check readyState before timeout as it changes 9819 if ( xhr.readyState === 4 ) { 9820 9821 // Allow onerror to be called first, 9822 // but that will not handle a native abort 9823 // Also, save errorCallback to a variable 9824 // as xhr.onerror cannot be accessed 9825 window.setTimeout( function() { 9826 if ( callback ) { 9827 errorCallback(); 9828 } 9829 } ); 9830 } 9831 }; 9832 } 9833 9834 // Create the abort callback 9835 callback = callback( "abort" ); 9836 9837 try { 9838 9839 // Do send the request (this may raise an exception) 9840 xhr.send( options.hasContent && options.data || null ); 9841 } catch ( e ) { 9842 9843 // #14683: Only rethrow if this hasn't been notified as an error yet 9844 if ( callback ) { 9845 throw e; 9846 } 9847 } 9848 }, 9849 9850 abort: function() { 9851 if ( callback ) { 9852 callback(); 9853 } 9854 } 9855 }; 9856 } 9857} ); 9858 9859 9860 9861 9862// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 9863jQuery.ajaxPrefilter( function( s ) { 9864 if ( s.crossDomain ) { 9865 s.contents.script = false; 9866 } 9867} ); 9868 9869// Install script dataType 9870jQuery.ajaxSetup( { 9871 accepts: { 9872 script: "text/javascript, application/javascript, " + 9873 "application/ecmascript, application/x-ecmascript" 9874 }, 9875 contents: { 9876 script: /\b(?:java|ecma)script\b/ 9877 }, 9878 converters: { 9879 "text script": function( text ) { 9880 jQuery.globalEval( text ); 9881 return text; 9882 } 9883 } 9884} ); 9885 9886// Handle cache's special case and crossDomain 9887jQuery.ajaxPrefilter( "script", function( s ) { 9888 if ( s.cache === undefined ) { 9889 s.cache = false; 9890 } 9891 if ( s.crossDomain ) { 9892 s.type = "GET"; 9893 } 9894} ); 9895 9896// Bind script tag hack transport 9897jQuery.ajaxTransport( "script", function( s ) { 9898 9899 // This transport only deals with cross domain or forced-by-attrs requests 9900 if ( s.crossDomain || s.scriptAttrs ) { 9901 var script, callback; 9902 return { 9903 send: function( _, complete ) { 9904 script = jQuery( "<script>" ) 9905 .attr( s.scriptAttrs || {} ) 9906 .prop( { charset: s.scriptCharset, src: s.url } ) 9907 .on( "load error", callback = function( evt ) { 9908 script.remove(); 9909 callback = null; 9910 if ( evt ) { 9911 complete( evt.type === "error" ? 404 : 200, evt.type ); 9912 } 9913 } ); 9914 9915 // Use native DOM manipulation to avoid our domManip AJAX trickery 9916 document.head.appendChild( script[ 0 ] ); 9917 }, 9918 abort: function() { 9919 if ( callback ) { 9920 callback(); 9921 } 9922 } 9923 }; 9924 } 9925} ); 9926 9927 9928 9929 9930var oldCallbacks = [], 9931 rjsonp = /(=)\?(?=&|$)|\?\?/; 9932 9933// Default jsonp settings 9934jQuery.ajaxSetup( { 9935 jsonp: "callback", 9936 jsonpCallback: function() { 9937 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 9938 this[ callback ] = true; 9939 return callback; 9940 } 9941} ); 9942 9943// Detect, normalize options and install callbacks for jsonp requests 9944jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 9945 9946 var callbackName, overwritten, responseContainer, 9947 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 9948 "url" : 9949 typeof s.data === "string" && 9950 ( s.contentType || "" ) 9951 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 9952 rjsonp.test( s.data ) && "data" 9953 ); 9954 9955 // Handle iff the expected data type is "jsonp" or we have a parameter to set 9956 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 9957 9958 // Get callback name, remembering preexisting value associated with it 9959 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 9960 s.jsonpCallback() : 9961 s.jsonpCallback; 9962 9963 // Insert callback into url or form data 9964 if ( jsonProp ) { 9965 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 9966 } else if ( s.jsonp !== false ) { 9967 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 9968 } 9969 9970 // Use data converter to retrieve json after script execution 9971 s.converters[ "script json" ] = function() { 9972 if ( !responseContainer ) { 9973 jQuery.error( callbackName + " was not called" ); 9974 } 9975 return responseContainer[ 0 ]; 9976 }; 9977 9978 // Force json dataType 9979 s.dataTypes[ 0 ] = "json"; 9980 9981 // Install callback 9982 overwritten = window[ callbackName ]; 9983 window[ callbackName ] = function() { 9984 responseContainer = arguments; 9985 }; 9986 9987 // Clean-up function (fires after converters) 9988 jqXHR.always( function() { 9989 9990 // If previous value didn't exist - remove it 9991 if ( overwritten === undefined ) { 9992 jQuery( window ).removeProp( callbackName ); 9993 9994 // Otherwise restore preexisting value 9995 } else { 9996 window[ callbackName ] = overwritten; 9997 } 9998 9999 // Save back as free 10000 if ( s[ callbackName ] ) { 10001 10002 // Make sure that re-using the options doesn't screw things around 10003 s.jsonpCallback = originalSettings.jsonpCallback; 10004 10005 // Save the callback name for future use 10006 oldCallbacks.push( callbackName ); 10007 } 10008 10009 // Call if it was a function and we have a response 10010 if ( responseContainer && isFunction( overwritten ) ) { 10011 overwritten( responseContainer[ 0 ] ); 10012 } 10013 10014 responseContainer = overwritten = undefined; 10015 } ); 10016 10017 // Delegate to script 10018 return "script"; 10019 } 10020} ); 10021 10022 10023 10024 10025// Support: Safari 8 only 10026// In Safari 8 documents created via document.implementation.createHTMLDocument 10027// collapse sibling forms: the second one becomes a child of the first one. 10028// Because of that, this security measure has to be disabled in Safari 8. 10029// https://bugs.webkit.org/show_bug.cgi?id=137337 10030support.createHTMLDocument = ( function() { 10031 var body = document.implementation.createHTMLDocument( "" ).body; 10032 body.innerHTML = "<form></form><form></form>"; 10033 return body.childNodes.length === 2; 10034} )(); 10035 10036 10037// Argument "data" should be string of html 10038// context (optional): If specified, the fragment will be created in this context, 10039// defaults to document 10040// keepScripts (optional): If true, will include scripts passed in the html string 10041jQuery.parseHTML = function( data, context, keepScripts ) { 10042 if ( typeof data !== "string" ) { 10043 return []; 10044 } 10045 if ( typeof context === "boolean" ) { 10046 keepScripts = context; 10047 context = false; 10048 } 10049 10050 var base, parsed, scripts; 10051 10052 if ( !context ) { 10053 10054 // Stop scripts or inline event handlers from being executed immediately 10055 // by using document.implementation 10056 if ( support.createHTMLDocument ) { 10057 context = document.implementation.createHTMLDocument( "" ); 10058 10059 // Set the base href for the created document 10060 // so any parsed elements with URLs 10061 // are based on the document's URL (gh-2965) 10062 base = context.createElement( "base" ); 10063 base.href = document.location.href; 10064 context.head.appendChild( base ); 10065 } else { 10066 context = document; 10067 } 10068 } 10069 10070 parsed = rsingleTag.exec( data ); 10071 scripts = !keepScripts && []; 10072 10073 // Single tag 10074 if ( parsed ) { 10075 return [ context.createElement( parsed[ 1 ] ) ]; 10076 } 10077 10078 parsed = buildFragment( [ data ], context, scripts ); 10079 10080 if ( scripts && scripts.length ) {
vendor: 14,511 bytes, lines 10081-10601
10081 jQuery( scripts ).remove(); 10082 } 10083 10084 return jQuery.merge( [], parsed.childNodes ); 10085}; 10086 10087 10088/** 10089 * Load a url into a page 10090 */ 10091jQuery.fn.load = function( url, params, callback ) { 10092 var selector, type, response, 10093 self = this, 10094 off = url.indexOf( " " ); 10095 10096 if ( off > -1 ) { 10097 selector = stripAndCollapse( url.slice( off ) ); 10098 url = url.slice( 0, off ); 10099 } 10100 10101 // If it's a function 10102 if ( isFunction( params ) ) { 10103 10104 // We assume that it's the callback 10105 callback = params; 10106 params = undefined; 10107 10108 // Otherwise, build a param string 10109 } else if ( params && typeof params === "object" ) { 10110 type = "POST"; 10111 } 10112 10113 // If we have elements to modify, make the request 10114 if ( self.length > 0 ) { 10115 jQuery.ajax( { 10116 url: url, 10117 10118 // If "type" variable is undefined, then "GET" method will be used. 10119 // Make value of this field explicit since 10120 // user can override it through ajaxSetup method 10121 type: type || "GET", 10122 dataType: "html", 10123 data: params 10124 } ).done( function( responseText ) { 10125 10126 // Save response for use in complete callback 10127 response = arguments; 10128 10129 self.html( selector ? 10130 10131 // If a selector was specified, locate the right elements in a dummy div 10132 // Exclude scripts to avoid IE 'Permission Denied' errors 10133 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 10134 10135 // Otherwise use the full result 10136 responseText ); 10137 10138 // If the request succeeds, this function gets "data", "status", "jqXHR" 10139 // but they are ignored because response was set above. 10140 // If it fails, this function gets "jqXHR", "status", "error" 10141 } ).always( callback && function( jqXHR, status ) { 10142 self.each( function() { 10143 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 10144 } ); 10145 } ); 10146 } 10147 10148 return this; 10149}; 10150 10151 10152 10153 10154// Attach a bunch of functions for handling common AJAX events 10155jQuery.each( [ 10156 "ajaxStart", 10157 "ajaxStop", 10158 "ajaxComplete", 10159 "ajaxError", 10160 "ajaxSuccess", 10161 "ajaxSend" 10162], function( i, type ) { 10163 jQuery.fn[ type ] = function( fn ) { 10164 return this.on( type, fn ); 10165 }; 10166} ); 10167 10168 10169 10170 10171jQuery.expr.pseudos.animated = function( elem ) { 10172 return jQuery.grep( jQuery.timers, function( fn ) { 10173 return elem === fn.elem; 10174 } ).length; 10175}; 10176 10177 10178 10179 10180jQuery.offset = { 10181 setOffset: function( elem, options, i ) { 10182 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 10183 position = jQuery.css( elem, "position" ), 10184 curElem = jQuery( elem ), 10185 props = {}; 10186 10187 // Set position first, in-case top/left are set even on static elem 10188 if ( position === "static" ) { 10189 elem.style.position = "relative"; 10190 } 10191 10192 curOffset = curElem.offset(); 10193 curCSSTop = jQuery.css( elem, "top" ); 10194 curCSSLeft = jQuery.css( elem, "left" ); 10195 calculatePosition = ( position === "absolute" || position === "fixed" ) && 10196 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 10197 10198 // Need to be able to calculate position if either 10199 // top or left is auto and position is either absolute or fixed 10200 if ( calculatePosition ) { 10201 curPosition = curElem.position(); 10202 curTop = curPosition.top; 10203 curLeft = curPosition.left; 10204 10205 } else { 10206 curTop = parseFloat( curCSSTop ) || 0; 10207 curLeft = parseFloat( curCSSLeft ) || 0; 10208 } 10209 10210 if ( isFunction( options ) ) { 10211 10212 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10213 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 10214 } 10215 10216 if ( options.top != null ) { 10217 props.top = ( options.top - curOffset.top ) + curTop; 10218 } 10219 if ( options.left != null ) { 10220 props.left = ( options.left - curOffset.left ) + curLeft; 10221 } 10222 10223 if ( "using" in options ) { 10224 options.using.call( elem, props ); 10225 10226 } else { 10227 curElem.css( props ); 10228 } 10229 } 10230}; 10231 10232jQuery.fn.extend( { 10233 10234 // offset() relates an element's border box to the document origin 10235 offset: function( options ) { 10236 10237 // Preserve chaining for setter 10238 if ( arguments.length ) { 10239 return options === undefined ? 10240 this : 10241 this.each( function( i ) { 10242 jQuery.offset.setOffset( this, options, i ); 10243 } ); 10244 } 10245 10246 var rect, win, 10247 elem = this[ 0 ]; 10248 10249 if ( !elem ) { 10250 return; 10251 } 10252 10253 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 10254 // Support: IE <=11 only 10255 // Running getBoundingClientRect on a 10256 // disconnected node in IE throws an error 10257 if ( !elem.getClientRects().length ) { 10258 return { top: 0, left: 0 }; 10259 } 10260 10261 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 10262 rect = elem.getBoundingClientRect(); 10263 win = elem.ownerDocument.defaultView; 10264 return { 10265 top: rect.top + win.pageYOffset, 10266 left: rect.left + win.pageXOffset 10267 }; 10268 }, 10269 10270 // position() relates an element's margin box to its offset parent's padding box 10271 // This corresponds to the behavior of CSS absolute positioning 10272 position: function() { 10273 if ( !this[ 0 ] ) { 10274 return; 10275 } 10276 10277 var offsetParent, offset, doc, 10278 elem = this[ 0 ], 10279 parentOffset = { top: 0, left: 0 }; 10280 10281 // position:fixed elements are offset from the viewport, which itself always has zero offset 10282 if ( jQuery.css( elem, "position" ) === "fixed" ) { 10283 10284 // Assume position:fixed implies availability of getBoundingClientRect 10285 offset = elem.getBoundingClientRect(); 10286 10287 } else { 10288 offset = this.offset(); 10289 10290 // Account for the *real* offset parent, which can be the document or its root element 10291 // when a statically positioned element is identified 10292 doc = elem.ownerDocument; 10293 offsetParent = elem.offsetParent || doc.documentElement; 10294 while ( offsetParent && 10295 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 10296 jQuery.css( offsetParent, "position" ) === "static" ) { 10297 10298 offsetParent = offsetParent.parentNode; 10299 } 10300 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 10301 10302 // Incorporate borders into its offset, since they are outside its content origin 10303 parentOffset = jQuery( offsetParent ).offset(); 10304 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 10305 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 10306 } 10307 } 10308 10309 // Subtract parent offsets and element margins 10310 return { 10311 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 10312 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 10313 }; 10314 }, 10315 10316 // This method will return documentElement in the following cases: 10317 // 1) For the element inside the iframe without offsetParent, this method will return 10318 // documentElement of the parent window 10319 // 2) For the hidden or detached element 10320 // 3) For body or html element, i.e. in case of the html node - it will return itself 10321 // 10322 // but those exceptions were never presented as a real life use-cases 10323 // and might be considered as more preferable results. 10324 // 10325 // This logic, however, is not guaranteed and can change at any point in the future 10326 offsetParent: function() { 10327 return this.map( function() { 10328 var offsetParent = this.offsetParent; 10329 10330 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 10331 offsetParent = offsetParent.offsetParent; 10332 } 10333 10334 return offsetParent || documentElement; 10335 } ); 10336 } 10337} ); 10338 10339// Create scrollLeft and scrollTop methods 10340jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 10341 var top = "pageYOffset" === prop; 10342 10343 jQuery.fn[ method ] = function( val ) { 10344 return access( this, function( elem, method, val ) { 10345 10346 // Coalesce documents and windows 10347 var win; 10348 if ( isWindow( elem ) ) { 10349 win = elem; 10350 } else if ( elem.nodeType === 9 ) { 10351 win = elem.defaultView; 10352 } 10353 10354 if ( val === undefined ) { 10355 return win ? win[ prop ] : elem[ method ]; 10356 } 10357 10358 if ( win ) { 10359 win.scrollTo( 10360 !top ? val : win.pageXOffset, 10361 top ? val : win.pageYOffset 10362 ); 10363 10364 } else { 10365 elem[ method ] = val; 10366 } 10367 }, method, val, arguments.length ); 10368 }; 10369} ); 10370 10371// Support: Safari <=7 - 9.1, Chrome <=37 - 49 10372// Add the top/left cssHooks using jQuery.fn.position 10373// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10374// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 10375// getComputedStyle returns percent when specified for top/left/bottom/right; 10376// rather than make the css module depend on the offset module, just check for it here 10377jQuery.each( [ "top", "left" ], function( i, prop ) { 10378 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 10379 function( elem, computed ) { 10380 if ( computed ) { 10381 computed = curCSS( elem, prop ); 10382 10383 // If curCSS returns percentage, fallback to offset 10384 return rnumnonpx.test( computed ) ? 10385 jQuery( elem ).position()[ prop ] + "px" : 10386 computed; 10387 } 10388 } 10389 ); 10390} ); 10391 10392 10393// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10394jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 10395 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 10396 function( defaultExtra, funcName ) { 10397 10398 // Margin is only for outerHeight, outerWidth 10399 jQuery.fn[ funcName ] = function( margin, value ) { 10400 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 10401 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 10402 10403 return access( this, function( elem, type, value ) { 10404 var doc; 10405 10406 if ( isWindow( elem ) ) { 10407 10408 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 10409 return funcName.indexOf( "outer" ) === 0 ? 10410 elem[ "inner" + name ] : 10411 elem.document.documentElement[ "client" + name ]; 10412 } 10413 10414 // Get document width or height 10415 if ( elem.nodeType === 9 ) { 10416 doc = elem.documentElement; 10417 10418 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10419 // whichever is greatest 10420 return Math.max( 10421 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 10422 elem.body[ "offset" + name ], doc[ "offset" + name ], 10423 doc[ "client" + name ] 10424 ); 10425 } 10426 10427 return value === undefined ? 10428 10429 // Get width or height on the element, requesting but not forcing parseFloat 10430 jQuery.css( elem, type, extra ) : 10431 10432 // Set width or height on the element 10433 jQuery.style( elem, type, value, extra ); 10434 }, type, chainable ? margin : undefined, chainable ); 10435 }; 10436 } ); 10437} ); 10438 10439 10440jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + 10441 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 10442 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 10443 function( i, name ) { 10444 10445 // Handle event binding 10446 jQuery.fn[ name ] = function( data, fn ) { 10447 return arguments.length > 0 ? 10448 this.on( name, null, data, fn ) : 10449 this.trigger( name ); 10450 }; 10451} ); 10452 10453jQuery.fn.extend( { 10454 hover: function( fnOver, fnOut ) { 10455 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 10456 } 10457} ); 10458 10459 10460 10461 10462jQuery.fn.extend( { 10463 10464 bind: function( types, data, fn ) { 10465 return this.on( types, null, data, fn ); 10466 }, 10467 unbind: function( types, fn ) { 10468 return this.off( types, null, fn ); 10469 }, 10470 10471 delegate: function( selector, types, data, fn ) { 10472 return this.on( types, selector, data, fn ); 10473 }, 10474 undelegate: function( selector, types, fn ) { 10475 10476 // ( namespace ) or ( selector, types [, fn] ) 10477 return arguments.length === 1 ? 10478 this.off( selector, "**" ) : 10479 this.off( types, selector || "**", fn ); 10480 } 10481} ); 10482 10483// Bind a function to a context, optionally partially applying any 10484// arguments. 10485// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 10486// However, it is not slated for removal any time soon 10487jQuery.proxy = function( fn, context ) { 10488 var tmp, args, proxy; 10489 10490 if ( typeof context === "string" ) { 10491 tmp = fn[ context ]; 10492 context = fn; 10493 fn = tmp; 10494 } 10495 10496 // Quick check to determine if target is callable, in the spec 10497 // this throws a TypeError, but we will just return undefined. 10498 if ( !isFunction( fn ) ) { 10499 return undefined; 10500 } 10501 10502 // Simulated bind 10503 args = slice.call( arguments, 2 ); 10504 proxy = function() { 10505 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 10506 }; 10507 10508 // Set the guid of unique handler to the same of original handler, so it can be removed 10509 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 10510 10511 return proxy; 10512}; 10513 10514jQuery.holdReady = function( hold ) { 10515 if ( hold ) { 10516 jQuery.readyWait++; 10517 } else { 10518 jQuery.ready( true ); 10519 } 10520}; 10521jQuery.isArray = Array.isArray; 10522jQuery.parseJSON = JSON.parse; 10523jQuery.nodeName = nodeName; 10524jQuery.isFunction = isFunction; 10525jQuery.isWindow = isWindow; 10526jQuery.camelCase = camelCase; 10527jQuery.type = toType; 10528 10529jQuery.now = Date.now; 10530 10531jQuery.isNumeric = function( obj ) { 10532 10533 // As of jQuery 3.0, isNumeric is limited to 10534 // strings and numbers (primitives or objects) 10535 // that can be coerced to finite numbers (gh-2662) 10536 var type = jQuery.type( obj ); 10537 return ( type === "number" || type === "string" ) && 10538 10539 // parseFloat NaNs numeric-cast false positives ("") 10540 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 10541 // subtraction forces infinities to NaN 10542 !isNaN( obj - parseFloat( obj ) ); 10543}; 10544 10545 10546 10547 10548// Register as a named AMD module, since jQuery can be concatenated with other 10549// files that may use define, but not via a proper concatenation script that 10550// understands anonymous AMD modules. A named AMD is safest and most robust 10551// way to register. Lowercase jquery is used because AMD module names are 10552// derived from file names, and jQuery is normally delivered in a lowercase 10553// file name. Do this after creating the global so that if an AMD module wants 10554// to call noConflict to hide this version of jQuery, it will work. 10555 10556// Note that for maximum portability, libraries that are not jQuery should 10557// declare themselves as anonymous modules, and avoid setting a global if an 10558// AMD loader is present. jQuery is a special case. For more information, see 10559// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10560 10561if ( typeof define === "function" && define.amd ) { 10562 define( "jquery", [], function() { 10563 return jQuery; 10564 } ); 10565} 10566 10567 10568 10569 10570var 10571 10572 // Map over jQuery in case of overwrite 10573 _jQuery = window.jQuery, 10574 10575 // Map over the $ in case of overwrite 10576 _$ = window.$; 10577 10578jQuery.noConflict = function( deep ) { 10579 if ( window.$ === jQuery ) { 10580 window.$ = _$; 10581 } 10582 10583 if ( deep && window.jQuery === jQuery ) { 10584 window.jQuery = _jQuery; 10585 } 10586 10587 return jQuery; 10588}; 10589 10590// Expose jQuery and $ identifiers, even in AMD 10591// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 10592// and CommonJS for browser emulators (#13566) 10593if ( !noGlobal ) { 10594 window.jQuery = window.$ = jQuery; 10595} 10596 10597 10598 10599 10600return jQuery; 10601} );
vendor: 5,871 bytes, lines 10602-10840
10602 10603/*! 10604 * JavaScript Cookie v2.2.1 10605 * https://github.com/js-cookie/js-cookie 10606 * 10607 * Copyright 2006, 2015 Klaus Hartl & Fagner Brack 10608 * Released under the MIT license 10609 */ 10610;(function (factory) { 10611 var registeredInModuleLoader; 10612 if (typeof define === 'function' && define.amd) { 10613 define(factory); 10614 registeredInModuleLoader = true; 10615 } 10616 if (typeof exports === 'object') { 10617 module.exports = factory(); 10618 registeredInModuleLoader = true; 10619 } 10620 if (!registeredInModuleLoader) { 10621 var OldCookies = window.Cookies; 10622 var api = window.Cookies = factory(); 10623 api.noConflict = function () { 10624 window.Cookies = OldCookies; 10625 return api; 10626 }; 10627 } 10628}(function () { 10629 function extend () { 10630 var i = 0; 10631 var result = {}; 10632 for (; i < arguments.length; i++) { 10633 var attributes = arguments[ i ]; 10634 for (var key in attributes) { 10635 result[key] = attributes[key]; 10636 } 10637 } 10638 return result; 10639 } 10640 10641 function decode (s) { 10642 return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent); 10643 } 10644 10645 function init (converter) { 10646 function api() {} 10647 10648 function set (key, value, attributes) { 10649 if (typeof document === 'undefined') { 10650 return; 10651 } 10652 10653 attributes = extend({ 10654 path: '/' 10655 }, api.defaults, attributes); 10656 10657 if (typeof attributes.expires === 'number') { 10658 attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5); 10659 } 10660 10661 // We're using "expires" because "max-age" is not supported by IE 10662 attributes.expires = attributes.expires ? attributes.expires.toUTCString() : ''; 10663 10664 try { 10665 var result = JSON.stringify(value); 10666 if (/^[\{\[]/.test(result)) { 10667 value = result; 10668 } 10669 } catch (e) {} 10670 10671 value = converter.write ? 10672 converter.write(value, key) : 10673 encodeURIComponent(String(value)) 10674 .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 10675 10676 key = encodeURIComponent(String(key)) 10677 .replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent) 10678 .replace(/[\(\)]/g, escape); 10679 10680 var stringifiedAttributes = ''; 10681 for (var attributeName in attributes) { 10682 if (!attributes[attributeName]) { 10683 continue; 10684 } 10685 stringifiedAttributes += '; ' + attributeName; 10686 if (attributes[attributeName] === true) { 10687 continue; 10688 } 10689 10690 // Considers RFC 6265 section 5.2: 10691 // ... 10692 // 3. If the remaining unparsed-attributes contains a %x3B (";") 10693 // character: 10694 // Consume the characters of the unparsed-attributes up to, 10695 // not including, the first %x3B (";") character. 10696 // ... 10697 stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]; 10698 } 10699 10700 return (document.cookie = key + '=' + value + stringifiedAttributes); 10701 } 10702 10703 function get (key, json) { 10704 if (typeof document === 'undefined') { 10705 return; 10706 } 10707 10708 var jar = {}; 10709 // To prevent the for loop in the first place assign an empty array 10710 // in case there are no cookies at all. 10711 var cookies = document.cookie ? document.cookie.split('; ') : []; 10712 var i = 0; 10713 10714 for (; i < cookies.length; i++) { 10715 var parts = cookies[i].split('='); 10716 var cookie = parts.slice(1).join('='); 10717 10718 if (!json && cookie.charAt(0) === '"') { 10719 cookie = cookie.slice(1, -1); 10720 } 10721 10722 try { 10723 var name = decode(parts[0]); 10724 cookie = (converter.read || converter)(cookie, name) || 10725 decode(cookie); 10726 10727 if (json) { 10728 try { 10729 cookie = JSON.parse(cookie); 10730 } catch (e) {} 10731 } 10732 10733 jar[name] = cookie; 10734 10735 if (key === name) { 10736 break; 10737 } 10738 } catch (e) {} 10739 } 10740 10741 return key ? jar[key] : jar; 10742 } 10743 10744 api.set = set; 10745 api.get = function (key) { 10746 return get(key, false /* read as raw */); 10747 }; 10748 api.getJSON = function (key) { 10749 return get(key, true /* read as json */); 10750 }; 10751 api.remove = function (key, attributes) { 10752 set(key, '', extend(attributes, { 10753 expires: -1 10754 })); 10755 }; 10756 10757 api.defaults = {}; 10758 10759 api.withConverter = init; 10760 10761 return api; 10762 } 10763 10764 return init(function () {}); 10765})); 10766 10767/** 10768 * 10769 * [SOW] Stepofweb Controller 10770 * 10771 * @author Dorin Grigoras 10772 * www.stepofweb.com 10773 * 10774 * @version 1.0.0 10775 10776 10777 @globals 10778 10779 $.SOW.globals.direction 'ltr|rtl' 10780 $.SOW.globals.width actual width (updated on resize) 10781 $.SOW.globals.height actual height (updated on resize) 10782 $.SOW.globals.is_mobile true|false 10783 $.SOW.globals.is_modern_browser true if modern 10784 $.SOW.globals.is_admin true|false (admin layout) 10785 $.SOW.globals.breakpoints.[sm|ms|lg|xl] bootstrap default breakpoints 10786 $.SOW.globals.elBody body element 10787 $.SOW.globals.elHeader header element 10788 $.SOW.globals.elAside main sidebar element 10789 $.SOW.globals.elSideCart CART @sidebar 10790 10791 @functions 10792 $.SOW.reinit('#container') reinit plugins for a specific ajax container; see also: 10793 10794 * 10795 **/ 10796;(function ($) { 10797 'use strict'; 10798 10799 /** 10800 * 10801 * @vars 10802 * 10803 * 10804 **/ 10805 var _v = '1.0.0'; 10806 10807 10808 $.SOW = { 10809 10810 10811 /** 10812 * 10813 * @init 10814 * 10815 * 10816 **/ 10817 init: function () { 10818 10819 /** 10820 10821 None, Strict and Lax Parameters 10822 1. None 10823 If you use the ‘None’ value, this allows cookies to be 10824 sent to requests issued by third parties. You have to make 10825 sure to add the secure attribute alongside setting SameSite=None. 10826 10827 2. Strict 10828 If you use the ‘Strict’ value, the cookies will not be sent when 10829 a third party issues the requests. In some cases, this option might 10830 negatively impact your browsing experience. For example, if a website 10831 you visit by clicking on a link has the SameSite=Strict attribute set, 10832 the website might request you to log in again, since the cookie won’t 10833 be sent along with the request. 10834 10835 3. Lax 10836 If you use the ‘Lax’ value, this allows cookies to be sent if the third 10837 party issues a GET request that causes a Top Level Navigation, which 10838 means that the request will change the address bar. Only those requests 10839 allow the cookie to be sent with the ‘Lax’ value. 10840
10841 **/ document.cookie = 'cross-site-cookie=sow; ' + $.SOW.globals.cookie_secure + ';path=/'; 10842 // -- -- 10843 10844 10845 10846 // Debug infos 10847 // https://developers.google.com/web/fundamentals/performance/navigation-and-resource-timing/ 10848 if(window.performance) { 10849 10850 var __start = new Date().getTime(); 10851 window.onload = function() { 10852 10853 if($.SOW.config.sow__debug_enable === true) { 10854 10855 var __now = new Date().getTime(); 10856 var pageNav = performance.getEntriesByType("navigation")[0]; 10857 var pagePaint = performance.getEntriesByType('paint'); 10858 10859 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 10860 $.SOW.helper.consoleLog('+ PAGE DISPLAY: ' + (__now - __start) + ' milliseconds', 'color: #6dbb30; font-size: 13px;'); 10861 $.SOW.helper.consoleLog('+ DOM RENDERING:', 'color: #6dbb30; font-size: 13px;'); 10862 10863 if(pagePaint) { 10864 pagePaint.forEach( (performanceEntry, i, entries) => { 10865 $.SOW.helper.consoleLog(' - ' + performanceEntry.name + ' was ' + performanceEntry.startTime + ' milliseconds', 'color: #6dbb30; font-size: 13px;'); 10866 }); 10867 } 10868 10869 $.SOW.helper.consoleLog('+ Depends on user hardware! First load is always expensive, next loads are using the cache! ', 'color: #999999; font-size: 12px;'); 10870 10871 if(pageNav) { 10872 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 10873 $.SOW.helper.consoleLog('+ DNS Lookup time: ' + (pageNav.domainLookupEnd - pageNav.domainLookupStart) + ' seconds', 'color: #6dbb30; font-size: 13px;'); 10874 $.SOW.helper.consoleLog('+ Connection time: ' + (pageNav.connectEnd - pageNav.connectStart) + ' milliseconds', 'color: #6dbb30; font-size: 13px;'); 10875 $.SOW.helper.consoleLog('+ Cache Seek: ' + (pageNav.responseEnd - pageNav.fetchStart) + ' milliseconds', 'color: #6dbb30; font-size: 13px;'); 10876 $.SOW.helper.consoleLog('+ Compression Ratio: ' + (pageNav.decodedBodySize / pageNav.encodedBodySize), 'color: #6dbb30; font-size: 13px;'); 10877 $.SOW.helper.consoleLog('+ Download Time: ' + (pageNav.responseEnd - pageNav.requestStart) + ' milliseconds', 'color: #6dbb30; font-size: 13px;'); 10878 } 10879 10880 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 10881 10882 } 10883 } 10884 10885 } 10886 10887 10888 10889 $(document).ready(function() { 10890 10891 /* 10892 10893 Check if debug is enabled 10894 Should be disabled on production! 10895 10896 */ 10897 if($.SOW.config.sow__debug_enable === true) { 10898 10899 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 10900 $.SOW.helper.consoleLog('+ CONSOLE DEBUG ENABLED : gulp.config.settings.js', 'color: #ff0000; font-size: 13px;'); 10901 $.SOW.helper.consoleLog('+ SOW Controller : ' + _v, 'color: #ff0000; font-size: 13px;'); 10902 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 10903 10904 } 10905 10906 // on load 10907 $.SOW.globals.js_location = $.SOW.helper.jsLocation(); 10908 $.SOW.globals.css_location = $.SOW.helper.cssLocation(); 10909 $.SOW.onresize(); 10910 10911 10912 10913 /* 10914 10915 1. Check for bootstrap 10916 :: Part of bundle file! 10917 vendor_bundle.min.js 10918 10919 */ 10920 if(typeof $().emulateTransitionEnd === 'function') { 10921 $.SOW.reinit(); /* first init ; ajax callable */ 10922 return; 10923 } 10924 10925 10926 10927 /* 10928 10929 1. Bundle not loaded 10930 :: Load it! And init! 10931 vendor_bundle.min.js 10932 10933 */ 10934 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10935 $.SOW.helper.loadScript([$.SOW.globals.js_location + 'vendor_bundle.min.js'], false, true).done(function() { 10936 $.SOW.helper.consoleLog('Vendor Bunde: Dynamically loaded!'); 10937 $.SOW.reinit(); /* first init ; ajax callable */ 10938 }); 10939 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10940 10941 }); 10942 10943 }, 10944 10945 10946 10947 /** 10948 * 10949 * @globals 10950 * SOW Config 10951 * 10952 **/ 10953 globals: { 10954 10955 direction : $('body').css('direction'), /* rtl | ltr */ 10956 width : $(window).width(), /* window width, updated on resize */ 10957 height : $(window).height(), /* window height, updated on resize */ 10958 is_modern_browser : ('querySelector' in document && 'localStorage' in window && 'addEventListener' in window), /* `true` if modern */ 10959 is_mobile : ($(window).width() < 993) ? true : false, 10960 is_admin : $('body').hasClass('layout-admin') ? true : false, 10961 ajax_container : 'body', /* DO NOT USE THIS IN YOUR SCRIPT, IS EXCLUSIVELY USED BY REINIT() FUNCTION */ 10962 page_first_load : true, /* set by reinit() to false after first load - used by ajax */ 10963 js_location : '', /* javascripts location, used to dinamicaly load js scripts */ 10964 css_location : '', /* javascripts location, used to dinamicaly load css */ 10965 cookie_secure : 'SameSite=None; secure', /* New Google Secure Cookie */ 10966 10967 /* bootstrap breakpoints */ 10968 breakpoints : { 10969 'sm': 576, 10970 'md': 768, 10971 'lg': 992, 10972 'xl': 1200 10973 }, 10974 10975 /* 10976 Most used only! 10977 Cache once : Use everywhere 10978 */ 10979 elBody : $('body'), 10980 elHeader : ($('#header').length > 0) ? $('#header') : null, 10981 elAside : ($('#aside-main').length > 0) ? $('#aside-main') : null, 10982 elSideCart : ($('#sidecart').length > 0) ? $('#sidecart') : null, 10983 10984 }, 10985 10986 10987 10988 /** 10989 * 10990 * @core 10991 * SOW Core Plugins 10992 * 10993 **/ 10994 core: {}, 10995 10996 10997 10998 /** 10999 * 11000 * @vendor 11001 * Vendor Plugins [separated by SOW] 11002 * 11003 **/ 11004 vendor: {}, 11005 11006 11007 11008 /** 11009 * 11010 * @helper 11011 * SOW Helpers 11012 * 11013 **/ 11014 helper: {}, 11015 11016 11017 11018 /** 11019 * 11020 * @custom 11021 * My Custom [optional] 11022 * 11023 **/ 11024 custom: {}, 11025 11026 11027 11028 /** 11029 * 11030 * @resize 11031 * Window Resize 11032 * 11033 **/ 11034 onresize: function() { 11035 11036 // On Resize 11037 jQuery(window).resize(function() { 11038 11039 if(window.afterResizeApp) 11040 clearTimeout(window.afterResizeApp); 11041 11042 window.afterResizeApp = setTimeout(function() { 11043 11044 11045 /** Window Width **/ 11046 $.SOW.globals.width = jQuery(window).width(); 11047 11048 /** Window Height **/ 11049 $.SOW.globals.height = jQuery(window).height(); 11050 11051 /** Is Mobile **/ 11052 $.SOW.globals.is_mobile = ($(window).width() < 993) ? true : false;
11053 11054 11055 }, 150); 11056 11057 }); 11058 11059 }, 11060 11061 11062 11063 /** 11064 * 11065 * @reinit 11066 * Ajax Callable 11067 * 11068 **/ 11069 reinit: function(ajax_container) { 11070 11071 /* 11072 For each Ajax call, we temporarily set the ajax container as global 11073 After reinit, we reset back the ajax container as 'body' 11074 */ 11075 $.SOW.globals.ajax_container = $.SOW.helper.check_var(ajax_container) || 'body'; 11076 11077 11078 /** Bootstrap Toasts **/ 11079 $($.SOW.globals.ajax_container + ' .toast').toast('show'); 11080 11081 11082 /** Bootstrap Tooltip **/ 11083 $($.SOW.globals.ajax_container + " [data-toggle=tooltip]," + $.SOW.globals.ajax_container + " [data-tooltip]").tooltip('dispose').tooltip({ 11084 container: ($.SOW.globals.ajax_container == 'body') ? 'html' : $.SOW.globals.ajax_container /* fixing wired positioning! */ 11085 }); 11086 11087 11088 /** Bootstrap Popover **/ 11089 $($.SOW.globals.ajax_container + ' [data-toggle="popover"]').popover({ 11090 container: ($.SOW.globals.ajax_container == 'body') ? 'html' : $.SOW.globals.ajax_container /* fixing wired positioning! */ 11091 }); 11092 11093 11094 /** Bootstrap Carousel **/ 11095 $($.SOW.globals.ajax_container + ' .carousel').carousel('dispose').carousel({ 11096 direction: ($.SOW.globals.direction == 'ltr') ? 'right' : 'left' 11097 }); 11098 11099 /** Bootstrap Scrollspy **/ 11100 $('[data-spy="scroll"]').each(function () { 11101 $(this).scrollspy('refresh'); 11102 }); 11103 11104 11105 11106 /* 11107 11108 Autoinit plugins 11109 Specified in Config 11110 11111 */ 11112 // for (var index = 0; index < $.SOW.config.autoinit.length; ++index) { 11113 for (var index in $.SOW.config.autoinit) { 11114 11115 // Not first page load, skip if plugin do not allow reinit by ajax 11116 if($.SOW.globals.page_first_load === false && $.SOW.config.autoinit[index][3] === false) 11117 continue; 11118 11119 $.SOW.helper.executeFunctionByName( 11120 $.SOW.config.autoinit[index][0], // script 11121 window, 11122 $.SOW.config.autoinit[index][1], // selector 11123 $.SOW.config.autoinit[index][2]); // config 11124 11125 } 11126 11127 11128 /* 11129 11130 Reserved for emergencies! 11131 Called for each ajax container! 11132 11133 global_callback = function(ajax_container) { 11134 ... 11135 } 11136 11137 */ 11138 if(typeof global_callback === 'function') 11139 $.SOW.helper.executeFunctionByName('global_callback', window, $.SOW.globals.ajax_container); 11140 11141 11142 /* 11143 Page classic preloader : first load only! 11144 */ 11145 if($.SOW.globals.page_first_load === true) { 11146 11147 jQuery('#page_preload').fadeOut(1000, function() { 11148 jQuery(this).remove(); 11149 }); 11150 11151 } 11152 11153 // First page load finished! 11154 // Any future reinit() calls are Ajax! 11155 $.SOW.globals.page_first_load = false;
11156 $.SOW.globals.ajax_container = 'body'; // reset 11157 11158 }, 11159 11160 11161 }; 11162 11163 11164 11165 /** 11166 * 11167 * Init this 11168 * 11169 * 11170 **/ 11171 $.SOW.init(); 11172 11173})(jQuery); 11174/** 11175 * 11176 * [SOW] Config 11177 * 11178 **/ 11179;(function ($) { 11180 'use strict'; 11181 11182 $.SOW.config = { 11183 11184 /* 11185 11186 +++++++++++++++++++++++++++++++++ 11187 OVERWRITEN BY GULP : LEAVE IT FALSE! 11188 Browser console global debuger! 11189 +++++++++++++++++++++++++++++++++ 11190 11191 */ 11192 sow__debug_enable : false, 11193 11194 11195 11196 /* 11197 11198 SOW : VARIOUS 11199 ----------------------------------------------------- 11200 11201 */ 11202 /* Icons */ 11203 sow__icon_loading : 'fi fi-circle-spin fi-spin', // ajax loading indicator 11204 sow__icon_check : 'fi fi-check', // 'success' messages or other places 11205 sow__icon_close : 'fi fi-close', // 'failed' messages or other places 11206 11207 }; 11208 11209})(jQuery); 11210/** 11211 * 11212 * [SOW] Helper 11213 * 11214 * @author Dorin Grigoras 11215 * www.stepofweb.com 11216 * 11217 * 11218 * @Dependency - 11219 * 11220 11221 * @check_var 11222 $.SOW.helper.check_var(variable); 11223 * 11224 @check_var 11225 $.SOW.helper.is_numeric(str); 11226 * 11227 @loadScript 11228 $.SOW.helper.loadScript(script_arr, async[true|false], cache[true|false]).done(function() { 11229 // all scripts loaded... do something 11230 // * async = false by default (scripts are loaded in order) 11231 // * cache = true by default 11232 }); 11233 11234 11235 * 11236 @loadCSS 11237 $.SOW.helper.loadCSS("/path/to/file.css", "append|prepend|remove"); "append" is default, if no option passed 11238 * 11239 @loadingSpinner 11240 $.SOW.helper.loadingSpinner('show|hide', "#mycontainer", 'overlay|icon'); 11241 * 11242 @executeFunctionByName 11243 $.SOW.helper.executeFunctionByName("FunctionName", window, arguments); 11244 * 11245 @overlay 11246 $.SOW.helper.overlay('show|hide|toggle'); 11247 * 11248 @randomStr 11249 $.SOW.helper.randomStr(8, ''|L|N); 11250 * 11251 @byte2size 11252 $.SOW.helper.byte2size(bytes, precision=2, int_only=false); 11253 $.SOW.helper.byte2kb(bytes); 11254 * 11255 @scrollAnimate 11256 $.SOW.helper.scrollAnimate(_el, _offset, _hash_change, _speed); 11257 _el = element to scroll to. #top = page top 11258 _offset = top offset (0 default) 11259 _hash_change = update url hash on click 11260 _speed = scroll speed (400 default) 11261 11262 $.SOW.helper.scrollAnimate('#top', 0, false, 400); 11263 * 11264 @removeUrlHash 11265 $.SOW.helper.removeUrlHash('https://domain.com/url#hash'); 11266 * 11267 @playSound 11268 $.SOW.helper.playSound('path/to/audio.mp3'); 11269 * 11270 @time_from_ms 11271 $.SOW.helper.time_from_ms(miliseconds, 's|m|h|d|empty for all'); 11272 * 11273 @get_browser (unfinished, need improvement, do not use) 11274 $.SOW.helper.get_browser(); 11275 * 11276 @params_parse 11277 var params = $.SOW.helper.params_parse('['param','value']['param2','value2']); // return: array 11278 11279 var ajax_params_arr = $.SOW.helper.params_parse(ajax_params); 11280 for (var i = 0; i < ajax_params_arr.length; ++i) { 11281 formDataDel.append(ajax_params_arr[i][0], ajax_params_arr[i][1]); 11282 } 11283 * 11284 @indexedDB (local database) 11285 $.SOW.helper.indexedDB(.. see function ..); 11286 * 11287 @currencyFormat 11288 $.SOW.helper.currencyFormat(1000000); // output: 1,234,567.89 11289 11290 // 1,234,567.89 11291 $.SOW.helper.currencyFormat(1000000, [ 11292 2, ',', '.' // en 11293 // 2, '.', ',' // de 11294 // 2, ' ', ',' // fr 11295 ]); 11296 * 11297 @strhash 11298 $.SOW.helper.strhash('string here'); // create a hash, md5 alternative 11299 * 11300 @videoEmbedFromUrl 11301 $.SOW.helper.videoEmbedFromUrl('https://www.youtube.com?v=jh8Hgd466', autoplay=1); 11302 * 11303 @consoleLog (output - only if debug is enabled!) 11304 $.SOW.helper.consoleLog('Lorem Ipsum', 'color: #ff0000;'); 11305 * 11306 * 11307 **/ 11308;(function ($) { 11309 'use strict'; 11310 11311 11312 /** 11313 * 11314 * @vars 11315 * 11316 * 11317 **/ 11318 var obj = {}; // used by loadScript 11319 11320 11321 $.SOW.helper = { 11322 11323 11324 /** 11325 * 11326 * @config 11327 * 11328 * 11329 **/ 11330 config: {}, 11331 11332 11333 11334 /** 11335 * 11336 * @collection 11337 * 11338 * 11339 **/ 11340 collection: $(), 11341 11342 11343 11344 /** 11345 * 11346 * @init 11347 * 11348 * 11349 **/ 11350 init: function (selector, config) {/** no init required **/}, 11351 11352 11353 11354 11355 /** 11356 * 11357 * @__selector 11358 * DO NOT! DO NOT CHANGE! 11359 * $.SOW.helper.__selector(selector); 11360 * 11361 **/ 11362 __selector: function(selector) { 11363 11364 var selector = $.SOW.helper.check_var(selector) || ''; /* '' is required if null */ 11365 var selector_orig = selector; 11366 var element = (selector && $(selector).length > 0) ? $(selector) : $(); 11367 11368 /* add ajax container - required for binds */ 11369 if($.SOW.globals.ajax_container != 'html' && $.SOW.globals.ajax_container != 'body' && $.SOW.globals.ajax_container != '') { 11370 11371 if (selector.indexOf(',') > -1) 11372 var selector = selector.split(',').join(', ' + $.SOW.globals.ajax_container + ' '); 11373 11374 selector = $.SOW.globals.ajax_container + ' ' + selector; 11375 11376 } 11377 11378 return [selector, element, selector_orig]; // selector_orig = without ajax container, in case is needed 11379 11380 }, 11381 11382 11383 11384 11385 11386 11387 /** 11388 * 11389 * @check_var 11390 * 11391 $.SOW.helper.check_var(variable); 11392 * 11393 **/ 11394 check_var: function(_var) { 11395 11396 return (typeof _var !== "undefined") ? _var : null; 11397 11398 }, 11399 11400 11401 11402 11403 11404 11405 11406 /** 11407 * 11408 * @is_numeric 11409 * 11410 * Welcome to Javascript! 11411 * Please, stay! Is nice in here! 11412 * 11413 $.SOW.helper.is_numeric(_var); 11414 * 1.2 = true ; 1,2 = false 11415 **/ 11416 is_numeric: function(_var) { 11417 11418 if(typeof _var === 'number') 11419 return true; 11420 11421 // at this point, we might have bool/object/function/etc 11422 else if(typeof _var !== 'string') 11423 return false;
11424 11425 // -- -- 11426 11427 var _var = ''+_var.replace(/\s/g, ''); 11428 if(_var === '') 11429 return false; 11430 11431 else if(_var.slice(-1) === '.') 11432 return false; // something like '1.' 11433 11434 // -- -- 11435 11436 return !isNaN(parseFloat(_var)) && isFinite(_var); 11437 11438 }, 11439 11440 11441 11442 11443 11444 11445 11446 /** 11447 * 11448 * @loadScript 11449 * 11450 11451 async false: 11452 loads scripts one-by-one using recursion (ordered) 11453 returns jQuery.Deferred 11454 11455 async true: 11456 loads scripts asynchronized, if order is not needed! 11457 returns jQuery.when 11458 11459 11460 11461 var script_arr = [ 11462 'myscript1.js', 11463 'myscript2.js', 11464 'myscript3.js' 11465 ]; 11466 11467 $.SOW.helper.loadScript(script_arr, async[true|false], cache[true|false]).done(function() { 11468 // all scripts loaded... do something 11469 // * async = false by default (scripts are loaded in order) 11470 // * cache = true by default 11471 }); 11472 11473 * 11474 **/ 11475 loadScript: function(script_arr, async, cache) { 11476 11477 return (async === true) ? $.SOW.helper.__loadScriptAsync(script_arr, cache) : $.SOW.helper.__loadScriptOrdered(script_arr, cache); 11478 11479 }, 11480 11481 /* 11482 11483 Credits (Salman A : stackovweflow user) 11484 https://stackoverflow.com/a/33312665 11485 11486 */ 11487 __loadScriptOrdered: function(script_arr, cache) { 11488 11489 var deferred = jQuery.Deferred(); 11490 11491 function __loadScript(i) { 11492 11493 if (i < script_arr.length) { 11494 11495 jQuery.ajax({ 11496 11497 url: script_arr[i], 11498 dataType: "script", 11499 cache: (cache !== false) ? true : false, 11500 11501 success: function() { 11502 11503 __loadScript(i + 1); 11504 11505 } 11506 11507 }); 11508 11509 } else { 11510 11511 deferred.resolve(); 11512 11513 } 11514 11515 } 11516 11517 __loadScript(0); 11518 return deferred; 11519 11520 }, 11521 11522 /* 11523 11524 Credits (adeneo stackovweflow user) 11525 https://stackoverflow.com/a/11803418 11526 11527 */ 11528 __loadScriptAsync: function(script_arr, cache) { 11529 11530 var _arr = $.map(script_arr, function(scr) { 11531 return (cache !== false) ? $.SOW.helper.getScriptCached( scr ) : $.getScript( scr ); 11532 }); 11533 11534 _arr.push($.Deferred(function( deferred ) { 11535 $( deferred.resolve ); 11536 })); 11537 11538 return $.when.apply($, _arr); 11539 11540 }, 11541 getScriptCached: function(url, options) { 11542 11543 // Allow user to set any option except for dataType, cache, and url 11544 options = $.extend( options || {}, { 11545 dataType: "script", 11546 cache: true, 11547 url: url 11548 }); 11549 11550 // Use $.ajax() since it is more flexible than $.getScript 11551 // Return the jqXHR object so we can chain callbacks 11552 return jQuery.ajax( options ); 11553 11554 }, 11555 11556 11557 11558 11559 /** 11560 * 11561 * @loadCSS 11562 * 11563 $.SOW.helper.loadCSS("/path/to/file.css", "append|prepend|remove"); 11564 "append" is default, if no option passed 11565 * 11566 **/ 11567 loadCSS: function(cssFile, option) { 11568 11569 /* 1. remove */ 11570 if(option === 'remove') 11571 jQuery('head link[href="'+cssFile+'"]').remove(); 11572 11573 11574 /* 2. prepend */ 11575 else if(option === 'prepend') { 11576 if(jQuery('head link[href="'+cssFile+'"]').length > 0) 11577 return; 11578 jQuery('head').prepend('<link rel="stylesheet" href="'+cssFile+'">'); 11579 } 11580 11581 11582 /* 3. append : default */ 11583 else { 11584 11585 if(jQuery('head link[href="'+cssFile+'"]').length > 0) 11586 return; 11587 11588 jQuery('head').append('<link rel="stylesheet" href="'+cssFile+'">'); 11589 } 11590 11591 11592 }, 11593 11594 11595 11596 11597 /** 11598 * 11599 * @loadingSpinner 11600 * 11601 $.SOW.helper.loadingSpinner('show|hide', "#mycontainer", 'overlay|icon'); 11602 * 11603 **/ 11604 loadingSpinner: function(option, _container, _layout) { // layout: overlay|icon 11605 11606 var _container = (_container === null) ? jQuery('body') : jQuery(_container); 11607 var _layout = (typeof _layout !== 'undefined') ? _layout : 'icon'; 11608 11609 if(option === 'show') { 11610 11611 // remove existing and stop 11612 if(jQuery('#js_loading_icon').length > 0) { 11613 jQuery('#js_loading_icon').remove(); 11614 return; 11615 } 11616 11617 // 1. overlay, absolute positioning inside container 11618 var _tpl1 = '<div id="js_loading_icon" class="position-absolute absolute-full overlay-dark overlay-opacity-2 z-index-9999 text-center">' 11619 + '<i class="' + $.SOW.config.sow__icon_loading + ' fs--30 text-muted valign-middle"></i>' 11620 + '</div>'; 11621 11622 // 2. fixed - bottom of the screen, no overlay 11623 var _tpl2 = 11624 '<div id="js_loading_icon" class="position-fixed fixed-bottom w-100 mb-3 z-index-9999 text-center shadow-none">'
11625 + '<span class="bg-white d-inline-block px-4 rounded-lg shadow-lg">' 11626 + '<i class="' + $.SOW.config.sow__icon_loading + ' fs--30 text-muted"></i>' 11627 + '</span>' 11628 + '</div>'; 11629 11630 11631 var _tpl = (_layout == 'overlay') ? _tpl1 : _tpl2; 11632 var _container = (_layout == 'overlay') ? _container : 'body'; // it's fixed, add to body! 11633 11634 11635 // show 11636 if(typeof _container === 'object') { 11637 _container.prepend(_tpl); 11638 } else { 11639 jQuery(_container).prepend(_tpl); 11640 } 11641 11642 11643 } else { 11644 11645 jQuery('#js_loading_icon').remove(); 11646 11647 } 11648 11649 }, 11650 11651 11652 11653 11654 /** 11655 * 11656 * @executeFunctionByName 11657 * 11658 $.SOW.helper.executeFunctionByName("FunctionName", window); 11659 $.SOW.helper.executeFunctionByName("My.Namespace.functionName", window, arguments); 11660 $.SOW.helper.executeFunctionByName("Namespace.functionName", My, arguments); 11661 11662 11663 !WARNING! !NOTE! 11664 11665 Most js code obfuscators might wreck the code as they will change the function names, making the string invalid. 11666 Anyway, all obfuscators will double the size of your code and, of course, will be much slower! 11667 11668 This function is used in two places: 11669 1. init|reinit scripts 11670 2. ajax callbacks 11671 11672 Please do not overuse it! 11673 11674 * 11675 **/ 11676 executeFunctionByName: function(functionName, context /*, args */) { 11677 11678 // return new Promise(resolve => { 11679 11680 if(typeof(window) !== 'undefined') { 11681 11682 // Use the window (from browser) as context if none providen. 11683 context = context || window; 11684 11685 } else { 11686 11687 // If using Node.js, the context will be an empty object 11688 context = context || global; 11689 11690 } 11691 11692 11693 var args = Array.prototype.slice.call(arguments, 2); 11694 var namespaces = functionName.split("."); 11695 var func = namespaces.pop(); 11696 11697 for(var i = 0; i < namespaces.length; i++) { 11698 context = context[namespaces[i]]; 11699 } 11700 11701 11702 return context[func].apply(context, args); 11703 11704 // }); 11705 11706 }, 11707 11708 11709 11710 11711 /** 11712 * 11713 * @overlay 11714 * 11715 $.SOW.helper.overlay('show|hide|toggle'); 11716 * 11717 **/ 11718 overlay: function(option) { 11719 11720 if(option === 'show') { 11721 11722 jQuery('body').append('<div id="overlay-default"></div>'); 11723 jQuery('body').addClass('overflow-hidden'); 11724 11725 } 11726 11727 else if(option === 'hide') { 11728 11729 jQuery('#overlay-default').unbind().remove(); 11730 jQuery('body').removeClass('overflow-hidden'); 11731 11732 } 11733 11734 else { 11735 11736 if(jQuery('#overlay-default').length > 0) { 11737 $.SOW.helper.__overlay_hide(); 11738 } else { 11739 $.SOW.helper.__overlay_show(); 11740 } 11741 11742 } 11743 11744 }, 11745 __overlay_show: function() { 11746 jQuery('body').append('<div id="overlay-default"></div>'); 11747 jQuery('body').addClass('overflow-hidden'); 11748 }, 11749 __overlay_hide: function() { 11750 jQuery('#overlay-default').unbind().remove(); 11751 jQuery('body').removeClass('overflow-hidden'); 11752 }, 11753 11754 11755 11756 11757 /** 11758 * 11759 * @randomStr 11760 * 11761 $.SOW.helper.randomStr(8, ''|L|N); 11762 * 11763 **/ 11764 randomStr: function(length, type) { 11765 11766 switch(type) { 11767 11768 case 'L': 11769 var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 11770 break; 11771 11772 case 'N': 11773 var characters = '0123456789'; 11774 break; 11775 11776 default: 11777 var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 11778 11779 } 11780 11781 var result = ''; 11782 var charactersLength = characters.length; 11783 11784 for ( var i = 0; i < length; i++ ) { 11785 result += characters.charAt(Math.floor(Math.random() * charactersLength)); 11786 } 11787 11788 return result; 11789 11790 }, 11791 11792 11793 /** 11794 * 11795 * @byte2size 11796 * 11797 * $.SOW.helper.byte2size(bytes, precision=2, int_only=false); 11798 * 11799 **/ 11800 byte2size: function(bytes, precision, int_only) { 11801 var precision = typeof precision !== 'undefined' ? precision : 2; 11802 var int_only = typeof int_only !== 'undefined' ? int_only : false;
11803 11804 if(bytes < 1) 11805 return 0 + (int_only === false) ? 'B' : ''; 11806 11807 11808 var k = 1024; 11809 var precision = precision < 0 ? 0 : precision; 11810 var unit = ['B', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb', 'Eb', 'Zb', 'Yb']; 11811 11812 var i = Math.floor(Math.log(bytes) / Math.log(k)); 11813 var unit_txt = (int_only === false) ? ' ' + unit[i] : 0; 11814 return parseFloat((bytes / Math.pow(k, i)).toFixed(precision)) + unit_txt; 11815 11816 }, 11817 11818 11819 11820 11821 /** 11822 * 11823 * @byte2kb 11824 * 11825 * $.SOW.helper.byte2kb(bytes); 11826 * 11827 **/ 11828 byte2kb: function(bytes) { 11829 11830 if(bytes < 1) 11831 return bytes; 11832 11833 var bytes = bytes / 1024; 11834 return (Math.round(bytes * 100) / 100); 11835 11836 }, 11837 11838 11839 11840 11841 11842 /** 11843 * 11844 * @scrollAnimate 11845 * 11846 $.SOW.helper.scrollAnimate(_el, _offset, _hash_change, _speed); 11847 _el = element to scroll to. #top = page top 11848 _offset = top offset (0 default) 11849 _hash_change = update url hash on click 11850 _speed = scroll speed (400 default) 11851 11852 $.SOW.helper.scrollAnimate('#top', 0, false, 400); 11853 * 11854 **/ 11855 scrollAnimate: function(_el, _offset, _hash_change, _speed) { 11856 _el = typeof _el !== 'undefined' ? _el : ''; 11857 _hash_change = typeof _hash_change !== 'undefined' ? _hash_change : 'false'; 11858 _offset = typeof _offset !== 'undefined' ? _offset : 0; 11859 _speed = typeof _speed !== 'undefined' ? _speed : 400; 11860 11861 // Calculate offset if not given! 11862 if(_offset < 1) { 11863 11864 if($.SOW.globals.elBody.hasClass('header-hide')) 11865 _offset = 15; 11866 11867 // .header-fixed is added by js header plugin for all: .header-sticky, .header-scroll-reveal 11868 else if($.SOW.globals.elBody.hasClass('header-fixed') || $.SOW.globals.elBody.hasClass('header-sticky')) 11869 _offset = $.SOW.globals.elHeader.outerHeight() + 15; 11870 11871 } 11872 11873 11874 // Scroll 11875 if(_el != '#' && _el != '#!' && _el != 'javascript:;') { 11876 11877 if(_el == '#top') { 11878 11879 jQuery('html, body').animate({scrollTop: $.SOW.globals.elBody.offset().top}, _speed, function() { 11880 11881 if(_hash_change == 'true') { 11882 window.location.hash = _el; 11883 } 11884 11885 }); 11886 11887 } else { 11888 11889 // unexpected error (should never happen - invalid element)! 11890 if(!jQuery(_el).offset()) return; 11891 11892 jQuery('html, body').animate({scrollTop: jQuery(_el).offset().top - parseInt(_offset)}, _speed, function() { 11893 11894 if(_hash_change == 'true') { 11895 window.location.hash = _el; 11896 } 11897 11898 }); 11899 11900 } 11901 11902 } 11903 11904 }, 11905 11906 11907 11908 /** 11909 * 11910 * @removeUrlHash 11911 * 11912 $.SOW.helper.removeUrlHash('https://domain.com/url#hash'); 11913 * 11914 **/ 11915 removeUrlHash: function(_url){ 11916 11917 if (_url.indexOf('#') > -1) 11918 return _url.replace(/#.*$/, ''); 11919 11920 return _url; 11921 11922 }, 11923 11924 11925 11926 /** 11927 * 11928 * @playSound 11929 * 11930 $.SOW.helper.playSound('path/to/audio.mp3'); 11931 * 11932 **/ 11933 playSound: function(_soundFile) { 11934 11935 var audioElement = document.createElement('audio'); 11936 11937 audioElement.setAttribute('src', _soundFile); 11938 audioElement.setAttribute('autoplay', 'autoplay'); 11939 11940 audioElement.addEventListener("load", function() { 11941 audioElement.play(); 11942 }, true); 11943 11944 }, 11945 11946 11947 11948 11949 11950 /** 11951 * 11952 * @time_from_ms 11953 * 11954 $.SOW.helper.time_from_ms(miliseconds, 's|m|h|d|empty for all'); 11955 * 11956 **/ 11957 time_from_ms: function(miliseconds, format) { 11958 var days, hours, minutes, seconds, total_hours, total_minutes, total_seconds; 11959 11960 total_seconds = parseInt(Math.floor(miliseconds / 1000)); 11961 total_minutes = parseInt(Math.floor(total_seconds / 60)); 11962 total_hours = parseInt(Math.floor(total_minutes / 60)); 11963 days = parseInt(Math.floor(total_hours / 24)); 11964 11965 seconds = parseInt(total_seconds % 60); 11966 minutes = parseInt(total_minutes % 60); 11967 hours = parseInt(total_hours % 24); 11968 11969 switch(format) { 11970 case 's': 11971 return total_seconds; 11972 11973 case 'm': 11974 return total_minutes; 11975 11976 case 'h': 11977 return total_hours; 11978 11979 case 'd': 11980 return days; 11981 11982 default: 11983 return { d: days, h: hours, m: minutes, s: seconds }; 11984 } 11985 11986 }, 11987 11988 11989 11990 /** 11991 * 11992 * @get_browser 11993 * 11994 $.SOW.helper.get_browser(); 11995 * 11996 **/ 11997 get_browser: function() { 11998 11999 var ua = navigator.userAgent.toLowerCase(); 12000 12001 if (ua.indexOf('chrome') > -1) 12002 return 'chrome'; 12003 12004 else if (ua.indexOf('safari') > -1) 12005 return 'safari'; 12006 12007 else if (ua.indexOf('mozilla') > -1) 12008 return 'mozilla'; 12009 12010 else if (ua.indexOf('edge') > -1) 12011 return 'edge'; 12012 12013 else // ie, etc 12014 return 'n/a'; 12015 12016 }, 12017 12018 12019 12020 12021 /** 12022 * 12023 * @params_parse 12024 * 12025 var params = $.SOW.helper.params_parse('['param','value']['param2','value2']); // return: array 12026 * 12027 **/ 12028 params_parse: function(string) { 12029 12030 if(string != '' && string.length > 2) { 12031 12032 // creating a valid json 12033 var string = '[' + string + ']'; // add [] brackets 12034 var string = string.replace(/'/g, '"'); // replace ' with " 12035 var string = string.replace(/ /g, ''); // remove spaces 12036 var string = string.replace(/]\[/g, '],['); // replace: '][' with '],[' 12037 12038 // parse 12039 var string = JSON.parse(string); 12040 12041 } 12042 12043 return string; 12044 12045 }, 12046 12047 12048 12049 12050 /** 12051 * 12052 * @indexedDB 12053 * 12054 https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API 12055 12056 IndexedDB is a low-level API for client-side storage of significant amounts of 12057 structured data, including files/blobs. This API uses indexes to enable 12058 high-performance searches of this data. While Web Storage is useful for storing 12059 smaller amounts of data, it is less useful for storing larger amounts of structured data. 12060 IndexedDB provides a solution. 12061 12062 12063 12064 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12065 :: EVERYTHING IS RETURNED TO A CALLBACK! :: 12066 12067 callbackFn = function(result) { 12068 console.log(result); 12069 } 12070 12071 12072 var _version = 1; 12073 var _database = "smarty_test"; 12074 12075 12076 // 1. Create Database 12077 $.SOW.helper.indexedDB({ // create database (& indexes) 12078 version: _version, 12079 action: 'db:create', 12080 database: _database, 12081 12082 // {} or null 12083 db_options: { keyPath: "item_id", autoIncrement: true }, 12084 12085 // define what data items the objectStore will contain 12086 // [indexName, keyPath, {objectParameters}] 12087 db_indexes: [ 12088 ['title', 'title', { unique: false }], 12089 ['date', 'date', { unique: false }] 12090 ] 12091 }); 12092 12093 // Check if database exists 12094 $.SOW.helper.indexedDB({ // check if database exists 12095 version: _version, 12096 action: 'db:check', 12097 database: _database, 12098 callback: callbackFn 12099 }); 12100 12101 12102 // 2. Add Item 12103 $.SOW.helper.indexedDB({ // add item 12104 version: _version, 12105 action: 'db:add', 12106 database: _database, 12107 callback: callbackFn, 12108 item: { 12109 item_id: 1, 12110 title: 'Lorem ipsum', 12111 date: new Date(), 12112 } 12113 }); 12114 12115 12116 // 3. Update : or insert if not exist 12117 $.SOW.helper.indexedDB({ // update | insert if not exist 12118 version: _version, 12119 action: 'db:update', 12120 database: _database, 12121 callback: callbackFn, 12122 item: { 12123 item_id: 2, 12124 title: 'This is updated!', 12125 date: new Date(), 12126 } 12127 }); 12128 12129 12130 12131 // 4. Delete database 12132 $.SOW.helper.indexedDB({ // delete entire database 12133 version: _version, 12134 action: 'db:delete:database', 12135 database: _database, 12136 }); 12137 12138 12139 $.SOW.helper.indexedDB({ // delete item by keyPath 12140 version: _version, 12141 action: 'db:delete', 12142 database: _database, 12143 keyPath: 1 12144 }); 12145 12146 12147 // 6. Get Items 12148 $.SOW.helper.indexedDB({ // get single item by keyPath 12149 version: _version, 12150 action: 'db:get:keyPath', 12151 database: _database, 12152 keyPath: 1, 12153 callback: callbackFn 12154 }); 12155 12156 $.SOW.helper.indexedDB({ // get all items 12157 version: _version, 12158 action: 'db:get:all', 12159 database: _database, 12160 callback: callbackFn 12161 }); 12162 12163 $.SOW.helper.indexedDB({ // get all item keys 12164 version: _version, 12165 action: 'db:get:allkeys', 12166 database: _database, 12167 callback: callbackFn 12168 }); 12169 12170 $.SOW.helper.indexedDB({ // get item key 12171 version: _version, 12172 action: 'db:get:key', 12173 database: _database, 12174 keyPath: 2, 12175 callback: callbackFn 12176 }); 12177 12178 $.SOW.helper.indexedDB({ // get columns (indexNames) 12179 version: _version, 12180 action: 'db:get:columns', 12181 database: _database, 12182 callback: callbackFn 12183 }); 12184 12185 // 7. Count Items 12186 $.SOW.helper.indexedDB({ // count items 12187 version: _version, 12188 action: 'db:count', 12189 database: _database, 12190 callback: callbackFn 12191 }); 12192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12193 12194 * 12195 **/ 12196 indexedDB: function(_obj) { 12197
12198 if (!('indexedDB' in window)) 12199 window.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; 12200 12201 12202 if(!window.indexedDB) { 12203 $.SOW.helper.consoleLog("[indexedDB] Not supported on this browser!"); 12204 return; 12205 } 12206 12207 // -- 12208 var version = _obj.version || 1; 12209 var action = _obj.action; 12210 var database = _obj.database; 12211 var key = _obj.key || _obj.db_options || _obj.item || _obj.keyPath; 12212 var callback = _obj.callback || _obj.db_indexes; 12213 // -- 12214 var req = window.indexedDB.open(database, version); 12215 var smarty = {}; 12216 var data = ''; 12217 12218 smarty.onerror = function(e) { 12219 console.log("[indexedDB] Database error: ", e.target.errorCode); 12220 }; 12221 12222 12223 req.onupgradeneeded = function(e) { 12224 smarty.db = e.target.result || e.result || this.result; 12225 12226 if(action !== 'db:create') 12227 return; 12228 12229 if(smarty.db.objectStoreNames.contains(database)) 12230 smarty.db.deleteObjectStore(database); 12231 12232 // Create an objectStore for this database 12233 // example: smarty.db.createObjectStore('database', {keyPath: "item_id", autoIncrement: true}); 12234 var objectStore = smarty.db.createObjectStore(database, key || {}); 12235 12236 // define what data items the objectStore will contain 12237 // callback is used as "columns" 12238 for(var i=0;i<callback.length;++i) { 12239 var column = callback[i]; 12240 objectStore.createIndex(column[0], column[1], column[2]); 12241 } 12242 12243 $.SOW.helper.consoleLog('[indexedDB] Table ' + database + ' created!'); 12244 12245 }; req.onerror = smarty.onerror; 12246 12247 12248 req.onsuccess = function(e) { 12249 12250 if(action === 'db:create') 12251 return; 12252 12253 12254 smarty.db = e.target.result || e.result || this.result; 12255 12256 var db_action = (action === 'db:add' || action === 'db:update' || action === 'db:delete' || action == 'db:delete:database') ? 'readwrite' : 'readonly'; 12257 12258 var transaction = smarty.db.transaction([database], db_action); 12259 transaction.oncomplete = function(event) {}; 12260 transaction.onerror = function(event) {}; 12261 var table = transaction.objectStore(database); 12262 12263 if(action === 'db:add') 12264 table.add(key); 12265 12266 else if(action === 'db:update') 12267 table.put(key); 12268 12269 else if(action === 'db:delete') 12270 table.delete(key); 12271 12272 else if(action === 'db:delete:database') 12273 table.clear(); 12274 12275 else if(action === 'db:get:keyPath') { 12276 12277 var get = table.get(key); 12278 12279 get.onsuccess = () => { 12280 callback(get.result); 12281 }; 12282 12283 } 12284 12285 else if(action === 'db:get:all') { 12286 12287 var get = table.getAll(key || null); // key = query, count 12288 12289 get.onsuccess = () => { 12290 callback(get.result); 12291 }; 12292 12293 } 12294 12295 else if(action === 'db:get:allkeys') { 12296 12297 var get = table.getAllKeys(key || null); // key = query, count 12298 12299 get.onsuccess = () => { 12300 callback(get.result); 12301 }; 12302 12303 } 12304 12305 else if(action === 'db:get:key') { 12306 12307 var get = table.getKey(key); 12308 12309 get.onsuccess = () => { 12310 callback(get.result); 12311 }; 12312 12313 } 12314 12315 else if(action === 'db:get:columns') { 12316 12317 var result = table.indexNames; 12318 callback(result); 12319 12320 } 12321 12322 else if(action === 'db:count') { 12323 12324 var get = table.count(); 12325 12326 get.onsuccess = () => { 12327 callback(get.result); 12328 }; 12329 12330 12331 } 12332 12333 12334 else if(action === 'db:check') { 12335 12336 var _exists = (smarty.db.objectStoreNames.contains(database)) ? true : false; 12337 callback(_exists); 12338 12339 } 12340 12341 12342 // smarty.db.close(); 12343 12344 }; req.onerror = smarty.onerror; 12345 12346 12347 }, 12348 12349 12350 12351 12352 /** 12353 * 12354 * @currencyFormat 12355 * 12356 $.SOW.helper.currencyFormat(1000000); // output: 1,234,567.89 12357 12358 // 1,234,567.89 12359 $.SOW.helper.currencyFormat(1000000, [ 12360 2, ',', '.' // en 12361 // 2, '.', ',' // de 12362 // 2, ' ', ',' // fr 12363 ]); 12364 12365 * 12366 **/ 12367 currencyFormat: function(amount, custom) { 12368 12369 if(typeof custom !== 'object') 12370 var custom = [ 12371 // 2, ',', '.' // en 12372 2, '.', ',' // de 12373 // 2, ' ', ',' // fr 12374 ]; 12375 12376 return ( amount.toFixed(custom[0]) 12377 .replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1:repl:') 12378 .replace('.', custom[2]) 12379 .replace(/:repl:/g, custom[1]) 12380 ); 12381 12382 }, 12383 12384 12385 12386 12387 /** 12388 * 12389 * @jsLocation 12390 * 12391 $.SOW.helper.jsLocation(); // output: javascript location 12392 * 12393 **/ 12394 jsLocation: function() { 12395 12396 var currentScript; 12397 var scripts = document.querySelectorAll('script[src]'); 12398 12399 for(var s = 0; s < scripts.length; s++) { 12400 12401 if(scripts[s].src.indexOf('core') !== -1) { 12402 var currentScript = scripts[s].src; 12403 break; 12404 } 12405 12406 else if(scripts[s].src.indexOf('bundle') !== -1) { 12407 var currentScript = scripts[s].src; 12408 break; 12409 } 12410 12411 else if(scripts[s].src.indexOf('vendor') !== -1) { 12412 var currentScript = scripts[s].src; 12413 break; 12414 } 12415 12416 } 12417 12418 // nothing we want found! get the last script! 12419 if(!currentScript) 12420 currentScript = scripts[scripts.length-1].src; 12421 12422 if(!currentScript) 12423 currentScript = 'assets/js/'; 12424 12425 var currentScriptChunks = currentScript.split('/'); 12426 var currentScriptFile = currentScriptChunks[currentScriptChunks.length - 1]; 12427 var scriptPath = currentScript.replace(currentScriptFile, ''); 12428 12429 return scriptPath; 12430 12431 }, 12432 12433 12434 12435 12436 /** 12437 * 12438 * @cssLocation 12439 * 12440 $.SOW.helper.cssLocation(); // output: css location 12441 * 12442 **/ 12443 cssLocation: function() { 12444 12445 var currentScript; 12446 var scripts = document.querySelectorAll('link[rel=stylesheet]'); 12447 12448 for(var s = 0; s < scripts.length; s++) { 12449 12450 if(scripts[s].href.indexOf('core') !== -1) { 12451 var currentScript = scripts[s].href; 12452 break; 12453 } 12454 12455 else if(scripts[s].href.indexOf('bundle') !== -1) { 12456 var currentScript = scripts[s].href; 12457 break; 12458 } 12459 12460 else if(scripts[s].href.indexOf('vendor') !== -1) { 12461 var currentScript = scripts[s].href; 12462 break; 12463 } 12464 12465 } 12466 12467 // nothing we want found! get the last script! 12468 if(!currentScript) 12469 currentScript = scripts[scripts.length-1].href; 12470 12471 if(!currentScript) 12472 currentScript = 'assets/css/'; 12473 12474 var currentScriptChunks = currentScript.split('/'); 12475 var currentScriptFile = currentScriptChunks[currentScriptChunks.length - 1]; 12476 var scriptPath = currentScript.replace(currentScriptFile, ''); 12477 12478 return scriptPath; 12479 12480 }, 12481 12482 12483 12484 12485 /** 12486 * 12487 * @vendorLogic 12488 * 12489 $.SOW.helper.vendorLogicPaths('fullcalendar'); // output:array 12490
12491 Get vendor logics: js & css paths 12492 FOR EXTERNAL SCRIPTS LOAD! 12493 * 12494 **/ 12495 vendorLogicPaths: function(vendor) { 12496 12497 if(!vendor) 12498 return arr; 12499 12500 var js_location = ($.SOW.globals.js_location != '') ? $.SOW.globals.js_location : $.SOW.helper.jsLocation(); 12501 var css_location = ($.SOW.globals.js_location != '') ? $.SOW.globals.css_location : $.SOW.helper.cssLocation(); 12502 var arr = []; 12503 arr['path_js'] = ''; 12504 arr['path_css'] = ''; 12505 12506 12507 12508 12509 /* CSS FILE */ 12510 if($.SOW.config["vendor:external_css"]) { 12511 12512 for (var module in $.SOW.config["vendor:external_css"]) { 12513 12514 for(var v = 0; v < $.SOW.config["vendor:external_css"][module].length; v++) { 12515 12516 if($.SOW.config["vendor:external_css"][module].includes(vendor) === true) { 12517 12518 arr['path_css'] = css_location+module+'.'+vendor+'.min.css'; 12519 12520 // apply here, else swiper and other plugins has issues : is css loaded after js 12521 $.SOW.helper.loadCSS(arr['path_css']); 12522 break; 12523 } 12524 12525 } 12526 12527 } 12528 12529 } 12530 12531 12532 12533 /* JS FILE */ 12534 if($.SOW.config["vendor:external_js"]) { 12535 12536 for (var module in $.SOW.config["vendor:external_js"]) { 12537 12538 for(var v = 0; v < $.SOW.config["vendor:external_js"][module].length; v++) { 12539 12540 if($.SOW.config["vendor:external_js"][module].includes(vendor) === true) { 12541 arr['path_js'] = js_location+module+'.'+vendor+'.min.js'; 12542 break; 12543 } 12544 12545 } 12546 12547 } 12548 12549 } 12550 12551 return arr; 12552 }, 12553 12554 12555 12556 12557 12558 /** 12559 * 12560 * @videoEmbedFromUrl 12561 $.SOW.helper.videoEmbedFromUrl('https://www.youtube.com?v=jh8Hgd466', autoplay=1); 12562 * 12563 **/ 12564 videoEmbedFromUrl: function(href, autoplay) { 12565 12566 12567 // Localvideo first! 12568 if( href.match(/(.mp4)/) || href.match(/(.webm)/) ) { 12569 12570 var mp4 = href.replace('.webm', '.mp4'); 12571 var webm = href.replace('.mp4', '.webm'); 12572 var jpg = href.replace('.mp4', '.jpg').replace('.webm', '.jpg'); 12573 var auto = (!autoplay) ? null : 'autoplay'; 12574 12575 // Local Video 12576 return '<div class="embed-responsive embed-responsive-16by9">' 12577 + '<video preload="auto" '+auto+' controls="controls" poster="'+jpg+'">' 12578 + '<source src="'+webm+'" type="video/webm;">' 12579 + '<source src="'+webm+'" type="video/mp4;">' 12580 + '</video>' 12581 + '</div>'; 12582 12583 }; 12584 12585 // :: default 12586 var videoEmbedLink = null; 12587 12588 12589 // :: youtube 12590 if(videoEmbedLink === null) { 12591 var youtubeMatch = href.match(/(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i); 12592 var videoEmbedLink = (youtubeMatch) ? "https://www.youtube.com/embed/"+youtubeMatch[4]+"?autoplay=" + autoplay || 1 + '' : null; 12593 } 12594 12595 // :: vimeo 12596 if(videoEmbedLink === null) { 12597 var vimeoMatch = href.match(/^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/); 12598 var videoEmbedLink = (vimeoMatch) ? "https://player.vimeo.com/video/"+vimeoMatch[2]+"?autoplay=" + autoplay || 1 + '' : null; 12599 } 12600 12601 12602 // Err! 12603 if(!videoEmbedLink) 12604 return null; 12605 12606 // -- -- 12607 12608 // Construct Embed! 12609 return '<div class="embed-responsive embed-responsive-16by9">' 12610 + '<iframe class="embed-responsive-item" src="' + videoEmbedLink + '" allow="autoplay; encrypted-media" width="560" height="315"></iframe>' 12611 + '</div>'; 12612 12613 }, 12614 12615 12616 12617 12618 /** 12619 * 12620 * @strhash 12621 * author: Sergey.Shuchkin 12622 * https://stackoverflow.com/questions/6122571/simple-non-secure-hash-function-for-javascript 12623 * 12624 $.SOW.helper.strhash('string here'); 12625 * 12626 **/ 12627 strhash: function( str ) { 12628 if (str.length % 32 > 0) str += Array(33 - str.length % 32).join("z"); 12629 12630 var hash = '', bytes = []; 12631 var i, j, k, a; i = j = k = a = 0;
12632 var dict = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','1','2','3','4','5','6','7','8','9']; 12633 12634 for (i = 0; i < str.length; i++ ) { 12635 var ch = str.charCodeAt(i); 12636 bytes[j++] = (ch < 127) ? ch & 0xFF : 127; 12637 } 12638 12639 var chunk_len = Math.ceil(bytes.length / 32); 12640 12641 for (i=0; i<bytes.length; i++) { 12642 j += bytes[i]; k++; 12643 12644 if ((k == chunk_len) || (i == bytes.length-1)) { 12645 var a = Math.floor( j / k ); 12646 12647 if (a < 32) hash += '0'; 12648 else if (a > 126) hash += 'z'; 12649 else hash += dict[ Math.floor( (a-32) / 2.76) ]; 12650 12651 var j = k = 0; 12652 } 12653 12654 } 12655 12656 return hash; 12657 }, 12658 12659 12660 12661 12662 /** 12663 * 12664 * @consoleLog 12665 * 12666 $.SOW.helper.consoleLog('%cLorem Ipsum', 'color: #ff0000;'); 12667 * 12668 **/ 12669 consoleLog: function(data, css) { 12670 12671 if($.SOW.config.sow__debug_enable !== true) 12672 return; 12673 12674 12675 // Console css 12676 if(typeof css !== "undefined" && typeof css !== 'object') { 12677 var data = '%c' + data; 12678 12679 console.log(data, css); 12680 return; 12681 } 12682 12683 else if(typeof css === 'object') { 12684 console.log(data, css); 12685 return; 12686 } 12687 12688 console.log(data); 12689 } 12690 12691 }; 12692})(jQuery); 12693/** 12694 * 12695 * [SOW] Header 12696 * 12697 * @author Dorin Grigoras 12698 * www.stepofweb.com 12699 * 12700 * @Dependency - 12701 * @Usage $.SOW.core.header.init(); 12702 * 12703 * 12704 **/ 12705;(function ($) { 12706 'use strict'; 12707 12708 12709 /** 12710 * 12711 * @vars 12712 * 12713 * 12714 **/ 12715 var scriptInfo = 'SOW Header'; 12716 12717 window._headerID = '#header'; 12718 window.lastScrollTop = 0; 12719 12720 12721 12722 $.SOW.core.header = { 12723 12724 12725 /** 12726 * 12727 * @config 12728 * 12729 * 12730 **/ 12731 config: {}, 12732 12733 12734 12735 /** 12736 * 12737 * @collection 12738 * 12739 * 12740 **/ 12741 collection: $(), 12742 12743 12744 12745 /** 12746 * 12747 * @init 12748 * 12749 * 12750 **/ 12751 init: function (selector, config) { 12752 12753 12754 if(!$.SOW.globals.elHeader) 12755 return; 12756 12757 12758 /** 12759 1. HEADER : STICKY/FIXED 12760 **/ 12761 if($.SOW.globals.elBody.hasClass('header-sticky')) 12762 $.SOW.core.header.header_sticky(); 12763 12764 12765 /** 12766 2. HEADER : REVEAL ON SCROLL 12767 **/ 12768 else if($.SOW.globals.elBody.hasClass('header-scroll-reveal')) 12769 $.SOW.core.header.header_scroll_reveal(); 12770 12771 12772 /** 12773 3. HEADER & ASIDE : HORIZONTAL NAVIGATION 12774 **/ $.SOW.core.header.horizontal_nav(); 12775 12776 12777 /** 12778 4. HEADER TOGGLE 12779 **/ $.SOW.core.header.header_toggle(); 12780 12781 12782 /** 12783 5. HEADER SCROLLTO : NAVBAR CLOSE 12784 **/ $.SOW.core.header.header_onepagenav(); 12785 12786 12787 // -- * -- 12788 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 12789 // -- * -- 12790 12791 12792 }, 12793 12794 12795 12796 12797 /** 12798 * 12799 * 1. HEADER : STICKY/FIXED 12800 * 12801 * 12802 **/ 12803 header_sticky: function() { 12804 12805 12806 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12807 // Oct. 08. 2019 12808 // EVERYTHING REPLCACED WITH FLEX & CSS position: sticky; 12809 // Not fully supported (IE, etc) but is ok for admin! 12810 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12811 // [v3.0.0] Stop on admin! 12812 // Curently not used! 12813 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12814 if($.SOW.globals.elBody.hasClass('layout-admin')) 12815 return; 12816 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12817 12818 if($.SOW.globals.elHeader.length < 1) 12819 return; 12820 12821 var _headerEl_H = $.SOW.globals.elHeader.outerHeight() || 0, 12822 _diff = 0; 12823 12824 12825 if($.SOW.globals.elBody.hasClass('layout-boxed')) 12826 _diff = _headerEl_H / 2 || 0; 12827 12828 /* 12829 12830 1. add header spacing 12831 2. add header-fixed class 12832 12833 */ $.SOW.globals.elBody.addClass('header-fixed'); 12834 12835 12836 // admin : padding top instead of spacer 12837 if($.SOW.globals.elBody.hasClass('layout-admin aside-sticky')) { 12838 12839 jQuery('#middle').css({"padding-top":_headerEl_H + _diff + parseInt(jQuery('#middle').css('padding-top'))}); 12840 12841 } else { 12842 12843 jQuery('#js_header_spacer').remove(); 12844 jQuery('#wrapper>'+window._headerID+', body>'+window._headerID).after('<div id="js_header_spacer"><!-- spacer added by header js --></div>'); 12845 jQuery('#js_header_spacer').css({"margin-top":_headerEl_H + _diff}); 12846 12847 } 12848 12849 12850 // -- -- -- -- 12851 12852 12853 12854 12855 12856 /* 12857 12858 .header-sticky + .header-over 12859 all what we do here is to apply body.user-scrolled-down if user scolled down 12860 so we can apply a CSS background-color to the header (else, will be buggy - transparent header on scroll down) 12861 12862 */ 12863 if($.SOW.globals.elBody.hasClass('header-over') && jQuery(this).scrollTop() > 0) 12864 $.SOW.globals.elBody.addClass('user-scrolled-down'); 12865 12866 12867 // stop! no need for scroll assist! 12868 if(!$.SOW.globals.elBody.hasClass('header-over') && jQuery('#top_bar').length < 1) 12869 return; 12870 12871 12872 12873 12874 12875 12876 12877 /* 12878
12879 1. on scroll down - hide #top_bar to make little more space (and show on scroll up) 12880 2. add|remove .user-scrolled-down - used together with .header-over 12881 12882 */ 12883 var 12884 top_bar_present = jQuery('#top_bar').length, 12885 top_bar_height = (top_bar_present > 0) ? jQuery('#top_bar').outerHeight() : 0, 12886 top_bar_js_ignore = false, 12887 delta = 5, 12888 didScroll; 12889 12890 jQuery(window).scroll(function(event) { 12891 didScroll = true; 12892 }); 12893 12894 12895 // check for js ignore (if true, do not hide #top_bar on scroll) 12896 if(top_bar_present > 0) { 12897 if(jQuery('#top_bar').hasClass('js-ignore')) 12898 var top_bar_js_ignore = true; 12899 } 12900 12901 12902 setInterval(function() { 12903 if(didScroll) { 12904 $.SOW.core.header.header_sticky__hasScrolled(_headerEl_H, delta, top_bar_present, top_bar_height, top_bar_js_ignore); 12905 didScroll = false; 12906 } 12907 }, 100); 12908 12909 12910 12911 // On first load! 12912 $.SOW.core.header.header_sticky__hasScrolled(_headerEl_H, delta, top_bar_present, top_bar_height, top_bar_js_ignore); 12913 // -- -- -- -- -- 12914 12915 }, 12916 header_sticky__hasScrolled: function(_headerEl_H, delta, top_bar_present, top_bar_height, top_bar_js_ignore) { 12917 var st = document.scrollingElement.scrollTop; 12918 12919 // ADD distinct class - used by transparent header 12920 if(st < 1) { 12921 $.SOW.globals.elBody.removeClass('user-scrolled-down'); 12922 } else { 12923 $.SOW.globals.elBody.addClass('user-scrolled-down'); 12924 } 12925 12926 12927 if(top_bar_present > 0 && top_bar_js_ignore === false) { 12928 12929 // Make sure they scroll more than delta 12930 if(Math.abs(window.lastScrollTop - st) <= delta) 12931 return; 12932 12933 12934 if(st > window.lastScrollTop && st > _headerEl_H){ 12935 12936 // Scroll Down 12937 $.SOW.globals.elHeader.css({"margin-top":"-"+top_bar_height+"px"}); 12938 12939 } else { 12940 12941 // Scroll Up 12942 if(st + jQuery(window).height() < jQuery(document).height()) { 12943 $.SOW.globals.elHeader.css({"margin-top":""}); 12944 } 12945 12946 } 12947 12948 window.lastScrollTop = st; 12949 12950 } 12951 12952 }, 12953 12954 12955 12956 12957 12958 /** 12959 * 12960 * 2. HEADER : REVEAL ON SCROLL 12961 * 12962 * 12963 **/ 12964 header_scroll_reveal: function() { 12965 12966 /** HEADER : REVEAL 12967 1. Hide Header on on scroll down 12968 2. Show Header on on scroll up 12969 ** ************************************/ 12970 if($.SOW.globals.elHeader.length > 0) { 12971 12972 var _headerEl_H = $.SOW.globals.elHeader.outerHeight() || 0, 12973 _diff = 0, 12974 lastScrollTop = 0, 12975 delta = 5, 12976 didScroll; 12977 12978 12979 if($.SOW.globals.elBody.hasClass('layout-boxed')) 12980 _diff = _headerEl_H / 2 || 0; 12981 12982 /* 12983 12984 1. add header spacing 12985 2. add header-fixed class 12986 12987 */ 12988 12989 jQuery('#js_header_spacer').remove(); 12990 jQuery('#wrapper>'+window._headerID+', body>'+window._headerID).after('<div id="js_header_spacer"><!-- spacer added by header js --></div>'); 12991 jQuery('#js_header_spacer').css({"margin-top":_headerEl_H + _diff}); 12992 12993 $.SOW.globals.elBody.addClass('header-fixed'); 12994 jQuery('body>'+window._headerID).addClass('header-fixed'); 12995 12996 // on load : according to .header-over 12997 if($.SOW.globals.elBody.hasClass('header-over') && jQuery(this).scrollTop() > 0) { 12998 $.SOW.globals.elBody.addClass('user-scrolled-down'); 12999 jQuery(window._headerID).addClass('header-down'); 13000 lastScrollTop = jQuery(this).scrollTop(); // avoid jumping 13001 } else { 13002 $.SOW.globals.elBody.addClass('header-is-on-top'); 13003 } 13004 13005 // -- -- -- -- 13006 13007 13008 jQuery(window).scroll(function(event) { 13009 didScroll = true; 13010 }); 13011 13012 setInterval(function() { 13013 if(didScroll) { 13014 $.SOW.core.header.header_scroll_reveal__hasScrolled(_headerEl_H, delta); 13015 didScroll = false; 13016 } 13017 }, 100); 13018 13019 } 13020 13021 }, 13022 13023 header_scroll_reveal__hasScrolled: function(_headerEl_H, delta) { 13024 var st = document.scrollingElement.scrollTop; 13025 13026 // ADD distinct class - used by transparent header 13027 if(st < 1) { 13028 $.SOW.globals.elBody.addClass('header-is-on-top').removeClass('user-scrolled-down'); 13029 } else { 13030 $.SOW.globals.elBody.addClass('user-scrolled-down'); 13031 } 13032 13033 // Make sure they scroll more than delta 13034 if(Math.abs(window.lastScrollTop - st) <= delta) 13035 return; 13036 13037 if(st > window.lastScrollTop && st > _headerEl_H){ 13038 13039 // Scroll Down 13040 $.SOW.globals.elHeader.removeClass('header-down').addClass('header-up'); 13041 $.SOW.globals.elBody.removeClass('header-is-on-top'); 13042 13043 } else { 13044 13045 // Scroll Up 13046 if(st + jQuery(window).height() < jQuery(document).height()) { 13047 $.SOW.globals.elHeader.removeClass('header-up').addClass('header-down'); 13048 } 13049 13050 } 13051 13052 window.lastScrollTop = st; 13053 }, 13054 13055 13056 /** 13057 * 13058 * 3. HEADER & ASIDE : HORIZONTAL NAVIGATION 13059 * 13060 * 13061 **/ 13062 horizontal_nav: function() { 13063 13064 13065 if(jQuery("nav.horizontal-nav").length < 1) 13066 return; 13067 13068 13069 13070 // CONTENT MAIN MENU 13071 if(jQuery("section nav.horizontal-nav").length > 0) { 13072 13073 var _diffWidth = (jQuery("section .container").width() - jQuery('section nav.horizontal-nav').width()), 13074 _navHeight = jQuery("section nav.horizontal-nav").height(); 13075 13076 // Submenu widh & height 13077 jQuery("section nav.horizontal-nav>div>ul>li.main-nav-expanded>.main-nav-submenu").css({"width":_diffWidth+"px"}); 13078 //jQuery("section nav.horizontal-nav>div>ul>li>.main-nav-submenu").css({"min-height":_navHeight+"px"}); 13079 13080 // SUBMENUS 13081 jQuery("section nav.horizontal-nav>div>ul>li").on("click", function(e) { 13082 var _this = jQuery(this); 13083 13084 if(!jQuery('div', _this).hasClass('main-nav-open')) { 13085 jQuery("section nav.horizontal-nav>div>ul>li>.main-nav-submenu").removeClass('main-nav-open'); 13086 } 13087 13088 jQuery('div', _this).toggleClass('main-nav-open'); 13089 }); 13090 13091 } 13092 13093 13094 13095 13096 13097 13098 // HEADER MAIN MENU 13099 var _hdiffWidth = jQuery(window._headerID+" .container").width() - 278, 13100 _hdiffHeight = jQuery(window._headerID+" nav.horizontal-nav").height(); 13101 13102 // Submenu widh & height 13103 jQuery(window._headerID+" nav.horizontal-nav>div>ul>li>.main-nav-submenu").css({"min-height":_hdiffHeight+"px"}); 13104 jQuery(window._headerID+" nav.horizontal-nav>div>ul>li.main-nav-expanded>
13104.main-nav-submenu").css({"width":_hdiffWidth+"px"}); 13105 13106 // SUBMENUS 13107 jQuery(window._headerID+" nav.horizontal-nav>div>ul>li").on("click", function(e) { 13108 var _this = jQuery(this); 13109 13110 if(!jQuery('div', _this).hasClass('main-nav-open')) { 13111 jQuery(window._headerID+" nav.horizontal-nav>div>ul>li>.main-nav-submenu").removeClass('main-nav-open'); 13112 } 13113 13114 jQuery('div', _this).toggleClass('main-nav-open'); 13115 }); 13116 13117 13118 13119 // HEADER MAIN MENU 13120 if(window.width > 960) { // desktop|tablet 13121 13122 jQuery("button.main-nav-horizontal").mouseover(function(e) { 13123 e.preventDefault(); 13124 13125 $.SOW.core.header._initMainNav(); 13126 13127 }); 13128 13129 13130 } else { // mobile 13131 13132 jQuery("button.main-nav-horizontal").on("click", function(e) { 13133 e.preventDefault(); 13134 13135 $.SOW.core.header._initMainNav(); 13136 13137 }); 13138 13139 } 13140 13141 $.SOW.globals.elBody.on('click', 'button.main-nav-horizontal, nav.horizontal-nav', function (e) { 13142 e.stopPropagation(); 13143 }); 13144 13145 jQuery("button.main-nav-horizontal, "+window._headerID+" nav.horizontal-nav").mouseover(function(e) { 13146 e.stopPropagation(); 13147 }); 13148 13149 13150 jQuery(document).on("click", function() { 13151 13152 $.SOW.core.header._hideMainNav(); 13153 13154 }); 13155 13156 13157 13158 // Menu Click 13159 jQuery("nav.horizontal-nav>div>ul>li a").on("click", function(e) { 13160 var _href = jQuery(this).attr('href'); 13161 13162 if(_href == '#') { 13163 e.preventDefault(); 13164 } 13165 }); 13166 }, 13167 13168 _initMainNav: function() { 13169 13170 // remove overlay first, no matter what 13171 jQuery("#main-nav-overlay").remove(); 13172 13173 // open menu 13174 jQuery(window._headerID+" nav.horizontal-nav").addClass('min-nav-active'); 13175 13176 // add overlay 13177 $.SOW.globals.elBody.append('<div id="main-nav-overlay"></div>'); 13178 13179 13180 // Mobile menu open|close on click 13181 jQuery('button.nav-toggle-close').on("click", function() { 13182 jQuery("nav.horizontal-nav").removeClass('min-nav-active'); 13183 }); 13184 13185 // Close menu on hover 13186 jQuery("#main-nav-overlay, "+window._headerID).mouseover(function() { 13187 13188 $.SOW.core.header._hideMainNav(); 13189 13190 }); 13191 13192 }, 13193 13194 _hideMainNav: function() { 13195 jQuery("#main-nav-overlay").remove(); 13196 jQuery("nav.horizontal-nav").removeClass('min-nav-active'); 13197 }, 13198 13199 13200 13201 13202 13203 /** 13204 * 13205 * 4. HEADER TOGGLE 13206 * 13207 * 13208 **/ 13209 header_toggle: function() { 13210 13211 jQuery('.btn-header-toggle').on('click', function(e) { 13212 e.preventDefault(); 13213 13214 var is_hidden = $.SOW.globals.elBody.hasClass('header-hide') ? true : false, 13215 has_spacer = jQuery('#js_header_spacer').length > 0 ? true : false, 13216 _headerEl_H = $.SOW.globals.elHeader.outerHeight() || 0, 13217 _addEl = ''; 13218 13219 // no header present? 13220 if(_headerEl_H < 1) 13221 return; 13222 13223 13224 // Add animation class to content 13225 if(has_spacer === true) { 13226 jQuery('#wrapper_content').addClass('js-animation-enable'); 13227 _addEl = ', #wrapper_content'; 13228 } 13229 13230 13231 // Add animation class! 13232 jQuery('#header'+_addEl).addClass('transition-all-ease-250'); 13233 13234 13235 if(is_hidden === false) { 13236 13237 jQuery('#header'+_addEl).animate({ 'margin-top': -_headerEl_H+"px" }, 50, function(e) { 13238 $.SOW.globals.elBody.addClass('header-hide'); 13239 13240 /* 13241 show toggle button with a delay to avoid spacing 13242 issues (because of fixed position) + nice effect with css 13243 */ 13244 setTimeout(function() { 13245 13246 $.SOW.globals.elBody.addClass('btn-header-toggle-show'); 13247 13248 }, 600); 13249 13250 }); 13251 13252 } else { 13253 13254 jQuery('#header'+_addEl).animate({ 'margin-top': "0" }, 0, function(e) { 13255 $.SOW.globals.elBody.removeClass('header-hide btn-header-toggle-show'); 13256 13257 // Remove animation class 13258 if(has_spacer === true) { 13259 setTimeout(function() { 13260 13261 jQuery('#wrapper_content').removeClass('js-animation-enable'); 13262 13263 }, 600); 13264 } 13265 13266 }); 13267 } 13268 13269 13270 }); 13271 13272 }, 13273 13274 13275 13276 /** 13277 * 13278 * 5. HEADER SCROLLTO : NAVBAR CLOSE 13279 * 13280 * 13281 **/ 13282 header_onepagenav: function() { 13283 13284 jQuery('.navbar-collapse').each(function() { 13285 13286 var _t = jQuery(this); 13287 13288 jQuery('.nav-item>.nav-link.scroll-to, .nav-item>.nav-link.js-ajax, .dropdown-item>.dropdown-link.js-ajax', _t).on('click',function() { 13289 13290 if($.SOW.globals.is_mobile === true) 13291 _t.collapse('hide'); 13292 13293 }); 13294 13295 }); 13296 13297 }, 13298 13299 13300 13301 13302 13303 13304 /** 13305 * 13306 * DESTROY / RESET (sticky/reveal) 13307 * 13308 * 13309 **/ 13310 header_destroy: function() { 13311 13312 $.SOW.globals.elHeader.removeClass('header-down header-up'); 13313 $.SOW.globals.elBody.removeClass('header-hide header-over header-fixed header-is-on-top user-scrolled-down'); 13314 $.SOW.globals.elHeader.css({"margin-top":""}); 13315 jQuery('#top_bar').removeClass('hide-by-scroll'); 13316 jQuery('#js_header_spacer').remove(); 13317 jQuery(window).off("scroll"); 13318 13319 } 13320 13321 }; 13322 13323 13324})(jQuery); 13325/** 13326 * 13327 * [SOW] Search Suggest 13328 * 13329 * @author Dorin Grigoras 13330 * www.stepofweb.com 13331 * 13332 * @Dependency - 13333 * @Usage $.SOW.core.search_suggest.init('form.js-ajax-search'); 13334 * 13335 * 13336 **/ 13337;(function ($) { 13338 'use strict'; 13339 13340 13341 /** 13342 * 13343 * @vars 13344 * 13345 * 13346 **/ 13347 var scriptInfo = 'SOW Search Suggest'; 13348 13349 window._relatedFirstLoad = ''; 13350 13351 13352 13353 $.SOW.core.search_suggest = { 13354 13355 13356 /** 13357 * 13358 * @config 13359 * 13360 * 13361 **/ 13362 config: { 13363 13364 enable : true, 13365 method : '', // [GET|POST] WARNING! THIS IS PRIMARY! Leave empty to use the form method (usualy is GET) 13366 container : '#sow-search-container', 13367 input_min_length : 2, 13368 input_delay : 100, // ms 13369 related_kw : '', // default keywords on load (leave empty to control from your backend) 13370 related_url : '', 13371 related_action : 'related_get', 13372 suggest_url : '', 13373 suggest_action : 'suggest_get', 13374 // -- 13375 contentType : '', // example: 'application/json; charset=utf-8' 13376 dataType : '', // example: json 13377 forceStringify : false, // stringify requests - data sent as JSON; data: JSON.stringify(...) 13378 13379 }, 13380 13381 13382 13383 /** 13384 * 13385 * @collection 13386 * 13387 * 13388 **/ 13389 collection: $(), 13390 13391 13392 13393 /** 13394 * 13395 * @init 13396 * 13397 * 13398 **/ 13399 init: function (selector, config) { 13400 13401 var __selector = $.SOW.helper.__selector(selector); 13402 var __config = $.SOW.helper.check_var(config); 13403 13404 this.selector = __selector[0]; // '#selector' 13405 this.collection = __selector[1]; // $('#selector') 13406 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 13407 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 13408 13409 13410 if(jQuery(this.selector).length < 1) 13411 return; 13412 13413 13414 // -- * -- 13415 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 13416 // -- * -- 13417 13418 13419 // Toggler 13420 $.SOW.core.search_suggest.sow_suggest_toggler(); 13421 13422 // 1. Has no selector 13423 if(!this.selector) { 13424 $.SOW.core.search_suggest.process($('form.js-ajax-search')); 13425 return this.collection; 13426 } 13427 13428 // 2. Has selector 13429 return this.collection.each(function() { 13430 13431 $.SOW.core.search_suggest.process($(this)); 13432 13433 }); 13434 13435 }, 13436 13437 13438 13439 /** 13440 * 13441 * @process 13442 * 13443 * 13444 * 13445 **/ 13446 process: function(_this) { 13447 13448 _this.each(function() { 13449 13450 var _t = jQuery(this), 13451 _method = _t.attr('method') || '', // got from form [GET|POST] 13452 search_enable = _t.data('autosuggest') || '', 13453 // -- 13454 search_mode = _t.data('mode') || 'html', // html|json 13455 json_max_results = _t.data('json-max-results') || 10, // JSON ONLY 13456 json_title_realted = _t.data('json-related-title') || 'Popular', // JSON ONLY 13457 json_icon_related = _t.data('json-related-item-icon') || 'fi fi-star-empty', // JSON ONLY 13458 json_title_suggest = _t.data('json-suggest-title') || 'Search Suggestion', // JSON ONLY 13459 json_noresult_txt = _t.data('json-suggest-noresult') || 'No results for', // JSON ONLY 13460 json_icon_suggest = _t.data('json-suggest-item-icon') || 'fi fi-search', // JSON ONLY 13461 json_min_score = _t.data('json-suggest-min-score') || 0, // JSON ONLY 13462 json_highlight_term = _t.data('json-highlight-term') || 'true', // JSON ONLY 13463 // -- 13464 _container = _t.data('container') || '', 13465 related_kw = _t.data('related-keywords') || '', 13466 related_url = _t.data('related-url') || '', 13467 suggest_url = _t.data('suggest-url') || '', 13468 suggest_action = _t.data('suggest-action') || '', // action type 13469 related_action = _t.data('related-action') || '', // action type 13470 _contentType = _t.data('contentType') || '',
13471 themeClass = _t.data('theme-class') || 'primary', // only the name *-primary; used by json only 13472 _dataType = _t.data('dataType') || '', 13473 min_length = _t.data('input-min-length') || 0, 13474 input_delay = _t.data('input-delay') || 0; // ms 13475 13476 13477 // -- 13478 13479 if(search_enable == '' && $.SOW.core.search_suggest.config.enable === false) 13480 return; 13481 13482 else if(search_enable != 'on') 13483 return; 13484 13485 // -- 13486 13487 13488 if(_container == '') 13489 var _container = $.SOW.core.search_suggest.config.container; 13490 13491 if(min_length < 1) 13492 var min_length = $.SOW.core.search_suggest.config.input_min_length; 13493 13494 if(input_delay < 50) 13495 var input_delay = $.SOW.core.search_suggest.config.input_delay; 13496 13497 if(related_kw == '') 13498 var related_kw = $.SOW.core.search_suggest.config.related_kw; 13499 13500 if(related_url == '') 13501 var related_url = $.SOW.core.search_suggest.config.related_url; 13502 13503 if(related_action == '') 13504 var related_action = $.SOW.core.search_suggest.config.related_action; 13505 13506 if(suggest_url == '') 13507 var suggest_url = $.SOW.core.search_suggest.config.suggest_url; 13508 13509 if(suggest_action == '') 13510 var suggest_action = $.SOW.core.search_suggest.config.suggest_action; 13511 13512 // -- 13513 13514 // Override the original form method! 13515 if($.SOW.core.search_suggest.config.method != '') 13516 var _method = $.SOW.core.search_suggest.config.method; 13517 13518 13519 13520 // Needed to avoid multiple same request 13521 window._lastSearch = null; 13522 13523 // Check required 13524 if(related_url == '' && suggest_url == '') { 13525 $.SOW.helper.consoleLog('Search Suggest Error: No related and/or suggest url provided!'); 13526 return; 13527 } 13528 13529 13530 // -- 13531 13532 13533 // Close/hide autosuggest on backdrop click 13534 window.suggestionIsAlreadyFocused = false; 13535 jQuery('.sow-search-backdrop', _t).addClass('hide').on('click', function(e) { 13536 $.SOW.core.search_suggest.__suggest_hide(_t); 13537 }); 13538 13539 // Close/hide autosuggest for `esc` key 13540 jQuery(document).keyup(function(e) { 13541 13542 if(e.keyCode === 27) { // 27 = ESC key 13543 $.SOW.core.search_suggest.__suggest_hide(_t, _container); 13544 } 13545 13546 }); 13547 13548 13549 13550 // -- 13551 13552 13553 13554 // :: FOCUS : RELATED 13555 jQuery('input.form-control-sow-search', _t).focus(function(e) { 13556 13557 var _autosuggestContent = jQuery(_container + ' .sow-search-content').html(); 13558 13559 13560 // SUGGEST BY RELATED (home, category, product, etc) 13561 if(_autosuggestContent.length < 3) { 13562 jQuery('.sow-search-loader').removeClass('hide'); 13563 13564 if(window.afterSearchKeyUp) 13565 clearTimeout(window.afterSearchKeyUp); 13566 13567 window.afterSearchKeyUp = setTimeout(function() { 13568 13569 var _formData = {ajax:"true", action:related_action, related_keywords:related_kw}; 13570 13571 // console log 13572 if($.SOW.core.search_suggest.config.forceStringify === true) 13573 $.SOW.helper.consoleLog("JSON Related Sent: " + JSON.stringify(_formData)); 13574 else 13575 $.SOW.helper.consoleLog("Related Sent: " + JSON.stringify(_formData)); 13576 13577 $.SOW.helper.consoleLog('Url Request: ' + related_url, 'color: #cccccc;'); 13578 $.SOW.helper.consoleLog('Mode: ' + search_mode, 'color: #cccccc;'); 13579 $.SOW.helper.consoleLog('------------------------------------------------------------', 'color: #cccccc;'); 13580 13581 jQuery.ajax({ 13582 13583 url: related_url, 13584 data: ($.SOW.core.search_suggest.config.forceStringify === true) ? JSON.stringify(_formData) : _formData, 13585 type: _method, 13586 cache: (search_mode == 'json') ? false : true, 13587 contentType: _contentType || 'application/x-www-form-urlencoded; charset=UTF-8', 13588 dataType: _dataType || null, 13589 headers: '', 13590 crossDomain: '', 13591 13592 error: function(XMLHttpRequest, textStatus, errorThrown) { 13593 13594 if(typeof $.SOW.core.toast === 'object') { 13595 13596 $.SOW.core.toast.show('danger', 'Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 13597 13598 } else { 13599 13600 alert("[404] Unexpected internal error!"); 13601 13602 } 13603 13604 jQuery('.sow-search-loader').addClass('hide'); 13605 13606 }, 13607 13608 success: function(data) { 13609 13610 if(search_mode === 'json') 13611 var data = $.SOW.core.search_suggest.process_json(data, related_kw, json_max_results, json_title_realted, json_noresult_txt, json_highlight_term, json_icon_related, json_min_score, themeClass); 13612 13613 // Push data 13614 jQuery(_container + ' .sow-search-content').html(data); 13615 13616 // keep as a 'cache' 13617 window._relatedFirstLoad = data; 13618 13619 // hide loader 13620 jQuery('.sow-search-loader').addClass('hide'); 13621 13622 } 13623 13624 }); 13625 13626 }, 50); 13627 13628 } 13629 13630 $.SOW.core.search_suggest.__suggest_show(_t, _container); 13631 13632 }); 13633 13634 13635 13636 // -- 13637 13638 13639 13640 // USER KEY UP : SEARCH 13641 jQuery('input.form-control-sow-search', _t).on('keyup change',function(e) { 13642 13643 var _keyInput = jQuery(this).val() || ''; 13644 13645 $.SOW.core.search_suggest.__suggest_show(_t, _container); 13646 13647 if(_keyInput.length >= Number(min_length) && window._lastSearch != _keyInput) { 13648 13649 13650 // START AJAX SEARCH 13651 jQuery('.sow-search-loader').removeClass('hide'); 13652 13653 13654 // SUGGEST BY USER INPUT 13655 if(window.afterSearchKeyUp) 13656 clearTimeout(window.afterSearchKeyUp); 13657 13658 window.afterSearchKeyUp = setTimeout(function() { 13659 13660 window._lastSearch = _keyInput; 13661 13662 var _formData = {ajax:"true", action:suggest_action, user_keywords:_keyInput }; 13663 13664 // console log 13665 if($.SOW.core.search_suggest.config.forceStringify === true) 13666 $.SOW.helper.consoleLog("JSON Suggest Sent: " + JSON.stringify(_formData)); 13667 else 13668 $.SOW.helper.consoleLog("Related Suggest: " + JSON.stringify(_formData)); 13669 13670 $.SOW.helper.consoleLog('Url Request: ' + related_url, 'color: #cccccc;'); 13671 $.SOW.helper.consoleLog('Mode: ' + search_mode, 'color: #cccccc;'); 13672 $.SOW.helper.consoleLog('------------------------------------------------------------', 'color: #cccccc;'); 13673 13674 jQuery.ajax({ 13675 url: suggest_url, 13676 data: ($.SOW.core.search_suggest.config.forceStringify === true) ? JSON.stringify(_formData) : _formData, 13677 type: _method, 13678 cache: (search_mode == 'json') ? false : true, 13679 contentType: _contentType || 'application/x-www-form-urlencoded; charset=UTF-8', 13680 dataType: _dataType || null, 13681 headers: '', 13682 crossDomain: '', 13683 13684 error: function(XMLHttpRequest, textStatus, errorThrown) { 13685 13686 if(typeof $.SOW.core.toast === 'object') { 13687 13688 $.SOW.core.toast.show('danger', 'Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 13689 13690 } else { 13691 13692 alert("[404] Unexpected internal error!"); 13693 13694 } 13695 13696 jQuery('.sow-search-loader').addClass('hide'); 13697 13698 }, 13699 13700 success: function(data) { 13701 13702 if(search_mode === 'json') 13703 var data = $.SOW.core.search_suggest.process_json(data, _keyInput, json_max_results, json_title_suggest, json_noresult_txt, json_highlight_term, json_icon_suggest, json_min_score, themeClass); 13704 13705 // Push data 13706 jQuery(_container + ' .sow-search-content').html(data); 13707 13708 // hide loader 13709 jQuery('.sow-search-loader').addClass('hide'); 13710 13711 } 13712 13713 }); 13714 13715 }, Number(input_delay)); 13716 13717 13718 13719 } else { 13720 13721 // BACK TO RELATED 13722 if(window._relatedFirstLoad != '' && _keyInput == '') { 13723 jQuery(_container + ' .sow-search-content').html(window._relatedFirstLoad); 13724 } 13725 13726 } 13727 13728 }); 13729 13730 13731 13732 }); 13733 13734 }, 13735 13736 /** 13737 * 13738 * @__suggest_show 13739 * :: Helper 13740 * 13741 * 13742 **/ 13743 __suggest_show: function(_t, _container) { 13744 13745 // Begin autosuggest 13746 if(window.suggestionIsAlreadyFocused === false) { 13747 13748 _t.removeClass('hide'); 13749 jQuery('.sow-search-backdrop', _t).removeClass('hide'); 13750 jQuery(_container).removeClass('hide'); 13751 window.suggestionIsAlreadyFocused = true; 13752 13753 } 13754 13755 }, 13756 13757 /** 13758 * 13759 * @__suggest_hide 13760 * :: Helper 13761 * 13762 * 13763 **/ 13764 __suggest_hide: function(_t, _container) { 13765 13766 if(window.suggestionIsAlreadyFocused === true) { 13767 13768 $.SOW.globals.elBody.removeClass('overflow-hidden'); 13769 13770 jQuery('.sow-search-backdrop', _t).addClass('hide'); 13771 jQuery('.sow-search-container', _t).addClass('hide'); 13772 jQuery('.sow-search-over', _t).addClass('hide'); 13773 13774 jQuery('input.form-control-sow-search', _t).blur(); 13775 _t.removeClass('sow-search-mobile'); 13776 jQuery('.sow-search-over').addClass('hide'); // all of them, if many available 13777 13778 window.suggestionIsAlreadyFocused = false;
13779 13780 } 13781 13782 }, 13783 13784 13785 13786 /** 13787 * 13788 * @sow_suggest_toggler 13789 * 13790 * 13791 * 13792 **/ 13793 sow_suggest_toggler: function() { 13794 13795 var _selector = this.selector_orig; 13796 13797 jQuery('.btn-sow-search-toggler:not(.btn-sow-search-togglified)').addClass('btn-sow-search-togglified').on('click', function(e) { 13798 e.preventDefault(); 13799 13800 var _target = jQuery(this).data('target') || _selector; 13801 13802 jQuery(_target).toggleClass('sow-search-mobile'); 13803 jQuery(_target+'.sow-search-over').toggleClass('hide'); 13804 13805 if(jQuery(_target).hasClass('sow-search-mobile')) { 13806 13807 jQuery(_target+' input.form-control-sow-search').focus(); 13808 $.SOW.globals.elBody.addClass('overflow-hidden'); 13809 jQuery(_target+'.sow-search-over').removeClass('hide'); 13810 13811 } else { 13812 13813 jQuery(_target+' input.form-control-sow-search').blur(); 13814 $.SOW.globals.elBody.removeClass('overflow-hidden'); 13815 jQuery(_target+'.sow-search-over').addClass('hide').removeClass('sow-search-mobile'); 13816 13817 } 13818 13819 }); 13820 13821 }, 13822 13823 13824 /** 13825 * 13826 * @process_json 13827 * 13828 * 13829 * 13830 **/ 13831 process_json: function(data, keyword, json_max_results, json_title, json_noresult_txt, highlight_term, icon, json_min_score, themeClass) { 13832 13833 /* 13834 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 13835 https://github.com/bripkens/fuzzy.js/blob/gh-pages/fuzzy.js 13836 Check for fuzzy.js vendor 13837 13838 */ 13839 if(typeof fuzzy !== 'function') { 13840 13841 // -- * -- 13842 $.SOW.helper.consoleLog(' ERROR : ' + scriptInfo + ' : Require fuzzy.js Vendor for JSON search mode!', 'color: #ff0000; font-weight: bold;'); 13843 // -- * -- 13844 13845 return '<h3 class="fs--18 p--20 pb--10 m-0 text-danger">' + scriptInfo + ' Error</h3>' 13846 + '<hr><p class="pl--20 pr--20">data-mode="json" <br> You enabled JSON search mode but fuzzy.js Vendor could not be found!</p>' 13847 + '<hr><p class="pl--20 pr--20"> Add fuzzy.js Vendor or switch to data-mode="html"</p>'; 13848 13849 } 13850 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 13851 13852 13853 13854 13855 13856 try { 13857 13858 var _data = JSON.parse(data); 13859 13860 } catch(err) { 13861 13862 var _data = data; 13863 13864 } var data = null; // clear/reset 13865 13866 13867 /* 13868 13869 TEST ONLY! 13870 fuzzy.js used instead! 13871 13872 var results = _data.filter(function(result) { 13873 return result.label.indexOf(keyword) > -1; 13874 }); 13875 console.log(results); 13876 13877 */ 13878 13879 13880 // TPL START : Common for related & suggest 13881 var _tpl = '<h3 class="fs--18 p-4 m-0 text-'+ themeClass +'">' + json_title + '</h3>' 13882 + '<ul class="list-unstyled list-suggestion">'; 13883 13884 13885 13886 13887 13888 // 1. FUZZY SEARCH : BY USER INPUT 13889 if(keyword != '') { 13890 13891 var filterResult = [], 13892 filterIndex = [], 13893 _found = 0; 13894 13895 // fuzzy setup 13896 fuzzy.analyzeSubTerms = true; 13897 13898 // Walk through json data 13899 for (var i = 0; i < _data.length; i++) { 13900 filterResult[i] = fuzzy(_data[i].label, keyword); // label filter 13901 filterResult[i].url = _data[i].url; // url required! 13902 } 13903 13904 13905 // sorting 13906 filterResult.sort(fuzzy.matchComparator); 13907 13908 13909 // Walk through results 13910 for (var i = 0; i < filterResult.length && i < json_max_results; i++) { 13911 var option = filterResult[i], 13912 term = option.term, 13913 score = option.score, 13914 termHighlighted = option.highlightedTerm, 13915 _term = (highlight_term == true) ? termHighlighted : term; 13916 13917 13918 13919 // Append each result 13920 if(score >= json_min_score) { 13921 _found++; 13922 _tpl += '<li class="list-item" data-score="'+score+'">' 13923 + '<a href="'+option.url+'">' 13924 //+ '<span class="text-muted fs--13 float-end p--3">0 results</span>' 13925 + '<i class="'+icon+'"></i> ' + _term 13926 + '</a>' 13927 + '</li>'; 13928 } 13929 13930 } 13931 13932 if(_found < 1) { 13933 _tpl += '<li class="list-item text-muted px-4 pb-4">' 13934 + json_noresult_txt + ' <i>"' + keyword + '"</i>' 13935 + '</li>'; 13936 } 13937 13938 // RELATED! 13939 } else { 13940 13941 var filterResult = []; 13942 13943 // Walk through json data 13944 for (var i = 0; i < _data.length; i++) { 13945 filterResult[i] = _data[i].label; 13946 } 13947 13948 13949 for (var i = 0; i < filterResult.length && i < json_max_results; i++) { 13950 13951 // Append each result 13952 _tpl += '<li class="list-item">' 13953 + '<a href="'+_data[i].url+'">' 13954 + '<i class="'+icon+'"></i> ' + _data[i].label 13955 + '</a>' 13956 + '</li>'; 13957 13958 } 13959 13960 } 13961 13962 13963 13964 13965 // TPL END : Common for related & suggest 13966 _tpl += '</ul>'; 13967 13968 13969 return _tpl; 13970 13971 13972 } 13973 13974 } 13975 13976})(jQuery); 13977 13978/** 13979 * 13980 * [SOW] Lazyload 13981 * 13982 * @author Dorin Grigoras 13983 * www.stepofweb.com 13984 * 13985 * @Dependency - 13986 * @Usage $.SOW.core.lazyload.init('.lazy'); 13987 * 13988 * Based on Lozad Plugin
13989 * https://github.com/ApoorvSaxena/lozad.js 13990 * 13991 **/ 13992;(function ($) { 13993 'use strict'; 13994 13995 13996 13997 /** 13998 * 13999 * @vars 14000 * 14001 * 14002 **/ 14003 var scriptInfo = 'SOW Lazyload'; 14004 var __observer = void 0; 14005 14006 $.SOW.core.lazyload = { 14007 14008 14009 /** 14010 * 14011 * @config 14012 * 14013 * 14014 **/ 14015 config: { 14016 14017 rootMargin: '0px', // syntax similar to that of CSS Margin 14018 threshold: 0.1, // 0 - 1; 1 = when 100% of the target is visible 14019 14020 load: function load(element) { 14021 14022 // <video> 14023 if (element.nodeName.toLowerCase() === 'video' && !element.getAttribute('data-src')) { 14024 14025 if (element.children) { 14026 14027 var childs = element.children; 14028 var childSrc = void 0; 14029 14030 for (var i = 0; i <= childs.length - 1; i++) { 14031 14032 childSrc = childs[i].getAttribute('data-src'); 14033 14034 if (childSrc) 14035 childs[i].src = childSrc; 14036 14037 } 14038 14039 element.load(); 14040 } 14041 14042 } 14043 14044 if (element.getAttribute('data-src')) 14045 element.src = element.getAttribute('data-src'); 14046 14047 if (element.getAttribute('data-srcset')) 14048 element.setAttribute('srcset', element.getAttribute('data-srcset')); 14049 14050 // mobile, if exists 14051 if ($.SOW.globals.is_mobile === true && element.getAttribute('data-background-image-xs')) 14052 element.style.backgroundImage = 'url(\'' + element.getAttribute('data-background-image-xs') + '\')'; 14053 14054 // fallback desktop from mobile 14055 else if (element.getAttribute('data-background-image')) 14056 element.style.backgroundImage = 'url(\'' + element.getAttribute('data-background-image') + '\')'; 14057 14058 /* 14059 <div class="lazy" data-toggle-class="active"> 14060 The active class will be toggled on the element when it enters the browser’s viewport. 14061 */ 14062 if (element.getAttribute('data-lazy-toggle-class')) { 14063 jQuery(element).addClass(element.getAttribute('data-lazy-toggle-class')); 14064 // element.classList.toggle(element.getAttribute('data-toggle-class')); 14065 } 14066 14067 // clear 14068 jQuery(element).removeAttr('data-lazy-toggle-class data-background-image data-srcset data-src'); 14069 14070 } 14071 14072 }, 14073 14074 14075 14076 /** 14077 * 14078 * @collection 14079 * 14080 * 14081 **/ 14082 collection: $(), 14083 14084 14085 14086 /** 14087 * 14088 * @init 14089 * 14090 * 14091 **/ 14092 init: function (selector, config) { 14093 14094 var __selector = $.SOW.helper.__selector(selector); 14095 var __config = $.SOW.helper.check_var(config); 14096 14097 this.selector = __selector[0]; // '#selector' 14098 this.collection = __selector[1]; // $('#selector') 14099 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 14100 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 14101 14102 14103 if(jQuery(this.selector).length < 1) 14104 return; 14105 14106 14107 // -- * -- 14108 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 14109 // -- * -- 14110 14111 14112 // 1. Has no selector 14113 if(!this.selector) { 14114 $.SOW.core.lazyload.process('.lazy').observe(); 14115 return jQuery('.lazy'); 14116 } 14117 14118 // 2. Has selector 14119 $.SOW.core.lazyload.process(this.selector).observe(); 14120 14121 14122 return this.collection; 14123 }, 14124 14125 14126 14127 /** 14128 * 14129 * @process 14130 * 14131 * 14132 * 14133 **/ 14134 process: function(selector) { 14135 14136 var load = $.SOW.core.lazyload.config.load; 14137 14138 if(window.IntersectionObserver) { 14139 14140 __observer = new IntersectionObserver($.SOW.core.lazyload.onIntersection(load), { 14141 rootMargin: $.SOW.core.lazyload.config.rootMargin, 14142 threshold: $.SOW.core.lazyload.config.threshold 14143 }); 14144 14145 } else { 14146 14147 // load them all instead of using polyfill! 14148 // https://www.npmjs.com/package/intersection-observer 14149 var elements = $.SOW.core.lazyload.getElements(selector); 14150 for(var i = 0; i < elements.length; i++) { 14151 load(elements[i]); 14152 $.SOW.core.lazyload.markLoaded(elements[i]); 14153 } 14154 14155 // -- * -- 14156 $.SOW.helper.consoleLog('Lazyload: This browser does not support IntersectionObserver()'); 14157 $.SOW.helper.consoleLog('Images loaded without lazyloading!'); 14158 $.SOW.helper.consoleLog('To enable, download this polyfill and include before any other js script: https://www.npmjs.com/package/intersection-observer'); 14159 // -- * -- 14160 14161 } 14162 14163 return { 14164 14165 observe: function observe() { 14166 14167 var items = $.SOW.core.lazyload.getElements(selector); 14168 for(var i=0; i < items.length; ++i) { 14169 14170 if($.SOW.core.lazyload.isLoaded(items[i])) 14171 continue; 14172 14173 if(__observer) { 14174 __observer.observe(items[i]); 14175 continue; 14176 } 14177 14178 load(items[i]); 14179 $.SOW.core.lazyload.markLoaded(items[i]); 14180 14181 } 14182 }, 14183 14184 __observer: __observer 14185 14186 }; 14187 14188 }, 14189 14190 14191 14192 14193 14194 /** 14195 * 14196 * @markLoaded 14197 * 14198 * 14199 * 14200 **/ 14201 markLoaded: function(element) { 14202 element.setAttribute('data-loaded', true); 14203 }, 14204 14205 14206 14207 14208 /** 14209 * 14210 * @isLoaded 14211 * 14212 * 14213 * 14214 **/ 14215 isLoaded: function(element) { 14216 return element.getAttribute('data-loaded') === 'true'; 14217 }, 14218 14219 14220 14221 14222 /** 14223 * 14224 * @onIntersection 14225 * 14226 * 14227 * 14228 **/ 14229 onIntersection: function(load) { 14230 14231 return function(items, __observer) { 14232
14233 items.forEach(function (item) { 14234 14235 if (item.intersectionRatio > 0 || item.isIntersecting) { 14236 14237 // call __observer is exists 14238 if(__observer) 14239 __observer.unobserve(item.target); 14240 14241 if (!$.SOW.core.lazyload.isLoaded(item.target)) { 14242 $.SOW.core.lazyload.config.load(item.target); 14243 $.SOW.core.lazyload.markLoaded(item.target); 14244 } 14245 } 14246 14247 }); 14248 14249 } 14250 14251 }, 14252 14253 14254 14255 14256 /** 14257 * 14258 * @getElements 14259 * 14260 * 14261 * 14262 **/ 14263 getElements: function(selector) { 14264 14265 if (selector instanceof Element) 14266 return [selector]; 14267 14268 if (selector instanceof NodeList) 14269 return selector; 14270 14271 return document.querySelectorAll(selector); 14272 14273 }, 14274 14275 } 14276 14277})(jQuery); 14278/** 14279 * 14280 * [SOW] Ajax Navigation 14281 * 14282 * @author Dorin Grigoras 14283 * www.stepofweb.com 14284 * 14285 * @Dependency - 14286 * @Usage $.SOW.core.ajax_navigation.init('a.js-ajax'); 14287 * -- + -- 14288 * From another plugin, for a specific container only: 14289 * Only this plugin is reinitialised, -WITHOUT- $.SOW.reinit() call 14290 * $.SOW.core.ajax_navigation.__initFor('#container'); 14291 * -- + -- 14292 * $.SOW.core.ajax_navigation.__selector(); 14293 * returns the selector only: .js-ajax 14294 * 14295 **/ 14296;(function ($) { 14297 'use strict'; 14298 14299 14300 /** 14301 * 14302 * @vars 14303 * 14304 * 14305 **/ 14306 var scriptInfo = 'SOW Ajax Navigation'; 14307 14308 window.sow_ajax_links_last_href = null; 14309 window.sow_ajax_links_curr_href = null; 14310 14311 14312 $.SOW.core.ajax_navigation = { 14313 14314 14315 /** 14316 * 14317 * @config 14318 * 14319 * 14320 **/ 14321 config: { 14322 14323 14324 /* 14325 14326 You can overwrite by adding the needed param to the link. 14327 14328 These params can be used on any <a class="js-ajax" ...></a> to overwrite thse settings 14329 data-ajax-method="GET|POST" 14330 data-ajax-container="#middle" container to push data from the server; admin use #middle as main content container 14331 data-ajax-update-url="true|false" update history state. 14332 data-ajax-show-loading-icon="true" false to disable loading icon on ajax requests 14333 data-ajax-callback-function="" custom callback function 14334 data-ajax-callback-before-push="false" do not push data to container, send to the callback only 14335 data-ajax-reponse-extract-element="#middle" get a specific element from returned data (not the entire result/page). Example: <div id="something"><div class="else"> <div id="middle">this content</div> </div></div> 14336 data-ajax-autoscroll-to-content="false" scroll to top content after loading 14337 14338 Second container, if needed to add a class: hide, show, animate, etc 14339 data-ajax-container2-element="img.js-ajax-loaded-animate" <img class="js-ajaxloaded-animate" ...> 14340 data-ajax-container2-class="animate-bouncein" 14341 14342 */ 14343 enable : true, 14344 method : 'GET', 14345 contentType : '', 14346 dataType : '', 14347 headers : '', 14348 crossDomain : '', 14349 data_params : {ajax:'true'}, 14350 14351 target_container : '#middle', // where data is pushed 14352 update_url : true, 14353 show_loading_icon : true, 14354 14355 /* 14356 callback_example = function(el, data, target_container) { 14357 // el = link clicked $(this) 14358 // data = server response (html|string) 14359 // target_container = container to push data (string:#middle) 14360 } 14361 */ 14362 callback_function : '', 14363 14364 // content (server response) is sent to your callback function only. 14365 callback_before_push : false, 14366 14367 /* 14368 #middle = main content to be extracted 14369 #page_js_files = second container containing js files wrapped inside a div 14370 */ 14371 parser_extract_enable : true, 14372 parser_force_push2target : false, // in case #middle element not found in request, entire data/page is pushed/shown 14373 parser_extract_element : '#middle, #page_js_files', 14374 14375 autoscroll_to_content : true, // scroll up to content after page loaded 14376 14377 14378 // Optional second container - add a class when page loaded 14379 container2_element : '', 14380 container2_class : '', 14381 14382 // 404 error page 14383 page_404 : '404.html', 14384 14385 14386 // Reload page content on back/forward history button instead of loading from history cache 14387 onpopstate_reload : true, 14388 14389 /* 14390 Different than callback, cannot be overwrited by params 14391 Will call a custom function after each page load 14392 Condition: callback_before_push: false (else, call the function from your callback). 14393 14394 Can be used to reinit custom scripts/plugins and/or process special data 14395 14396 custom_function_example = function(el, target_container) { 14397 // el = link clicked $(this) 14398 // container = container where data is pushed (string:#middle) 14399 } 14400 */ 14401 custom_function_call : '', 14402 14403 14404 14405 14406 // Ajax remainings of other plugins that are not self removed 14407 // .note-popover = summernote (bootstrap4 bug) 14408 AjaxOtherGarbage : '.datepicker, .daterangepicker, .modal, .modal-backdrop, .note-popover, #dropdown_toggle_overlay', 14409 }, 14410 14411 14412 14413 /** 14414 * 14415 * @collection 14416 * 14417 * 14418 **/ 14419 collection: $(), 14420 14421 14422 14423 /** 14424 * 14425 * @init 14426 * 14427 * 14428 **/ 14429 init: function (selector, config) { 14430 14431 14432 /* disabled by config */ 14433 if($.SOW.core.ajax_navigation.config.enable !== true) { 14434 $.SOW.helper.consoleLog('Disabled : ' + scriptInfo, 'color: #ff0000;'); 14435 return; 14436 } 14437 14438 14439 var __selector = $.SOW.helper.__selector(selector); 14440 var __config = $.SOW.helper.check_var(config); 14441 14442 this.selector = __selector[0]; // '#selector' 14443 this.collection = __selector[1]; // $('#selector') 14444 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 14445 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 14446 14447 if(jQuery(this.selector).length < 1) 14448 return; 14449 14450 14451 // -- * -- 14452 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 14453 // -- * -- 14454 14455 14456 /* 14457 14458 History Postate 14459 14460 */ 14461 $.SOW.core.ajax_navigation.__historyPopState(); 14462 14463 14464 14465 // 1. Has no selector 14466 if(!this.selector) { 14467 $.SOW.core.ajax_navigation.ajax_navigation($('a.js-ajax')); 14468 return this.collection; 14469 } 14470 14471 // 2. Has selector 14472 return this.collection.each(function() { 14473 14474 $.SOW.core.ajax_navigation.ajax_navigation($(this)); 14475 14476 }); 14477 14478 }, 14479 14480 14481 14482 /** 14483 * 14484 * @ajax_navigation 14485 * 14486 1. LINKS 14487 14488 USAGE 1: 14489 14490 <a href="https://myurl.com/request/" class="js-ajax" data-ajax-container="#my_container">Click</a> 14491 <div id="my_container"><!-- ajax content is loaded here --></div> 14492 14493 USAGE 2: (using data-href) 14494 14495 <a href="#" data-href="https://myurl.com/request/" class="js-ajax" data-ajax-container="#my_container">Click</a> 14496 <div id="my_container"><!-- ajax content is loaded here --></div> 14497 14498 14499 OPTIONAL PARAMS: 14500 data-ajax-method="GET|POST" default: GET 14501 data-ajax-update-url="true" default: false - update history state 14502 data-ajax-show-loading-icon="false" do not show loading icon 14503 data-ajax-callback-function="" custom callback function 14504 data-ajax-callback-before-push="false" do not push data to container, send to the callback only 14505 data-ajax-reponse-extract-element="#middle" push only an element returned from aja
14505x (not the entire result/page) 14506 data-ajax-autoscroll-to-content="false" scroll to top content after loading 14507 data-ajax-container="#middle" container to push data from the server 14508 14509 Second container, if needed to add a class: hide, show, animate, etc 14510 data-ajax-container2-element="#myimg" 14511 data-ajax-container2-class="animate-bouncein" 14512 14513 &ajax=true - added but NOT to .html files 14514 * 14515 * 14516 **/ 14517 ajax_navigation: function(_this, ajax_navigation_reinit_skip) { // ajax_navigation_reinit_skip: used by calling from other plugins via __initFor(). DO NOT REMOVE! 14518 14519 var _selector = this.selector; 14520 var _selector_orig = this.selector_orig; 14521 14522 if($.SOW.core.ajax_navigation.config.enable !== true) { 14523 _this.off('click'); 14524 return; 14525 } 14526 14527 // !!! do not use unbind() 14528 // deep navigation links conflict for ajax 14529 _this.on('click', function(e) { 14530 14531 14532 /* 14533 Because we want to be sure that we bind only once 14534 and avoid multiple times! We can't use unbind() because 14535 some other plugins might bind that link for some reason! 14536 */ 14537 // if(jQuery(this).hasClass('js-ajaxified')) 14538 // return; 14539 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 14540 14541 14542 e.preventDefault(); 14543 e.stopPropagation(); 14544 14545 var _t = jQuery(this), 14546 _href = _t.attr('href') || '#', 14547 _href_data = _t.attr('data-href') || '', 14548 _href_title = _t.attr('title') || '', // used by historyPushState to update the title 14549 _scrollToContent = _t.attr('data-ajax-autoscroll-to-content') || '', 14550 _callback = _t.data('ajax-callback-function') || '', 14551 _callbackBeforePush = _t.attr('data-ajax-callback-before-push') || '', // pass to calback, do not push content to container 14552 _method = _t.data('ajax-method') || '', 14553 _updateURL = _t.attr('data-ajax-update-url') || '', // istory push state 14554 _showLoadingIcon = _t.attr('data-ajax-show-loading-icon') || '', 14555 _container2El = _t.data('ajax-container2-element') || '', // add a class to a container, or an animation... anything 14556 _container2Class = _t.data('ajax-container2-class') || '', // add a class to a container, or an animation... anything 14557 _contentResponseExtract = _t.data('ajax-parser-extract-element') || '', // id|class (document container to get data from) 14558 _target = _t.data('ajax-target-container') || ''; 14559 14560 14561 if(_href_data != '') 14562 _href = _href_data; 14563 14564 14565 14566 // ok, bind identifier for this function so we don't bind again! 14567 //_t.addClass('js-ajaxified'); 14568 14569 14570 14571 // Check nav-deep for this link, if comes from content! 14572 // We want it highlighted! 14573 if(!_t.hasClass('nav-link') && typeof $.SOW.core.nav_deep === 'object') { 14574 14575 /** 14576 14577 We remove #hash and rewrite the _href 14578 Actually, the back button on pushState will not contain the #hash anymore 14579 But when the user click "Back Button", page position is ok 14580 It's not something critical, we can live with this intentional bug. 14581 The chance that somebody notice... is very, very, very low :) 14582 14583 **/ 14584 var _href = $.SOW.helper.removeUrlHash(_href); // remove hash (helper) 14585 var __navHasThisLink = jQuery(_selector_orig+'.nav-link[href="'+_href+'"]'); 14586 14587 if(__navHasThisLink.length > 0) { 14588 14589 $.SOW.core.nav_deep.nav_deep_open(__navHasThisLink); 14590 $.SOW.core.nav_deep.nav_deep_close_all(__navHasThisLink); 14591 14592 } 14593 14594 // clear/reset 14595 var __navHasThisLink = null; 14596 14597 } 14598 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 14599 14600 14601 14602 /** 14603 CONFIG DEFAULTS 14604 **/ 14605 if(_scrollToContent == '') 14606 var _scrollToContent = $.SOW.core.ajax_navigation.config.autoscroll_to_content; 14607 14608 if(_callback == '') 14609 var _callback = $.SOW.core.ajax_navigation.config.callback_function; 14610 14611 if(_callbackBeforePush == '') 14612 var _callbackBeforePush = $.SOW.core.ajax_navigation.config.callback_before_push; 14613 14614 if(_method == '') 14615 var _method = $.SOW.core.ajax_navigation.config.method; 14616 14617 if(_updateURL == '') 14618 var _updateURL = $.SOW.core.ajax_navigation.config.update_url; 14619 14620 if(_showLoadingIcon == '') 14621 var _showLoadingIcon = $.SOW.core.ajax_navigation.config.show_loading_icon; 14622 14623 if(_container2El == '')
14624 var _container2El = $.SOW.core.ajax_navigation.config.container2_element; 14625 14626 if(_container2Class == '') 14627 var _container2Class = $.SOW.core.ajax_navigation.config.container2_class; 14628 14629 // -- 14630 14631 if(_contentResponseExtract == '' && $.SOW.core.ajax_navigation.config.parser_extract_enable === true) /* default self config (se top config) */ 14632 var _contentResponseExtract = $.SOW.core.ajax_navigation.config.parser_extract_element; 14633 14634 /* 14635 14636 In case there is another ajax request, 14637 but for a different specified #destination_container 14638 14639 */ 14640 if(_target != '' && _target != _contentResponseExtract) 14641 _contentResponseExtract = ''; 14642 14643 // -- 14644 14645 if(_target == '') 14646 var _target = $.SOW.core.ajax_navigation.config.target_container; 14647 14648 14649 14650 if(_target == '') { 14651 14652 $.SOW.helper.consoleLog('Ajax request: data-ajax-container missing!'); 14653 return; 14654 14655 } 14656 14657 14658 else if(_href == '#' || _href == '#!' || _href == '' || _href == 'javascript:;') { 14659 14660 $.SOW.helper.consoleLog('Ajax request: no valid link!'); 14661 return; 14662 14663 } 14664 14665 14666 14667 14668 /* 14669 14670 Block "flooding" 14671 14672 */ 14673 if(window.sow_ajax_links_last_href == _href) 14674 return; 14675 14676 window.sow_ajax_links_last_href = _href; 14677 // -- 14678 14679 14680 14681 // Remove any unwanted stuff - like: if click was from modal 14682 jQuery('.modal-backdrop').remove(); 14683 jQuery('body').removeClass('modal-open overflow-hidden'); 14684 14685 14686 14687 14688 14689 14690 14691 /* 14692 14693 CREATE AN OBJECT WITH ALL PARAMS TO SEND THEM TO AJAX FUNCTION! 14694 14695 The reason we do this, is because we need the exactly same 14696 ajax request for historyPushState on "back button" click. 14697 This object we save it as "html" (json) to historyPushState 14698 14699 This object will be packed as json by __ajaxLinkProcess() function 14700 _json = JSON.stringify(_obj); 14701 14702 */ 14703 var _obj = new Object(); 14704 _obj._t = _t; 14705 _obj._href = _href; 14706 _obj._scrollToContent = _scrollToContent; 14707 _obj._callback = _callback; 14708 _obj._callbackBeforePush = _callbackBeforePush; 14709 _obj._method = _method; 14710 _obj._updateURL = _updateURL; 14711 _obj._showLoadingIcon = _showLoadingIcon; 14712 _obj._container2El = _container2El; 14713 _obj._container2Class = _container2Class; 14714 _obj._contentResponseExtract = _contentResponseExtract; 14715 _obj._target = _target; 14716 14717 14718 /** 14719 14720 HOW IT WORKS? 14721 14722 1. __ajaxLinkProcess() send an ajax request. If _callbackBeforePush is not set tot true, the page will update. 14723 2. the object above is packed into a JSON string and passed it to __ajaxLinkProcess() as to keep it in history pushState ;) 14724 3. user is happy, drinking 10 beers but suddently navigate back using "back button" so the page is the same but the link is changing! 14725 4. the history will return the sting from cache (our jsonified object) we just created on step 2 14726 5. history function will call __ajaxLinkProcess() passing the object but disabling things like _updateURL (because is already on that page) 14727 6. __ajaxLinkProcess() will try to find the link to get the element because jQuery(this) is needed (I mean: _t) 14728 7. Because we keep the previous pages in pushHistory, we use them to catch the clicked link. 14729 14730 Looks complicated but the process is simple. 14731 14732 **/ 14733 return $.SOW.core.ajax_navigation.__ajaxLinkProcess(_obj, ajax_navigation_reinit_skip); 14734 14735 14736 }); 14737 14738 14739 }, 14740 14741 /** 14742 * 14743 * Ajax Process 14744 * :: Helper 14745 * 14746 **/ 14747 __ajaxLinkProcess: function(_obj, ajax_navigation_reinit_skip) { 14748 14749 if($.SOW.core.ajax_navigation.config.enable !== true) 14750 return; 14751 14752 14753 var _t = _obj._t, 14754 _href = _obj._href, 14755 _scrollToContent = _obj._scrollToContent, 14756 _callback = _obj._callback, 14757 _callbackBeforePush = _obj._callbackBeforePush, 14758 _method = _obj._method, 14759 _updateURL = _obj._updateURL, 14760 _showLoadingIcon = _obj._showLoadingIcon, 14761 _container2El = _obj._container2El, 14762 _container2Class = _obj._container2Class, 14763 _contentResponseExtract = _obj._contentResponseExtract, 14764 _target = _obj._target, 14765 _obj = null; 14766 14767 14768 14769 // Yeah, the ugliest bool fix ever. 14770 var _callbackBeforePush = _callbackBeforePush+'';
14771 var _callbackBeforePush = _callbackBeforePush.toLowerCase(); 14772 var _updateURL = _updateURL+''; 14773 var _updateURL = _updateURL.toLowerCase(); 14774 var _showLoadingIcon = _showLoadingIcon+''; 14775 var _showLoadingIcon = _showLoadingIcon.toLowerCase(); 14776 var _scrollToContent = _scrollToContent+''; 14777 var _scrollToContent = _scrollToContent.toLowerCase(); 14778 14779 14780 14781 jQuery.ajax({ 14782 url: _href, 14783 data: $.SOW.core.ajax_navigation.config.data_params, 14784 type: _method, 14785 contentType: $.SOW.core.ajax_navigation.config.contentType, 14786 dataType: $.SOW.core.ajax_navigation.config.dataType, 14787 headers: $.SOW.core.ajax_navigation.config.headers, 14788 crossDomain: $.SOW.core.ajax_navigation.config.crossDomain, 14789 14790 beforeSend: function() { 14791 14792 if(_showLoadingIcon == 'true') 14793 $.SOW.helper.loadingSpinner('show', _target); 14794 14795 // disable link 14796 _t.addClass('disabled'); 14797 14798 14799 /* 14800 14801 Click from admin : close mobile aside 14802 14803 */ 14804 if($.SOW.globals.is_mobile === true) { 14805 14806 if($.SOW.globals.elBody.hasClass('layout-admin') && jQuery('#aside-main').hasClass('js-aside-show')) 14807 jQuery('.btn-sidebar-toggle').trigger('click'); 14808 14809 } 14810 14811 }, 14812 14813 error: function(XMLHttpRequest, textStatus, errorThrown) { 14814 14815 // 404 error page 14816 var page_404_response = $.SOW.core.ajax_navigation.page_404(_contentResponseExtract, _target); // should return true! 14817 14818 if(!page_404_response) { 14819 14820 $.SOW.helper.loadingSpinner('hide'); 14821 14822 if(typeof $.SOW.core.toast === 'object') { 14823 14824 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 14825 14826 } else { 14827 14828 alert("[404] Unexpected internal error!"); 14829 14830 } 14831 14832 } 14833 14834 14835 14836 // if debug enabled, see config 14837 if($.SOW.config.sow__debug_enable === true) { 14838 14839 $.SOW.helper.consoleLog('----------------------------'); 14840 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 14841 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 14842 $.SOW.helper.consoleLog(XMLHttpRequest); 14843 $.SOW.helper.consoleLog('2. textStatus:'); 14844 $.SOW.helper.consoleLog(textStatus); 14845 $.SOW.helper.consoleLog('3. errorThrown:'); 14846 $.SOW.helper.consoleLog(errorThrown); 14847 $.SOW.helper.consoleLog('----------------------------'); 14848 14849 } 14850 14851 }, 14852 14853 success: function(data) { 14854 14855 14856 // Ajax remainings of other plugins that are not self removed 14857 $.SOW.core.ajax_navigation.__cleanAjaxOtherGarbage(); 14858 // ---------------------------------------------------------- 14859 14860 14861 var __dataHtml = ''; 14862 14863 if(_callbackBeforePush == 'false') { 14864 14865 // Push data 14866 if(_contentResponseExtract == '' || $.SOW.core.ajax_navigation.config.parser_extract_enable === false) { 14867 14868 14869 14870 /* 14871 14872 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated 14873 because of its detrimental effects to the end user's experience. 14874 For more help, check https://xhr.spec.whatwg.org/ 14875 14876 Remove any <script> and append them using async: 14877 html_parsed__apply_scripts() 14878 14879 */ 14880 var script_src = new Array, 14881 script_inline = new Array, 14882 jQ_source = jQuery('<div>' + data + '</div>'); 14883 14884 // get scripts with src 14885 jQuery('script[src]', jQ_source).each(function() { 14886 script_src.push($(this).attr('src')); 14887 }); 14888 jQuery('script[src]', jQ_source).remove(); 14889 14890 // get scripts without src 14891 jQuery('script', jQ_source).each(function() { 14892 script_inline.push($(this)); 14893 }); 14894 jQuery('script', jQ_source).remove(); 14895 // -------------------------------------------------------------------------------- 14896 var parsed_data = jQ_source.html(); 14897 14898 14899 // force push content, as it is because nothing parsed 14900 if(parsed_data == '' && $.SOW.core.ajax_navigation.config.parser_force_push2target === true) 14901 var parsed_data = data; 14902 14903 14904 // Append data 14905 jQuery(_target).empty().append(parsed_data); 14906 14907 14908 // Apply JS 14909 $.SOW.core.ajax_navigation.html_parsed__apply_scripts(script_src, script_inline); 14910 var jQ_source = null; 14911 14912 14913 if(_updateURL == 'true') 14914 var __dataHtml = parsed_data; 14915 14916 // Parse content and push 14917 } else { 14918 14919 // Pase data 14920 var _objParsed = $.SOW.core.ajax_navigation.html_parse(_contentResponseExtract, data); 14921 14922 if(typeof _objParsed !== 'object') { 14923 14924 var __dataHtml = ''; 14925 14926 } else { 14927 14928 var __dataHtml = _objParsed.html_content; 14929 var _href_title = _objParsed.meta_title; 14930 14931 } 14932 14933 14934 // force push content, as it is because nothing parsed 14935 if(!__dataHtml && $.SOW.core.ajax_navigation.config.parser_force_push2target === true) 14936 __dataHtml = data; 14937 14938 14939 // Push Content 14940 jQuery(_target).empty().append(__dataHtml); 14941 14942 // Push Scripts 14943 $.SOW.core.ajax_navigation.html_parsed__apply_scripts(_objParsed.scripts_src, _objParsed.scripts_inline); 14944 var _objParsed = null; // clear 14945 14946 } 14947 // -- 14948 14949 14950 // We also avoid adding same page to history pushState on multiple clicks on the same link 14951 if(_updateURL == 'true' && window.sow_ajax_links_curr_href != _href) { 14952 14953 /* 14954 14955 We create a new object here, can't use the one passed to the function! 14956 Regular js function is working. This is not! 14957 */ 14958 var _obj = new Object; 14959 _obj._href = _href; 14960 _obj._callback = _callback; 14961 _obj._callbackBeforePush = _callbackBeforePush; 14962 _obj._contentResponseExtract = _contentResponseExtract; 14963 _obj._updateURL = _updateURL; 14964 _obj._container2El = _container2El; 14965 _obj._container2Class = _container2Class; 14966 _obj._scrollToContent = _scrollToContent; 14967 _obj._target = _target; 14968 _obj._html = (__dataHtml != '') ? __dataHtml : ''; 14969 var _json = JSON.stringify(_obj); 14970 14971 $.SOW.core.ajax_navigation.__historyPushState(_href, _href_title, _json); 14972 } 14973 14974 14975 // scroll to content 14976 if(_scrollToContent == 'true') { 14977 if(typeof $.SOW.helper.scrollAnimate === "function") { 14978 var _contentEl = jQuery(_target); 14979 $.SOW.helper.scrollAnimate(_contentEl, 0, false, 200); 14980 } 14981 } 14982 14983 14984 // Second container - remove and|or add class (animation, toggle, hide, etc) 14985 if(_container2El != '') { 14986 14987 // to animate after scrolling 14988 var _container2Delay = (_scrollToContent == true) ? 200 : 60; 14989 14990 14991 // Remove first 14992 jQuery(_container2El).removeClass(_container2Class); 14993 14994 setTimeout(function() { 14995 14996 // Add back (useful for animation) 14997 if(_container2Class != '') 14998 jQuery(_container2El).addClass(_container2Class); 14999 15000 }, _container2Delay); 15001 15002 } 15003 15004 15005 // custom_function_call() 15006 // call this function after each page load 15007 if($.SOW.core.ajax_navigation.config.custom_function_call != '') { 15008 15009 if(typeof $.SOW.helper.executeFunctionByName === "function") 15010 $.SOW.helper.executeFunctionByName($.SOW.core.ajax_navigation.config.custom_function_call, window, _t, _target, this.selector); 15011 15012 } 15013 15014 15015 // ++ REINIT PLUGINS ++ 15016 if(ajax_navigation_reinit_skip !== 'true') 15017 $.SOW.core.ajax_navigation.reinit_call(_target); 15018 // ++ ++ ++ ++ ++ ++ ++ 15019 15020 15021 } 15022 15023 15024 15025 // notice only 15026 if(_callbackBeforePush == 'true' && _callback == '') 15027 $.SOW.helper.consoleLog('data-ajax-callback-function="" -BUT- data-ajax-callback-before-push="true"'); 15028 15029 15030 15031 // callback function 15032 if(_callback != '') { 15033 15034 if(typeof $.SOW.helper.executeFunctionByName === "function") 15035 $.SOW.helper.executeFunctionByName(_callback, window, _t, __dataHtml || data, _target); 15036 15037 } 15038 15039 15040 15041 // remove loading icon 15042 $.SOW.helper.loadingSpinner('hide'); 15043 15044 15045 15046 // enable link 15047 _t.removeClass('disabled'); 15048 15049 15050 15051 // Add url to container, in case is "ajax content" plugin used 15052 // so we can have a real "reload btn" with new link 15053 if(jQuery(_target).hasClass('js-ajax')) 15054 jQuery(_target).attr('data-ajax-url', _href); 15055 15056 15057 15058 // clear/reset 15059 var data = null, 15060 _obj = null, 15061 _json = null, 15062 __dataHtml = null, 15063 __source = null, 15064 __dataParsed = null; 15065 window.sow_ajax_links_last_href = null; 15066 15067 // Used to avoid adding same page to history pushState on multiple clicks on the same link 15068 if(_updateURL == 'true' && window.sow_ajax_links_curr_href != _href) 15069 window.sow_ajax_links_curr_href = _href; 15070 15071 15072 // Needed for links from fullscreen 15073 $.SOW.globals.elBody.removeClass('overflow-hidden'); 15074 15075 } 15076 15077 }); 15078 15079 return true; 15080 15081 }, 15082 15083 15084 15085 15086 15087 15088 15089 /** 15090 * 15091 * @html_parse 15092 * Extract content of html. One or more selectors 15093 * html_parse('#selector1, #selector2, ...', html); 15094 * 15095 * 15096 **/ 15097 html_parse: function(_selectors, _data) { 15098 15099 if(!_data) 15100 return null; 15101 15102 else if(!_selectors) { 15103 var _obj = new Object; 15104 _obj.meta_title = null; 15105 _obj.html_content = _data; 15106 } 15107 15108 var jQ_source = jQuery('<div>' + _data + '</div>'), 15109 html_content = '', 15110 meta_title = jQ_source.find('title').html() || '', 15111 data_parsed = jQ_source.find(_selectors), 15112 script_src = new Array, 15113 script_inline = new Array; 15114 15115 if(!data_parsed) 15116 return null; 15117 15118 15119 // Add each element (if more than one elements passed) 15120 data_parsed.each(function() { 15121 15122 /* 15123 15124 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated 15125 because of its detrimental effects to the end user's experience. 15126 For more help, check https://xhr.spec.whatwg.org/ 15127 15128 Remove any <script> and append them using async: 15129 html_parsed__apply_scripts() 15130 15131 */ 15132 // get scripts with src 15133 jQuery('script[src]', this).each(function() { 15134 script_src.push($(this).attr('src')); 15135 }); 15136 jQuery('script[src]', this).remove(); 15137 15138 // get scripts without src 15139 jQuery('script', this).each(function() { 15140 script_inline.push($(this)); 15141 }); 15142 jQuery('script', this).remove(); 15143 15144 // at this point, we shuld be <script> free 15145 html_content += $(this).html(); // required for __historyPushState 15146 15147 }); 15148 15149 15150 var _obj = new Object; 15151 _obj.meta_title = meta_title; 15152 _obj.html_content = html_content; 15153 _obj.scripts_src = script_src; 15154 _obj.scripts_inline = script_inline; 15155 15156 return _obj; 15157 }, 15158 15159 15160 15161 15162 15163 15164 /** 15165 * 15166 * @html_parsed__apply_scripts 15167 * Apply parsed scripts 15168 * 15169 * 15170 **/ 15171 html_parsed__apply_scripts: function(scripts_src, scripts_inline) { 15172 15173 15174 /** 15175 15176 Reason this function exists: 15177 15178 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated 15179 because of its detrimental effects to the end user's experience. 15180 For more help, check https://xhr.spec.whatwg.org/ 15181 15182 So we can't just append(html_content) including scripts. 15183 We cut them out on html_parse() and append them this way! 15184 15185 **/
15186 // $.SOW.helper.loadScript(script_arr, async[true|false], cache[true|false]) 15187 $.SOW.helper.loadScript(scripts_src, false, true).done(function() { 15188 15189 jQuery('#js_ajax_navigation_appended_scripts').remove(); 15190 15191 if(scripts_inline.length > 0) { 15192 15193 jQuery('body').append('<div id="js_ajax_navigation_appended_scripts"></div>'); 15194 15195 for (var i in scripts_inline) { 15196 jQuery('#js_ajax_navigation_appended_scripts').append(scripts_inline[i]); 15197 } 15198 15199 } 15200 15201 }); 15202 15203 return true; 15204 15205 }, 15206 15207 15208 15209 15210 15211 15212 15213 /** 15214 * 15215 * @reinit_call 15216 * Call main $.SOW.reinit() 15217 * 15218 * 15219 **/ 15220 reinit_call: function(_target) { 15221 15222 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 15223 // reinit inside ajax container 15224 if($.SOW.config.sow__debug_enable === true) { // just to avoid always calling the helper 15225 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 15226 $.SOW.helper.consoleLog(scriptInfo, 'color: #6dbb30; font-weight: bold; font-size:14px;'); 15227 $.SOW.helper.consoleLog('Ajax Reinit For: ' + _target); 15228 $.SOW.helper.consoleLog(window.location.href); 15229 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 15230 } 15231 15232 $.SOW.reinit(_target); 15233 15234 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 15235 15236 }, 15237 15238 15239 15240 15241 15242 15243 15244 15245 /** 15246 * 15247 * @page_404 15248 * Get Page 404 15249 * 15250 * 15251 **/ 15252 page_404: function(_contentResponseExtract, _target) { 15253 15254 if($.SOW.core.ajax_navigation.config.page_404 == '') 15255 return null; 15256 15257 // get the page 15258 jQuery.ajax({ 15259 url: $.SOW.core.ajax_navigation.config.page_404, 15260 data: {ajax:"true"}, 15261 type: 'GET', 15262 contentType: '', 15263 dataType: '', 15264 headers: '', 15265 crossDomain: '', 15266 15267 beforeSend: function() { 15268 15269 $.SOW.helper.loadingSpinner('show', _target); 15270 15271 }, 15272 15273 error: function(XMLHttpRequest, textStatus, errorThrown) { 15274 15275 $.SOW.helper.loadingSpinner('hide'); 15276 15277 }, 15278 15279 success: function(data) { 15280 15281 // Pase data 15282 var _objParsed = $.SOW.core.ajax_navigation.html_parse(_contentResponseExtract, data), 15283 data = null; 15284 15285 if(typeof _objParsed !== 'object') { 15286 15287 var __dataHtml = ''; 15288 15289 } else { 15290 15291 var __dataHtml = _objParsed.html_content; 15292 document.title = _objParsed.meta_title; 15293 15294 // we need it in case o refresh! 15295 $.SOW.core.ajax_navigation.__historyPushState($.SOW.core.ajax_navigation.config.page_404, document.title, __dataHtml); 15296 15297 } 15298 15299 15300 // force push content, as it is because nothing parsed 15301 if(!__dataHtml && $.SOW.core.ajax_navigation.config.parser_force_push2target === true) 15302 __dataHtml = data; 15303 15304 15305 // Push Content 15306 jQuery(_target).empty().html(__dataHtml); 15307 $.SOW.helper.loadingSpinner('hide'); 15308 15309 // Push Scripts 15310 $.SOW.core.ajax_navigation.html_parsed__apply_scripts(_objParsed.scripts_src, _objParsed.scripts_inline); 15311 var _objParsed = null; // clear 15312 15313 15314 // reinit plugins for 404 page 15315 $.SOW.core.ajax_navigation.reinit_call(_target); 15316 15317 15318 15319 } 15320 15321 }); 15322 15323 15324 return true; 15325 15326 }, 15327 15328 15329 15330 15331 15332 15333 15334 15335 15336 /* 15337 15338 Init for specific container 15339 Used by other plugins 15340 15341 */ 15342 __initFor: function(_container) { 15343 15344 if(!_container) 15345 return; 15346 15347 var ajax_navigation_reinit_skip = true; // true, no matter what! 15348 return $.SOW.core.ajax_navigation.ajax_navigation(jQuery(_container + ' ' + this.selector_orig), ajax_navigation_reinit_skip); 15349 15350 }, 15351 15352 15353 15354 15355 15356 15357 15358 /* 15359 15360 Return the selector only 15361 Example: .js-ajax 15362 15363 */ 15364 __selector: function() { 15365 15366 return this.selector_orig; 15367 15368 }, 15369 15370 15371 15372 15373 15374 /* 15375 15376 Clean `garbage` 15377 Ajax remainings that are not self removed 15378 15379 */ 15380 __cleanAjaxOtherGarbage: function() { 15381 15382 $($.SOW.core.ajax_navigation.config.AjaxOtherGarbage).remove(); 15383 jQuery('body').removeClass('overflow-hidden modal-open'); 15384 15385 }, 15386 15387 15388 15389 15390 15391 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 /** HISTORY PUSH STATE 15405 Change url without refresh & push data 15406 **************************************************************** **/ 15407 __historyPushState: function(_url, _pageTitle, html) { 15408 15409 if(_url == '' || _url == '#' || _url == 'javascript:;') 15410 return; 15411 15412 // Non compatible browsers 15413 if(typeof(history.pushState) == "undefined") { 15414 window.location = _url; 15415 return; 15416 } 15417 15418 window.history.pushState( 15419 { 15420 "html": html, 15421 "pageTitle": _pageTitle, 15422 }, 15423 "", _url 15424 ); 15425 15426 $.SOW.helper.consoleLog("SOW Ajax : history.pushState : " + _url); 15427 }, 15428 15429 15430 15431 15432 15433 15434 /* 15435 15436 Popstate 15437 Back Button 15438 15439 */ 15440 __historyPopState: function() { 15441 15442 var _selector = this.selector; 15443 var _selector_orig = this.selector_orig; // without ajax container 15444 15445 if(typeof(window.onpopstate) !== "function") { 15446 15447 window.onpopstate = function(e) { 15448 15449 if(e.state) { 15450 15451 document.title = e.state.pageTitle; // update title from history 15452 15453 var _obj = JSON.parse(e.state.html); 15454 15455 // Update html (from history version) 15456 // needed to search the link - see below 15457 var _target = (_obj._target != '') ? _obj._target : '#middle'; 15458 jQuery(_target).empty().html(_obj._html); 15459 15460 // No reason to continue, we can't find the element to click or get data 15461 // We keep the page from history! 15462 if(_obj._href == '') { 15463 $.SOW.helper.consoleLog("SOW Ajax : history.pushState : Err : Missing Back Link! Displayed the page from history, no real request to the server reload!"); 15464 return; 15465 } 15466 15467 15468 /* --------------------------------------------------------------------------- */ 15469 15470 // Let's get the element! We have only the link to work with! 15471 var _t = jQuery(_selector_orig+'[href="'+_obj._href+'"]').first(); 15472 15473 if(!_t) 15474 var _t = jQuery(_selector_orig+'[href="'+_obj._href+'"]').first(); 15475 15476 15477 if(!_t) { 15478 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 15479 15480 // No link found? Reload page if also no history html version. 15481 if(_obj._html == '') 15482 location.reload(true); 15483 15484 // Ok, stop here! 15485 return; 15486 15487 } 15488 15489 /* --------------------------------------------------------------------------- */ 15490 if($.SOW.core.ajax_navigation.config.onpopstate_reload === true) { 15491 /* 15492 Reload the content! 15493 Display the page from the history, which is already doing few lines above! 15494 */ 15495 15496 _obj._t = _t; // most important (is actually the link clicked - dom element) 15497 _obj._updateURL = false; // do not update, we already are on it 15498 _obj._scrollToContent = false; // annoyng on each back to have a scrolling page 15499 15500 $.SOW.core.ajax_navigation.__ajaxLinkProcess(_obj); // ajax call, refresh page|content 15501 $.SOW.helper.consoleLog("SOW Ajax : onpopstate : Content request sent to the server!"); 15502 15503 } 15504 /* --------------------------------------------------------------------------- */ 15505 15506 /* 15507 Deep Navigation Plugin 15508 Active Current 15509 */ 15510 if(typeof $.SOW.core.nav_deep === 'object') { 15511 $.SOW.core.nav_deep.nav_deep_open(_t); 15512 $.SOW.core.nav_deep.nav_deep_close_all(_t); 15513 } 15514 15515 /* --------------------------------------------------------------------------- */ 15516 15517 15518 } else { 15519 15520 /* 15521 15522 onpopstate is handling hashed as "regular" links, refreshing the page 15523 So we have to stop this behavior! 15524 15525 */ 15526 var _href = window.location.href; 15527 if (_href.indexOf('#') > -1) 15528 return; 15529 15530 // Origin - refresh! 15531 location.reload(true); 15532 15533 } 15534 15535 15536 }; 15537 15538 } 15539 } 15540 15541 } 15542 15543})(jQuery); 15544/** 15545 * 15546 * [SOW] Ajax Content 15547 * 15548 * @author Dorin Grigoras 15549 * www.stepofweb.com 15550 * 15551 * @Dependency - 15552 * @Usage $.SOW.core.ajax_content.init('div.js-ajax, section.js-ajax'); 15553 * 15554 * 15555 **/ 15556;(function ($) { 15557 'use strict'; 15558 15559 15560 /** 15561 * 15562 * @vars 15563 * 15564 * 15565 **/ 15566 var scriptInfo = 'SOW Ajax Content'; 15567 15568 15569 $.SOW.core.ajax_content = { 15570 15571 15572 /** 15573 * 15574 * @config 15575 * 15576 * 15577 **/ 15578 config: { 15579 method : 'GET', 15580 contentType : '', 15581 dataType : '', 15582 headers : '', 15583 crossDomain : '', 15584 data_params : {ajax:'true'}, 15585 15586 /*
15587 callback_example = function(el, data, target_container) { 15588 // el = link clicked $(this) 15589 // data = server response (html|string) 15590 // target_container = container to push data (string:#middle) 15591 } 15592 */ 15593 callback_function : '', 15594 15595 // content (server response) is sent to your callback function only. 15596 callback_before_push : false, 15597 15598 }, 15599 15600 15601 15602 /** 15603 * 15604 * @collection 15605 * 15606 * 15607 **/ 15608 collection: $(), 15609 15610 15611 15612 /** 15613 * 15614 * @init 15615 * 15616 * 15617 **/ 15618 init: function (selector, config) { 15619 15620 var __selector = $.SOW.helper.__selector(selector); 15621 var __config = $.SOW.helper.check_var(config); 15622 15623 this.selector = __selector[0]; // '#selector' 15624 this.collection = __selector[1]; // $('#selector') 15625 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 15626 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 15627 15628 15629 if(jQuery(this.selector).length < 1) 15630 return; 15631 15632 15633 /* 15634 15635 Because this script is needed on body only and not inside itself, 15636 we block this script loading by another plugins reinit 15637 Easier and better than creating another rule in Controller for all plugins! 15638 15639 15640 Note: we use .last() instead of .first() because we might have 15641 one content in a static area (main navigation as an eample) 15642 and another one inside ajax (loaded by ajax navigation) 15643 15644 */ 15645 if(jQuery(this.selector_orig).last().hasClass('js-ajaxified')) 15646 return; 15647 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 15648 15649 15650 // -- * -- 15651 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 15652 // -- * -- 15653 15654 15655 // 1. Has no selector 15656 if(!this.selector) { 15657 $.SOW.core.ajax_content.ajax_content($('div.js-ajax, section.js-ajax')); 15658 return this.collection; 15659 } 15660 15661 // 2. Has selector 15662 return this.collection.each(function() { 15663 15664 $.SOW.core.ajax_content.ajax_content($(this)); 15665 15666 }); 15667 15668 }, 15669 15670 15671 15672 /** 15673 * 15674 * @ajax_content 15675 * 15676 2. DIVS (and sections) 15677 15678 USAGE: 15679 15680 <section id="section_1" class="js-ajax" data-ajax-url="_ajax/dummy_text.html" data-ajax-container="#section_1 .section-body" data-ajax-method="GET"> 15681 15682 <div class="section-body"> 15683 Lorem Ipsum 15684 </div> 15685 15686 <a href="#" class="btn-js-ajax-reload" data-ajax-container="#section_1">Reload Content</a> 15687 15688 </section> 15689 15690 &ajax=true - added but NOT to .html files 15691 * 15692 * 15693 **/ 15694 ajax_content: function(_this) { 15695 15696 if(_this.hasClass('.js-ajaxified') || _this.length < 1) 15697 return; 15698 15699 _this.addClass('js-ajaxified'); 15700 15701 15702 var _id = _this.attr('id') || '', 15703 _url = _this.data('ajax-url') || '', 15704 _callback = _this.data('ajax-callback-function') || $.SOW.core.ajax_content.config.callback_function, 15705 _callbackBeforePush = _this.data('ajax-callback-before-push') || $.SOW.core.ajax_content.config.callback_before_push, 15706 _method = _this.data('ajax-method') || $.SOW.core.ajax_content.config.method, 15707 _btn_reload = _this.data('ajax-btn-reload') || '', 15708 _target = _this.data('ajax-target-container') || ''; 15709 15710 15711 /* 15712 15713 Container has no ID 15714 We generate one 15715 15716 */ 15717 if(_id == '') { 15718 _id = $.SOW.helper.randomStr(8); 15719 _this.attr('id', _id); 15720 } 15721 15722 15723 // Add a generated id to reload button, if has no id. 15724 // do not rewrite if exists 15725 if(jQuery(_btn_reload).length > 0) { 15726 15727 var _btnReloadTarget = jQuery(_btn_reload).attr('data-ajax-container') || ''; 15728 15729 if(_btnReloadTarget == '') 15730 jQuery(_btn_reload).attr('data-ajax-container', '#'+_id).addClass('btn-js-ajax-content-reloader'); 15731 15732 } 15733 15734 15735 15736 15737 15738 /* 15739 15740 No target specified 15741 We use self container 15742 15743 */ 15744 if(_target == '' || _target == 'self' || _target == '_self') 15745 var _target = '#' + _id; 15746 15747 15748 15749 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15750 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15751 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15752 // FUTURE UPDATE 15753 // PROECESS ONLY WHEN ELEMENT IS VISIBLE! 15754 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15755 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15756 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 15757 15758 15759 // Process! 15760 $.SOW.core.ajax_content.__ajaxDivProcess(_id, _url, _target, _method, null, _callback, _callbackBeforePush); 15761 // -- -- -- 15762 15763 15764 15765 15766 // Bind reload button[s] 15767 $.SOW.core.ajax_content.btn_reload_bind(); 15768 15769 }, 15770 15771 15772 15773 15774 15775 15776 /** 15777 * 15778 * @btn_reload_bind 15779 * 15780 * 15781 * 15782 **/ 15783 btn_reload_bind: function() { 15784 15785 jQuery('.btn-js-ajax-content-reloader:not(.btn-js-ajaxified)').addClass('btn-js-ajaxified').on('click', function(e) { 15786 e.preventDefault(); 15787 15788 var __btnEl = jQuery(this), 15789 __containerID = jQuery(this).data('ajax-container') || ''; 15790 15791 if(__containerID != '') { 15792 15793 var __t = jQuery(__containerID), 15794 __id = __t.attr('id') || '', 15795 __url = __t.attr('data-ajax-url') || '', // .attr, ELSE WILL NOT UPDATE! 15796 __callback = __t.data('ajax-callback-function') || $.SOW.core.ajax_content.config.callback_function, 15797 __callbackBeforePush = __t.data('ajax-callback-before-push') || $.SOW.core.ajax_content.config.callback_before_push, 15798 __method = __t.data('ajax-method') || $.SOW.core.ajax_content.config.method, 15799 __target = __t.data('ajax-target-container') || __containerID; 15800 15801 // Process! 15802 $.SOW.core.ajax_content.__ajaxDivProcess(__id, __url, __target, __method, __btnEl, __callback, __callbackBeforePush); 15803 // -- -- -- 15804 15805 } 15806 15807 }); 15808 15809 }, 15810 15811 15812 15813 15814 15815 15816 15817 /* 15818 15819 Function also called on reload ajax content! 15820 15821 _btnEl - is reload button element 15822 Used only on reload content to disable|enable on ajax process 15823 15824 */ 15825 __ajaxDivProcess: function(_id, _url, _target, _method, _btnEl, _callback, _callbackBeforePush) { 15826 15827 var _selector = this.selector; 15828 15829 15830 // Yeah, the ugliest bool fix ever. 15831 var _callbackBeforePush = _callbackBeforePush+'';
15832 var _callbackBeforePush = _callbackBeforePush.toLowerCase(); 15833 15834 15835 jQuery.ajax({ 15836 url: _url, 15837 type: _method, 15838 data: $.SOW.core.ajax_content.config.data_params, 15839 contentType: $.SOW.core.ajax_content.config.contentType, 15840 dataType: $.SOW.core.ajax_content.config.dataType, 15841 headers: $.SOW.core.ajax_content.config.headers, 15842 crossDomain: $.SOW.core.ajax_content.config.crossDomain, 15843 15844 beforeSend: function() { 15845 15846 // We don't show loading icon on load! 15847 // Let user show it's own loading message 15848 // Show loading only for "reload button" 15849 if(_btnEl) { 15850 15851 jQuery(_target).addClass('overlay-light overlay-opacity-6 overlay-over'); 15852 $.SOW.helper.loadingSpinner('show', _target); 15853 _btnEl.addClass('disabled active').prop('disabled', true); 15854 15855 } 15856 15857 }, 15858 15859 error: function(XMLHttpRequest, textStatus, errorThrown) { 15860 15861 $.SOW.helper.loadingSpinner('hide'); 15862 15863 if(typeof $.SOW.core.toast === 'object') { 15864 15865 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 15866 15867 } else { 15868 15869 alert("[404] Unexpected internal error!"); 15870 15871 } 15872 15873 // if debug enabled, see config 15874 $.SOW.helper.consoleLog('----------------------------'); 15875 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 15876 $.SOW.helper.consoleLog('DIV|SECTION ID: ' + _id); 15877 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 15878 $.SOW.helper.consoleLog(XMLHttpRequest); 15879 $.SOW.helper.consoleLog('2. textStatus:'); 15880 $.SOW.helper.consoleLog(textStatus); 15881 $.SOW.helper.consoleLog('3. errorThrown:'); 15882 $.SOW.helper.consoleLog(errorThrown); 15883 $.SOW.helper.consoleLog('----------------------------'); 15884 15885 }, 15886 15887 success: function(data) { 15888 15889 // Push data 15890 if(_callbackBeforePush == 'false') 15891 jQuery(_target).empty().html(data); 15892 15893 15894 // callback function 15895 if(_callback != '' && typeof $.SOW.helper.executeFunctionByName === "function") 15896 $.SOW.helper.executeFunctionByName(_callback, window, _id, _target, data); 15897 15898 15899 15900 // notice 15901 if(_callbackBeforePush == 'true' && _callback == '') 15902 $.SOW.helper.consoleLog('data-ajax-callback-function="" -BUT- data-ajax-callback-before-push="true"'); 15903 15904 15905 15906 // enable reload button 15907 // if(_btnEl) { 15908 15909 // Set a delay, so user know content loaded, if was too fast 15910 setTimeout(function() { 15911 $.SOW.helper.loadingSpinner('hide'); 15912 jQuery(_target).removeClass('overlay-light overlay-opacity-6 overlay-over'); 15913 15914 if(_btnEl) 15915 _btnEl.removeClass('disabled active').prop('disabled', false); 15916 15917 15918 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 15919 // reinit inside ajax container 15920 if(_callbackBeforePush == 'false') { 15921 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 15922 $.SOW.helper.consoleLog(scriptInfo, 'color: #6dbb30; font-weight: bold; font-size:14px;'); 15923 $.SOW.helper.consoleLog('Ajax Reinit For: ' + _target); 15924 $.SOW.helper.consoleLog(window.location.href); 15925 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 15926 15927 $.SOW.reinit(_target); 15928 15929 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 15930 } 15931 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 15932 15933 }, 300); 15934 15935 15936 // } 15937 15938 15939 15940 } 15941 15942 }); 15943 15944 return true; 15945 15946 }, 15947 15948 15949 15950 } 15951 15952})(jQuery); 15953/** 15954 * 15955 * [SOW] Ajax Form 15956 * 15957 * @author Dorin Grigoras 15958 * www.stepofweb.com 15959 * 15960 * @Dependency - 15961 * @Usage $.SOW.core.ajax_form.init('form.js-ajax'); 15962 * 15963 * 15964 **/ 15965;(function ($) { 15966 'use strict'; 15967 15968 15969 /** 15970 * 15971 * @vars 15972 * 15973 * 15974 **/ 15975 var scriptInfo = 'SOW Ajax Form'; 15976 15977 15978 15979 15980 $.SOW.core.ajax_form = { 15981 15982 15983 /** 15984 * 15985 * @config 15986 * 15987 * 15988 **/ 15989 config: { 15990 15991 method : 'GET', 15992 contentType : '', 15993 dataType : '', 15994 headers : '', 15995 crossDomain : '', 15996 15997 }, 15998 15999 16000 16001 /** 16002 * 16003 * @collection 16004 * 16005 * 16006 **/ 16007 collection: $(), 16008 16009 16010 16011 /** 16012 * 16013 * @init 16014 * 16015 * 16016 **/ 16017 init: function (selector, config) { 16018 16019 var __selector = $.SOW.helper.__selector(selector); 16020 var __config = $.SOW.helper.check_var(config); 16021 16022 this.selector = __selector[0]; // '#selector' 16023 this.collection = __selector[1]; // $('#selector') 16024 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 16025 16026 16027 16028 if(jQuery(this.selector).length < 1) 16029 return; 16030 16031 16032 // -- * -- 16033 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 16034 // -- * -- 16035 16036 16037 // 1. Has no selector 16038 if(!this.selector) { 16039 $.SOW.core.ajax_form.process($('form.js-ajax')); 16040 return this.collection; 16041 } 16042 16043 // 2. Has selector 16044 return this.collection.each(function() { 16045 16046 $.SOW.core.ajax_form.process($(this)); 16047 16048 }); 16049 16050 }, 16051 16052 16053 16054 /** 16055 * 16056 * @ajax_form 16057 * 16058 3. FORMS 16059 16060 16061 EXAMPLE USAGE. (form.js-ajax - REQUIRED) 16062 16063 <form class="js-ajax bs-validate" novalidate action="YOUR_URL" data-ajax-container="#ajax_container" data-ajax-update-url="true"> 16064 16065 <input required type="text" name="first_name" value="" placeholder="first name" class="form-control mb-4"> 16066 <input type="text" name="birthdate" value="" placeholder="birthdate" class="form-control mb-4"> 16067 16068 <!-- 16069 Error Notice - more visible 16070 16071 Instead of this alert, you can use a toast alert instead by adding to form: 16072 data-error-toast-text="<i class='fi fi-circle-spin fi-spin float-start'></i> Please, complete all required fields!" 16073 data-error-toast-delay="3000" 16074 data-error-toast-position="top-right" 16075 16076 --> 16077 <div class="bs-validate-info hide alert alert-danger" data-error-alert-delay="4000"> 16078 <i class="fi fi-circle-spin fi-spin float-start"></i> 16079 Please, complete all required fields! 16080 </div> 16081 16082 <button type="submit" class="btn btn-primary">Submit</button> 16083 </form> 16084 16085 16086 <!-- position relative|fixed|absolute is required for loading icon --> 16087 <div id="ajax_container" class="position-relative w--500 pl--30 pr--30 pt--80 pb--80"> 16088 <!-- RESPONSE ADDED HERE, IF NEEDED --> 16089 </div> 16090 16091 16092 ajax-callback-function="" - used to handle the response, instead of appending the response to a container 16093 * 16094 * 16095 **/ 16096 process: function(_this) { 16097 16098 var _selector = this.selector; 16099 var _selector_orig = this.selector_orig; 16100 16101 _this.submit(function(e) { 16102 16103 var _t = _this, 16104 _formID = _t.attr('id') || '', 16105 _action = _t.attr('action') || '', 16106 _callback = _t.attr('data-ajax-callback-function') || '', 16107 _method = _t.attr('method') || $.SOW.core.ajax_form.config.method, 16108 _updateURL = _t.attr('data-ajax-update-url') || 'false', 16109 _scrollErrUp = _t.attr('data-error-scroll-up') || 'false', 16110 _showLoadingIcon = _t.attr('data-ajax-show-loading-icon') || 'true', 16111 _contentType = _t.data('ajax-contentType') || '', 16112 _dataType = _t.data('ajax-dataType') || '', 16113 _target = _t.data('ajax-container') || '', 16114 _toast_text = _t.data('error-toast-text') || '', // toast alert for .bs-validate 16115 _toast_delay = _t.data('error-toast-delay') || 0, // toast alert for .bs-validate 16116 _toast_pos = _t.data('error-toast-position') || "top-right", // toast alert for .bs-validate 16117 _toast_success = _t.data('success-toast-text') || "", 16118 16119 _controlAlerts = _t.attr('data-ajax-control-alerts') || "false", 16120 _controlSuccess = _t.attr('data-ajax-control-alert-succes') || "", 16121 _controlUnexpected = _t.attr('data-ajax-control-alert-unexpected') || "", 16122 _controlMandatory = _t.attr('data-ajax-control-alert-mandaroty') || "", 16123 16124 // show|hide container for error|success 16125 _onSucessShow = _t.data('ajax-inline-alert-succes') || '', 16126 _onErrorShow = _t.data('ajax-inline-alert-error') || '', 16127 16128 // autoclose modal on success 16129 _modalCloseOnSuccess = _t.data('modal-autoclose-on-success') || 'false', 16130 _modalCloseOnSuccessDelay = _t.data('modal-autoclose-on-success-delay') || 0; 16131 16132 if(_onSucessShow != '' || _onErrorShow != '') { 16133 if(_target == '#middle') 16134 _target = ''; 16135 } 16136 16137 // the most uglies bool hack 16138 var _scrollErrUp = _scrollErrUp+''; 16139 var _updateURL = _updateURL+''; 16140 16141 // Assign a random id if not exist 16142 if(_formID == '') { 16143 var _formID = 'js_' + $.SOW.helper.randomStr(10); 16144 _t.attr('id', _formID); 16145 } 16146 16147 // Bootstrap Validation +++++++++++++++++++++++++++++++++++++++++++++++++++ 16148 // This part already exists in _formvalidate.js 16149 // We use it again here in case the file is not loaded! 16150 16151 // default reset 16152 window.ajax_form_stop = false;
16153 16154 // Form Element 16155 var _form = document.getElementById(_formID); 16156 16157 if(_t.hasClass('bs-validate')) { 16158 16159 // hide all errors info 16160 jQuery('.bs-validate-info').addClass('hide hide-force'); 16161 16162 if(typeof $.SOW.core.toast === 'object') 16163 $.SOW.core.toast.destroy(); 16164 16165 if(_form.checkValidity() === false) { 16166 16167 16168 // -- message|toast --- 16169 if(_toast_text != '') { 16170 16171 if(typeof $.SOW.core.toast === 'object') { 16172 16173 if(Number(_toast_delay) < 1) 16174 var _toast_delay = 4000; 16175 16176 $.SOW.core.toast.show('danger', '', _toast_text, _toast_pos, Number(_toast_delay), true); 16177 16178 } else { 16179 16180 alert(_toast_text); 16181 16182 } 16183 16184 } else { 16185 16186 // show error info 16187 jQuery('.bs-validate-info', _t).removeClass('hide hide-force'); // show error info 16188 16189 // error info delay timeout 16190 var _delay = jQuery('.bs-validate-info', _t).data('error-alert-delay') || 3000; 16191 16192 // hide error info in X seconds 16193 setTimeout(function() { 16194 jQuery('.bs-validate-info', _t).addClass('hide hide-force'); 16195 }, Number(_delay)); 16196 16197 } 16198 // -- -- -- -- 16199 16200 // show|hide custom containers 16201 if(_onErrorShow != '') { 16202 jQuery(_onSucessShow).addClass('hide hide-force'); 16203 jQuery(_onErrorShow).removeClass('hide hide-force'); 16204 } 16205 16206 // Focus invalid element and scroll 16207 jQuery('.form-control:invalid', _t).first().focus(); 16208 16209 // Do not animate inside modal! 16210 if(typeof $.SOW.helper.scrollAnimate === "function" && _scrollErrUp == 'true' && !jQuery('.modal').hasClass('show')) { 16211 var _formEl = jQuery('input:invalid, select:invalid, textarea:invalid', _t); 16212 $.SOW.helper.scrollAnimate(_formEl, 0, false, 200); 16213 } 16214 // -- -- -- -- 16215 16216 e.preventDefault(); 16217 e.stopPropagation(); 16218 window.ajax_form_stop = true; 16219 } 16220 16221 16222 _t.addClass('was-validated'); 16223 16224 16225 // Stop here! 16226 if(window.ajax_form_stop === true) 16227 return; 16228 16229 } else { 16230 16231 if(_form.checkValidity() === false) { 16232 16233 e.preventDefault(); 16234 e.stopPropagation(); 16235 window.ajax_form_stop = true; 16236 } 16237 16238 } 16239 16240 // Stop here! 16241 if(window.ajax_form_stop === true) 16242 return; 16243 16244 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 16245 16246 16247 // Start the show 16248 e.preventDefault(); 16249 16250 if(_action == '') { 16251 16252 $.SOW.helper.consoleLog('Ajax request: form action missing!'); 16253 16254 if(typeof $.SOW.core.toast === 'object') { 16255 16256 $.SOW.core.toast.show('danger', 'Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 16257 16258 } else { 16259 16260 alert("[404] Unexpected internal error!"); 16261 16262 } 16263 16264 return; 16265 } 16266 16267 16268 if(_method.toLowerCase() == 'post') { 16269 16270 var formData = new FormData(this); 16271 var __processData = false; 16272 var __contentType = false; 16273 16274 } else { 16275 16276 var __processData = true; 16277 var __contentType = _contentType || $.SOW.core.ajax_form.config.contentType; 16278 var formData = _t.serializeArray(); 16279 16280 } 16281 16282 16283 jQuery.ajax({ 16284 url: _action, 16285 data: formData, 16286 type: _method, 16287 dataType: _dataType || $.SOW.core.ajax_form.config.dataType, 16288 headers: $.SOW.core.ajax_form.config.headers, 16289 crossDomain: $.SOW.core.ajax_form.config.crossDomain, 16290 contentType: __contentType, 16291 processData: __processData, 16292 cache: false, 16293 16294 beforeSend: function() { 16295 16296 // icon over form 16297 if(_showLoadingIcon == 'true') 16298 $.SOW.helper.loadingSpinner('show', _t); 16299 16300 // Disable submit button 16301 jQuery(this).attr('disabled', true).addClass('disabled'); 16302 16303 }, 16304 16305 error: function(XMLHttpRequest, textStatus, errorThrown) { 16306 16307 // if debug enabled, see config 16308 if($.SOW.config.sow__debug_enable === true) { 16309 16310 $.SOW.helper.consoleLog('----------------------------'); 16311 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 16312 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 16313 $.SOW.helper.consoleLog(XMLHttpRequest); 16314 $.SOW.helper.consoleLog('2. textStatus:'); 16315 $.SOW.helper.consoleLog(textStatus); 16316 $.SOW.helper.consoleLog('3. errorThrown:'); 16317 $.SOW.helper.consoleLog(errorThrown); 16318 $.SOW.helper.consoleLog('----------------------------'); 16319 16320 } 16321 16322 $.SOW.helper.loadingSpinner('hide'); 16323 16324 if(typeof $.SOW.core.toast === 'object') { 16325 16326 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', _toast_pos, 0, true); 16327 16328 } else { 16329 16330 alert("[404] Unexpected internal error!"); 16331 16332 } 16333 16334 // show|hide custom containers 16335 if(_onErrorShow != '') { 16336 jQuery(_onSucessShow).addClass('hide hide-force'); 16337 jQuery(_onErrorShow).removeClass('hide hide-force'); 16338 } 16339 16340 // Enable submit button 16341 jQuery(this).attr('disabled', false).removeClass('disabled'); 16342 }, 16343 16344 success: function(data) { 16345 16346 $.SOW.helper.loadingSpinner('hide'); 16347 $.SOW.helper.consoleLog(data); 16348 16349 // Enable submit button 16350 jQuery(this).attr('disabled', false).removeClass('disabled'); 16351 var hasErrors = false;
16352 16353 // Control alerts 16354 if(_controlAlerts+'' == 'true') { 16355 16356 // reset first 16357 var hasErrors = true; 16358 jQuery(_controlSuccess).addClass('hide hide-force'); 16359 jQuery(_controlUnexpected).addClass('hide hide-force'); 16360 jQuery(_controlMandatory).addClass('hide hide-force'); 16361 16362 if(data == '{:success:}') { 16363 jQuery(_controlSuccess).removeClass('hide hide-force'); 16364 var hasErrors = false; 16365 var data = ''; 16366 } 16367 16368 else if(data == '{:err:required:}') 16369 jQuery(_controlMandatory).removeClass('hide hide-force'); 16370 16371 else if(data == '{:err:unexpected:}') 16372 jQuery(_controlUnexpected).removeClass('hide hide-force'); 16373 16374 16375 if(hasErrors === true) { 16376 16377 // this is a server message - debug only! 16378 if($.SOW.config.sow__debug_enable === true) 16379 jQuery(_target).empty().html(data); 16380 else 16381 jQuery(_target).empty().html('Server Error!'); 16382 16383 16384 _t.removeClass('was-validated'); 16385 return; 16386 } 16387 16388 } 16389 16390 16391 16392 // Callbat and/or Reset 16393 if(_callback == '') { 16394 16395 // Reset Form 16396 jQuery('input:not([type=hidden])', _t).val(''); 16397 jQuery('textarea:not(.hide)', _t).val(''); 16398 16399 if(_target != '') 16400 jQuery(_target).empty().html(data); 16401 16402 // reset form validation 16403 _t.removeClass('was-validated'); 16404 16405 } else { 16406 16407 if(typeof $.SOW.helper.executeFunctionByName === "function") 16408 $.SOW.helper.executeFunctionByName(_callback, window, _t, data); 16409 16410 } 16411 16412 16413 16414 // Update URL 16415 if(_updateURL == 'true' && $.SOW.core.ajax_navigation === 'object') 16416 $.SOW.core.ajax_navigation.__historyPushState(_action, '', data); 16417 16418 16419 if(_target != '' && typeof $.SOW.helper.scrollAnimate === "function" && _scrollErrUp == 'true') { 16420 var _elResponse = jQuery(_target || _onSucessShow); 16421 if(_elResponse.length) 16422 $.SOW.helper.scrollAnimate(_elResponse, 0, false, 200); 16423 } 16424 16425 16426 // show|hide custom containers 16427 if(_onSucessShow != '') { 16428 jQuery(_onSucessShow).removeClass('hide hide-force'); 16429 jQuery(_onErrorShow).addClass('hide hide-force'); 16430 } 16431 16432 16433 16434 // if form is on modal 16435 if(_modalCloseOnSuccess+'' == 'true') { 16436 16437 setTimeout(function() { 16438 jQuery('#sow_ajax_modal').modal('hide'); 16439 }, Number(_modalCloseOnSuccessDelay)); 16440 16441 } 16442 16443 16444 // success tost, if text provided 16445 if(typeof $.SOW.core.toast === 'object' && _toast_success != '') 16446 $.SOW.core.toast.show('success', '', _toast_success, _toast_pos, 1500, true); 16447 16448 16449 } 16450 16451 }); 16452 16453 16454 }); 16455 16456 16457 }, 16458 16459 } 16460 16461})(jQuery); 16462/** 16463 * 16464 * [SOW] Ajax Select 16465 * 16466 * @author Dorin Grigoras 16467 * www.stepofweb.com 16468 * 16469 * @Dependency - 16470 * @Usage $.SOW.core.ajax_select.init('select.js-ajax'); 16471 * 16472 * 16473 **/ 16474;(function ($) { 16475 'use strict'; 16476 16477 16478 /** 16479 * 16480 * @vars 16481 * 16482 * 16483 **/ 16484 var scriptInfo = 'SOW Ajax Select'; 16485 window.ajax_select_chain_process = null; 16486 16487 16488 16489 $.SOW.core.ajax_select = { 16490 16491 16492 /** 16493 * 16494 * @config 16495 * 16496 * 16497 **/ 16498 config: { 16499 16500 method : 'GET', 16501 contentType : '', 16502 dataType : '', 16503 headers : '', 16504 crossDomain : '', 16505 data_params : {ajax:'true'}, 16506 16507 /* 16508 callback_example = function(el, data, modal_container) { 16509 // el = element $(this) 16510 // data = server response (html|string) 16511 // modal_container = container to push data (string) 16512 } 16513 */ 16514 callback_function : '' 16515 }, 16516 16517 16518 16519 /** 16520 * 16521 * @collection 16522 * 16523 * 16524 **/ 16525 collection: $(), 16526 16527 16528 16529 /** 16530 * 16531 * @init 16532 * 16533 * 16534 **/ 16535 init: function (selector, config) { 16536 16537 var __selector = $.SOW.helper.__selector(selector); 16538 var __config = $.SOW.helper.check_var(config); 16539 16540 this.selector = __selector[0]; // '#selector' 16541 this.collection = __selector[1]; // $('#selector') 16542 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 16543 16544 16545 16546 if(jQuery(this.selector).length < 1) 16547 return; 16548 16549 16550 // -- * -- 16551 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 16552 // -- * -- 16553 16554 16555 // 1. Has no selector 16556 if(!this.selector) { 16557 $.SOW.core.ajax_select.process($('select.js-ajax')); 16558 return this.collection; 16559 } 16560 16561 // 2. Has selector 16562 return this.collection.each(function() { 16563 16564 $.SOW.core.ajax_select.process($(this)); 16565 16566 }); 16567 16568 }, 16569 16570 16571 16572 /** 16573 * 16574 * @process 16575 * 16576 * 16577 **/ 16578 process: function(_this) { 16579 16580 16581 /** 16582 16583 Form Populate 16584 16585 **/ 16586 var populate_form = _this.data('form-target') || ''; 16587 if(populate_form != '') { 16588 16589 _this.not('.js-ajaxified').addClass('js-ajaxified').on('change', function() { 16590 16591 var _method = _this.data('ajax-method') || $.SOW.core.ajax_select.config.method, 16592 _url = _this.data('ajax-url') || '', 16593 _params = _this.data('ajax-params') || '', 16594 _thisVal = _this.val() || '', 16595 data_params = $.SOW.core.ajax_select.config.data_params; 16596 data_params['value'] = _thisVal; 16597 16598 if(_url == '') 16599 return; 16600 16601 16602 // reset 16603 if(_thisVal == '') { 16604 16605 jQuery('input[type=text], input[type=number], input[type=tel], textarea', populate_form).val(''); 16606 jQuery('input[type=checkbox]', populate_form).prop('checked', false); 16607 16608 jQuery('select', populate_form).val(0); 16609 16610 // Refresh bootstrap select
16611 if(typeof $.SOW.vendor.bootstrap_select === 'object') 16612 $.SOW.vendor.bootstrap_select.refresh(_el); 16613 16614 return; 16615 } 16616 16617 16618 16619 if(_params != '') { 16620 16621 var ajax_params_arr = $.SOW.helper.params_parse(_params); 16622 for (var i = 0; i < ajax_params_arr.length; ++i) { 16623 data_params[ajax_params_arr[i][0]] = ajax_params_arr[i][1]; 16624 } 16625 16626 } 16627 16628 16629 jQuery.ajax({ 16630 url: _url, 16631 type: _method, 16632 data: data_params, 16633 contentType: $.SOW.core.ajax_select.config.contentType, 16634 dataType: $.SOW.core.ajax_select.config.dataType, 16635 headers: $.SOW.core.ajax_select.config.headers, 16636 crossDomain: $.SOW.core.ajax_select.config.crossDomain, 16637 16638 beforeSend: function() { 16639 $.SOW.helper.consoleLog('Params request sent to the server:'); 16640 $.SOW.helper.consoleLog(_url); 16641 $.SOW.helper.consoleLog(data_params); 16642 }, 16643 16644 error: function(XMLHttpRequest, textStatus, errorThrown) { 16645 16646 // if debug enabled, see config 16647 if($.SOW.config.sow__debug_enable === true) { 16648 16649 $.SOW.helper.consoleLog('----------------------------'); 16650 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 16651 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 16652 $.SOW.helper.consoleLog(XMLHttpRequest); 16653 $.SOW.helper.consoleLog('2. textStatus:'); 16654 $.SOW.helper.consoleLog(textStatus); 16655 $.SOW.helper.consoleLog('3. errorThrown:'); 16656 $.SOW.helper.consoleLog(errorThrown); 16657 $.SOW.helper.consoleLog('----------------------------'); 16658 16659 } 16660 16661 if(typeof $.SOW.core.toast === 'object') { 16662 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 16663 } else { 16664 alert("[404] Unexpected internal error!"); 16665 } 16666 16667 }, 16668 16669 success: function(data) { 16670 16671 if(typeof data !== 'object') { 16672 $.SOW.helper.consoleLog('----------------------------'); 16673 $.SOW.helper.consoleLog('Select Form Populate : Not JSON! Aborting...'); 16674 $.SOW.helper.consoleLog('----------------------------'); 16675 return; 16676 } 16677 16678 for(var i = 0; i < data.length; i++) { 16679 16680 for(var key in data[i]) { 16681 16682 var _el = $(populate_form + ' #' + key); 16683 if(_el.length < 1) 16684 var _el = $(populate_form + ' .' + key); 16685 if(_el.length < 1) 16686 continue; 16687 16688 16689 // file : skip 16690 if(_el.attr('type') == 'file') 16691 continue; 16692 16693 // checkbox & radio 16694 if(_el.attr('type') == 'checkbox' || _el.attr('type') == 'radio') 16695 if(data[i][key] > 0 || data[i][key] == true) { _el.prop('checked', true); } else { _el.prop('checked', false); } 16696 16697 // input 16698 else if(_el.is('input')) 16699 _el.val(data[i][key]); 16700 16701 // textarea 16702 else if(_el.is('textarea')) 16703 _el.val(data[i][key]); 16704 16705 // select 16706 else if(_el.is('select')) { 16707 16708 _el.val(data[i][key]); 16709 16710 // Refresh bootstrap select 16711 if(typeof $.SOW.vendor.bootstrap_select === 'object') 16712 $.SOW.vendor.bootstrap_select.refresh(_el); 16713 16714 } 16715 16716 } 16717 16718 16719 } 16720 16721 16722 } 16723 16724 }); 16725 16726 }); 16727 16728 return; 16729 } 16730 16731 16732 16733 16734 16735 16736 /** 16737 16738 Self Populate 16739 16740 **/ 16741 var self_populate_url = _this.data('ajax-url-self-populate') || ''; 16742 16743 if(self_populate_url != '') { 16744 16745 var _method = _this.data('ajax-method') || $.SOW.core.ajax_select.config.method, 16746 _params = _this.data('ajax-params') || '', 16747 _callback = _this.data('ajax-callback-function') || $.SOW.core.ajax_select.config.callback_function, 16748 data_params = $.SOW.core.ajax_select.config.data_params, 16749 16750 _val = '', 16751 _label = ':on_load:'; 16752 16753 if(_params != '') { 16754 16755 var ajax_params_arr = $.SOW.helper.params_parse(_params); 16756 for (var i = 0; i < ajax_params_arr.length; ++i) { 16757 data_params[ajax_params_arr[i][0]] = ajax_params_arr[i][1]; 16758 } 16759 16760 } 16761 16762 16763 $.SOW.core.ajax_select.ajax_process(self_populate_url, _method, data_params, _this, _val, _label, _this, _callback, 'self'); 16764 16765 } 16766 16767 16768 16769 16770 16771 16772 /** 16773 16774 Populate on change 16775 16776 **/ 16777 _this.not('.js-ajaxified').addClass('js-ajaxified').on('change', function() { 16778 16779 var _t = jQuery(this), 16780 _val = _t.val() || '', 16781 _label = jQuery('option:selected', _t).text() || '', 16782 _callback = _t.data('ajax-callback-function') || $.SOW.core.ajax_select.config.callback_function, 16783 _target = _t.data('ajax-target') || ''; 16784 16785 if(_target != '') { 16786 16787 // Get url from #target 16788 var el_target = jQuery(_target), 16789 _url = el_target.data('ajax-url') || '', 16790 _method = el_target.data('ajax-method') || $.SOW.core.ajax_select.config.method, 16791 _params = el_target.data('ajax-params') || '', 16792 data_params = $.SOW.core.ajax_select.config.data_params; 16793 16794 16795 if(_url != '') { 16796 16797 if(_params != '') { 16798 16799 var ajax_params_arr = $.SOW.helper.params_parse(_params); 16800 for (var i = 0; i < ajax_params_arr.length; ++i) { 16801 data_params[ajax_params_arr[i][0]] = ajax_params_arr[i][1]; 16802 } 16803 16804 } 16805 16806 data_params['value'] = _val; 16807 16808 16809 $.SOW.core.ajax_select.ajax_process(_url, _method, data_params, el_target, _val, _label, _t, _callback, 'target'); 16810 16811 } 16812 16813 } 16814 16815 16816 16817 16818 16819 16820 16821 16822 16823 /** 16824 16825 Show container 16826 16827 **/ 16828 // hide all first 16829 _t.children('option').each(function() { 16830 var __t = jQuery(this).data('show-container') || ''; 16831 if(__t != '') 16832 jQuery(__t).addClass('hide hide-force'); 16833 }); 16834 16835 // show selected 16836 var _container = _t.find(':selected').data('show-container') || ''; 16837 if(_container != '') 16838 jQuery(_container).removeClass('hide hide-force'); 16839 16840 }); 16841 16842 16843 }, 16844 16845 16846 16847 16848 16849 /** 16850 * 16851 * @ajax_process 16852 * 16853 * 16854 **/
16855 ajax_process: function(_url, _method, data_params, el_target, _val, _label, _t, _callback, process_type) { 16856 16857 jQuery.ajax({ 16858 url: _url, 16859 type: _method, 16860 data: data_params, 16861 contentType: $.SOW.core.ajax_select.config.contentType, 16862 dataType: $.SOW.core.ajax_select.config.dataType, 16863 headers: $.SOW.core.ajax_select.config.headers, 16864 crossDomain: $.SOW.core.ajax_select.config.crossDomain, 16865 16866 beforeSend: function() {}, 16867 16868 error: function(XMLHttpRequest, textStatus, errorThrown) { 16869 16870 // if debug enabled, see config 16871 if($.SOW.config.sow__debug_enable === true) { 16872 16873 $.SOW.helper.consoleLog('----------------------------'); 16874 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 16875 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 16876 $.SOW.helper.consoleLog(XMLHttpRequest); 16877 $.SOW.helper.consoleLog('2. textStatus:'); 16878 $.SOW.helper.consoleLog(textStatus); 16879 $.SOW.helper.consoleLog('3. errorThrown:'); 16880 $.SOW.helper.consoleLog(errorThrown); 16881 $.SOW.helper.consoleLog('----------------------------'); 16882 16883 } 16884 16885 if(typeof $.SOW.core.toast === 'object') { 16886 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 16887 } else { 16888 alert("[404] Unexpected internal error!"); 16889 } 16890 16891 }, 16892 16893 success: function(data) { 16894 16895 var selected_val = _val; 16896 var selected_label = _label; 16897 var process_recursive = null; 16898 var process_recursive_selected = ''; 16899 16900 $.SOW.helper.consoleLog(data); 16901 16902 // remove disabled 16903 el_target.removeAttr('disabled'); 16904 16905 16906 try { 16907 16908 var _data = JSON.parse(data); 16909 16910 } catch(err) { 16911 16912 var _data = data; 16913 16914 } var data = null; // clear/reset 16915 16916 16917 // Clear select 16918 el_target.find('option').remove(); 16919 16920 if(_data.length > 0) { 16921 16922 // Walk through json data 16923 for (var i = 0; i < _data.length; i++) { 16924 16925 if(typeof _data[i]['label'] === 'undefined') 16926 continue; 16927 16928 if(typeof _data[i]['value'] === 'undefined') 16929 _data[i]['value'] = ''; 16930 16931 if(_data[i]['label'] == '' && _data[i]['value'] == '') 16932 continue; 16933 16934 // -- -- -- 16935 var o = new Option(_data[i]['label'], _data[i]['value']); 16936 jQuery(o).html(_data[i]['label']); 16937 16938 // selected 16939 if(typeof _data[i]['selected'] !== 'undefined' && _data[i]['selected'] == true) { 16940 jQuery(o).attr('selected', 'selected'); 16941 var process_recursive_selected = _data[i]['value']; 16942 } 16943 16944 // show container 16945 if(typeof _data[i]['show_container'] !== 'undefined') { 16946 jQuery(o).attr('data-show-container', _data[i]['show_container']); 16947 16948 if(process_recursive_selected == _data[i]['value']) 16949 jQuery(_data[i]['show_container']).removeClass('hide hide-force'); 16950 } 16951 16952 16953 el_target.append(o); 16954 // -- -- -- 16955 16956 16957 if(_data[i]['selected'] && _data[i]['selected'] === true) { 16958 // var selected_val = _data[i]['value'], 16959 // selected_label = _data[i]['label']; 16960 16961 if(process_type === 'self') 16962 var process_recursive = true; 16963 16964 } 16965 16966 16967 } 16968 16969 } else { 16970 16971 // set disabled 16972 el_target.prop('disabled', true).attr('disabled', ''); 16973 16974 } 16975 16976 16977 // Refresh bootstrap select 16978 if(typeof $.SOW.vendor.bootstrap_select === 'object') 16979 $.SOW.vendor.bootstrap_select.refresh(el_target); 16980 16981 16982 setTimeout(function () { 16983 16984 // Callback
16985 if(_callback != '' && typeof _callback !== 'undefined') 16986 $.SOW.core.ajax_select.ajax_callback(_callback, _t, selected_val, selected_label); 16987 16988 16989 16990 /** 16991 16992 Callback on change 16993 16994 **/ 16995 if(el_target !== null) { 16996 16997 el_target.not('.js-callbackified').addClass('js-callbackified').on('change', function() { 16998 16999 var _t = jQuery(this), 17000 _val = _t.val() || '', 17001 _label = _t.find('option:selected').text() || '', 17002 _callback = _t.data('ajax-callback-function') || $.SOW.core.ajax_select.config.callback_function; 17003 17004 17005 // Callback 17006 if(_callback != '' && typeof _callback !== 'undefined') 17007 $.SOW.core.ajax_select.ajax_callback(_callback, _t, _val, _label); 17008 17009 }); 17010 17011 } 17012 17013 17014 17015 /** 17016 17017 Recursive 17018 Used by select on load 17019 data-ajax-url-self-populate 17020 17021 **/ 17022 if(process_recursive === true && el_target.data('ajax-target')) { 17023 17024 // Get url from #target 17025 var _selector = el_target.data('ajax-target') || '', 17026 el_target2 = jQuery(_selector), 17027 _url = el_target2.data('ajax-url') || '', 17028 _method = el_target2.data('ajax-method') || $.SOW.core.ajax_select.config.method, 17029 _params = el_target2.data('ajax-params') || '', 17030 data_params = $.SOW.core.ajax_select.config.data_params; 17031 17032 if(_url == '') 17033 return; 17034 17035 if(_params != '') { 17036 17037 var ajax_params_arr = $.SOW.helper.params_parse(_params); 17038 for (var i = 0; i < ajax_params_arr.length; ++i) { 17039 data_params[ajax_params_arr[i][0]] = ajax_params_arr[i][1]; 17040 } 17041 17042 } 17043 17044 data_params['value'] = process_recursive_selected; 17045 17046 17047 $.SOW.core.ajax_select.ajax_process(_url, _method, data_params, el_target2, '', '', el_target, _callback, 'target'); 17048 17049 } 17050 17051 }, 100); 17052 17053 17054 } 17055 17056 }); 17057 17058 }, 17059 17060 17061 17062 17063 /** 17064 * 17065 * @ajax_callback 17066 * 17067 * 17068 **/ 17069 ajax_callback: function(_callback, _t, value, label) { 17070 17071 if(_callback != '' && typeof $.SOW.helper.executeFunctionByName === 'function') 17072 $.SOW.helper.executeFunctionByName(_callback, window, _t, value, label); 17073 17074 } 17075 17076 } 17077 17078})(jQuery); 17079/** 17080 * 17081 * [SOW] Ajax Modal 17082 * 17083 * @author Dorin Grigoras 17084 * www.stepofweb.com 17085 * 17086 * @Dependency - 17087 * @Usage $.SOW.core.ajax_modal.init('.js-ajax-modal'); 17088 * 17089 // Programtically Create Modal : url , 'modal-md', 'true' (centered), 'backdrop' (optional), callback (optional) 17090 $.SOW.core.ajax_modal.createFromThinAir(modalUrl, 'modal-lg', 'true', 'static', callback); 17091 17092 // Programtically Attach Element/Link ( $('.selector') or '.selector' ) 17093 $.SOW.core.ajax_modal.attach(selector); 17094 17095 * 17096 **/ 17097;(function ($) { 17098 'use strict'; 17099 17100 17101 /** 17102 * 17103 * @vars 17104 * 17105 * 17106 **/ 17107 var scriptInfo = 'SOW Ajax Modal'; 17108 17109 17110 17111 $.SOW.core.ajax_modal = { 17112 17113 17114 /** 17115 * 17116 * @config 17117 * 17118 * 17119 **/ 17120 config: { 17121 method : 'GET', 17122 contentType : '', // jQuery params 17123 dataType : '', // jQuery params 17124 headers : '', // jQuery params 17125 crossDomain : '', // jQuery params 17126 data_params : {ajax:'true'}, 17127 17128 modal_container : '#sow_ajax_modal', 17129 modal_size : 'modal-md', 17130 modal_centered : 'false', 17131 17132 /* 17133 callback_example = function(el, data, modal_container) { 17134 // el = element $(this) 17135 // data = server response (html|string) 17136 // modal_container = container to push data (string:#middle) 17137 } 17138 */ 17139 callback_function : '' 17140 }, 17141 17142 17143 17144 /** 17145 * 17146 * @collection 17147 * 17148 * 17149 **/ 17150 collection: $(), 17151 17152 17153 17154 /** 17155 * 17156 * @init 17157 * 17158 * 17159 **/ 17160 init: function (selector, config) { 17161 17162 var __selector = $.SOW.helper.__selector(selector); 17163 var __config = $.SOW.helper.check_var(config); 17164 17165 this.selector = __selector[0]; // '#selector' 17166 this.collection = __selector[1]; // $('#selector') 17167 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 17168 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 17169 17170 17171 if(jQuery(this.selector).length < 1) 17172 return; 17173 17174 17175 // -- * -- 17176 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 17177 // -- * -- 17178 17179 17180 // Create modal container 17181 $.SOW.core.ajax_modal.ajax_modal_template(); 17182 17183 17184 17185 // 1. Has no selector 17186 if(!this.selector) { 17187 $.SOW.core.ajax_modal.ajax_modal($('.js-ajax-modal')); 17188 return $('.js-ajax-modal'); 17189 } 17190 17191 // 2. Has selector 17192 return this.collection.each(function() { 17193 17194 $.SOW.core.ajax_modal.ajax_modal($(this)); 17195 17196 }); 17197 17198 }, 17199 17200 17201 17202 /** 17203 * 17204 * @ajax_modal 17205 * 17206 * 17207 * 17208 **/
17209 ajax_modal: function(_this) { 17210 17211 var _selector = this.selector, 17212 _selector_orig = this.selector_orig, 17213 _modal_container = this.config.modal_container, 17214 _modal_size = this.config.modal_size, 17215 _callback = this.config.callback_function, 17216 _method = this.config.method, 17217 _modal_centered = this.config.modal_centered; 17218 17219 // precech to avoid useless bind. checked again on click! 17220 var _href = _this.attr('href') || '', 17221 _href_data = _this.data('href') || ''; 17222 17223 if(_href_data != '') 17224 _href = _href_data; 17225 17226 if(_href == '') 17227 return; 17228 17229 17230 17231 _this.not('.js-modalified').addClass('js-modalified').on('click', function(e) { 17232 e.preventDefault(); 17233 17234 var _t = jQuery(this), 17235 _href = _t.attr('href') || '', 17236 _href_data = _t.data('href') || '', 17237 _modalType = _t.attr('data-ajax-modal-type') || '', // video (or more in the future) 17238 _target = _t.data('ajax-modal-container') || _modal_container, 17239 _modal_callback = _t.data('ajax-modal-callback-function') || _callback, // callback function to call, on modal load 17240 _modal_size = _t.data('ajax-modal-size') || _modal_size, // modal-sm, modal-md, modal-lg , modal-full 17241 _modal_backgdrop = _t.data('ajax-modal-backdrop') || '', // data-backdrop="static" - do not close on click 17242 _modal_centered = _t.data('ajax-modal-centered') || _modal_centered, // true|false 17243 _method = _t.data('ajax-modal-method') || _method; // true|false 17244 17245 if(_href_data != '') 17246 _href = _href_data; 17247 17248 if(_href == '' || _href == '#' || _href == 'javascript:;') 17249 return; 17250 17251 17252 // Ignore by request! 17253 if(_t.hasClass('js-ignore')) 17254 return; 17255 17256 17257 /* 17258 Empty ajax modal on close 17259 else, plugins like selectpicker will not refresh 17260 */ jQuery(_target + ' .modal-content').empty(); 17261 17262 17263 17264 // Close any open dropdown 17265 jQuery('.dropdown-menu:not(.dropdown-menu-hover)').parent().find('a[data-toggle="dropdown"][aria-expanded="true"]').attr('aria-expanded', 'false').dropdown('hide'); 17266 17267 // Call the trigger 17268 $.SOW.core.ajax_modal.modalAjaxShow(_href, _target, _modal_size, _modal_centered, _modal_backgdrop, _modal_callback, _method, _modalType); 17269 17270 }); 17271 17272 17273 // Modals on load 17274 $.SOW.core.ajax_modal.ajax_modal_onLoad(); 17275 17276 }, 17277 17278 /** 17279 * 17280 * Ajax Process 17281 * :: Helper 17282 * 17283 **/ 17284 modalAjaxShow: function(_href, _target, _modal_size, _modal_centered, _modal_backgdrop, _modal_callback, _method, _modalType) { 17285 17286 var _modal_size = typeof _modal_size !== 'undefined' ? _modal_size : this.config.modal_size; 17287 var _modal_centered = typeof _modal_centered !== 'undefined' ? _modal_centered : this.config.modal_centered; 17288 var _modal_backgdrop = typeof _modal_backgdrop !== 'undefined' ? _modal_backgdrop : ''; 17289 var _modal_callback = typeof _modal_callback !== 'undefined' ? _modal_callback : ''; 17290 17291 17292 // Create modal container (if not exists) 17293 $.SOW.core.ajax_modal.ajax_modal_template(); 17294 17295 17296 if(_href == '#' || _href == '') 17297 return; 17298 17299 if(_target == '') 17300 var _target = this.config.modal_container; 17301 17302 if(_modal_size == '') 17303 var _modal_size = this.config.modal_size; // modal-lg , modal-full 17304 17305 // -- 17306 17307 17308 // Remove any known size class 17309 jQuery('.modal-dialog', _target).removeClass('modal-dialog-centered modal-sm modal-lg modal-xl modal-full'); 17310 17311 // Add size class by request 17312 if(_modal_size != '') 17313 jQuery('.modal-dialog', _target).addClass(_modal_size); 17314 17315 // centered 17316 if(_modal_centered == true) 17317 jQuery('.modal-dialog', _target).addClass('modal-dialog-centered'); 17318 17319 // static, do not close on click 17320 if(_modal_backgdrop != '') { 17321 var _backdrop = 'static'; 17322 var _keyboard = false; 17323 } else { 17324 var _backdrop = 'dynamic'; 17325 var _keyboard = true; 17326 } 17327 17328 // RESET - needed to load a modal from another modal 17329 jQuery('.modal-backdrop').remove(); 17330 17331 17332 // ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 17333 // is video modal! stop here! process video! 17334 if(_modalType.toLowerCase() +'' == 'video') { 17335 17336 var _backdrop = 'dynamic'; // forced
17337 var embedData = $.SOW.helper.videoEmbedFromUrl(_href, 1); // 1 = autoplay 17338 17339 if(embedData === null) { 17340 17341 if(typeof $.SOW.core.toast === 'object') { 17342 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 17343 } else { 17344 alert("[404] Unexpected internal error!"); 17345 } 17346 17347 return false; 17348 } 17349 17350 17351 17352 17353 // load modal 17354 var _loader = '<div class="text-center p-6 fs--30 text-muted '+$.SOW.config.sow__icon_loading+'"></div>'; 17355 jQuery(_target).modal('dispose').modal({backdrop: _backdrop, keyboard:_keyboard}).find('.modal-content').html(_loader); 17356 17357 setTimeout(function () { 17358 17359 jQuery(_target).find('.modal-content') 17360 .html(embedData) 17361 .addClass('rounded-xl bg-dark shadow-primary-xs border border-dark bw--3') 17362 .prepend('<button type="button" class="close pointer position-absolute top-0 end-0 mt--n50 mx-1 text-white z-index-100" data-dismiss="modal" aria-label="Close"><span class="fi fi-close fs--25" aria-hidden="true"></span></button>'); 17363 17364 17365 // try another way to start the video! AdBlock is problematic! 17366 jQuery('iframe', _target).attr('src', jQuery('iframe', _target).data('autoplay-src')); 17367 17368 }, 450); 17369 17370 17371 // Destroy on close! Too much customization! 17372 // And anyway, else, video remain to play on background! 17373 jQuery(_target).on('hidden.bs.modal', function (e) { 17374 jQuery(_target).remove(); 17375 }); 17376 17377 17378 17379 17380 return false; 17381 } 17382 // ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 17383 17384 17385 17386 // Ajax Request 17387 jQuery.ajax({ 17388 url: _href, 17389 type: _method, 17390 data: $.SOW.core.ajax_modal.config.data_params, 17391 contentType: $.SOW.core.ajax_modal.config.contentType, 17392 dataType: $.SOW.core.ajax_modal.config.dataType, 17393 headers: $.SOW.core.ajax_modal.config.headers, 17394 crossDomain: $.SOW.core.ajax_modal.config.crossDomain, 17395 17396 beforeSend: function() { 17397 17398 var _loader = '<div class="text-center p-6 fs--30 text-muted '+$.SOW.config.sow__icon_loading+'"></div>'; 17399 jQuery(_target).modal('dispose').modal({backdrop: _backdrop, keyboard:_keyboard}).find('.modal-content').html(_loader); 17400 17401 }, 17402 17403 error: function(XMLHttpRequest, textStatus, errorThrown) { 17404 17405 if(typeof $.SOW.core.toast === 'object') { 17406 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 17407 } else { 17408 alert("[404] Unexpected internal error!"); 17409 } 17410 17411 // if debug enabled, see config 17412 if($.SOW.config.sow__debug_enable === true) { 17413 $.SOW.helper.consoleLog('----------------------------'); 17414 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 17415 $.SOW.helper.consoleLog(' - MODAL -'); 17416 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 17417 $.SOW.helper.consoleLog(XMLHttpRequest); 17418 $.SOW.helper.consoleLog('2. textStatus:'); 17419 $.SOW.helper.consoleLog(textStatus); 17420 $.SOW.helper.consoleLog('3. errorThrown:'); 17421 $.SOW.helper.consoleLog(errorThrown); 17422 $.SOW.helper.consoleLog('----------------------------'); 17423 } 17424 17425 }, 17426 17427 success: function(data) { 17428 17429 jQuery(_target).find('.modal-content').html(data); 17430 17431 setTimeout(function () { 17432 17433 // Optional callback function 17434 if(_modal_callback != '' && typeof $.SOW.helper.executeFunctionByName === 'function') 17435 $.SOW.helper.executeFunctionByName(_modal_callback, window, _target); 17436 17437 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 17438 // reinit inside ajax container 17439 $.SOW.reinit(_target); 17440 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 17441 17442 // focus first input element 17443 jQuery('input:visible:enabled:first', _target).focus(); 17444 17445 17446 }, 450); 17447 17448 } 17449 17450 }); 17451 17452 17453 }, 17454 17455 17456 17457 17458 17459 /** 17460 * 17461 * @ajax_modal_template 17462 * 17463 * 17464 **/ 17465 ajax_modal_template: function() { 17466 17467 if(jQuery(this.config.modal_container).length > 0) 17468 return; 17469 17470 var modal_container = this.config.modal_container.replace('#', ''), 17471 _tpl = '<div class="modal fade" id="' + modal_container + '" role="dialog" tabindex="-1" aria-hidden="true">' 17472 + '<div class="modal-dialog '+ this.config.modal_size +'" role="document">' 17473 17474 + '<div class="modal-content"><!-- content added by ajax --></div>' 17475 17476 + '</div>' 17477 + '</div>'; 17478 17479 $.SOW.globals.elBody.append(_tpl); 17480 $(this.config.modal_container).modal('handleUpdate'); 17481 17482 }, 17483 17484 17485 17486 17487 17488 /** 17489 * 17490 * @createFromThinAir 17491 * Programtically Create Modal : url , 'modal-md', 'true' (centered), 'backdrop' (optional), callback (optional) 17492 * $.SOW.core.ajax_modal.createFromThinAir(modalUrl, 'modal-lg', 'true', 'static', callback); 17493 * 17494 **/ 17495 createFromThinAir: function(url, modal_size, modal_centered, modal_backdrop, modal_callback) { 17496 17497 if(!url) 17498 $.SOW.helper.consoleLog('SOW Ajax Modal : [createFromThinAir()] : No url provided!'); 17499 17500 17501 if(!this.selector_orig) 17502 this.selector_orig = '.js-ajax-modal'; 17503 17504 if(!modal_size) 17505 modal_size = 'modal-md'; 17506
17507 if(!modal_centered) 17508 modal_centered = 'false'; 17509 17510 if(!modal_backdrop) 17511 modal_backdrop = ''; 17512 17513 if(!modal_callback) 17514 modal_callback = ''; 17515 17516 // Create DOM 17517 var selectorClass = this.selector_orig.replace('.', ''); 17518 $.SOW.globals.elBody.append('<a id="ajax_modal_create_tmp" href="'+url+'" class="hide '+selectorClass+'"></a>'); 17519 17520 // Add Attributes 17521 jQuery('#ajax_modal_create_tmp') 17522 .attr('data-ajax-modal-size', modal_size) 17523 .attr('data-ajax-modal-centered', modal_centered) 17524 .attr('data-ajax-modal-backdrop', modal_backdrop) 17525 .attr('data-ajax-callback-function', modal_callback); 17526 17527 // Init this plugin 17528 $.SOW.core.ajax_modal.init(this.selector_orig); 17529 jQuery('#ajax_modal_create_tmp').trigger('click'); 17530 17531 // Delete, not needed anymore! 17532 setTimeout(function() { 17533 jQuery('#ajax_modal_create_tmp').off().remove(); 17534 },350); 17535 17536 return true; 17537 }, 17538 17539 17540 17541 17542 17543 17544 /** 17545 * 17546 * @ajax_modal_onLoad 17547 * 17548 **/ 17549 ajax_modal_onLoad: function() { 17550 17551 jQuery('.js-ajax-modal.js-onload'+this.selector).not('.js-loadmodalified').addClass('js-loadmodalified').each(function() { 17552 17553 var _t = jQuery(this), 17554 _delay = jQuery(this).attr('data-ajax-modal-delay') || 3000, 17555 _ID = _t.attr('id') || ''; 17556 17557 if(_ID != '') { 17558 var modalCookie = Cookies.get(_ID, { path: '/' }); 17559 if(modalCookie == '1') 17560 return; 17561 } 17562 17563 setTimeout(function() { 17564 _t.trigger('click'); 17565 }, Number(_delay)); 17566 17567 }); 17568 17569 }, 17570 17571 17572 17573 17574 17575 /** 17576 * 17577 * @attach 17578 * Programtically Init For Element 17579 * $.SOW.core.ajax_modal.attach(bg_element|string_id_class); 17580 * 17581 **/ 17582 attach: function(href) { 17583 17584 // obj required 17585 var el = (typeof href === 'string') ? jquery(href) : href; 17586 17587 // unbind 17588 if(el.hasClass('js-modalified')) 17589 el.off().removeClass('js-modalified'); 17590 17591 // add required 17592 el.addClass('js-ajax-modal'); 17593 17594 // init 17595 $.SOW.core.ajax_modal.ajax_modal(el); 17596 setTimeout(function() { 17597 el.trigger('click'); 17598 },200); 17599 17600 return true; 17601 17602 }, 17603 17604 17605 17606 17607 17608 /** 17609 * 17610 * @Return Selector 17611 * 17612 * 17613 **/ 17614 __selector: function() { 17615 return this.selector_orig; 17616 } 17617 17618 17619 } 17620 17621})(jQuery); 17622/** 17623 * 17624 * [SOW] Ajax Confirm 17625 * 17626 * @author Dorin Grigoras 17627 * www.stepofweb.com 17628 * 17629 * @Dependency - 17630 * @Usage $.SOW.core.ajax_confirm.init('.js-ajax-confirm'); 17631 * 17632 * 17633 **/ 17634;(function ($) { 17635 'use strict'; 17636 17637 17638 /** 17639 * 17640 * @vars 17641 * 17642 * 17643 **/ 17644 var scriptInfo = 'SOW Ajax Confirm'; 17645 17646 17647 17648 $.SOW.core.ajax_confirm = { 17649 17650 17651 /** 17652 * 17653 * @config 17654 * 17655 * 17656 **/ 17657 config: { 17658 method : 'GET', // (ajax mode only) 17659 contentType : '', // jQuery params (ajax mode only) 17660 dataType : '', // jQuery params (ajax mode only) 17661 headers : '', // jQuery params (ajax mode only) 17662 crossDomain : '', // jQuery params (ajax mode only) 17663 data_params : {ajax:'true'},// jQuery params (ajax mode only) 17664 17665 confirm_container : '#sow_ajax_confirm', 17666 confirm_size : '', 17667 confirm_centered : false, 17668 17669 confirm_type : '', // primary|secondary|success|warning|danger|info; empty = regular/clean 17670 confirm_mode : 'regular', // ajax|regular
17671 confirm_title : 'Please Confirm', 17672 confirm_body : 'Are you sure?', 17673 17674 btn_class_yes : 'btn-sm btn-primary', 17675 btn_class_no : 'btn-sm btn-light', 17676 btn_text_yes : 'Confirm', 17677 btn_text_no : 'Cancel', 17678 btn_icon_yes : 'fi fi-check', 17679 btn_icon_no : 'fi fi-close', 17680 17681 /* 17682 callback_example = function(el, data) { 17683 // el = link clicked $(this) 17684 // data = server response (html|string) 17685 } 17686 */ 17687 callback_function : '' 17688 17689 }, 17690 17691 17692 17693 /** 17694 * 17695 * @collection 17696 * 17697 * 17698 **/ 17699 collection: $(), 17700 17701 17702 17703 /** 17704 * 17705 * @init 17706 * 17707 * 17708 **/ 17709 init: function (selector, config) { 17710 17711 var __selector = $.SOW.helper.__selector(selector); 17712 var __config = $.SOW.helper.check_var(config); 17713 17714 this.selector = __selector[0]; // '#selector' 17715 this.collection = __selector[1]; // $('#selector') 17716 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 17717 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 17718 17719 17720 if(jQuery(this.selector).length < 1) 17721 return; 17722 17723 17724 // -- * -- 17725 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 17726 // -- * -- 17727 17728 17729 // Create modal container 17730 $.SOW.core.ajax_confirm.ajax_confirm_template(); 17731 17732 17733 // 1. Has no selector 17734 if(!this.selector) { 17735 $.SOW.core.ajax_confirm.ajax_confirm($('a.js-ajax-confirm')); 17736 return this.collection; 17737 } 17738 17739 // 2. Has selector 17740 return this.collection.each(function() { 17741 17742 $.SOW.core.ajax_confirm.ajax_confirm($(this)); 17743 17744 }); 17745 17746 }, 17747 17748 17749 17750 /** 17751 * 17752 * @ajax_confirm 17753 * 17754 17755 <a href="URL-HERE" 17756 class="js-ajax-confirm" 17757 17758 data-ajax-confirm-size="modal-md" 17759 data-ajax-confirm-centered="false" 17760 17761 data-ajax-confirm-callback-function="" 17762 data-ajax-confirm-type="ajax" 17763 data-ajax-confirm-method="GET" 17764 17765 data-ajax-confirm-title="Please Confirm" 17766 data-ajax-confirm-body="Are you sure? Delete this item?" 17767 17768 data-ajax-confirm-btn-yes-text="Confirm" 17769 data-ajax-confirm-btn-yes-class="btn-sm btn-primary" 17770 data-ajax-confirm-btn-yes-icon="fi fi-check" 17771 17772 data-ajax-confirm-btn-no-text="Cancel" 17773 data-ajax-confirm-btn-no-class="btn-sm btn-light" 17774 data-ajax-confirm-btn-no-icon="fi fi-close" 17775 17776 rel="nofollow"> 17777 Confirm 17778 </a> 17779 17780 data-ajax-confirm-size="modal-sm|modal-md|modal-lg|modal-full" 17781 17782 data-ajax-confirm-callback-function="_myCustomFunc" (optional - your custom function called on load) 17783 Example: 17784 var _myCustomFunc = function(el, data) { 17785 el = button element 17786 data = ajax result from server 17787 alert('My Function Called! Do something like... reinit some plugins'); 17788 } 17789 17790 * 17791 * 17792 **/ 17793 ajax_confirm: function(_this) { 17794 17795 var _selector = this.selector, 17796 _selector_orig = this.selector_orig, 17797 _confirm_container = this.config.confirm_container, 17798 _confirm_size = this.config.confirm_size, 17799 _confirm_centered = this.config.confirm_centered, 17800 _confirm_callback = this.config.callback_function, 17801 17802 confirm_method = this.config.method, 17803 confirm_mode = this.config.confirm_mode, 17804 confirm_type = this.config.confirm_type, 17805 confirm_title = this.config.confirm_title, 17806 confirm_body = this.config.confirm_body, 17807 17808 btn_class_yes = this.config.btn_class_yes, 17809 btn_class_no = this.config.btn_class_no, 17810 btn_text_yes = this.config.btn_text_yes, 17811 btn_text_no = this.config.btn_text_no, 17812 btn_icon_yes = this.config.btn_icon_yes, 17813 btn_icon_no = this.config.btn_icon_no; 17814 17815 17816 var _href = _this.attr('href') || '', 17817 _href_data = _this.data('href') || ''; 17818 17819 if(_href_data != '') 17820 _href = _href_data; 17821 17822 17823 if(_href == '') 17824 return; 17825 17826 _this.attr('data-href', _href); 17827 _this.attr('href', '#'); 17828 17829 17830 _this.not('.js-ajaxconfirmified').addClass('js-ajaxconfirmified').on('click', function(e) { 17831 e.preventDefault(); 17832 17833 var _t = jQuery(this), 17834 _href = _t.data('href') || '#', 17835 17836 _target = _t.data('ajax-confirm-container') || _confirm_container, // modal (id or class) 17837 _modal_confirm_size = _t.data('ajax-confirm-size') || _confirm_size, // modal-sm, modal-md, modal-lg , modal-full 17838 _modal_centered = _t.data('ajax-confirm-centered') || _confirm_centered, // true|false 17839 _confirmCallback = _t.data('ajax-confirm-callback-function') || _confirm_callback, // custom function 17840 _confirmType = _t.data('ajax-confirm-type') || confirm_type, // confirmation type: danger|warning|etc. empty for normal/clean 17841 _confirmMode = _t.data('ajax-confirm-mode') || confirm_mode, // confirmation type: regular|ajax 17842 _confirmMethod = _t.data('ajax-confirm-method') || confirm_method, // confirmation method: GET|POST 17843 17844 _confirmTitle = _t.data('ajax-confirm-title') || confirm_title, // modal title 17845 _confirmBody = _t.data('ajax-confirm-body') || confirm_body, // message | question 17846 17847 _confirmBtnYesTxt = _t.data('ajax-confirm-btn-yes-text') || btn_text_yes, // button text 17848 _confirmBtnYesClass = _t.data('ajax-confirm-btn-yes-class') || btn_class_yes, // button class 17849 _confirmBtnYesIcon = _t.data('ajax-confirm-btn-yes-icon') || btn_icon_yes, // button icon. eg: fi fi-check 17850 17851 _confirmBtnNoTxt = _t.data('ajax-confirm-btn-no-text') || btn_text_no, // button text 17852 _confirmBtnNoClass = _t.data('ajax-confirm-btn-no-class') || btn_class_no, // button class 17853 _confirmBtnNoIcon = _t.data('ajax-confirm-btn-no-icon') || btn_icon_no; // button icon. eg: fi fi-check 17854 17855 17856 17857 // Ignore by request! 17858 if(_t.hasClass('js-ignore')) 17859 return; 17860 17861 17862 // Always create new modal 17863 $.SOW.core.ajax_confirm.ajax_confirm_template(); 17864 17865 // Close any open dropdown 17866 jQuery('.dropdown-menu:not(.dropdown-menu-hover)').parent().find('a[data-toggle="dropdown"][aria-expanded="true"]').attr('aria-expanded', 'false').dropdown('hide'); 17867 17868 17869 // Add size class by request
17870 jQuery('.modal-dialog', _target).removeClass('modal-sm, modal-md, modal-lg, modal-xlg, modal-full bg-primary-soft bg-secondary-soft bg-success-soft bg-warning-soft bg-danger-soft bg-pink-soft bg-indigo-soft bg-purple-soft').addClass(_modal_confirm_size); 17871 17872 17873 // Header Bg Color 17874 jQuery('.modal-header', _target).removeClass('bg-primary-soft bg-secondary-soft bg-success-soft bg-warning-soft bg-danger-soft bg-info-soft bg-pink-soft bg-indigo-soft bg-purple-soft border-0'); 17875 if(_confirmType != '') 17876 jQuery('.modal-header', _target).addClass('bg-'+_confirmType+'-soft border-0'); 17877 17878 17879 // centered 17880 (_modal_centered+'' == 'true') ? jQuery('.modal-dialog', _target).addClass('modal-dialog-centered') : jQuery('.modal-dialog', _target).removeClass('modal-dialog-centered'); 17881 17882 17883 // Reset 17884 jQuery('.btn-confirm-yes', _target).attr('class', '').attr('class', 'btn btn-confirm-yes'); 17885 jQuery('.btn-confirm-no', _target).attr('class', '').attr('class', 'btn btn-confirm-no'); 17886 jQuery('.btn-confirm-yes>i', _target).remove(); 17887 jQuery('.btn-confirm-no>i', _target).remove(); 17888 jQuery(_target + ' .modal-footer').removeClass('hide'); 17889 17890 17891 // Add Icons 17892 if(_confirmBtnYesIcon.length > 1) 17893 var _confirmBtnYesTxt = '<i class="' + _confirmBtnYesIcon + '"></i> ' + _confirmBtnYesTxt; 17894 17895 if(_confirmBtnNoIcon.length > 1) 17896 var _confirmBtnNoTxt = '<i class="' + _confirmBtnNoIcon + '"></i> ' + _confirmBtnNoTxt; 17897 17898 jQuery('.btn-confirm-yes', _target).attr('href', _href).html(_confirmBtnYesTxt).addClass(_confirmBtnYesClass); 17899 jQuery('.btn-confirm-no', _target).html(_confirmBtnNoTxt).addClass(_confirmBtnNoClass); 17900 17901 jQuery('.modal-title', _target).html(_confirmTitle); 17902 jQuery('.modal-body', _target).html(_confirmBody); 17903 17904 jQuery(_target).modal('show'); 17905 17906 // CONFIRMATION AJAX REQUEST 17907 if(_confirmMode == 'ajax') { 17908 17909 jQuery('.btn-confirm-yes', _target).unbind('click').on("click", function(e) { 17910 e.preventDefault(); 17911 17912 jQuery.ajax({ 17913 url: _href, 17914 type: _confirmMethod, 17915 data: $.SOW.core.ajax_confirm.config.data_params, 17916 contentType: $.SOW.core.ajax_confirm.config.contentType, 17917 dataType: $.SOW.core.ajax_confirm.config.dataType, 17918 headers: $.SOW.core.ajax_confirm.config.headers, 17919 crossDomain: $.SOW.core.ajax_confirm.config.crossDomain, 17920 17921 beforeSend: function() { 17922 17923 $.SOW.helper.loadingSpinner('show', _target + ' .modal-content'); 17924 jQuery('.btn-confirm-yes', _target).addClass('disabled').prop('disabled', true); 17925 }, 17926 17927 error: function(XMLHttpRequest, textStatus, errorThrown) { 17928 17929 $.SOW.helper.loadingSpinner('hide'); 17930 jQuery('.btn-confirm-yes', _target).removeClass('disabled').prop('disabled', false); 17931 17932 if(typeof $.SOW.core.toast === 'object') { 17933 17934 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'top-center', 0, true); 17935 jQuery(_target).modal('hide'); 17936 17937 } else { 17938 alert("[404] Unexpected internal error!"); 17939 } 17940 17941 }, 17942 17943 success: function(data) { 17944 17945 $.SOW.helper.loadingSpinner('hide'); 17946 17947 jQuery(_target + ' .modal-footer').addClass('hide'); 17948 jQuery(_target + ' .modal-content .modal-body').html('<div class="js-modal-confirm-ok pt--20 pb--30 text-center animate-bouncein"><i class="'+$.SOW.config.sow__icon_check+' fs--40 text-muted"></i></div>'); 17949 jQuery('.btn-confirm-yes', _target).removeClass('disabled').prop('disabled', false); 17950 17951 setTimeout(function(){ 17952 17953 jQuery(_target).modal('hide'); 17954 17955 },500); 17956 17957 17958 if(_confirmCallback != '' && typeof $.SOW.helper.executeFunctionByName === 'function') 17959 $.SOW.helper.executeFunctionByName(_confirmCallback, window, _t, data); 17960 17961 17962 } 17963 }); 17964 17965 }); 17966 17967 } else { 17968 17969 // Callback Function 17970 if(_confirmCallback != '' && typeof $.SOW.helper.executeFunctionByName === 'function') { 17971 jQuery('.btn-confirm-yes', _target).unbind('click').on('click', function(e) { 17972 e.preventDefault(); 17973 $.SOW.helper.executeFunctionByName(_confirmCallback, window, _t); 17974 }); 17975 } 17976 17977 17978 jQuery('.btn-confirm-yes', _target).unbind('click').on("click", function(e) { 17979 jQuery(_target).modal('hide'); 17980 }); 17981 17982 } 17983 17984 17985 }); 17986 17987 return true; 17988 }, 17989 17990 17991 17992 17993 17994 /** 17995 * 17996 * @ajax_confirm_template 17997 * 17998 * 17999 **/
18000 ajax_confirm_template: function() { 18001 18002 // remove last 18003 jQuery(this.config.confirm_container).remove(); 18004 18005 var confirm_container = this.config.confirm_container.replace('#', ''), 18006 _tpl = '<div class="modal fade" id="' + confirm_container + '" role="dialog" tabindex="-1" aria-labelledby="modal-title-confirm" aria-hidden="true">' 18007 + '<div class="modal-dialog '+ this.config.confirm_size +'" role="document">' 18008 18009 + '<div class="modal-content">' 18010 18011 + '<div class="modal-header">' 18012 18013 + '<h5 id="modal-title-confirm" class="modal-title font-light fs--18">' 18014 + this.config.confirm_title 18015 + '</h5>' 18016 18017 + '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' 18018 + '<span class="fi fi-close fs--18" aria-hidden="true"></span>' 18019 + '</button>' 18020 18021 + '</div>' 18022 18023 + '<div class="modal-body pt--30 pb--30">' 18024 18025 + this.config.confirm_body 18026 18027 + '</div>' 18028 18029 + '<div class="modal-footer">' 18030 18031 + '<a href="#" class="btn pt--10 pb--10 fs--16 btn-confirm-yes '+ this.config.btn_class_yes +'">' 18032 + this.config.btn_text_yes 18033 + '</a>' 18034 18035 + '<a href="#" class="btn pt--10 pb--10 fs--16 btn-confirm-no '+ this.config.btn_class_no +'" data-dismiss="modal">' 18036 + this.config.btn_text_no 18037 + '</a>' 18038 18039 + '</div>' 18040 18041 + '</div>' 18042 18043 + '</div>' 18044 + '</div>'; 18045 18046 18047 $.SOW.globals.elBody.append(_tpl); 18048 $(this.config.confirm_container).modal('handleUpdate'); 18049 18050 // clear 18051 _tpl = null; 18052 18053 }, 18054 18055 18056 18057 18058 /** 18059 * 18060 * @Return Selector 18061 * 18062 * 18063 **/ 18064 __selector: function() { 18065 return this.selector_orig; 18066 } 18067 18068 18069 } 18070 18071})(jQuery); 18072/** 18073 * 18074 * [SOW] Form Advanced 18075 * 18076 * @author Dorin Grigoras 18077 * www.stepofweb.com 18078 * 18079 * @Dependency - 18080 * @Usage $.SOW.core.file_upload.init('input[type="file"].custom-file-input'); 18081 * 18082 * 18083 **/ 18084;(function ($) { 18085 'use strict'; 18086 18087 18088 /** 18089 * 18090 * @vars 18091 * 18092 * 18093 **/ 18094 var scriptInfo = 'SOW File Upload'; 18095 window.fileInventory = {}; 18096 window.filesLastBulk = []; 18097 window.filesSizeBulk = 0; 18098 window.browser_hasIssues = false; // example: safari do not allow input file cloning. So we mark it as having issues 18099 18100 18101 $.SOW.core.file_upload = { 18102 18103 18104 /** 18105 * 18106 * @config 18107 * 18108 * 18109 **/ 18110 config: { 18111 18112 // toast messages 18113 toast_pos: 'bottom-center', 18114 toast_delay: 2000, 18115 18116 browsers_with_issues: ['safari'], // browsers with issues (are treated different by file input) 18117 18118 }, 18119 18120 18121 18122 /** 18123 * 18124 * @collection 18125 * 18126 * 18127 **/ 18128 collection: $(), 18129 18130 18131 18132 /** 18133 * 18134 * @init 18135 * 18136 * 18137 **/ 18138 init: function (selector, config) { 18139 18140 var __selector = $.SOW.helper.__selector(selector); 18141 var __config = $.SOW.helper.check_var(config); 18142 18143 this.selector = __selector[0]; // '#selector' 18144 this.collection = __selector[1]; // $('#selector') 18145 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 18146 18147 18148 // Mark browser with issues (eample: safari do not allow cloning input file) 18149 var browser_vendor = $.SOW.helper.get_browser(); 18150 if(this.config.browsers_with_issues.indexOf(browser_vendor) !== -1) 18151 window.browser_hasIssues = true; 18152 18153 18154 // 1. Has no selector 18155 if(!this.selector) { 18156 $.SOW.core.file_upload.file_upload__init('input[type="file"].custom-file-input'); 18157 return this.collection; 18158 } 18159 18160 // 2. Has selector 18161 $.SOW.core.file_upload.file_upload__init(this.selector); 18162 18163 18164 // No chaining! 18165 return null; 18166 }, 18167 18168 18169 18170 18171 /** 18172 * 18173 * @file_upload__init 18174 * File Input|Upload 18175 * 18176 * 18177 **/ 18178 file_upload__init: function(_this) { 18179 18180 18181 /* 18182 18183 First setup 18184 : unique identifier 18185 : empty inventory array 18186 : correcting human errors (like array name missing on multiple files) 18187 18188 */ 18189 jQuery(_this).each(function() { 18190 18191 var _t = jQuery(this), 18192 is_multiple = _t.attr('multiple') || false, 18193 input_name = _t.attr('name') || '', 18194 preview_delete = _t.data('file-ajax-delete-enable') || false, 18195 preview_reorder = _t.data('file-ajax-reorder-enable') || false, 18196 fileInputIdentifier = $.SOW.helper.randomStr(4, 'N'); 18197 18198 18199 // add unique identifier for each file input 18200 _t.attr('data-js-advanced-identifier', fileInputIdentifier); 18201 18202 // create empty array 18203 window.fileInventory[fileInputIdentifier] = []; 18204 18205 // name array missing on multiple input upload 18206 if(is_multiple !== false && input_name.indexOf('[]') === -1) 18207 _t.attr('name', input_name+'[]'); 18208 18209 18210 // Used by preadded files 18211 if(preview_delete != false) { 18212 18213 if(is_multiple != false) 18214 $.SOW.core.file_upload.file_upload__preview_delbtn_bind_multiple(_t, true); 18215 18216 if(is_multiple == false) 18217 $.SOW.core.file_upload.file_upload__preview_delbtn_bind_single(_t, true); 18218 18219 } 18220 18221 if(preview_reorder != false) 18222 $.SOW.core.file_upload.file_upload__preview__reorder_bind(_t, true); 18223 18224 18225 }); 18226 18227 18228 jQuery(_this).not('.js-advancified').addClass('js-advancified').on('change',function(e) { 18229 18230 var _t = jQuery(this), 18231 fileInputIdentifier = _t.data('js-advanced-identifier') || '', // static, real identifier for each file input 18232 is_multiple = _t.attr('multiple') || false, 18233 file_name = (is_multiple === false) ? _t.get(0).files[0].name.replace('C:\\fakepath\\', " ") : '', 18234 label_orig = _t.next('.custom-file-label').attr('data-orig') || '', 18235 exts_allowed = _t.data('file-ext') || '', 18236 exist_error_txt = _t.data('file-exist-err-msg') || 'File already exist: ', 18237 exts_error_txt = _t.data('file-ext-err-msg') || 'Allowed: ', 18238 size_error_txt = _t.data('file-size-err-item-msg') || 'File too large! ', 18239 size_error_txt_total = _t.data('file-size-err-total-msg') || 'Total size exceeded!', 18240 selected_txt = _t.data('file-size-err-total-msg') || 'selected', // in case preview is not used 18241 max_error_txt_total = _t.data('file-size-err-max-msg') || 'Maximum allowed files:', 18242 toast_position = _t.data('file-toast-position') || 'bottom-center', 18243 max_size_per_file = _t.data('file-max-size-kb-per-file') || 0, 18244 max_size_total = _t.data('file-max-size-kb-total') || 0, 18245 max_files = _t.data('file-max-total-files') || 0, 18246 btn_clear_files = _t.data('file-btn-clear') || 'a.js-advanced-form-input-clone-clear', 18247 preview_container = _t.data('file-preview-container') || '', 18248 preview_height = _t.data('file-preview-img-height') || 120, 18249 preview_info = _t.data('file-preview-show-info') || false, 18250 preview_info = _t.data('file-preview-show-info') || false, 18251 preview_list_type = _t.data('file-preview-list-type') || 'box', 18252 preview_class = _t.data('file-preview-class') || '', 18253 preview_as_cover = _t.data('file-preview-img-cover') || false, 18254 preview_reorder = _t.data('file-ajax-reorder-enable') || false, 18255 preview_delete = _t.data('file-ajax-delete-enable') || false, 18256 18257 // @Ajax 18258 ajax_process_enable = _t.data('file-ajax-upload-enable') || false; // false by default! 18259 18260 18261 18262 18263 // Force preview as cover for lists 18264 if(preview_list_type == 'list') 18265 preview_as_cover = true; 18266 18267 18268 // Some settings 18269 _t.attr('data-orig-name', jQuery(this).attr('name')); 18270 18271 18272 if(label_orig == '') { 18273 label_orig = _t.next('.custom-file-label').html() || 'Choose file'; 18274 _t.next('.custom-file-label').attr('data-orig', label_orig); 18275 } 18276 18277 18278 if(exts_allowed != '') 18279 exts_allowed = exts_allowed.split(",").map(function(ext) { 18280 return ext.trim(); 18281 }); 18282 18283 18284 // Always reset on safari and single file 18285 // SAFARI ISSUE: Cloning input file is not supported! 18286 if(window.browser_hasIssues === true || is_multiple === false) { 18287 18288 window.fileInventory[fileInputIdentifier] = []; 18289 18290 if(ajax_process_enable != true) { 18291 jQuery('.js-file-input-item', preview_container).remove(); 18292 jQuery(btn_clear_files).addClass('hide'); 18293 } 18294 18295 } 18296 18297 18298 18299 /* 18300 18301 Single File : add file name 18302 18303 */ 18304 if(is_multiple === false) 18305 _t.next('.custom-file-label').text(file_name); 18306 else 18307 _t.next('.custom-file-label').text(_t.get(0).files.length + ' ' + selected_txt); // in case preview is not used 18308 18309 18310 18311 18312 18313 /* 18314 18315 2. Preview & Logics 18316 18317 */ 18318 var input_name = _t.attr('name') || _t.data('orig-name'), 18319 _clone = _t.clone(true).off(), // turn off binds from clone 18320 _bulkNo = 'bulkNo_' + $.SOW.helper.randomStr(8), 18321 total_files = _t.get(0).files.length, 18322 file_size_kb_bulk = 0; 18323 18324 18325 // set back "Choose file" label 18326 if(is_multiple !== false) 18327 _t.next('.custom-file-label').html(label_orig); 18328 18329 18330 18331 for (var i = 0; i < total_files; ++i) { 18332 18333 var file = _t.get(0).files[i], 18334 file_ext = file.name.substring(file.name.lastIndexOf('.')+1, file.name.length) || null, 18335 file_size_kb = $.SOW.helper.byte2kb(file.size), 18336 _rand = 'rand_' + $.SOW.helper.randomStr(3), 18337 file_img = '<div class="js-advanced-form-default-preview absolute-full d-table w-100 h--120"><div class="d-table-cell align-middle text-center"><span class="fs--30 text-gray-500">?</span></div></div>', 18338 _concat = file.name+':'+file.size+':'+fileInputIdentifier; 18339 window.filesLastBulk.push(_rand); // because are already in the dom! 18340 18341 18342 18343 /* 18344 18345 Maximum files 18346 18347 */ 18348 if(max_files > 0) { 18349 18350 var total_files_current = jQuery('.js-file-input-item', preview_container).length; 18351 18352 if(parseInt(total_files_current) >= max_files) { 18353 18354 var _msg = max_error_txt_total + ' ' + max_files; 18355 18356 if(typeof $.SOW.core.toast === 'object') { 18357 $.SOW.core.toast.show('danger', '', _msg, toast_position, 6000, true); 18358 } else { 18359 alert(_msg); 18360 } 18361 18362 // delete input & images of this input 18363 $.SOW.core.file_upload.file_upload__del_bulk(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18364 return; 18365 18366 } 18367 18368 } 18369 18370 18371 18372 /* 18373 18374 Maximum total upload 18375 18376 */ 18377 if(max_size_total > 0) { 18378 18379 // because window.filesSizeBulk is calculated at the end 18380 var filesSizeBulk_current = file_size_kb_bulk + window.filesSizeBulk ; 18381 18382 if(parseInt(filesSizeBulk_current) > parseInt(max_size_total)) { 18383 18384 var _msg = size_error_txt_total + ' <hr>(' + max_size_total+'kb)'; 18385 18386 if(typeof $.SOW.core.toast === 'object') 18387 $.SOW.core.toast.show('danger', '', _msg, toast_position, 6000, true); 18388 18389 // delete input & images of this input 18390 $.SOW.core.file_upload.file_upload__del_bulk(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18391 18392 return; 18393 18394 } 18395 } 18396 18397 18398 18399 18400 // Check file size 18401 if(max_size_per_file > 0) { 18402 18403 if(parseInt(file_size_kb) > parseInt(max_size_per_file)) { 18404 18405 var _msg = size_error_txt + ' <hr>' + file.name +'<br>(' + file_size_kb+'kb / '+max_size_per_file+'Kb)'; 18406 18407 if(typeof $.SOW.core.toast === 'object') 18408 $.SOW.core.toast.show('danger', '', _msg, toast_position, 6000, true); 18409 18410 // delete input & images of this input 18411 $.SOW.core.file_upload.file_upload__del_bulk(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18412 18413 return; 18414 18415 } 18416 18417 } 18418 18419 18420 // Sum the size of all files in this bulk 18421 // if everything is ok, will add to window.filesSizeBulk 18422 file_size_kb_bulk += file_size_kb; 18423 18424 18425 // check allowed extension 18426 if(exts_allowed != '' && exts_allowed.indexOf(file_ext) === -1) { 18427 18428 var _msg = exts_error_txt + ' ' + exts_allowed.join(', '); 18429 18430 if(typeof $.SOW.core.toast === 'object') { 18431 $.SOW.core.toast.show('danger', '', _msg, toast_position, 4500, true); 18432 } else { 18433 alert(_msg); 18434 } 18435 18436 18437 // delete input & images of this input 18438 $.SOW.core.file_upload.file_upload__del_bulk(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18439 18440 return; 18441 18442 } 18443 18444 18445 /* 18446 18447 File already exists 18448 18449 */ 18450 if(window.fileInventory[fileInputIdentifier].indexOf(_concat) !== -1) { 18451 18452 if(typeof $.SOW.core.toast === 'object') 18453 $.SOW.core.toast.show('danger', '', exist_error_txt + '<br> '+file.name, toast_position, 4500, true); 18454 18455 18456 // delete input & images of this input 18457 $.SOW.core.file_upload.file_upload__del_bulk(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18458 18459 return; 18460 18461 } 18462 18463 18464 // add file to inventory 18465 window.fileInventory[fileInputIdentifier].push(_concat); 18466 18467 18468 // preview image 18469 if(preview_container != '') { 18470 18471 var _tpl = $.SOW.core.file_upload.file_upload__preview_tpl(file, file_ext, _rand, _bulkNo, preview_height, preview_info, preview_class, ajax_process_enable, preview_delete, preview_as_cover, preview_list_type, is_multiple); 18472 jQuery(preview_container).append(_tpl); 18473 18474 // bind delete button 18475 if(ajax_process_enable === true) { 18476 18477 if(preview_delete != false) { 18478 18479 if(is_multiple != false) 18480 $.SOW.core.file_upload.file_upload__preview_delbtn_bind_multiple(_t, false); 18481 18482 if(is_multiple == false) 18483 $.SOW.core.file_upload.file_upload__preview_delbtn_bind_single(_t, false); 18484 18485 } 18486 18487 if(preview_reorder === true) 18488 $.SOW.core.file_upload.file_upload__preview__reorder_bind(_t, false); 18489 18490 } 18491 18492 // image preview --------------------------------------- 18493 if (file_ext == "gif" || file_ext == "png" || file_ext == "jpg" || file_ext == "jpeg") 18494 $.SOW.core.file_upload.file_upload__preview_img_render('#'+_rand, file, preview_as_cover, preview_list_type); 18495 18496 } 18497 18498 18499 } 18500 18501 18502 // show `remove all files` button 18503 $.SOW.core.file_upload.file_upload__btn_clear_bind(btn_clear_files, _t, preview_container, input_name, fileInputIdentifier); 18504 18505 18506 18507 // 1. append cloned element 18508 // safari DO NOT support file input cloning! 18509 // also not allowing hidden file inputs - so we use .viewport-out class, just in case, for future chrome/etc updates 18510 if(window.browser_hasIssues !== true) { 18511 18512 // hard to debug with all variables. We remove them, never used as a clone! 18513 _clone.removeAttr('class name data-orig-name aria-describedby data-file-ajax-upload-url data-file-ajax-upload-params data-file-ajax-delete-params data-file-ajax-callback-function data-file-ajax-toast-success-txt data-file-ajax-toast-error-txt data-file-ajax-upload-enable data-file-ajax-reorder-enable data-file-ajax-reorder-url data-js-advanced-identifier data-js-file-input-clone js-advanced-identifier data-file-ext data-file-max-size-kb-per-file data-file-max-size-kb-total data-file-max-total-files data-file-ext-err-msg data-file-exist-err-msg data-file-size-err-item-msg data-file-size-err-total-msg data-file-size-err-max-msg data-file-toast-position data-file-preview-container data-file-preview-img-height data-file-preview-show-info data-file-btn-clear data-file-preview-class data-file-preview-img-cover file-preview-list-type data-file-ajax-progressbar-custom data-file-ajax-progressbar-disable'); 18514 _clone.attr('id', _bulkNo).attr('name', input_name); 18515 18516 _t.val('').removeAttr('name').attr('data-orig-name', input_name); 18517 18518 // This container holds all clonned inputs 18519 if(jQuery('#js_advanced_form_identifier_'+fileInputIdentifier).length < 1) { 18520 var __el = _t.next(); 18521 18522 // If input is inside a <label> 18523 if(_t.parents('label').length > 0) 18524 __el = _t.parents('label'); 18525 18526 // bootstrap custom file 18527 else if(_t.parents('div.custom-file').length > 0) { 18528 __el = _t.parents('div.custom-file'); 18529 18530 if(_t.parents('div.input-group').length > 0) 18531 __el = _t.parents('div.input-group'); 18532 18533 } 18534 18535 // If input is directly inside a <form> 18536 if(_t.parent('form').length > 0) 18537 __el = _t; 18538 18539 __el.after('<div id="js_advanced_form_identifier_'+fileInputIdentifier+'" class="viewport-out w--50 h--50 opacity-0"></div>'); 18540 } 18541 18542 jQuery('#js_advanced_form_identifier_'+fileInputIdentifier).append(_clone); 18543 18544 window.filesLastBulk = []; 18545 window.filesSizeBulk += file_size_kb_bulk; 18546 18547 } 18548 18549 18550 18551 18552 /** 18553 18554 AJAX : UPLOAD 18555 18556 **/ 18557 if(ajax_process_enable === true) { 18558 18559 // Block input 18560 _t.addClass('disabled').prop('disabled', true); 18561 _t.parents('.btn').a
18561ddClass('disabled active'); 18562 18563 // Wait a little bit for the previews to show up! 18564 setTimeout(function() { 18565 18566 // are added back by ajax if no error 18567 _t.removeClass('disabled').prop('disabled', false); 18568 _t.parents('.btn').removeClass('disabled active'); 18569 $.SOW.core.file_upload.file_upload__ajax_upload(fileInputIdentifier, _bulkNo); 18570 18571 }, 350); 18572 } 18573 18574 // console.log(window.fileInventory); 18575 18576 }); 18577 18578 18579 18580 18581 }, 18582 18583 // reset to intial state 18584 file_upload__reset: function(_t, btn_clear_files, preview_container, input_name, fileInputIdentifier) { 18585 18586 jQuery('.js-file-input-item', preview_container).remove(); 18587 jQuery(btn_clear_files).addClass('hide'); 18588 18589 // restoring back to original 18590 _t.val('').attr('name', input_name).removeAttr('data-orig-name').prop('disabled', false); 18591 18592 // remove the entire container holding cloned/inputs 18593 jQuery('#js_advanced_form_identifier_'+fileInputIdentifier).remove(); 18594 18595 // set back "Choose file" label 18596 var label_orig = _t.next('.custom-file-label').attr('data-orig') || 'Choose file'; 18597 _t.next('.custom-file-label').html(label_orig); 18598 18599 window.fileInventory[fileInputIdentifier] = []; 18600 window.filesLastBulk = []; 18601 18602 }, 18603 18604 // clear input values 18605 file_upload__clear: function(fileInputIdentifier) { 18606 18607 jQuery('input[type="file"][data-js-advanced-identifier="'+fileInputIdentifier+'"]').val('').prop('disabled', false); 18608 18609 }, 18610 18611 file_upload__preview_tpl: function(file, file_ext, item_unique_id, _bulkNo, h, preview_info, preview_class, ajax_process_enable, preview_delete, preview_as_cover, preview_list_type, is_multiple) { 18612 18613 18614 18615 var default_preview_height = (h == 'auto' || h == '100%') ? h : 120, 18616 img_fluid = ''; 18617 18618 18619 if(typeof h !== 'number') { 18620 18621 switch(preview_list_type) { 18622 18623 case 'list': var h = 50; 18624 break; 18625 18626 // 'box' 18627 default: var h = default_preview_height; 18628 var img_fluid = 'img-fluid'; 18629 18630 } 18631 18632 } 18633 18634 // 50px min. height for `list` type 18635 if(preview_list_type == 'list' && h < 50) 18636 var h = 50; 18637 18638 var __h = (typeof h !== 'number') ? '100%' : h + 'px'; 18639 18640 18641 switch(preview_as_cover) { 18642 18643 case true: var item_style = 'width: '+__h+'; height: '+__h+';'; 18644 break; 18645 18646 // false 18647 default: var item_style = 'min-width: '+__h+'; min-height: '+__h+'; width: auto; height: auto;'; 18648 18649 } 18650 18651 18652 var _loadingIcon = '<i class="' + $.SOW.config.sow__icon_loading + ' fs--30"></i>'; 18653 var _loadingIconSize = (preview_list_type == 'list') ? 'fs--20' : 'fs--30'; 18654 18655 // default preview class 18656 if(preview_class == '') 18657 var preview_class = (preview_list_type == 'list') ? 'show-hover-container shadow-md mb-2 rounded' : 'show-hover-container shadow-md m-2 rounded'; 18658 18659 // Default : Show Loading 18660 var file_img = '<span class="js-advanced-form-default-preview absolute-full d-flex align-items-center justify-content-center opacity-6 '+_loadingIconSize+' '+$.SOW.config.sow__icon_loading+'"></span>'; 18661 18662 // bytes to size 18663 var human_size = $.SOW.helper.byte2size(file.size); 18664 18665 // Image -or- extension 18666 // Default append. src = transaprent png base64 18667 var file_is_image = false; 18668 if (file_ext == "gif" || file_ext == "png" || file_ext == "jpg" || file_ext == "jpeg" || file_ext == "jpeg") { 18669 var file_is_image = true; 18670 file_img += '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="" class="hide animate-bouncein js-file-input-preview mw-100 '+img_fluid+'" height="'+h+'">'; 18671 } 18672 18673 else if (file_ext != '') { 18674 var file_ext_font_size = (h < 80) ? 'fs--20' : 'fs--30'; 18675 var file_ext_font_size = (preview_list_type == 'list') ? 'fs--18' : file_ext_font_size; 18676 var file_img = '<span class="absolute-full d-flex align-items-center justify-content-center '+file_ext_font_size+' opacity-6 text-uppercase text-truncate">'+file_ext+'</span>'; 18677 } 18678 18679 var pos_start = ($.SOW.globals.direction == 'ltr') ? 'left-0' : 'right-0'; 18680 var pos_end = ($.SOW.globals.direction == 'ltr') ? 'right-0' : 'left-0'; 18681 18682 18683 18684 18685 18686
18687 // 1. LIST : START TEMPLATE 18688 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 18689 if(preview_list_type == 'list') { 18690 18691 var _tpl = '<div data-id="0" data-file-name="'+file.name+'" data-file-size="'+file.size+'" id="'+item_unique_id+'" class="js-file-input-item '+_bulkNo+' d-flex clearfix position-relative '+preview_class+'">'; 18692 18693 // delete button 18694 if(preview_delete != false) { 18695 18696 _tpl += '<a href="#" data-item-id="'+item_unique_id+'" data-id="0" data-file-name="'+file.name+'" class="js-file-item-del position-absolute absolute-top show-hover-item '+pos_end+' z-index-2">' 18697 + '<span class="d-inline-block btn btn-sm bg-danger text-white pt--4 pb--4 pl--10 pr--10 m--1">' 18698 + '<i class="'+$.SOW.config.sow__icon_close+' m-0"></i>' 18699 + '</span>' 18700 + '</a>'; 18701 18702 } 18703 18704 // image | file required min-* because of flex... 18705 _tpl += '<div class="position-relative d-inline-block bg-cover" style="width:'+h+'px; min-width:'+h+'px; height:'+h+'px">' + file_img + '</div>'; 18706 18707 _tpl += '<div class="pl--15 pr--15 flex-fill d-flex min-w-0 align-items-center">'; 18708 18709 // file name 18710 _tpl += '<span class="text-truncate d-block line-height-1">' + file.name; 18711 18712 // file size 18713 if(preview_info != false) 18714 _tpl += '<br><span class="fs--12 d-block pt-1">'+human_size+'</span>'; 18715 18716 _tpl += '</span>'; 18717 18718 _tpl += '</div>'; 18719 18720 // ajax loading 18721 if(ajax_process_enable === true) { 18722 _tpl += '<span class="hide hide-force js-file-input-preview-ajax-uploading absolute-full d-flex align-items-center justify-content-center overlay-light overlay-opacity-8 z-index-2 pl--15 pr--15">' 18723 + _loadingIcon 18724 + '</span>'; 18725 } 18726 18727 18728 _tpl += '</div>'; 18729 18730 return _tpl; 18731 18732 } 18733 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 18734 18735 18736 18737 18738 18739 18740 18741 // 2. BOX : START TEMPLATE 18742 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 18743 var _tpl = '<span data-id="0" data-file-name="'+file.name+'" data-file-size="'+file.size+'" id="'+item_unique_id+'" class="js-file-input-item '+_bulkNo+' d-inline-block position-relative overflow-hidden text-center '+preview_class+'" style="'+item_style+'">'; 18744 18745 _tpl += (preview_as_cover !== false) ? '' : file_img; 18746 // _tpl += '<span class="overlay-dark overlay-opacity-1 absolute-full"></span>' 18747 18748 18749 // header (file name) to non-image files! 18750 if(file_is_image === false || preview_info != false) { 18751 18752 _tpl += '<span class="js-file-input-preview-header text-white position-absolute w-100 top-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">' 18753 + '<span class="text-truncate d-block fs--12 pl--5 pr--5">' + file.name + '</span>' 18754 + '</span>'; 18755 } 18756 18757 // footer 18758 if(preview_info != false) { 18759 18760 // file will be populated (or not) by reader (reason: async) 18761 _tpl += '<span class="js-file-input-preview-footer text-white position-absolute w-100 bottom-0 left-0 right-0 clearfix overlay-dark overlay-opacity-2">' 18762 + '<span class="js-file-input-file-info-size text-truncate d-block fs--12 pl--5 pr--5">'+human_size+'</span>' 18763 + '</span>'; 18764 18765 } 18766 18767 // ajax only 18768 if(ajax_process_enable === true) { 18769 18770 // delete button 18771 if(preview_delete != false && is_multiple != false) { 18772 18773 _tpl += '<a href="#" data-item-id="'+item_unique_id+'" data-id="0" data-file-name="'+file.name+'" class="js-file-item-del position-absolute absolute-top show-hover-item '+pos_start+' z-index-2">' 18774 + '<span class="d-inline-block btn btn-sm bg-danger text-white pt--4 pb--4 pl--10 pr--10 m--1">' 18775 + '<i class="'+$.SOW.config.sow__icon_close+' m-0"></i>' 18776 + '</span>' 18777 + '</a>'; 18778 } 18779 18780 // ajax loading 18781 _tpl += '<span class="hide hide-force js-file-input-preview-ajax-uploading absolute-full d-flex align-items-center justify-content-center overlay-light overlay-opacity-8 z-index-3">' 18782 +_loadingIcon 18783 + '</span>'; 18784 18785 } 18786 18787 18788 _tpl += '</span>'; 18789 18790 return _tpl; 18791 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 18792 18793 18794 }, 18795 18796 file_upload__preview_img_render: function(id, file, preview_as_cover, preview_list_type) { 18797 18798 var reader = new FileReader(); 18799 reader.onload = function(s) { 18800 18801 jQuery(id + ' .js-advanced-form-default-preview').remove(); 18802 18803 if(preview_as_cover !== false) { 18804 18805 var __id = (preview_list_type == 'list') ? id + '>.bg-cover' : id; 18806 jQuery(__id).css("background-image", "url(" + s.target.result + ")").addClass('bg-cover').removeClass('hide'); 18807 18808 } else { 18809 18810 jQuery(id + ' img.js-file-input-preview').attr('src', s.target.result).removeClass('hide'); 18811 18812 } 18813 18814 } 18815
18816 reader.readAsDataURL(file); 18817 18818 }, 18819 18820 // delete last bulk added (multiple file only) 18821 file_upload__del_bulk: function(_t, _bulkNo, btn_clear_files, preview_container, input_name, fileInputIdentifier) { 18822 18823 // clear last added! 18824 for (var b = 0; b < window.filesLastBulk.length; ++b) { 18825 18826 // remove last bulk added only 18827 jQuery('#'+_bulkNo).remove(); // file input 18828 jQuery('.'+_bulkNo).remove(); // images 18829 18830 // check if other files are there. if not, reset 18831 var _remains = jQuery('.js-file-input-item', preview_container).length; 18832 if(_remains < 1) 18833 $.SOW.core.file_upload.file_upload__reset(_t, btn_clear_files, preview_container, input_name, fileInputIdentifier); 18834 18835 } 18836 18837 // reset 18838 $.SOW.core.file_upload.file_upload__clear(fileInputIdentifier); 18839 window.fileInventory[fileInputIdentifier] = []; 18840 18841 }, 18842 18843 file_upload__preview_delbtn_bind_multiple: function(_t, request_from_preadded) { 18844 18845 var fileInputIdentifier = _t.attr('data-js-advanced-identifier') || '', 18846 preview_container = _t.attr('data-file-preview-container') || '', 18847 preview_delete = _t.attr('data-file-ajax-delete-enable') || false, 18848 ajax_url = _t.attr('data-file-ajax-delete-url') || _t.attr('data-file-ajax-upload-url'), 18849 ajax_params = _t.attr('data-file-ajax-delete-params') || '', 18850 is_multiple = _t.attr('multiple') || false, 18851 preview_height = _t.attr('data-file-preview-img-height') || '120'; 18852 18853 if(preview_container == '' || is_multiple == false) 18854 return; 18855 18856 else if(ajax_url == '' || preview_delete == false) { 18857 18858 // remove delete button 18859 jQuery(preview_container + ' a.js-file-item-del').remove(); 18860 18861 return; 18862 } 18863 18864 // -- 18865 18866 18867 // Setting up preadded files 18868 if(request_from_preadded === true) { 18869 jQuery(preview_container + ' .js-file-input-item').each(function() { 18870 18871 var elItemPreadded = jQuery(this), 18872 _preaddedItemId = 'rand_' + $.SOW.helper.randomStr(3); 18873 18874 elItemPreadded.attr('id', _preaddedItemId); 18875 18876 jQuery('img', elItemPreadded).attr('height', preview_height); 18877 jQuery('a.js-file-item-del', elItemPreadded).attr('data-item-id', _preaddedItemId); // DOM item id 18878 18879 }); 18880 } 18881 18882 var btn_file_del = preview_container + ' a.js-file-item-del'; 18883 $.SOW.core.file_upload.file_upload__preview_item_del_ajax(fileInputIdentifier, btn_file_del, ajax_params, ajax_url); 18884 18885 }, 18886 18887 file_upload__preview_delbtn_bind_single: function(_t, request_from_preadded) { 18888 18889 var fileInputIdentifier = _t.attr('data-js-advanced-identifier') || '', 18890 preview_container = _t.attr('data-file-preview-container') || '', 18891 preview_delete = _t.attr('data-file-ajax-delete-enable') || false, 18892 ajax_url = _t.attr('data-file-ajax-delete-url') || _t.attr('data-file-ajax-upload-url'), 18893 ajax_params = _t.attr('data-file-ajax-delete-params') || '', 18894 btn_clear = _t.attr('data-file-btn-clear') || '', 18895 is_multiple = _t.attr('multiple') || false; 18896 18897 if(is_multiple != false || btn_clear == '' || ajax_url == '' || preview_delete == false) 18898 return; 18899 18900 // We use the same button as "delete" button normally added by the template 18901 jQuery(btn_clear).addClass('js-file-item-del'); 18902 18903 // Setting up 18904 var elItemPreadded = jQuery(preview_container + ' .js-file-input-item'), 18905 _preaddedFileName = elItemPreadded.attr('data-file-name') || '', 18906 _preaddedItemId = elItemPreadded.attr('id') || ''; 18907 18908 if(elItemPreadded.length < 1) 18909 return; 18910 18911 // Disable input 18912 _t.prop('disabled', true); 18913 18914 if(_preaddedItemId == '') { 18915 _preaddedItemId = 'rand_' + $.SOW.helper.randomStr(3); 18916 elItemPreadded.attr('id', _preaddedItemId); 18917 } 18918 18919 jQuery(btn_clear).attr('data-item-id', _preaddedItemId); // DOM item id 18920 18921 $.SOW.core.file_upload.file_upload__preview_item_del_ajax(fileInputIdentifier, btn_clear, ajax_params, ajax_url); 18922 18923 // REQUIRED: AFTER file_upload__preview_item_del_ajax() 18924 if(request_from_preadded === true) { 18925 var input_name = _t.attr('name') || _t.data('orig-name'); 18926 $.SOW.core.file_upload.file_upload__btn_clear_bind(btn_clear, _t, preview_container, input_name, fileInputIdentifier); 18927 } 18928 18929 }, 18930 18931 file_upload__preview_item_del_ajax: function(fileInputIdentifier, btn_file_del, ajax_params, ajax_url) { 18932 18933 jQuery(btn_file_del).not('.js-advancified').addClass('js-advancified').on('click', function(e) { 18934 e.preventDefault(); 18935 18936 var elBtn = jQuery(this), 18937 item_id = elBtn.attr('data-item-id') || ''; 18938 18939 if(item_id == '') // required 18940 return; 18941 18942 var elItem = $('#'+item_id), 18943 fileName = elItem.attr('data-file-name') || '', 18944 fileSize = elItem.attr('data-file-size') || 0, 18945 fileID = elItem.attr('data-id') || 0; 18946 18947 if(fileName == '' && item_id == '') { 18948 $.SOW.helper.consoleLog('Delete request not sent!'); 18949 $.SOW.helper.consoleLog('Please provide: data-id -OR- data-file-name '); 18950 return; 18951 } 18952 18953 18954 /* 18955 18956 Form & custom params 18957 18958 */ 18959 var formDataDel = new FormData(); 18960 formDataDel.append('action', 'delete_file'); 18961 formDataDel.append('ajax', 'true'); 18962 18963 var ajax_params_arr = $.SOW.helper.params_parse(ajax_params); 18964 for (var i = 0; i < ajax_params_arr.length; ++i) { 18965 formDataDel.append(ajax_params_arr[i][0], ajax_params_arr[i][1]); 18966 } 18967 18968 // Add required params to form 18969 formDataDel.append('file_name', fileName); 18970 formDataDel.append('file_id', fileID); 18971 formDataDel.append('__info', '`file_id` = internal/database file id. 0 = not provided!'); 18972 18973 // -- 18974 18975 $.ajax({ 18976 url: ajax_url, 18977 cache: false, 18978 contentType: false, 18979 processData: false, 18980 data: formDataDel, 18981 type: 'POST', 18982 headers: '', 18983 crossDomain: '', 18984 18985 beforeSend: function() { 18986 18987 18988 }, 18989 18990 success: function (data) { 18991 18992 $.SOW.helper.consoleLog(data); 18993 18994 // remove file from the list 18995 if(item_id != '') 18996 jQuery('#'+item_id).remove(); 18997 18998 18999 19000 // remove from inventory, or the file could not be added again 19001 if(fileSize != '') { 19002 19003 var _concat = fileName+':'+fileSize+':'+fileInputIdentifier; 19004 for (var inventoryIndex in window.fileInventory[fileInputIdentifier]) { 19005 if(window.fileInventory[fileInputIdentifier][inventoryIndex] == _concat) { 19006 window.fileInventory[fileInputIdentifier].splice(inventoryIndex,1); 19007 break; 19008 } 19009 } // -- 19010 19011 } 19012 19013 }, 19014 19015 error: function (data) { 19016 19017 $.SOW.helper.consoleLog(data); 19018 19019 if(typeof $.SOW.core.toast === 'object') { 19020 $.SOW.core.toast.show('danger', '', '404 Server Error!', $.SOW.core.file_upload.config.toast_pos, $.SOW.core.file_upload.config.toast_delay, true); 19021 } else { 19022 alert('404 Server Error!'); 19023 } 19024 19025 }, 19026 19027 }); 19028 19029 }); 19030 19031 }, 19032 19033 file_upload__preview__reorder_bind: function(_t, request_from_preadded) { 19034 19035 var sortableProcessDelay = 0; 19036
19037 if(typeof $.SOW.vendor.sortable !== 'object') { 19038 19039 $.SOW.helper.consoleLog('Ajax Image Reorder : Require Sortablejs Vendor!'); 19040 return; 19041 19042 } else { 19043 19044 // sortable is external? 19045 if (typeof Sortable !== 'function') { 19046 19047 var sortableProcessDelay = 1300; 19048 19049 if($.SOW.config.autoinit['sortable']) { 19050 var _selector = $.SOW.config.autoinit['sortable'][1]; 19051 var _config = $.SOW.config.autoinit['sortable'][2]; 19052 var _class = _selector.replace('.', ''); 19053 jQuery('#middle').append('<span class="hide '+_class+'"></span>'); 19054 $.SOW.vendor.sortable.init(_selector, _config); 19055 } else { return false; } 19056 } 19057 19058 } 19059 19060 19061 var fileInputIdentifier = _t.attr('data-js-advanced-identifier') || '', 19062 fileInputName = _t.attr('name') || _t.attr('data-orig-name'), 19063 preview_container = _t.attr('data-file-preview-container') || '', 19064 ajax_url = _t.attr('data-file-ajax-reorder-url') || _t.attr('data-file-ajax-upload-url'), 19065 ajax_params = _t.attr('data-file-ajax-reorder-params') || '', 19066 reorder_toast_success = _t.attr('data-file-ajax-reorder-toast-success') || '', 19067 reorder_toast_position = _t.attr('data-file-ajax-reorder-toast-position') || '', 19068 preview_reorder = _t.attr('data-file-ajax-reorder-enable') || false; 19069 19070 if(preview_container == '') 19071 return; 19072 19073 else if(ajax_url == '' || preview_reorder == false) { 19074 19075 // remove draggable attribute 19076 jQuery(preview_container + ' .js-file-input-item').removeAttr('draggable'); 19077 19078 return; 19079 19080 } 19081 19082 // -- 19083 19084 // add .js-ignore filter for all other items that are not files (texts, titles, etc) 19085 jQuery('>:not(.js-file-input-item)', preview_container).addClass('js-ignore'); 19086 19087 // Add Sortable required params 19088 jQuery(preview_container).attr('data-ajax-update-url', ajax_url); 19089 jQuery(preview_container).attr('data-ajax-update-params', ajax_params); 19090 jQuery(preview_container).attr('data-ajax-update-identifier', fileInputName.replace('[]', '')); 19091 19092 if(reorder_toast_success != '') 19093 jQuery(preview_container).attr('data-update-toast-success', reorder_toast_success); 19094 19095 if(reorder_toast_position != '') 19096 jQuery(preview_container).attr('data-update-toast-position', reorder_toast_position); 19097 19098 setTimeout(function() { 19099 $.SOW.vendor.sortable.process($(preview_container)); 19100 }, sortableProcessDelay); 19101 19102 }, 19103 19104 file_upload__btn_clear_bind: function(btn_clear_files, _t, preview_container, input_name, fileInputIdentifier) { 19105 19106 // show `remove all files` button 19107 jQuery(btn_clear_files).removeClass('hide').on('click', function(e) { 19108 e.preventDefault(); 19109 19110 // added by file_upload__preview_delbtn_bind_single() 19111 jQuery(this).removeAttr('data-item-id data-id data-file-name'); 19112 19113 $.SOW.core.file_upload.file_upload__reset(_t, btn_clear_files, preview_container, input_name, fileInputIdentifier); 19114 }); 19115 19116 }, 19117 19118 file_upload__ajax_upload: function(fileInputIdentifier, _bulkNo) { 19119 19120 19121 if(_bulkNo == '' && fileInputIdentifier == '') { 19122 $.SOW.helper.consoleLog('Ajax Image Upload Status : Identifiers missing!'); 19123 return; 19124 } 19125 19126 19127 // Getting Data 19128 var fileInventory = [], 19129 elFileInput = jQuery('input[type="file"][data-js-advanced-identifier="'+fileInputIdentifier+'"]'), 19130 ajax_url = elFileInput.data('file-ajax-upload-url') || '', 19131 ajax_params = elFileInput.data('file-ajax-upload-params') || '', 19132 msg_success = elFileInput.data('file-ajax-toast-success-txt') || '', 19133 msg_error = elFileInput.data('file-ajax-toast-error-txt') || '', 19134 btn_remove = elFileInput.data('file-btn-clear') || '', 19135 form_name = elFileInput.attr('name') || elFileInput.data('orig-name'), 19136 ajax_callback = elFileInput.data('file-ajax-callback-function') || '', 19137 is_multiple = elFileInput.attr('multiple') || false, 19138 preview_container = elFileInput.data('file-preview-container') || '', 19139 preview_reorder = elFileInput.data('file-ajax-reorder-enable') || false, 19140 progressDisabled = elFileInput.data('file-ajax-progressbar-disable') || false, 19141 toast_position = elFileInput.data('file-toast-position') || $.SOW.core.file_upload.config.toast_pos; 19142 19143 19144 // search for from as parent, if exists 19145 if(ajax_url == '') { 19146 19147 if(elFileInput.parents('form').length > 0) 19148 ajax_url = elFileInput.parents('form').attr('action'); 19149 19150 } 19151 19152 // still empty? 19153 if(ajax_url == '') { 19154 $.SOW.helper.consoleLog('Ajax Image Upload Status : [data-file-ajax-upload-url] : Missing -or- Empty!'); 19155 return; 19156 } 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 19167 19168 /* 19169 19170 1. Bulk only 19171 19172 */ 19173 if(_bulkNo != '') { 19174 19175 if(window.browser_hasIssues === true) { 19176 var _t = jQuery('input[type="file"][data-js-advanced-identifier="'+fileInputIdentifier+'"]'); 19177 } else { 19178 var _t = jQuery('input[type="file"]#'+_bulkNo); 19179 } 19180 19181 19182 for (var i = 0; i < _t.get(0).files.length; ++i) { 19183 fileInventory.push(_t.get(0).files[i]); 19184 } 19185 19186 19187 /* 19188 19189 2. All bulks at once (for safari or other browsers with issue) 19190 19191 */ 19192 } else { 19193 19194 if(window.browser_hasIssues === true) { 19195 var _t = jQuery('input[type="file"][data-js-advanced-identifier="'+fileInputIdentifier+'"]'); 19196 } else { 19197 var _t = jQuery('#js_advanced_form_identifier_'+fileInputIdentifier+'>input[type="file"]'); 19198 } 19199 19200 19201 _t.each(function() { 19202 19203 var files = jQuery(this).get(0).files; 19204 19205 for (var i = 0; i < files.length; ++i) { 19206 fileInventory.push(files[i]); 19207 } 19208 19209 }); 19210 19211 } 19212 19213 19214 19215 19216 19217 19218 19219 // Safe Check 19220 if(fileInventory.length < 1) { 19221 $.SOW.helper.consoleLog('Ajax Image Upload Status : No file found to upload!'); 19222 return; 19223 } 19224 19225 19226 19227 19228 // Create form 19229 var formData = new FormData(); 19230 // -- -- -- -- 19231 19232 19233 19234 19235 19236 // Add custom params to post +++++++++++++++++++++++++++++++++++++++ 19237 var ajax_params_arr = $.SOW.helper.params_parse(ajax_params); 19238 for (var i = 0; i < ajax_params_arr.length; ++i) { 19239 formData.append(ajax_params_arr[i][0], ajax_params_arr[i][1]); 19240 } 19241 19242 // Of course, our eternal param :) 19243 formData.append('ajax', 'true'); 19244 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 19245 19246 19247 19248 19249 19250 // add files to form +++++++++++++++++++++++++++++++++++++++++++++++ 19251 for (var i = 0; i < fileInventory.length; ++i) { 19252 formData.append(form_name, fileInventory[i]); 19253 } 19254 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 19255 19256 19257 19258 19259 19260 $.ajax({ 19261 url: ajax_url, 19262 cache: false, 19263 contentType: false, 19264 processData: false, 19265 data: formData, 19266 type: 'POST', 19267 enctype: 'multipart/form-data', 19268 headers: '', 19269 crossDomain: '', 19270 19271 beforeSend: function() { 19272 19273 jQuery('.js-file-input-item.'+_bulkNo+' .js-file-input-preview-ajax-uploading').removeClass('hide hide-force'); 19274 // jQuery(btn_remove).addClass('hide hide-force'); // button "remove files" 19275 19276 elFileInput.addClass('disabled').prop('disabled', true); 19277 elFileInput.parents('.btn').addClass('disabled active'); 19278 elFileInput.parent().find('.js-file-input-ajax-loader').removeClass('hide hide-force'); 19279 19280 // Create progress bar 19281 $.SOW.core.file_upload.file_upload__ajax_upload_progressbar_init(elFileInput); 19282 19283 }, 19284 19285 success: function (data) { 19286 19287 $.SOW.helper.consoleLog(data); 19288 elFileInput.removeClass('disabled').prop('disabled', false); 19289 elFileInput.parents('.btn').removeClass('disabled active'); 19290 elFileInput.parent().find('.js-file-input-ajax-loader').addClass('hide hide-force'); 19291 19292 jQuery('.js-file-input-item.'+_bulkNo+' .js-file-input-preview-ajax-uploading i').replaceWith('<i class="'+$.SOW.config.sow__icon_check+' fs--20 pt--5 text-success w--40 h--40 d-inline-block text-center bg-success-soft rounded-circle opacity-8 animate-bouncein"></i>'); 19293 setTimeout(function() { 19294 19295 jQuery('.js-file-input-item.'+_bulkNo+' .js-file-input-preview-ajax-uploading').fadeOut(200, function() { 19296 jQuery(this).remove(); 19297 }); 19298 19299 }, $.SOW.core.file_upload.config.toast_delay); 19300 19301 19302 if(typeof $.SOW.core.toast === 'object' && msg_success != '') 19303 $.SOW.core.toast.show('success', '', msg_success, toast_position, $.SOW.core.file_upload.config.toast_delay, true); 19304 19305 19306 // callback function 19307 if(ajax_callback != '' && typeof $.SOW.helper.executeFunctionByName === "function") 19308 $.SOW.helper.executeFunctionByName(ajax_callback, window, data, elFileInput); // input element is returned because of safari issues (bulk is empty) 19309 19310 // Destroy progress bar 19311 $.SOW.core.file_upload.file_upload__ajax_upload_progressbar_destroy(elFileInput, false); 19312 19313 19314 // Disable input 19315 if(is_multiple === false) 19316 elFileInput.prop('disabled', true); 19317 19318 /** 19319 19320 UPDATE FOR REORDER 19321 If backend provided required data (internal id) 19322 19323 data-id="0" 19324 data-file-name="file.jpg" 19325 19326 19327 PHP Example 19328 Server response format: 19329 19330 $response = array( 19331 'file_list' => array( 19332 19333 // original file name internal id 19334 'orig_file_name_1.jpg' => 1, 19335 'orig_file_name_2.jpg' => 345, 19336 19337 // ... 19338 19339 ), 19340 19341 // more stuff for callback (if used) 19342 'something_else' => array(), 19343 ); 19344 19345 echo json_encode($response); 19346 exit; 19347 19348 **/ 19349 // if(preview_reorder != false) { 19350 19351 /* test */ // var data = {"file_list":{"orig_file_name_1.jpg":1,"orig_file_name_2.jpg":345},"something_else":[]} 19352 try { 19353 19354 var _json = JSON.parse(data); 19355 19356 } catch(err) { 19357 19358 // No json, we do nothing! 19359 var _json = ''; 19360 19361 } 19362 19363 if(_json != '') { 19364 19365 if(typeof _json['file_list'] !== 'undefined') { 19366 19367 for (var fileName in _json['file_list']) { 19368 19369 jQuery(preview_container + ' .js-file-input-item[data-file-name="'+fileName+'"]').attr('data-id', _json['file_list'][fileName]); 19370 19371 } 19372 19373 } 19374 19375 // Bind reorder 19376 $.SOW.core.file_upload.file_upload__preview__reorder_bind(jQuery(preview_container), true); 19377 19378 } 19379 19380 // } // end preview reorder 19381 19382 }, 19383 19384 error: function (data) { 19385 19386 $.SOW.helper.consoleLog(data); 19387 19388 elFileInput.removeClass('disabled').prop('disabled', false); 19389 elFileInput.parents('.btn').removeClass('disabled active'); 19390 elFileInput.parent().find('.js-file-input-ajax-loader').addClass('hide hide-force'); 19391 19392 jQuery('.js-file-input-item.'+_bulkNo+' .js-file-input-preview-ajax-uploading i').replaceWith('<i title="Ajax upload error!" class="'+$.SOW.config.sow__icon_close+' fs--20 text-success w--40 h--40 pt--5 d-inline-block text-center bg-danger-soft rounded-circle opacity-8 animate-bouncein"></i>'); 19393 if(typeof $.SOW.core.toast === 'object' && msg_error != '') 19394 $.SOW.core.toast.show('danger', '', msg_error, toast_position, $.SOW.core.file_upload.config.toast_delay, true); 19395 19396 // Destroy progress bar 19397 $.SOW.core.file_upload.file_upload__ajax_upload_progressbar_destroy(elFileInput, false); 19398 19399 }, 19400 19401 // progress bar 19402 xhr: function() { 19403 19404 var __xhr = new XMLHttpRequest(); 19405 19406 __xhr.upload.addEventListener("progress", function(e) { 19407 19408 if(e.lengthComputable && progressDisabled == false) { 19409 19410 var ___percent = e.loaded / e.total, 19411 ___percent = Math.round(___percent * 100); // (___percent * 100); -or- Math.round(___percent * 100); 19412 19413 $('.js_file_input_progress__'+fileInputIdentifier + ' .js-file-input-upload-percent').text(___percent+'%'); 19414 $('.js_file_input_progress__'+fileInputIdentifier + ' .progress-bar').
19414css('width', ___percent+'%'); 19415 $('.js_file_input_progress__'+fileInputIdentifier + ' .progress-bar').attr('aria-valuenow', ___percent); 19416 19417 if(___percent >= 100) { 19418 19419 // we add "ok" icon only to the dynamic progress created by this script, not to custom 19420 $('.js_file_input_progress__'+fileInputIdentifier + ' .js-file-input-upload-percent.js-file-input-upload-percent-dynamic').prepend('<i class="'+$.SOW.config.sow__icon_check+' fs--10 animate-bouncein"></i> '); 19421 19422 // we add some common classes as helpers to custom progress, in case needed as extra! 19423 $('.js_file_input_progress__'+fileInputIdentifier + ', .js_file_input_progress__'+fileInputIdentifier + ' .js-file-input-upload-percent:not(.js-file-input-upload-percent-dynamic) .group-icon').addClass('active'); 19424 19425 } 19426 19427 } 19428 19429 }, false); 19430 19431 return __xhr; 19432 19433 } 19434 19435 19436 }); 19437 19438 }, 19439 19440 file_upload__ajax_upload_progressbar_init: function(elFileInput) { 19441 19442 if(elFileInput.length < 1) 19443 return; 19444 19445 var fileInputIdentifier = elFileInput.data('js-advanced-identifier') || '', 19446 customProgress = elFileInput.data('file-ajax-progressbar-custom') || '', 19447 progressDisabled = elFileInput.data('file-ajax-progressbar-disable') || false, 19448 __next = elFileInput.next(); 19449 19450 if(fileInputIdentifier == '' || progressDisabled != false) 19451 return; 19452 19453 19454 19455 19456 19457 19458 19459 // ++ ++ ++ ++ ++ ++ ++ Check custom progress ++ ++ ++ ++ ++ ++ 19460 if(jQuery(customProgress).length > 0) { 19461 19462 var elCustomProgress = jQuery(customProgress); 19463 19464 // usually first init, should have the class in place each call (new upload) 19465 if(!elCustomProgress.hasClass('js_file_input_progress__' + fileInputIdentifier)) 19466 elCustomProgress.addClass('js_file_input_progress__' + fileInputIdentifier); 19467 19468 19469 // Reset progress. If previously used should be at 100% now 19470 jQuery('.progress-bar', elCustomProgress).css('width', '0%'); 19471 jQuery('.progress-bar', elCustomProgress).css('width', '0%'); 19472 jQuery('.js-file-input-upload-percent', elCustomProgress).text('0%'); 19473 elCustomProgress.removeClass('hide hide-force'); 19474 19475 19476 // Done! Ajax function will do the update! 19477 return; 19478 19479 } 19480 // ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 19481 19482 19483 19484 19485 19486 19487 19488 // ++ ++ ++ ++ ++ Finding a place for progress bar ++ ++ ++ ++ ++ 19489 // If input is inside a <label> 19490 if(elFileInput.parents('label').length > 0) 19491 __next = elFileInput.parents('label'); 19492 19493 // bootstrap custom file 19494 else if(elFileInput.parents('div.custom-file').length > 0) 19495 __next = elFileInput.parents('div.custom-file'); 19496 // ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 19497 19498 19499 19500 // Remove first, in case already exists! 19501 jQuery('.js_file_input_progress__'+fileInputIdentifier).remove(); 19502 19503 19504 19505 // PROGRESS TEMPLATE ++++++++++++ 19506 var _tpl = '<span class="js_file_input_progress__'+fileInputIdentifier+' animate-bouncein transition-all-ease-500 position-absolute w-100 mb--n5 bottom-0 left-0 right-0 h--3">' 19507 + '<span class="progress rounded h--3">' 19508 + '<span class="progress-bar bg-success" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></span>' 19509 + '</span>' 19510 + '<i class="js-file-input-upload-percent js-file-input-upload-percent-dynamic float-start mb--n20 z-index-2 text-dark fs--11">0%</i>' 19511 + '</span>'; 19512 // ++++++++++++++++++++++++++++++ 19513 __next.append(_tpl); // Append inside, absolute position used! 19514 // ++++++++++++++++++++++++++++++ 19515 19516 19517 // Done! Ajax function will do the update! 19518 19519 }, 19520 19521 file_upload__ajax_upload_progressbar_destroy: function(elFileInput, elDestroyForReal) { 19522 19523 19524 if(elFileInput.length < 1) 19525 return; 19526 19527 var fileInputIdentifier = elFileInput.data('js-advanced-identifier') || ''; 19528 19529 if(fileInputIdentifier == '') 19530 return; 19531 19532 19533 19534 // Wait a little bit, sometimes the upload is too fast for small files 19535 // and we want to impress the visitor with our shiny progress bar pointing to 100% DONE! 19536 // Whooo! 19537 setTimeout(function() { 19538 19539 jQuery('.js_file_input_progress__'+fileInputIdentifier).not('.js-ignore').fadeOut(800, function() { 19540 19541 19542 /* 19543 19544 Should be removed only dynamic progress bars 19545 Custom ones should only be hidden, if .js-ignore not present, of course! 19546 19547 */ 19548 if(elDestroyForReal === true) 19549 jQuery(this).remove(); 19550 19551 }); 19552 19553 }, 1000); 19554 19555 }, 19556 19557 file_upload__destroy: function(container) { 19558 var container = (typeof container === 'undefined') ? '' : container; 19559 19560 jQuery(container + ' ' + $.SOW.core.file_upload.config.selector_advanced_file).each(function() { 19561 19562 var _t = jQuery(this), 19563 input_name = _t.attr('name') || _t.data('orig-name'); 19564 19565 // remove class 19566 _t.removeClass('js-advancified'); 19567 19568 // destroy any progress bar 19569 $.SOW.core.file_upload.file_upload__ajax_upload_progressbar_destroy(_t, true); 19570 19571 // restoring back to original 19572 _t.val('').attr('name', input_name).removeAttr('data-orig-name'); 19573 19574 // set back "Choose file" label 19575 var label_orig = _t.next('.custom-file-label').attr('data-orig') || 'Choose file'; 19576 _t.next('.custom-file-label').html(label_orig); 19577 19578 // replace with a clone! 19579 var _cl = _t.clone().off('change'); 19580 _t.replaceWith(_cl); 19581 19582 jQuery('div>.js-file-input-item:first-child').parent().empty(); 19583 19584 }); 19585 19586 window.fileInventory = {}; 19587 window.filesLastBulk = []; 19588 window.filesSizeBulk = 0; 19589 19590 } 19591 19592 } 19593 19594})(jQuery); 19595/** 19596 * 19597 * [SOW] Toast 19598 * 19599 * @author Dorin Grigoras 19600 * www.stepofweb.com 19601 * 19602 * @Dependency - 19603 * @Usage $.SOW.core.toast.init('.toast-on-load'); 19604 * 19605 * 19606 **/ 19607;(function ($) { 19608 'use strict'; 19609 19610 19611 /** 19612 * 19613 * @vars 19614 * 19615 * 19616 **/ 19617 var scriptInfo = 'SOW Toast'; 19618 19619 19620 19621 $.SOW.core.toast = { 19622 19623 19624 /** 19625 * 19626 * @config 19627 * 19628 * 19629 **/ 19630 config: { 19631 animation: 'fade' 19632 }, 19633 19634 19635 19636 /** 19637 * 19638 * @collection 19639 * 19640 * 19641 **/ 19642 collection: $(), 19643 19644 19645 19646 /** 19647 * 19648 * @init 19649 * 19650 * 19651 **/ 19652 init: function (selector, config) { 19653 19654 var __selector = $.SOW.helper.__selector(selector); 19655 var __config = $.SOW.helper.check_var(config); 19656 19657 this.selector = __selector[0]; // '#selector' 19658 this.collection = __selector[1]; // $('#selector') 19659 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 19660 19661 19662 19663 if(jQuery(this.selector).length < 1) 19664 return; 19665 19666 19667 19668 // -- * -- 19669 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 19670 // -- * -- 19671 19672 19673 // 1. Has no selector 19674 if(!this.selector) { 19675 $.SOW.core.toast.toast_on_load('.toast-on-load'); 19676 return this.collection; 19677 } 19678 19679 // 2. Has selector 19680 return this.collection.each(function() { 19681 19682 $.SOW.core.toast.toast_on_load($(this)); 19683 19684 }); 19685 19686 }, 19687 19688 19689 19690 /** 19691 * 19692 * @show 19693 * Direct callable 19694 * 19695 19696 $.SOW.core.toast.show(type, title, body, pos, delay, fill); 19697 type = '', success, danger, warning, info 19698 title = toast title (optional) 19699 body = toast body (required) 19700 pos = top-left, top-right, bottom-left, bottom-right, top-center, bottom-center 19701 delay = autoclose in ms 19702 fill = background color [true|false] 19703 19704 19705 19706 1. NO AUTOHIDE 19707 $.SOW.core.toast.show('', 'Default', 'Body Text Here', 'top-right'); 19708 $.SOW.core.toast.show('danger', 'Error', 'Body Text Here', 'top-right'); 19709 $.SOW.core.toast.show('success', 'Success', 'Body Text Here', 'top-right'); 19710 $.SOW.core.toast.show('warning', 'Warning', 'Body Text Here', 'top-right'); 19711 $.SOW.core.toast.show('info', 'Info', 'Body Text Here', 'top-right'); 19712 19713 2. AUTOHIDE 19714 $.SOW.core.toast.show('', 'Default', 'Body Text Here', 'top-right', 3000); 19715 $.SOW.core.toast.show('danger', 'Error', 'Body Text Here', 'top-right', 3000); 19716 $.SOW.core.toast.show('success', 'Success', 'Body Text Here', 'top-right', 3000); 19717 $.SOW.core.toast.show('warning', 'Warning', 'Body Text Here', 'top-right', 3000); 19718 $.SOW.core.toast.show('info', 'Info', 'Body Text Here', 'top-right', 3000); 19719 19720 3. NO TITLE 19721 $.SOW.core.toast.show('', '', 'Body Text Here', 'top-right'); 19722 $.SOW.core.toast.show('danger', '', 'Body Text Here', 'top-right'); 19723 $.SOW.core.toast.show('success', '', 'Body Text Here', 'top-right'); 19724 $.SOW.core.toast.show('warning', '', 'Body Text Here', 'top-right'); 19725 $.SOW.core.toast.show('info', '', 'Body Text Here', 'top-right'); 19726 19727 1. NO TITLE + BACKGROUND FILL 19728 $.SOW.core.toast.show('', '', 'Body Text Here', 'top-right', 0, true); 19729 $.SOW.core.toast.show('danger', '', 'Body Text Here', 'top-right', 0, true); 19730 $.SOW.core.toast.show('success', '', 'Body Text Here', 'top-right', 0, true); 19731 $.SOW.core.toast.show('warning', '', 'Body Text Here', 'top-right', 0, true); 19732 $.SOW.core.toast.show('info', '', 'Body Text Here', 'top-right', 0, true); 19733 19734
19735 Clear all toasts 19736 $.SOW.core.toast.destroy(); 19737 19738 * 19739 * 19740 **/ 19741 show: function(t_type, t_title, t_body, t_pos, t_delay, t_bg_fill) { 19742 19743 var t_type = typeof t_type !== 'undefined' ? t_type : '', // default|success|danger[error]|warning|info 19744 t_title = typeof t_title !== 'undefined' ? t_title : '', 19745 t_body = typeof t_body !== 'undefined' ? t_body : '', 19746 t_pos = typeof t_pos !== 'undefined' ? t_pos : 'top-left', 19747 t_delay = typeof t_delay !== 'undefined' ? t_delay : 0, 19748 t_bg_fill = typeof t_bg_fill !== 'undefined' ? t_bg_fill : false; 19749 19750 if(t_type == 'error') 19751 var t_type = 'danger'; 19752 19753 else if(t_type == 'default') 19754 var t_type = ''; 19755 19756 // In case body is empty but we have the title - switch between them! 19757 if(t_body == '' && t_title != '') { 19758 var t_body = t_title; 19759 var t_title = ''; 19760 } 19761 19762 19763 // -- 19764 19765 19766 // top right 19767 if(t_pos == 'top-right') { 19768 var _posClass = 'fixed-top right-0'; 19769 var _wrapperID = 'wrapper_toast_tr'; 19770 var t_spacing = 'mt--15 mr--30'; 19771 } 19772 19773 // bottom right 19774 else if(t_pos == 'bottom-right') { 19775 var _posClass = 'fixed-bottom right-0'; 19776 var _wrapperID = 'wrapper_toast_br'; 19777 var t_spacing = 'mb--15 mr--30'; 19778 } 19779 19780 // top left 19781 else if(t_pos == 'top-left') { 19782 var _posClass = 'fixed-top left-0'; 19783 var _wrapperID = 'wrapper_toast_tl'; 19784 var t_spacing = 'mt--15 ml--30'; 19785 } 19786 19787 // bottom left 19788 else if(t_pos == 'bottom-left') { 19789 var _posClass = 'fixed-bottom left-0'; 19790 var _wrapperID = 'wrapper_toast_bl'; 19791 var t_spacing = 'mb--15 ml--30'; 19792 } 19793 19794 // top center 19795 if(t_pos == 'top-center') { 19796 var _posClass = 'fixed-top mx-auto'; 19797 var _wrapperID = 'wrapper_toast_tc'; 19798 var t_spacing = 'mt--15'; 19799 } 19800 19801 19802 // bottom center 19803 if(t_pos == 'bottom-center') { 19804 var _posClass = 'fixed-bottom mx-auto'; 19805 var _wrapperID = 'wrapper_toast_bc'; 19806 var t_spacing = 'mb--15'; 19807 } 19808 19809 19810 // -- 19811 19812 // Toast icon indicator 19813 var t_icon = (t_type != '') ? '<i class="float-start rounded-circle w--15 h--15 mt--3 bg-'+t_type+'"></i>' : ''; 19814 19815 // Autohide in ms 19816 var t_delay_bs = (t_delay > 0) ? ' data-delay="'+t_delay+'" data-autohide="true"' : ' data-autohide="false" '; 19817 19818 // Close Button & Progress 19819 if(t_delay > 0) { 19820 19821 var t_close = ''; 19822 var t_progress = '<div class="mt--n1"><div class="progress h--1 bg-transparent"><div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 100%; background-color: #121212; opacity:0.2"></div></div></div>'; 19823 19824 } else { 19825 19826 var _btnCloseClass = (t_title == '') ? ' fs--10 mt--n1 ' : ''; 19827 var t_close = '<button type="button" class="close float-end'+_btnCloseClass+'" data-dismiss="toast" aria-label="Close"><span class="fi fi-close fs--16" aria-hidden="true"></span></button>'; 19828 var t_progress = ''; 19829 19830 } 19831 19832 19833 // -- 19834 19835 // Create specific main container if not exists (to avoid destroying current toasts) 19836 if(jQuery('#'+_wrapperID).length < 1) 19837 jQuery('body').append('<div id="'+_wrapperID+'" class="w-100 max-w-300 max-h-75vh scrollable-vertical rounded z-index-9999 '+_posClass+'"></div>'); 19838 19839 19840 // -- 19841 19842 19843 // BUILD HTML TOAST 19844 var t_main_class = (t_bg_fill === true && t_type != '') ? 'b--0 bg-'+t_type : 'bg-white'; 19845 var _toastBody = '<div class="toast js-toast '+$.SOW.core.toast.config.animation+' '+t_main_class+' '+t_spacing+'" role="alert" aria-live="polite" aria-atomic="true" '+t_delay_bs+'>'; 19846 19847 // No title 19848 if(t_title != '') { 19849 19850 // remove icon on fill 19851 t_icon = (t_bg_fill === true) ? '' : t_icon; 19852 19853 var t_header_class = (t_bg_fill === true && t_type != '') ? ' bg-transparent overlay-dark overlay-opacity-1 text-white' : ''; 19854 19855 var _toastBody = _toastBody + '<div class="toast-header'+t_header_class+'">' 19856 19857 + '<div class="w-100 text-truncate">' 19858 + t_icon 19859 + '<strong>' + t_title + '</strong>' 19860 + '</div>' 19861 19862 + '<div class="w--180 text-align-end">' 19863 //+ '<small class="d-inline-block pt--6 w--80 text-truncate">11 mins ago</small>' 19864 + t_close 19865 + '</div>' 19866 19867 + '</div>'; 19868 19869 } 19870 19871 // Add close button to body, because we have no title 19872 var _closeBtnBody = (t_title == '') ? t_close : ''; 19873 19874 // Add Color to body text if no title available 19875 if(t_title == '') { 19876 19877 if(t_bg_fill === true && (t_type == 'success-soft' || t_type == 'danger-soft' || t_type == 'info-soft' || t_type == 'warning-soft' || t_type == 'primary-soft' || t_type == 'pink-soft' || t_type == 'indigo-soft')) { 19878 var t_txt_color = ''; 19879 } else { 19880 var t_txt_color = (t_bg_fill === true && t_type != '') ? 'text-white' : 'text-'+t_type; 19881 } 19882 19883 var t_body = '<div class="pt--15 pb--15 '+t_txt_color+'">' + t_body + '</div>'; 19884 19885 } else { 19886 19887 var t_body = (t_bg_fill === true && t_type != '') ? '<div class="pt--5 pb--10 text-white">' + t_body + '</div>' : t_body; 19888 19889 } 19890 19891 var _toastBody = _toastBody + t_progress 19892 + '<div class="toast-body">' + _closeBtnBody + t_body + '</div>' 19893 + '</div>'; 19894 19895 // Prepend 19896 jQuery('#'+_wrapperID).prepend(_toastBody); 19897 19898 // Reinit toast 19899 jQuery('#'+_wrapperID+' .js-toast:not(.hide)').toast('show'); 19900 19901 19902 // -- 19903 19904 19905 // Animate progress bar 19906 if(t_delay > 0) 19907 jQuery('#'+_wrapperID + ' .js-toast:not(.hide):first-child .progress>.progress-bar').filter(':not(:animated)').stop().animate({width:'100%'}, 0).stop().animate({width:'0%'}, t_delay); 19908 19909 19910 // -- 19911 19912 19913 // Cleanup 19914 setTimeout(function () { 19915 19916 jQuery('#'+_wrapperID + ' .js-toast.hide').remove(); 19917 19918 }, t_delay + 1500); 19919 19920 }, 19921 19922 19923 19924 19925 19926 /** 19927 * 19928 * @toast_template 19929 * 19930 19931 Toast on page load, by HTML code 19932 19933 <!-- 19934 19935 Toast On Load 19936 Add anywhere on your HTML page to show toas on load 19937 19938 data-type = '', success, danger, warning, info 19939 data-title = toast title (optional) 19940 data-body = toast body (required) 19941 data-pos = top-left, top-right, bottom-left, bottom-right, top-center, bottom-center 19942 data-delay = autoclose in ms 19943 data-fill = background color fill [true|false] 19944 19945 --> 19946 <div class="hide toast-on-load" 19947 data-type="danger" 19948 data-title="" 19949 data-body="Welcome to Smarty" 19950 data-pos="top-right" 19951 data-delay="4000" 19952 data-fill="true" 19953 ></div> 19954 19955 * 19956 **/ 19957 toast_on_load: function(_this) { 19958 19959 _this.each(function() { 19960 19961 var _t = jQuery(this), 19962 _type = _t.data('toast-type') || '', 19963 _title = _t.data('toast-title') || '', 19964 _body = _t.data('toast-body') || '', 19965 _delay = _t.data('toast-delay') || 0, 19966 _pos = _t.data('toast-pos') || 'top-right', 19967 _fill = _t.data('toast-fill') || true; 19968 19969 // safe correction 19970 _fill = (_fill != true) ? false : true; 19971 19972 // show toast 19973 $.SOW.core.toast.show(_type, _title, _body, _pos, _delay, _fill); 19974 19975 // not needed 19976 // remove to avoid triggering again on ajax loads! 19977 _t.remove(); 19978 19979 }); 19980 19981 }, 19982 19983 19984 19985 /** 19986 * 19987 * @clear 19988 * 19989 **/ 19990 destroy: function() { 19991 19992 jQuery('#wrapper_toast_tr, #wrapper_toast_br, wrapper_toast_tl, #wrapper_toast_bl, #wrapper_toast_tc, #wrapper_toast_bc').remove(); 19993 19994 } 19995 19996 } 19997 19998})(jQuery); 19999/** 20000 * 20001 * [SOW] Dropdown 20002 * 20003 * @author Dorin Grigoras 20004 * www.stepofweb.com 20005 * 20006 * @Dependency - 20007 * @Usage $.SOW.core.dropdown_click_ignore.init('.dropdown-menu.dropdown-click-ignore'); 20008 * 20009 * 20010 **/ 20011;(function ($) { 20012 'use strict'; 20013 20014 20015 /** 20016 * 20017 * @vars 20018 * 20019 * 20020 **/ 20021 var scriptInfo = 'SOW Dropdown Click Ignore'; 20022 20023 20024 $.SOW.core.dropdown_click_ignore = { 20025 20026 20027 /** 20028 * 20029 * @config 20030 * 20031 * 20032 **/ 20033 config: {}, 20034 20035 20036 20037 /** 20038 * 20039 * @collection 20040 * 20041 * 20042 **/ 20043 collection: $(), 20044 20045 20046 20047 /** 20048 * 20049 * @init 20050 * 20051 * 20052 **/ 20053 init: function (selector, config) { 20054 20055 var __selector = $.SOW.helper.__selector(selector); 20056 var __config = $.SOW.helper.check_var(config); 20057 20058 this.selector = __selector[0]; // '#selector' 20059 this.collection = __selector[1]; // $('#selector') 20060 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 20061 20062 // in case the class is changed 20063 if(jQuery(this.selector).length < 1) 20064 return; 20065 20066 20067 // -- * -- 20068 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 20069 // -- * -- 20070 20071 20072 // Stop clicks on empty dropdown links 20073 $.SOW.core.dropdown_click_ignore.stop_dd_empty_link($('.dropdown-menu a')); 20074 20075 20076 // 1. Has no selector 20077 if(!this.selector) { 20078 $.SOW.core.dropdown_click_ignore.process($(".dropdown-menu.dropdown-click-ignore")); 20079 return $(".dropdown-menu.dropdown-click-ignore"); 20080 } 20081 20082 20083 // 2. Has selector 20084 return this.collection.each(function() { 20085 20086 $.SOW.core.dropdown_click_ignore.process($(this)); 20087 20088 }); 20089 20090 20091 }, 20092 20093 20094 20095 /** 20096 * 20097 * @process 20098 * keep a dropdown open on self container click 20099 * 20100 **/ 20101 process: function(_this) { 20102 20103 /* 20104 If any form is present inside dropdown, 20105 the dropdown will not close. 20106 So we skip dropdowns with forms! 20107 20108 Still is an issue on outside form click!!! 20109 */ 20110 if(jQuery('form', _this).length > 0) { 20111 20112 // we try to use the same class inside! 20113 jQuery('.dropdown-click-ignore', _this).on('click', function(e) { 20114 e.stopPropagation(); 20115 }) 20116 20117 return; 20118 } 20119 20120 20121 _this.on('click', function(e) { 20122 e.stopPropagation(); 20123 }); 20124 20125 }, 20126 20127 20128 20129 20130 /** 20131 * 20132 * @stop_dd_empty_link 20133 * Stop clicks on empty dropdown links 20134 * 20135 **/ 20136 stop_dd_empty_link: function(_this) { 20137 20138 _this.not('[data-toggle="collapse"]').on("click", function(e) { 20139 20140 var _t = jQuery(this), 20141 _href = jQuery(this).attr('href') || '#'; 20142 20143 // prevent empty href click 20144 if(_href == '#' && !_t.hasClass('js-ignore')) 20145 e.preventDefault(); 20146 20147 }); 20148 20149 } 20150 20151 }; 20152 20153 20154})(jQuery); 20155/** 20156 * 20157 * [SOW] Dropdown 20158 * 20159 * @author Dorin Grigoras 20160 * www.stepofweb.com 20161 * 20162 * @Dependency $.SOW.core.dropdown_click_ignore 20163 * @Usage $.SOW.core.dropdown.init('.dropdown-menu.dropdown-menu-hover'); 20164 * 20165 * 20166 **/ 20167;(function ($) { 20168 'use strict'; 20169 20170 20171 /** 20172 * 20173 * @vars 20174 * 20175 * 20176 **/ 20177 var scriptInfo = 'SOW Dropdown'; 20178 20179 20180 $.SOW.core.dropdown = { 20181 20182 20183 /** 20184 * 20185 * @config 20186 * 20187 * 20188 **/ 20189 config: {}, 20190 20191 20192 20193 /** 20194 * 20195 * @collection 20196 * 20197 * 20198 **/ 20199 collection: $(), 20200 20201 20202 20203 /** 20204 * 20205 * @init 20206 * 20207 * 20208 **/ 20209 init: function (selector, config) { 20210 20211 var __selector = $.SOW.helper.__selector(selector); 20212 var __config = $.SOW.helper.check_var(config); 20213 20214 this.selector = __selector[0]; // '#selector' 20215 this.collection = __selector[1]; // $('#selector') 20216 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 20217 20218 20219 // Update text on click 20220 $.SOW.core.dropdown.onClickUpdateText(); 20221 20222 20223 if(jQuery(this.selector).length < 1) 20224 return; 20225 20226 20227 // Dependency Check 20228 if(typeof $.SOW.core.dropdown_click_ignore !== 'object') 20229 $.SOW.helper.consoleLog('[sow.dropdown] Missing [sow.dropdown_click_ignore]'); 20230 20231 20232 // -- * -- 20233 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 20234 // -- * -- 20235 20236 20237 $.SOW.core.dropdown.process(this.collection); 20238 return this.collection; 20239 20240 }, 20241 20242 20243 20244 /** 20245 * 20246 * @process 20247 20248 @Fix|Hack 20249 MULTILEVEL DROPDOWN ON MOBILE 20250 20251 Issue: nested|multi level dropdowns are not supported in Bootstrap v3+ 20252 20253 So the issue is: we cannot use $().dropdown('hide|show|toggle') from documentation 20254 Bootstrap was developed for a single level, not multilevel. 20255 So we have to hack it somehow to allow multilevel, especially on mobile. 20256 20257 Ugly but a necesity! 99% better than developing a new mega menu from scratch! 20258 20259 20260 NOTE: we ignore dropdowns without .dropdown-menu-hover 20261 Are working on click 20262 20263 * 20264 **/ 20265 process: function(_this) { 20266 20267 _this.parent().find('.dropdown>a[data-toggle="dropdown"]').on('click', function(e) { 20268 20269 var _t = jQuery(this); 20270 this.collection = _t; 20271 20272 /* 20273 20274 Mobile devices only! 20275 20276 */ 20277 if($.SOW.globals.is_mobile === true) { 20278 20279 if(!_t.parent('.dropdown').hasClass('show')) { 20280 20281 // first click : open 20282 $.SOW.core.dropdown.__ddBSControl(_t, 'show'); 20283 20284 // now close all other open parent dropdowns 20285 _t.parent('.dropdown').parent().find('.dropdown.show>a[data-toggle="dropdown"]').not(this).each(function() { 20286 $.SOW.core.dropdown.__ddBSControl(jQuery(this), 'hide'); 20287 }); 20288 20289 } else { 20290 20291 // second click : close 20292 $.SOW.core.dropdown.__ddBSControl(_t, 'hide'); 20293 20294 // now close all childs, if any 20295 _t.parent('.dropdown').find('.dropdown-menu .dropdown>a[data-toggle="dropdown"]').each(function(e) { 20296 $.SOW.core.dropdown.__ddBSControl(jQuery(this), 'hide'); 20297 }); 20298 20299 } 20300 20301 // Stop here, block bootstrap to run its dropdowns stuff 20302 e.stopPropagation(); 20303 20304 } 20305 20306 }); 20307 20308 }, 20309 20310 20311 20312 /** 20313 * 20314 * @__ddBSControl 20315 * :: Helper 20316 * 20317 **/ 20318 __ddBSControl: function(_t, status) { 20319 20320 if(status == 'show') { 20321 20322 _t.attr('aria-expanded','true').parent('.dropdown').addClass('show'); 20323 _t.next('.dropdown-menu').addClass('show'); 20324 20325 } else { 20326 20327 _t.attr('aria-expanded','false').parent('.dropdown').removeClass('show'); 20328 _t.next('.dropdown-menu').removeClass('show'); 20329 20330 20331 } 20332 20333 }, 20334 20335 20336 20337 20338 20339 20340 /** 20341 * 20342 * @onClickUpdateText 20343 * 20344 * 20345 **/ 20346 onClickUpdateText: function() { 20347 20348 jQuery('.dropdown-menu-click-update a.dropdown-item, .dropdown-menu-click-update a.dropdown-link').not('.js-dropdown-triggerified').addClass('js-dropdown-triggerified').on('click', function(e) { 20349 20350 var _t = jQuery(this); 20351 20352 var dropdownContainer = _t.parents('.dropdown-menu-click-update'); 20353 jQuery('a.dropdown-item, a.dropdown-link', dropdownContainer).removeClass('active'); 20354 _t.addClass('active'); 20355 20356 20357 // find button trigger & update text 20358 var dropdownBtnTrigger = dropdownContainer.parent().find('[data-toggle="dropdown"]'); 20359 if(dropdownBtnTrigger) { 20360 var dropdownBtnTextToUpdate = jQuery('.js-trigger-text', _t).text(); 20361 if(dropdownBtnTextToUpdate) 20362 jQuery('.js-trigger-text', dropdownBtnTrigger).text(dropdownBtnTextToUpdate); 20363 } 20364 20365 20366 20367 setTimeout(function() { 20368 20369 // Close dropdown on link click 20370 // if no .dropdown-click-ignore is present 20371 if(!dropdownContainer.hasClass('dropdown-click-ignore') && dropdownContainer.hasClass('show')) 20372 dropdownContainer.dropdown('hide'); 20373 20374 // Callback 20375 var callBack = dropdownContainer.attr('data-dropdown-callback') || ''; 20376 if(callBack != '') { 20377 if(typeof window[callBack] === 'function') 20378 window[callBack](_t.attr('href')); 20379 } 20380 20381 }, 0); 20382 20383 e.preventDefault(); 20384 20385 }); 20386 20387 return true; 20388 } 20389 20390 }; 20391 20392 20393})(jQuery); 20394/** 20395 * 20396 * [SOW] Dropdown Ajax 20397 * 20398 * @author Dorin Grigoras 20399 * www.stepofweb.com 20400 * 20401 * @Dependency $.SOW.core.dropdown_click_ignore 20402 * $.SOW.core.dropdown 20403 * @Usage $.SOW.core.dropdown_ajax.init('a[data-toggle="dropdown"]'); 20404 * 20405 * 20406 **/ 20407;(function ($) { 20408 'use strict'; 20409 20410 20411 /** 20412 * 20413 * @vars 20414 * 20415 * 20416 **/ 20417 var scriptInfo = 'SOW Dropdown Ajax'; 20418 var ddTimeKepper = {}; 20419 20420 20421 $.SOW.core.dropdown_ajax = { 20422 20423 20424 /** 20425 * 20426 * @config 20427 * 20428 * 20429 **/ 20430 config: { 20431 20432 // general 20433 loading_icon: 'fi fi-circle-spin fi-spin', 20434 clearCacheInterval: 1000 * 60, // 1 min 20435 20436 20437 // json only : dropdown strating|ending tags 20438 tpl_start: '<ul class="list-unstyled m-0 p-0">', 20439 tpl_end: '</ul>', 20440 20441 tpl_ItemStart: '<li class="dropdown-item">', 20442 tpl_ItemStartWChilds: '<li class="dropdown-item dropdown">', 20443 tpl_ItemEnd: '</li>', 20444 20445 tpl_Child_Start: '<ul class="dropdown-menu dropdown-menu-hover dropdown-menu-block-md shadow-lg b-0 m-0">', 20446 tpl_Divider: '<li class="dropdown-divider"></li>', 20447 20448 }, 20449 20450 20451 20452 /** 20453 * 20454 * @collection 20455 * 20456 * 20457 **/ 20458 collection: $(), 20459 20460 20461 20462 /** 20463 * 20464 * @init 20465 * 20466 * 20467 **/ 20468 init: function (selector, config) { 20469 20470 var __selector = $.SOW.helper.__selector(selector); 20471 var __config = $.SOW.helper.check_var(config); 20472 20473 this.selector = __selector[0]; // '#selector' 20474 this.collection = __selector[1]; // $('#selector') 20475 this.selector_orig = __selector[2]; // $('#selector') // without ajax container prefix 20476 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 20477 20478 20479 if(jQuery(this.selector).length < 1) 20480 return; 20481 20482 20483 // -- * -- 20484 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 20485 // -- * -- 20486 20487 20488 $.SOW.core.dropdown_ajax.process(this.collection); 20489 return this.collection; 20490 20491 }, 20492 20493 20494 20495 /** 20496 * 20497 * @process 20498 * 20499 **/ 20500 process: function(_this) { 20501 20502 // Required 20503 if(_this.data('dropdown-ajax
20503-source') == '') 20504 return; 20505 20506 20507 // Initial Setup 20508 if($.SOW.globals.is_mobile === true) { 20509 20510 var jQ_actions = 'click'; 20511 20512 } else { 20513 20514 var jQ_actions = 'click mouseover'; 20515 20516 // Hover only, remove click 20517 if(_this.next().closest('.dropdown-menu').hasClass('dropdown-menu-hover')) 20518 var jQ_actions = 'mouseover'; 20519 20520 } 20521 20522 20523 // Repopulate dropdowns from cache, if exists 20524 $.SOW.core.dropdown_ajax.repopulateFromCache(); 20525 20526 20527 // mouse over|click 20528 _this.on(jQ_actions, function(e) { 20529 20530 var _t = jQuery(this), 20531 _source = _t.data('dropdown-ajax-source') || '', 20532 _mode = _t.data('dropdown-ajax-mode') || 'html', // html|json 20533 _clearCacheInterval = _t.data('dropdown-ajax-refresh-interval') || $.SOW.core.dropdown_ajax.config.clearCacheInterval, 20534 _reloadAlways = _t.data('dropdown-ajax-reload-always') || false, 20535 _loadIcon = _t.data('dropdown-ajax-loadicon') || $.SOW.core.dropdown_ajax.config.loading_icon, 20536 _container = _t.next().closest('.dropdown-menu') || '', 20537 _useCache = _t.attr('data-dropdown-ajax-cache') || 'false', 20538 _containerID = _container.attr('id') || '', 20539 _method = _t.data('dropdown-ajax-method') || 'GET', 20540 _contentType = _t.data('dropdown-ajax-contentType') || '', 20541 _dataType = _t.data('dropdown-ajax-dataType') || ''; 20542 20543 20544 if(_source == '' || _container == '') 20545 return; 20546 20547 20548 // Add an ID to dropdown container if empty 20549 if(_containerID == '') { 20550 var _containerID = 'rand_' + $.SOW.helper.randomStr(8); 20551 _container.attr('id', _containerID); 20552 } 20553 20554 20555 // Cached? Check expired 20556 if(_useCache+'' == 'true' && _t.hasClass('js-cached')) { 20557 var $continue = $.SOW.core.dropdown_ajax.validateCache(_source); 20558 if($continue === false) 20559 return; 20560 } 20561 20562 20563 /* 20564 force : overwrite 20565 do not reload data on mouse over 20566 */ 20567 if(jQ_actions == 'mouseover' && $.SOW.globals.is_mobile === false) 20568 _reloadAlways = false; 20569 20570 20571 // Refresh Interval! 20572 if(_reloadAlways == false && _clearCacheInterval > 0) 20573 $.SOW.core.dropdown_ajax.process_clearCacheInterval(_t, _containerID, _clearCacheInterval); 20574 20575 20576 // Content already successfully loaded and reload on each click|show is disabled 20577 if(_reloadAlways == false && _t.hasClass('js-dropdownified')) 20578 return; 20579 20580 20581 // set initialized 20582 _container.addClass('js-dropdownified'); 20583 20584 20585 // Ajax 20586 jQuery.ajax({ 20587 url: _source, 20588 data: (_mode === 'json') ? {} : {ajax:"true"}, 20589 type: _method, 20590 contentType: _contentType || 'application/x-www-form-urlencoded; charset=UTF-8', 20591 dataType: _dataType || null, 20592 headers: '', 20593 crossDomain: '', 20594 20595 beforeSend: function() { 20596 20597 _container.html('<div class="js-dd-ajax-loader text-center rounded p-3"><i class="' + _loadIcon + ' h5 text-gray-400"></i></div>'); 20598 20599 }, 20600 20601 error: function(XMLHttpRequest, textStatus, errorThrown) { 20602 20603 if(typeof $.SOW.core.toast === 'object') { 20604 20605 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 20606 20607 } else { 20608 20609 // alert("[404] Unexpected internal error!"); 20610 20611 } 20612 20613 // if debug enabled, see config 20614 if($.SOW.config.sow__debug_enable === true) { // optional, just to skip so many callings 20615 $.SOW.helper.consoleLog('----------------------------'); 20616 $.SOW.helper.consoleLog('--- AJAX DROPDOWN ERROR ---'); 20617 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 20618 $.SOW.helper.consoleLog(XMLHttpRequest); 20619 $.SOW.helper.consoleLog('2. textStatus:'); 20620 $.SOW.helper.consoleLog(textStatus); 20621 $.SOW.helper.consoleLog('3. errorThrown:'); 20622 $.SOW.helper.consoleLog(errorThrown); 20623 $.SOW.helper.consoleLog('----------------------------'); 20624 } 20625 20626 }, 20627 20628 success: function(data) { 20629 20630 _t.addClass('js-dropdownified'); 20631 20632 /* json */ 20633 if(_mode === 'json') 20634 var data = $.SOW.core.dropdown_ajax.process_json(data); 20635 20636 // push data 20637 _container.html(data); 20638 20639 20640 // Add to cache 20641 if(_useCache+'' == 'true') 20642 $.SOW.core.dropdown_ajax.addToCache(_source, data); 20643 20644 20645 /* 20646 Reinits [mobile required] 20647 */ 20648 // SOW :: Dropdown 20649 if(typeof $.SOW.core.dropdown === 'object') 20650 $.SOW.core.dropdown.process(_container); 20651 20652 // SOW :: Dropdown Click Ignore 20653 if(typeof $.SOW.core.dropdown_click_ignore === 'object') { 20654 var _containerLinks = $('a', _container); 20655 $.SOW.core.dropdown_click_ignore.stop_dd_empty_link(_containerLinks); 20656 } 20657 20658 // SOW :: Ajax Navigation 20659 if(typeof $.SOW.core.ajax_navigation === 'object')
20660 $.SOW.core.ajax_navigation.__initFor('#' + _containerID); 20661 20662 20663 // -- * -- 20664 $.SOW.helper.consoleLog('[#'+_containerID+'] Dropdown Ajax Content Loaded! ' + _source, 'color: #999999;'); 20665 // -- * -- 20666 20667 20668 // Reinit Plugins : HTML only 20669 if(_mode == 'html') { 20670 var _target = '#'+_containerID; 20671 20672 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20673 // reinit inside ajax container 20674 if($.SOW.config.sow__debug_enable === true) { // just to avoid always calling the helper 20675 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 20676 $.SOW.helper.consoleLog(scriptInfo, 'color: #6dbb30; font-weight: bold; font-size:14px;'); 20677 $.SOW.helper.consoleLog('Ajax Reinit For: ' + _target); 20678 $.SOW.helper.consoleLog(window.location.href); 20679 $.SOW.helper.consoleLog('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); 20680 } 20681 20682 $.SOW.reinit(_target); 20683 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20684 20685 } 20686 20687 } 20688 20689 }); 20690 20691 }); 20692 20693 }, 20694 20695 20696 20697 20698 /** 20699 * 20700 * @process_json 20701 * 20702 * 20703 * 20704 **/ 20705 process_json: function(data) { 20706 20707 try { 20708 20709 var _data = JSON.parse(data); 20710 20711 } catch(err) { 20712 20713 var _data = data; 20714 20715 } 20716 20717 /* --------------------------------- */ 20718 var _tpl = ''; 20719 _tpl += $.SOW.core.dropdown_ajax.config.tpl_start; 20720 _tpl += $.SOW.core.dropdown_ajax.process_json_build_tree(_data); 20721 _tpl += $.SOW.core.dropdown_ajax.config.tpl_end; 20722 /* --------------------------------- */ 20723 20724 20725 return _tpl; 20726 20727 }, 20728 20729 20730 20731 20732 /** 20733 * 20734 * @process_json_build_tree 20735 * Recursive 20736 * 20737 * 20738 **/ 20739 process_json_build_tree: function(data) { 20740 20741 var _tpl = ''; 20742 20743 if(typeof data === 'undefined') 20744 return _tpl; 20745 20746 for (var i = 0; i < data.length; i++) { 20747 20748 /* 0. Divider -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20749 if(typeof data[i].divider !== 'undefined' && data[i].divider === true) { 20750 _tpl += $.SOW.core.dropdown_ajax.config.tpl_Divider; 20751 continue; 20752 } 20753 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20754 20755 20756 /* 1. Text -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20757 else if(typeof data[i].text !== 'undefined' && data[i].text.length > 0) { 20758 _tpl += $.SOW.core.dropdown_ajax.config.tpl_ItemStart + data[i].text + $.SOW.core.dropdown_ajax.config.tpl_ItemEnd; 20759 continue; 20760 } 20761 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20762 20763 20764 20765 var has_childs = (typeof data[i].childs !== 'undefined' && data[i].childs.length > 0) ? true : false; 20766 20767 20768 /* 2. tpl start <li> -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20769 _tpl += (has_childs === true) ? $.SOW.core.dropdown_ajax.config.tpl_ItemStartWChilds : $.SOW.core.dropdown_ajax.config.tpl_ItemStart; 20770 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20771 20772 20773 20774 /* 3. add link -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20775 var _childsTag = (has_childs === true) ? ' data-toggle="dropdown"' : ''; 20776 20777 var _class = (typeof data[i].class !== 'undefined' && data[i].class != '') ? ' ' + data[i].class : ''; 20778 _class += (typeof data[i].active !== 'undefined' && data[i].active == true) ? ' active' : ''; 20779 _class += (typeof data[i].disabled !== 'undefined' && data[i].disabled == true) ? ' disabled' : ''; 20780 20781 var _icon = (typeof data[i].icon !== 'undefined' && data[i].icon != '') ? '<i class="'+data[i].icon+'"></i>' : ''; 20782 var _target = (typeof data[i].target !== 'undefined' && data[i].target != '') ? ' target="'+data[i].target+'"' : ''; 20783 20784 _tpl += '<a href="'+data[i].url+'" class="dropdown-link' + _class + '"' + _childsTag + _target+'>' + _icon + data[i].label + '</a>'; 20785 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20786 20787 20788 20789 /* 4. recursive childs -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20790 if(has_childs === true) { 20791 _tpl += $.SOW.core.dropdown_ajax.config.tpl_Child_Start; 20792 _tpl += $.SOW.core.dropdown_ajax.process_json_build_tree(data[i].childs); 20793 _tpl += $.SOW.core.dropdown_ajax.config.tpl_end; 20794 } 20795 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20796 20797 20798 20799 /* 5. tpl end </li> -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20800 _tpl += $.SOW.core.dropdown_ajax.config.tpl_ItemEnd; 20801 /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- */ 20802 20803 } 20804 20805 20806 /* return final tpl */ 20807 return _tpl; 20808 }, 20809 20810 20811 20812 20813 /** 20814 * 20815 * @process_clearCacheInterval 20816 * 20817 * 20818 * 20819 **/ 20820 process_clearCacheInterval: function(_t, _containerID, _clearCacheInterval) { 20821 20822 var timestampNow = new Date().getTime(); 20823 20824 // First click/hover 20825 // Refresh : Cache Added! 20826 if(typeof ddTimeKepper[_containerID] === 'undefined') 20827 ddTimeKepper[_containerID] = timestampNow; 20828 20829 // Cache Refreshed & Content Reloaded 20830 else if((timestampNow - ddTimeKepper[_containerID]) > _clearCacheInterval) { 20831 ddTimeKepper[_containerID] = timestampNow; 20832 _t.removeClass('js-dropdownified'); 20833 } 20834 20835 }, 20836 20837 20838 20839 20840 20841 20842 20843 /** 20844 * 20845 * @addToCache 20846 * 20847 **/ 20848 addToCache: function(_URL, data) { 20849 20850 // Skip 20851 if(jQuery('body[data-dropdown-ajax-cache-ignore="true"]').length > 0) {
20852 localStorage.removeItem('cachedDropdowns'); 20853 return; 20854 } 20855 20856 // Get from cache! 20857 var cachedDropdowns = localStorage.getItem("cachedDropdowns"); 20858 var cachedDropdownsArr = (cachedDropdowns) ? JSON.parse(cachedDropdowns) : {}; 20859 20860 // create a hash from URL 20861 var hash = $.SOW.helper.strhash(_URL); 20862 var timestampNow = new Date().getTime(); 20863 20864 cachedDropdownsArr[hash] = { url:_URL, html:data, timestamp:timestampNow } 20865 localStorage.setItem("cachedDropdowns", JSON.stringify(cachedDropdownsArr)); 20866 20867 return true; 20868 20869 }, 20870 20871 20872 20873 /** 20874 * 20875 * @repopulateFromCache 20876 * 20877 **/ 20878 repopulateFromCache: function() { 20879 20880 // Skip 20881 if(jQuery('body[data-dropdown-ajax-cache-ignore="true"]').length > 0) 20882 return; 20883 20884 // Get from cache! 20885 var cachedDropdowns = localStorage.getItem("cachedDropdowns"); 20886 if(!cachedDropdowns) 20887 return false; 20888 20889 // Array conversion 20890 var cachedDropdownsArr = JSON.parse(cachedDropdowns); 20891 for(var key in cachedDropdownsArr) { 20892 jQuery('[data-dropdown-ajax-source="'+cachedDropdownsArr[key]['url']+'"]').addClass('js-cached').next().closest('.dropdown-menu').html(cachedDropdownsArr[key]['html']); 20893 } 20894 20895 return true; 20896 }, 20897 20898 20899 20900 20901 20902 20903 /** 20904 * 20905 * @validateCache 20906 * 20907 **/ 20908 validateCache: function(_URL) { 20909 20910 // Get from cache! 20911 var cachedDropdowns = localStorage.getItem("cachedDropdowns"); 20912 if(!cachedDropdowns) 20913 return true; // true = continue 20914 20915 // Parse cache & create hash from url 20916 var cachedDropdownsArr = JSON.parse(cachedDropdowns); 20917 var hash = $.SOW.helper.strhash(_URL); 20918 20919 // Cache Refreshed & Content Reloaded 20920 var timestampNow = new Date().getTime(); 20921 if((timestampNow - cachedDropdownsArr[hash]['timestamp']) > 60*30) { 20922 cachedDropdownsArr[hash] = {}; 20923 delete cachedDropdownsArr[hash]; 20924 20925 // reset 20926 localStorage.setItem("cachedDropdowns", JSON.stringify(cachedDropdownsArr)); 20927 return true; // true = continue 20928 20929 } 20930 20931 return false; // false = stop, cache is valid! 20932 20933 }, 20934 20935 20936 20937 20938 20939 }; 20940 20941 20942})(jQuery); 20943/** 20944 * 20945 * [SOW] Count Animate 20946 * 20947 * @author Dorin Grigoras 20948 * www.stepofweb.com 20949 * 20950 * @Dependency - 20951 * @Usage $.SOW.core.count_animate.init() 20952 * @Ajax Support YES 20953 * 20954 * 20955 **/ 20956;(function ($) { 20957 'use strict'; 20958 20959 20960 /** 20961 * 20962 * @vars 20963 * 20964 * 20965 **/ 20966 var scriptInfo = 'SOW Count Animate'; 20967 window.sowCountInterval = null; 20968 window.sowCountBtnList = {}; 20969 // window.startScrollPos = 0; 20970 20971 20972 $.SOW.core.count_animate = { 20973 20974 20975 20976 /** 20977 * 20978 * @config 20979 * 20980 * 20981 **/ 20982 config: { 20983 count_duration : 1500, 20984 easing : 'easeInOutExpo', // easeOutExpo, easeInOutExpo, linear, swing 20985 }, 20986 20987 20988 20989 /** 20990 * 20991 * @collection 20992 * 20993 * 20994 **/ 20995 collection: $(), 20996 20997 20998 20999 /** 21000 * 21001 * @init 21002 * 21003 * 21004 **/ 21005 init: function (selector, config) { 21006 21007 var el_selector = '[data-toggle=count]'; 21008 var btn_selector = '[data-count-target]'; 21009 21010 var __config = $.SOW.helper.check_var(config); 21011 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 21012 21013 21014 // init button 21015 $.SOW.core.count_animate.btn_process(el_selector, btn_selector); 21016 // -- 21017 21018 21019 if($(el_selector).length < 1) { 21020 21021 // stop everything 21022 if(window.sowCountInterval !== null) { 21023 clearInterval(window.sowCountInterval); 21024 window.sowCountInterval = null; 21025 $(el_selector).stop(true, true); // stop all animations 21026 } 21027 21028 return; 21029 } 21030 21031 21032 // -- * -- 21033 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 21034 // -- * -- 21035 21036 21037 // On Load 21038 // window.startScrollPos = jQuery(window).scrollTop() || 0; // used on scroll up 21039 $.SOW.core.count_animate.process($(el_selector)); 21040 21041 21042 21043 var scrolling = false; 21044 $(window).scroll(function() { 21045 scrolling = true; 21046 }); 21047 21048 window.sowCountInterval = setInterval( function() { 21049 21050 if(scrolling) { 21051 scrolling = false; 21052 $.SOW.core.count_animate.process($(el_selector)); 21053 } 21054 21055 }, 250); 21056 21057 21058 // it's always cool to return something that nobody will ever need :) 21059 return $(el_selector); 21060 21061 }, 21062 21063 21064 21065 21066 21067 /** 21068 * 21069 * @process 21070 * 21071 * 21072 **/ 21073 process: function(_this) { 21074 21075 // custom easing 21076 $.SOW.core.count_animate.custom_easing(); 21077 21078 var topPos = jQuery(window).scrollTop() || 0;
21079 var scrollPos = ($.SOW.globals.height || 0) + topPos; 21080 21081 _this.not('.js-count-completed').each(function(e) { 21082 21083 var _t = jQuery(this), 21084 _offset = _t.offset(), 21085 elOffsetTop = _offset.top || 0; 21086 21087 21088 /** 21089 21090 Known issue: refresh when scroll is on middle 21091 21092 // on scroll up (from refresh) 21093 var elOffsetTop2 = elOffsetTop + $.SOW.globals.height; 21094 if(window.startScrollPos > $.SOW.globals.height && scrollPos < elOffsetTop2) 21095 $.SOW.core.count_animate.animate(_t); 21096 21097 // on scroll down 21098 else if (window.startScrollPos < $.SOW.globals.height && scrollPos > elOffsetTop) 21099 $.SOW.core.count_animate.animate(_t); 21100 21101 **/ 21102 21103 /* on scroll down only */ 21104 if (scrollPos > elOffsetTop) 21105 $.SOW.core.count_animate.animate(_t); 21106 21107 }); 21108 21109 }, 21110 21111 21112 21113 21114 /** 21115 * 21116 * @animate 21117 * 21118 * 21119 **/ 21120 animate: function(_t) { 21121 21122 var count_from = _t.attr('data-count-from') || 0, 21123 count_to = _t.attr('data-count-to') || 0, 21124 count_duration = _t.attr('data-count-duration') || $.SOW.core.count_animate.count_duration, 21125 count_display = _t.attr('data-count-display') || false, 21126 callback = _t.data('count-callback') || '', 21127 count_decimals = _t.data('count-decimals') || '', 21128 oncomplete = _t.data('count-oncomplete') || ''; 21129 21130 if(count_from == count_to) 21131 return; 21132 21133 // https://api.jquery.com/animate/ 21134 jQuery({sowCount:count_from}).animate({sowCount:count_to}, { 21135 21136 duration: Number(count_duration), 21137 easing: $.SOW.core.count_animate.easing, //'linear', 'swing' 21138 queue: true, 21139 21140 step: function(curr) { 21141 21142 21143 21144 var numRes = count_to.substr(0, count_to.indexOf('.')), 21145 _val = (numRes) ? parseFloat(curr).toFixed(2) : Math.floor(curr); 21146 21147 if(count_decimals) 21148 var _val = parseFloat(_val).toFixed(count_decimals); 21149 21150 if(count_display === 'currency') 21151 var _val = $.SOW.helper.currencyFormat( parseFloat(_val) ); 21152 21153 _t.text(_val); 21154 }, 21155 21156 start: function() { 21157 21158 _t.addClass('js-count-completed'); 21159 21160 }, 21161 21162 complete: function() { 21163 21164 if(callback != '' && typeof $.SOW.helper.executeFunctionByName === "function") 21165 $.SOW.helper.executeFunctionByName(callback, window, _t); 21166 21167 21168 if(typeof oncomplete === 'object') { 21169 21170 if(oncomplete.target) { 21171 21172 if(oncomplete.action.toLowerCase() == 'show') 21173 jQuery(oncomplete.target).removeClass('hide hide-force'); 21174 21175 else if(oncomplete.action.toLowerCase() == 'hide') 21176 jQuery(oncomplete.target).addClass('hide hide-force'); 21177 21178 if(oncomplete.class) 21179 jQuery(oncomplete.target).addClass(oncomplete.class); 21180 21181 } 21182 } 21183 21184 }, 21185 21186 done: function(_e) { 21187 _e.stop(true, true); 21188 } 21189 21190 }); 21191 21192 }, 21193 21194 21195 21196 21197 21198 /** 21199 * 21200 * @btn_process 21201 * 21202 * 21203 **/ 21204 btn_process: function(el_selector, btn_selector) { 21205 21206 if(jQuery(btn_selector).length < 1) 21207 return; 21208 21209 // custom easing 21210 $.SOW.core.count_animate.custom_easing(); 21211 21212 // reset for each page (ajax required) 21213 window.sowCountBtnList = {}; 21214 21215 jQuery(btn_selector).each(function() { 21216 21217 var _thisBtn = jQuery(this), 21218 _action = (_thisBtn.is('a') || _thisBtn.is('button')) ? 'click' : 'change'; 21219 21220 _thisBtn.on(_action, function(e) { 21221 21222 var _t = jQuery(this), 21223 _href = _t.attr('href') || null, 21224 _target = _t.data('count-target') || null, 21225 _math = _t.data('count-math') || null; 21226 21227 if(!_target) return; 21228 if(_href) e.preventDefault(); // links only! 21229 jQuery(_target).stop(true, true); // stop any animation 21230 _t.toggleClass('active'); // mark active 21231 21232 21233 21234 // :: MATH 21235 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 21236 $.SOW.core.count_animate.btn_process_math(_t); 21237 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 21238 21239 21240 21241 // :: TOGGLE 21242 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 21243 $.SOW.core.count_animate.btn_process_toggle(_target); 21244 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 21245 21246 21247 }); 21248 21249 21250 }); 21251 21252 }, 21253 21254 21255 21256 21257 21258 /** 21259 * 21260 * @btn_process_math 21261 * 21262 * 21263 **/ 21264 btn_process_math: function(_t) { 21265 21266 var _target = _t.data('count-target') || '', 21267 _tMth = jQuery(_target), 21268 _math = _t.data('count-math') || '0', 21269 _math = Number(_math), 21270 is_select = _t.is('select'), 21271 el_type = _t.attr('type'); // radio|checkbox 21272 21273 21274 // Select 21275 if(is_select) { 21276 21277 var _val = _t.find(':selected').data('count-math') || 0 21278 _lastCalc = _tMth.attr('data-count-to') || 0, 21279 _calculate = _val; 21280 21281 // Checkbox, Radio, etc 21282 } else { 21283 21284 if(_math < 1) 21285 return; 21286 21287 var _lastCalc = _tMth.attr('data-count-last-math') || 0,
21288 _lastCalc = Number(_lastCalc), // last calculation 21289 _baseVal = _tMth.attr('data-count-base-to') || '', 21290 _currVal = _tMth.attr('data-count-to') || 0, 21291 _currVal = Number(_currVal); 21292 21293 if(_baseVal == '') { 21294 var _baseVal = _currVal, 21295 _lastCalc = _currVal; 21296 _tMth.attr('data-count-base-to', _currVal); 21297 } 21298 21299 if(el_type == 'radio') 21300 var _calculate = (_t.hasClass('active') || _t.is(':checked')) ? Number(_baseVal) + _math : Number(_lastCalc) - _math; 21301 21302 21303 else // invert the math because 'active' class is toggled before 21304 var _calculate = (_t.hasClass('active') || _t.is(':checked')) ? Number(_lastCalc) + _math : Number(_lastCalc) - _math; 21305 21306 } 21307 21308 _tMth.attr('data-toggle', 'count'); // just in case! 21309 _tMth.attr('data-count-last-math', _calculate); 21310 _tMth.attr('data-count-from', _lastCalc); 21311 _tMth.attr('data-count-to', _calculate); 21312 $.SOW.core.count_animate.animate(_tMth); 21313 21314 }, 21315 21316 21317 21318 21319 21320 /** 21321 * 21322 * @btn_process_toggle 21323 * 21324 * 21325 **/ 21326 btn_process_toggle: function(_target) { 21327 21328 jQuery(_target).each(function(e) { 21329 21330 var _el = jQuery(this), 21331 _json = _el.data('count-toggle') || '', 21332 _elID = _el.attr('id') || ''; 21333 21334 if(_elID == '') { 21335 _elID = 'rand_' + $.SOW.helper.randomStr(3); 21336 _el.attr('id', _elID); 21337 } 21338 21339 if(typeof _json === 'object') { 21340 21341 // in case a button is used to toggle only one value (from-to) 21342 if(!_json[1]) 21343 _json[1] = {"from":_json[0]['to'], "to":_json[0]['from'], "duration":_json[0]['duration']}; 21344 21345 21346 if(window.sowCountBtnList[_elID] === 1) { 21347 21348 _el.attr('data-toggle', 'count'); 21349 _el.attr('data-count-from', (_json[1]['from'] != '0') ? _json[1]['to'] : _json[0]['from'] ); 21350 _el.attr('data-count-to', _json[0]['to']); 21351 _el.attr('data-count-duration', _json[0]['duration']); 21352 21353 window.sowCountBtnList[_elID] = 0; 21354 21355 } else { 21356 21357 _el.attr('data-toggle', 'count'); 21358 _el.attr('data-count-from', _json[1]['from']); 21359 _el.attr('data-count-to', _json[1]['to']); 21360 _el.attr('data-count-duration', _json[1]['duration']); 21361 21362 window.sowCountBtnList[_elID] = 1; 21363 } 21364 21365 $.SOW.core.count_animate.animate(_el); 21366 21367 } 21368 21369 }); 21370 21371 }, 21372 21373 21374 21375 21376 21377 /** 21378 * 21379 * @custom_easing 21380 * 21381 * 21382 **/ 21383 custom_easing: function() { 21384 21385 $.extend($.easing, { 21386 easeInOutExpo: function (x, t, b, c, d) { 21387 if (t==0) return b; 21388 if (t==d) return b+c; 21389 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 21390 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 21391 }, 21392 easeOutExpo: function (x, t, b, c, d) { 21393 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 21394 }, 21395 }); 21396 21397 } 21398 }; 21399 21400 21401})(jQuery); 21402/** 21403 * 21404 * [SOW] Btn Toggle 21405 * 21406 * @author Dorin Grigoras 21407 * www.stepofweb.com 21408 * 21409 * @Dependency - 21410 * @Usage $.SOW.core.btn_toggle.init('.btn-toggle'); 21411 * 21412 * 21413 **/ 21414;(function ($) { 21415 'use strict'; 21416 21417 21418 /** 21419 * 21420 * @vars 21421 * 21422 * 21423 **/ 21424 var scriptInfo = 'SOW Btn Toggle'; 21425 21426 21427 $.SOW.core.btn_toggle = { 21428 21429 21430 /** 21431 * 21432 * @config 21433 * 21434 * 21435 **/ 21436 config: { 21437 method : 'GET', 21438 contentType : '', // jQuery params 21439 dataType : '', // jQuery params 21440 headers : '', // jQuery params 21441 crossDomain : '', // jQuery params 21442 data_params : {ajax:'true'}, 21443 }, 21444 21445 21446 21447 /** 21448 * 21449 * @collection 21450 * 21451 * 21452 **/ 21453 collection: $(), 21454 21455 21456 21457 /** 21458 * 21459 * @init 21460 * 21461 * 21462 **/ 21463 init: function (selector, config) { 21464 21465 var __selector = $.SOW.helper.__selector(selector); 21466 var __config = $.SOW.helper.check_var(config); 21467 21468 this.selector = __selector[0]; // '#selector' 21469 this.collection = __selector[1]; // $('#selector') 21470 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 21471 21472 21473 if(jQuery(this.selector).length < 1) 21474 return; 21475 21476 21477 // -- * -- 21478 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 21479 // -- * -- 21480 21481 21482 // 1. Has no selector 21483 if(!this.selector) { 21484 $.SOW.core.btn_toggle.process($('.btn-toggle')); 21485 return this.collection; 21486 } 21487 21488 // 2. Has selector 21489 return this.collection.each(function() { 21490 21491 $.SOW.core.btn_toggle.process($(this)); 21492 21493 }); 21494 21495 }, 21496 21497 21498 21499 /** 21500 * 21501 * @process 21502 * 21503 21504 <!-- toggle --> 21505 <button class="btn btn-secondary btn-toggle btn-icon btn-circle" data-toggle="popover" data-placement="left" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?"> 21506 <span class="group-icon"> 21507 <i class="mdi mdi-help-circle-outline"></i> 21508 <i class="mdi mdi-close"></i> 21509 </span> 21510 </button> 21511 21512 <!-- Toggle fullscreen container --> 21513 <a href="javascript:;" class="btn-toggle" data-toggle-container-class="fullscreen" data-toggle-body-class="overflow-hidden" data-target="#footer"> 21514 <span class="group-icon"> 21515 <i class="fi fi-expand"></i> 21516 <i class="fi fi-shrink"></i> 21517 </span> 21518 </a> 21519 21520 * 21521 **/ 21522 process: function(_this) { 21523 21524 21525 // bind once 21526 _this.not(".js-togglified").addClass('js-togglified').on("click", function(e) { 21527 21528 21529 // BUTTON TRIGGER - LIKE MOBILE MENU 21530 var _t = jQuery(this), 21531 _target = _t.data('target') || '', 21532 _targetRw = _t.data('toggle-target') || '', // because data-target might be used by collapse! 21533 _target2 = _t.data('target-2') || '', 21534 _toastMessage = _t.data('toast-success-message') || '', 21535 _toastPos = _t.data('toast-success-position') || 'top-center', 21536 _temporized = _t.data('toggle-temporized') || 0, 21537 _toggleClass = _t.data('toggle-container-class') || '', // toggle class for a specific container 21538 _toggleClass2 = _t.data('toggle-container-class-2') || '', // toggle class for a specific container 21539 _requestOn = _t.data('toggle-ajax-url-on') || '', // send request to the server when on 21540 _requestOff = _t.data('toggle-ajax-url-off') || '', // send request to the server when off 21541 _requestMethod = _t.data('toggle-ajax-method') || $.SOW.core.btn_toggle.config.method, // send request to the server when off 21542 _bodyToggleClass = _t.data('toggle-body-class') || ''; // toggle class for body 21543 21544 21545 // Stop! 21546 if(_t.hasClass('disabled')) 21547 return; 21548 21549 // example: Like button - stop if off is not set but on is set! 21550 // Means only LIKE allowed! 21551 if(_requestOff == '' && _requestOn != '' && _t.hasClass('active')) 21552 return null; 21553 21554 21555 // set|uset active class 21556 _t.toggleClass('active'); 21557 21558 21559 if(_target == '' && _targetRw != '') 21560 _target = _targetRw; 21561 21562 21563 if(_target != '' && _toggleClass != '') { 21564 21565 jQuery(_target).toggleClass(_toggleClass); 21566 e.preventDefault(); 21567 21568 } 21569 21570 if(_target2 != '' && _toggleClass != '') 21571 jQuery(_target2).toggleClass(_toggleClass2); 21572 21573 21574 if(_bodyToggleClass != '') { 21575 21576 jQuery('body').toggleClass(_bodyToggleClass); 21577 e.preventDefault(); 21578 21579 } 21580 21581 21582 21583 if(_temporized > 0) { 21584 21585 setTimeout(function() { 21586 21587 if(_target != '' && _toggleClass != '') 21588 jQuery(_target).removeClass(_toggleClass); 21589 21590 if(_target2 != '' && _toggleClass2 != '') 21591 jQuery(_target2).removeClass(_toggleClass2); 21592 21593 if(_bodyToggleClass != '') 21594 jQuery('body').removeClass(_bodyToggleClass); 21595 21596 _t.removeClass('active'); 21597 21598 }, Number(_temporized)); 21599 21600 21601 // NO AJAX REQUESTS IF _temporized SET 21602 return; 21603 } 21604 21605 21606 21607 21608 21609 21610 21611 /** 21612 21613 Ajax Request 21614 --------------------------------------------------------------- 21615 21616 **/ 21617 if(_requestOff == '' && _requestOn == '') 21618 return null; 21619 21620 21621 e.preventDefault(); 21622 var _url = _t.hasClass('active') ? _requestOn : _requestOff; 21623 21624 21625 // Ajax Request 21626 jQuery.ajax({ 21627 url: _url, 21628 type: _requestMethod, 21629 data: $.SOW.core.btn_toggle.config.data_params, 21630 contentType: $.SOW.core.btn_toggle.config.contentType, 21631 dataType: $.SOW.core.btn_toggle.config.dataType, 21632 headers: $.SOW.core.btn_toggle.config.headers, 21633 crossDomain: $.SOW.core.btn_toggle.config.crossDomain, 21634 21635 beforeSend: function() { 21636 21637 $.SOW.helper.consoleLog('SOW Btn Toggle [Ajax][Request Sent]: ' + _url); 21638 21639 }, 21640 21641 error: function(XMLHttpRequest, textStatus, errorThrown) { 21642 21643 if(typeof $.SOW.core.toast === 'object') { 21644 $.SOW.core.toast.show('danger', '404 Error', 'Unexpected Internal error!', 'bottom-center', 0, true); 21645 } else { 21646 alert("[404] Unexpected internal error!"); 21647 } 21648 21649 // if debug enabled, see config 21650 if($.SOW.config.sow__debug_enable === true) { 21651 $.SOW.helper.consoleLog('----------------------------'); 21652 $.SOW.helper.consoleLog('--- AJAX REQUEST ERROR ----'); 21653 $.SOW.helper.consoleLog(' - MODAL -'); 21654 $.SOW.helper.consoleLog('1. XMLHttpRequest:'); 21655 $.SOW.helper.consoleLog(XMLHttpRequest); 21656 $.SOW.helper.consoleLog('2. textStatus:'); 21657 $.SOW.helper.consoleLog(textStatus); 21658 $.SOW.helper.consoleLog('3. errorThrown:'); 21659 $.SOW.helper.consoleLog(errorThrown); 21660 $.SOW.helper.consoleLog('----------------------------'); 21661 } 21662 21663 }, 21664 21665 success: function(data) { 21666 21667 $.SOW.helper.consoleLog('SOW Btn Toggle [Ajax][Server Response]: ' + data); 21668 21669 21670 // OPk, disable Like button! 21671 if(_requestOff == '' && _requestOn != '') 21672 _t.addClass('disabled'); 21673 21674 21675 if(_toastMessage != '' && typeof $.SOW.core.toast === 'object') 21676 $.SOW.core.toast.show('success', '', _toastMessage, _toastPos, 1500, true); 21677 21678 } 21679 21680 }); 21681 21682 21683 }); 21684 }, 21685 21686 21687 }; 21688 21689 21690})(jQuery); 21691/** 21692 * 21693 * [SOW] Nav Deep 21694 * 21695 * @author Dorin Grigoras 21696 * www.stepofweb.com 21697 * 21698 * @Dependency - 21699 * @Usage $.SOW.core.nav_deep.init('.nav-deep', {speed:200}); 21700 * 21701 * 21702 **/ 21703;(function ($) { 21704 'use strict'; 21705 21706 21707 /** 21708 * 21709 * @vars 21710 * 21711 * 21712 **/ 21713 var scriptInfo = 'SOW Nav Deep'; 21714 window.firstLoad = true; 21715 21716 $.SOW.core.nav_deep = { 21717 21718 21719 /** 21720 * 21721 * @config 21722 * 21723 * 21724 **/ 21725 config: { 21726 speed: 200 21727 }, 21728 21729 21730 21731 /** 21732 * 21733 * @collection 21734 * 21735 * 21736 **/ 21737 collection: $(), 21738 21739 21740 21741 /** 21742 * 21743 * @init 21744 * 21745 * 21746 **/ 21747 init: function (selector, config) { 21748 21749 var __selector = $.SOW.helper.__selector(selector); 21750 var __config = $.SOW.helper.check_var(config); 21751 21752 this.selector = __selector[0]; // '#selector' 21753 this.collection = __selector[1]; // $('#selector') 21754 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 21755 21756 21757 // Nav Tabs 21758 $.SOW.core.nav_deep.process_tabs(); 21759 21760 21761 if(jQuery(this.selector).length < 1) 21762 return; 21763 21764 21765 // -- * -- 21766 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 21767 // -- * -- 21768 21769 21770 // on page refresh, scroll sidebar to active link/item 21771 // in case there are many links! 21772 if(window.firstLoad) { 21773 window.firstLoad = false;
21774 $.SOW.core.nav_deep.asideScrollToActiveLink(this.selector); 21775 } 21776 21777 21778 // 1. Has no selector 21779 if(!this.selector) { 21780 $.SOW.core.nav_deep.process($('.nav-deep')); 21781 return this.collection; 21782 } 21783 21784 // 2. Has selector 21785 return this.collection.each(function() { 21786 21787 $.SOW.core.nav_deep.process($(this)); 21788 21789 }); 21790 21791 }, 21792 21793 21794 21795 /** 21796 * 21797 * @process 21798 * 21799 * 21800 **/ 21801 process: function(_this) { 21802 21803 _this.not('.js-ajaxified').addClass('js-ajaxified').each(function() { 21804 21805 var _tnd = jQuery(this), 21806 js_ignore = _tnd.hasClass('js-ignore'); 21807 21808 $('.nav-link', jQuery(this)).on('click', function(e) { 21809 21810 var _t = jQuery(this), 21811 _href = _t.attr('href') || '#', 21812 _target = _t.attr('target') || ''; 21813 21814 21815 // Ignore on target _blank, _self... 21816 if(_target != '') 21817 return; 21818 21819 21820 21821 if(!_t.parent('.nav-item').hasClass('active')) { 21822 21823 // 1. Open 21824 $.SOW.core.nav_deep.nav_deep_open(_t); 21825 21826 } else { 21827 21828 // 2. Close 21829 $.SOW.core.nav_deep.nav_deep_close(_t); 21830 21831 } 21832 21833 21834 21835 // 3. Close all other open navs only if .js-ignore is not present! 21836 if(!js_ignore) 21837 $.SOW.core.nav_deep.nav_deep_close_all(_t); 21838 21839 21840 21841 // -- 21842 if(_href == '#' || _href == '#!') 21843 e.preventDefault(); 21844 21845 }); 21846 21847 }); 21848 21849 }, 21850 21851 21852 21853 21854 21855 21856 /** 21857 21858 :: Single Item 21859 Navigation Links : Open 21860 21861 **/ 21862 nav_deep_open: function(_t) { 21863 21864 _t.next('ul').slideDown(this.config.speed, function(e) { 21865 _t.parent('.nav-item').addClass('active'); 21866 jQuery(this).css({"display":""}); // remove display: block 21867 }); 21868 21869 }, 21870 21871 21872 21873 /** 21874 21875 :: Single Item 21876 Navigation Links : Close 21877 21878 21879 **/ 21880 nav_deep_close: function(_t) { 21881 21882 _t.next('ul').slideUp(this.config.speed, function(e) { 21883 _t.parent('.nav-item').removeClass('active'); 21884 jQuery(this).css({"display":""}); // remove display: block 21885 }); 21886 21887 }, 21888 21889 21890 21891 21892 /** 21893 21894 :: Multiple Items 21895 Navigation Links : Close Active 21896 21897 21898 **/ 21899 nav_deep_close_all: function(_t) { 21900 21901 // Close all open parents 21902 _t.parent('.nav-item').parent().find('.nav-item.active').not(_t.parent('.nav-item')).find('ul.nav').slideUp(this.config.speed, function(e) { 21903 21904 jQuery(this).parent('.nav-item.active').removeClass('active').next().find('ul.nav').css({"display":""}); // remove display: block added by slideUp() 21905 21906 }); 21907 21908 21909 // Single link (no childs) - add .active. Ajax Purpose! 21910 if(_t.next().find('ul.nav').length < 1) 21911 _t.parent('.nav-item').addClass('active'); 21912 21913 21914 // Remove .active from singles (without childs) - ajax purpose only 21915 setTimeout(function() { // do not interfere with the one above! 21916 _t.parent('.nav-item').parent().find('.nav-item.active').not(_t.parent('.nav-item')).removeClass('active'); 21917 }, this.config.speed + 30); 21918 21919 }, 21920 21921 21922 21923 21924 21925 /** 21926 * 21927 * @asideScrollToActiveLink 21928 * 21929 on page refresh, scroll sidebar to active link/item 21930 needed when there are many links! 21931 21932 Do not move this function to sow.sidebar.js 21933 this selector is needed! 21934 * 21935 **/ 21936 asideScrollToActiveLink: function(selector) { 21937 21938 if(jQuery('aside '+selector+' .nav-item.active').length < 1) 21939 return; 21940 21941 var activeLinkOffset = jQuery('aside '+selector+' .nav-item.active').offset(); 21942 var scrollableDivOffset = jQuery('aside .scrollable-vertical').offset(); 21943 21944 // issue when window height is smaller and element is fixed/absolute outside of viewport 21945 if(!scrollableDivOffset || !activeLinkOffset) return; 21946 21947 var scrollDivTo = (activeLinkOffset.top - scrollableDivOffset.top) - Math.round($.SOW.globals.height / 8); 21948 21949 if(activeLinkOffset.top < $.SOW.globals.height) 21950 return; 21951 21952 jQuery('aside .scrollable-vertical:not(.js-ignore)').animate({ 21953 scrollTop: scrollDivTo 21954 }, 0); 21955 21956 }, 21957 21958 21959 21960 21961 21962 /** 21963 * 21964 * @process_tabs 21965 * @add to any tab link: .nav-link-remember 21966 * 21967 **/ 21968 process_tabs: function() { 21969 21970 // add to localStorage 21971 jQuery('a.nav-link-remember').on('click', function(e) { 21972 localStorage.setItem('activeNavTab', jQuery(e.target).attr('href')); 21973 }); 21974 21975 // get from localStorage 21976 var activeNavTab = localStorage.getItem('activeNavTab'); 21977 if(activeNavTab) { 21978 jQuery('a.nav-link-remember[href="' + activeNavTab + '"]').tab('show'); 21979 } 21980 21981 } 21982 21983 21984 }; 21985 21986 21987})(jQuery); 21988/** 21989 * 21990 * [SOW] Form Validate 21991 * 21992 * @author Dorin Grigoras 21993 * www.stepofweb.com 21994 * 21995 * @Dependency - 21996 * @Usage $.SOW.core.form_validate.init('form.bs-validate'); 21997 * 21998 * 21999 **/ 22000;(function ($) { 22001 'use strict'; 22002 22003 22004 /** 22005 * 22006 * @vars 22007 * 22008 * 22009 **/ 22010 var scriptInfo = 'SOW Form Validate'; 22011 22012 22013 22014 22015 $.SOW.core.form_validate = { 22016 22017 22018 /** 22019 * 22020 * @config 22021 * 22022 * 22023 **/ 22024 config: {}, 22025 22026 22027 22028 /** 22029 * 22030 * @collection 22031 * 22032 * 22033 **/ 22034 collection: $(), 22035 22036 22037 22038 /** 22039 * 22040 * @init 22041 * 22042 * 22043 **/ 22044 init: function (selector, config) { 22045 22046 var __selector = $.SOW.helper.__selector(selector); 22047 var __config = $.SOW.helper.check_var(config); 22048 22049 this.selector = __selector[0]; // '#selector' 22050 this.collection = __selector[1]; // $('#selector') 22051 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 22052 22053 22054 if(jQuery(this.selector).length < 1) 22055 return; 22056 22057 22058 // -- * -- 22059 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 22060 // -- * -- 22061 22062 22063 // 1. Has no selector 22064 if(!this.selector) { 22065 $.SOW.core.form_validate.form_validate($('form.bs-validate')); 22066 return this.collection; 22067 } 22068 22069 // 2. Has selector 22070 return this.collection.each(function() { 22071 22072 $.SOW.core.form_validate.form_validate($(this)); 22073 22074 }); 22075 22076 }, 22077 22078 22079 22080 /** 22081 * 22082 * @form_validate 22083 * 22084 * 22085 * 22086 **/ 22087 form_validate: function(_this) { 22088 22089 var _selector = this.selector; 22090 22091 // Stop if ajax form already in action! 22092 if(jQuery(_selector).hasClass('.js-ajax') && typeof $.SOW.core.ajax_form === 'object') { 22093 $.SOW.helper.consoleLog('Ajax Form Detected! ' + scriptInfo + ' Skipped!'); 22094 return; 22095 } 22096 22097 22098 _this.submit(function(e) { 22099 22100 var _t = jQuery(this), 22101 _formID = _t.attr('id') || '', 22102 _scrollErrUp = _t.attr('data-error-scroll-up') || 'false', 22103 _toast_text = _t.data('error-toast-text') || '', // toast alert for .bs-validate 22104 _toast_delay = _t.data('error-toast-delay') || 0, // toast alert for .bs-validate 22105 _toast_pos = _t.data('error-toast-position') || "top-right"; // toast alert for .bs-validate 22106 22107 // Assign a random id if not exist 22108 if(_formID == '') { 22109 var _formID = 'js_' + $.SOW.helper.randomStr(10); 22110 _t.attr('id', _formID); 22111 } 22112 22113 // Check if form already handled by ajax 22114 if(typeof $.SOW.core.ajax_form === 'object' && _t.hasClass('js-ajax')) 22115 return; 22116 22117 var _form = document.getElementById(_formID); 22118 22119 // hide all errors info 22120 jQuery('.bs-validate-info', _t).addClass('hide hide-force'); 22121 22122 if(typeof $.SOW.core.toast === 'object') 22123 $.SOW.core.toast.destroy(); 22124 22125 22126 if(!_form.checkValidity()) { 22127 22128 22129 // -- message|toast --- 22130 if(_toast_text != '') { 22131 22132 if(typeof $.SOW.core.toast === 'object') { 22133 22134 if(Number(_toast_delay) < 1)
22135 var _toast_delay = 4000; 22136 22137 $.SOW.core.toast.show('danger', '', _toast_text, _toast_pos, Number(_toast_delay), true); 22138 22139 } else { 22140 22141 alert(_toast_text); 22142 22143 } 22144 22145 } else { 22146 22147 // show error info 22148 jQuery('.bs-validate-info', _t).removeClass('hide hide-force'); // show error info 22149 22150 // error info delay timeout 22151 var _delay = jQuery('.bs-validate-info', _t).data('error-alert-delay') || 3000; 22152 22153 // hide error info in X seconds 22154 setTimeout(function() { 22155 jQuery('.bs-validate-info', _t).addClass('hide hide-force'); 22156 }, Number(_delay)); 22157 22158 } 22159 // -- -- -- -- 22160 22161 // Focus invalid element and scroll 22162 jQuery('.form-control:invalid', _t).first().focus(); 22163 22164 // Do not animate inside modal! 22165 if(typeof $.SOW.helper.scrollAnimate === "function" && (_scrollErrUp+'' == 'true') && !jQuery('.modal').hasClass('show')) { 22166 var _formEl = jQuery('input:invalid, select:invalid, textarea:invalid', _t); 22167 $.SOW.helper.scrollAnimate(_formEl, 0, false, 200); 22168 } 22169 // -- -- -- -- 22170 22171 e.preventDefault(); 22172 e.stopPropagation(); 22173 22174 } else { 22175 22176 // disable on submit to avoid multiple click 22177 jQuery('.btn-bs-validate').attr('disabled', true); 22178 22179 if(typeof $.SOW.core.toast === 'object') 22180 $.SOW.core.toast.destroy(); 22181 22182 } 22183 22184 _t.addClass('was-validated'); 22185 22186 22187 }); 22188 22189 22190 }, 22191 22192 } 22193 22194})(jQuery); 22195/** 22196 * 22197 * [SOW] Form Advanced 22198 * 22199 * @author Dorin Grigoras 22200 * www.stepofweb.com 22201 * 22202 * @Dependency - 22203 * @Usage $.SOW.core.form_advanced.init(); 22204 * 22205 * 22206 **/ 22207;(function ($) { 22208 'use strict'; 22209 22210 22211 /** 22212 * 22213 * @vars 22214 * 22215 * 22216 **/ 22217 var scriptInfo = 'SOW Form Advanced'; 22218 22219 22220 $.SOW.core.form_advanced = { 22221 22222 22223 /** 22224 * 22225 * @config 22226 * 22227 * 22228 **/ 22229 config: { 22230 22231 /* 22232 22233 1. Bulk 22234 @form_advanced_bulk 22235 22236 */ 22237 selector_advanced_bulk: "a.js-form-advanced-bulk", 22238 advanced_bulk_selected_require: false, 22239 22240 // toast messages 22241 toast_pos: 'bottom-center', 22242 toast_delay: 2000, 22243 toast_msg_noitems: 'No Items Selected!', 22244 22245 22246 22247 /* 22248 22249 2. Form input numeric limit 22250 @form_advanced_numeric_limit 22251 22252 */ 22253 selector_advanced_numeric_limit: "input.js-form-advanced-limit", 22254 22255 22256 22257 22258 /* 22259 22260 3. Form char count 22261 @form_advanced_char_count_down 22262 22263 */ 22264 selector_advanced_char_count_down: "input.js-form-advanced-char-count-down, textarea.js-form-advanced-char-count-down", 22265 selector_advanced_char_count_up: "input.js-form-advanced-char-count-up, textarea.js-form-advanced-char-count-up", 22266 selector_advanced_type_toggle: ".btn-password-type-toggle", 22267 22268 }, 22269 22270 22271 22272 /** 22273 * 22274 * @collection 22275 * 22276 * 22277 **/ 22278 collection: $(), 22279 22280 22281 22282 /** 22283 * 22284 * @init 22285 * 22286 * 22287 **/ 22288 init: function (selector, config) { 22289 22290 var __selector = $.SOW.helper.__selector(selector); 22291 var __config = $.SOW.helper.check_var(config); 22292 22293 this.selector = __selector[0]; // '#selector' 22294 this.collection = __selector[1]; // $('#selector') 22295 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 22296 22297 22298 // 1. Bulk 22299 $.SOW.core.form_advanced.form_advanced_bulk(this.config.selector_advanced_bulk); 22300 22301 // 2. Form input numeric limit 22302 $.SOW.core.form_advanced.form_advanced_numeric_limit(this.config.selector_advanced_numeric_limit); 22303 22304 // 3. Form char count down 22305 $.SOW.core.form_advanced.form_advanced_char_count_down(this.config.selector_advanced_char_count_down); 22306 22307 // 4. Form char count up 22308 $.SOW.core.form_advanced.form_advanced_char_count_up(this.config.selector_advanced_char_count_up); 22309 22310 // 5. Form password toggle 22311 $.SOW.core.form_advanced.form_advanced_type_toggle(this.config.selector_advanced_type_toggle); 22312 22313 // 6. Misc 22314 $.SOW.core.form_advanced.formatCreditCard(); 22315 $.SOW.core.form_advanced.formAdvancedList(); 22316 $.SOW.core.form_advanced.formAdvancedReset(); 22317 22318 22319 // No chaining 22320 return null; 22321 22322 }, 22323 22324 22325 22326 /** 22327 * 22328 * @form_advanced_bulk 22329 Form actions[submit] using a regular link 22330 * 22331 * 22332 * 22333 **/ 22334 form_advanced_bulk: function(_this) { 22335 22336 // -- * -- 22337 if(jQuery(_this).length > 0) 22338 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 22339 // -- * -- 22340 22341 22342 jQuery(_this).not('.js-form-advancified').addClass('js-form-advancified').on('click', function(e) { 22343 e.preventDefault(); 22344 22345 var _t = jQuery(this), 22346 22347 _citems = _t.data('js-form-advanced-bulk-container-items') || 'table tbody', // from what container to count checked items? 22348 _reqSelectedItems = _t.data('js-form-advanced-bulk-required-selected') || $.SOW.core.form_advanced.config.advanced_bulk_selected_require, 22349 _requiredMsg = _t.data('js-form-advanced-bulk-required-txt-error') || $.SOW.core.form_advanced.config.toast_msg_noitems, 22350 _requiredMsgPos = _t.data('js-form-advanced-bulk-required-txt-position') || $.SOW.core.form_advanced.config.toast_pos, // button icon 22351 22352 // Modal 22353 _reqModalCustom = _t.data('js-form-advanced-bulk-required-custom-modal') || '', // modal id 22354 _reqModalCustomAjaxUrl = _t.data('js-form-advanced-bulk-required-custom-modal-content-ajax') || '', 22355 22356 _reqModalType = _t.data('js-form-advanced-bulk-required-modal-type') || 'secondary', 22357 _reqModalSize = _t.data('js-form-advanced-bulk-required-modal-size') || 'modal-md', 22358 _reqModalTitle = _t.data('js-form-advanced-bulk-required-modal-txt-title') || 'Please Confirm', 22359 _reqModalTxtSubtitle = _t.data('js-form-advanced-bulk-required-modal-txt-subtitle') || '-', 22360 _reqModalTxtBodyTxt = _t.data('js-form-advanced-bulk-required-modal-txt-body-txt') || 'Are you sure?', 22361 _reqModalTxtBodyInfo = _t.data('js-form-advanced-bulk-required-modal-txt-body-info') || '', 22362 _reqModalBtnTxtYes = _t.data('js-form-advanced-bulk-required-modal-btn-text-yes') || 'Submit', 22363 _reqModalBtnTxtNo = _t.data('js-form-advanced-bulk-required-modal-btn-text-no') || 'Cancel', 22364 _reqModalBtnIcoYes = _t.data('js-form-advanced-bulk-required-modal-btn-icon-yes') || $.SOW.config.sow__icon_check, // button icon 22365 _reqModalBtnIcoNo = _t.data('js-form-advanced-bulk-required-modal-btn-icon-no') || $.SOW.config.sow__icon_close, // button icon 22366 22367 // Form 22368 _formID = _t.attr('data-js-form-advanced-form-id') || '', // form#id .attr REQUIRED, or old one used! 22369 _formSubmitNoConfirm = _t.data('js-form-advanced-bulk-submit-without-confirmation') || 'false', 22370 22371 // Hidden action input 22372 _formActionID = _t.data('js-form-advanced-bulk-hidden-action-id') || '#action', 22373 _formActionVal = _t.data('js-form-advanced-bulk-hidden-action-value') || ''; 22374 22375 // count selecteditems & update 22376 var total_selected_items = jQuery(_citems + " input:checked").length; 22377 22378 22379 22380 // Check for required selected items 22381 if(_reqSelectedItems == true && Number(total_selected_items) < 1) { 22382 22383 // SHOW ERROR 22384 if(typeof $.SOW.core.toast === 'object') { 22385 $.SOW.core.toast.destroy(); 22386 $.SOW.core.toast.show('danger', '', _requiredMsg, _requiredMsgPos, $.SOW.core.form_advanced.config.toast_delay, true); 22387 } else { 22388 alert(_requiredMsg); 22389 } 22390 22391 e.stopPropagation(); 22392 return; 22393 22394 } 22395 22396 22397 22398 22399 22400 22401 // Update action hidden input 22402 if(_formActionVal != '') 22403 jQuery(_formActionID).val(_formActionVal); 22404 22405 22406 // Direct submit, no confirmation 22407 if(_formSubmitNoConfirm != 'false') { 22408 jQuery(_formID).unbind().submit(); // unbind required 22409 return; 22410 } 22411 22412 22413 // Button Icons 22414 if(_reqModalBtnIcoYes.length > 1)
22415 var _reqModalBtnTxtYes = '<i class="' + _reqModalBtnIcoYes + '"></i> ' + _reqModalBtnTxtYes; 22416 22417 if(_reqModalBtnIcoNo.length > 1) 22418 var _reqModalBtnTxtNo = '<i class="' + _reqModalBtnIcoNo + '"></i> ' + _reqModalBtnTxtNo; 22419 22420 22421 // Replacements 22422 _reqModalTitle = _reqModalTitle.replace('{{no_selected}}', total_selected_items); 22423 _reqModalTxtBodyTxt = _reqModalTxtBodyTxt.replace('{{no_selected}}', total_selected_items); 22424 _reqModalTxtBodyInfo = _reqModalTxtBodyInfo.replace('{{no_selected}}', total_selected_items); 22425 _reqModalTxtSubtitle = _reqModalTxtSubtitle.replace('{{no_selected}}', total_selected_items); 22426 22427 22428 // Additional info 22429 var _reqModalTxtBodyTxt = (_reqModalTxtBodyInfo != '') ? _reqModalTxtBodyTxt + '<span class="d-block d-block fs--12 mt--3">' + _reqModalTxtBodyInfo + '</span>' : _reqModalTxtBodyTxt; 22430 22431 22432 22433 22434 22435 22436 22437 22438 // 1. Inline Modal 22439 if(_reqModalCustom != '') { 22440 22441 // Update selected items counter 22442 if(_reqModalCustom != '') 22443 $.SOW.core.form_advanced.form_advanced_bulk_counter_update(total_selected_items); 22444 22445 22446 // SHOW MODAL 22447 jQuery(_reqModalCustom).modal('show'); 22448 22449 22450 // LOAD FROM AJAX 22451 if(_reqModalCustomAjaxUrl != '') { 22452 22453 jQuery(_reqModalCustom).find('.modal-content').load(_reqModalCustomAjaxUrl, function() { 22454 22455 // Update selected items counter 22456 $.SOW.core.form_advanced.form_advanced_bulk_counter_update(total_selected_items); 22457 22458 }); 22459 22460 } 22461 22462 // stop here 22463 return; 22464 22465 22466 } 22467 22468 22469 22470 22471 // 2. Generated modal 22472 var _tpl = '<div class="modal fade" id="js_advanced_form_bulk_modal_confirm" role="dialog" tabindex="-1" aria-labelledby="modal-title-confirm" aria-hidden="true">' 22473 + '<div class="modal-dialog '+_reqModalSize+'" role="document">' 22474 22475 + '<div class="modal-content">' 22476 22477 + '<div class="modal-header b-0 bg-'+_reqModalType+'-soft">' 22478 22479 + '<h5 id="modal-title-confirm" class="modal-title font-light fs--18 line-height-1">' 22480 + _reqModalTitle 22481 + '<small class="d-block fs--12 mt--3">'+_reqModalTxtSubtitle+'</small>' 22482 + '</h5>' 22483 22484 + '<button type="button" class="close" data-dismiss="modal" aria-label="Close">' 22485 + '<span class="'+$.SOW.config.sow__icon_close+' fs--18" aria-hidden="true"></span>' 22486 + '</button>' 22487 22488 + '</div>' 22489 22490 + '<div class="modal-body fs--18 pt--30 pb--30">' 22491 22492 + _reqModalTxtBodyTxt 22493 22494 + '</div>' 22495 22496 + '<div class="modal-footer">' 22497 22498 + '<button type="submit" class="btn pt--10 pb--10 fs--16 btn-js-advanced-form-bulk-confirm-yes btn-'+ _reqModalType +'">' 22499 + _reqModalBtnTxtYes 22500 + '</button>' 22501 22502 + '<a href="#" class="btn pt--10 pb--10 fs--16 btn-js-advanced-form-bulk-confirm-no btn-light" data-dismiss="modal">' 22503 + _reqModalBtnTxtNo 22504 + '</a>' 22505 22506 + '</div>' 22507 22508 + '</div>' 22509 22510 + '</div>' 22511 + '</div>'; 22512 22513 // Add modal to DOM 22514 22515 $('#js_advanced_form_bulk_modal_confirm').remove(); 22516 $(_formID).append(_tpl); // REQUIRED INSIDE THE FORM! Because of Submit button! 22517 22518 // Show Modal 22519 $('#js_advanced_form_bulk_modal_confirm').modal('handleUpdate').modal('show'); 22520 22521 // Custom Ajax Content 22522 if(_reqModalCustomAjaxUrl != '') { 22523 22524 jQuery('#js_advanced_form_bulk_modal_confirm .modal-body').empty().append('<div class="py-4 text-center animate-bouncein"><i class="'+$.SOW.config.sow__icon_loading+' fs--40 text-muted"></i></div>'); 22525 22526 jQuery('#js_advanced_form_bulk_modal_confirm .modal-body').load(_reqModalCustomAjaxUrl, function() { 22527 22528 // Update selected items counter 22529 $.SOW.core.form_advanced.form_advanced_bulk_counter_update(total_selected_items); 22530 22531 }); 22532 } 22533 22534 return; 22535 22536 22537 }); 22538 22539 22540 }, 22541 22542 22543 22544 22545 /** 22546 * 22547 * @form_advanced_bulk_counter_update 22548 * :: Helper 22549 * 22550 * 22551 **/ 22552 form_advanced_bulk_counter_update: function(total_selected_items) { 22553 22554 // Update selected items 22555 jQuery('.js-form-advanced-selected-items').html(total_selected_items); 22556 22557 }, 22558 22559 22560 /** 22561 * 22562 * @form_advanced_numeric_limit 22563 Input min/max limits 22564 22565 <!-- input limit + hidden message --> 22566 <div class="position-relative"> 22567 22568 <span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2"> 22569 please, order between 1 and 48. 22570 </span> 22571 22572 <input type="number" value="8" min="1" max="48" class="form-control js-form-advanced-limit">
22573 </div> 22574 <!-- /input limit + hidden message --> 22575 22576 * 22577 * 22578 * 22579 **/ 22580 form_advanced_numeric_limit: function(_this) { 22581 22582 if(jQuery(_this).length < 1) 22583 return; 22584 22585 jQuery(_this).keyup(function() { 22586 var _t = jQuery(this), 22587 _val = _t.val() || '', 22588 _min = _t.attr('min') || '', 22589 _max = _t.attr('max') || ''; 22590 22591 if(_min == '' || _max == '') 22592 return; 22593 22594 if(Number(_val) < Number(_min)) 22595 _t.val(_min); 22596 22597 else if(Number(_val) > Number(_max)) { 22598 _t.val(_max); 22599 22600 // Optional simple info message 22601 $.SOW.core.form_advanced.form_advanced_simple_alert(_t); 22602 } 22603 22604 22605 }); 22606 22607 }, 22608 22609 22610 22611 /** 22612 * 22613 * @form_advanced_char_count_down 22614 Char Count Down 22615 22616 <!-- input --> 22617 <div class="position-relative"> 22618 22619 <span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2"> 22620 100 chars limit 22621 </span> 22622 22623 <input type="text" name="-" class="form-control js-form-advanced-char-count-down" data-output-target=".js-form-advanced-char-left" value="" maxlength="100"> 22624 22625 <div class="fs--12 text-muted text-align--end mt--3"> 22626 characters left: <span class="js-form-advanced-char-left">100</span> 22627 </div> 22628 22629 </div> 22630 22631 <br> 22632 22633 <!-- textarea --> 22634 <div class="position-relative"> 22635 22636 <span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2"> 22637 100 chars limit 22638 </span> 22639 22640 <textarea class="js-form-advanced-char-count-down form-control" data-output-target=".js-form-advanced-char-left2" maxlength="100"></textarea> 22641 22642 <div class="fs--12 text-muted text-align--end mt--3"> 22643 characters left: <span class="js-form-advanced-char-left2">100</span> 22644 </div> 22645 22646 </div> 22647 22648 * 22649 * 22650 * 22651 **/ 22652 form_advanced_char_count_down: function(_this) { 22653 22654 22655 if(jQuery(_this).length < 1) 22656 return; 22657 22658 jQuery(_this).keyup(function(e) { 22659 22660 var _t = jQuery(this), 22661 _val = _t.val(), 22662 _length = _val.length, 22663 _max = _t.attr('maxlength') || 0, 22664 _output = _t.data('output-target') || '.char-left'; 22665 22666 if(_max < 1 && _output != '') 22667 return; 22668 22669 if(_length >= _max) { 22670 _t.val(_val.substring(0, _max - 1)); // limit - remove anything over maximum allowed 22671 jQuery(_output).html('0'); 22672 22673 // Optional simple info message 22674 $.SOW.core.form_advanced.form_advanced_simple_alert(_t); 22675 22676 } else { 22677 var _left = _max - _length; 22678 jQuery(_output).html(_left); 22679 } 22680 22681 22682 }); 22683 22684 }, 22685 22686 22687 22688 22689 22690 /** 22691 * 22692 * @form_advanced_char_count_up 22693 Char Count Up 22694 22695 22696 Remove maxlength for no limit, only to count chars 22697 22698 22699 22700 <!-- input --> 22701 <div class="position-relative"> 22702 22703 <span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2"> 22704 100 chars limit 22705 </span> 22706 22707 <input type="text" name="-" class="form-control js-form-advanced-char-count-up" data-output-target=".js-form-advanced-char-total" value="" maxlength="100"> 22708 22709 <div class="fs--12 text-muted text-align--end mt--3"> 22710 characters: <span class="js-form-advanced-char-total">0</span> / 100 22711 </div> 22712 22713 </div> 22714 22715 <br> 22716 22717 <!-- textarea --> 22718 <div class="position-relative"> 22719 22720 <span class="js-form-advanced-limit-info badge badge-warning hide animate-bouncein position-absolute absolute-top m--2"> 22721 100 chars limit 22722 </span> 22723 22724 <textarea class="js-form-advanced-char-count-up form-control" data-output-target=".js-form-advanced-char-total2" maxlength="100"></textarea> 22725 22726 <div class="fs--12 text-muted text-align--end mt--3"> 22727 characters: <span class="js-form-advanced-char-total2">0</span> / 100 22728 </div> 22729 22730 </div> 22731 22732 * 22733 * 22734 * 22735 **/ 22736 form_advanced_char_count_up: function(_this) { 22737 22738 if(jQuery(_this).length < 1) 22739 return; 22740 22741 jQuery(_this).keyup(function() { 22742 22743 var _t = jQuery(this), 22744 _val = _t.val(), 22745 _length = _val.length || 0, 22746 _max = _t.attr('maxlength') || 0, 22747 _output = _t.data('output-target') || '.char-count'; 22748 22749 jQuery(_output).html(_length); 22750 22751 // limit if specified 22752 if(_length >= _max && _max > 0) { 22753 _t.val(_val.substring(0, _max)); // limit - remove anything over maximum allowed 22754 22755 // Optional simple info message 22756 $.SOW.core.form_advanced.form_advanced_simple_alert(_t); 22757 } 22758 22759 }); 22760 22761 }, 22762 22763 22764 22765 22766 /** 22767 * 22768 * @form_advanced_simple_alert 22769 * Optional form alert 22770 * 22771 * 22772 **/ 22773 form_advanced_simple_alert: function(_this) { 22774 22775 _this.next('.js-form-advanced-limit-info').removeClass('hide'); 22776 _this.prev('.js-form-advanced-limit-info').removeClass('hide'); 22777 22778 setTimeout(function() { 22779 _this.next('.js-form-advanced-limit-info').addClass('hide'); 22780 _this.prev('.js-form-advanced-limit-info').addClass('hide'); 22781 }, 3000); 22782 22783 }, 22784 22785 22786 22787 22788 /** 22789 * 22790 * @form_advanced_type_toggle 22791 * 22792 * 22793 **/ 22794 form_advanced_type_toggle: function(_this) { 22795 22796 if(jQuery(_this).length < 1) 22797 return; 22798 22799 jQuery(_this).on('click', function(e) { 22800 e.preventDefault(); 22801 22802 var _target = jQuery(this).data('target') || ''; 22803 22804 if(_target == '') 22805 return; 22806 22807 jQuery(this).toggleClass('active'); 22808 if(jQuery(_target).attr('type') == 'password') { 22809 jQuery(_target).attr('type', 'text'); 22810 } else { 22811 jQuery(_target).attr('type', 'password'); 22812 } 22813 22814 }); 22815 22816 }, 22817 22818 22819 22820 22821 /** 22822 * 22823 * @formAdvancedList 22824 * on a list, reveal/expand selected (example: payment method - checkout) 22825 * 22826 **/ 22827 formAdvancedList: function() { 22828 22829 jQuery('.form-advanced-list').each(function() { 22830 22831 var _t = jQuery(this); 22832 22833 jQuery('.form-advanced-list-reveal', _t).on('change', function() { 22834 22835 var __t = jQuery(this), 22836 __target = __t.data('form-advanced-target') || ''; 22837 22838 // hide all first 22839 jQuery('.form-advanced-list-reveal-item', _t).addClass('hide hide-force'); 22840 22841 // reveal selected 22842 if(__target != '') 22843 jQuery(__target).removeClass('hide hide-force'); 22844 22845 }) 22846 22847 }); 22848 22849 }, 22850 22851 22852 22853 22854 22855 /** 22856 * 22857 * @formAdvancedReset 22858 * reset form on button click 22859 * 22860 **/ 22861 formAdvancedReset: function() { 22862 22863 jQuery('.form-advanced-reset').not('.js-ignore').not('.js-advancified').addClass('js-advancified').each(function() { 22864 22865 var _t = jQuery(this), 22866 _target = _t.data('target-reset'); 22867 22868 if(_target == '') 22869 return null; 22870 22871 jQuery(_target+' input').on('change', function() { 22872 _t.removeClass('hide hide-force'); 22873 }); 22874 22875 jQuery(_target+' textarea').on('change', function() { 22876 _t.removeClass('hide hide-force'); 22877 }); 22878 22879 22880 22881 // reset button click 22882 _t.on('click', function(e) { 22883 e.preventDefault(); 22884 22885 jQuery(_target+' input').val(''); 22886 jQuery(_target+' textarea').val(''); 22887 jQuery(_target+' input[type=checkbox]').prop('checked', false); 22888 jQuery(_target+' input[type=radio]').prop('checked', false); 22889 22890 // hide reset button 22891 if(!_t.hasClass('js-ignore')) 22892 _t.addClass('hide hide-force'); 22893 22894 }); 22895 22896 22897 }); 22898 22899 22900 22901 22902 }, 22903 22904 22905 22906 22907 22908 /** 22909 * 22910 * @formatCreditCard 22911 * 22912 * 22913 **/ 22914 formatCreditCard: function() { 22915 22916 22917 /* 22918 22919 Credit card number 22920 22921 */ 22922 jQuery('input.cc-format.cc-number').keyup(function() { 22923 22924 var _t = jQuery(this), 22925 val = _t.val() || '', 22926 targetCardType = _t.data('card-type') || ''; 22927 22928 // format 22929 var cc_formatted = $.SOW.core.form_advanced.formatCardNumber(val); 22930 _t.val(cc_formatted); 22931 22932 // Credit card type 22933 if(targetCardType != '') { 22934 var cc_type = $.SOW.core.form_advanced.detectCardType(val); 22935 var cc_type = (cc_type) ? cc_type.name : ''; 22936 jQuery(targetCardType).val(cc_type); 22937 } 22938 22939 }); 22940 22941 22942 /* 22943 22944 Credit card expire 22945 22946 */ 22947 jQuery('input.cc-format.cc-expire').keyup(function(e) { 22948 22949 var _t = jQuery(this), 22950 val = _t.val() || '', 22951 code = e.keyCode, 22952 allowedKeys = [8]; 22953 22954 if(allowedKeys.indexOf(code) !== -1) { 22955 return; 22956 } 22957 22958 e.target.value = e.target.value.replace( 22959 /^([1-9]\/|[2-9])$/g, '0$1/' // 3 > 03/ 22960 ).replace( 22961 /^(0[1-9]|1[0-2])$/g, '$1/' // 11 > 11/ 22962 ).replace( 22963 /^([0-1])([3-9])$/g, '0$1/$2' // 13 > 01/3 22964 ).replace( 22965 /^(0?[1-9]|1[0-2])([0-9]{2})$/g, '$1/$2' // 141 > 01/41 22966 ).replace( 22967 /^([0]+)\/|[0]+$/g, '0' // 0/ > 0 and 00 > 0 22968 ).replace( 22969 /[^\d\/]|^[\/]*$/g, '' // To allow only digits and `/` 22970 ).replace( 22971 /\/\//g, '/' // Prevent entering more than 1 `/` 22972 ); 22973 22974 }); 22975 22976 }, 22977 22978 22979 22980 /** 22981 * 22982 * @formatCardNumber 22983 * https://www.peterbe.com/plog/cc-formatter 22984 * 22985 **/ 22986 formatCardNumber: function(value) { 22987 22988 var v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, ''); 22989 var matches = v.match(/\d{4,16}/g); 22990 var match = matches && matches[0] || ''; 22991 var parts = []; 22992 22993 for (var i=0, len=match.length; i<len; i+=4) { 22994 parts.push(match.substring(i, i+4)); 22995 } 22996 22997 if(parts.length) { 22998 return parts.join(' '); 22999 } else { 23000 return value; 23001 } 23002 23003 }, 23004 23005 23006 23007 23008 /** 23009 *
23010 * @detectCardType 23011 * 23012 * 23013 **/ 23014 detectCardType: function(number) { 23015 23016 var card_types = [ 23017 { 23018 name: 'amex', 23019 pattern: /^3[47]/, 23020 valid_length: [15] 23021 }, { 23022 // name: 'diners_club_carte_blanche', 23023 name: 'diners', 23024 pattern: /^30[0-5]/, 23025 valid_length: [14] 23026 }, { 23027 // name: 'diners_club_international', 23028 name: 'diners', 23029 pattern: /^36/, 23030 valid_length: [14] 23031 }, { 23032 name: 'jcb', 23033 pattern: /^35(2[89]|[3-8][0-9])/, 23034 valid_length: [16] 23035 }, { 23036 name: 'laser', 23037 pattern: /^(6304|670[69]|6771)/, 23038 valid_length: [16, 17, 18, 19] 23039 }, { 23040 // name: 'visa_electron', 23041 name: 'visa', 23042 pattern: /^(4026|417500|4508|4844|491(3|7))/, 23043 valid_length: [16] 23044 }, { 23045 name: 'visa', 23046 pattern: /^4/, 23047 valid_length: [16] 23048 }, { 23049 name: 'mastercard', 23050 pattern: /^5[1-5]/, 23051 valid_length: [16] 23052 }, { 23053 name: 'maestro', 23054 pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, 23055 valid_length: [12, 13, 14, 15, 16, 17, 18, 19] 23056 }, { 23057 name: 'discover', 23058 pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/, 23059 valid_length: [16] 23060 } 23061 ]; 23062 23063 23064 var _j, _len1, _ref1, card, card_type, options = {}; 23065 var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; 23066 23067 23068 if (options.accept == null) { 23069 options.accept = (function() { 23070 var _i, _len, _results; 23071 _results = []; 23072 23073 for (_i = 0, _len = card_types.length; _i < _len; _i++) { 23074 card = card_types[_i]; 23075 _results.push(card.name); 23076 } 23077 23078 return _results; 23079 23080 })(); 23081 } 23082 23083 var _ref = options.accept; 23084 for (var _i = 0, _len = _ref.length; _i < _len; _i++) { 23085 card_type = _ref[_i]; 23086 23087 if (__indexOf.call((function() { 23088 var _j, _len1, _results = []; 23089 23090 for (var _j = 0, _len1 = card_types.length; _j < _len1; _j++) { 23091 card = card_types[_j]; 23092 _results.push(card.name); 23093 } 23094 23095 return _results; 23096 23097 })(), card_type) < 0) { 23098 23099 // throw "Credit card type '" + card_type + "' is not supported"; 23100 23101 } 23102 } 23103 23104 _ref1 = (function() { 23105 var _k, _len1, _ref1, _results = []; 23106 23107 for (_k = 0, _len1 = card_types.length; _k < _len1; _k++) { 23108 card = card_types[_k]; 23109 if (_ref1 = card.name, __indexOf.call(options.accept, _ref1) >= 0) { 23110 _results.push(card); 23111 } 23112 } 23113 23114 return _results; 23115 23116 })(); 23117 23118 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { 23119 card_type = _ref1[_j]; 23120 23121 if (number.match(card_type.pattern)) { 23122 return card_type; 23123 } 23124 23125 } 23126 23127 return null; 23128 23129 23130 /** 23131 var re = { 23132 electron: /^(4026|417500|4405|4508|4844|4913|4917)\d+$/, 23133 maestro: /^(5018|5020|5038|5612|5893|6304|6759|6761|6762|6763|0604|6390)\d+$/, 23134 dankort: /^(5019)\d+$/, 23135 interpayment: /^(636)\d+$/, 23136 unionpay: /^(62|88)\d+$/, 23137 visa: /^4[0-9]{12}(?:[0-9]{3})?$/, 23138 mastercard: /^5[1-5][0-9]{14}$/, 23139 amex: /^3[47][0-9]{13}$/, 23140 diners: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/, 23141 discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/, 23142 jcb: /^(?:2131|1800|35\d{3})\d{11}$/ 23143 }; 23144 23145 for(var key in re) { 23146 if(re[key].test(number)) { 23147 return key; 23148 } 23149 } 23150 **/ 23151 23152 } 23153 23154 } 23155 23156})(jQuery); 23157/** 23158 * 23159 * [SOW] Check All 23160 * 23161 * @author Dorin Grigoras 23162 * www.stepofweb.com 23163 * 23164 * @Dependency - 23165 * @Usage $.SOW.core.checkall.init('.checkall'); 23166 * 23167 * 23168 **/ 23169;(function ($) { 23170 'use strict'; 23171 23172 23173 /** 23174 * 23175 * @vars 23176 * 23177 * 23178 **/ 23179 var scriptInfo = 'SOW Check All'; 23180 23181 23182 $.SOW.core.checkall = { 23183 23184 23185 /** 23186 * 23187 * @collection 23188 * 23189 * 23190 **/ 23191 collection: $(), 23192 23193 23194 23195 /** 23196 * 23197 * @init 23198 * 23199 * 23200 **/ 23201 init: function (selector, config) { 23202 23203 var __selector = $.SOW.helper.__selector(selector); 23204 this.selector = __selector[0]; // '#selector' 23205 this.collection = __selector[1]; // $('#selector') 23206 23207 23208 if(jQuery(this.selector).length < 1) 23209 return; 23210 23211 // -- * -- 23212 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 23213 // -- * -- 23214 23215 23216 $.SOW.core.checkall.process(this.collection); 23217 return null; 23218 23219 }, 23220 23221 23222 23223 /** 23224 * 23225 * @process 23226 * 23227 * 23228 **/ 23229 process: function(_this) { 23230 23231 this.collection.on('click', function () { 23232 var _target = jQuery(this).data('checkall-container'); 23233 23234 jQuery(_target + ' input:checkbox').not(this).prop('checked', this.checked); 23235
23236 // when starting to deselect some checboxes, remove checkall 23237 jQuery(_target + ' input:checkbox').bind("click", function () { 23238 23239 if(!jQuery(this).is(":checked")) { 23240 jQuery('input.checkall[data-checkall-container="'+_target+'"]').prop('checked', false); 23241 } 23242 23243 }); 23244 23245 23246 // other checkall 23247 if(jQuery(this).is(":checked")) { 23248 jQuery('input.checkall[data-checkall-container="'+_target+'"]').prop('checked', true); 23249 } else { 23250 jQuery('input.checkall[data-checkall-container="'+_target+'"]').prop('checked', false); 23251 } 23252 23253 }); 23254 23255 }, 23256 23257 23258 }; 23259 23260 23261})(jQuery); 23262/** 23263 * 23264 * [SOW] GDPR 23265 * 23266 * @author Dorin Grigoras 23267 * www.stepofweb.com 23268 * 23269 * @Dependency - 23270 * @Usage $.SOW.core.gdpr.init('#gdpr'); 23271 * 23272 * 23273 **/ 23274;(function ($) { 23275 'use strict'; 23276 23277 23278 /** 23279 * 23280 * @vars 23281 * 23282 * 23283 **/ 23284 var scriptInfo = 'SOW GDPR'; 23285 23286 23287 $.SOW.core.gdpr = { 23288 23289 23290 /** 23291 * 23292 * @config 23293 * 23294 * 23295 **/ 23296 config: { 23297 23298 cookie_name: '__gdpr', 23299 cookie_expire: 365, 23300 cookie_path: $.SOW.globals.cookie_secure, // 'SameSite=None; secure' (Google) 23301 23302 }, 23303 23304 23305 23306 /** 23307 * 23308 * @collection 23309 * 23310 * 23311 **/ 23312 collection: $(), 23313 23314 23315 23316 /** 23317 * 23318 * @init 23319 * 23320 * 23321 **/ 23322 init: function (selector, config) { 23323 23324 var __selector = $.SOW.helper.__selector(selector); 23325 var __config = $.SOW.helper.check_var(config); 23326 23327 this.selector = __selector[0]; // '#selector' 23328 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 23329 23330 23331 if(jQuery(this.selector).length < 1) 23332 return; 23333 23334 23335 // -- * -- 23336 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 23337 // -- * -- 23338 23339 23340 23341 // 1. Has no selector 23342 if(!this.selector) { 23343 $.SOW.core.gdpr.process('#gdpr'); 23344 return this.collection; 23345 } 23346 23347 // 2. Has selector 23348 $.SOW.core.gdpr.process(this.selector); 23349 return this.collection; 23350 23351 }, 23352 23353 23354 23355 /** 23356 * 23357 * @process 23358 * 23359 23360 <!-- 23361 GDPR POPUP 23362 23363 Reset GDPR: 23364 $.SOW.core.gdpr.destroy(); 23365 OR BY HASH: #del:gdpr 23366 23367 By hitting 'Accept' Button, cookie is 0 => all cookies accepted. 23368 23369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 23370 23371 Extend Consent by level: 23372 0 = accept all cookies! 23373 1 = website only 23374 2 = website + advertising 23375 ... more if needed 23376 23377 JS USAGE: 23378 $.SOW.core.gdpr.extend(2); // // allow website + advertising 23379 23380 23381 BACKEND: 23382 Backend should use the cookie specified in config (default: cookie_name: '__gdpr') 23383 23384 --> 23385 <div id="gdpr" class="hide bg-white rounded-lg shadow-lg w-100 max-w-350 p--30 m--15 position-fixed fixed-bottom right-0 z-index-9999"> 23386 23387 <h3 class="fs--18 mb-4"> 23388 23389 <a href="#" class="close mt--n3"> 23390 <span class="fi fi-close fs--18" aria-hidden="true"></span> 23391 </a> 23392 23393 Smarty Cookies 23394 23395 </h3> 23396 23397 <hr> 23398 23399 <p class="lead"> 23400 We use cookies to improve your experience on our site and to show you personalised ads. 23401 </p> 23402 23403 <a href="#" class="btn btn-primary btn-cookie-accept btn-lg btn-block"> 23404 Accept & Continue 23405 </a> 23406 23407 <hr class="mt-4 mb-4"> 23408 23409 <p class="m--0"> 23410 23411 <span class="d-block">Need to learn more?</span> 23412 23413 <a href="#" class="link-muted">Privacy Policy</a> 23414 23415 – and – 23416 23417 <a href="../page/cookie.html" class="link-muted">Cookie Policy</a> 23418 23419 </p> 23420 </div> 23421 <!-- /GDPR POPUP --> 23422 23423 * 23424 **/ 23425 process: function(_selector) { 23426 23427 var __gdpr = Cookies.get($.SOW.core.gdpr.config.cookie_name, { path: $.SOW.core.gdpr.config.cookie_path }); 23428 23429 // -- 23430 23431 // Delete by hash 23432 if(window.location.hash == '#del:gdpr') { 23433 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name+': Hash Request'); 23434 $.SOW.core.gdpr.destroy(); 23435 var __gdpr = null; 23436 } 23437 23438 // -- 23439 23440 if(__gdpr == null) { 23441 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name+': Shown'); 23442 jQuery(_selector).removeClass('hide hide-force'); 23443 } else { 23444 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name+': Refresh'); 23445 Cookies.set($.SOW.core.gdpr.config.cookie_name, __gdpr, { expires: $.SOW.core.gdpr.config.cookie_expire, path: $.SOW.core.gdpr.config.cookie_path }); // refresh 23446 jQuery(_selector).remove(); // just in case 23447 return; 23448 } 23449 23450 // -- 23451 23452 // Accept Button 23453 jQuery(' a.btn-cookie-accept:not(.js-gdprified)').addClass('js-gdprified').on('click', function(e) { 23454 e.preventDefault(); 23455 23456 /* 23457 values: 23458 0 = accept all cookies! 23459 1 = website only 23460 2 = website + advertising 23461 */
23462 Cookies.set($.SOW.core.gdpr.config.cookie_name, 0, { expires: $.SOW.core.gdpr.config.cookie_expire, path: $.SOW.core.gdpr.config.cookie_path }); 23463 jQuery(_selector).remove(); // just in case 23464 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name+': Accepted. Delete cookie by hash: #del:gdpr (developing purpose)'); 23465 23466 }); 23467 23468 // -- 23469 23470 // Extend Button 23471 jQuery('.btn-cookie-extend:not(.js-gdprified)').addClass('js-gdprified').on('click', function(e) { 23472 e.preventDefault(); 23473 23474 var __gdprLevel = jQuery(this).data('cookie-level') || 0; 23475 $.SOW.core.gdpr.extend(__gdprLevel); 23476 23477 }); 23478 23479 // -- 23480 23481 // Close Button 23482 jQuery(' a.close:not(.js-gdprified)').addClass('js-gdprified').on('click', function(e) { 23483 e.preventDefault(); 23484 23485 jQuery(_selector).addClass('hide hide-force'); 23486 23487 }); 23488 23489 }, 23490 23491 23492 23493 23494 /* 23495 Direct Set: 23496 23497 __gdprLevel 23498 0 = accept all cookies! 23499 1 = website only 23500 2 = website + advertising 23501 ... more if needed 23502 23503 Usage: 23504 $.SOW.core.gdpr.extend(2); // allow website + advertising 23505 */ 23506 extend: function(__gdprLevel) { 23507 $.SOW.core.gdpr.destroy(); 23508 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name + ': Level: ' + __gdprLevel); 23509 Cookies.set($.SOW.core.gdpr.config.cookie_name, __gdprLevel, { expires: $.SOW.core.gdpr.config.cookie_expire, path: $.SOW.core.gdpr.config.cookie_path }); 23510 return true; 23511 }, 23512 23513 23514 23515 23516 /** 23517 * 23518 * @destroy 23519 * $.SOW.core.gdpr.destroy(); 23520 * 23521 * 23522 **/ 23523 destroy: function() { 23524 23525 Cookies.remove($.SOW.core.gdpr.config.cookie_name, { path: '' }); 23526 Cookies.remove($.SOW.core.gdpr.config.cookie_name, { path: '/' }); 23527 Cookies.remove($.SOW.core.gdpr.config.cookie_name, { path: $.SOW.core.gdpr.config.cookie_path }); 23528 $.SOW.helper.consoleLog($.SOW.core.gdpr.config.cookie_name + ' : Cookie Deleted'); 23529 return true; 23530 23531 } 23532 23533 23534 }; 23535 23536 23537})(jQuery); 23538/** 23539 * 23540 * [SOW] Sidebar 23541 * 23542 * @author Dorin Grigoras 23543 * www.stepofweb.com 23544 * 23545 * @Dependency - 23546 * @Usage $.SOW.core.sidebar.init(); 23547 * 23548 * 23549 **/ 23550;(function ($) { 23551 'use strict'; 23552 23553 23554 /** 23555 * 23556 * @vars 23557 * 23558 * 23559 **/ 23560 var scriptInfo = 'SOW Sidebar'; 23561 23562 23563 $.SOW.core.sidebar = { 23564 23565 23566 /** 23567 * 23568 * @config 23569 * 23570 * 23571 **/ 23572 config: {}, 23573 23574 23575 23576 /** 23577 * 23578 * @collection 23579 * 23580 * 23581 **/ 23582 collection: $(), 23583 23584 23585 23586 /** 23587 * 23588 * @init 23589 * 23590 * 23591 **/ 23592 init: function (selector, config) { 23593 23594 if(jQuery('aside').length < 1) 23595 return; 23596 23597 // -- * -- 23598 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 23599 // -- * -- 23600 23601 23602 $.SOW.core.sidebar.sidebar_toggle(); 23603 $.SOW.core.sidebar.sidebar_minify(); 23604 $.SOW.core.sidebar.sidebar_extended(); 23605 23606 return this.collection; 23607 23608 }, 23609 23610 23611 23612 /** 23613 * 23614 * @sidebar_toggle 23615 * Mobile show|hide sidebar 23616 * 23617 **/ 23618 sidebar_toggle: function() { 23619 23620 23621 jQuery('.btn-sidebar-toggle').on('click', function(e) { 23622 e.preventDefault(); 23623 23624 var _href = jQuery(this).attr('href') || ''; 23625 23626 if(_href == '' || _href == '#') 23627 return; 23628 23629 jQuery(_href).toggleClass('js-aside-show'); 23630 $.SOW.helper.overlay('toggle'); 23631 23632 jQuery(this).toggleClass('active'); 23633 23634 if( $("#sidebar-toggler").length > 0 ) { 23635 setTimeout(function() { 23636 $("#sidebar-toggler").toggleClass('cross'); 23637 }, 800); 23638 } 23639 23640 // toggle back on overlay click 23641 jQuery('#overlay-default').unbind().on('click', function(e) { 23642 $.SOW.helper.overlay('hide'); 23643 jQuery(_href).removeClass('js-aside-show'); 23644 jQuery('.btn-sidebar-toggle').removeClass('active'); 23645 if( $("#sidebar-toggler").length > 0 ) { 23646 setTimeout(function() { 23647 $("#sidebar-toggler").removeClass('cross'); 23648 }, 800); 23649 } 23650 }); 23651 23652 }); 23653 23654 23655 /** 23656 23657 CLOSE SIDEBAR ON ITEM CLICK 23658 Add to nav: .nav-link-click-close 23659 23660 **/ 23661 if($.SOW.globals.is_mobile === true) { 23662 23663 jQuery('nav.nav-link-click-close a.nav-link').on('click', function() { 23664 var _href = jQuery(this).attr('href'); 23665 23666 if(_href != '#' && _href != '#!' && _href != 'javascript:;') { 23667 $.SOW.helper.overlay('hide'); 23668 jQuery('aside').removeClass('js-aside-show'); 23669 jQuery('.btn-sidebar-toggle').removeClass('active'); 23670 } 23671 23672 }); 23673 23674 } 23675 23676 }, 23677 23678 23679 23680 23681 /** 23682 * 23683 * @sidebar_minify 23684 * href used as a target ID 23685 * 23686 **/ 23687 sidebar_minify: function() { 23688 23689 jQuery('.btn-aside-minify').on('click', function(e) { 23690 e.preventDefault(); 23691 23692 var _href = jQuery(this).attr('href') || ''; 23693 23694 if(_href == '' || _href == '#' || _href == '#!' || _href == 'javascript:;') 23695 return; 23696 23697 $.SOW.globals.elBody.toggleClass('aside-min'); 23698 }); 23699 23700 }, 23701 23702 23703 23704 23705 /** 23706 * 23707 * @sidebar_extended 23708 * 23709 * 23710 **/ 23711 sidebar_extended: function() { 23712 23713 jQuery('.btn-aside-item-extended-close').unbind().on('click', function(e) { 23714 e.preventDefault(); 23715 23716 jQuery(this).parent().closest('.nav-item.active').removeClass('active'); 23717 23718 }); 23719 23720 }, 23721 23722 23723 23724 23725 /** 23726 * 23727 * @sidebar_dispose 23728 * 23729 * 23730 **/ 23731 sidebar_dispose: function() { 23732 23733 jQuery('.btn-sidebar-toggle').unbind('click'); 23734 jQuery('.btn-sidebar-toggle-minify').unbind('click'); 23735 jQuery('.btn-aside-item-extended-close').unbind('click'); 23736 jQuery('.nav-deep .nav-link').unbind('click'); 23737 23738 }, 23739 23740 }; 23741 23742 23743})(jQuery); 23744/** 23745 * 23746 * [SOW] Scroll To 23747 * 23748 * @author Dorin Grigoras 23749 * www.stepofweb.com 23750 * 23751 * @Dependency - 23752 * @Usage $.SOW.core.scroll_to.init('a.scroll-to', {speed:400}); 23753 * 23754 * 23755 **/ 23756;(function ($) { 23757 'use strict'; 23758 23759 23760 /** 23761 * 23762 * @vars 23763 * 23764 * 23765 **/ 23766 var scriptInfo = 'SOW Scroll To'; 23767 23768 23769 $.SOW.core.scroll_to = { 23770 23771 23772 /** 23773 * 23774 * @config 23775 * 23776 * 23777 **/ 23778 config: { 23779 23780 // button scroll to speed 23781 speed: 400, 23782 23783 // scroll 2 top 23784 s2t_enable: true, 23785 s2t_class: 'btn-secondary', 23786 s2t_position: 'end', // start = left, end = right (inverted for RT
23786L) 23787 s2t_mob_minH: 1200, // min. content height to show on mobile 23788 s2t_dsk_minH: 2300, // min. content to show on desktop 23789 // when scrolling, button is shown if currentScroll > minH / 2 23790 23791 }, 23792 23793 23794 23795 /** 23796 * 23797 * @collection 23798 * 23799 * 23800 **/ 23801 collection: $(), 23802 23803 23804 23805 /** 23806 * 23807 * @init 23808 * 23809 * 23810 **/ 23811 init: function (selector, config) { 23812 23813 var __selector = $.SOW.helper.__selector(selector); 23814 var __config = $.SOW.helper.check_var(config); 23815 23816 this.selector = __selector[0]; // '#selector' 23817 this.collection = __selector[1]; // $('#selector') 23818 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 23819 23820 23821 23822 // Scroll to top when user scroll % 23823 if($.SOW.core.scroll_to.config.s2t_enable === true) 23824 $.SOW.core.scroll_to.scrollToTop(); 23825 23826 23827 23828 if(jQuery(this.selector).length < 1) 23829 return; 23830 23831 23832 // -- * -- 23833 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 23834 // -- * -- 23835 23836 23837 // 1. Has no selector 23838 if(!this.selector) { 23839 $.SOW.core.scroll_to.process($('.scroll-to')); 23840 return this.collection; 23841 } 23842 23843 // 2. Has selector 23844 return this.collection.each(function() { 23845 23846 $.SOW.core.scroll_to.process($(this)); 23847 23848 }); 23849 23850 }, 23851 23852 23853 23854 /** 23855 * 23856 * @process 23857 * 23858 23859 <a href="#top" class="scroll-animate">Go to top</a> 23860 <a href="#div_id" class="scroll-animate">Go to a section</a> 23861 23862 * 23863 **/ 23864 process: function(_this) { 23865 23866 var config_speed = this.config.speed; 23867 23868 // SCROLL TO [LINK] 23869 _this.not('.js-scrolltoified').addClass('js-scrolltoified').on("click", function(e) { 23870 e.preventDefault(); 23871 23872 var _t = jQuery(this), 23873 _href = _t.attr('href') || '', 23874 _offset = _t.data('offset') || 0, 23875 _toggle = _t.data('toggle') || '', 23876 _expanded = _t.attr('aria-expanded') || '', 23877 _hash = _t.data('update-hash') || 'false', 23878 _speed = _t.data('speed') || config_speed, 23879 _delay = _t.data('delay') || 0; 23880 23881 23882 // add a delay if this has also a collapse option 23883 if(_toggle == 'collapse') 23884 _delay = (_delay > 0) ? _delay : 300; // bootstrap default is 400 23885 23886 // Scroll (helper.js) 23887 if(typeof $.SOW.helper.scrollAnimate === "function") { 23888 23889 setTimeout(function() { 23890 23891 // stop on collapse back 23892 // if(_toggle == 'collapse' && _expanded != '') 23893 if(_t.hasClass('collapsed')) 23894 return; 23895 23896 $.SOW.helper.scrollAnimate(_href, _offset, _hash, _speed); 23897 23898 }, Number(_delay) ); 23899 23900 } 23901 23902 }); 23903 23904 }, 23905 23906 23907 23908 /** 23909 * 23910 * @scroll to top 23911 * 23912 * 23913 **/ 23914 scrollToTop: function() { 23915 23916 23917 // reset always on load 23918 if(window.sowScrollToInterval !== null) { 23919 clearInterval(window.sowScrollToInterval); 23920 window.sowScrollToInterval = null; 23921 23922 jQuery('#btnScrollTo').remove(); 23923 } 23924 23925 23926 23927 // Different for mobile/desktop 23928 var minInitHeight = $.SOW.globals.is_mobile === true ? $.SOW.core.scroll_to.config.s2t_mob_minH : $.SOW.core.scroll_to.config.s2t_dsk_minH; 23929 23930 23931 // do not init on short content 23932 if($(document).height() < minInitHeight) 23933 return; 23934 23935 23936 var _pos = $.SOW.globals.elBody.data('s2t-position') || $.SOW.core.scroll_to.config.s2t_position; 23937 var _cls = $.SOW.globals.elBody.data('s2t-class') || $.SOW.core.scroll_to.config.s2t_class; 23938 var _dis = $.SOW.globals.elBody.data('s2t-disable') || 'false'; 23939 23940 if(_dis+'' == 'true') 23941 return; 23942 23943 23944 // Disable on admin ; Enable only if specified: 23945 // data-s2t-disable="false" 23946 if($.SOW.globals.elBody.hasClass('layout-admin') && _dis+'' != 'false') 23947 return; 23948 23949 23950 // Is admin and has Footer 23951 var takeCareOfAdminFooter = false; 23952 if($.SOW.globals.elBody.hasClass('layout-admin') && jQuery('#footer').length > 0) { 23953 23954 var footerPos = 0; 23955 var tookCare = false; 23956 var btnScrollToMargins = 0; 23957 var footerHeight = jQuery('#footer').outerHeight(); 23958 23959 if(footerHeight < 200) { 23960 var takeCareOfAdminFooter = true; 23961 var footerPos = $('#footer').offset().top; 23962 var btnScrollToMargins = footerHeight + 15 + Number($.SOW.globals.elBody.css('padding').replace("px", "") || 0) + Number($.SOW.globals.elBody.css('margin').replace("px", "") || 0); 23963 } 23964 23965 } 23966 23967 23968 // Create Element 23969 $.SOW.globals.elBody.append('<a aria-label="Scroll page to top" href="#" id="bt
23969nScrollTo" class="btn ' + _cls + ' position-fixed z-index-99 ' + _pos + '-0 bottom-0 m-2" style="display:none"><i class="m-0 fi fi-arrow-up"></i></a>'); 23970 23971 23972 // bind click 23973 jQuery('#btnScrollTo').off().on('click', function(e) { 23974 e.preventDefault(); 23975 $.SOW.helper.scrollAnimate('body', 0, false, 500); 23976 }); 23977 23978 23979 var appearAtMin = minInitHeight / 2; 23980 window.isVisibleBtnScrollTo = false; 23981 var scrolling = false; 23982 var currScrollPos = 0; 23983 23984 $(window).scroll(function() { 23985 scrolling = true; 23986 currScrollPos = $(this).scrollTop(); 23987 }); 23988 23989 window.sowScrollToInterval = setInterval( function() { 23990 23991 if(scrolling) { 23992 scrolling = false; 23993 23994 23995 if (currScrollPos > appearAtMin) { 23996 23997 if(window.isVisibleBtnScrollTo === false) { 23998 window.isVisibleBtnScrollTo = true; 23999 jQuery('#btnScrollTo').fadeIn(400); 24000 } 24001 24002 } else { 24003 24004 if(window.isVisibleBtnScrollTo === true) { 24005 window.isVisibleBtnScrollTo = false; 24006 jQuery('#btnScrollTo').fadeOut(200); 24007 } 24008 24009 } 24010 24011 24012 // Admin footer : fix 24013 if(takeCareOfAdminFooter === true) { 24014 if(currScrollPos + $.SOW.globals.height > footerPos) { 24015 if(tookCare === false) { 24016 jQuery('#btnScrollTo').addClass('transition-all-ease-250').attr('style', "margin-bottom: "+ btnScrollToMargins +"px !important"); 24017 tookCare = true; 24018 } 24019 } else { 24020 if(tookCare === true) { 24021 jQuery('#btnScrollTo').css({"margin-bottom":""}); 24022 tookCare = false; 24023 } 24024 } 24025 } 24026 24027 } 24028 24029 }, 500); 24030 24031 24032 } 24033 24034 }; 24035 24036 24037})(jQuery); 24038/** 24039 * 24040 * [SOW] Inline Search 24041 * 24042 * @author Dorin Grigoras 24043 * www.stepofweb.com 24044 * 24045 * @Dependency - 24046 * @Usage $.SOW.core.search_inline.init('input.iqs-input'); 24047 * 24048 * 24049 **/ 24050;(function ($) { 24051 'use strict'; 24052 24053 24054 /** 24055 * 24056 * @vars 24057 * 24058 * 24059 **/ 24060 var scriptInfo = 'SOW Inline Search'; 24061 24062 24063 $.SOW.core.search_inline = { 24064 24065 24066 /** 24067 * 24068 * @config 24069 * 24070 * 24071 **/ 24072 config: {}, 24073 24074 24075 24076 /** 24077 * 24078 * @collection 24079 * 24080 * 24081 **/ 24082 collection: $(), 24083 24084 24085 24086 /** 24087 * 24088 * @init 24089 * 24090 * 24091 **/ 24092 init: function (selector, config) { 24093 24094 var __selector = $.SOW.helper.__selector(selector); 24095 var __config = $.SOW.helper.check_var(config); 24096 24097 this.selector = __selector[0]; // '#selector' 24098 this.collection = __selector[1]; // $('#selector') 24099 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 24100 24101 24102 if(jQuery(this.selector).length < 1) 24103 return; 24104 24105 24106 /* Case Sensitive :contains */ 24107 jQuery.extend(jQuery.expr[":"], { 24108 "containsIN": function(elem, i, match, array) { 24109 return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0; 24110 } 24111 }); 24112 24113 24114 24115 // -- * -- 24116 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 24117 // -- * -- 24118 24119 24120 // 1. Has no selector 24121 if(!this.selector) { 24122 $.SOW.core.search_inline.process($('input.iqs-input')); 24123 return this.collection; 24124 } 24125 24126 // 2. Has selector 24127 return this.collection.each(function() { 24128 24129 $.SOW.core.search_inline.process($(this)); 24130 24131 }); 24132 24133 }, 24134 24135 24136 24137 /** 24138 * 24139 * @process 24140 * 24141 24142 <input type="text" class="form-control iqs-input" data-container=".iqs-container" name="quick-filter" value="" placeholder="quick filter"> 24143 24144 <div class="iqs-container"> 24145 24146 <div class="iqs-item"> 24147 <span>Something Here</span> 24148 </div> 24149 24150 </div> 24151 24152 * 24153 * 24154 **/ 24155 process: function(_this) { 24156 24157 var _container = _this.data('container') || '.iqs-container'; 24158 24159 _this.keyup(function() { 24160 24161 var keywords = jQuery.trim(this.value); 24162 24163 if (keywords == "") { 24164 24165 jQuery(_container+" .iqs-item").removeClass('hide hide-force'); 24166 24167 } else { 24168 24169 jQuery(_container+" .iqs-item").addClass('hide hide-force'); 24170 jQuery(_container+' .iqs-item :containsIN('+keywords+')').closest(".iqs-item").removeClass('hide hide-force'); 24171 24172 } 24173 24174 }); 24175 24176 }, 24177 24178 }; 24179 24180 24181})(jQuery); 24182/** 24183 * 24184 * [SOW] Timer Autohide 24185 * 24186 * @author Dorin Grigoras 24187 * www.stepofweb.com 24188 * 24189 * @Dependency - 24190 * @Usage $.SOW.core.timer_autohide.init('.timer-autohide'); 24191 24192 <div class="timer-autohide" data-timer-autohide="4000">...</div> 24193 24194 * 24195 * 24196 **/ 24197;(function ($) { 24198 'use strict'; 24199 24200 24201 /** 24202 * 24203 * @vars 24204 * 24205 * 24206 **/ 24207 var scriptInfo = 'SOW Timer Autohide'; 24208 24209 24210 $.SOW.core.timer_autohide = { 24211 24212 24213 /** 24214 * 24215 * @config 24216 * 24217 * 24218 **/ 24219 config: {}, 24220 24221 24222 24223 /** 24224 * 24225 * @collection 24226 * 24227 * 24228 **/ 24229 collection: $(), 24230 24231 24232 24233 /** 24234 * 24235 * @init 24236 * 24237 * 24238 **/ 24239 init: function (selector, config) { 24240 24241 var __selector = $.SOW.helper.__selector(selector); 24242 var __config = $.SOW.helper.check_var(config); 24243 24244 this.selector = __selector[0]; // '#selector' 24245 this.collection = __selector[1]; // $('#selector') 24246 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 24247 24248 24249 if(jQuery(this.selector).length < 1) 24250 return; 24251 24252 24253 // -- * -- 24254 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 24255 // -- * -- 24256 24257 24258 // 1. Has no selector 24259 if(!this.selector) { 24260 $.SOW.core.timer_autohide.process($('.autohide')); 24261 return this.collection; 24262 } 24263 24264 // 2. Has selector 24265 return this.collection.each(function() { 24266 24267 $.SOW.core.timer_autohide.process($(this)); 24268 24269 }); 24270 24271 }, 24272 24273 24274 24275 /** 24276 * 24277 * @process 24278 * 24279 24280 <div data-autohide="3000"> 24281 .... 24282 </div> 24283 * 24284 **/ 24285 process: function(_this) { 24286 24287 24288 var _time = _this.data('timer-autohide') || 0; 24289 24290 if(_time < 1) 24291 return; 24292 24293 24294 setTimeout(function() { 24295 24296 _this.fadeOut(100, function() { 24297 // _this.remove(); 24298 }); 24299 24300 }, Number(_time)); 24301 24302 }, 24303 24304 24305 }; 24306 24307 24308})(jQuery); 24309/** 24310 *
24311 * [SOW] Timer Countdown 24312 * 24313 * @author Dorin Grigoras 24314 * www.stepofweb.com 24315 * 24316 * @Dependency - 24317 * @Usage $.SOW.core.timer_countdown.init('.timer-countdown'); 24318 * 24319 * 24320 **/ 24321;(function ($) { 24322 'use strict'; 24323 24324 24325 /** 24326 * 24327 * @vars 24328 * 24329 * 24330 **/ 24331 var scriptInfo = 'SOW Timer Countdown'; 24332 window.timeleft = []; 24333 window._timerInterval = []; 24334 24335 24336 $.SOW.core.timer_countdown = { 24337 24338 24339 /** 24340 * 24341 * @config 24342 * 24343 * 24344 **/ 24345 config: {}, 24346 24347 24348 24349 /** 24350 * 24351 * @collection 24352 * 24353 * 24354 **/ 24355 collection: $(), 24356 24357 24358 24359 /** 24360 * 24361 * @init 24362 * 24363 * 24364 **/ 24365 init: function (selector, config) { 24366 24367 var __selector = $.SOW.helper.__selector(selector); 24368 var __config = $.SOW.helper.check_var(config); 24369 24370 this.selector = __selector[0]; // '#selector' 24371 this.collection = __selector[1]; // $('#selector') 24372 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 24373 24374 if(jQuery(this.selector).length < 1) 24375 return; 24376 24377 24378 // -- * -- 24379 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 24380 // -- * -- 24381 24382 24383 // 1. Has no selector 24384 if(!this.selector) { 24385 $.SOW.core.timer_countdown.process($('.timer-countdown')); 24386 return this.collection; 24387 } 24388 24389 // 2. Has selector 24390 return this.collection.each(function() { 24391 24392 $.SOW.core.timer_countdown.process($(this)); 24393 24394 }); 24395 24396 }, 24397 24398 24399 24400 /** 24401 * 24402 * @process 24403 * 24404 * 24405 **/ 24406 process: function(_this) { 24407 24408 var _time = _this.data('timer-countdown-from') || '', 24409 _inline = _this.hasClass('timer-countdown-inline') ? true : false, 24410 _elID = _this.attr('id') || ''; 24411 24412 if(_time == '') 24413 return; 24414 24415 24416 // Remove hide class if exist 24417 _this.removeClass('hide hide-force'); 24418 24419 var _rand = 'rand_' + $.SOW.helper.randomStr(8); 24420 24421 // if element has no id, add one 24422 if(_elID == '') { 24423 var _elID = _rand; 24424 _this.attr('id', _rand); 24425 } 24426 24427 24428 // Numeric - milisseconds|seconds passed 24429 if(typeof _time === 'number') { 24430 24431 // Calculate in seconds and set initial time left 24432 window.timeleft[_elID] = (_time > 1000) ? Math.round(_time / 1000) : Math.round(_time); 24433 24434 } else { 24435 24436 var _time = _time.trim(), 24437 __dateNow = new Date(), 24438 __dateFuture = new Date(_time), 24439 offset = __dateFuture.getTimezoneOffset() * 60 * 1000, 24440 24441 withOffset = __dateFuture.getTime(), 24442 withoutOffset = withOffset - offset, 24443 _msRemains = withOffset - __dateNow; 24444 24445 24446 window.timeleft[_elID] = Math.round(_msRemains / 1000); 24447 24448 } 24449 24450 24451 /* 24452 Date is in the past, no time left! 24453 Stop here, to avoid callback 24454 */ 24455 if(window.timeleft[_elID] < 1) 24456 return; 24457 24458 24459 // Show time before starting 24460 $.SOW.core.timer_countdown.timer_compute(_this, _elID, _inline, false); 24461 24462 // Start loop, each second 24463 window._timerInterval[_elID] = setInterval(function() { 24464 24465 $.SOW.core.timer_countdown.timer_compute(_this, _elID, _inline, true); 24466 24467 }, 1000); 24468 24469 24470 }, 24471 24472 24473 24474 24475 /** 24476 * 24477 * @timer_compute 24478 * 24479 * 24480 **/ 24481 timer_compute: function(_this, _elID, _inline, _calledByInterval) { 24482 24483 // If page switched by ajax or element removed, 24484 // the loop goes on and callback is fired 24485 // we avoid this by checking the element 24486 var __elID = _this.attr('id'); 24487 if(jQuery('#'+__elID).length < 1) { 24488 $.SOW.core.timer_countdown.timer_compute_stop(_elID); 24489 return; 24490 } 24491 24492 24493 24494 // Time end! 00:00:00 24495 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24496 if(window.timeleft[_elID] < 0) { 24497 24498 // Stop loop! 24499 $.SOW.core.timer_countdown.timer_compute_stop(_elID); 24500 24501 var _callback = _this.data('timer-countdown-callback-function') || '', 24502 _endSelfHide = _this.data('timer-countdown-end-hide-self') || false, 24503 _endTargetHide = _this.data('timer-countdown-end-hide-target') || ''; 24504 24505 24506 // Self hide 24507 if(_endSelfHide == true) 24508 _this.addClass('hide hide-force'); 24509 24510 // Another container (or more separated by space) hide 24511 if(_endTargetHide != '') 24512 jQuery(_endTargetHide).addClass('hide hide-force'); 24513 24514 24515 24516 // custom callback function 24517 if(_callback != '' && _calledByInterval === true) { 24518 24519 // get element id or assign a random one 24520 var _elID = _this.attr('id') || ''; 24521 $.SOW.helper.executeFunctionByName(_callback, window, _elID); 24522 24523 } 24524 24525 return false;
24526 } 24527 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24528 24529 24530 24531 // Compute output format time like 00:00:50 24532 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24533 var __date = new Date(null); 24534 __date.setSeconds(window.timeleft[_elID]); 24535 24536 var timeString = __date.toISOString().substr(11, 8); 24537 var daysleft = $.SOW.helper.time_from_ms(window.timeleft[_elID] * 1000, 'd'); 24538 24539 if(daysleft > 0) { 24540 var _cutHours = timeString.substr(0, 2); 24541 var _addedDaysHours = Number(_cutHours) + daysleft * 24; 24542 var timeString = _addedDaysHours + timeString.substr(2, 8); 24543 } 24544 24545 24546 // update timeleft 24547 window.timeleft[_elID] = Math.round(window.timeleft[_elID] - 1); 24548 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24549 24550 24551 if(_inline === true) 24552 $.SOW.core.timer_countdown.timer2html(_this, timeString); 24553 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24554 24555 24556 // update element 24557 else _this.html(timeString); 24558 24559 }, 24560 24561 24562 24563 24564 /** 24565 * 24566 * @timer_compute_stop 24567 * 24568 * 24569 **/ 24570 timer_compute_stop: function(_elID) { 24571 24572 // Stop loop! 24573 if(_elID) 24574 clearInterval(window._timerInterval[_elID]); 24575 24576 return true; 24577 }, 24578 24579 24580 24581 24582 /** 24583 * 24584 * @timer2html 24585 * 24586 * 24587 **/ 24588 timer2html: function(_this, timeString) { 24589 // return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); // working: return true if bisect year! 24590 24591 if(timeString == '00:00:00') 24592 return; 24593 24594 24595 var _timeSplit = timeString.split(':'), 24596 _hours = 0, 24597 _days = 0, 24598 _years = 0; 24599 24600 24601 // calc no of days 24602 if(_timeSplit[0] >= 24) { 24603 _days = Math.floor(_timeSplit[0] / 24); // round always down 24604 _hours = Math.floor(_timeSplit[0] % 24); // round always down 24605 } 24606 24607 // calc no of years 24608 if(_days >= 365) 24609 _years = Math.floor(_days / 365); // round always down 24610 24611 24612 24613 // update dom 24614 jQuery('.s', _this).text(_timeSplit[2]); // seconds 24615 jQuery('.m', _this).text(_timeSplit[1]); // minutes 24616 jQuery('.h', _this).text(_hours); // hours 24617 jQuery('.d', _this).text(_days); // days 24618 jQuery('.y', _this).text(_years); // years 24619 24620 24621 } 24622 24623 24624 }; 24625 24626 24627})(jQuery); 24628/** 24629 * 24630 * [SOW] Google Font 24631 * 24632 * @author Dorin Grigoras 24633 * www.stepofweb.com 24634 * 24635 * @Dependency - 24636 * @Usage $.SOW.core.gfont.init('[data-gfont]'); 24637 * 24638 * 24639 **/ 24640;(function ($) { 24641 'use strict'; 24642 24643 24644 /** 24645 * 24646 * @vars 24647 * 24648 * 24649 **/ 24650 var scriptInfo = 'SOW Google Font'; 24651 24652 24653 $.SOW.core.gfont = { 24654 24655 24656 /** 24657 * 24658 * @config 24659 * 24660 * 24661 **/ 24662 config: {}, 24663 24664 24665 24666 /** 24667 * 24668 * @collection 24669 * 24670 * 24671 **/ 24672 collection: $(), 24673 24674 24675 24676 /** 24677 * 24678 * @init 24679 * 24680 * 24681 **/ 24682 init: function (selector, config) { 24683 24684 var __selector = $.SOW.helper.__selector(selector); 24685 var __config = $.SOW.helper.check_var(config); 24686 24687 this.selector = __selector[0]; // '#selector' 24688 this.collection = __selector[1]; // $('#selector') 24689 this.config = (__config !== null) ? $.extend({}, this.config, __config) : this.config; 24690 24691 24692 if(jQuery(this.selector).length < 1) 24693 return; 24694 24695 24696 // -- * -- 24697 $.SOW.helper.consoleLog('Init : ' + scriptInfo); 24698 // -- * -- 24699 24700 24701 // 1. Has no selector 24702 if(!this.selector) { 24703 $.SOW.core.gfont.process($('[data-gfont]')); 24704 return this.collection; 24705 } 24706 24707 // 2. Has selector 24708 return this.collection.each(function() { 24709 24710 $.SOW.core.gfont.process($(this)); 24711 24712 }); 24713 24714 }, 24715 24716 24717 24718 /** 24719 * 24720 * @process 24721 * 24722 * 24723 **/ 24724 process: function(_this) { 24725 24726 if(_this.hasClass('js-gfontified')) 24727 return; 24728 24729 var _font = _this.data('gfont') || ''; 24730 24731 if(_font == '') 24732 return; 24733 24734 _this.addClass('js-gfontified'); 24735 var _gfont = _font.replace(/ /g, '+'); 24736 var _cssID = _font.replace(/ /g, '_').toLowerCase(); 24737 var _rand = $.SOW.helper.randomStr(3, 'L'); 24738 var _lnk = 'https://fonts.googleapis.com/css?family='+_gfont+':300,400,500,700&display=swap'; 24739 var _el = jQuery('head #'+_cssID); 24740 24741 if(_el.length > 0) { 24742 var _class = _el.data('class'); 24743 _this.addClass(_class); 24744 return; 24745 } 24746 24747 jQuery('head').append('<link id="'+_cssID+'" data-class="gfont_'+_rand+'" href="'+_lnk+'" rel="stylesheet">') 24748 .append('<style type="text/css">' 24749 + ".gfont_"+_rand+" { font-family: '"+_font+"', sans-serif !important; }" 24750 +'</style>'); 24751 24752 _this.addClass("gfont_"+_rand); 24753 24754 }, 24755 24756 24757 }; 24758 24759 24760})(jQuery); 24761/** 24762 * 24763 * [SOW] Utils 24764 * 24765 * @author Dorin Grigoras 24766 * www.stepofweb.com 24767 * 24768 * @Dependency - 24769 * @Usage $.SOW.core.utils.init(); 24770 * 24771 * 24772 **/ 24773;(function ($) { 24774 'use strict'; 24775 24776 24777 /** 24778 * 24779 * @vars 24780 * 24781 * 24782 **/ 24783 var scriptInfo = 'SOW Utils'; 24784 var timeAgoList = []; 24785 var slideshowList = {}; 24786 24787 $.SOW.core.utils = { 24788 24789 24790 /** 24791 * 24792 * @config 24793 * 24794 * 24795 **/ 24796 config: { 24797 24798 // selectors 24799 selector__initialFromString : '.sow-util-initials', 24800 selector__timeAgo : '.sow-util-timeago', 24801 selector__cookie : '.sow-util-cookie', 24802 selector__slideshow : '.sow-util-slideshow', 24803 24804 24805 lang__timeAgo : { 24806 seconds : "less than a minute ago", 24807 minute : "about a minute ago", 24808 minutes : "%d minutes ago", 24809 hour : "about an hour ago", 24810 hours : "about %d hours ago", 24811 day : "a day ago", 24812 days : "%d days ago", 24813 month : "about a month ago", 24814 months : "%d months ago", 24815 year : "about a year ago", 24816 years : "%d years ago" 24817 }, 24818 }, 24819 24820 24821 24822 /** 24823 * 24824 * @init 24825 * 24826 * 24827 **/ 24828 init: function (selector, config) { 24829 24830 var __selector = $.SOW.helper.__selector(selector); 24831 this.selector = __selector[0]; // '#selector' 24832 24833 // Initials from a string [name] 24834 $.SOW.core.utils.initialsFromString(this.selector+' '+$.SOW.core.utils.config.selector__initialFromString); 24835 24836 // Time Ago 24837 $.SOW.core.utils.timeAgo(this.selector+' '+$.SOW.core.utils.config.selector__timeAgo); 24838 24839 // Cookies 24840 $.SOW.core.utils.cookieUtil(this.selector+' '+$.SOW.core.utils.config.selector__cookie); 24841
24842 // Background Slideshow 24843 $.SOW.core.utils.slideshow(this.selector+' '+$.SOW.core.utils.config.selector__slideshow); 24844 24845 24846 return null; 24847 24848 }, 24849 24850 24851 24852 /** 24853 * 24854 * @initialsFromString 24855 * 24856 * 24857 **/ 24858 initialsFromString: function(selector) { 24859 24860 var el = jQuery(selector), 24861 loaded = false; 24862 24863 if(el.length < 1) 24864 return; 24865 24866 24867 el.not('.js-sowformstringified').addClass('js-sowformstringified').each(function(selector) { 24868 24869 var _t = jQuery(this), 24870 fullName = _t.data('initials') || '', 24871 assignColor = jQuery(this).attr('data-assign-color') || 'false'; 24872 24873 if(fullName == '') 24874 return false; 24875 24876 24877 // Assign color by name 24878 if(assignColor+'' == 'true') { 24879 24880 var hash = 0, 24881 s = 70, // saturation 24882 l = 90; // lightness 24883 24884 for (var i = 0; i < fullName.length; i++) { 24885 hash = fullName.charCodeAt(i) + ((hash << 5) - hash); 24886 } 24887 24888 var h = hash % 360; 24889 _t.removeClass('bg-light').css({"background":'hsl('+h+', '+s+'%, '+l+'%)'}); 24890 24891 } 24892 24893 24894 // Extract Initials 24895 var initials = fullName.match(/\b\w/g) || []; 24896 initials = ((initials.shift() || '') + (initials.pop() || '')).toUpperCase(); 24897 24898 24899 // Push & remove ununsed! 24900 _t.text(initials).removeAttr('data-initials data-assign-color'); 24901 loaded = true; 24902 24903 }); 24904 24905 24906 // -- * -- 24907 if(loaded === true) 24908 $.SOW.helper.consoleLog('Init : ' + scriptInfo + ' : Initials From String'); 24909 // -- * -- 24910 24911 }, 24912 24913 24914 24915 24916 /** 24917 * 24918 * @timeAgo 24919 * inspired from jQuery timeago 24920 * https://timeago.yarp.com/jquery.timeago.js 24921 * 24922 * 24923 **/ 24924 timeAgo: function(selector) { 24925 24926 var el = jQuery(selector), 24927 loaded = false; 24928 24929 if(el.length < 1) 24930 return; 24931 24932 /** 24933 24934 You can also set once an empty element if you have many timeago's. 24935 Example: <span class="sow-util-timeago-lang" data-lang-timeago='{}'> 24936 Set it anywhere - bottom, etc! 24937 24938 **/ 24939 var langBySpan = jQuery('span.sow-util-timeago-lang').data('lang') || ''; 24940 if(typeof langBySpan === 'object') 24941 $.SOW.core.utils.config.lang__timeAgo = langBySpan; 24942 24943 if(typeof sow_util_timeago_lang === 'object') 24944 $.SOW.core.utils.config.lang__timeAgo = sow_util_timeago_lang; 24945 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 24946 24947 24948 el.not('.js-sowtimeagofied').addClass('js-sowtimeagofied').each(function(selector) { 24949 24950 var _t = jQuery(this), 24951 time = _t.data('time') || _t.attr('datetime'), 24952 live = _t.attr('live') || 'false', 24953 lang = _t.data('lang') || '', 24954 ID = _t.attr('id') || ''; 24955 24956 if(!time) 24957 return 24958 24959 if(typeof lang === 'object') 24960 $.SOW.core.utils.config.lang__timeAgo = lang; 24961 24962 if(ID == '') { 24963 var ID = 'rand_' + $.SOW.helper.randomStr(3, 'N'); 24964 _t.attr('id', ID); 24965 } 24966 24967 24968 $.SOW.core.utils.timeAgoLooper(_t, ID); // on load 24969 24970 // update time every minute 24971 if(live+'' == 'true') { 24972 timeAgoList[ID] = setInterval(function() { 24973 $.SOW.core.utils.timeAgoLooper(_t, ID); 24974 }, 60000); 24975 } 24976 24977 loaded == true; 24978 24979 }); 24980 24981 24982 // -- * -- 24983 if(loaded === true) 24984 $.SOW.helper.consoleLog('Init : ' + scriptInfo + ' : Time Ago'); 24985 // -- * -- 24986 24987 }, 24988 timeAgoLooper: function(_t, ID) { 24989 24990 var time = _t.data('time') || _t.attr('datetime'); 24991 var templates = $.SOW.core.utils.config.lang__timeAgo; 24992 var template = function (t, n) { 24993 return templates[t] && templates[t].replace(/%d/i, Math.abs(Math.round(n))); 24994 }; 24995 24996 // parse iso8601 24997 if(typeof time === 'string') { // timestamp skipped! 24998 24999 time = time.replace(/\.\d+/,""); // remove milliseconds 25000 time = time.replace(/-/,"/").replace(/-/,"/"); 25001 time = time.replace(/T/," ").replace(/Z/," UTC"); 25002 time = time.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 25003 time = time.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900 25004 25005 } 25006 25007 var time = new Date(time * 1000 || time); 25008 var now = new Date(); 25009 var seconds = ((now.getTime() - time) * .001) >> 0; 25010 var minutes = seconds / 60; 25011 var hours = minutes / 60; 25012 var days = hours / 24; 25013 var years = days / 365; 25014 var finalTime = (seconds < 45 && template('seconds', seconds) || seconds < 90 && template('minute', 1) || minutes < 45 && template('minutes', minutes) || minutes < 90 && template('hour', 1) || hours < 24 && template('hours', hours) || hours < 42 && template('day', 1) || days < 30 && template('days', days) || days < 45 && template('month', 1) || days < 365 && template('months', days / 30) || years < 1.5 && template('year', 1) || template('years', years)); 25015 25016 // Update 25017 _t.text(finalTime); 25018
25019 // Do not refresh too old! 25020 if(typeof timeAgoList[ID] !== 'undefined' && (days > 3 || years > 1)) 25021 clearInterval(timeAgoList[ID]); 25022 25023 }, 25024 25025 25026 25027 25028 /** 25029 * 25030 * @cookieUtil 25031 * 25032 * 25033 **/ 25034 cookieUtil: function(selector) { 25035 25036 var el = jQuery(selector); 25037 25038 if(el.length < 1) 25039 return; 25040 25041 25042 el.not('.js-sowcookiefied').addClass('js-sowcookiefied').on('click', function(e) { 25043 e.preventDefault(); 25044 25045 var _t = jQuery(this), 25046 _set = _t.data('cookie-set') || '', 25047 _del = _t.data('cookie-del') || '', 25048 _toggle = _t.data('cookie-toggle') || '', 25049 _val = _t.data('cookie-val') || '1', 25050 _expire = _t.data('cookie-expire') || '7', 25051 _path = _t.data('cookie-path') || $.SOW.globals.cookie_secure, 25052 toastMsgSet = _t.data('toast-msg-set') || '', 25053 toastMsgDel = _t.data('toast-msg-del') || '', 25054 toastMsgPos = _t.data('toast-msg-pos') || 'top-center', 25055 toastTypeSet = _t.data('toast-msg-type-set') || 'success', 25056 toastTypeDel = _t.data('toast-msg-type-del') || 'success', 25057 toastMsg = '', 25058 toastType = ''; 25059 25060 25061 // SET 25062 if(_set != '') { 25063 Cookies.set(_set, _val, { expires: _expire, path: _path }); 25064 toastMsg = toastMsgSet; 25065 toastType = toastTypeSet; 25066 } 25067 25068 25069 // DEL 25070 else if(_del != '') { 25071 Cookies.remove(_del, { path: _path }); 25072 toastMsg = toastMsgDel; 25073 toastType = toastTypeDel; 25074 } 25075 25076 25077 // TOGGLE 25078 else if(_toggle != '') { 25079 var chkCookie = Cookies.get(_toggle, { path: _path }); 25080 25081 if(!chkCookie) { 25082 Cookies.set(_toggle, _val, { expires: _expire, path: _path }); 25083 toastMsg = toastMsgSet; 25084 toastType = toastTypeSet; 25085 } else { 25086 Cookies.remove(_toggle, { path: _path }); 25087 toastMsg = toastMsgDel; 25088 toastType = toastTypeDel; 25089 } 25090 } 25091 25092 25093 // TOAST MESSAGE 25094 if(toastMsg != '' && typeof $.SOW.core.toast === 'object') { 25095 $.SOW.core.toast.destroy(); 25096 $.SOW.core.toast.show(toastType, '', toastMsg, toastMsgPos, 1500, true); 25097 } 25098 25099 25100 }); 25101 25102 }, 25103 25104 25105 25106 25107 25108 /** 25109 * 25110 * @slideshow 25111 * 25112 * 25113 **/ 25114 slideshow: function(selector) { 25115 25116 var el = jQuery(selector), 25117 loaded = false; 25118 25119 if(el.length < 1) 25120 return; 25121 25122 el.each(function() { 25123 25124 var _t = jQuery(this), 25125 dataBgs = _t.data('sow-slideshow') || '', 25126 dataBgsXs = _t.data('sow-slideshow-xs') || '', 25127 dataInterval = _t.data('sow-slideshow-interval') || 4000, 25128 dataFadeDelay = _t.data('sow-slideshow-fade-delay') || 1500, 25129 slideRand = 'sow_'+$.SOW.helper.randomStr(3, 'L'); 25130 25131 25132 // Is Mobile! 25133 if($.SOW.globals.is_mobile === true && dataBgsXs.length > 10) 25134 dataBgs = dataBgsXs; 25135 25136 // should be a long string 25137 if(dataBgs.length < 10) 25138 return false; 25139 25140 // remove attribute, already got! 25141 _t.removeAttr('data-sow-slideshow'); 25142 25143 // create a container, just to izolate stuff! 25144 _t.prepend('<div id="'+slideRand+'" class="sow-slideshow absolute-full z-index-0"></div>'); 25145 25146 // Split by comma 25147 var arrImgs = dataBgs.split(','); 25148 25149 // Create array! Avoid checking the DOM each time! 25150 slideshowList[slideRand] = {}; 25151 slideshowList[slideRand].current = 0; 25152 slideshowList[slideRand].itemsCount = 0; 25153 slideshowList[slideRand].timeOutInstance; 25154 25155 // Create each item and push it to the container 25156 for(var i = 0; i < arrImgs.length; i++) { 25157 var _class_ = (i === 0) ? 'sow-slideshow-current' : ''; 25158 var _display_ = (i === 0) ? '' : 'display:none;'; 25159 25160 25161 var imgInstance = new Image(); 25162 imgInstance.src = arrImgs[i]; 25163 imgInstance.onload = function(e) {/* on load - nothing */} 25164 imgInstance.onerror = function(e) {/* on error - nothing */} 25165 25166 jQuery('#'+slideRand).prepend('<span class="sow-slideshow-item sow-slideshow-item-'+i+' absolute-full bg-cover ' + _class_ + '" style="z-index:0;'+_display_+'background-image:url(' + imgInstance.src + ')"></span>'); 25167 slideshowList[slideRand].itemsCount++; 25168 } 25169 25170 // no images - no loop needed! 25171 // first image is already visible! 25172 if(arrImgs.length < 2) 25173 return false;
25174 25175 25176 // Looper start! 25177 slideLooper(); 25178 function slideLooper() { 25179 slideshowList[slideRand].timeOutInstance = setTimeout(function () { 25180 25181 // determine next image 25182 var next = slideshowList[slideRand].current + 1; 25183 if(next >= slideshowList[slideRand].itemsCount) 25184 next = 0; 25185 25186 jQuery('#'+slideRand+' span.sow-slideshow-item-'+slideshowList[slideRand].current).fadeOut(dataFadeDelay); 25187 jQuery('#'+slideRand+' span.sow-slideshow-item-'+next).fadeIn(dataFadeDelay); 25188 slideshowList[slideRand].current = next; 25189 25190 slideLooper(); 25191 25192 }, dataInterval); 25193 } 25194 25195 25196 25197 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 25198 // Pause on tab out of focus! 25199 function onVisibilityChanged() { 25200 25201 if (document.hidden || document.mozHidden || document.webkitHidden || document.msHidden) { 25202 // The tab has lost focus 25203 clearTimeout(slideshowList[slideRand].timeOutInstance); 25204 } else { 25205 // The tab has gained focus 25206 slideshowList[slideRand].timeOutInstance = setTimeout(slideLooper, dataInterval); 25207 } 25208 25209 } 25210 25211 document.addEventListener("visibilitychange", onVisibilityChanged, false); 25212 document.addEventListener("mozvisibilitychange", onVisibilityChanged, false); 25213 document.addEventListener("webkitvisibilitychange", onVisibilityChanged, false); 25214 document.addEventListener("msvisibilitychange", onVisibilityChanged, false); 25215 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 25216 25217 25218 loaded = true; 25219 25220 }); 25221 25222 25223 25224 // -- * -- 25225 if(loaded === true) 25226 $.SOW.helper.consoleLog('Init : ' + scriptInfo + ' : Slideshow'); 25227 // -- * -- 25228 25229 } 25230 25231 }; 25232 25233 25234})(jQuery); 25235/** 25236 * fuzzy.js v0.1.0 25237 * (c) 2016 Ben Ripkens 25238 * @license: MIT 25239 */ 25240(function (context) { 25241 'use strict'; 25242 25243 var fuzzy = function fuzzy(term, query) { 25244 var max = calcFuzzyScore(term, query); 25245 var termLength = term.length; 25246 25247 if (fuzzy.analyzeSubTerms) { 25248 25249 for (var i = 1; i < termLength && i < fuzzy.analyzeSubTermDepth; i++) { 25250 var subTerm = term.substring(i); 25251 var score = calcFuzzyScore(subTerm, query); 25252 if (score.score > max.score) { 25253 // we need to correct 'term' and 'matchedTerm', as calcFuzzyScore 25254 // does not now that it operates on a substring. Doing it only for 25255 // new maximum score to save some performance. 25256 score.term = term; 25257 score.highlightedTerm = term.substring(0, i) + score.highlightedTerm; 25258 max = score; 25259 } 25260 } 25261 } 25262 25263 return max; 25264 }; 25265 25266 var calcFuzzyScore = function calcFuzzyScore(term, query) { 25267 var score = 0; 25268 var termLength = term.length; 25269 var queryLength = query.length; 25270 var highlighting = ''; 25271 var ti = 0; 25272 // -1 would not work as this would break the calculations of bonus 25273 // points for subsequent character matches. Something like 25274 // Number.MIN_VALUE would be more appropriate, but unfortunately 25275 // Number.MIN_VALUE + 1 equals 1... 25276 var previousMatchingCharacter = -2; 25277 25278 for (var qi = 0; qi < queryLength && ti < termLength; qi++) { 25279 var qc = query.charAt(qi); 25280 var lowerQc = qc.toLowerCase(); 25281 25282 for (; ti < termLength; ti++) { 25283 var tc = term.charAt(ti); 25284 25285 if (lowerQc === tc.toLowerCase()) { 25286 score++; 25287 25288 if ((previousMatchingCharacter + 1) === ti) { 25289 score += 2; 25290 } 25291 25292 highlighting += fuzzy.highlighting.before + 25293 tc + 25294 fuzzy.highlighting.after; 25295 previousMatchingCharacter = ti; 25296 ti++; 25297 break; 25298 } else { 25299 highlighting += tc; 25300 } 25301 } 25302 } 25303 25304 highlighting += term.substring(ti, term.length); 25305 25306 return { 25307 score: score, 25308 term: term, 25309 query: query, 25310 highlightedTerm: highlighting 25311 }; 25312 }; 25313 25314 fuzzy.matchComparator = function matchComparator(m1, m2) { 25315 return (m2.score - m1.score != 0) ? m2.score - m1.score : m1.term.length - m2.term.length; 25316 }; 25317 25318 /* 25319 * Whether or not fuzzy.js should analyze sub-terms, i.e. also 25320 * check term starting positions != 0. 25321 * 25322 * Example: 25323 * Given the term 'Halleluja' and query 'luja'
25324 * 25325 * Fuzzy.js scores this combination with an 8, when analyzeSubTerms is 25326 * set to false, as the following matching string will be calculated: 25327 * Ha[l]lel[uja] 25328 * 25329 * If you activate sub temr analysis though, the query will reach a score 25330 * of 10, as the matching string looks as following: 25331 * Halle[luja] 25332 * 25333 * Naturally, the second version is more expensive than the first one. 25334 * You should therefore configure how many sub terms you which to analyse. 25335 * This can be configured through fuzzy.analyzeSubTermDepth = 10. 25336 */ 25337 fuzzy.analyzeSubTerms = false; 25338 25339 /* 25340 * How many sub terms should be analyzed. 25341 */ 25342 fuzzy.analyzeSubTermDepth = 10; 25343 25344 fuzzy.highlighting = { 25345 before: '<em>', 25346 after: '</em>' 25347 }; 25348 25349 /* 25350 * Exporting the public API 25351 * ------------------------ 25352 * In a browser, the library will be available through this.fuzzy. Should 25353 * requireJS be used, we register fuzzy.js through requireJS. 25354 * For other environments, CommonJS is supported. 25355 */ 25356 if (typeof module !== 'undefined' && module.exports) { 25357 module.exports = fuzzy; 25358 } else if (typeof define === 'function') { 25359 define(function() { 25360 return fuzzy; 25361 }); 25362 } else { 25363 /* 25364 * In case the global variable fuzzy needs to be reset to its previous 25365 * value, the fuzzy library is returned by this method. 25366 */ 25367 var previousFuzzy = context.fuzzy; 25368 fuzzy.noConflict = function() { 25369 context.fuzzy = previousFuzzy; 25370 return fuzzy; 25371 }; 25372 25373 context.fuzzy = fuzzy; 25374 } 25375})(this); 25376 25377$.SOW.config.sow__debug_enable = true; 25378if(typeof $.SOW.config.autoinit === 'undefined') { $.SOW.config.autoinit = {}; } 25379$.SOW.config.autoinit['sow_header'] = ['$.SOW.core.header.init','null', null,false]; 25380$.SOW.config.autoinit['sow_search_suggest'] = ['$.SOW.core.search_suggest.init','form.js-ajax-search', null,false]; 25381$.SOW.config.autoinit['sow_lazyload'] = ['$.SOW.core.lazyload.init','.lazy', null,true]; 25382$.SOW.config.autoinit['sow_ajax_navigation'] = ['$.SOW.core.ajax_navigation.init','a.js-ajax', {enable:true,target_container:"#middle",parser_extract_enable:true,parser_force_push2target:false,parser_extract_element:"#middle, #page_js_files",page_404:"404.html",container2_element:"img.js-ajax-loaded-animate",container2_class:"animate-bouncein",data_params:{ajax:"true"},update_url:true,show_loading_icon:true,method:"GET",callback_function:"",callback_before_push:false,autoscroll_to_content:true,onpopstate_reload:true,custom_function_call:"",contentType:"",dataType:"",headers:"",crossDomain:""},true]; 25383$.SOW.config.autoinit['sow_ajax_content'] = ['$.SOW.core.ajax_content.init','div.js-ajax, section.js-ajax', null,true]; 25384$.SOW.config.autoinit['sow_ajax_form'] = ['$.SOW.core.ajax_form.init','form.js-ajax', null,true]; 25385$.SOW.config.autoinit['sow_ajax_select'] = ['$.SOW.core.ajax_select.init','select.js-ajax', null,true]; 25386$.SOW.config.autoinit['sow_ajax_modal'] = ['$.SOW.core.ajax_modal.init','.js-ajax-modal', {size:"modal-md"},true]; 25387$.SOW.config.autoinit['sow_ajax_confirm'] = ['$.SOW.core.ajax_confirm.init','.js-ajax-confirm', null,true]; 25388$.SOW.config.autoinit['sow_file_upload'] = ['$.SOW.core.file_upload.init','input[type="file"].custom-file-input', null,true]; 25389$.SOW.config.autoinit['sow_toast'] = ['$.SOW.core.toast.init','div.toast-on-load', null,true]; 25390$.SOW.config.autoinit['sow_dropdown_click_ignore'] = ['$.SOW.core.dropdown_click_ignore.init','.dropdown-menu.dropdown-click-ignore', null,true]; 25391$.SOW.config.autoinit['sow_dropdown'] = ['$.SOW.core.dropdown.init','.dropdown-menu.dropdown-menu-hover', null,true]; 25392$.SOW.config.autoinit['sow_dropdown_ajax'] = ['$.SOW.core.dropdown_ajax.init','a[data-toggle="dropdown"]', {loading_icon:"fi fi-circle-spin fi-spin",clearCacheInterval:1800000,tpl_start:"<ul class=\"list-unstyled m-0 p-0\">",tpl_end:"</ul>",tpl_ItemStart:"<li class=\"dropdown-item\">",tpl_ItemStartWChilds:"<li class=\"dropdown-item dropdown\">",tpl_ItemEnd:"</li>",tpl_Child_Start:"<ul class=\"dropdown-menu dropdown-menu-hover dropdown-menu-block-md shadow-lg b-0 m-0\">",tpl_Divider:"<li class=\"dropdown-divider\"></li>"},true]; 25393$.SOW.config.autoinit['sow_count_animate'] = ['$.SOW.core.count_animate.
25393init','null', null,true]; 25394$.SOW.config.autoinit['sow_btn_toggle'] = ['$.SOW.core.btn_toggle.init','.btn-toggle', null,true]; 25395$.SOW.config.autoinit['sow_nav_deep'] = ['$.SOW.core.nav_deep.init','.nav-deep', {speed:150},true]; 25396$.SOW.config.autoinit['sow_form_validate'] = ['$.SOW.core.form_validate.init','form.bs-validate', null,true]; 25397$.SOW.config.autoinit['sow_form_advanced'] = ['$.SOW.core.form_advanced.init','null', null,true]; 25398$.SOW.config.autoinit['sow_checkall'] = ['$.SOW.core.checkall.init','input.checkall', null,true]; 25399$.SOW.config.autoinit['sow_gdpr'] = ['$.SOW.core.gdpr.init','#gdpr', {cookie_name:"__gdpr"},false]; 25400$.SOW.config.autoinit['sow_sidebar'] = ['$.SOW.core.sidebar.init','null', null,false]; 25401$.SOW.config.autoinit['sow_scroll_to'] = ['$.SOW.core.scroll_to.init','a.scroll-to', {speed:400,s2t_enable:true,s2t_class:"btn-secondary",s2t_position:"end",s2t_mob_minH:1200,s2t_dsk_minH:2300},true]; 25402$.SOW.config.autoinit['sow_search_inline'] = ['$.SOW.core.search_inline.init','input.iqs-input', null,true]; 25403$.SOW.config.autoinit['sow_timer_autohide'] = ['$.SOW.core.timer_autohide.init','.timer-autohide', null,true]; 25404$.SOW.config.autoinit['sow_timer_countdown'] = ['$.SOW.core.timer_countdown.init','.timer-countdown', null,true]; 25405$.SOW.config.autoinit['sow_gfont'] = ['$.SOW.core.gfont.init','[data-gfont]', null,true]; 25406$.SOW.config.autoinit['sow_utils'] = ['$.SOW.core.utils.init','', {selector__initialFromString:".sow-util-initials",selector__timeAgo:".sow-util-timeago",selector__cookie:".sow-util-cookie",lang__timeAgo:{seconds:"less than a minute ago",minute:"about a minute ago",minutes:"%d minutes ago",hour:"about an hour ago",hours:"about %d hours ago",day:"a day ago",days:"%d days ago",month:"about a month ago",months:"%d months ago",year:"about a year ago",years:"%d years ago"}},true]; 25407 25408// DETECT FIRST INTERACTION OF VISITOR: 25409let userInteraction = false; 25410let userPausedVideo = false; 25411 25412["click", "touchmove"].forEach((eventName)=>{ 25413 window.addEventListener(eventName, ()=> { 25414 if(!userInteraction) { 25415 try { 25416 userInteraction = true; 25417 var v = document.querySelector("video.scroll-play.inview"); 25418 if( v !== null ) { 25419 v.play(); 25420 } 25421 //console.log("User interaction detected."); 25422 }catch(e){ 25423 console.warn(e.message); 25424 } 25425 } 25426 }); 25427}); 25428 25429function getHighest( elmo, target ) { 25430 if( $( elmo ).length > 0 && $( target ).length > 0 ) { 25431 setTimeout(function() { 25432 var hst = 0; 25433 $( elmo ).each(function() { 25434 if( $(this).height() > hst ) { 25435 hst = $(this).height(); 25436 } 25437 }); 25438 $( target ).height( hst + 100 ); 25439 }, 1000); 25440 } 25441} 25442 25443function fitPartnerImage() { 25444 if( $("#partner-page-modal").length > 0 && $(window).width() < 767 ) { 25445 setTimeout(function() { 25446 $(".placeholder-img.img-set").height( Math.round($(".placeholder-img.img-set").width()*1.2125) ); 25447 //document.querySelector(".placeholder-img.img-set").style.height = Math.round($(".placeholder-img.img-set").width()*1.33)+"px !important"; 25448 console.log('PartnerIMG fitted.'); 25449 }, 500); 25450 } else { 25451 console.log('no change.'); 25452 } 25453} 25454 25455 25456if( $('.hl-on-scroll').length > 0 ) { 25457 function closest(array, number) { 25458 var num = 0; 25459 for (var i = array.length - 1; i >= 0; i--) { 25460 if(Math.abs(number - array[i].position) < Math.abs(number - array[num].position)) { 25461 num = i; 25462 } 25463 } 25464 return array[num].element; 25465 } 25466 25467 $(window).scroll(function() { 25468 if( $(window).width() >= 992 ) { 25469 var scrollTop = $(document).scrollTop() + ($(window).height() / 2) - 250; 25470 } else { 25471 var scrollTop = $(document).scrollTop() + ($(window).height() / 2) - 350; 25472 } 25473 var positions = []; 25474 25475 $('.hl-on-scroll').each(function() { 25476 $(this).removeClass("hover"); 25477 positions.push({position:$(this).offset().top, element: $(this)}); 25478 var video = $(this)[0].querySelector("video.scroll-play"); 25479 if( video !== null ) { 25480 video.classList.remove("inview"); 25481 if(userInteraction === true) { 25482 video.volume = 0; 25483 video.pause(); 25484 } 25485 } 25486 }); 25487 25488 var getClosest = closest(positions,scrollTop); 25489 getClosest.addClass("hover"); 25490 var video = getClosest[0].querySelector("video.scroll-play"); 25491 if( video !== null ) { 25492 video.classList.add("inview"); 25493 if( userInteraction === true && userPausedVideo === false ) { 25494 var promise = video.play(); 25495 if( promise !== undefined ) { 25496 promise.then(_ => { 25497 video.volume = 0.25; 25498 }); 25499 } 25500 } 25501 } 25502 }); 25503} 25504 25505if( $('.faq-container').length > 0 ) { 25506 $(".faq-container .card .collapse").on('show.bs.collapse', function() { 25507 $(this).parents('.card').addClass('background-shown'); 25508 }); 25509 $(".faq-container .card .collapse").on('hide.bs.collapse', function() { 25510 $(this).parents('.card').removeClass('background-shown'); 25511 }); 25512} 25513 25514getHighest(".swiper-rel-element","#swiper-related"); 25515 25516if( $(".category-link").length > 0 ) { 25517 $(".category-link").each(function() { 25518 $(this).click(function(e) { 25519 e.preventDefault(); 25520 e.stopPropagation(); 25521 window.location.href = $(this).attr('href'); 25522 }); 25523 }); 25524} 25525 25526 25527if(jQuery("#gmap.contact-map").length > 0) { 25528 25529 function contactMap() { 25530 25531 //var latLang = new google.maps.LatLng(47.001386,8.586857); 25532 var latLang = new google.maps.LatLng(47.004074532418144, 8.616762542818202); 25533 25534 var mapOptions = { 25535 zoom:17, 25536 center: latLang, 25537 disableDefaultUI: false, 25538 navigationControl: false, 25539 mapTypeControl: false, 25540 scrollwheel: false, 25541 mapTypeId: google.maps.MapTypeId.ROADMAP, 25542 styles: [ 25543 { 25544 "featureType": "water", 25545 "elementType": "geometry", 25546 "stylers": [ 25547 { 25548 "color": "#e9e9e9" 25549 }, 25550 { 25551 "lightness": 17 25552 } 25553 ] 25554 }, 25555 { 25556 "featureType": "landscape", 25557 "elementType": "geometry", 25558 "stylers": [ 25559 { 25560 "color": "#f5f5f5" 25561 }, 25562 { 25563 "lightness": 20 25564 } 25565 ] 25566 }, 25567 { 25568 "featureType": "road.highway", 25569 "elementType": "geometry.fill", 25570 "stylers": [ 25571 { 25572 "color": "#ffffff" 25573 }, 25574 { 25575 "lightness": 17 25576 } 25577 ] 25578 }, 25579 { 25580 "featureType": "road.highway", 25581 "elementType": "geometry.stroke", 25582 "stylers": [ 25583 { 25584 "color": "#ffffff" 25585 }, 25586 { 25587 "lightness": 29 25588 }, 25589 { 25590 "weight": 0.2 25591 } 25592 ] 25593 }, 25594 { 25595 "featureType": "road.arterial", 25596 "elementType": "geometry", 25597 "stylers": [ 25598 { 25599 "color": "#ffffff" 25600 }, 25601 { 25602 "lightness": 18 25603 } 25604 ] 25605 }, 25606 { 25607 "featureType": "road.local", 25608 "elementType": "geometry", 25609 "stylers": [ 25610 { 25611 "color": "#ffffff" 25612 }, 25613 { 25614 "lightness": 16 25615 } 25616 ] 25617 }, 25618 { 25619 "featureType": "poi", 25620 "elementType": "geometry", 25621 "stylers": [ 25622 { 25623 "color": "#f5f5f5" 25624 }, 25625 { 25626 "lightness": 21 25627 } 25628 ] 25629 }, 25630 { 25631 "featureType": "poi.park", 25632 "elementType": "geometry", 25633 "stylers": [ 25634 { 25635 "color": "#dedede" 25636 }, 25637 { 25638 "lightness": 21 25639 } 25640 ] 25641 }, 25642 { 25643 "elementType": "labels.text.stroke", 25644 "stylers": [ 25645 { 25646 "visibility": "on" 25647 }, 25648 { 25649 "color": "#ffffff" 25650 }, 25651 { 25652 "lightness": 16 25653 } 25654 ] 25655 }, 25656 { 25657 "elementType": "labels.text.fill", 25658 "stylers": [ 25659 { 25660 "saturation": 36 25661 }, 25662 { 25663 "color": "#333333" 25664 }, 25665 { 25666 "lightness": 40 25667 } 25668 ] 25669 }, 25670 { 25671 "elementType": "labels.icon", 25672 "stylers": [ 25673 { 25674 "visibility": "off" 25675 } 25676 ] 25677 }, 25678 { 25679 "featureType": "transit", 25680 "elementType": "geometry", 25681 "stylers": [ 25682 { 25683 "color": "#f2f2f2" 25684 }, 25685 { 25686 "lightness": 19 25687 } 25688 ] 25689 }, 25690 { 25691 "featureType": "administrative", 25692 "elementType": "geometry.fill", 25693 "stylers": [ 25694 { 25695 "color": "#fefefe" 25696 }, 25697 { 25698 "lightness": 20 25699 } 25700 ] 25701 }, 25702 { 25703 "featureType": "administrative", 25704 "elementType": "geometry.stroke", 25705 "stylers": [ 25706 { 25707 "color": "#fefefe" 25708 }, 25709 { 25710 "lightness": 17 25711 }, 25712 { 25713 "weight": 1.2 25714 } 25715 ] 25716 } 25717 ] 25718 25719 }; 25720 25721 var map = new google.maps.Map(document.getElementById('gmap'), mapOptions); 25722 google.maps.event.trigger(map, 'resize'); 25723 map.setZoom( map.getZoom() ); 25724 25725 var marker = new google.maps.Marker({ 25726 icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACcAAAArCAYAAAD7YZFOAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBG
25726CzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABONJREFUeNrEmMFvG0UUh7+13dI0Ng0pVEJIEJCQcgmEI1zo7pEDyh+A1JY7EhUnTglIvSG1cEGIQ3JBAg5VwglBWW9JSQWFkoCsxFjJOgpWtlXjNE6dOl57h8vbauV61/baEU8aRfaMZ7/83pvfzKymlCIqDMOYBM4Bk8DZNkMs4DowBxSj5jJNk15CC4MzDOMsMB0CFBYWcBFYHgRcIgTsMpDtEQwZ/ycwwwAi1QI1IlCTfc47DbwAXOhnklblBgHmx3lgdiBwkspBgQUB34/7Y00p5Rd/tovxy1L0e8ApYAoY6+J3LwLFXhdEKlAjnVbhhTZWcVEWQSfVp+PUX0J8LGpVzpmmqZumWYwAf018Liq9Y3Fq7lxE/7xpmt3+xxfC/E1iKg5clGoXe5wvavybceAmI9JZ7HE+K0K9sdhW0iZWYjqAFfL95CDhlmPC7Q3KJKPgxvifIwru1ZhzhhV+MQ7c/TBvkoNALzEWsfpjwYXV1kiMffFyRF9R07SE9ngQ1hIdCn/aMIzzYZ3ZbFaTllBKvRtltJ7n5YDjwBPSjsv2mRKRtHZ76/UOCs0ahjFmmuZMEEomTExMTIyOjo5+omnaO1GSViqVW0AaUIEG0AQa0pqA5/dpuq6PALtdpKwIzHuet9hsNveVUqeTyeTbyWTyLTmhhIZSasuyrNcD6mgCoAlQE6gDh9I8QPlHpjhH8q6j0Wh8s7i4+AFwTBRPtaTRA1ygCjzwAX0rWThKv2o2mwvAAfBQFEsBQ8BJaWlR/0n5PgloPtzcEbIVl5aWvhVFHggksihOAsOBlpbvE49M2DTN+8D8EcHN67ruF71fU0og0oE2HADTWneIT48ILjivJik90aKYD6YFVq1KBC68VhwX76QaUBTrSYlCzwBPi8n7qp0QNatATeAe21s/GiSZUuqzbDZ7TGrrNPA88BLwHPAUkJE+gH3ZSmuPfK71dYRhGPYgTiRKqUXLsqbk4aeAM8CzAumvyIZAbQHrQEnU8x678QfUm+0XznGcr4BXBGxUlEoHvM4H2wX+Be4ErCb8RU6/6tVqtX9u3rz5uSg0FNhPE/JwV1K4CeQBWz43gnCJkJR83I9qtm2vAuOB+jojBjssyj2UFOZlEe61goXCWZY1p5S6EQdsZ2en6DhOXWprRKDSUnuaKFQA/gY2JK1uK1jkSbher1+KsU256+vrm7IK0/LX97AG4AA5eU223i6VHeGUUmppaSnruu7VXuC2t7e3q9VqMuD4Q6JWRdS6Bfwhqaz4ZhvnDtGwbftDpVS1G7CDg4OHhUJhR6BOymHSBe7KNfMX4LbYRrUTWCc4VSqVnN3d3SvdwBUKhXuBlalJkeeBG3Kg/QvYlo3f6+v2pZTygNrKyspsrVbLR01SKpX2y+WyJ75ZE4u4BfwE/CyQ5bDCj6McUqxl27ZnPM87bDfg8PCwadv2gTz4jqTwR+B74FcB3dd1vdELWEc4Ua/qOM5vjuN83W7M2tranuu6O8CavIBcAK6JVdwFDnVd9+LYUqqbUzZwL5/Pf5nJZN7IZDIv+x2bm5uVcrmcl3q
257266LarZUm9uXKhu0+qrdwDYq6url+r1elVWZ21jY+Ma8B1wVdTKATtAvV+wbpXzr2+71Wr190Kh8MX4+Ph7uVxuAfhBfGtLjuCuruuKAcV/AwDnrxMM7gFGVQAAAABJRU5ErkJggg==', 25727 position: latLang, 25728 map: map, 25729 title: "" 25730 }); 25731 25732 marker.setMap(map); 25733 google.maps.event.addListener(marker, "click", function() { 25734 // Add optionally an action for when the marker is clicked 25735 }); 25736 25737 // kepp googlemap responsive - center on resize 25738 google.maps.event.addDomListener(window, 'resize', function() { 25739 map.setCenter(latLang); 25740 }); 25741 25742 } 25743 25744 25745 function showMap(initWhat) { 25746 var script = document.createElement('script'); 25747 script.type = 'text/javascript'; 25748 script.src = '//maps.google.com/maps/api/js?key=AIzaSyA8Ea7FZji6JDtI4DbaxIqcIvhfWJddijk&callback='+initWhat; 25749 document.body.appendChild(script); 25750 } 25751 25752 showMap('contactMap'); 25753} 25754 25755 25756/* fitty v2.3.0 */ 25757!function(e,t){if("function"==typeof define&&define.amd)define(["module","exports"],t);else if("undefined"!=typeof exports)t(module,exports);else{var n={exports:{}};t(n,n.exports),e.fitty=n.exports}}(this,function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var E=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])}return e};t.default=function(n){if(n){var r={IDLE:0,DIRTY_CONTENT:1,DIRTY_LAYOUT:2,DIRTY:3},i=[],e=null,o="requestAnimationFrame"in n?function(){n.cancelAnimationFrame(e),e=n.requestAnimationFrame(function(){return u(i.filter(function(e){return e.dirty&&e.active}))})}:function(){},t=function(t){return function(){i.forEach(function(e){return e.dirty=t}),o()}},u=function(e){e.filter(function(e){return!e.styleComputed}).forEach(function(e){e.styleComputed=s(e)}),e.filter(f).forEach(d);var t=e.filter(c);t.forEach(l),t.forEach(function(e){d(e),a(e)}),t.forEach(p)},a=function(e){return e.dirty=r.IDLE},l=function(e){e.availableWidth=e.element.parentNode.clientWidth,e.currentWidth=e.element.scrollWidth,e.previousFontSize=e.currentFontSize,e.currentFontSize=Math.min(Math.max(e.minSize,e.availableWidth/e.currentWidth*e.previousFontSize),e.maxSize),e.whiteSpace=e.multiLine&&e.currentFontSize===e.minSize?"normal":"nowrap"},c=function(e){return e.dirty!==r.DIRTY_LAYOUT||e.dirty===r.DIRTY_LAYOUT&&e.element.parentNode.clientWidth!==e.availableWidth},s=function(e){var t=n.getComputedStyle(e.element,null);e.currentFontSize=parseInt(t.getPropertyValue("font-size"),10),e.display=t.getPropertyValue("display"),e.whiteSpace=t.getPropertyValue("white-space")},f=function(e){var t=!1;return!e.preStyleTestCompleted&&(/inline-/.test(e.display)||(t=!0,e.display="inline-block"),"nowrap"!==e.whiteSpace&&(t=!0,e.whiteSpace="nowrap"),e.preStyleTestCompleted=!0,t)},d=function(e){e.originalStyle||(e.originalStyle=e.element.getAttribute("style")||""),e.element.style.cssText=e.originalStyle+";white-space:"+e.whiteSpace+";display:"+e.display+";font-size:"+e.currentFontSize+"px"},p=function(e){e.element.dispatchEvent(new CustomEvent("fit",{detail:{oldValue:e.previousFontSize,newValue:e.currentFontSize,scaleFactor:e.currentFontSize/e.previousFontSize}}))},v=function(e,t){return function(){e.dirty=t,e.active&&o()}},m=function(e){b(e),e.newbie=!0,e.dirty=!0,i.push(e)},y=function(t){return function(){i=i.filter(function(e){return e.element!==t.element}),t.observeMutations&&t.observer.disconnect(),t.element.style.cssText=t.originalStyle}},h=function(e){return function(){e.active||(e.active=!0,o())}},S=function(e){return function(){return e.active=!1}},b=function(e){e.observeMutations&&(e.observer=new MutationObserver(v(e,r.DIRTY_CONTENT)),e.observer.observe(e.element,e.observeMutations))},w={minSize:16,maxSize:512,multiLine:!0,observeMutations:"MutationObserver"in n&&{subtree:!0,childList:!0,characterData:!0}},T=null,z=function(){n.clearTimeout(T),T=n.setTimeout(t(r.DIRTY_LAYOUT),D.observeWindowDelay)},F=["resize","orientationchange"];return Object.defineProperty(D,"observeWindow",{set:function(e){var t=(e?"add":"remove")+"EventListener";F.forEach(function(e){n[t](e,z)})}}),D.observeWindow=!0,D.observeWindowDelay=100,D.fitAll=t(r.DIRTY),D}function g(e,t){var n=E({},w,t),i=e.map(function(e){var t=E({},n,{element:e,active:!0});return m(t),{element:e,fit:v(t,r.DIRTY),unfreeze:h(t),freeze:S(t),unsubscribe:y(t)}});return o(),i}function D(e){var t,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e?g((t=document.querySelectorAll(e),[].slice.call(t)),n):g([e],n)[0]}}("undefined"==typeof window?null:window),e.exports=t.default}); 25758 25759/* TouchSwipe v1.6.18 */ 25760!function(factory){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],factory):factory("undefined"!=typeof module&&module.exports?require("jquery"):jQuery)}(function($){"use strict";function init(options){return!options||void 0!==options.allowPageScroll||void 0===options.swipe&&void 0===options.swipeStatus||(options.allowPageScroll=NONE),void 0!==options.click&&void 0===options.tap&&(options.tap=options.click),options||(options={}),options=$.extend({},$.fn.swipe.defaults,options),this.each(function(){var $this=$(this),plugin=$this.data(PLUGIN_NS);plugin||(plugin=new TouchSwipe(this,options),$this.data(PLUGIN_NS,plugin))})}function TouchSwipe(element,options){function touchStart(jqEvent){if(!(getTouchInProgress()||$(jqEvent.target).closest(options.excludedElements,$element).length>0)){var event=jqEvent.originalEvent?jqEvent.originalEvent:jqEvent;if(!event.pointerType||"mouse"!=event.pointerType||0!=options.fallbackToMouseEvents){var ret,touches=event.touches,evt=touches?touches[0]:event;return phase=PHASE_START,touches?fingerCount=touches.length:options.preventDefaultEvents!==!1&&jqEvent.preventDefault(),distance=0,direction=null,currentDirection=null,pinchDirection=null,duration=0,startTouchesDistance=0,endTouchesDistance=0,pinchZoom=1,pinchDistance=0,maximumsMap=createMaximumsData(),cancelMultiFingerRelease(),createFingerData(0,evt),!touches||fingerCount===options.fingers||options.fingers===ALL_FINGERS||hasPinches()?(startTime=getTimeStamp(),2==fingerCount&&(createFingerData(1,touches[1]),startTouchesDistance=endTouchesDistance=calculateTouchesDistance(fingerData[0].start,f
vendor: 16,482 bytes, line 25760
25760ingerData[1].start)),(options.swipeStatus||options.pinchStatus)&&(ret=triggerHandler(event,phase))):ret=!1,ret===!1?(phase=PHASE_CANCEL,triggerHandler(event,phase),ret):(options.hold&&(holdTimeout=setTimeout($.proxy(function(){$element.trigger("hold",[event.target]),options.hold&&(ret=options.hold.call($element,event,event.target))},this),options.longTapThreshold)),setTouchInProgress(!0),null)}}}function touchMove(jqEvent){var event=jqEvent.originalEvent?jqEvent.originalEvent:jqEvent;if(phase!==PHASE_END&&phase!==PHASE_CANCEL&&!inMultiFingerRelease()){var ret,touches=event.touches,evt=touches?touches[0]:event,currentFinger=updateFingerData(evt);if(endTime=getTimeStamp(),touches&&(fingerCount=touches.length),options.hold&&clearTimeout(holdTimeout),phase=PHASE_MOVE,2==fingerCount&&(0==startTouchesDistance?(createFingerData(1,touches[1]),startTouchesDistance=endTouchesDistance=calculateTouchesDistance(fingerData[0].start,fingerData[1].start)):(updateFingerData(touches[1]),endTouchesDistance=calculateTouchesDistance(fingerData[0].end,fingerData[1].end),pinchDirection=calculatePinchDirection(fingerData[0].end,fingerData[1].end)),pinchZoom=calculatePinchZoom(startTouchesDistance,endTouchesDistance),pinchDistance=Math.abs(startTouchesDistance-endTouchesDistance)),fingerCount===options.fingers||options.fingers===ALL_FINGERS||!touches||hasPinches()){if(direction=calculateDirection(currentFinger.start,currentFinger.end),currentDirection=calculateDirection(currentFinger.last,currentFinger.end),validateDefaultEvent(jqEvent,currentDirection),distance=calculateDistance(currentFinger.start,currentFinger.end),duration=calculateDuration(),setMaxDistance(direction,distance),ret=triggerHandler(event,phase),!options.triggerOnTouchEnd||options.triggerOnTouchLeave){var inBounds=!0;if(options.triggerOnTouchLeave){var bounds=getbounds(this);inBounds=isInBounds(currentFinger.end,bounds)}!options.triggerOnTouchEnd&&inBounds?phase=getNextPhase(PHASE_MOVE):options.triggerOnTouchLeave&&!inBounds&&(phase=getNextPhase(PHASE_END)),phase!=PHASE_CANCEL&&phase!=PHASE_END||triggerHandler(event,phase)}}else phase=PHASE_CANCEL,triggerHandler(event,phase);ret===!1&&(phase=PHASE_CANCEL,triggerHandler(event,phase))}}function touchEnd(jqEvent){var event=jqEvent.originalEvent?jqEvent.originalEvent:jqEvent,touches=event.touches;if(touches){if(touches.length&&!inMultiFingerRelease())return startMultiFingerRelease(event),!0;if(touches.length&&inMultiFingerRelease())return!0}return inMultiFingerRelease()&&(fingerCount=fingerCountAtRelease),endTime=getTimeStamp(),duration=calculateDuration(),didSwipeBackToCancel()||!validateSwipeDistance()?(phase=PHASE_CANCEL,triggerHandler(event,phase)):options.triggerOnTouchEnd||options.triggerOnTouchEnd===!1&&phase===PHASE_MOVE?(options.preventDefaultEvents!==!1&&jqEvent.cancelable!==!1&&jqEvent.preventDefault(),phase=PHASE_END,triggerHandler(event,phase)):!options.triggerOnTouchEnd&&hasTap()?(phase=PHASE_END,triggerHandlerForGesture(event,phase,TAP)):phase===PHASE_MOVE&&(phase=PHASE_CANCEL,triggerHandler(event,phase)),setTouchInProgress(!1),null}function touchCancel(){fingerCount=0,endTime=0,startTime=0,startTouchesDistance=0,endTouchesDistance=0,pinchZoom=1,cancelMultiFingerRelease(),setTouchInProgress(!1)}function touchLeave(jqEvent){var event=jqEvent.originalEvent?jqEvent.originalEvent:jqEvent;options.triggerOnTouchLeave&&(phase=getNextPhase(PHASE_END),triggerHandler(event,phase))}function removeListeners(){$element.off(START_EV,touchStart),$element.off(CANCEL_EV,touchCancel),$element.off(MOVE_EV,touchMove),$element.off(END_EV,touchEnd),LEAVE_EV&&$element.off(LEAVE_EV,touchLeave),setTouchInProgress(!1)}function getNextPhase(currentPhase){var nextPhase=currentPhase,validTime=validateSwipeTime(),validDistance=validateSwipeDistance(),didCancel=didSwipeBackToCancel();return!validTime||didCancel?nextPhase=PHASE_CANCEL:!validDistance||currentPhase!=PHASE_MOVE||options.triggerOnTouchEnd&&!options.triggerOnTouchLeave?!validDistance&¤tPhase==PHASE_END&&options.triggerOnTouchLeave&&(nextPhase=PHASE_CANCEL):nextPhase=PHASE_END,nextPhase}function triggerHandler(event,phase){var ret,touches=event.touches;return(didSwipe()||hasSwipes())&&(ret=triggerHandlerForGesture(event,phase,SWIPE)),(didPinch()||hasPinches())&&ret!==!1&&(ret=triggerHandlerForGesture(event,phase,PINCH)),didDoubleTap()&&ret!==!1?ret=triggerHandlerForGesture(event,phase,DOUBLE_TAP):didLongTap()&&ret!==!1?ret=triggerHandlerForGesture(event,phase,LONG_TAP):didTap()&&ret!==!1&&(ret=triggerHandlerForGesture(event,phase,TAP)),phase===PHASE_CANCEL&&touchCancel(event),phase===PHASE_END&&(touches?touches.length||touchCancel(event):touchCancel(event)),ret}function triggerHandlerForGesture(event,phase,gesture){var ret;if(gesture==SWIPE){if($element.trigger("swipeStatus",[phase,direction||null,distance||0,duration||0,fingerCount,fingerData,currentDirection]),options.swipeStatus&&(ret=options.swipeStatus.call($element,event,phase,direction||null,distance||0,duration||0,fingerCount,fingerData,currentDirection),ret===!1))return!1;if(phase==PHASE_END&&validateSwipe()){if(clearTimeout(singleTapTimeout),clearTimeout(holdTimeout),$element.trigger("swipe",[direction,distance,duration,fingerCount,fingerData,currentDirection]),options.swipe&&(ret=options.swipe.call($element,event,direction,distance,duration,fingerCount,fingerData,currentDirection),ret===!1))return!1;switch(direction){case LEFT:$element.trigger("swipeLeft",[direction,distance,duration,fingerCount,fingerData,currentDirection]),options.swipeLeft&&(ret=options.swipeLeft.call($element,event,direction,distance,duration,fingerCount,fingerData,currentDirection));break;case RIGHT:$element.trigger("swipeRight",[direction,distance,duration,fingerCount,fingerData,currentDirection]),options.swipeRight&&(ret=options.swipeRight.call($element,event,direction,distance,duration,fingerCount,fingerData,currentDirection));break;case UP:$element.trigger("swipeUp",[direction,distance,duration,fingerCount,fingerData,currentDirection]),options.swipeUp&&(ret=options.swipeUp.call($element,event,direction,distance,duration,fingerCount,fingerData,currentDirection));break;case DOWN:$element.trigger("swipeDown",[direction,distance,duration,fingerCount,fingerData,currentDirection]),options.swipeDown&&(ret=options.swipeDown.call($element,event,direction,distance,duration,fingerCount,fingerData,currentDirection))}}}if(gesture==PINCH){if($element.trigger("pinchStatus",[phase,pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData]),options.pinchStatus&&(ret=options.pinchStatus.call($element,event,phase,pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData),ret===!1))return!1;if(phase==PHASE_END&&validatePinch())switch(pinchDirection){case IN:$element.trigger("pinchIn",[pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData]),options.pinchIn&&(ret=options.pinchIn.call($element,event,pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData));break;case OUT:$element.trigger("pinchOut",[pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData]),options.pinchOut&&(ret=options.pinchOut.call($element,event,pinchDirection||null,pinchDistance||0,duration||0,fingerCount,pinchZoom,fingerData))}}return gesture==TAP?phase!==PHASE_CANCEL&&phase!==PHASE_END||(clearTimeout(singleTapTimeout),clearTimeout(holdTimeout),hasDoubleTap()&&!inDoubleTap()?(doubleTapStartTime=getTimeStamp(),singleTapTimeout=setTimeout($.proxy(function(){doubleTapStartTime=null,$element.trigger("tap",[event.target]),options.tap&&(ret=options.tap.call($element,event,event.target))},this),options.doubleTapThreshold)):(doubleTapStartTime=null,$element.trigger("tap",[event.target]),options.tap&&(ret=options.tap.call($element,event,event.target)))):gesture==DOUBLE_TAP?phase!==PHASE_CANCEL&&phase!==PHASE_END||(clearTimeout(singleTapTimeout),clearTimeout(holdTimeout),doubleTapStartTime=null,$element.trigger("doubletap",[event.target]),options.doubleTap&&(ret=options.doubleTap.call($element,event,event.target))):gesture==LONG_TAP&&(phase!==PHASE_CANCEL&&phase!==PHASE_END||(clearTimeout(singleTapTimeout),doubleTapStartTime=null,$element.trigger("longtap",[event.target]),options.longTap&&(ret=options.longTap.call($element,event,event.target)))),ret}function validateSwipeDistance(){var valid=!0;return null!==options.threshold&&(valid=distance>=options.threshold),valid}function didSwipeBackToCancel(){var cancelled=!1;return null!==options.cancelThreshold&&null!==direction&&(cancelled=getMaxDistance(direction)-distance>=options.cancelThreshold),cancelled}function validatePinchDistance(){return null!==options.pinchThreshold?pinchDistance>=options.pinchThreshold:!0}function validateSwipeTime(){var result;return result=options.maxTimeThreshold?!(duration>=options.maxTimeThreshold):!0}function validateDefaultEvent(jqEvent,direction){if(options.preventDefaultEvents!==!1)if(options.allowPageScroll===NONE)jqEvent.preventDefault();else{var auto=options.allowPageScroll===AUTO;switch(direction){case LEFT:(options.swipeLeft&&auto||!auto&&options.allowPageScroll!=HORIZONTAL)&&jqEvent.preventDefault();break;case RIGHT:(options.swipeRight&&auto||!auto&&options.allowPageScroll!=HORIZONTAL)&&jqEvent.preventDefault();break;case UP:(options.swipeUp&&auto||!auto&&options.allowPageScroll!=VERTICAL)&&jqEvent.preventDefault();break;case DOWN:(options.swipeDown&&auto||!auto&&options.allowPageScroll!=VERTICAL)&&jqEvent.preventDefault();break;case NONE:}}}function validatePinch(){var hasCorrectFingerCount=validateFingers(),hasEndPoint=validateEndPoint(),hasCorrectDistance=validatePinchDistance();return hasCorrectFingerCount&&hasEndPoint&&hasCorrectDistance}function hasPinches(){return!!(options.pinchStatus||options.pinchIn||options.pinchOut)}function didPinch(){return!(!validatePinch()||!hasPinches())}function validateSwipe(){var hasValidTime=validateSwipeTime(),hasValidDistance=validateSwipeDistance(),hasCorrectFingerCount=validateFingers(),hasEndPoint=validateEndPoint(),didCancel=didSwipeBackToCancel(),valid=!didCancel&&hasEndPoint&&hasCorrectFingerCount&&hasValidDistance&&hasValidTime;return valid}function hasSwipes(){return!!(options.swipe||options.swipeStatus||options.swipeLeft||options.swipeRight||options.swipeUp||options.swipeDown)}function didSwipe(){return!(!validateSwipe()||!hasSwipes())}function validateFingers(){return fingerCount===options.fingers||options.fingers===ALL_FINGERS||!SUPPORTS_TOUCH}function validateEndPoint(){return 0!==fingerData[0].end.x}function hasTap(){return!!options.tap}function hasDoubleTap(){return!!options.doubleTap}function hasLongTap(){return!!options.longTap}function validateDoubleTap(){if(null==doubleTapStartTime)return!1;var now=getTimeStamp();return hasDoubleTap()&&now-doubleTapStartTime<=options.doubleTapThreshold}function inDoubleTap(){return validateDoubleTap()}function validateTap(){return(1===fingerCount||!SUPPORTS_TOUCH)&&(isNaN(distance)||distance<options.threshold)}function validateLongTap(){return duration>options.longTapThreshold&&DOUBLE_TAP_THRESHOLD>distance}function didTap(){return!(!validateTap()||!hasTap())}function didDoubleTap(){return!(!validateDoubleTap()||!hasDoubleTap())}function didLongTap(){return!(!validateLongTap()||!hasLongTap())}function startMultiFingerRelease(event){previousTouchEndTime=getTimeStamp(),fingerCountAtRelease=event.touches.length+1}function cancelMultiFingerRelease(){previousTouchEndTime=0,fingerCountAtRelease=0}function inMultiFingerRelease(){var withinThreshold=!1;if(previousTouchEndTime){var diff=getTimeStamp()-previousTouchEndTime;diff<=options.fingerReleaseThreshold&&(withinThreshold=!0)}return withinThreshold}function getTouchInProgress(){return!($element.data(PLUGIN_NS+"_intouch")!==!0)}function setTouchInProgress(val){$element&&(val===!0?($element.on(MOVE_EV,touchMove),$element.on(END_EV,touchEnd),LEAVE_EV&&$element.on(LEAVE_EV,touchLeave)):($element.off(MOVE_EV,touchMove,!1),$element.off(END_EV,touchEnd,!1),LEAVE_EV&&$element.off(LEAVE_EV,touchLeave,!1)),$element.data(PLUGIN_NS+"_intouch",val===!0))}function createFingerData(id,evt){var f={start:{x:0,y:0},last:{x:0,y:0},end:{x:0,y:0}};return f.start.x=f.last.x=f.end.x=evt.pageX||evt.clientX,f.start.y=f.last.y=f.end.y=evt.pageY||evt.clientY,fingerData[id]=f,f}function updateFingerData(evt){var id=void 0!==evt.identifier?evt.identifier:0,f=getFingerData(id);return null===f&&(f=createFingerData(id,evt)),f.last.x=f.end.x,f.last.y=f.end.y,f.end.x=evt.pageX||evt.clientX,f.end.y=evt.pageY||evt.clientY,f}function getFingerData(id){return fingerData[id]||null}function setMaxDistance(direction,distance){direction!=NONE&&(distance=Math.max(distance,getMaxDistance(direction)),maximumsMap[direction].distance=distance)}function getMaxDistance(direction){return maximumsMap[direction]?maximumsMap[direction].distance:void 0}function createMaximumsData(){var maxData={};return maxData[LEFT]=createMaximumVO(LEFT),maxData[RIGHT]=createMaximumVO(RIGHT),maxData[UP]=createMaximumVO(UP),maxData[DOWN]=createMaximumVO(DOWN),maxData}function createMaximumVO(dir){return{direction:dir,distance:0}}function calculateDuration(){return endTime-startTime}function calculateTouchesDistance(startPoint,endPoint){var diffX=Math.abs(startPoint.x-endPoint.x),diffY=Math.abs(startPoint.y-endPoint.y);return Math.round(Math.sqrt(diffX*diffX+diffY*diffY))}function calculatePinchZoom(startDistance,endDistance){var percent=endDistance/startDistance*1;return percent.toFixed(2)}function calculatePinchDirection(){return 1>pinchZoom?OUT:IN}function calculateDistance(startPoint,endPoint){return Math.round(Math.sqrt(Math.pow(endPoint.x-startPoint.x,2)+Math.pow(endPoint.y-startPoint.y,2)))}function calculateAngle(startPoint,endPoint){var x=startPoint.x-endPoint.x,y=endPoint.y-startPoint.y,r=Math.atan2(y,x),angle=Math.round(180*r/Math.PI);return 0>angle&&(angle=360-Math.abs(angle)),angle}function calculateDirection(startPoint,endPoint){if(comparePoints(startPoint,endPoint))return NONE;var angle=calculateAngle(startPoint,endPoint);return 45>=angle&&angle>=0?LEFT:360>=angle&&angle>=315?LEFT:angle>=135&&225>=angle?RIGHT:angle>45&&135>angle?DOWN:UP}function getTimeStamp(){var now=new Date;return now.getTime()}function getbounds(el){el=$(el);var offset=el.offset(),bounds={left:offset.left,right:offset.left+el.outerWidth(),top:offset.top,bottom:offset.top+el.outerHeight()};return bounds}function isInBounds(point,bounds){return point.x>bounds.left&&point.x<bounds.right&&point.y>bounds.top&&point.y<bounds.bottom}function comparePoints(pointA,pointB){return pointA.x==pointB.x&&pointA.y==pointB.y}var options=$.extend({},options),useTouchEvents=SUPPORTS_TOUCH||SUPPORTS_POINTER||!options.fallbackToMouseEvents,START_EV=useTouchEvents?SUPPORTS_POINTER?SUPPORTS_POINTER_IE10?"MSPointerDown":"pointerdown":"touchstart":"mousedown",MOVE_EV=useTouchEvents?SUPPORTS_POINTER?SUPPORTS_POINTER_IE10?"MSPointerMove":"pointermove":"touchmove":"mousemove",END_EV=useTouchEvents?SUPPORTS_POINTER?SUPPORTS_POINTER_IE10?"MSPointerUp":"pointerup":"touchend":"mouseup",LEAVE_EV=useTouchEvents?SUPPORTS_POINTER?"mouseleave":null:"mouseleave",CANCEL_EV=SUPPORTS_POINTER?SUPPORTS_POINTER_IE10?"MSPointerCancel":"pointercancel":"touchcancel",distance=0,direction=null,currentDirection=null,duration=0,startTouchesDistance=0,endTouchesDistance=0,pinchZoom=1,pinchDistance=0,pinchDirection=0,maximumsMap=null,$element=$(element),phase="start",fingerCount=0,fingerData={},startTime=0,endTime=0,previousTouchEndTime=0,fingerCountAtRelease=0,doubleTapStartTime=0,singleTapTimeout=null,holdTimeout=null;try{$element.on(START_EV,touchStart),$element.on(CANCEL_EV,touchCancel)}catch(e){$.error("events not supported "+START_EV+","+CANCEL_EV+" on jQuery.swipe")}this.enable=function(){return this.disable(),$element.on(START_EV,touchStart),$element.on(CANCEL_EV,touchCancel),$element},this.disable=function(){return removeListeners(),$element},this.destroy=function(){removeListeners(),$element.data(PLUGIN_NS,null),$element=null},this.option=function(property,value){if("object"==typeof property)options=$.extend(options,property);else if(void 0!==options[property]){if(void 0===value)return options[property];options[property]=value}else{if(!property)return options;$.error("Option "+property+" does not exist on jQuery.swipe.options")}return null}}var VERSION="1.6.18",LEFT="left",RIGHT="right",UP="up",DOWN="down",IN="in",OUT="out",
25760NONE="none",AUTO="auto",SWIPE="swipe",PINCH="pinch",TAP="tap",DOUBLE_TAP="doubletap",LONG_TAP="longtap",HORIZONTAL="horizontal",VERTICAL="vertical",ALL_FINGERS="all",DOUBLE_TAP_THRESHOLD=10,PHASE_START="start",PHASE_MOVE="move",PHASE_END="end",PHASE_CANCEL="cancel",SUPPORTS_TOUCH="ontouchstart"in window,SUPPORTS_POINTER_IE10=window.navigator.msPointerEnabled&&!window.PointerEvent&&!SUPPORTS_TOUCH,SUPPORTS_POINTER=(window.PointerEvent||window.navigator.msPointerEnabled)&&!SUPPORTS_TOUCH,PLUGIN_NS="TouchSwipe",defaults={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:".noSwipe",preventDefaultEvents:!0};$.fn.swipe=function(method){var $this=$(this),plugin=$this.data(PLUGIN_NS);if(plugin&&"string"==typeof method){if(plugin[method])return plugin[method].apply(plugin,Array.prototype.slice.call(arguments,1));$.error("Method "+method+" does not exist on jQuery.swipe")}else if(plugin&&"object"==typeof method)plugin.option.apply(plugin,arguments);else if(!(plugin||"object"!=typeof method&&method))return init.apply(this,arguments);return $this},$.fn.swipe.version=VERSION,$.fn.swipe.defaults=defaults,$.fn.swipe.phases={PHASE_START:PHASE_START,PHASE_MOVE:PHASE_MOVE,PHASE_END:PHASE_END,PHASE_CANCEL:PHASE_CANCEL},$.fn.swipe.directions={LEFT:LEFT,RIGHT:RIGHT,UP:UP,DOWN:DOWN,IN:IN,OUT:OUT},$.fn.swipe.pageScroll={NONE:NONE,HORIZONTAL:HORIZONTAL,VERTICAL:VERTICAL,AUTO:AUTO},$.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,FOUR:4,FIVE:5,ALL:ALL_FINGERS}}); 25761 25762 25763function prettyfieHempMate() { 25764 $(".prettyfie-hempmate").each(function() { 25765 var str = $(this).html(); 25766 str = str.replace('Hemp', '<b>Hemp</b>'); 25767 str = str.replace('HEMP', '<b>HEMP</b>'); 25768 $(this).html( str ); 25769 }); 25770} 25771 25772function prettyfieVapeMate() { 25773 $(".prettyfie-vapemate").each(function() { 25774 var str = $(this).html(); 25775 str = str.replace('Vape', '<b>Vape</b>'); 25776 str = str.replace('VAPE', '<b>VAPE</b>'); 25777 $(this).html( str ); 25778 }); 25779} 25780 25781function partnerModalClose() { 25782 if( partnerPopUp ) { 25783 $("#partner-page-modal").modal("hide"); 25784 $(document.body).removeClass('modal-open'); 25785 $(window.document).find('html').removeClass('modal-open'); 25786 } 25787} 25788 25789function partnerModalOpen() { 25790 if( partnerPopUp ) { 25791 $(document.body).addClass('modal-open'); 25792 $(window.document).find('html').addClass('modal-open'); 25793 $("#partner-page-modal").modal({ 25794 backdrop: 'static', 25795 keyboard: true, 25796 show: true 25797 }); 25798 } 25799} 25800 25801function updateInvoiceFormSubmit() { 25802 25803 if( $("#cart-update-invoice").length > 0 ) { 25804 console.log("standard"); 25805 $("#cart-update-invoice").data("yiiActiveForm").submitting = true; 25806 $("#cart-update-invoice").yiiActiveForm("validate"); 25807 } 25808 25809} 25810 25811function kundenModalOpen() { 25812 if( kundenPopUp ) { 25813 var bd = $("#modalKunde").attr("data-backdrop"), 25814 kb = $("#modalKunde").attr("data-keyboard"); 25815 bd = (typeof bd !== 'undefined' && bd !== false) ? 'static' : true; 25816 kb = (typeof kb !== 'undefined' && kb !== false) ? false : true; 25817 $(document.body).addClass('modal-open'); 25818 $(window.document).find('html').addClass('modal-open'); 25819 $("#modalKunde").modal({ 25820 backdrop: bd, 25821 keyboard: kb, 25822 show: true 25823 }); 25824 kundenPopUp = false; 25825 } 25826} 25827 25828 25829 25830 25831 25832 25833 25834 25835 25836 25837 25838 25839 25840 25841 25842 25843 25844 25845 25846 25847function revealfaq(block, quest) { 25848 var revealent = "#" + block; 25849 revealent = revealent + quest; 25850 var revealSpeed = 700; 25851 if( $(revealent).length > 0 ) { 25852 25853 setTimeout(function() { 25854 $('html, body').animate({scrollTop: $( revealent ).offset().top -150}, revealSpeed); 25855 setTimeout(function() { 25856 $( revealent ).find('button').click(); 25857 console.log( revealent ); 25858 }, revealSpeed); 25859 }, revealSpeed); 25860 } 25861} 25862 25863$(document).ready(function() { 25864 if( $("#adult-modal").length > 0 ) { 25865 if( $("#adultCheck").length > 0 ) { 25866 $("#adultCheck").change(function() { 25867 if( document.getElementById("adultCheck").checked ) { 25868 $("#adultButton").removeClass("disabled"); 25869 } else { 25870 $("#adultButton").addClass("disabled"); 25871 } 25872 }); 25873 } 25874 setTimeout(function() { 25875 $("#adult-modal").modal('show'); 25876 }, 750); 25877 } 25878 25879 if( $("#modalChangeSponsor").length > 0 ) { 25880 setTimeout(function() { 25881 $("#modalChangeSponsor").modal('show'); 25882 }, 450); 25883 } 25884 25885 if( $(".embed-responsive.embed-responsive-overlay").length > 0 ) { 25886 $(".embed-responsive.embed-responsive-overlay").each(function() { 25887 var childVID = $(this).children("video.no-controlls"); 25888 if( childVID.length > 0 ) { 25889 childVID = childVID[0]; 25890 childVID.controls = false;
25891 $(this).click( function() { 25892 if(childVID.paused && userInteraction === true) { 25893 var promise = childVID.play(); 25894 if( promise !== undefined ) { 25895 promise.then(_ => { 25896 childVID.volume = 0.25; 25897 userPausedVideo = false; 25898 }); 25899 } 25900 } else { 25901 childVID.volume = 0; 25902 userPausedVideo = true; 25903 childVID.pause(); 25904 } 25905 }); 25906 childVID.onpause = function() { 25907 if( childVID.nextElementSibling !== null ) { 25908 childVID.nextElementSibling.classList.add("show"); 25909 } 25910 } 25911 childVID.onplay = function() { 25912 if( childVID.nextElementSibling !== null ) { 25913 childVID.nextElementSibling.classList.remove("show"); 25914 } 25915 } 25916 } 25917 }); 25918 } 25919 25920 if( $("#cat-headln").length > 0 ) { 25921 fitty('#cat-headln'); 25922 } 25923 //if( $("#testi-container").length > 0 ) { 25924 if( $("#testimonials").length > 0 ) { 25925 setTimeout(function(){ 25926 $("#testi-container").addClass("testi-0"); 25927 var testiSlider = $("#testimonials")[0].swiper; 25928 25929 testiSlider.on("slideChange", function() { 25930 $("#testi-container").removeClass("testi-" + testiSlider.previousIndex); 25931 $("#testi-container").addClass("testi-" + testiSlider.activeIndex ); 25932 }); 25933 },2000); 25934 } 25935 if( $("#partner-page-modal").length > 0 && partnerAutoPopUp ) { 25936 setTimeout(function(){ 25937 partnerModalOpen(); 25938 fitPartnerImage(); 25939 },1000); 25940 } 25941 if( $(".prettyfie-hempmate").length > 0 ) { 25942 prettyfieHempMate(); 25943 } 25944 if( $(".prettyfie-vapemate").length > 0 ) { 25945 prettyfieVapeMate(); 25946 } 25947 if( $("section.faqs").length > 0 && typeof revealAnswer !== 'undefined' && revealAnswer === true ) { 25948 revealfaq(block, quest); 25949 } 25950 if( $("#head-slider").length > 0 ) { 25951 setTimeout(function(){ 25952 $("#head-slider").on("slide.bs.carousel", function(event) { 25953 $(".banner-background").each(function() { 25954 $(this)[0].style.backgroundColor = event.relatedTarget.getAttribute("data-bannerBG"); 25955 }); 25956 $(".banner-text-holder").each(function() { 25957 $(this).fadeOut(750,function() { 25958 $(this)[0].style.color = event.relatedTarget.getAttribute("data-textCOL"); 25959 }); 25960 }); 25961 }); 25962 $("#head-slider").on("slid.bs.carousel", function(event) { 25963 $(".banner-text-holder").each(function() { 25964 var diese = $(this); 25965 setTimeout(function() { 25966 diese.fadeIn(750); 25967 },300); 25968 }); 25969 }); 25970 console.log("Slider loaded."); 25971 },2000); 25972 } 25973 if( $("#kunden-geburtsdatum").length > 0 ) { 25974 $("#kunden-geburtsdatum").inputmask("dd.mm.yyyy"); 25975 } 25976 if( $("#modalKunde").length > 0 && kundenPopUp === true ) { 25977 setTimeout(function() { 25978 $("#modalKunde").modal("show"); 25979 kundenPopUp = false; 25980 }, 1111); 25981 } 25982 25983 refreshVoucherButton(); 25984 thisSiteTitle = $('head > title').text(); 25985}); 25986 25987 25988$(".edit-link[data-action='edit-what']").click(function() { 25989 $( $(this).attr("data-parent") ).addClass("editing"); 25990}); 25991 25992$(".edit-link[data-action='edit-link']").click(function() { 25993 window.location.href = $(this).attr("data-prompt"); 25994}); 25995 25996$(".edit-link[data-action='edit-link-pjax']").click(function() { 25997 let thisLink = $(this).attr("data-container"); 25998 if( thisLink !== "undefined" && thisLink !== "" && thisLink !== null ) { 25999 $.ajax({ 26000 type : 'GET', 26001 async : false, 26002 cache : false, 26003 url : $(this).attr("data-prompt"), 26004 success : function(data) { 26005 $.pjax.reload({ 26006 container: thisLink, 26007 async: false 26008 }); 26009 } 26010 }); 26011 } 26012}); 26013 26014$(".edit-what-abbort").click(function() { 26015 $( $(this).attr("data-parent") ).removeClass("editing"); 26016}); 26017 26018 26019function recoverSiteTitle() { 26020 setTimeout(function() { 26021 $('head > title').text( thisSiteTitle ); 26022 }, 1000); 26023} 26024 26025function closeKDmodalANDsetAction(action, zusatz) { 26026 zusatz = typeof zusatz !== 'undefined' ? zusatz : ''; 26027 let actions = ['update-user', 'update-invoice', 'update-shipping', 'changesponsor', 'select-payment']; 26028 if ( jQuery.inArray( action, actions ) ) { 26029 let url = window.location.href + 'action=' + action + zusatz; 26030 $.ajax({ 26031 type : 'GET', 26032 async : false, 26033 cache : false, 26034 url : url, 26035 success : $.pjax.reload({container:'#pjaxCart', async:false}), 26036 complete: $('#modalKunde').modal('hide') 26037 }); 26038 } 26039} 26040 26041 26042function closeMyModal( modalID ) { 26043 if( $( modalID ).length > 0 ) { 26044 $( modalID ).modal('hide'); 26045 } else { 26046 console.log(modalID + " nicht gefunden!"); 26047 } 26048} 26049 26050function clickMyLink( linkID ) { 26051 if( $( linkID ).length > 0 ) { 26052 $( linkID ).click(); 26053 } else { 26054 console.log(linkID + " nicht gefunden!"); 26055 } 26056} 26057 26058 26059function refreshVoucherButton() { 26060 if( $("#voucher-button").length > 0 ) { 26061 26062 $("#voucher-button").unbind(); 26063 $("#voucher-button").not(".inactive").on('click', function(e) { 26064 e.preventDefault(); 26065 if( $("#voucher-button").hasClass("redeem-voucher") ) { 26066 $.ajax({ 26067 type : 'GET', 26068 data : 'gutscheincode='+$('#neworder-gutscheincode').val(), 26069 async : false, 26070 cache : false, 26071 url : $("#voucher-button").attr("data-url"), 26072 success : function(error) { 26073 let VBerr = parseInt( error ); 26074 switch( VBerr ) { 26075 case 0: 26076 $.pjax.reload({container: '#pjaxCart', async:false}); 26077 $.pjax.reload({container: '#pjaxSeitenkorb', async:false}); 26078 $.pjax.reload({container: '#pjaxWarenkorb', async:false}); 26079 break; 26080 case 1: 26081 swal({ 26082 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26083 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26084 type: 'error' 26085 }); 26086 break; 26087 case 2: 26088 swal({ 26089 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26090 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26091 type: 'error' 26092 }); 26093 break; 26094 case 3: 26095 swal({ 26096 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26097 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26098 type: 'error' 26099 }); 26100 break; 26101 case 4: 26102 swal({ 26103 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26104 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26105 type: 'error' 26106 }); 26107 break; 26108 case 5: 26109 swal({ 26110 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26111 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26112 type: 'error' 26113 }); 26114 break; 26115 case 6: 26116 swal({ 26117 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26118 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26119 type: 'error' 26120 }); 26121 break; 26122 case 7: 26123 swal({ 26124 title: voucherButtonErrorSWAL[ VBerr ]['title'], 26125 html: voucherButtonErrorSWAL[ VBerr ]['html'], 26126 type: 'error' 26127 }); 26128 break; 26129 } 26130 } 26131 }); 26132 return false;
26133 } else if( $("#voucher-button").hasClass("dismiss-voucher") ) { 26134 $.ajax({ 26135 type : 'GET', 26136 async : false, 26137 cache : false, 26138 url : $("#voucher-button").attr("data-url"), 26139 success : function(data) { 26140 $.pjax.reload({container: '#pjaxCart', async:false}); 26141 $.pjax.reload({container: '#pjaxSeitenkorb', async:false}); 26142 $.pjax.reload({container: '#pjaxWarenkorb', async:false}); 26143 } 26144 }); 26145 return false; 26146 } 26147 }); 26148 } 26149} 26150 26151 26152function payment_selection( bezahloption ) { 26153 let $EL = $( "#"+bezahloption ), 26154 $CK = $("#zahlart-" + $EL.attr("data-label")), 26155 $URL= $EL.attr("data-url") + "?bezahlart=" + $CK.attr("data-target"); 26156 if( !$CK.is(":checked") ) { 26157 setTimeout(function() { 26158 $.ajax({ 26159 type : 'GET', 26160 async : false, 26161 cache : false, 26162 url : $URL, 26163 complete: function(data) { 26164 $("#modalKunde").modal("hide"); 26165 $.pjax.reload({container: '#pjaxCart', async:true}); 26166 } 26167 }); 26168 }, 500); 26169 } 26170} 26171 26172function zurKasseButton(e) { 26173 e = e || window.event; 26174 e.preventDefault(); 26175 26176 $.ajax({ 26177 type : "GET", 26178 data : "checkout = 1", 26179 cache : false, 26180 async : false, 26181 url : zurKasseLink + '?checkout=1', 26182 complete: function() { 26183 window.location.href = zurKasseLink; 26184 } 26185 }); 26186} 26187 26188 26189 26190 26191 26192 26193 26194 26195 26196 26197/** 26198 * 26199 * @SIDECART FUNCTIONS 26200 * 26201 **/ 26202function sidecart_toggle() { 26203 $("#sidecart").toggleClass('js-aside-show'); 26204 $.SOW.helper.overlay('toggle'); 26205 26206 // toggle back on overlay click 26207 $("#overlay-default").unbind().on('click', function(e) { 26208 $.SOW.helper.overlay('hide'); 26209 $("#sidecart").removeClass('js-aside-show'); 26210 }); 26211 // toggle back on arrow click 26212 $("#sidecart-close-arrow").unbind().on('click', function(e) { 26213 $.SOW.helper.overlay('hide'); 26214 $("#sidecart").removeClass('js-aside-show'); 26215 }); 26216 // toggle back on cross-click 26217 $("#sidecart-close-cross").unbind().on('click', function(e) { 26218 $.SOW.helper.overlay('hide'); 26219 $("#sidecart").removeClass('js-aside-show'); 26220 }); 26221} 26222function sidecart_cartaction(whatwasdone) { 26223 $("#sidecart")[0].classList.remove('new-item-added','other-item-added','item-removed','item-deleted'); 26224 $("#sidecart")[0].classList.add( whatwasdone ); 26225} 26226function sidecart_changeActiveItem( clicked ) { 26227 $("#pjaxSeitenkorb > .sidecart-item-container").each(function() { 26228 let ae = $(this).attr('id'); 26229 $( '#' + ae ).removeClass("active"); 26230 setTimeout(function() { 26231 document.getElementById( ae ).classList.remove('status-1','status-2','status-3','status-4'); 26232 document.getElementById( ae ).classList.add("status-0"); 26233 }, 120); 26234 }); 26235 26236 $( clicked ).addClass("active"); 26237} 26238function sidecart_deleteItem( item, destination ) { 26239 let cartID = $( item ).attr("data-cartid"); 26240 $( item ).fadeOut(220, function() { 26241 $.ajax({ 26242 type : 'POST', 26243 cache : false, 26244 async : false, 26245 url : destination, 26246 success : function(response) { 26247 $.pjax.reload({container: '#pjaxWarenkorb', async:false}); 26248 $.pjax.reload({container: '#pjaxSeitenkorb', async:false}); 26249 } 26250 }); 26251 }); 26252} 26253 26254$(document).on('pjax:complete', function(e) { 26255 26256 var gespart = parseFloat( $('#pjax-cart-ersparnis').attr('data-pure') ); 26257 26258 console.log( e.target.id ); 26259 26260 // SHOW SIDECART AFTER ITEM ADDED TO CART 26261 if( e.currentTarget.activeElement.classList.contains("toggle-sidecart") && e.target.id == 'pjaxSeitenkorb' ) { 26262 26263 $("#sidecart-total").text( $("#pjax-cart-total").val() ); 26264 $('#sidecart-ersparnis').text( $("#pjax-cart-ersparnis").val() ); 26265 26266 if( gespart > 0 ) { 26267 $('#sidecart-ersparnis-total').removeClass('none'); 26268 } else { 26269 $('#sidecart-ersparnis-total').addClass('none'); 26270 } 26271 sidecart_toggle(); 26272 26273 // UPDATE SIDECART TOTAL PRICE 26274 } else if( e.target.id == 'pjaxSeitenkorb' ) { 26275 26276 let cartPS = $("#pjaxSeitenkorb > .sidecart-item-container").length - 1; 26277 if( cartPS < 0 ) { 26278 $('#sidecart-total').text( $('#sidecart').attr('data-currency') + " 0,00" ); 26279 $('#sidecart-ersparnis').text( $('#sidecart').attr('data-currency') + " 0,00" ); 26280 $('#sidecart-ersparnis-total').addClass('none'); 26281 setTimeout(function() { 26282 $("#sidecart-close-arrow").click(); 26283 }, 333); 26284 } else { 26285 $("#sidecart-total").text( $("#pjax-cart-total").val() );
26286 $('#sidecart-ersparnis').text( $("#pjax-cart-ersparnis").val() ); 26287 if( parseFloat($('#pjax-cart-ersparnis').attr('data-pure')) < 1 ) { 26288 $('#sidecart-ersparnis-total').addClass('none'); 26289 } 26290 } 26291 26292 /*/* item-activation links 26293 $(".item-container-overlay").unbind().on('click', function(e) { 26294 sidecart_changeActiveItem( "#"+e.target.getAttribute("data-parent") ); 26295 }); 26296 */ 26297 26298 26299 /* 26300 } else if( e.target.id == 'pjaxWarenkorb' ) { 26301 return false; 26302 } 26303 */ 26304 26305 26306 26307 // #modalKunde -> Mask #kunden-geburtsdatum 26308 } else if( e.target.id == 'pjaxKunde' ) { 26309 26310 if( $("#kunden-geburtsdatum").length > 0 ) { 26311 $("#kunden-geburtsdatum").unbind().inputmask("dd.mm.yyyy"); 26312 } 26313 26314 // #modalKunde -> AUTO OPEN 26315 } else if( e.target.id == 'pjaxCart' ) { 26316 console.log('kundenPopUp: '+kundenPopUp); 26317 if( kundenPopUp != false && $("#modalKunde").length > 0 ) { 26318 setTimeout(function() { 26319 $("#modalKunde").modal("show"); 26320 kundenPopUp = false; 26321 }, 500); 26322 } 26323 26324 $(".edit-link[data-action='edit-what']").unbind().click(function() { 26325 $( $(this).attr("data-parent") ).addClass("editing"); 26326 }); 26327 26328 $(".edit-link[data-action='edit-link']").unbind().click(function() { 26329 window.location.href = $(this).attr("data-prompt"); 26330 }); 26331 26332 $(".edit-link[data-action='edit-link-pjax']").unbind().click(function() { 26333 let thisLink = $(this).attr("data-container"); 26334 if( thisLink !== "undefined" && thisLink !== "" && thisLink !== null ) { 26335 $.ajax({ 26336 type : 'GET', 26337 async : false, 26338 cache : false, 26339 url : $(this).attr("data-prompt"), 26340 success : function(data) { 26341 $.pjax.reload({ 26342 container: thisLink, 26343 async: false 26344 }); 26345 } 26346 }); 26347 } 26348 }); 26349 26350 $(".edit-what-abbort").unbind().click(function() { 26351 $( $(this).attr("data-parent") ).removeClass("editing"); 26352 }); 26353 26354 links_in_text(); 26355 26356 } else { 26357 console.log( e ); 26358 } 26359 26360}); 26361 26362 26363 26364 26365 26366 26367 26368/* item-activation links 26369$(".item-container-overlay").unbind().on('click', function(e) { 26370 sidecart_changeActiveItem( "#"+e.target.getAttribute("data-parent") ); 26371}); 26372*/ 26373 26374 26375$("#pjax-cart-total").change(function() { 26376 $("#sidecart-total").text( $("#pjax-cart-total").val() ); 26377}); 26378 26379$("#pjax-cart-ersparnis").change(function() { 26380 $("#sidecart-ersparnis").text( $("#pjax-cart-ersparnis").val() ); 26381}); 26382 26383 26384 26385 26386 26387 26388 26389 26390 26391
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.