vendor: 113,357 bytes, lines 1-4077
1/*! 2 * jQuery JavaScript Library v3.7.1 3 * https://jquery.com/ 4 * 5 * Copyright OpenJS Foundation and other contributors 6 * Released under the MIT license 7 * https://jquery.org/license 8 * 9 * Date: 2023-08-28T13:37Z 10 */ 11( function( global, factory ) { 12 13 "use strict"; 14 15 if ( typeof module === "object" && typeof module.exports === "object" ) { 16 17 // For CommonJS and CommonJS-like environments where a proper `window` 18 // is present, execute the factory and get jQuery. 19 // For environments that do not have a `window` with a `document` 20 // (such as Node.js), expose a factory as module.exports. 21 // This accentuates the need for the creation of a real `window`. 22 // e.g. var jQuery = require("jquery")(window); 23 // See ticket trac-14549 for more info. 24 module.exports = global.document ? 25 factory( global, true ) : 26 function( w ) { 27 if ( !w.document ) { 28 throw new Error( "jQuery requires a window with a document" ); 29 } 30 return factory( w ); 31 }; 32 } else { 33 factory( global ); 34 } 35 36// Pass this if window is not defined yet 37} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 38 39// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 40// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 41// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 42// enough that all such attempts are guarded in a try block. 43"use strict"; 44 45var arr = []; 46 47var getProto = Object.getPrototypeOf; 48 49var slice = arr.slice; 50 51var flat = arr.flat ? function( array ) { 52 return arr.flat.call( array ); 53} : function( array ) { 54 return arr.concat.apply( [], array ); 55}; 56 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 isFunction = function isFunction( obj ) { 75 76 // Support: Chrome <=57, Firefox <=52 77 // In some browsers, typeof returns "function" for HTML <object> elements 78 // (i.e., `typeof document.createElement( "object" ) === "function"`). 79 // We don't want to classify *any* DOM node as a function. 80 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 81 // Plus for old WebKit, typeof returns "function" for HTML collections 82 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 83 return typeof obj === "function" && typeof obj.nodeType !== "number" && 84 typeof obj.item !== "function"; 85 }; 86 87 88var isWindow = function isWindow( obj ) { 89 return obj != null && obj === obj.window; 90 }; 91 92 93var document = window.document; 94 95 96 97 var preservedScriptAttributes = { 98 type: true, 99 src: true, 100 nonce: true, 101 noModule: true 102 }; 103 104 function DOMEval( code, node, doc ) { 105 doc = doc || document; 106 107 var i, val, 108 script = doc.createElement( "script" ); 109 110 script.text = code; 111 if ( node ) { 112 for ( i in preservedScriptAttributes ) { 113 114 // Support: Firefox 64+, Edge 18+ 115 // Some browsers don't support the "nonce" property on scripts. 116 // On the other hand, just using `getAttribute` is not enough as 117 // the `nonce` attribute is reset to an empty string whenever it 118 // becomes browsing-context connected. 119 // See https://github.com/whatwg/html/issues/2369 120 // See https://html.spec.whatwg.org/#nonce-attributes 121 // The `node.getAttribute` check was added for the sake of 122 // `jQuery.globalEval` so that it can fake a nonce-containing node 123 // via an object. 124 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 125 if ( val ) { 126 script.setAttribute( i, val ); 127 } 128 } 129 } 130 doc.head.appendChild( script ).parentNode.removeChild( script ); 131 } 132 133 134function toType( obj ) { 135 if ( obj == null ) { 136 return obj + ""; 137 } 138 139 // Support: Android <=2.3 only (functionish RegExp) 140 return typeof obj === "object" || typeof obj === "function" ? 141 class2type[ toString.call( obj ) ] || "object" : 142 typeof obj; 143} 144/* global Symbol */ 145// Defining this global in .eslintrc.json would create a danger of using the global 146// unguarded in another place, it seems safer to define global only for this module 147 148 149 150var version = "3.7.1", 151 152 rhtmlSuffix = /HTML$/i, 153 154 // Define a local copy of jQuery 155 jQuery = function( selector, context ) { 156 157 // The jQuery object is actually just the init constructor 'enhanced' 158 // Need init if jQuery is called (just allow error to be thrown if not included) 159 return new jQuery.fn.init( selector, context ); 160 }; 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 even: function() { 227 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 228 return ( i + 1 ) % 2; 229 } ) ); 230 }, 231 232 odd: function() { 233 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 234 return i % 2; 235 } ) ); 236 }, 237 238 eq: function( i ) { 239 var len = this.length, 240 j = +i + ( i < 0 ? len : 0 ); 241 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 242 }, 243 244 end: function() { 245 return this.prevObject || this.constructor(); 246 }, 247 248 // For internal use only. 249 // Behaves like an Array's method, not like a jQuery method. 250 push: push, 251 sort: arr.sort, 252 splice: arr.splice 253}; 254 255jQuery.extend = jQuery.fn.extend = function() { 256 var options, name, src, copy, copyIsArray, clone, 257 target = arguments[ 0 ] || {}, 258 i = 1, 259 length = arguments.length, 260 deep = false; 261 262 // Handle a deep copy situation 263 if ( typeof target === "boolean" ) { 264 deep = target; 265 266 // Skip the boolean and the target 267 target = arguments[ i ] || {}; 268 i++; 269 } 270 271 // Handle case when target is a string or something (possible in deep copy) 272 if ( typeof target !== "object" && !isFunction( target ) ) { 273 target = {}; 274 } 275 276 // Extend jQuery itself if only one argument is passed 277 if ( i === length ) { 278 target = this; 279 i--; 280 } 281 282 for ( ; i < length; i++ ) { 283 284 // Only deal with non-null/undefined values 285 if ( ( options = arguments[ i ] ) != null ) { 286 287 // Extend the base object 288 for ( name in options ) { 289 copy = options[ name ]; 290 291 // Prevent Object.prototype pollution 292 // Prevent never-ending loop 293 if ( name === "__proto__" || target === copy ) { 294 continue; 295 } 296 297 // Recurse if we're merging plain objects or arrays 298 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 299 ( copyIsArray = Array.isArray( copy ) ) ) ) { 300 src = target[ name ]; 301 302 // Ensure proper type for the source value 303 if ( copyIsArray && !Array.isArray( src ) ) { 304 clone = []; 305 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 306 clone = {}; 307 } else { 308 clone = src; 309 } 310 copyIsArray = false; 311 312 // Never move original objects, clone them 313 target[ name ] = jQuery.extend( deep, clone, copy ); 314 315 // Don't bring in undefined values 316 } else if ( copy !== undefined ) { 317 target[ name ] = copy; 318 } 319 } 320 } 321 } 322 323 // Return the modified object 324 return target; 325}; 326 327jQuery.extend( { 328 329 // Unique for each copy of jQuery on the page 330 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 331 332 // Assume jQuery is ready without the ready module 333 isReady: true, 334 335 error: function( msg ) { 336 throw new Error( msg ); 337 }, 338 339 noop: function() {}, 340 341 isPlainObject: function( obj ) { 342 var proto, Ctor; 343 344 // Detect obvious negatives 345 // Use toString instead of jQuery.type to catch host objects 346 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 347 return false; 348 } 349 350 proto = getProto( obj ); 351 352 // Objects with no prototype (e.g., `Object.create( null )`) are plain 353 if ( !proto ) { 354 return true; 355 } 356 357 // Objects with prototype are plain iff they were constructed by a global Object function 358 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 359 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 360 }, 361 362 isEmptyObject: function( obj ) { 363 var name; 364 365 for ( name in obj ) { 366 return false; 367 } 368 return true; 369 }, 370 371 // Evaluates a script in a provided context; falls back to the global one 372 // if not specified. 373 globalEval: function( code, options, doc ) { 374 DOMEval( code, { nonce: options && options.nonce }, doc ); 375 }, 376 377 each: function( obj, callback ) { 378 var length, i = 0; 379 380 if ( isArrayLike( obj ) ) { 381 length = obj.length; 382 for ( ; i < length; i++ ) { 383 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 384 break; 385 } 386 } 387 } else { 388 for ( i in obj ) { 389 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 390 break; 391 } 392 } 393 } 394 395 return obj; 396 }, 397 398 399 // Retrieve the text value of an array of DOM nodes 400 text: function( elem ) { 401 var node, 402 ret = "", 403 i = 0, 404 nodeType = elem.nodeType; 405 406 if ( !nodeType ) { 407 408 // If no nodeType, this is expected to be an array 409 while ( ( node = elem[ i++ ] ) ) { 410 411 // Do not traverse comment nodes 412 ret += jQuery.text( node ); 413 } 414 } 415 if ( nodeType === 1 || nodeType === 11 ) { 416 return elem.textContent; 417 } 418 if ( nodeType === 9 ) { 419 return elem.documentElement.textContent; 420 } 421 if ( nodeType === 3 || nodeType === 4 ) { 422 return elem.nodeValue; 423 } 424 425 // Do not include comment or processing instruction nodes 426 427 return ret; 428 }, 429 430 // results is for internal usage only 431 makeArray: function( arr, results ) { 432 var ret = results || []; 433 434 if ( arr != null ) { 435 if ( isArrayLike( Object( arr ) ) ) { 436 jQuery.merge( ret, 437 typeof arr === "string" ? 438 [ arr ] : arr 439 ); 440 } else { 441 push.call( ret, arr ); 442 } 443 } 444 445 return ret; 446 }, 447 448 inArray: function( elem, arr, i ) { 449 return arr == null ? -1 : indexOf.call( arr, elem, i ); 450 }, 451 452 isXMLDoc: function( elem ) { 453 var namespace = elem && elem.namespaceURI, 454 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 455 456 // Assume HTML when documentElement doesn't yet exist, such as inside 457 // document fragments. 458 return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); 459 }, 460 461 // Support: Android <=4.0 only, PhantomJS 1 only 462 // push.apply(_, arraylike) throws on ancient WebKit 463 merge: function( first, second ) { 464 var len = +second.length, 465 j = 0, 466 i = first.length; 467 468 for ( ; j < len; j++ ) { 469 first[ i++ ] = second[ j ]; 470 } 471 472 first.length = i; 473 474 return first; 475 }, 476 477 grep: function( elems, callback, invert ) { 478 var callbackInverse, 479 matches = [], 480 i = 0, 481 length = elems.length, 482 callbackExpect = !invert; 483 484 // Go through the array, only saving the items 485 // that pass the validator function 486 for ( ; i < length; i++ ) { 487 callbackInverse = !callback( elems[ i ], i ); 488 if ( callbackInverse !== callbackExpect ) { 489 matches.push( elems[ i ] ); 490 } 491 } 492 493 return matches; 494 }, 495 496 // arg is for internal usage only 497 map: function( elems, callback, arg ) { 498 var length, value, 499 i = 0, 500 ret = []; 501 502 // Go through the array, translating each of the items to their new values 503 if ( isArrayLike( elems ) ) { 504 length = elems.length; 505 for ( ; i < length; i++ ) { 506 value = callback( elems[ i ], i, arg ); 507 508 if ( value != null ) { 509 ret.push( value ); 510 } 511 } 512 513 // Go through every key on the object, 514 } else { 515 for ( i in elems ) { 516 value = callback( elems[ i ], i, arg ); 517 518 if ( value != null ) { 519 ret.push( value ); 520 } 521 } 522 } 523 524 // Flatten any nested arrays 525 return flat( ret ); 526 }, 527 528 // A global GUID counter for objects 529 guid: 1, 530 531 // jQuery.support is not used in Core but other projects attach their 532 // properties to it so it needs to exist. 533 support: support 534} ); 535 536if ( typeof Symbol === "function" ) { 537 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 538} 539 540// Populate the class2type map 541jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 542 function( _i, name ) { 543 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 544 } ); 545 546function isArrayLike( obj ) { 547 548 // Support: real iOS 8.2 only (not reproducible in simulator) 549 // `in` check used to prevent JIT error (gh-2145) 550 // hasOwn isn't used here due to false negatives 551 // regarding Nodelist length in IE 552 var length = !!obj && "length" in obj && obj.length, 553 type = toType( obj ); 554 555 if ( isFunction( obj ) || isWindow( obj ) ) { 556 return false; 557 } 558 559 return type === "array" || length === 0 || 560 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 561} 562 563 564function nodeName( elem, name ) { 565 566 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 567 568} 569var pop = arr.pop; 570 571 572var sort = arr.sort; 573 574 575var splice = arr.splice; 576 577 578var whitespace = "[\\x20\\t\\r\\n\\f]"; 579 580 581var rtrimCSS = new RegExp( 582 "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", 583 "g" 584); 585 586 587 588 589// Note: an element does not contain itself 590jQuery.contains = function( a, b ) { 591 var bup = b && b.parentNode; 592 593 return a === bup || !!( bup && bup.nodeType === 1 && ( 594 595 // Support: IE 9 - 11+ 596 // IE doesn't have `contains` on SVG. 597 a.contains ? 598 a.contains( bup ) : 599 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 600 ) ); 601}; 602 603 604 605 606// CSS string/identifier serialization 607// https://drafts.csswg.org/cssom/#common-serializing-idioms 608var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 609 610function fcssescape( ch, asCodePoint ) { 611 if ( asCodePoint ) { 612 613 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 614 if ( ch === "\0" ) { 615 return "\uFFFD"; 616 } 617 618 // Control characters and (dependent upon position) numbers get escaped as code points 619 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 620 } 621 622 // Other potentially-special ASCII characters get backslash-escaped 623 return "\\" + ch; 624} 625 626jQuery.escapeSelector = function( sel ) { 627 return ( sel + "" ).replace( rcssescape, fcssescape ); 628}; 629 630 631 632 633var preferredDoc = document, 634 pushNative = push; 635 636( function() { 637 638var i, 639 Expr, 640 outermostContext, 641 sortInput, 642 hasDuplicate, 643 push = pushNative, 644 645 // Local document vars 646 document, 647 documentElement, 648 documentIsHTML, 649 rbuggyQSA, 650 matches, 651 652 // Instance-specific data 653 expando = jQuery.expando, 654 dirruns = 0, 655 done = 0, 656 classCache = createCache(), 657 tokenCache = createCache(), 658 compilerCache = createCache(), 659 nonnativeSelectorCache = createCache(), 660 sortOrder = function( a, b ) { 661 if ( a === b ) { 662 hasDuplicate = true; 663 } 664 return 0; 665 }, 666 667 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + 668 "loop|multiple|open|readonly|required|scoped", 669 670 // Regular expressions 671 672 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 673 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 674 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 675 676 // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors 677 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 678 679 // Operator (capture 2) 680 "*([*^$|!~]?=)" + whitespace + 681 682 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 683 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 684 whitespace + "*\\]", 685 686 pseudos = ":(" + identifier + ")(?:\\((" + 687 688 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 689 // 1. quoted (capture 3; capture 4 or capture 5) 690 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 691 692 // 2. simple (capture 6) 693 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 694 695 // 3. anything else (capture 2) 696 ".*" + 697 ")\\)|)", 698 699 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 700 rwhitespace = new RegExp( whitespace + "+", "g" ), 701 702 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 703 rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + 704 whitespace + "*" ), 705 rdescend = new RegExp( whitespace + "|>" ), 706 707 rpseudo = new RegExp( pseudos ), 708 ridentifier = new RegExp( "^" + identifier + "$" ), 709 710 matchExpr = { 711 ID: new RegExp( "^#(" + identifier + ")" ), 712 CLASS: new RegExp( "^\\.(" + identifier + ")" ), 713 TAG: new RegExp( "^(" + identifier + "|[*])" ), 714 ATTR: new RegExp( "^" + attributes ), 715 PSEUDO: new RegExp( "^" + pseudos ), 716 CHILD: new RegExp( 717 "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 718 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 719 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 720 bool: new RegExp( "^(?:" + booleans + ")$", "i" ), 721 722 // For use in libraries implementing .is() 723 // We use this for POS matching in `select` 724 needsContext: new RegExp( "^" + whitespace + 725 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 726 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 727 }, 728 729 rinputs = /^(?:input|select|textarea|button)$/i, 730 rheader = /^h\d$/i, 731 732 // Easily-parseable/retrievable ID or TAG or CLASS selectors 733 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 734 735 rsibling = /[+~]/, 736 737 // CSS escapes 738 // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters 739 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + 740 "?|\\\\([^\\r\\n\\f])", "g" ), 741 funescape = function( escape, nonHex ) { 742 var high = "0x" + escape.slice( 1 ) - 0x10000; 743 744 if ( nonHex ) { 745 746 // Strip the backslash prefix from a non-hex escape sequence 747 return nonHex; 748 } 749 750 // Replace a hexadecimal escape sequence with the encoded Unicode code point 751 // Support: IE <=11+ 752 // For values outside the Basic Multilingual Plane (BMP), manually construct a 753 // surrogate pair 754 return high < 0 ? 755 String.fromCharCode( high + 0x10000 ) : 756 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 757 }, 758 759 // Used for iframes; see `setDocument`. 760 // Support: IE 9 - 11+, Edge 12 - 18+ 761 // Removing the function wrapper causes a "Permission Denied" 762 // error in IE/Edge. 763 unloadHandler = function() { 764 setDocument(); 765 }, 766 767 inDisabledFieldset = addCombinator( 768 function( elem ) { 769 return elem.disabled === true && nodeName( elem, "fieldset" ); 770 }, 771 { dir: "parentNode", next: "legend" } 772 ); 773 774// Support: IE <=9 only 775// Accessing document.activeElement can throw unexpectedly 776// https://bugs.jquery.com/ticket/13393 777function safeActiveElement() { 778 try { 779 return document.activeElement; 780 } catch ( err ) { } 781} 782 783// Optimize for push.apply( _, NodeList ) 784try { 785 push.apply( 786 ( arr = slice.call( preferredDoc.childNodes ) ), 787 preferredDoc.childNodes 788 ); 789 790 // Support: Android <=4.0 791 // Detect silently failing push.apply 792 // eslint-disable-next-line no-unused-expressions 793 arr[ preferredDoc.childNodes.length ].nodeType; 794} catch ( e ) { 795 push = { 796 apply: function( target, els ) { 797 pushNative.apply( target, slice.call( els ) ); 798 }, 799 call: function( target ) { 800 pushNative.apply( target, slice.call( arguments, 1 ) ); 801 } 802 }; 803} 804 805function find( selector, context, results, seed ) { 806 var m, i, elem, nid, match, groups, newSelector, 807 newContext = context && context.ownerDocument, 808 809 // nodeType defaults to 9, since context defaults to document 810 nodeType = context ? context.nodeType : 9; 811 812 results = results || []; 813 814 // Return early from calls with invalid selector or context 815 if ( typeof selector !== "string" || !selector || 816 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 817 818 return results; 819 } 820 821 // Try to shortcut find operations (as opposed to filters) in HTML documents 822 if ( !seed ) { 823 setDocument( context ); 824 context = context || document; 825 826 if ( documentIsHTML ) { 827 828 // If the selector is sufficiently simple, try using a "get*By*" DOM method 829 // (excepting DocumentFragment context, where the methods don't exist) 830 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 831 832 // ID selector 833 if ( ( m = match[ 1 ] ) ) { 834 835 // Document context 836 if ( nodeType === 9 ) { 837 if ( ( elem = context.getElementById( m ) ) ) { 838 839 // Support: IE 9 only 840 // getElementById can match elements by name instead of ID 841 if ( elem.id === m ) { 842 push.call( results, elem ); 843 return results; 844 } 845 } else { 846 return results; 847 } 848 849 // Element context 850 } else { 851 852 // Support: IE 9 only 853 // getElementById can match elements by name instead of ID 854 if ( newContext && ( elem = newContext.getElementById( m ) ) && 855 find.contains( context, elem ) && 856 elem.id === m ) { 857 858 push.call( results, elem ); 859 return results; 860 } 861 } 862 863 // Type selector 864 } else if ( match[ 2 ] ) { 865 push.apply( results, context.getElementsByTagName( selector ) ); 866 return results; 867 868 // Class selector 869 } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { 870 push.apply( results, context.getElementsByClassName( m ) ); 871 return results; 872 } 873 } 874 875 // Take advantage of querySelectorAll 876 if ( !nonnativeSelectorCache[ selector + " " ] && 877 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { 878 879 newSelector = selector; 880 newContext = context; 881 882 // qSA considers elements outside a scoping root when evaluating child or 883 // descendant combinators, which is not what we want. 884 // In such cases, we work around the behavior by prefixing every selector in the 885 // list with an ID selector referencing the scope context. 886 // The technique has to be used as well when a leading combinator is used 887 // as such selectors are not recognized by querySelectorAll. 888 // Thanks to Andrew Dupont for this technique. 889 if ( nodeType === 1 && 890 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { 891 892 // Expand context for sibling selectors 893 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 894 context; 895 896 // We can use :scope instead of the ID hack if the browser 897 // supports it & if we're not changing the context. 898 // Support: IE 11+, Edge 17 - 18+ 899 // IE/Edge sometimes throw a "Permission denied" error when 900 // strict-comparing two documents; shallow comparisons work. 901 // eslint-disable-next-line eqeqeq 902 if ( newContext != context || !support.scope ) { 903 904 // Capture the context ID, setting it first if necessary 905 if ( ( nid = context.getAttribute( "id" ) ) ) { 906 nid = jQuery.escapeSelector( nid ); 907 } else { 908 context.setAttribute( "id", ( nid = expando ) ); 909 } 910 } 911 912 // Prefix every selector in the list 913 groups = tokenize( selector ); 914 i = groups.length; 915 while ( i-- ) { 916 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 917 toSelector( groups[ i ] ); 918 } 919 newSelector = groups.join( "," ); 920 } 921 922 try { 923 push.apply( results, 924 newContext.querySelectorAll( newSelector ) 925 ); 926 return results; 927 } catch ( qsaError ) { 928 nonnativeSelectorCache( selector, true ); 929 } finally { 930 if ( nid === expando ) { 931 context.removeAttribute( "id" ); 932 } 933 } 934 } 935 } 936 } 937 938 // All others 939 return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); 940} 941 942/** 943 * Create key-value caches of limited size 944 * @returns {function(string, object)} Returns the Object data after storing it on itself with 945 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 946 * deleting the oldest entry 947 */ 948function createCache() { 949 var keys = []; 950 951 function cache( key, value ) { 952 953 // Use (key + " ") to avoid collision with native prototype properties 954 // (see https://github.com/jquery/sizzle/issues/157) 955 if ( keys.push( key + " " ) > Expr.cacheLength ) { 956 957 // Only keep the most recent entries 958 delete cache[ keys.shift() ]; 959 } 960 return ( cache[ key + " " ] = value ); 961 } 962 return cache; 963} 964 965/** 966 * Mark a function for special use by jQuery selector module 967 * @param {Function} fn The function to mark 968 */ 969function markFunction( fn ) { 970 fn[ expando ] = true; 971 return fn; 972} 973 974/** 975 * Support testing using an element 976 * @param {Function} fn Passed the created element and returns a boolean result 977 */ 978function assert( fn ) { 979 var el = document.createElement( "fieldset" ); 980 981 try { 982 return !!fn( el ); 983 } catch ( e ) { 984 return false; 985 } finally { 986 987 // Remove from its parent by default 988 if ( el.parentNode ) { 989 el.parentNode.removeChild( el ); 990 } 991 992 // release memory in IE 993 el = null; 994 } 995} 996 997/** 998 * Returns a function to use in pseudos for input types 999 * @param {String} type 1000 */ 1001function createInputPseudo( type ) { 1002 return function( elem ) { 1003 return nodeName( elem, "input" ) && elem.type === type; 1004 }; 1005} 1006 1007/** 1008 * Returns a function to use in pseudos for buttons 1009 * @param {String} type 1010 */ 1011function createButtonPseudo( type ) { 1012 return function( elem ) { 1013 return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && 1014 elem.type === type; 1015 }; 1016} 1017 1018/** 1019 * Returns a function to use in pseudos for :enabled/:disabled 1020 * @param {Boolean} disabled true for :disabled; false for :enabled 1021 */ 1022function createDisabledPseudo( disabled ) { 1023 1024 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 1025 return function( elem ) { 1026 1027 // Only certain elements can match :enabled or :disabled 1028 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 1029 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 1030 if ( "form" in elem ) { 1031 1032 // Check for inherited disabledness on relevant non-disabled elements: 1033 // * listed form-associated elements in a disabled fieldset 1034 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 1035 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1036 // * option elements in a disabled optgroup 1037 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1038 // All such elements have a "form" property. 1039 if ( elem.parentNode && elem.disabled === false ) { 1040 1041 // Option elements defer to a parent optgroup if present 1042 if ( "label" in elem ) { 1043 if ( "label" in elem.parentNode ) { 1044 return elem.parentNode.disabled === disabled; 1045 } else { 1046 return elem.disabled === disabled; 1047 } 1048 } 1049 1050 // Support: IE 6 - 11+ 1051 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1052 return elem.isDisabled === disabled || 1053 1054 // Where there is no isDisabled, check manually 1055 elem.isDisabled !== !disabled && 1056 inDisabledFieldset( elem ) === disabled; 1057 } 1058 1059 return elem.disabled === disabled; 1060 1061 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1062 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1063 // even exist on them, let alone have a boolean value. 1064 } else if ( "label" in elem ) { 1065 return elem.disabled === disabled; 1066 } 1067 1068 // Remaining elements are neither :enabled nor :disabled 1069 return false; 1070 }; 1071} 1072 1073/** 1074 * Returns a function to use in pseudos for positionals 1075 * @param {Function} fn 1076 */ 1077function createPositionalPseudo( fn ) { 1078 return markFunction( function( argument ) { 1079 argument = +argument; 1080 return markFunction( function( seed, matches ) { 1081 var j, 1082 matchIndexes = fn( [], seed.length, argument ), 1083 i = matchIndexes.length; 1084 1085 // Match elements found at the specified indexes 1086 while ( i-- ) { 1087 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 1088 seed[ j ] = !( matches[ j ] = seed[ j ] ); 1089 } 1090 } 1091 } ); 1092 } ); 1093} 1094 1095/** 1096 * Checks a node for validity as a jQuery selector context 1097 * @param {Element|Object=} context 1098 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1099 */ 1100function testContext( context ) { 1101 return context && typeof context.getElementsByTagName !== "undefined" && context; 1102} 1103 1104/** 1105 * Sets document-related variables once based on the current document 1106 * @param {Element|Object} [node] An element or document object to use to set the document 1107 * @returns {Object} Returns the current document 1108 */ 1109function setDocument( node ) { 1110 var subWindow, 1111 doc = node ? node.ownerDocument || node : preferredDoc; 1112 1113 // Return early if doc is invalid or already selected 1114 // Support: IE 11+, Edge 17 - 18+ 1115 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1116 // two documents; shallow comparisons work. 1117 // eslint-disable-next-line eqeqeq 1118 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 1119 return document; 1120 } 1121 1122 // Update global variables 1123 document = doc; 1124 documentElement = document.documentElement; 1125 documentIsHTML = !jQuery.isXMLDoc( document ); 1126 1127 // Support: iOS 7 only, IE 9 - 11+ 1128 // Older browsers didn't support unprefixed `matches`. 1129 matches = documentElement.matches || 1130 documentElement.webkitMatchesSelector || 1131 documentElement.msMatchesSelector; 1132 1133 // Support: IE 9 - 11+, Edge 12 - 18+ 1134 // Accessing iframe documents after unload throws "permission denied" errors 1135 // (see trac-13936). 1136 // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, 1137 // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. 1138 if ( documentElement.msMatchesSelector && 1139 1140 // Support: IE 11+, Edge 17 - 18+ 1141 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1142 // two documents; shallow comparisons work. 1143 // eslint-disable-next-line eqeqeq 1144 preferredDoc != document && 1145 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 1146 1147 // Support: IE 9 - 11+, Edge 12 - 18+ 1148 subWindow.addEventListener( "unload", unloadHandler ); 1149 } 1150 1151 // Support: IE <10 1152 // Check if getElementById returns elements by name 1153 // The broken getElementById methods don't pick up programmatically-set names, 1154 // so use a roundabout getElementsByName test 1155 support.getById = assert( function( el ) { 1156 documentElement.appendChild( el ).id = jQuery.expando; 1157 return !document.getElementsByName || 1158 !document.getElementsByName( jQuery.expando ).length; 1159 } ); 1160 1161 // Support: IE 9 only 1162 // Check to see if it's possible to do matchesSelector 1163 // on a disconnected node. 1164 support.disconnectedMatch = assert( function( el ) { 1165 return matches.call( el, "*" ); 1166 } ); 1167 1168 // Support: IE 9 - 11+, Edge 12 - 18+ 1169 // IE/Edge don't support the :scope pseudo-class. 1170 support.scope = assert( function() { 1171 return document.querySelectorAll( ":scope" ); 1172 } ); 1173 1174 // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only 1175 // Make sure the `:has()` argument is parsed unforgivingly. 1176 // We include `*` in the test to detect buggy implementations that are 1177 // _selectively_ forgiving (specifically when the list includes at least 1178 // one valid selector). 1179 // Note that we treat complete lack of support for `:has()` as if it were 1180 // spec-compliant support, which is fine because use of `:has()` in such 1181 // environments will fail in the qSA path and fall back to jQuery traversal 1182 // anyway. 1183 support.cssHas = assert( function() { 1184 try { 1185 document.querySelector( ":has(*,:jqfake)" ); 1186 return false; 1187 } catch ( e ) { 1188 return true; 1189 } 1190 } ); 1191 1192 // ID filter and find 1193 if ( support.getById ) { 1194 Expr.filter.ID = function( id ) { 1195 var attrId = id.replace( runescape, funescape ); 1196 return function( elem ) { 1197 return elem.getAttribute( "id" ) === attrId; 1198 }; 1199 }; 1200 Expr.find.ID = function( id, context ) { 1201 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1202 var elem = context.getElementById( id ); 1203 return elem ? [ elem ] : []; 1204 } 1205 }; 1206 } else { 1207 Expr.filter.ID = function( id ) { 1208 var attrId = id.replace( runescape, funescape ); 1209 return function( elem ) { 1210 var node = typeof elem.getAttributeNode !== "undefined" && 1211 elem.getAttributeNode( "id" ); 1212 return node && node.value === attrId; 1213 }; 1214 }; 1215 1216 // Support: IE 6 - 7 only 1217 // getElementById is not reliable as a find shortcut 1218 Expr.find.ID = function( id, context ) { 1219 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 1220 var node, i, elems, 1221 elem = context.getElementById( id ); 1222 1223 if ( elem ) { 1224 1225 // Verify the id attribute 1226 node = elem.getAttributeNode( "id" ); 1227 if ( node && node.value === id ) { 1228 return [ elem ]; 1229 } 1230 1231 // Fall back on getElementsByName 1232 elems = context.getElementsByName( id ); 1233 i = 0; 1234 while ( ( elem = elems[ i++ ] ) ) { 1235 node = elem.getAttributeNode( "id" ); 1236 if ( node && node.value === id ) { 1237 return [ elem ]; 1238 } 1239 } 1240 } 1241 1242 return []; 1243 } 1244 }; 1245 } 1246 1247 // Tag 1248 Expr.find.TAG = function( tag, context ) { 1249 if ( typeof context.getElementsByTagName !== "undefined" ) { 1250 return context.getElementsByTagName( tag ); 1251 1252 // DocumentFragment nodes don't have gEBTN 1253 } else { 1254 return context.querySelectorAll( tag ); 1255 } 1256 }; 1257 1258 // Class 1259 Expr.find.CLASS = function( className, context ) { 1260 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 1261 return context.getElementsByClassName( className ); 1262 } 1263 }; 1264 1265 /* QSA/matchesSelector 1266 ---------------------------------------------------------------------- */ 1267 1268 // QSA and matchesSelector support 1269 1270 rbuggyQSA = []; 1271 1272 // Build QSA regex 1273 // Regex strategy adopted from Diego Perini 1274 assert( function( el ) { 1275 1276 var input; 1277 1278 documentElement.appendChild( el ).innerHTML = 1279 "<a id='" + expando + "' href='' disabled='disabled'></a>" + 1280 "<select id='" + expando + "-\r\\' disabled='disabled'>" + 1281 "<option selected=''></option></select>"; 1282 1283 // Support: iOS <=7 - 8 only 1284 // Boolean attributes and "value" are not treated correctly in some XML documents 1285 if ( !el.querySelectorAll( "[selected]" ).length ) { 1286 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 1287 } 1288 1289 // Support: iOS <=7 - 8 only 1290 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 1291 rbuggyQSA.push( "~=" ); 1292 } 1293 1294 // Support: iOS 8 only 1295 // https://bugs.webkit.org/show_bug.cgi?id=136851 1296 // In-page `selector#id sibling-combinator selector` fails 1297 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 1298 rbuggyQSA.push( ".#.+[+~]" ); 1299 } 1300 1301 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1302 // In some of the document kinds, these selectors wouldn't work natively. 1303 // This is probably OK but for backwards compatibility we want to maintain 1304 // handling them through jQuery traversal in jQuery 3.x. 1305 if ( !el.querySelectorAll( ":checked" ).length ) { 1306 rbuggyQSA.push( ":checked" ); 1307 } 1308 1309 // Support: Windows 8 Native Apps 1310 // The type and name attributes are restricted during .innerHTML assignment 1311 input = document.createElement( "input" ); 1312 input.setAttribute( "type", "hidden" ); 1313 el.appendChild( input ).setAttribute( "name", "D" ); 1314 1315 // Support: IE 9 - 11+ 1316 // IE's :disabled selector does not pick up the children of disabled fieldsets 1317 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 1318 // In some of the document kinds, these selectors wouldn't work natively. 1319 // This is probably OK but for backwards compatibility we want to maintain 1320 // handling them through jQuery traversal in jQuery 3.x. 1321 documentElement.appendChild( el ).disabled = true; 1322 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 1323 rbuggyQSA.push( ":enabled", ":disabled" ); 1324 } 1325 1326 // Support: IE 11+, Edge 15 - 18+ 1327 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 1328 // Adding a temporary attribute to the document before the selection works 1329 // around the issue. 1330 // Interestingly, IE 10 & older don't seem to have the issue. 1331 input = document.createElement( "input" ); 1332 input.setAttribute( "name", "" ); 1333 el.appendChild( input ); 1334 if ( !el.querySelectorAll( "[name='']" ).length ) { 1335 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 1336 whitespace + "*(?:''|\"\")" ); 1337 } 1338 } ); 1339 1340 if ( !support.cssHas ) { 1341 1342 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 1343 // Our regular `try-catch` mechanism fails to detect natively-unsupported 1344 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 1345 // in browsers that parse the `:has()` argument as a forgiving selector list. 1346 // https://drafts.csswg.org/selectors/#relational now requires the argument 1347 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 1348 rbuggyQSA.push( ":has" ); 1349 } 1350 1351 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 1352 1353 /* Sorting 1354 ---------------------------------------------------------------------- */ 1355 1356 // Document order sorting 1357 sortOrder = function( a, b ) { 1358 1359 // Flag for duplicate removal 1360 if ( a === b ) { 1361 hasDuplicate = true; 1362 return 0; 1363 } 1364 1365 // Sort on method existence if only one input has compareDocumentPosition 1366 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1367 if ( compare ) { 1368 return compare; 1369 } 1370 1371 // Calculate position if both inputs belong to the same document 1372 // Support: IE 11+, Edge 17 - 18+ 1373 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1374 // two documents; shallow comparisons work. 1375 // eslint-disable-next-line eqeqeq 1376 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 1377 a.compareDocumentPosition( b ) : 1378 1379 // Otherwise we know they are disconnected 1380 1; 1381 1382 // Disconnected nodes 1383 if ( compare & 1 || 1384 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 1385 1386 // Choose the first element that is related to our preferred document 1387 // Support: IE 11+, Edge 17 - 18+ 1388 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1389 // two documents; shallow comparisons work. 1390 // eslint-disable-next-line eqeqeq 1391 if ( a === document || a.ownerDocument == preferredDoc && 1392 find.contains( preferredDoc, a ) ) { 1393 return -1; 1394 } 1395 1396 // Support: IE 11+, Edge 17 - 18+ 1397 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1398 // two documents; shallow comparisons work. 1399 // eslint-disable-next-line eqeqeq 1400 if ( b === document || b.ownerDocument == preferredDoc && 1401 find.contains( preferredDoc, b ) ) { 1402 return 1; 1403 } 1404 1405 // Maintain original order 1406 return sortInput ? 1407 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 1408 0; 1409 } 1410 1411 return compare & 4 ? -1 : 1; 1412 }; 1413 1414 return document; 1415} 1416 1417find.matches = function( expr, elements ) { 1418 return find( expr, null, null, elements ); 1419}; 1420 1421find.matchesSelector = function( elem, expr ) { 1422 setDocument( elem ); 1423 1424 if ( documentIsHTML && 1425 !nonnativeSelectorCache[ expr + " " ] && 1426 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 1427 1428 try { 1429 var ret = matches.call( elem, expr ); 1430 1431 // IE 9's matchesSelector returns false on disconnected nodes 1432 if ( ret || support.disconnectedMatch || 1433 1434 // As well, disconnected nodes are said to be in a document 1435 // fragment in IE 9 1436 elem.document && elem.document.nodeType !== 11 ) { 1437 return ret; 1438 } 1439 } catch ( e ) { 1440 nonnativeSelectorCache( expr, true ); 1441 } 1442 } 1443 1444 return find( expr, document, null, [ elem ] ).length > 0; 1445}; 1446 1447find.contains = function( context, elem ) { 1448 1449 // Set document vars if needed 1450 // Support: IE 11+, Edge 17 - 18+ 1451 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1452 // two documents; shallow comparisons work. 1453 // eslint-disable-next-line eqeqeq 1454 if ( ( context.ownerDocument || context ) != document ) { 1455 setDocument( context ); 1456 } 1457 return jQuery.contains( context, elem ); 1458}; 1459 1460 1461find.attr = function( elem, name ) { 1462 1463 // Set document vars if needed 1464 // Support: IE 11+, Edge 17 - 18+ 1465 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1466 // two documents; shallow comparisons work. 1467 // eslint-disable-next-line eqeqeq 1468 if ( ( elem.ownerDocument || elem ) != document ) { 1469 setDocument( elem ); 1470 } 1471 1472 var fn = Expr.attrHandle[ name.toLowerCase() ], 1473 1474 // Don't get fooled by Object.prototype properties (see trac-13807) 1475 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 1476 fn( elem, name, !documentIsHTML ) : 1477 undefined; 1478 1479 if ( val !== undefined ) { 1480 return val; 1481 } 1482 1483 return elem.getAttribute( name ); 1484}; 1485 1486find.error = function( msg ) { 1487 throw new Error( "Syntax error, unrecognized expression: " + msg ); 1488}; 1489 1490/** 1491 * Document sorting and removing duplicates 1492 * @param {ArrayLike} results 1493 */ 1494jQuery.uniqueSort = function( results ) { 1495 var elem, 1496 duplicates = [], 1497 j = 0, 1498 i = 0; 1499 1500 // Unless we *know* we can detect duplicates, assume their presence 1501 // 1502 // Support: Android <=4.0+ 1503 // Testing for detecting duplicates is unpredictable so instead assume we can't 1504 // depend on duplicate detection in all browsers without a stable sort. 1505 hasDuplicate = !support.sortStable; 1506 sortInput = !support.sortStable && slice.call( results, 0 ); 1507 sort.call( results, sortOrder ); 1508 1509 if ( hasDuplicate ) { 1510 while ( ( elem = results[ i++ ] ) ) { 1511 if ( elem === results[ i ] ) { 1512 j = duplicates.push( i ); 1513 } 1514 } 1515 while ( j-- ) { 1516 splice.call( results, duplicates[ j ], 1 ); 1517 } 1518 } 1519 1520 // Clear input after sorting to release objects 1521 // See https://github.com/jquery/sizzle/pull/225 1522 sortInput = null; 1523 1524 return results; 1525}; 1526 1527jQuery.fn.uniqueSort = function() { 1528 return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); 1529}; 1530 1531Expr = jQuery.expr = { 1532 1533 // Can be adjusted by the user 1534 cacheLength: 50, 1535 1536 createPseudo: markFunction, 1537 1538 match: matchExpr, 1539 1540 attrHandle: {}, 1541 1542 find: {}, 1543 1544 relative: { 1545 ">": { dir: "parentNode", first: true }, 1546 " ": { dir: "parentNode" }, 1547 "+": { dir: "previousSibling", first: true }, 1548 "~": { dir: "previousSibling" } 1549 }, 1550 1551 preFilter: { 1552 ATTR: function( match ) { 1553 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 1554 1555 // Move the given value to match[3] whether quoted or unquoted 1556 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) 1557 .replace( runescape, funescape ); 1558 1559 if ( match[ 2 ] === "~=" ) { 1560 match[ 3 ] = " " + match[ 3 ] + " "; 1561 } 1562 1563 return match.slice( 0, 4 ); 1564 }, 1565 1566 CHILD: function( match ) { 1567 1568 /* matches from matchExpr["CHILD"] 1569 1 type (only|nth|...) 1570 2 what (child|of-type) 1571 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1572 4 xn-component of xn+y argument ([+-]?\d*n|) 1573 5 sign of xn-component 1574 6 x of xn-component 1575 7 sign of y-component 1576 8 y of y-component 1577 */ 1578 match[ 1 ] = match[ 1 ].toLowerCase(); 1579 1580 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 1581 1582 // nth-* requires argument 1583 if ( !match[ 3 ] ) { 1584 find.error( match[ 0 ] ); 1585 } 1586 1587 // numeric x and y parameters for Expr.filter.CHILD 1588 // remember that false/true cast respectively to 0/1 1589 match[ 4 ] = +( match[ 4 ] ? 1590 match[ 5 ] + ( match[ 6 ] || 1 ) : 1591 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) 1592 ); 1593 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 1594 1595 // other types prohibit arguments 1596 } else if ( match[ 3 ] ) { 1597 find.error( match[ 0 ] ); 1598 } 1599 1600 return match; 1601 }, 1602 1603 PSEUDO: function( match ) { 1604 var excess, 1605 unquoted = !match[ 6 ] && match[ 2 ]; 1606 1607 if ( matchExpr.CHILD.test( match[ 0 ] ) ) { 1608 return null; 1609 } 1610 1611 // Accept quoted arguments as-is 1612 if ( match[ 3 ] ) { 1613 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 1614 1615 // Strip excess characters from unquoted arguments 1616 } else if ( unquoted && rpseudo.test( unquoted ) && 1617 1618 // Get excess from tokenize (recursively) 1619 ( excess = tokenize( unquoted, true ) ) && 1620 1621 // advance to the next closing parenthesis 1622 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 1623 1624 // excess is a negative index 1625 match[ 0 ] = match[ 0 ].slice( 0, excess ); 1626 match[ 2 ] = unquoted.slice( 0, excess ); 1627 } 1628 1629 // Return only captures needed by the pseudo filter method (type and argument) 1630 return match.slice( 0, 3 ); 1631 } 1632 }, 1633 1634 filter: { 1635 1636 TAG: function( nodeNameSelector ) { 1637 var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 1638 return nodeNameSelector === "*" ? 1639 function() { 1640 return true; 1641 } : 1642 function( elem ) { 1643 return nodeName( elem, expectedNodeName ); 1644 }; 1645 }, 1646 1647 CLASS: function( className ) { 1648 var pattern = classCache[ className + " " ]; 1649 1650 return pattern || 1651 ( pattern = new RegExp( "(^|" + whitespace + ")" + className + 1652 "(" + whitespace + "|$)" ) ) && 1653 classCache( className, function( elem ) { 1654 return pattern.test( 1655 typeof elem.className === "string" && elem.className || 1656 typeof elem.getAttribute !== "undefined" && 1657 elem.getAttribute( "class" ) || 1658 "" 1659 ); 1660 } ); 1661 }, 1662 1663 ATTR: function( name, operator, check ) { 1664 return function( elem ) { 1665 var result = find.attr( elem, name ); 1666 1667 if ( result == null ) { 1668 return operator === "!="; 1669 } 1670 if ( !operator ) { 1671 return true; 1672 } 1673 1674 result += ""; 1675 1676 if ( operator === "=" ) { 1677 return result === check; 1678 } 1679 if ( operator === "!=" ) { 1680 return result !== check; 1681 } 1682 if ( operator === "^=" ) { 1683 return check && result.indexOf( check ) === 0; 1684 } 1685 if ( operator === "*=" ) { 1686 return check && result.indexOf( check ) > -1; 1687 } 1688 if ( operator === "$=" ) { 1689 return check && result.slice( -check.length ) === check; 1690 } 1691 if ( operator === "~=" ) { 1692 return ( " " + result.replace( rwhitespace, " " ) + " " ) 1693 .indexOf( check ) > -1; 1694 } 1695 if ( operator === "|=" ) { 1696 return result === check || result.slice( 0, check.length + 1 ) === check + "-"; 1697 } 1698 1699 return false; 1700 }; 1701 }, 1702 1703 CHILD: function( type, what, _argument, first, last ) { 1704 var simple = type.slice( 0, 3 ) !== "nth", 1705 forward = type.slice( -4 ) !== "last", 1706 ofType = what === "of-type"; 1707 1708 return first === 1 && last === 0 ? 1709 1710 // Shortcut for :nth-*(n) 1711 function( elem ) { 1712 return !!elem.parentNode; 1713 } : 1714 1715 function( elem, _context, xml ) { 1716 var cache, outerCache, node, nodeIndex, start, 1717 dir = simple !== forward ? "nextSibling" : "previousSibling", 1718 parent = elem.parentNode, 1719 name = ofType && elem.nodeName.toLowerCase(), 1720 useCache = !xml && !ofType, 1721 diff = false; 1722 1723 if ( parent ) { 1724 1725 // :(first|last|only)-(child|of-type) 1726 if ( simple ) { 1727 while ( dir ) { 1728 node = elem; 1729 while ( ( node = node[ dir ] ) ) { 1730 if ( ofType ? 1731 nodeName( node, name ) : 1732 node.nodeType === 1 ) { 1733 1734 return false; 1735 } 1736 } 1737 1738 // Reverse direction for :only-* (if we haven't yet done so) 1739 start = dir = type === "only" && !start && "nextSibling"; 1740 } 1741 return true; 1742 } 1743 1744 start = [ forward ? parent.firstChild : parent.lastChild ]; 1745 1746 // non-xml :nth-child(...) stores cache data on `parent` 1747 if ( forward && useCache ) { 1748 1749 // Seek `elem` from a previously-cached index 1750 outerCache = parent[ expando ] || ( parent[ expando ] = {} ); 1751 cache = outerCache[ type ] || []; 1752 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1753 diff = nodeIndex && cache[ 2 ]; 1754 node = nodeIndex && parent.childNodes[ nodeIndex ]; 1755 1756 while ( ( node = ++nodeIndex && node && node[ dir ] || 1757 1758 // Fallback to seeking `elem` from the start 1759 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1760 1761 // When found, cache indexes on `parent` and break 1762 if ( node.nodeType === 1 && ++diff && node === elem ) { 1763 outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 1764 break; 1765 } 1766 } 1767 1768 } else { 1769 1770 // Use previously-cached element index if available 1771 if ( useCache ) { 1772 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 1773 cache = outerCache[ type ] || []; 1774 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 1775 diff = nodeIndex; 1776 } 1777 1778 // xml :nth-child(...) 1779 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1780 if ( diff === false ) { 1781 1782 // Use the same loop as above to seek `elem` from the start 1783 while ( ( node = ++nodeIndex && node && node[ dir ] || 1784 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 1785 1786 if ( ( ofType ? 1787 nodeName( node, name ) : 1788 node.nodeType === 1 ) && 1789 ++diff ) { 1790 1791 // Cache the index of each encountered element 1792 if ( useCache ) { 1793 outerCache = node[ expando ] || 1794 ( node[ expando ] = {} ); 1795 outerCache[ type ] = [ dirruns, diff ]; 1796 } 1797 1798 if ( node === elem ) { 1799 break; 1800 } 1801 } 1802 } 1803 } 1804 } 1805 1806 // Incorporate the offset, then check against cycle size 1807 diff -= last; 1808 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 1809 } 1810 }; 1811 }, 1812 1813 PSEUDO: function( pseudo, argument ) { 1814 1815 // pseudo-class names are case-insensitive 1816 // https://www.w3.org/TR/selectors/#pseudo-classes 1817 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1818 // Remember that setFilters inherits from pseudos 1819 var args, 1820 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 1821 find.error( "unsupported pseudo: " + pseudo ); 1822 1823 // The user may use createPseudo to indicate that 1824 // arguments are needed to create the filter function 1825 // just as jQuery does 1826 if ( fn[ expando ] ) { 1827 return fn( argument ); 1828 } 1829 1830 // But maintain support for old signatures 1831 if ( fn.length > 1 ) { 1832 args = [ pseudo, pseudo, "", argument ]; 1833 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 1834 markFunction( function( seed, matches ) { 1835 var idx, 1836 matched = fn( seed, argument ), 1837 i = matched.length; 1838 while ( i-- ) { 1839 idx = indexOf.call( seed, matched[ i ] ); 1840 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 1841 } 1842 } ) : 1843 function( elem ) { 1844 return fn( elem, 0, args ); 1845 }; 1846 } 1847 1848 return fn; 1849 } 1850 }, 1851 1852 pseudos: { 1853 1854 // Potentially complex pseudos 1855 not: markFunction( function( selector ) { 1856 1857 // Trim the selector passed to compile 1858 // to avoid treating leading and trailing 1859 // spaces as combinators 1860 var input = [], 1861 results = [], 1862 matcher = compile( selector.replace( rtrimCSS, "$1" ) ); 1863 1864 return matcher[ expando ] ? 1865 markFunction( function( seed, matches, _context, xml ) { 1866 var elem, 1867 unmatched = matcher( seed, null, xml, [] ), 1868 i = seed.length; 1869 1870 // Match elements unmatched by `matcher` 1871 while ( i-- ) { 1872 if ( ( elem = unmatched[ i ] ) ) { 1873 seed[ i ] = !( matches[ i ] = elem ); 1874 } 1875 } 1876 } ) : 1877 function( elem, _context, xml ) { 1878 input[ 0 ] = elem; 1879 matcher( input, null, xml, results ); 1880 1881 // Don't keep the element 1882 // (see https://github.com/jquery/sizzle/issues/299) 1883 input[ 0 ] = null; 1884 return !results.pop(); 1885 }; 1886 } ), 1887 1888 has: markFunction( function( selector ) { 1889 return function( elem ) { 1890 return find( selector, elem ).length > 0; 1891 }; 1892 } ), 1893 1894 contains: markFunction( function( text ) { 1895 text = text.replace( runescape, funescape ); 1896 return function( elem ) { 1897 return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; 1898 }; 1899 } ), 1900 1901 // "Whether an element is represented by a :lang() selector 1902 // is based solely on the element's language value 1903 // being equal to the identifier C, 1904 // or beginning with the identifier C immediately followed by "-". 1905 // The matching of C against the element's language value is performed case-insensitively. 1906 // The identifier C does not have to be a valid language name." 1907 // https://www.w3.org/TR/selectors/#lang-pseudo 1908 lang: markFunction( function( lang ) { 1909 1910 // lang value must be a valid identifier 1911 if ( !ridentifier.test( lang || "" ) ) { 1912 find.error( "unsupported lang: " + lang ); 1913 } 1914 lang = lang.replace( runescape, funescape ).toLowerCase(); 1915 return function( elem ) { 1916 var elemLang; 1917 do { 1918 if ( ( elemLang = documentIsHTML ? 1919 elem.lang : 1920 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 1921 1922 elemLang = elemLang.toLowerCase(); 1923 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 1924 } 1925 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 1926 return false; 1927 }; 1928 } ), 1929 1930 // Miscellaneous 1931 target: function( elem ) { 1932 var hash = window.location && window.location.hash; 1933 return hash && hash.slice( 1 ) === elem.id; 1934 }, 1935 1936 root: function( elem ) { 1937 return elem === documentElement; 1938 }, 1939 1940 focus: function( elem ) { 1941 return elem === safeActiveElement() && 1942 document.hasFocus() && 1943 !!( elem.type || elem.href || ~elem.tabIndex ); 1944 }, 1945 1946 // Boolean properties 1947 enabled: createDisabledPseudo( false ), 1948 disabled: createDisabledPseudo( true ), 1949 1950 checked: function( elem ) { 1951 1952 // In CSS3, :checked should return both checked and selected elements 1953 // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1954 return ( nodeName( elem, "input" ) && !!elem.checked ) || 1955 ( nodeName( elem, "option" ) && !!elem.selected ); 1956 }, 1957 1958 selected: function( elem ) { 1959 1960 // Support: IE <=11+ 1961 // Accessing the selectedIndex property 1962 // forces the browser to treat the default option as 1963 // selected when in an optgroup. 1964 if ( elem.parentNode ) { 1965 // eslint-disable-next-line no-unused-expressions 1966 elem.parentNode.selectedIndex; 1967 } 1968 1969 return elem.selected === true; 1970 }, 1971 1972 // Contents 1973 empty: function( elem ) { 1974 1975 // https://www.w3.org/TR/selectors/#empty-pseudo 1976 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1977 // but not by others (comment: 8; processing instruction: 7; etc.) 1978 // nodeType < 6 works because attributes (2) do not appear as children 1979 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 1980 if ( elem.nodeType < 6 ) { 1981 return false; 1982 } 1983 } 1984 return true; 1985 }, 1986 1987 parent: function( elem ) { 1988 return !Expr.pseudos.empty( elem ); 1989 }, 1990 1991 // Element/input types 1992 header: function( elem ) { 1993 return rheader.test( elem.nodeName ); 1994 }, 1995 1996 input: function( elem ) { 1997 return rinputs.test( elem.nodeName ); 1998 }, 1999 2000 button: function( elem ) { 2001 return nodeName( elem, "input" ) && elem.type === "button" || 2002 nodeName( elem, "button" ); 2003 }, 2004 2005 text: function( elem ) { 2006 var attr; 2007 return nodeName( elem, "input" ) && elem.type === "text" && 2008 2009 // Support: IE <10 only 2010 // New HTML5 attribute values (e.g., "search") appear 2011 // with elem.type === "text" 2012 ( ( attr = elem.getAttribute( "type" ) ) == null || 2013 attr.toLowerCase() === "text" ); 2014 }, 2015 2016 // Position-in-collection 2017 first: createPositionalPseudo( function() { 2018 return [ 0 ]; 2019 } ), 2020 2021 last: createPositionalPseudo( function( _matchIndexes, length ) { 2022 return [ length - 1 ]; 2023 } ), 2024 2025 eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { 2026 return [ argument < 0 ? argument + length : argument ]; 2027 } ), 2028 2029 even: createPositionalPseudo( function( matchIndexes, length ) { 2030 var i = 0; 2031 for ( ; i < length; i += 2 ) { 2032 matchIndexes.push( i ); 2033 } 2034 return matchIndexes; 2035 } ), 2036 2037 odd: createPositionalPseudo( function( matchIndexes, length ) { 2038 var i = 1; 2039 for ( ; i < length; i += 2 ) { 2040 matchIndexes.push( i ); 2041 } 2042 return matchIndexes; 2043 } ), 2044 2045 lt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2046 var i; 2047 2048 if ( argument < 0 ) { 2049 i = argument + length; 2050 } else if ( argument > length ) { 2051 i = length; 2052 } else { 2053 i = argument; 2054 } 2055 2056 for ( ; --i >= 0; ) { 2057 matchIndexes.push( i ); 2058 } 2059 return matchIndexes; 2060 } ), 2061 2062 gt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2063 var i = argument < 0 ? argument + length : argument; 2064 for ( ; ++i < length; ) { 2065 matchIndexes.push( i ); 2066 } 2067 return matchIndexes; 2068 } ) 2069 } 2070}; 2071 2072Expr.pseudos.nth = Expr.pseudos.eq; 2073 2074// Add button/input type pseudos 2075for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2076 Expr.pseudos[ i ] = createInputPseudo( i ); 2077} 2078for ( i in { submit: true, reset: true } ) { 2079 Expr.pseudos[ i ] = createButtonPseudo( i ); 2080} 2081 2082// Easy API for creating new setFilters 2083function setFilters() {} 2084setFilters.prototype = Expr.filters = Expr.pseudos; 2085Expr.setFilters = new setFilters(); 2086 2087function tokenize( selector, parseOnly ) { 2088 var matched, match, tokens, type, 2089 soFar, groups, preFilters, 2090 cached = tokenCache[ selector + " " ]; 2091 2092 if ( cached ) { 2093 return parseOnly ? 0 : cached.slice( 0 ); 2094 } 2095 2096 soFar = selector; 2097 groups = []; 2098 preFilters = Expr.preFilter; 2099 2100 while ( soFar ) { 2101 2102 // Comma and first run 2103 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 2104 if ( match ) { 2105 2106 // Don't consume trailing commas as valid 2107 soFar = soFar.slice( match[ 0 ].length ) || soFar; 2108 } 2109 groups.push( ( tokens = [] ) ); 2110 } 2111 2112 matched = false; 2113 2114 // Combinators 2115 if ( ( match = rleadingCombinator.exec( soFar ) ) ) { 2116 matched = match.shift(); 2117 tokens.push( { 2118 value: matched, 2119 2120 // Cast descendant combinators to space 2121 type: match[ 0 ].replace( rtrimCSS, " " ) 2122 } ); 2123 soFar = soFar.slice( matched.length ); 2124 } 2125 2126 // Filters 2127 for ( type in Expr.filter ) { 2128 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 2129 ( match = preFilters[ type ]( match ) ) ) ) { 2130 matched = match.shift(); 2131 tokens.push( { 2132 value: matched, 2133 type: type, 2134 matches: match 2135 } ); 2136 soFar = soFar.slice( matched.length ); 2137 } 2138 } 2139 2140 if ( !matched ) { 2141 break; 2142 } 2143 } 2144 2145 // Return the length of the invalid excess 2146 // if we're just parsing 2147 // Otherwise, throw an error or return tokens 2148 if ( parseOnly ) { 2149 return soFar.length; 2150 } 2151 2152 return soFar ? 2153 find.error( selector ) : 2154 2155 // Cache the tokens 2156 tokenCache( selector, groups ).slice( 0 ); 2157} 2158 2159function toSelector( tokens ) { 2160 var i = 0, 2161 len = tokens.length, 2162 selector = ""; 2163 for ( ; i < len; i++ ) { 2164 selector += tokens[ i ].value; 2165 } 2166 return selector; 2167} 2168 2169function addCombinator( matcher, combinator, base ) { 2170 var dir = combinator.dir, 2171 skip = combinator.next, 2172 key = skip || dir, 2173 checkNonElements = base && key === "parentNode", 2174 doneName = done++; 2175 2176 return combinator.first ? 2177 2178 // Check against closest ancestor/preceding element 2179 function( elem, context, xml ) { 2180 while ( ( elem = elem[ dir ] ) ) { 2181 if ( elem.nodeType === 1 || checkNonElements ) { 2182 return matcher( elem, context, xml ); 2183 } 2184 } 2185 return false; 2186 } : 2187 2188 // Check against all ancestor/preceding elements 2189 function( elem, context, xml ) { 2190 var oldCache, outerCache, 2191 newCache = [ dirruns, doneName ]; 2192 2193 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2194 if ( xml ) { 2195 while ( ( elem = elem[ dir ] ) ) { 2196 if ( elem.nodeType === 1 || checkNonElements ) { 2197 if ( matcher( elem, context, xml ) ) { 2198 return true; 2199 } 2200 } 2201 } 2202 } else { 2203 while ( ( elem = elem[ dir ] ) ) { 2204 if ( elem.nodeType === 1 || checkNonElements ) { 2205 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 2206 2207 if ( skip && nodeName( elem, skip ) ) { 2208 elem = elem[ dir ] || elem; 2209 } else if ( ( oldCache = outerCache[ key ] ) && 2210 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 2211 2212 // Assign to newCache so results back-propagate to previous elements 2213 return ( newCache[ 2 ] = oldCache[ 2 ] ); 2214 } else { 2215 2216 // Reuse newcache so results back-propagate to previous elements 2217 outerCache[ key ] = newCache; 2218 2219 // A match means we're done; a fail means we have to keep checking 2220 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 2221 return true; 2222 } 2223 } 2224 } 2225 } 2226 } 2227 return false; 2228 }; 2229} 2230 2231function elementMatcher( matchers ) { 2232 return matchers.length > 1 ? 2233 function( elem, context, xml ) { 2234 var i = matchers.length; 2235 while ( i-- ) { 2236 if ( !matchers[ i ]( elem, context, xml ) ) { 2237 return false; 2238 } 2239 } 2240 return true; 2241 } : 2242 matchers[ 0 ]; 2243} 2244 2245function multipleContexts( selector, contexts, results ) { 2246 var i = 0, 2247 len = contexts.length; 2248 for ( ; i < len; i++ ) { 2249 find( selector, contexts[ i ], results ); 2250 } 2251 return results; 2252} 2253 2254function condense( unmatched, map, filter, context, xml ) { 2255 var elem, 2256 newUnmatched = [], 2257 i = 0, 2258 len = unmatched.length, 2259 mapped = map != null; 2260 2261 for ( ; i < len; i++ ) { 2262 if ( ( elem = unmatched[ i ] ) ) { 2263 if ( !filter || filter( elem, context, xml ) ) { 2264 newUnmatched.push( elem ); 2265 if ( mapped ) { 2266 map.push( i ); 2267 } 2268 } 2269 } 2270 } 2271 2272 return newUnmatched; 2273} 2274 2275function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 2276 if ( postFilter && !postFilter[ expando ] ) { 2277 postFilter = setMatcher( postFilter ); 2278 } 2279 if ( postFinder && !postFinder[ expando ] ) { 2280 postFinder = setMatcher( postFinder, postSelector ); 2281 } 2282 return markFunction( function( seed, results, context, xml ) { 2283 var temp, i, elem, matcherOut, 2284 preMap = [], 2285 postMap = [], 2286 preexisting = results.length, 2287 2288 // Get initial elements from seed or context 2289 elems = seed || 2290 multipleContexts( selector || "*", 2291 context.nodeType ? [ context ] : context, [] ), 2292 2293 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2294 matcherIn = preFilter && ( seed || !selector ) ? 2295 condense( elems, preMap, preFilter, context, xml ) : 2296 elems; 2297 2298 if ( matcher ) { 2299 2300 // If we have a postFinder, or filtered seed, or non-seed postFilter 2301 // or preexisting results, 2302 matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 2303 2304 // ...intermediate processing is necessary 2305 [] : 2306 2307 // ...otherwise use results directly 2308 results; 2309 2310 // Find primary matches 2311 matcher( matcherIn, matcherOut, context, xml ); 2312 } else { 2313 matcherOut = matcherIn; 2314 } 2315 2316 // Apply postFilter 2317 if ( postFilter ) { 2318 temp = condense( matcherOut, postMap ); 2319 postFilter( temp, [], context, xml ); 2320 2321 // Un-match failing elements by moving them back to matcherIn 2322 i = temp.length; 2323 while ( i-- ) { 2324 if ( ( elem = temp[ i ] ) ) { 2325 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 2326 } 2327 } 2328 } 2329 2330 if ( seed ) { 2331 if ( postFinder || preFilter ) { 2332 if ( postFinder ) { 2333 2334 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2335 temp = []; 2336 i = matcherOut.length; 2337 while ( i-- ) { 2338 if ( ( elem = matcherOut[ i ] ) ) { 2339 2340 // Restore matcherIn since elem is not yet a final match 2341 temp.push( ( matcherIn[ i ] = elem ) ); 2342 } 2343 } 2344 postFinder( null, ( matcherOut = [] ), temp, xml ); 2345 } 2346 2347 // Move matched elements from seed to results to keep them synchronized 2348 i = matcherOut.length; 2349 while ( i-- ) { 2350 if ( ( elem = matcherOut[ i ] ) && 2351 ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { 2352 2353 seed[ temp ] = !( results[ temp ] = elem ); 2354 } 2355 } 2356 } 2357 2358 // Add elements to results, through postFinder if defined 2359 } else { 2360 matcherOut = condense( 2361 matcherOut === results ? 2362 matcherOut.splice( preexisting, matcherOut.length ) : 2363 matcherOut 2364 ); 2365 if ( postFinder ) { 2366 postFinder( null, results, matcherOut, xml ); 2367 } else { 2368 push.apply( results, matcherOut ); 2369 } 2370 } 2371 } ); 2372} 2373 2374function matcherFromTokens( tokens ) { 2375 var checkContext, matcher, j, 2376 len = tokens.length, 2377 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 2378 implicitRelative = leadingRelative || Expr.relative[ " " ], 2379 i = leadingRelative ? 1 : 0, 2380 2381 // The foundational matcher ensures that elements are reachable from top-level context(s) 2382 matchContext = addCombinator( function( elem ) { 2383 return elem === checkContext; 2384 }, implicitRelative, true ), 2385 matchAnyContext = addCombinator( function( elem ) { 2386 return indexOf.call( checkContext, elem ) > -1; 2387 }, implicitRelative, true ), 2388 matchers = [ function( elem, context, xml ) { 2389 2390 // Support: IE 11+, Edge 17 - 18+ 2391 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2392 // two documents; shallow comparisons work. 2393 // eslint-disable-next-line eqeqeq 2394 var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( 2395 ( checkContext = context ).nodeType ? 2396 matchContext( elem, context, xml ) : 2397 matchAnyContext( elem, context, xml ) ); 2398 2399 // Avoid hanging onto element 2400 // (see https://github.com/jquery/sizzle/issues/299) 2401 checkContext = null; 2402 return ret; 2403 } ]; 2404 2405 for ( ; i < len; i++ ) { 2406 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 2407 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 2408 } else { 2409 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 2410 2411 // Return special upon seeing a positional matcher 2412 if ( matcher[ expando ] ) { 2413 2414 // Find the next relative operator (if any) for proper handling 2415 j = ++i; 2416 for ( ; j < len; j++ ) { 2417 if ( Expr.relative[ tokens[ j ].type ] ) { 2418 break; 2419 } 2420 } 2421 return setMatcher( 2422 i > 1 && elementMatcher( matchers ), 2423 i > 1 && toSelector( 2424 2425 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2426 tokens.slice( 0, i - 1 ) 2427 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 2428 ).replace( rtrimCSS, "$1" ), 2429 matcher, 2430 i < j && matcherFromTokens( tokens.slice( i, j ) ), 2431 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 2432 j < len && toSelector( tokens ) 2433 ); 2434 } 2435 matchers.push( matcher ); 2436 } 2437 } 2438 2439 return elementMatcher( matchers ); 2440} 2441 2442function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 2443 var bySet = setMatchers.length > 0, 2444 byElement = elementMatchers.length > 0, 2445 superMatcher = function( seed, context, xml, results, outermost ) { 2446 var elem, j, matcher, 2447 matchedCount = 0, 2448 i = "0", 2449 unmatched = seed && [], 2450 setMatched = [], 2451 contextBackup = outermostContext, 2452 2453 // We must always have either seed elements or outermost context 2454 elems = seed || byElement && Expr.find.TAG( "*", outermost ), 2455 2456 // Use integer dirruns iff this is the outermost matcher 2457 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 2458 len = elems.length; 2459 2460 if ( outermost ) { 2461 2462 // Support: IE 11+, Edge 17 - 18+ 2463 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2464 // two documents; shallow comparisons work. 2465 // eslint-disable-next-line eqeqeq 2466 outermostContext = context == document || context || outermost; 2467 } 2468 2469 // Add elements passing elementMatchers directly to results 2470 // Support: iOS <=7 - 9 only 2471 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching 2472 // elements by id. (see trac-14142) 2473 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 2474 if ( byElement && elem ) { 2475 j = 0; 2476 2477 // Support: IE 11+, Edge 17 - 18+ 2478 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2479 // two documents; shallow comparisons work. 2480 // eslint-disable-next-line eqeqeq 2481 if ( !context && elem.ownerDocument != document ) { 2482 setDocument( elem ); 2483 xml = !documentIsHTML; 2484 } 2485 while ( ( matcher = elementMatchers[ j++ ] ) ) { 2486 if ( matcher( elem, context || document, xml ) ) { 2487 push.call( results, elem ); 2488 break; 2489 } 2490 } 2491 if ( outermost ) { 2492 dirruns = dirrunsUnique; 2493 } 2494 } 2495 2496 // Track unmatched elements for set filters 2497 if ( bySet ) { 2498 2499 // They will have gone through all possible matchers 2500 if ( ( elem = !matcher && elem ) ) { 2501 matchedCount--; 2502 } 2503 2504 // Lengthen the array for every element, matched or not 2505 if ( seed ) { 2506 unmatched.push( elem ); 2507 } 2508 } 2509 } 2510 2511 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2512 // makes the latter nonnegative. 2513 matchedCount += i; 2514 2515 // Apply set filters to unmatched elements 2516 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2517 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2518 // no element matchers and no seed. 2519 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2520 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2521 // numerically zero. 2522 if ( bySet && i !== matchedCount ) { 2523 j = 0; 2524 while ( ( matcher = setMatchers[ j++ ] ) ) { 2525 matcher( unmatched, setMatched, context, xml ); 2526 } 2527 2528 if ( seed ) { 2529 2530 // Reintegrate element matches to eliminate the need for sorting 2531 if ( matchedCount > 0 ) { 2532 while ( i-- ) { 2533 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 2534 setMatched[ i ] = pop.call( results ); 2535 } 2536 } 2537 } 2538 2539 // Discard index placeholder values to get only actual matches 2540 setMatched = condense( setMatched ); 2541 } 2542 2543 // Add matches to results 2544 push.apply( results, setMatched ); 2545 2546 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2547 if ( outermost && !seed && setMatched.length > 0 && 2548 ( matchedCount + setMatchers.length ) > 1 ) { 2549 2550 jQuery.uniqueSort( results ); 2551 } 2552 } 2553 2554 // Override manipulation of globals by nested matchers 2555 if ( outermost ) { 2556 dirruns = dirrunsUnique; 2557 outermostContext = contextBackup; 2558 } 2559 2560 return unmatched; 2561 }; 2562 2563 return bySet ? 2564 markFunction( superMatcher ) : 2565 superMatcher; 2566} 2567 2568function compile( selector, match /* Internal Use Only */ ) { 2569 var i, 2570 setMatchers = [], 2571 elementMatchers = [], 2572 cached = compilerCache[ selector + " " ]; 2573 2574 if ( !cached ) { 2575 2576 // Generate a function of recursive functions that can be used to check each element 2577 if ( !match ) { 2578 match = tokenize( selector ); 2579 } 2580 i = match.length; 2581 while ( i-- ) { 2582 cached = matcherFromTokens( match[ i ] ); 2583 if ( cached[ expando ] ) { 2584 setMatchers.push( cached ); 2585 } else { 2586 elementMatchers.push( cached ); 2587 } 2588 } 2589 2590 // Cache the compiled function 2591 cached = compilerCache( selector, 2592 matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 2593 2594 // Save selector and tokenization 2595 cached.selector = selector; 2596 } 2597 return cached; 2598} 2599 2600/** 2601 * A low-level selection function that works with jQuery's compiled 2602 * selector functions 2603 * @param {String|Function} selector A selector or a pre-compiled 2604 * selector function built with jQuery selector compile 2605 * @param {Element} context 2606 * @param {Array} [results] 2607 * @param {Array} [seed] A set of elements to match against 2608 */ 2609function select( selector, context, results, seed ) { 2610 var i, tokens, token, type, find, 2611 compiled = typeof selector === "function" && selector, 2612 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 2613 2614 results = results || []; 2615 2616 // Try to minimize operations if there is only one selector in the list and no seed 2617 // (the latter of which guarantees us context) 2618 if ( match.length === 1 ) { 2619 2620 // Reduce context if the leading compound selector is an ID 2621 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 2622 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 2623 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 2624 2625 context = ( Expr.find.ID( 2626 token.matches[ 0 ].replace( runescape, funescape ), 2627 context 2628 ) || [] )[ 0 ]; 2629 if ( !context ) { 2630 return results; 2631 2632 // Precompiled matchers will still verify ancestry, so step up a level 2633 } else if ( compiled ) { 2634 context = context.parentNode; 2635 } 2636 2637 selector = selector.slice( tokens.shift().value.length ); 2638 } 2639 2640 // Fetch a seed set for right-to-left matching 2641 i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; 2642 while ( i-- ) { 2643 token = tokens[ i ]; 2644 2645 // Abort if we hit a combinator 2646 if ( Expr.relative[ ( type = token.type ) ] ) { 2647 break; 2648 } 2649 if ( ( find = Expr.find[ type ] ) ) { 2650 2651 // Search, expanding context for leading sibling combinators 2652 if ( ( seed = find( 2653 token.matches[ 0 ].replace( runescape, funescape ), 2654 rsibling.test( tokens[ 0 ].type ) && 2655 testContext( context.parentNode ) || context 2656 ) ) ) { 2657 2658 // If seed is empty or no tokens remain, we can return early 2659 tokens.splice( i, 1 ); 2660 selector = seed.length && toSelector( tokens ); 2661 if ( !selector ) { 2662 push.apply( results, seed ); 2663 return results; 2664 } 2665 2666 break; 2667 } 2668 } 2669 } 2670 } 2671 2672 // Compile and execute a filtering function if one is not provided 2673 // Provide `match` to avoid retokenization if we modified the selector above 2674 ( compiled || compile( selector, match ) )( 2675 seed, 2676 context, 2677 !documentIsHTML, 2678 results, 2679 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 2680 ); 2681 return results; 2682} 2683 2684// One-time assignments 2685 2686// Support: Android <=4.0 - 4.1+ 2687// Sort stability 2688support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 2689 2690// Initialize against the default document 2691setDocument(); 2692 2693// Support: Android <=4.0 - 4.1+ 2694// Detached nodes confoundingly follow *each other* 2695support.sortDetached = assert( function( el ) { 2696 2697 // Should return 1, but returns 4 (following) 2698 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 2699} ); 2700 2701jQuery.find = find; 2702 2703// Deprecated 2704jQuery.expr[ ":" ] = jQuery.expr.pseudos; 2705jQuery.unique = jQuery.uniqueSort; 2706 2707// These have always been private, but they used to be documented as part of 2708// Sizzle so let's maintain them for now for backwards compatibility purposes. 2709find.compile = compile; 2710find.select = select; 2711find.setDocument = setDocument; 2712find.tokenize = tokenize; 2713 2714find.escape = jQuery.escapeSelector; 2715find.getText = jQuery.text; 2716find.isXML = jQuery.isXMLDoc; 2717find.selectors = jQuery.expr; 2718find.support = jQuery.support; 2719find.uniqueSort = jQuery.uniqueSort; 2720 2721 /* eslint-enable */ 2722 2723} )(); 2724 2725 2726var dir = function( elem, dir, until ) { 2727 var matched = [], 2728 truncate = until !== undefined; 2729 2730 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 2731 if ( elem.nodeType === 1 ) { 2732 if ( truncate && jQuery( elem ).is( until ) ) { 2733 break; 2734 } 2735 matched.push( elem ); 2736 } 2737 } 2738 return matched; 2739}; 2740 2741 2742var siblings = function( n, elem ) { 2743 var matched = []; 2744 2745 for ( ; n; n = n.nextSibling ) { 2746 if ( n.nodeType === 1 && n !== elem ) { 2747 matched.push( n ); 2748 } 2749 } 2750 2751 return matched; 2752}; 2753 2754 2755var rneedsContext = jQuery.expr.match.needsContext; 2756 2757var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 2758 2759 2760 2761// Implement the identical functionality for filter and not 2762function winnow( elements, qualifier, not ) { 2763 if ( isFunction( qualifier ) ) { 2764 return jQuery.grep( elements, function( elem, i ) { 2765 return !!qualifier.call( elem, i, elem ) !== not; 2766 } ); 2767 } 2768 2769 // Single element 2770 if ( qualifier.nodeType ) { 2771 return jQuery.grep( elements, function( elem ) { 2772 return ( elem === qualifier ) !== not; 2773 } ); 2774 } 2775 2776 // Arraylike of elements (jQuery, arguments, Array) 2777 if ( typeof qualifier !== "string" ) { 2778 return jQuery.grep( elements, function( elem ) { 2779 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 2780 } ); 2781 } 2782 2783 // Filtered directly for both simple and complex selectors 2784 return jQuery.filter( qualifier, elements, not ); 2785} 2786 2787jQuery.filter = function( expr, elems, not ) { 2788 var elem = elems[ 0 ]; 2789 2790 if ( not ) { 2791 expr = ":not(" + expr + ")"; 2792 } 2793 2794 if ( elems.length === 1 && elem.nodeType === 1 ) { 2795 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 2796 } 2797 2798 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 2799 return elem.nodeType === 1; 2800 } ) ); 2801}; 2802 2803jQuery.fn.extend( { 2804 find: function( selector ) { 2805 var i, ret, 2806 len = this.length, 2807 self = this; 2808 2809 if ( typeof selector !== "string" ) { 2810 return this.pushStack( jQuery( selector ).filter( function() { 2811 for ( i = 0; i < len; i++ ) { 2812 if ( jQuery.contains( self[ i ], this ) ) { 2813 return true; 2814 } 2815 } 2816 } ) ); 2817 } 2818 2819 ret = this.pushStack( [] ); 2820 2821 for ( i = 0; i < len; i++ ) { 2822 jQuery.find( selector, self[ i ], ret ); 2823 } 2824 2825 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 2826 }, 2827 filter: function( selector ) { 2828 return this.pushStack( winnow( this, selector || [], false ) ); 2829 }, 2830 not: function( selector ) { 2831 return this.pushStack( winnow( this, selector || [], true ) ); 2832 }, 2833 is: function( selector ) { 2834 return !!winnow( 2835 this, 2836 2837 // If this is a positional/relative selector, check membership in the returned set 2838 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2839 typeof selector === "string" && rneedsContext.test( selector ) ? 2840 jQuery( selector ) : 2841 selector || [], 2842 false 2843 ).length; 2844 } 2845} ); 2846 2847 2848// Initialize a jQuery object 2849 2850 2851// A central reference to the root jQuery(document) 2852var rootjQuery, 2853 2854 // A simple way to check for HTML strings 2855 // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521) 2856 // Strict HTML recognition (trac-11290: must start with <) 2857 // Shortcut simple #id case for speed 2858 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 2859 2860 init = jQuery.fn.init = function( selector, context, root ) { 2861 var match, elem; 2862 2863 // HANDLE: $(""), $(null), $(undefined), $(false) 2864 if ( !selector ) { 2865 return this; 2866 } 2867 2868 // Method init() accepts an alternate rootjQuery 2869 // so migrate can support jQuery.sub (gh-2101) 2870 root = root || rootjQuery; 2871 2872 // Handle HTML strings 2873 if ( typeof selector === "string" ) { 2874 if ( selector[ 0 ] === "<" && 2875 selector[ selector.length - 1 ] === ">" && 2876 selector.length >= 3 ) { 2877 2878 // Assume that strings that start and end with <> are HTML and skip the regex check 2879 match = [ null, selector, null ]; 2880 2881 } else { 2882 match = rquickExpr.exec( selector ); 2883 } 2884 2885 // Match html or make sure no context is specified for #id 2886 if ( match && ( match[ 1 ] || !context ) ) { 2887 2888 // HANDLE: $(html) -> $(array) 2889 if ( match[ 1 ] ) { 2890 context = context instanceof jQuery ? context[ 0 ] : context; 2891 2892 // Option to run scripts is true for back-compat 2893 // Intentionally let the error be thrown if parseHTML is not present 2894 jQuery.merge( this, jQuery.parseHTML( 2895 match[ 1 ], 2896 context && context.nodeType ? context.ownerDocument || context : document, 2897 true 2898 ) ); 2899 2900 // HANDLE: $(html, props) 2901 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 2902 for ( match in context ) { 2903 2904 // Properties of context are called as methods if possible 2905 if ( isFunction( this[ match ] ) ) { 2906 this[ match ]( context[ match ] ); 2907 2908 // ...and otherwise set as attributes 2909 } else { 2910 this.attr( match, context[ match ] ); 2911 } 2912 } 2913 } 2914 2915 return this; 2916 2917 // HANDLE: $(#id) 2918 } else { 2919 elem = document.getElementById( match[ 2 ] ); 2920 2921 if ( elem ) { 2922 2923 // Inject the element directly into the jQuery object 2924 this[ 0 ] = elem; 2925 this.length = 1; 2926 } 2927 return this; 2928 } 2929 2930 // HANDLE: $(expr, $(...)) 2931 } else if ( !context || context.jquery ) { 2932 return ( context || root ).find( selector ); 2933 2934 // HANDLE: $(expr, context) 2935 // (which is just equivalent to: $(context).find(expr) 2936 } else { 2937 return this.constructor( context ).find( selector ); 2938 } 2939 2940 // HANDLE: $(DOMElement) 2941 } else if ( selector.nodeType ) { 2942 this[ 0 ] = selector; 2943 this.length = 1; 2944 return this; 2945 2946 // HANDLE: $(function) 2947 // Shortcut for document ready 2948 } else if ( isFunction( selector ) ) { 2949 return root.ready !== undefined ? 2950 root.ready( selector ) : 2951 2952 // Execute immediately if ready is not present 2953 selector( jQuery ); 2954 } 2955 2956 return jQuery.makeArray( selector, this ); 2957 }; 2958 2959// Give the init function the jQuery prototype for later instantiation 2960init.prototype = jQuery.fn; 2961 2962// Initialize central reference 2963rootjQuery = jQuery( document ); 2964 2965 2966var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2967 2968 // Methods guaranteed to produce a unique set when starting from a unique set 2969 guaranteedUnique = { 2970 children: true, 2971 contents: true, 2972 next: true, 2973 prev: true 2974 }; 2975 2976jQuery.fn.extend( { 2977 has: function( target ) { 2978 var targets = jQuery( target, this ), 2979 l = targets.length; 2980 2981 return this.filter( function() { 2982 var i = 0; 2983 for ( ; i < l; i++ ) { 2984 if ( jQuery.contains( this, targets[ i ] ) ) { 2985 return true; 2986 } 2987 } 2988 } ); 2989 }, 2990 2991 closest: function( selectors, context ) { 2992 var cur, 2993 i = 0, 2994 l = this.length, 2995 matched = [], 2996 targets = typeof selectors !== "string" && jQuery( selectors ); 2997 2998 // Positional selectors never match, since there's no _selection_ context 2999 if ( !rneedsContext.test( selectors ) ) { 3000 for ( ; i < l; i++ ) { 3001 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3002 3003 // Always skip document fragments 3004 if ( cur.nodeType < 11 && ( targets ? 3005 targets.index( cur ) > -1 : 3006 3007 // Don't pass non-elements to jQuery#find 3008 cur.nodeType === 1 && 3009 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3010 3011 matched.push( cur ); 3012 break; 3013 } 3014 } 3015 } 3016 } 3017 3018 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3019 }, 3020 3021 // Determine the position of an element within the set 3022 index: function( elem ) { 3023 3024 // No argument, return index in parent 3025 if ( !elem ) { 3026 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3027 } 3028 3029 // Index in selector 3030 if ( typeof elem === "string" ) { 3031 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3032 } 3033 3034 // Locate the position of the desired element 3035 return indexOf.call( this, 3036 3037 // If it receives a jQuery object, the first element is used 3038 elem.jquery ? elem[ 0 ] : elem 3039 ); 3040 }, 3041 3042 add: function( selector, context ) { 3043 return this.pushStack( 3044 jQuery.uniqueSort( 3045 jQuery.merge( this.get(), jQuery( selector, context ) ) 3046 ) 3047 ); 3048 }, 3049 3050 addBack: function( selector ) { 3051 return this.add( selector == null ? 3052 this.prevObject : this.prevObject.filter( selector ) 3053 ); 3054 } 3055} ); 3056 3057function sibling( cur, dir ) { 3058 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3059 return cur; 3060} 3061 3062jQuery.each( { 3063 parent: function( elem ) { 3064 var parent = elem.parentNode; 3065 return parent && parent.nodeType !== 11 ? parent : null; 3066 }, 3067 parents: function( elem ) { 3068 return dir( elem, "parentNode" ); 3069 }, 3070 parentsUntil: function( elem, _i, until ) { 3071 return dir( elem, "parentNode", until ); 3072 }, 3073 next: function( elem ) { 3074 return sibling( elem, "nextSibling" ); 3075 }, 3076 prev: function( elem ) { 3077 return sibling( elem, "previousSibling" ); 3078 }, 3079 nextAll: function( elem ) { 3080 return dir( elem, "nextSibling" ); 3081 }, 3082 prevAll: function( elem ) { 3083 return dir( elem, "previousSibling" ); 3084 }, 3085 nextUntil: function( elem, _i, until ) { 3086 return dir( elem, "nextSibling", until ); 3087 }, 3088 prevUntil: function( elem, _i, until ) { 3089 return dir( elem, "previousSibling", until ); 3090 }, 3091 siblings: function( elem ) { 3092 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3093 }, 3094 children: function( elem ) { 3095 return siblings( elem.firstChild ); 3096 }, 3097 contents: function( elem ) { 3098 if ( elem.contentDocument != null && 3099 3100 // Support: IE 11+ 3101 // <object> elements with no `data` attribute has an object 3102 // `contentDocument` with a `null` prototype. 3103 getProto( elem.contentDocument ) ) { 3104 3105 return elem.contentDocument; 3106 } 3107 3108 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3109 // Treat the template element as a regular one in browsers that 3110 // don't support it. 3111 if ( nodeName( elem, "template" ) ) { 3112 elem = elem.content || elem; 3113 } 3114 3115 return jQuery.merge( [], elem.childNodes ); 3116 } 3117}, function( name, fn ) { 3118 jQuery.fn[ name ] = function( until, selector ) { 3119 var matched = jQuery.map( this, fn, until ); 3120 3121 if ( name.slice( -5 ) !== "Until" ) { 3122 selector = until; 3123 } 3124 3125 if ( selector && typeof selector === "string" ) { 3126 matched = jQuery.filter( selector, matched ); 3127 } 3128 3129 if ( this.length > 1 ) { 3130 3131 // Remove duplicates 3132 if ( !guaranteedUnique[ name ] ) { 3133 jQuery.uniqueSort( matched ); 3134 } 3135 3136 // Reverse order for parents* and prev-derivatives 3137 if ( rparentsprev.test( name ) ) { 3138 matched.reverse(); 3139 } 3140 } 3141 3142 return this.pushStack( matched ); 3143 }; 3144} ); 3145var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 3146 3147 3148 3149// Convert String-formatted options into Object-formatted ones 3150function createOptions( options ) { 3151 var object = {}; 3152 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 3153 object[ flag ] = true; 3154 } ); 3155 return object; 3156} 3157 3158/* 3159 * Create a callback list using the following parameters: 3160 * 3161 * options: an optional list of space-separated options that will change how 3162 * the callback list behaves or a more traditional option object 3163 * 3164 * By default a callback list will act like an event callback list and can be 3165 * "fired" multiple times. 3166 * 3167 * Possible options: 3168 * 3169 * once: will ensure the callback list can only be fired once (like a Deferred) 3170 * 3171 * memory: will keep track of previous values and will call any callback added 3172 * after the list has been fired right away with the latest "memorized" 3173 * values (like a Deferred) 3174 * 3175 * unique: will ensure a callback can only be added once (no duplicate in the list) 3176 * 3177 * stopOnFalse: interrupt callings when a callback returns false 3178 * 3179 */ 3180jQuery.Callbacks = function( options ) { 3181 3182 // Convert options from String-formatted to Object-formatted if needed 3183 // (we check in cache first) 3184 options = typeof options === "string" ? 3185 createOptions( options ) : 3186 jQuery.extend( {}, options ); 3187 3188 var // Flag to know if list is currently firing 3189 firing, 3190 3191 // Last fire value for non-forgettable lists 3192 memory, 3193 3194 // Flag to know if list was already fired 3195 fired, 3196 3197 // Flag to prevent firing 3198 locked, 3199 3200 // Actual callback list 3201 list = [], 3202 3203 // Queue of execution data for repeatable lists 3204 queue = [], 3205 3206 // Index of currently firing callback (modified by add/remove as needed) 3207 firingIndex = -1, 3208 3209 // Fire callbacks 3210 fire = function() { 3211 3212 // Enforce single-firing 3213 locked = locked || options.once; 3214 3215 // Execute callbacks for all pending executions, 3216 // respecting firingIndex overrides and runtime changes 3217 fired = firing = true; 3218 for ( ; queue.length; firingIndex = -1 ) { 3219 memory = queue.shift(); 3220 while ( ++firingIndex < list.length ) { 3221 3222 // Run callback and check for early termination 3223 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 3224 options.stopOnFalse ) { 3225 3226 // Jump to end and forget the data so .add doesn't re-fire 3227 firingIndex = list.length; 3228 memory = false; 3229 } 3230 } 3231 } 3232 3233 // Forget the data if we're done with it 3234 if ( !options.memory ) { 3235 memory = false; 3236 } 3237 3238 firing = false; 3239 3240 // Clean up if we're done firing for good 3241 if ( locked ) { 3242 3243 // Keep an empty list if we have data for future add calls 3244 if ( memory ) { 3245 list = []; 3246 3247 // Otherwise, this object is spent 3248 } else { 3249 list = ""; 3250 } 3251 } 3252 }, 3253 3254 // Actual Callbacks object 3255 self = { 3256 3257 // Add a callback or a collection of callbacks to the list 3258 add: function() { 3259 if ( list ) { 3260 3261 // If we have memory from a past run, we should fire after adding 3262 if ( memory && !firing ) { 3263 firingIndex = list.length - 1; 3264 queue.push( memory ); 3265 } 3266 3267 ( function add( args ) { 3268 jQuery.each( args, function( _, arg ) { 3269 if ( isFunction( arg ) ) { 3270 if ( !options.unique || !self.has( arg ) ) { 3271 list.push( arg ); 3272 } 3273 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 3274 3275 // Inspect recursively 3276 add( arg ); 3277 } 3278 } ); 3279 } )( arguments ); 3280 3281 if ( memory && !firing ) { 3282 fire(); 3283 } 3284 } 3285 return this; 3286 }, 3287 3288 // Remove a callback from the list 3289 remove: function() { 3290 jQuery.each( arguments, function( _, arg ) { 3291 var index; 3292 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 3293 list.splice( index, 1 ); 3294 3295 // Handle firing indexes 3296 if ( index <= firingIndex ) { 3297 firingIndex--; 3298 } 3299 } 3300 } ); 3301 return this; 3302 }, 3303 3304 // Check if a given callback is in the list. 3305 // If no argument is given, return whether or not list has callbacks attached. 3306 has: function( fn ) { 3307 return fn ? 3308 jQuery.inArray( fn, list ) > -1 : 3309 list.length > 0; 3310 }, 3311 3312 // Remove all callbacks from the list 3313 empty: function() { 3314 if ( list ) { 3315 list = []; 3316 } 3317 return this; 3318 }, 3319 3320 // Disable .fire and .add 3321 // Abort any current/pending executions 3322 // Clear all callbacks and values 3323 disable: function() { 3324 locked = queue = []; 3325 list = memory = ""; 3326 return this; 3327 }, 3328 disabled: function() { 3329 return !list; 3330 }, 3331 3332 // Disable .fire 3333 // Also disable .add unless we have memory (since it would have no effect) 3334 // Abort any pending executions 3335 lock: function() { 3336 locked = queue = []; 3337 if ( !memory && !firing ) { 3338 list = memory = ""; 3339 } 3340 return this; 3341 }, 3342 locked: function() { 3343 return !!locked; 3344 }, 3345 3346 // Call all callbacks with the given context and arguments 3347 fireWith: function( context, args ) { 3348 if ( !locked ) { 3349 args = args || []; 3350 args = [ context, args.slice ? args.slice() : args ]; 3351 queue.push( args ); 3352 if ( !firing ) { 3353 fire(); 3354 } 3355 } 3356 return this; 3357 }, 3358 3359 // Call all the callbacks with the given arguments 3360 fire: function() { 3361 self.fireWith( this, arguments ); 3362 return this; 3363 }, 3364 3365 // To know if the callbacks have already been called at least once 3366 fired: function() { 3367 return !!fired; 3368 } 3369 }; 3370 3371 return self; 3372}; 3373 3374 3375function Identity( v ) { 3376 return v; 3377} 3378function Thrower( ex ) { 3379 throw ex; 3380} 3381 3382function adoptValue( value, resolve, reject, noValue ) { 3383 var method; 3384 3385 try { 3386 3387 // Check for promise aspect first to privilege synchronous behavior 3388 if ( value && isFunction( ( method = value.promise ) ) ) { 3389 method.call( value ).done( resolve ).fail( reject ); 3390 3391 // Other thenables 3392 } else if ( value && isFunction( ( method = value.then ) ) ) { 3393 method.call( value, resolve, reject ); 3394 3395 // Other non-thenables 3396 } else { 3397 3398 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 3399 // * false: [ value ].slice( 0 ) => resolve( value ) 3400 // * true: [ value ].slice( 1 ) => resolve() 3401 resolve.apply( undefined, [ value ].slice( noValue ) ); 3402 } 3403 3404 // For Promises/A+, convert exceptions into rejections 3405 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 3406 // Deferred#then to conditionally suppress rejection. 3407 } catch ( value ) { 3408 3409 // Support: Android 4.0 only 3410 // Strict mode functions invoked without .call/.apply get global-object context 3411 reject.apply( undefined, [ value ] ); 3412 } 3413} 3414 3415jQuery.extend( { 3416 3417 Deferred: function( func ) { 3418 var tuples = [ 3419 3420 // action, add listener, callbacks, 3421 // ... .then handlers, argument index, [final state] 3422 [ "notify", "progress", jQuery.Callbacks( "memory" ), 3423 jQuery.Callbacks( "memory" ), 2 ], 3424 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 3425 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 3426 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 3427 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 3428 ], 3429 state = "pending", 3430 promise = { 3431 state: function() { 3432 return state; 3433 }, 3434 always: function() { 3435 deferred.done( arguments ).fail( arguments ); 3436 return this; 3437 }, 3438 "catch": function( fn ) { 3439 return promise.then( null, fn ); 3440 }, 3441 3442 // Keep pipe for back-compat 3443 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 3444 var fns = arguments; 3445 3446 return jQuery.Deferred( function( newDefer ) { 3447 jQuery.each( tuples, function( _i, tuple ) { 3448 3449 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 3450 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 3451 3452 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 3453 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 3454 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 3455 deferred[ tuple[ 1 ] ]( function() { 3456 var returned = fn && fn.apply( this, arguments ); 3457 if ( returned && isFunction( returned.promise ) ) { 3458 returned.promise() 3459 .progress( newDefer.notify ) 3460 .done( newDefer.resolve ) 3461 .fail( newDefer.reject ); 3462 } else { 3463 newDefer[ tuple[ 0 ] + "With" ]( 3464 this, 3465 fn ? [ returned ] : arguments 3466 ); 3467 } 3468 } ); 3469 } ); 3470 fns = null; 3471 } ).promise(); 3472 }, 3473 then: function( onFulfilled, onRejected, onProgress ) { 3474 var maxDepth = 0; 3475 function resolve( depth, deferred, handler, special ) { 3476 return function() { 3477 var that = this, 3478 args = arguments, 3479 mightThrow = function() { 3480 var returned, then; 3481 3482 // Support: Promises/A+ section 2.3.3.3.3 3483 // https://promisesaplus.com/#point-59 3484 // Ignore double-resolution attempts 3485 if ( depth < maxDepth ) { 3486 return; 3487 } 3488 3489 returned = handler.apply( that, args ); 3490 3491 // Support: Promises/A+ section 2.3.1 3492 // https://promisesaplus.com/#point-48 3493 if ( returned === deferred.promise() ) { 3494 throw new TypeError( "Thenable self-resolution" ); 3495 } 3496 3497 // Support: Promises/A+ sections 2.3.3.1, 3.5 3498 // https://promisesaplus.com/#point-54 3499 // https://promisesaplus.com/#point-75 3500 // Retrieve `then` only once 3501 then = returned && 3502 3503 // Support: Promises/A+ section 2.3.4 3504 // https://promisesaplus.com/#point-64 3505 // Only check objects and functions for thenability 3506 ( typeof returned === "object" || 3507 typeof returned === "function" ) && 3508 returned.then; 3509 3510 // Handle a returned thenable 3511 if ( isFunction( then ) ) { 3512 3513 // Special processors (notify) just wait for resolution 3514 if ( special ) { 3515 then.call( 3516 returned, 3517 resolve( maxDepth, deferred, Identity, special ), 3518 resolve( maxDepth, deferred, Thrower, special ) 3519 ); 3520 3521 // Normal processors (resolve) also hook into progress 3522 } else { 3523 3524 // ...and disregard older resolution values 3525 maxDepth++; 3526 3527 then.call( 3528 returned, 3529 resolve( maxDepth, deferred, Identity, special ), 3530 resolve( maxDepth, deferred, Thrower, special ), 3531 resolve( maxDepth, deferred, Identity, 3532 deferred.notifyWith ) 3533 ); 3534 } 3535 3536 // Handle all other returned values 3537 } else { 3538 3539 // Only substitute handlers pass on context 3540 // and multiple values (non-spec behavior) 3541 if ( handler !== Identity ) { 3542 that = undefined; 3543 args = [ returned ]; 3544 } 3545 3546 // Process the value(s) 3547 // Default process is resolve 3548 ( special || deferred.resolveWith )( that, args ); 3549 } 3550 }, 3551 3552 // Only normal processors (resolve) catch and reject exceptions 3553 process = special ? 3554 mightThrow : 3555 function() { 3556 try { 3557 mightThrow(); 3558 } catch ( e ) { 3559 3560 if ( jQuery.Deferred.exceptionHook ) { 3561 jQuery.Deferred.exceptionHook( e, 3562 process.error ); 3563 } 3564 3565 // Support: Promises/A+ section 2.3.3.3.4.1 3566 // https://promisesaplus.com/#point-61 3567 // Ignore post-resolution exceptions 3568 if ( depth + 1 >= maxDepth ) { 3569 3570 // Only substitute handlers pass on context 3571 // and multiple values (non-spec behavior) 3572 if ( handler !== Thrower ) { 3573 that = undefined; 3574 args = [ e ]; 3575 } 3576 3577 deferred.rejectWith( that, args ); 3578 } 3579 } 3580 }; 3581 3582 // Support: Promises/A+ section 2.3.3.3.1 3583 // https://promisesaplus.com/#point-57 3584 // Re-resolve promises immediately to dodge false rejection from 3585 // subsequent errors 3586 if ( depth ) { 3587 process(); 3588 } else { 3589 3590 // Call an optional hook to record the error, in case of exception 3591 // since it's otherwise lost when execution goes async 3592 if ( jQuery.Deferred.getErrorHook ) { 3593 process.error = jQuery.Deferred.getErrorHook(); 3594 3595 // The deprecated alias of the above. While the name suggests 3596 // returning the stack, not an error instance, jQuery just passes 3597 // it directly to `console.warn` so both will work; an instance 3598 // just better cooperates with source maps. 3599 } else if ( jQuery.Deferred.getStackHook ) { 3600 process.error = jQuery.Deferred.getStackHook(); 3601 } 3602 window.setTimeout( process ); 3603 } 3604 }; 3605 } 3606 3607 return jQuery.Deferred( function( newDefer ) { 3608 3609 // progress_handlers.add( ... ) 3610 tuples[ 0 ][ 3 ].add( 3611 resolve( 3612 0, 3613 newDefer, 3614 isFunction( onProgress ) ? 3615 onProgress : 3616 Identity, 3617 newDefer.notifyWith 3618 ) 3619 ); 3620 3621 // fulfilled_handlers.add( ... ) 3622 tuples[ 1 ][ 3 ].add( 3623 resolve( 3624 0, 3625 newDefer, 3626 isFunction( onFulfilled ) ? 3627 onFulfilled : 3628 Identity 3629 ) 3630 ); 3631 3632 // rejected_handlers.add( ... ) 3633 tuples[ 2 ][ 3 ].add( 3634 resolve( 3635 0, 3636 newDefer, 3637 isFunction( onRejected ) ? 3638 onRejected : 3639 Thrower 3640 ) 3641 ); 3642 } ).promise(); 3643 }, 3644 3645 // Get a promise for this deferred 3646 // If obj is provided, the promise aspect is added to the object 3647 promise: function( obj ) { 3648 return obj != null ? jQuery.extend( obj, promise ) : promise; 3649 } 3650 }, 3651 deferred = {}; 3652 3653 // Add list-specific methods 3654 jQuery.each( tuples, function( i, tuple ) { 3655 var list = tuple[ 2 ], 3656 stateString = tuple[ 5 ]; 3657 3658 // promise.progress = list.add 3659 // promise.done = list.add 3660 // promise.fail = list.add 3661 promise[ tuple[ 1 ] ] = list.add; 3662 3663 // Handle state 3664 if ( stateString ) { 3665 list.add( 3666 function() { 3667 3668 // state = "resolved" (i.e., fulfilled) 3669 // state = "rejected" 3670 state = stateString; 3671 }, 3672 3673 // rejected_callbacks.disable 3674 // fulfilled_callbacks.disable 3675 tuples[ 3 - i ][ 2 ].disable, 3676 3677 // rejected_handlers.disable 3678 // fulfilled_handlers.disable 3679 tuples[ 3 - i ][ 3 ].disable, 3680 3681 // progress_callbacks.lock 3682 tuples[ 0 ][ 2 ].lock, 3683 3684 // progress_handlers.lock 3685 tuples[ 0 ][ 3 ].lock 3686 ); 3687 } 3688 3689 // progress_handlers.fire 3690 // fulfilled_handlers.fire 3691 // rejected_handlers.fire 3692 list.add( tuple[ 3 ].fire ); 3693 3694 // deferred.notify = function() { deferred.notifyWith(...) } 3695 // deferred.resolve = function() { deferred.resolveWith(...) } 3696 // deferred.reject = function() { deferred.rejectWith(...) } 3697 deferred[ tuple[ 0 ] ] = function() { 3698 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 3699 return this; 3700 }; 3701 3702 // deferred.notifyWith = list.fireWith 3703 // deferred.resolveWith = list.fireWith 3704 // deferred.rejectWith = list.fireWith 3705 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 3706 } ); 3707 3708 // Make the deferred a promise 3709 promise.promise( deferred ); 3710 3711 // Call given func if any 3712 if ( func ) { 3713 func.call( deferred, deferred ); 3714 } 3715 3716 // All done! 3717 return deferred; 3718 }, 3719 3720 // Deferred helper 3721 when: function( singleValue ) { 3722 var 3723 3724 // count of uncompleted subordinates 3725 remaining = arguments.length, 3726 3727 // count of unprocessed arguments 3728 i = remaining, 3729 3730 // subordinate fulfillment data 3731 resolveContexts = Array( i ), 3732 resolveValues = slice.call( arguments ), 3733 3734 // the primary Deferred 3735 primary = jQuery.Deferred(), 3736 3737 // subordinate callback factory 3738 updateFunc = function( i ) { 3739 return function( value ) { 3740 resolveContexts[ i ] = this; 3741 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 3742 if ( !( --remaining ) ) { 3743 primary.resolveWith( resolveContexts, resolveValues ); 3744 } 3745 }; 3746 }; 3747 3748 // Single- and empty arguments are adopted like Promise.resolve 3749 if ( remaining <= 1 ) { 3750 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 3751 !remaining ); 3752 3753 // Use .then() to unwrap secondary thenables (cf. gh-3000) 3754 if ( primary.state() === "pending" || 3755 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 3756 3757 return primary.then(); 3758 } 3759 } 3760 3761 // Multiple arguments are aggregated like Promise.all array elements 3762 while ( i-- ) { 3763 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 3764 } 3765 3766 return primary.promise(); 3767 } 3768} ); 3769 3770 3771// These usually indicate a programmer mistake during development, 3772// warn about them ASAP rather than swallowing them by default. 3773var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 3774 3775// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error 3776// captured before the async barrier to get the original error cause 3777// which may otherwise be hidden. 3778jQuery.Deferred.exceptionHook = function( error, asyncError ) { 3779 3780 // Support: IE 8 - 9 only 3781 // Console exists when dev tools are open, which can happen at any time 3782 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 3783 window.console.warn( "jQuery.Deferred exception: " + error.message, 3784 error.stack, asyncError ); 3785 } 3786}; 3787 3788 3789 3790 3791jQuery.readyException = function( error ) { 3792 window.setTimeout( function() { 3793 throw error; 3794 } ); 3795}; 3796 3797 3798 3799 3800// The deferred used on DOM ready 3801var readyList = jQuery.Deferred(); 3802 3803jQuery.fn.ready = function( fn ) { 3804 3805 readyList 3806 .then( fn ) 3807 3808 // Wrap jQuery.readyException in a function so that the lookup 3809 // happens at the time of error handling instead of callback 3810 // registration. 3811 .catch( function( error ) { 3812 jQuery.readyException( error ); 3813 } ); 3814 3815 return this; 3816}; 3817 3818jQuery.extend( { 3819 3820 // Is the DOM ready to be used? Set to true once it occurs. 3821 isReady: false, 3822 3823 // A counter to track how many items to wait for before 3824 // the ready event fires. See trac-6781 3825 readyWait: 1, 3826 3827 // Handle when the DOM is ready 3828 ready: function( wait ) { 3829 3830 // Abort if there are pending holds or we're already ready 3831 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 3832 return; 3833 } 3834 3835 // Remember that the DOM is ready 3836 jQuery.isReady = true; 3837 3838 // If a normal DOM Ready event fired, decrement, and wait if need be 3839 if ( wait !== true && --jQuery.readyWait > 0 ) { 3840 return; 3841 } 3842 3843 // If there are functions bound, to execute 3844 readyList.resolveWith( document, [ jQuery ] ); 3845 } 3846} ); 3847 3848jQuery.ready.then = readyList.then; 3849 3850// The ready event handler and self cleanup method 3851function completed() { 3852 document.removeEventListener( "DOMContentLoaded", completed ); 3853 window.removeEventListener( "load", completed ); 3854 jQuery.ready(); 3855} 3856 3857// Catch cases where $(document).ready() is called 3858// after the browser event has already occurred. 3859// Support: IE <=9 - 10 only 3860// Older IE sometimes signals "interactive" too soon 3861if ( document.readyState === "complete" || 3862 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 3863 3864 // Handle it asynchronously to allow scripts the opportunity to delay ready 3865 window.setTimeout( jQuery.ready ); 3866 3867} else { 3868 3869 // Use the handy event callback 3870 document.addEventListener( "DOMContentLoaded", completed ); 3871 3872 // A fallback to window.onload, that will always work 3873 window.addEventListener( "load", completed ); 3874} 3875 3876 3877 3878 3879// Multifunctional method to get and set values of a collection 3880// The value/s can optionally be executed if it's a function 3881var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 3882 var i = 0, 3883 len = elems.length, 3884 bulk = key == null; 3885 3886 // Sets many values 3887 if ( toType( key ) === "object" ) { 3888 chainable = true; 3889 for ( i in key ) { 3890 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 3891 } 3892 3893 // Sets one value 3894 } else if ( value !== undefined ) { 3895 chainable = true; 3896 3897 if ( !isFunction( value ) ) { 3898 raw = true; 3899 } 3900 3901 if ( bulk ) { 3902 3903 // Bulk operations run against the entire set 3904 if ( raw ) { 3905 fn.call( elems, value ); 3906 fn = null; 3907 3908 // ...except when executing function values 3909 } else { 3910 bulk = fn; 3911 fn = function( elem, _key, value ) { 3912 return bulk.call( jQuery( elem ), value ); 3913 }; 3914 } 3915 } 3916 3917 if ( fn ) { 3918 for ( ; i < len; i++ ) { 3919 fn( 3920 elems[ i ], key, raw ? 3921 value : 3922 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 3923 ); 3924 } 3925 } 3926 } 3927 3928 if ( chainable ) { 3929 return elems; 3930 } 3931 3932 // Gets 3933 if ( bulk ) { 3934 return fn.call( elems ); 3935 } 3936 3937 return len ? fn( elems[ 0 ], key ) : emptyGet; 3938}; 3939 3940 3941// Matches dashed string for camelizing 3942var rmsPrefix = /^-ms-/, 3943 rdashAlpha = /-([a-z])/g; 3944 3945// Used by camelCase as callback to replace() 3946function fcamelCase( _all, letter ) { 3947 return letter.toUpperCase(); 3948} 3949 3950// Convert dashed to camelCase; used by the css and data modules 3951// Support: IE <=9 - 11, Edge 12 - 15 3952// Microsoft forgot to hump their vendor prefix (trac-9572) 3953function camelCase( string ) { 3954 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 3955} 3956var acceptData = function( owner ) { 3957 3958 // Accepts only: 3959 // - Node 3960 // - Node.ELEMENT_NODE 3961 // - Node.DOCUMENT_NODE 3962 // - Object 3963 // - Any 3964 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 3965}; 3966 3967 3968 3969 3970function Data() { 3971 this.expando = jQuery.expando + Data.uid++; 3972} 3973 3974Data.uid = 1; 3975 3976Data.prototype = { 3977 3978 cache: function( owner ) { 3979 3980 // Check if the owner object already has a cache 3981 var value = owner[ this.expando ]; 3982 3983 // If not, create one 3984 if ( !value ) { 3985 value = {}; 3986 3987 // We can accept data for non-element nodes in modern browsers, 3988 // but we should not, see trac-8335. 3989 // Always return an empty object. 3990 if ( acceptData( owner ) ) { 3991 3992 // If it is a node unlikely to be stringify-ed or looped over 3993 // use plain assignment 3994 if ( owner.nodeType ) { 3995 owner[ this.expando ] = value; 3996 3997 // Otherwise secure it in a non-enumerable property 3998 // configurable must be true to allow the property to be 3999 // deleted when data is removed 4000 } else { 4001 Object.defineProperty( owner, this.expando, { 4002 value: value, 4003 configurable: true 4004 } ); 4005 } 4006 } 4007 } 4008 4009 return value; 4010 }, 4011 set: function( owner, data, value ) { 4012 var prop, 4013 cache = this.cache( owner ); 4014 4015 // Handle: [ owner, key, value ] args 4016 // Always use camelCase key (gh-2257) 4017 if ( typeof data === "string" ) { 4018 cache[ camelCase( data ) ] = value; 4019 4020 // Handle: [ owner, { properties } ] args 4021 } else { 4022 4023 // Copy the properties one-by-one to the cache object 4024 for ( prop in data ) { 4025 cache[ camelCase( prop ) ] = data[ prop ]; 4026 } 4027 } 4028 return cache; 4029 }, 4030 get: function( owner, key ) { 4031 return key === undefined ? 4032 this.cache( owner ) : 4033 4034 // Always use camelCase key (gh-2257) 4035 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 4036 }, 4037 access: function( owner, key, value ) { 4038 4039 // In cases where either: 4040 // 4041 // 1. No key was specified 4042 // 2. A string key was specified, but no value provided 4043 // 4044 // Take the "read" path and allow the get method to determine 4045 // which value to return, respectively either: 4046 // 4047 // 1. The entire cache object 4048 // 2. The data stored at the key 4049 // 4050 if ( key === undefined || 4051 ( ( key && typeof key === "string" ) && value === undefined ) ) { 4052 4053 return this.get( owner, key ); 4054 } 4055 4056 // When the key is not a string, or both a key and value 4057 // are specified, set or extend (existing objects) with either: 4058 // 4059 // 1. An object of properties 4060 // 2. A key and value 4061 // 4062 this.set( owner, key, value ); 4063 4064 // Since the "set" path can have two possible entry points 4065 // return the expected data based on which path was taken[*] 4066 return value !== undefined ? value : key; 4067 }, 4068 remove: function( owner, key ) { 4069 var i, 4070 cache = owner[ this.expando ]; 4071 4072 if ( cache === undefined ) { 4073 return; 4074 } 4075 4076 if ( key !== undefined ) { 4077
vendor: 4,799 bytes, lines 4078-4260
4078 // Support array or space separated string of keys 4079 if ( Array.isArray( key ) ) { 4080 4081 // If key is an array of keys... 4082 // We always set camelCase keys, so remove that. 4083 key = key.map( camelCase ); 4084 } else { 4085 key = camelCase( key ); 4086 4087 // If a key with the spaces exists, use it. 4088 // Otherwise, create an array by matching non-whitespace 4089 key = key in cache ? 4090 [ key ] : 4091 ( key.match( rnothtmlwhite ) || [] ); 4092 } 4093 4094 i = key.length; 4095 4096 while ( i-- ) { 4097 delete cache[ key[ i ] ]; 4098 } 4099 } 4100 4101 // Remove the expando if there's no more data 4102 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 4103 4104 // Support: Chrome <=35 - 45 4105 // Webkit & Blink performance suffers when deleting properties 4106 // from DOM nodes, so set to undefined instead 4107 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4108 if ( owner.nodeType ) { 4109 owner[ this.expando ] = undefined; 4110 } else { 4111 delete owner[ this.expando ]; 4112 } 4113 } 4114 }, 4115 hasData: function( owner ) { 4116 var cache = owner[ this.expando ]; 4117 return cache !== undefined && !jQuery.isEmptyObject( cache ); 4118 } 4119}; 4120var dataPriv = new Data(); 4121 4122var dataUser = new Data(); 4123 4124 4125 4126// Implementation Summary 4127// 4128// 1. Enforce API surface and semantic compatibility with 1.9.x branch 4129// 2. Improve the module's maintainability by reducing the storage 4130// paths to a single mechanism. 4131// 3. Use the same single mechanism to support "private" and "user" data. 4132// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 4133// 5. Avoid exposing implementation details on user objects (eg. expando properties) 4134// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 4135 4136var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 4137 rmultiDash = /[A-Z]/g; 4138 4139function getData( data ) { 4140 if ( data === "true" ) { 4141 return true; 4142 } 4143 4144 if ( data === "false" ) { 4145 return false; 4146 } 4147 4148 if ( data === "null" ) { 4149 return null; 4150 } 4151 4152 // Only convert to a number if it doesn't change the string 4153 if ( data === +data + "" ) { 4154 return +data; 4155 } 4156 4157 if ( rbrace.test( data ) ) { 4158 return JSON.parse( data ); 4159 } 4160 4161 return data; 4162} 4163 4164function dataAttr( elem, key, data ) { 4165 var name; 4166 4167 // If nothing was found internally, try to fetch any 4168 // data from the HTML5 data-* attribute 4169 if ( data === undefined && elem.nodeType === 1 ) { 4170 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 4171 data = elem.getAttribute( name ); 4172 4173 if ( typeof data === "string" ) { 4174 try { 4175 data = getData( data ); 4176 } catch ( e ) {} 4177 4178 // Make sure we set the data so it isn't changed later 4179 dataUser.set( elem, key, data ); 4180 } else { 4181 data = undefined; 4182 } 4183 } 4184 return data; 4185} 4186 4187jQuery.extend( { 4188 hasData: function( elem ) { 4189 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 4190 }, 4191 4192 data: function( elem, name, data ) { 4193 return dataUser.access( elem, name, data ); 4194 }, 4195 4196 removeData: function( elem, name ) { 4197 dataUser.remove( elem, name ); 4198 }, 4199 4200 // TODO: Now that all calls to _data and _removeData have been replaced 4201 // with direct calls to dataPriv methods, these can be deprecated. 4202 _data: function( elem, name, data ) { 4203 return dataPriv.access( elem, name, data ); 4204 }, 4205 4206 _removeData: function( elem, name ) { 4207 dataPriv.remove( elem, name ); 4208 } 4209} ); 4210 4211jQuery.fn.extend( { 4212 data: function( key, value ) { 4213 var i, name, data, 4214 elem = this[ 0 ], 4215 attrs = elem && elem.attributes; 4216 4217 // Gets all values 4218 if ( key === undefined ) { 4219 if ( this.length ) { 4220 data = dataUser.get( elem ); 4221 4222 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 4223 i = attrs.length; 4224 while ( i-- ) { 4225 4226 // Support: IE 11 only 4227 // The attrs elements can be null (trac-14894) 4228 if ( attrs[ i ] ) { 4229 name = attrs[ i ].name; 4230 if ( name.indexOf( "data-" ) === 0 ) { 4231 name = camelCase( name.slice( 5 ) ); 4232 dataAttr( elem, name, data[ name ] ); 4233 } 4234 } 4235 } 4236 dataPriv.set( elem, "hasDataAttrs", true ); 4237 } 4238 } 4239 4240 return data; 4241 } 4242 4243 // Sets multiple values 4244 if ( typeof key === "object" ) { 4245 return this.each( function() { 4246 dataUser.set( this, key ); 4247 } ); 4248 } 4249 4250 return access( this, function( value ) { 4251 var data; 4252 4253 // The calling jQuery object (element matches) is not empty 4254 // (and therefore has an element appears at this[ 0 ]) and the 4255 // `value` parameter was not undefined. An empty jQuery object 4256 // will result in `undefined` for elem = this[ 0 ] which will 4257 // throw an exception if an attempt to read a data cache is made. 4258 if ( elem && value === undefined ) { 4259 4260 // Attempt to get data from the cache
vendor: 20,334 bytes, lines 4261-5034
4261 // The key will always be camelCased in Data 4262 data = dataUser.get( elem, key ); 4263 if ( data !== undefined ) { 4264 return data; 4265 } 4266 4267 // Attempt to "discover" the data in 4268 // HTML5 custom data-* attrs 4269 data = dataAttr( elem, key ); 4270 if ( data !== undefined ) { 4271 return data; 4272 } 4273 4274 // We tried really hard, but the data doesn't exist. 4275 return; 4276 } 4277 4278 // Set the data... 4279 this.each( function() { 4280 4281 // We always store the camelCased key 4282 dataUser.set( this, key, value ); 4283 } ); 4284 }, null, value, arguments.length > 1, null, true ); 4285 }, 4286 4287 removeData: function( key ) { 4288 return this.each( function() { 4289 dataUser.remove( this, key ); 4290 } ); 4291 } 4292} ); 4293 4294 4295jQuery.extend( { 4296 queue: function( elem, type, data ) { 4297 var queue; 4298 4299 if ( elem ) { 4300 type = ( type || "fx" ) + "queue"; 4301 queue = dataPriv.get( elem, type ); 4302 4303 // Speed up dequeue by getting out quickly if this is just a lookup 4304 if ( data ) { 4305 if ( !queue || Array.isArray( data ) ) { 4306 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 4307 } else { 4308 queue.push( data ); 4309 } 4310 } 4311 return queue || []; 4312 } 4313 }, 4314 4315 dequeue: function( elem, type ) { 4316 type = type || "fx"; 4317 4318 var queue = jQuery.queue( elem, type ), 4319 startLength = queue.length, 4320 fn = queue.shift(), 4321 hooks = jQuery._queueHooks( elem, type ), 4322 next = function() { 4323 jQuery.dequeue( elem, type ); 4324 }; 4325 4326 // If the fx queue is dequeued, always remove the progress sentinel 4327 if ( fn === "inprogress" ) { 4328 fn = queue.shift(); 4329 startLength--; 4330 } 4331 4332 if ( fn ) { 4333 4334 // Add a progress sentinel to prevent the fx queue from being 4335 // automatically dequeued 4336 if ( type === "fx" ) { 4337 queue.unshift( "inprogress" ); 4338 } 4339 4340 // Clear up the last queue stop function 4341 delete hooks.stop; 4342 fn.call( elem, next, hooks ); 4343 } 4344 4345 if ( !startLength && hooks ) { 4346 hooks.empty.fire(); 4347 } 4348 }, 4349 4350 // Not public - generate a queueHooks object, or return the current one 4351 _queueHooks: function( elem, type ) { 4352 var key = type + "queueHooks"; 4353 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 4354 empty: jQuery.Callbacks( "once memory" ).add( function() { 4355 dataPriv.remove( elem, [ type + "queue", key ] ); 4356 } ) 4357 } ); 4358 } 4359} ); 4360 4361jQuery.fn.extend( { 4362 queue: function( type, data ) { 4363 var setter = 2; 4364 4365 if ( typeof type !== "string" ) { 4366 data = type; 4367 type = "fx"; 4368 setter--; 4369 } 4370 4371 if ( arguments.length < setter ) { 4372 return jQuery.queue( this[ 0 ], type ); 4373 } 4374 4375 return data === undefined ? 4376 this : 4377 this.each( function() { 4378 var queue = jQuery.queue( this, type, data ); 4379 4380 // Ensure a hooks for this queue 4381 jQuery._queueHooks( this, type ); 4382 4383 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 4384 jQuery.dequeue( this, type ); 4385 } 4386 } ); 4387 }, 4388 dequeue: function( type ) { 4389 return this.each( function() { 4390 jQuery.dequeue( this, type ); 4391 } ); 4392 }, 4393 clearQueue: function( type ) { 4394 return this.queue( type || "fx", [] ); 4395 }, 4396 4397 // Get a promise resolved when queues of a certain type 4398 // are emptied (fx is the type by default) 4399 promise: function( type, obj ) { 4400 var tmp, 4401 count = 1, 4402 defer = jQuery.Deferred(), 4403 elements = this, 4404 i = this.length, 4405 resolve = function() { 4406 if ( !( --count ) ) { 4407 defer.resolveWith( elements, [ elements ] ); 4408 } 4409 }; 4410 4411 if ( typeof type !== "string" ) { 4412 obj = type; 4413 type = undefined; 4414 } 4415 type = type || "fx"; 4416 4417 while ( i-- ) { 4418 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 4419 if ( tmp && tmp.empty ) { 4420 count++; 4421 tmp.empty.add( resolve ); 4422 } 4423 } 4424 resolve(); 4425 return defer.promise( obj ); 4426 } 4427} ); 4428var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 4429 4430var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 4431 4432 4433var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 4434 4435var documentElement = document.documentElement; 4436 4437 4438 4439 var isAttached = function( elem ) { 4440 return jQuery.contains( elem.ownerDocument, elem ); 4441 }, 4442 composed = { composed: true }; 4443 4444 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 4445 // Check attachment across shadow DOM boundaries when possible (gh-3504) 4446 // Support: iOS 10.0-10.2 only 4447 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 4448 // leading to errors. We need to check for `getRootNode`. 4449 if ( documentElement.getRootNode ) { 4450 isAttached = function( elem ) { 4451 return jQuery.contains( elem.ownerDocument, elem ) || 4452 elem.getRootNode( composed ) === elem.ownerDocument; 4453 }; 4454 } 4455var isHiddenWithinTree = function( elem, el ) { 4456 4457 // isHiddenWithinTree might be called from jQuery#filter function; 4458 // in that case, element will be second argument 4459 elem = el || elem; 4460 4461 // Inline style trumps all 4462 return elem.style.display === "none" || 4463 elem.style.display === "" && 4464 4465 // Otherwise, check computed style 4466 // Support: Firefox <=43 - 45 4467 // Disconnected elements can have computed display: none, so first confirm that elem is 4468 // in the document. 4469 isAttached( elem ) && 4470 4471 jQuery.css( elem, "display" ) === "none"; 4472 }; 4473 4474 4475 4476function adjustCSS( elem, prop, valueParts, tween ) { 4477 var adjusted, scale, 4478 maxIterations = 20, 4479 currentValue = tween ? 4480 function() { 4481 return tween.cur(); 4482 } : 4483 function() { 4484 return jQuery.css( elem, prop, "" ); 4485 }, 4486 initial = currentValue(), 4487 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 4488 4489 // Starting value computation is required for potential unit mismatches 4490 initialInUnit = elem.nodeType && 4491 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 4492 rcssNum.exec( jQuery.css( elem, prop ) ); 4493 4494 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 4495 4496 // Support: Firefox <=54 4497 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 4498 initial = initial / 2; 4499 4500 // Trust units reported by jQuery.css 4501 unit = unit || initialInUnit[ 3 ]; 4502 4503 // Iteratively approximate from a nonzero starting point 4504 initialInUnit = +initial || 1; 4505 4506 while ( maxIterations-- ) { 4507 4508 // Evaluate and update our best guess (doubling guesses that zero out). 4509 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 4510 jQuery.style( elem, prop, initialInUnit + unit ); 4511 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 4512 maxIterations = 0; 4513 } 4514 initialInUnit = initialInUnit / scale; 4515 4516 } 4517 4518 initialInUnit = initialInUnit * 2; 4519 jQuery.style( elem, prop, initialInUnit + unit ); 4520 4521 // Make sure we update the tween properties later on 4522 valueParts = valueParts || []; 4523 } 4524 4525 if ( valueParts ) { 4526 initialInUnit = +initialInUnit || +initial || 0; 4527 4528 // Apply relative offset (+=/-=) if specified 4529 adjusted = valueParts[ 1 ] ? 4530 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 4531 +valueParts[ 2 ]; 4532 if ( tween ) { 4533 tween.unit = unit; 4534 tween.start = initialInUnit; 4535 tween.end = adjusted; 4536 } 4537 } 4538 return adjusted; 4539} 4540 4541 4542var defaultDisplayMap = {}; 4543 4544function getDefaultDisplay( elem ) { 4545 var temp, 4546 doc = elem.ownerDocument, 4547 nodeName = elem.nodeName, 4548 display = defaultDisplayMap[ nodeName ]; 4549 4550 if ( display ) { 4551 return display; 4552 } 4553 4554 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 4555 display = jQuery.css( temp, "display" ); 4556 4557 temp.parentNode.removeChild( temp ); 4558 4559 if ( display === "none" ) { 4560 display = "block"; 4561 } 4562 defaultDisplayMap[ nodeName ] = display; 4563 4564 return display; 4565} 4566 4567function showHide( elements, show ) { 4568 var display, elem, 4569 values = [], 4570 index = 0, 4571 length = elements.length; 4572 4573 // Determine new display value for elements that need to change 4574 for ( ; index < length; index++ ) { 4575 elem = elements[ index ]; 4576 if ( !elem.style ) { 4577 continue; 4578 } 4579 4580 display = elem.style.display; 4581 if ( show ) { 4582 4583 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 4584 // check is required in this first loop unless we have a nonempty display value (either 4585 // inline or about-to-be-restored) 4586 if ( display === "none" ) { 4587 values[ index ] = dataPriv.get( elem, "display" ) || null; 4588 if ( !values[ index ] ) { 4589 elem.style.display = ""; 4590 } 4591 } 4592 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 4593 values[ index ] = getDefaultDisplay( elem ); 4594 } 4595 } else { 4596 if ( display !== "none" ) { 4597 values[ index ] = "none"; 4598 4599 // Remember what we're overwriting 4600 dataPriv.set( elem, "display", display ); 4601 } 4602 } 4603 } 4604 4605 // Set the display of the elements in a second loop to avoid constant reflow 4606 for ( index = 0; index < length; index++ ) { 4607 if ( values[ index ] != null ) { 4608 elements[ index ].style.display = values[ index ]; 4609 } 4610 } 4611 4612 return elements; 4613} 4614 4615jQuery.fn.extend( { 4616 show: function() { 4617 return showHide( this, true ); 4618 }, 4619 hide: function() { 4620 return showHide( this ); 4621 }, 4622 toggle: function( state ) { 4623 if ( typeof state === "boolean" ) { 4624 return state ? this.show() : this.hide(); 4625 } 4626 4627 return this.each( function() { 4628 if ( isHiddenWithinTree( this ) ) { 4629 jQuery( this ).show(); 4630 } else { 4631 jQuery( this ).hide(); 4632 } 4633 } ); 4634 } 4635} ); 4636var rcheckableType = ( /^(?:checkbox|radio)$/i ); 4637 4638var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 4639 4640var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 4641 4642 4643 4644( function() { 4645 var fragment = document.createDocumentFragment(), 4646 div = fragment.appendChild( document.createElement( "div" ) ), 4647 input = document.createElement( "input" ); 4648 4649 // Support: Android 4.0 - 4.3 only 4650 // Check state lost if the name is set (trac-11217) 4651 // Support: Windows Web Apps (WWA) 4652 // `name` and `type` must use .setAttribute for WWA (trac-14901) 4653 input.setAttribute( "type", "radio" ); 4654 input.setAttribute( "checked", "checked" ); 4655 input.setAttribute( "name", "t" ); 4656 4657 div.appendChild( input ); 4658 4659 // Support: Android <=4.1 only 4660 // Older WebKit doesn't clone checked state correctly in fragments 4661 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 4662 4663 // Support: IE <=11 only 4664 // Make sure textarea (and checkbox) defaultValue is properly cloned 4665 div.innerHTML = "<textarea>x</textarea>"; 4666 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 4667 4668 // Support: IE <=9 only 4669 // IE <=9 replaces <option> tags with their contents when inserted outside of 4670 // the select element. 4671 div.innerHTML = "<option></option>"; 4672 support.option = !!div.lastChild; 4673} )(); 4674 4675 4676// We have to close these tags to support XHTML (trac-13200) 4677var wrapMap = { 4678 4679 // XHTML parsers do not magically insert elements in the 4680 // same way that tag soup parsers do. So we cannot shorten 4681 // this by omitting <tbody> or other required elements. 4682 thead: [ 1, "<table>", "</table>" ], 4683 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 4684 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 4685 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 4686 4687 _default: [ 0, "", "" ] 4688}; 4689 4690wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4691wrapMap.th = wrapMap.td; 4692 4693// Support: IE <=9 only 4694if ( !support.option ) { 4695 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 4696} 4697 4698 4699function getAll( context, tag ) { 4700 4701 // Support: IE <=9 - 11 only 4702 // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) 4703 var ret; 4704 4705 if ( typeof context.getElementsByTagName !== "undefined" ) { 4706 ret = context.getElementsByTagName( tag || "*" ); 4707 4708 } else if ( typeof context.querySelectorAll !== "undefined" ) { 4709 ret = context.querySelectorAll( tag || "*" ); 4710 4711 } else { 4712 ret = []; 4713 } 4714 4715 if ( tag === undefined || tag && nodeName( context, tag ) ) { 4716 return jQuery.merge( [ context ], ret ); 4717 } 4718 4719 return ret; 4720} 4721 4722 4723// Mark scripts as having already been evaluated 4724function setGlobalEval( elems, refElements ) { 4725 var i = 0, 4726 l = elems.length; 4727 4728 for ( ; i < l; i++ ) { 4729 dataPriv.set( 4730 elems[ i ], 4731 "globalEval", 4732 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 4733 ); 4734 } 4735} 4736 4737 4738var rhtml = /<|&#?\w+;/; 4739 4740function buildFragment( elems, context, scripts, selection, ignored ) { 4741 var elem, tmp, tag, wrap, attached, j, 4742 fragment = context.createDocumentFragment(), 4743 nodes = [], 4744 i = 0, 4745 l = elems.length; 4746 4747 for ( ; i < l; i++ ) { 4748 elem = elems[ i ]; 4749 4750 if ( elem || elem === 0 ) { 4751 4752 // Add nodes directly 4753 if ( toType( elem ) === "object" ) { 4754 4755 // Support: Android <=4.0 only, PhantomJS 1 only 4756 // push.apply(_, arraylike) throws on ancient WebKit 4757 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 4758 4759 // Convert non-html into a text node 4760 } else if ( !rhtml.test( elem ) ) { 4761 nodes.push( context.createTextNode( elem ) ); 4762 4763 // Convert html into DOM nodes 4764 } else { 4765 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 4766 4767 // Deserialize a standard representation 4768 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 4769 wrap = wrapMap[ tag ] || wrapMap._default; 4770 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 4771 4772 // Descend through wrappers to the right content 4773 j = wrap[ 0 ]; 4774 while ( j-- ) { 4775 tmp = tmp.lastChild; 4776 } 4777 4778 // Support: Android <=4.0 only, PhantomJS 1 only 4779 // push.apply(_, arraylike) throws on ancient WebKit 4780 jQuery.merge( nodes, tmp.childNodes ); 4781 4782 // Remember the top-level container 4783 tmp = fragment.firstChild; 4784 4785 // Ensure the created nodes are orphaned (trac-12392) 4786 tmp.textContent = ""; 4787 } 4788 } 4789 } 4790 4791 // Remove wrapper from fragment 4792 fragment.textContent = ""; 4793 4794 i = 0; 4795 while ( ( elem = nodes[ i++ ] ) ) { 4796 4797 // Skip elements already in the context collection (trac-4087) 4798 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 4799 if ( ignored ) { 4800 ignored.push( elem ); 4801 } 4802 continue; 4803 } 4804 4805 attached = isAttached( elem ); 4806 4807 // Append to fragment 4808 tmp = getAll( fragment.appendChild( elem ), "script" ); 4809 4810 // Preserve script evaluation history 4811 if ( attached ) { 4812 setGlobalEval( tmp ); 4813 } 4814 4815 // Capture executables 4816 if ( scripts ) { 4817 j = 0; 4818 while ( ( elem = tmp[ j++ ] ) ) { 4819 if ( rscriptType.test( elem.type || "" ) ) { 4820 scripts.push( elem ); 4821 } 4822 } 4823 } 4824 } 4825 4826 return fragment; 4827} 4828 4829 4830var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4831 4832function returnTrue() { 4833 return true; 4834} 4835 4836function returnFalse() { 4837 return false; 4838} 4839 4840function on( elem, types, selector, data, fn, one ) { 4841 var origFn, type; 4842 4843 // Types can be a map of types/handlers 4844 if ( typeof types === "object" ) { 4845 4846 // ( types-Object, selector, data ) 4847 if ( typeof selector !== "string" ) { 4848 4849 // ( types-Object, data ) 4850 data = data || selector; 4851 selector = undefined; 4852 } 4853 for ( type in types ) { 4854 on( elem, type, selector, data, types[ type ], one ); 4855 } 4856 return elem; 4857 } 4858 4859 if ( data == null && fn == null ) { 4860 4861 // ( types, fn ) 4862 fn = selector; 4863 data = selector = undefined; 4864 } else if ( fn == null ) { 4865 if ( typeof selector === "string" ) { 4866 4867 // ( types, selector, fn ) 4868 fn = data; 4869 data = undefined; 4870 } else { 4871 4872 // ( types, data, fn ) 4873 fn = data; 4874 data = selector; 4875 selector = undefined; 4876 } 4877 } 4878 if ( fn === false ) { 4879 fn = returnFalse; 4880 } else if ( !fn ) { 4881 return elem; 4882 } 4883 4884 if ( one === 1 ) { 4885 origFn = fn; 4886 fn = function( event ) { 4887 4888 // Can use an empty set, since event contains the info 4889 jQuery().off( event ); 4890 return origFn.apply( this, arguments ); 4891 }; 4892 4893 // Use same guid so caller can remove using origFn 4894 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 4895 } 4896 return elem.each( function() { 4897 jQuery.event.add( this, types, fn, data, selector ); 4898 } ); 4899} 4900 4901/* 4902 * Helper functions for managing events -- not part of the public interface. 4903 * Props to Dean Edwards' addEvent library for many of the ideas. 4904 */ 4905jQuery.event = { 4906 4907 global: {}, 4908 4909 add: function( elem, types, handler, data, selector ) { 4910 4911 var handleObjIn, eventHandle, tmp, 4912 events, t, handleObj, 4913 special, handlers, type, namespaces, origType, 4914 elemData = dataPriv.get( elem ); 4915 4916 // Only attach events to objects that accept data 4917 if ( !acceptData( elem ) ) { 4918 return; 4919 } 4920 4921 // Caller can pass in an object of custom data in lieu of the handler 4922 if ( handler.handler ) { 4923 handleObjIn = handler; 4924 handler = handleObjIn.handler; 4925 selector = handleObjIn.selector; 4926 } 4927 4928 // Ensure that invalid selectors throw exceptions at attach time 4929 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 4930 if ( selector ) { 4931 jQuery.find.matchesSelector( documentElement, selector ); 4932 } 4933 4934 // Make sure that the handler has a unique ID, used to find/remove it later 4935 if ( !handler.guid ) { 4936 handler.guid = jQuery.guid++; 4937 } 4938 4939 // Init the element's event structure and main handler, if this is the first 4940 if ( !( events = elemData.events ) ) { 4941 events = elemData.events = Object.create( null ); 4942 } 4943 if ( !( eventHandle = elemData.handle ) ) { 4944 eventHandle = elemData.handle = function( e ) { 4945 4946 // Discard the second event of a jQuery.event.trigger() and 4947 // when an event is called after a page has unloaded 4948 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 4949 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 4950 }; 4951 } 4952 4953 // Handle multiple events separated by a space 4954 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 4955 t = types.length; 4956 while ( t-- ) { 4957 tmp = rtypenamespace.exec( types[ t ] ) || []; 4958 type = origType = tmp[ 1 ]; 4959 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 4960 4961 // There *must* be a type, no attaching namespace-only handlers 4962 if ( !type ) { 4963 continue; 4964 } 4965 4966 // If event changes its type, use the special event handlers for the changed type 4967 special = jQuery.event.special[ type ] || {}; 4968 4969 // If selector defined, determine special event api type, otherwise given type 4970 type = ( selector ? special.delegateType : special.bindType ) || type; 4971 4972 // Update special based on newly reset type 4973 special = jQuery.event.special[ type ] || {}; 4974 4975 // handleObj is passed to all event handlers 4976 handleObj = jQuery.extend( { 4977 type: type, 4978 origType: origType, 4979 data: data, 4980 handler: handler, 4981 guid: handler.guid, 4982 selector: selector, 4983 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 4984 namespace: namespaces.join( "." ) 4985 }, handleObjIn ); 4986 4987 // Init the event handler queue if we're the first 4988 if ( !( handlers = events[ type ] ) ) { 4989 handlers = events[ type ] = []; 4990 handlers.delegateCount = 0; 4991 4992 // Only use addEventListener if the special events handler returns false 4993 if ( !special.setup || 4994 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 4995 4996 if ( elem.addEventListener ) { 4997 elem.addEventListener( type, eventHandle ); 4998 } 4999 } 5000 } 5001 5002 if ( special.add ) { 5003 special.add.call( elem, handleObj ); 5004 5005 if ( !handleObj.handler.guid ) { 5006 handleObj.handler.guid = handler.guid; 5007 } 5008 } 5009 5010 // Add to the element's handler list, delegates in front 5011 if ( selector ) { 5012 handlers.splice( handlers.delegateCount++, 0, handleObj ); 5013 } else { 5014 handlers.push( handleObj ); 5015 } 5016 5017 // Keep track of which events have ever been used, for event optimization 5018 jQuery.event.global[ type ] = true; 5019 } 5020 5021 }, 5022 5023 // Detach an event or set of events from an element 5024 remove: function( elem, types, handler, selector, mappedTypes ) { 5025 5026 var j, origCount, tmp, 5027 events, t, handleObj, 5028 special, handlers, type, namespaces, origType, 5029 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 5030 5031 if ( !elemData || !( events = elemData.events ) ) { 5032 return; 5033 } 5034
vendor: 4,336 bytes, lines 5035-5173
5035 // Once for each type.namespace in types; type may be omitted 5036 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5037 t = types.length; 5038 while ( t-- ) { 5039 tmp = rtypenamespace.exec( types[ t ] ) || []; 5040 type = origType = tmp[ 1 ]; 5041 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5042 5043 // Unbind all events (on this namespace, if provided) for the element 5044 if ( !type ) { 5045 for ( type in events ) { 5046 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 5047 } 5048 continue; 5049 } 5050 5051 special = jQuery.event.special[ type ] || {}; 5052 type = ( selector ? special.delegateType : special.bindType ) || type; 5053 handlers = events[ type ] || []; 5054 tmp = tmp[ 2 ] && 5055 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 5056 5057 // Remove matching events 5058 origCount = j = handlers.length; 5059 while ( j-- ) { 5060 handleObj = handlers[ j ]; 5061 5062 if ( ( mappedTypes || origType === handleObj.origType ) && 5063 ( !handler || handler.guid === handleObj.guid ) && 5064 ( !tmp || tmp.test( handleObj.namespace ) ) && 5065 ( !selector || selector === handleObj.selector || 5066 selector === "**" && handleObj.selector ) ) { 5067 handlers.splice( j, 1 ); 5068 5069 if ( handleObj.selector ) { 5070 handlers.delegateCount--; 5071 } 5072 if ( special.remove ) { 5073 special.remove.call( elem, handleObj ); 5074 } 5075 } 5076 } 5077 5078 // Remove generic event handler if we removed something and no more handlers exist 5079 // (avoids potential for endless recursion during removal of special event handlers) 5080 if ( origCount && !handlers.length ) { 5081 if ( !special.teardown || 5082 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5083 5084 jQuery.removeEvent( elem, type, elemData.handle ); 5085 } 5086 5087 delete events[ type ]; 5088 } 5089 } 5090 5091 // Remove data and the expando if it's no longer used 5092 if ( jQuery.isEmptyObject( events ) ) { 5093 dataPriv.remove( elem, "handle events" ); 5094 } 5095 }, 5096 5097 dispatch: function( nativeEvent ) { 5098 5099 var i, j, ret, matched, handleObj, handlerQueue, 5100 args = new Array( arguments.length ), 5101 5102 // Make a writable jQuery.Event from the native event object 5103 event = jQuery.event.fix( nativeEvent ), 5104 5105 handlers = ( 5106 dataPriv.get( this, "events" ) || Object.create( null ) 5107 )[ event.type ] || [], 5108 special = jQuery.event.special[ event.type ] || {}; 5109 5110 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5111 args[ 0 ] = event; 5112 5113 for ( i = 1; i < arguments.length; i++ ) { 5114 args[ i ] = arguments[ i ]; 5115 } 5116 5117 event.delegateTarget = this; 5118 5119 // Call the preDispatch hook for the mapped type, and let it bail if desired 5120 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5121 return; 5122 } 5123 5124 // Determine handlers 5125 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 5126 5127 // Run delegates first; they may want to stop propagation beneath us 5128 i = 0; 5129 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 5130 event.currentTarget = matched.elem; 5131 5132 j = 0; 5133 while ( ( handleObj = matched.handlers[ j++ ] ) && 5134 !event.isImmediatePropagationStopped() ) { 5135 5136 // If the event is namespaced, then each handler is only invoked if it is 5137 // specially universal or its namespaces are a superset of the event's. 5138 if ( !event.rnamespace || handleObj.namespace === false || 5139 event.rnamespace.test( handleObj.namespace ) ) { 5140 5141 event.handleObj = handleObj; 5142 event.data = handleObj.data; 5143 5144 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 5145 handleObj.handler ).apply( matched.elem, args ); 5146 5147 if ( ret !== undefined ) { 5148 if ( ( event.result = ret ) === false ) { 5149 event.preventDefault(); 5150 event.stopPropagation(); 5151 } 5152 } 5153 } 5154 } 5155 } 5156 5157 // Call the postDispatch hook for the mapped type 5158 if ( special.postDispatch ) { 5159 special.postDispatch.call( this, event ); 5160 } 5161 5162 return event.result; 5163 }, 5164 5165 handlers: function( event, handlers ) { 5166 var i, handleObj, sel, matchedHandlers, matchedSelectors, 5167 handlerQueue = [], 5168 delegateCount = handlers.delegateCount, 5169 cur = event.target; 5170 5171 // Find delegate handlers 5172 if ( delegateCount && 5173
vendor: 26,293 bytes, lines 5174-6050
5174 // Support: IE <=9 5175 // Black-hole SVG <use> instance trees (trac-13180) 5176 cur.nodeType && 5177 5178 // Support: Firefox <=42 5179 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 5180 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 5181 // Support: IE 11 only 5182 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 5183 !( event.type === "click" && event.button >= 1 ) ) { 5184 5185 for ( ; cur !== this; cur = cur.parentNode || this ) { 5186 5187 // Don't check non-elements (trac-13208) 5188 // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) 5189 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 5190 matchedHandlers = []; 5191 matchedSelectors = {}; 5192 for ( i = 0; i < delegateCount; i++ ) { 5193 handleObj = handlers[ i ]; 5194 5195 // Don't conflict with Object.prototype properties (trac-13203) 5196 sel = handleObj.selector + " "; 5197 5198 if ( matchedSelectors[ sel ] === undefined ) { 5199 matchedSelectors[ sel ] = handleObj.needsContext ? 5200 jQuery( sel, this ).index( cur ) > -1 : 5201 jQuery.find( sel, this, null, [ cur ] ).length; 5202 } 5203 if ( matchedSelectors[ sel ] ) { 5204 matchedHandlers.push( handleObj ); 5205 } 5206 } 5207 if ( matchedHandlers.length ) { 5208 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 5209 } 5210 } 5211 } 5212 } 5213 5214 // Add the remaining (directly-bound) handlers 5215 cur = this; 5216 if ( delegateCount < handlers.length ) { 5217 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 5218 } 5219 5220 return handlerQueue; 5221 }, 5222 5223 addProp: function( name, hook ) { 5224 Object.defineProperty( jQuery.Event.prototype, name, { 5225 enumerable: true, 5226 configurable: true, 5227 5228 get: isFunction( hook ) ? 5229 function() { 5230 if ( this.originalEvent ) { 5231 return hook( this.originalEvent ); 5232 } 5233 } : 5234 function() { 5235 if ( this.originalEvent ) { 5236 return this.originalEvent[ name ]; 5237 } 5238 }, 5239 5240 set: function( value ) { 5241 Object.defineProperty( this, name, { 5242 enumerable: true, 5243 configurable: true, 5244 writable: true, 5245 value: value 5246 } ); 5247 } 5248 } ); 5249 }, 5250 5251 fix: function( originalEvent ) { 5252 return originalEvent[ jQuery.expando ] ? 5253 originalEvent : 5254 new jQuery.Event( originalEvent ); 5255 }, 5256 5257 special: { 5258 load: { 5259 5260 // Prevent triggered image.load events from bubbling to window.load 5261 noBubble: true 5262 }, 5263 click: { 5264 5265 // Utilize native event to ensure correct state for checkable inputs 5266 setup: function( data ) { 5267 5268 // For mutual compressibility with _default, replace `this` access with a local var. 5269 // `|| data` is dead code meant only to preserve the variable through minification. 5270 var el = this || data; 5271 5272 // Claim the first handler 5273 if ( rcheckableType.test( el.type ) && 5274 el.click && nodeName( el, "input" ) ) { 5275 5276 // dataPriv.set( el, "click", ... ) 5277 leverageNative( el, "click", true ); 5278 } 5279 5280 // Return false to allow normal processing in the caller 5281 return false; 5282 }, 5283 trigger: function( data ) { 5284 5285 // For mutual compressibility with _default, replace `this` access with a local var. 5286 // `|| data` is dead code meant only to preserve the variable through minification. 5287 var el = this || data; 5288 5289 // Force setup before triggering a click 5290 if ( rcheckableType.test( el.type ) && 5291 el.click && nodeName( el, "input" ) ) { 5292 5293 leverageNative( el, "click" ); 5294 } 5295 5296 // Return non-false to allow normal event-path propagation 5297 return true; 5298 }, 5299 5300 // For cross-browser consistency, suppress native .click() on links 5301 // Also prevent it if we're currently inside a leveraged native-event stack 5302 _default: function( event ) { 5303 var target = event.target; 5304 return rcheckableType.test( target.type ) && 5305 target.click && nodeName( target, "input" ) && 5306 dataPriv.get( target, "click" ) || 5307 nodeName( target, "a" ); 5308 } 5309 }, 5310 5311 beforeunload: { 5312 postDispatch: function( event ) { 5313 5314 // Support: Firefox 20+ 5315 // Firefox doesn't alert if the returnValue field is not set. 5316 if ( event.result !== undefined && event.originalEvent ) { 5317 event.originalEvent.returnValue = event.result; 5318 } 5319 } 5320 } 5321 } 5322}; 5323 5324// Ensure the presence of an event listener that handles manually-triggered 5325// synthetic events by interrupting progress until reinvoked in response to 5326// *native* events that it fires directly, ensuring that state changes have 5327// already occurred before other listeners are invoked. 5328function leverageNative( el, type, isSetup ) { 5329 5330 // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add 5331 if ( !isSetup ) { 5332 if ( dataPriv.get( el, type ) === undefined ) { 5333 jQuery.event.add( el, type, returnTrue ); 5334 } 5335 return; 5336 } 5337 5338 // Register the controller as a special universal handler for all event namespaces 5339 dataPriv.set( el, type, false ); 5340 jQuery.event.add( el, type, { 5341 namespace: false, 5342 handler: function( event ) { 5343 var result, 5344 saved = dataPriv.get( this, type ); 5345 5346 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 5347 5348 // Interrupt processing of the outer synthetic .trigger()ed event 5349 if ( !saved ) { 5350 5351 // Store arguments for use when handling the inner native event 5352 // There will always be at least one argument (an event object), so this array 5353 // will not be confused with a leftover capture object. 5354 saved = slice.call( arguments ); 5355 dataPriv.set( this, type, saved ); 5356 5357 // Trigger the native event and capture its result 5358 this[ type ](); 5359 result = dataPriv.get( this, type ); 5360 dataPriv.set( this, type, false ); 5361 5362 if ( saved !== result ) { 5363 5364 // Cancel the outer synthetic event 5365 event.stopImmediatePropagation(); 5366 event.preventDefault(); 5367 5368 return result; 5369 } 5370 5371 // If this is an inner synthetic event for an event with a bubbling surrogate 5372 // (focus or blur), assume that the surrogate already propagated from triggering 5373 // the native event and prevent that from happening again here. 5374 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 5375 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 5376 // less bad than duplication. 5377 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 5378 event.stopPropagation(); 5379 } 5380 5381 // If this is a native event triggered above, everything is now in order 5382 // Fire an inner synthetic event with the original arguments 5383 } else if ( saved ) { 5384 5385 // ...and capture the result 5386 dataPriv.set( this, type, jQuery.event.trigger( 5387 saved[ 0 ], 5388 saved.slice( 1 ), 5389 this 5390 ) ); 5391 5392 // Abort handling of the native event by all jQuery handlers while allowing 5393 // native handlers on the same element to run. On target, this is achieved 5394 // by stopping immediate propagation just on the jQuery event. However, 5395 // the native event is re-wrapped by a jQuery one on each level of the 5396 // propagation so the only way to stop it for jQuery is to stop it for 5397 // everyone via native `stopPropagation()`. This is not a problem for 5398 // focus/blur which don't bubble, but it does also stop click on checkboxes 5399 // and radios. We accept this limitation. 5400 event.stopPropagation(); 5401 event.isImmediatePropagationStopped = returnTrue; 5402 } 5403 } 5404 } ); 5405} 5406 5407jQuery.removeEvent = function( elem, type, handle ) { 5408 5409 // This "if" is needed for plain objects 5410 if ( elem.removeEventListener ) { 5411 elem.removeEventListener( type, handle ); 5412 } 5413}; 5414 5415jQuery.Event = function( src, props ) { 5416 5417 // Allow instantiation without the 'new' keyword 5418 if ( !( this instanceof jQuery.Event ) ) { 5419 return new jQuery.Event( src, props ); 5420 } 5421 5422 // Event object 5423 if ( src && src.type ) { 5424 this.originalEvent = src; 5425 this.type = src.type; 5426 5427 // Events bubbling up the document may have been marked as prevented 5428 // by a handler lower down the tree; reflect the correct value. 5429 this.isDefaultPrevented = src.defaultPrevented || 5430 src.defaultPrevented === undefined && 5431 5432 // Support: Android <=2.3 only 5433 src.returnValue === false ? 5434 returnTrue : 5435 returnFalse; 5436 5437 // Create target properties 5438 // Support: Safari <=6 - 7 only 5439 // Target should not be a text node (trac-504, trac-13143) 5440 this.target = ( src.target && src.target.nodeType === 3 ) ? 5441 src.target.parentNode : 5442 src.target; 5443 5444 this.currentTarget = src.currentTarget; 5445 this.relatedTarget = src.relatedTarget; 5446 5447 // Event type 5448 } else { 5449 this.type = src; 5450 } 5451 5452 // Put explicitly provided properties onto the event object 5453 if ( props ) { 5454 jQuery.extend( this, props ); 5455 } 5456 5457 // Create a timestamp if incoming event doesn't have one 5458 this.timeStamp = src && src.timeStamp || Date.now(); 5459 5460 // Mark it as fixed 5461 this[ jQuery.expando ] = true; 5462}; 5463 5464// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5465// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5466jQuery.Event.prototype = { 5467 constructor: jQuery.Event, 5468 isDefaultPrevented: returnFalse, 5469 isPropagationStopped: returnFalse, 5470 isImmediatePropagationStopped: returnFalse, 5471 isSimulated: false, 5472 5473 preventDefault: function() { 5474 var e = this.originalEvent; 5475 5476 this.isDefaultPrevented = returnTrue; 5477 5478 if ( e && !this.isSimulated ) { 5479 e.preventDefault(); 5480 } 5481 }, 5482 stopPropagation: function() { 5483 var e = this.originalEvent; 5484 5485 this.isPropagationStopped = returnTrue; 5486 5487 if ( e && !this.isSimulated ) { 5488 e.stopPropagation(); 5489 } 5490 }, 5491 stopImmediatePropagation: function() { 5492 var e = this.originalEvent; 5493 5494 this.isImmediatePropagationStopped = returnTrue; 5495 5496 if ( e && !this.isSimulated ) { 5497 e.stopImmediatePropagation(); 5498 } 5499 5500 this.stopPropagation(); 5501 } 5502}; 5503 5504// Includes all common event props including KeyEvent and MouseEvent specific props 5505jQuery.each( { 5506 altKey: true, 5507 bubbles: true, 5508 cancelable: true, 5509 changedTouches: true, 5510 ctrlKey: true, 5511 detail: true, 5512 eventPhase: true, 5513 metaKey: true, 5514 pageX: true, 5515 pageY: true, 5516 shiftKey: true, 5517 view: true, 5518 "char": true, 5519 code: true, 5520 charCode: true, 5521 key: true, 5522 keyCode: true, 5523 button: true, 5524 buttons: true, 5525 clientX: true, 5526 clientY: true, 5527 offsetX: true, 5528 offsetY: true, 5529 pointerId: true, 5530 pointerType: true, 5531 screenX: true, 5532 screenY: true, 5533 targetTouches: true, 5534 toElement: true, 5535 touches: true, 5536 which: true 5537}, jQuery.event.addProp ); 5538 5539jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 5540 5541 function focusMappedHandler( nativeEvent ) { 5542 if ( document.documentMode ) { 5543 5544 // Support: IE 11+ 5545 // Attach a single focusin/focusout handler on the document while someone wants 5546 // focus/blur. This is because the former are synchronous in IE while the latter 5547 // are async. In other browsers, all those handlers are invoked synchronously. 5548 5549 // `handle` from private data would already wrap the event, but we need 5550 // to change the `type` here. 5551 var handle = dataPriv.get( this, "handle" ), 5552 event = jQuery.event.fix( nativeEvent ); 5553 event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; 5554 event.isSimulated = true; 5555 5556 // First, handle focusin/focusout 5557 handle( nativeEvent ); 5558 5559 // ...then, handle focus/blur 5560 // 5561 // focus/blur don't bubble while focusin/focusout do; simulate the former by only 5562 // invoking the handler at the lower level. 5563 if ( event.target === event.currentTarget ) { 5564 5565 // The setup part calls `leverageNative`, which, in turn, calls 5566 // `jQuery.event.add`, so event handle will already have been set 5567 // by this point. 5568 handle( event ); 5569 } 5570 } else { 5571 5572 // For non-IE browsers, attach a single capturing handler on the document 5573 // while someone wants focusin/focusout. 5574 jQuery.event.simulate( delegateType, nativeEvent.target, 5575 jQuery.event.fix( nativeEvent ) ); 5576 } 5577 } 5578 5579 jQuery.event.special[ type ] = { 5580 5581 // Utilize native event if possible so blur/focus sequence is correct 5582 setup: function() { 5583 5584 var attaches; 5585 5586 // Claim the first handler 5587 // dataPriv.set( this, "focus", ... ) 5588 // dataPriv.set( this, "blur", ... ) 5589 leverageNative( this, type, true ); 5590 5591 if ( document.documentMode ) { 5592 5593 // Support: IE 9 - 11+ 5594 // We use the same native handler for focusin & focus (and focusout & blur) 5595 // so we need to coordinate setup & teardown parts between those events. 5596 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5597 attaches = dataPriv.get( this, delegateType ); 5598 if ( !attaches ) { 5599 this.addEventListener( delegateType, focusMappedHandler ); 5600 } 5601 dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); 5602 } else { 5603 5604 // Return false to allow normal processing in the caller 5605 return false; 5606 } 5607 }, 5608 trigger: function() { 5609 5610 // Force setup before trigger 5611 leverageNative( this, type ); 5612 5613 // Return non-false to allow normal event-path propagation 5614 return true; 5615 }, 5616 5617 teardown: function() { 5618 var attaches; 5619 5620 if ( document.documentMode ) { 5621 attaches = dataPriv.get( this, delegateType ) - 1; 5622 if ( !attaches ) { 5623 this.removeEventListener( delegateType, focusMappedHandler ); 5624 dataPriv.remove( this, delegateType ); 5625 } else { 5626 dataPriv.set( this, delegateType, attaches ); 5627 } 5628 } else { 5629 5630 // Return false to indicate standard teardown should be applied 5631 return false; 5632 } 5633 }, 5634 5635 // Suppress native focus or blur if we're currently inside 5636 // a leveraged native-event stack 5637 _default: function( event ) { 5638 return dataPriv.get( event.target, type ); 5639 }, 5640 5641 delegateType: delegateType 5642 }; 5643 5644 // Support: Firefox <=44 5645 // Firefox doesn't have focus(in | out) events 5646 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5647 // 5648 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 5649 // focus(in | out) events fire after focus & blur events, 5650 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 5651 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 5652 // 5653 // Support: IE 9 - 11+ 5654 // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, 5655 // attach a single handler for both events in IE. 5656 jQuery.event.special[ delegateType ] = { 5657 setup: function() { 5658 5659 // Handle: regular nodes (via `this.ownerDocument`), window 5660 // (via `this.document`) & document (via `this`). 5661 var doc = this.ownerDocument || this.document || this, 5662 dataHolder = document.documentMode ? this : doc, 5663 attaches = dataPriv.get( dataHolder, delegateType ); 5664 5665 // Support: IE 9 - 11+ 5666 // We use the same native handler for focusin & focus (and focusout & blur) 5667 // so we need to coordinate setup & teardown parts between those events. 5668 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 5669 if ( !attaches ) { 5670 if ( document.documentMode ) { 5671 this.addEventListener( delegateType, focusMappedHandler ); 5672 } else { 5673 doc.addEventListener( type, focusMappedHandler, true ); 5674 } 5675 } 5676 dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); 5677 }, 5678 teardown: function() { 5679 var doc = this.ownerDocument || this.document || this, 5680 dataHolder = document.documentMode ? this : doc, 5681 attaches = dataPriv.get( dataHolder, delegateType ) - 1; 5682 5683 if ( !attaches ) { 5684 if ( document.documentMode ) { 5685 this.removeEventListener( delegateType, focusMappedHandler ); 5686 } else { 5687 doc.removeEventListener( type, focusMappedHandler, true ); 5688 } 5689 dataPriv.remove( dataHolder, delegateType ); 5690 } else { 5691 dataPriv.set( dataHolder, delegateType, attaches ); 5692 } 5693 } 5694 }; 5695} ); 5696 5697// Create mouseenter/leave events using mouseover/out and event-time checks 5698// so that event delegation works in jQuery. 5699// Do the same for pointerenter/pointerleave and pointerover/pointerout 5700// 5701// Support: Safari 7 only 5702// Safari sends mouseenter too often; see: 5703// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 5704// for the description of the bug (it existed in older Chrome versions as well). 5705jQuery.each( { 5706 mouseenter: "mouseover", 5707 mouseleave: "mouseout", 5708 pointerenter: "pointerover", 5709 pointerleave: "pointerout" 5710}, function( orig, fix ) { 5711 jQuery.event.special[ orig ] = { 5712 delegateType: fix, 5713 bindType: fix, 5714 5715 handle: function( event ) { 5716 var ret, 5717 target = this, 5718 related = event.relatedTarget, 5719 handleObj = event.handleObj; 5720 5721 // For mouseenter/leave call the handler if related is outside the target. 5722 // NB: No relatedTarget if the mouse left/entered the browser window 5723 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 5724 event.type = handleObj.origType; 5725 ret = handleObj.handler.apply( this, arguments ); 5726 event.type = fix; 5727 } 5728 return ret; 5729 } 5730 }; 5731} ); 5732 5733jQuery.fn.extend( { 5734 5735 on: function( types, selector, data, fn ) { 5736 return on( this, types, selector, data, fn ); 5737 }, 5738 one: function( types, selector, data, fn ) { 5739 return on( this, types, selector, data, fn, 1 ); 5740 }, 5741 off: function( types, selector, fn ) { 5742 var handleObj, type; 5743 if ( types && types.preventDefault && types.handleObj ) { 5744 5745 // ( event ) dispatched jQuery.Event 5746 handleObj = types.handleObj; 5747 jQuery( types.delegateTarget ).off( 5748 handleObj.namespace ? 5749 handleObj.origType + "." + handleObj.namespace : 5750 handleObj.origType, 5751 handleObj.selector, 5752 handleObj.handler 5753 ); 5754 return this; 5755 } 5756 if ( typeof types === "object" ) { 5757 5758 // ( types-object [, selector] ) 5759 for ( type in types ) { 5760 this.off( type, selector, types[ type ] ); 5761 } 5762 return this; 5763 } 5764 if ( selector === false || typeof selector === "function" ) { 5765 5766 // ( types [, fn] ) 5767 fn = selector; 5768 selector = undefined; 5769 } 5770 if ( fn === false ) { 5771 fn = returnFalse; 5772 } 5773 return this.each( function() { 5774 jQuery.event.remove( this, types, fn, selector ); 5775 } ); 5776 } 5777} ); 5778 5779 5780var 5781 5782 // Support: IE <=10 - 11, Edge 12 - 13 only 5783 // In IE/Edge using regex groups here causes severe slowdowns. 5784 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5785 rnoInnerhtml = /<script|<style|<link/i, 5786 5787 // checked="checked" or checked 5788 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5789 5790 rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g; 5791 5792// Prefer a tbody over its parent table for containing new rows 5793function manipulationTarget( elem, content ) { 5794 if ( nodeName( elem, "table" ) && 5795 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 5796 5797 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 5798 } 5799 5800 return elem; 5801} 5802 5803// Replace/restore the type attribute of script elements for safe DOM manipulation 5804function disableScript( elem ) { 5805 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 5806 return elem; 5807} 5808function restoreScript( elem ) { 5809 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 5810 elem.type = elem.type.slice( 5 ); 5811 } else { 5812 elem.removeAttribute( "type" ); 5813 } 5814 5815 return elem; 5816} 5817 5818function cloneCopyEvent( src, dest ) { 5819 var i, l, type, pdataOld, udataOld, udataCur, events; 5820 5821 if ( dest.nodeType !== 1 ) { 5822 return; 5823 } 5824 5825 // 1. Copy private data: events, handlers, etc. 5826 if ( dataPriv.hasData( src ) ) { 5827 pdataOld = dataPriv.get( src ); 5828 events = pdataOld.events; 5829 5830 if ( events ) { 5831 dataPriv.remove( dest, "handle events" ); 5832 5833 for ( type in events ) { 5834 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 5835 jQuery.event.add( dest, type, events[ type ][ i ] ); 5836 } 5837 } 5838 } 5839 } 5840 5841 // 2. Copy user data 5842 if ( dataUser.hasData( src ) ) { 5843 udataOld = dataUser.access( src ); 5844 udataCur = jQuery.extend( {}, udataOld ); 5845 5846 dataUser.set( dest, udataCur ); 5847 } 5848} 5849 5850// Fix IE bugs, see support tests 5851function fixInput( src, dest ) { 5852 var nodeName = dest.nodeName.toLowerCase(); 5853 5854 // Fails to persist the checked state of a cloned checkbox or radio button. 5855 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 5856 dest.checked = src.checked; 5857 5858 // Fails to return the selected option to the default selected state when cloning options 5859 } else if ( nodeName === "input" || nodeName === "textarea" ) { 5860 dest.defaultValue = src.defaultValue; 5861 } 5862} 5863 5864function domManip( collection, args, callback, ignored ) { 5865 5866 // Flatten any nested arrays 5867 args = flat( args ); 5868 5869 var fragment, first, scripts, hasScripts, node, doc, 5870 i = 0, 5871 l = collection.length, 5872 iNoClone = l - 1, 5873 value = args[ 0 ], 5874 valueIsFunction = isFunction( value ); 5875 5876 // We can't cloneNode fragments that contain checked, in WebKit 5877 if ( valueIsFunction || 5878 ( l > 1 && typeof value === "string" && 5879 !support.checkClone && rchecked.test( value ) ) ) { 5880 return collection.each( function( index ) { 5881 var self = collection.eq( index ); 5882 if ( valueIsFunction ) { 5883 args[ 0 ] = value.call( this, index, self.html() ); 5884 } 5885 domManip( self, args, callback, ignored ); 5886 } ); 5887 } 5888 5889 if ( l ) { 5890 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 5891 first = fragment.firstChild; 5892 5893 if ( fragment.childNodes.length === 1 ) { 5894 fragment = first; 5895 } 5896 5897 // Require either new content or an interest in ignored elements to invoke the callback 5898 if ( first || ignored ) { 5899 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 5900 hasScripts = scripts.length; 5901 5902 // Use the original fragment for the last item 5903 // instead of the first because it can end up 5904 // being emptied incorrectly in certain situations (trac-8070). 5905 for ( ; i < l; i++ ) { 5906 node = fragment; 5907 5908 if ( i !== iNoClone ) { 5909 node = jQuery.clone( node, true, true ); 5910 5911 // Keep references to cloned scripts for later restoration 5912 if ( hasScripts ) { 5913 5914 // Support: Android <=4.0 only, PhantomJS 1 only 5915 // push.apply(_, arraylike) throws on ancient WebKit 5916 jQuery.merge( scripts, getAll( node, "script" ) ); 5917 } 5918 } 5919 5920 callback.call( collection[ i ], node, i ); 5921 } 5922 5923 if ( hasScripts ) { 5924 doc = scripts[ scripts.length - 1 ].ownerDocument; 5925 5926 // Re-enable scripts 5927 jQuery.map( scripts, restoreScript ); 5928 5929 // Evaluate executable scripts on first document insertion 5930 for ( i = 0; i < hasScripts; i++ ) { 5931 node = scripts[ i ]; 5932 if ( rscriptType.test( node.type || "" ) && 5933 !dataPriv.access( node, "globalEval" ) && 5934 jQuery.contains( doc, node ) ) { 5935 5936 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 5937 5938 // Optional AJAX dependency, but won't run scripts if not present 5939 if ( jQuery._evalUrl && !node.noModule ) { 5940 jQuery._evalUrl( node.src, { 5941 nonce: node.nonce || node.getAttribute( "nonce" ) 5942 }, doc ); 5943 } 5944 } else { 5945 5946 // Unwrap a CDATA section containing script contents. This shouldn't be 5947 // needed as in XML documents they're already not visible when 5948 // inspecting element contents and in HTML documents they have no 5949 // meaning but we're preserving that logic for backwards compatibility. 5950 // This will be removed completely in 4.0. See gh-4904. 5951 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 5952 } 5953 } 5954 } 5955 } 5956 } 5957 } 5958 5959 return collection; 5960} 5961 5962function remove( elem, selector, keepData ) { 5963 var node, 5964 nodes = selector ? jQuery.filter( selector, elem ) : elem, 5965 i = 0; 5966 5967 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 5968 if ( !keepData && node.nodeType === 1 ) { 5969 jQuery.cleanData( getAll( node ) ); 5970 } 5971 5972 if ( node.parentNode ) { 5973 if ( keepData && isAttached( node ) ) { 5974 setGlobalEval( getAll( node, "script" ) ); 5975 } 5976 node.parentNode.removeChild( node ); 5977 } 5978 } 5979 5980 return elem; 5981} 5982 5983jQuery.extend( { 5984 htmlPrefilter: function( html ) { 5985 return html; 5986 }, 5987 5988 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 5989 var i, l, srcElements, destElements, 5990 clone = elem.cloneNode( true ), 5991 inPage = isAttached( elem ); 5992 5993 // Fix IE cloning issues 5994 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 5995 !jQuery.isXMLDoc( elem ) ) { 5996 5997 // We eschew jQuery#find here for performance reasons: 5998 // https://jsperf.com/getall-vs-sizzle/2 5999 destElements = getAll( clone ); 6000 srcElements = getAll( elem ); 6001 6002 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6003 fixInput( srcElements[ i ], destElements[ i ] ); 6004 } 6005 } 6006 6007 // Copy the events from the original to the clone 6008 if ( dataAndEvents ) { 6009 if ( deepDataAndEvents ) { 6010 srcElements = srcElements || getAll( elem ); 6011 destElements = destElements || getAll( clone ); 6012 6013 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6014 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 6015 } 6016 } else { 6017 cloneCopyEvent( elem, clone ); 6018 } 6019 } 6020 6021 // Preserve script evaluation history 6022 destElements = getAll( clone, "script" ); 6023 if ( destElements.length > 0 ) { 6024 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6025 } 6026 6027 // Return the cloned set 6028 return clone; 6029 }, 6030 6031 cleanData: function( elems ) { 6032 var data, elem, type, 6033 special = jQuery.event.special, 6034 i = 0; 6035 6036 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 6037 if ( acceptData( elem ) ) { 6038 if ( ( data = elem[ dataPriv.expando ] ) ) { 6039 if ( data.events ) { 6040 for ( type in data.events ) { 6041 if ( special[ type ] ) { 6042 jQuery.event.remove( elem, type ); 6043 6044 // This is a shortcut to avoid jQuery.event.remove's overhead 6045 } else { 6046 jQuery.removeEvent( elem, type, data.handle ); 6047 } 6048 } 6049 } 6050
vendor: 4,139 bytes, lines 6051-6215
6051 // Support: Chrome <=35 - 45+ 6052 // Assign undefined instead of using delete, see Data#remove 6053 elem[ dataPriv.expando ] = undefined; 6054 } 6055 if ( elem[ dataUser.expando ] ) { 6056 6057 // Support: Chrome <=35 - 45+ 6058 // Assign undefined instead of using delete, see Data#remove 6059 elem[ dataUser.expando ] = undefined; 6060 } 6061 } 6062 } 6063 } 6064} ); 6065 6066jQuery.fn.extend( { 6067 detach: function( selector ) { 6068 return remove( this, selector, true ); 6069 }, 6070 6071 remove: function( selector ) { 6072 return remove( this, selector ); 6073 }, 6074 6075 text: function( value ) { 6076 return access( this, function( value ) { 6077 return value === undefined ? 6078 jQuery.text( this ) : 6079 this.empty().each( function() { 6080 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6081 this.textContent = value; 6082 } 6083 } ); 6084 }, null, value, arguments.length ); 6085 }, 6086 6087 append: function() { 6088 return domManip( this, arguments, function( elem ) { 6089 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6090 var target = manipulationTarget( this, elem ); 6091 target.appendChild( elem ); 6092 } 6093 } ); 6094 }, 6095 6096 prepend: function() { 6097 return domManip( this, arguments, function( elem ) { 6098 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6099 var target = manipulationTarget( this, elem ); 6100 target.insertBefore( elem, target.firstChild ); 6101 } 6102 } ); 6103 }, 6104 6105 before: function() { 6106 return domManip( this, arguments, function( elem ) { 6107 if ( this.parentNode ) { 6108 this.parentNode.insertBefore( elem, this ); 6109 } 6110 } ); 6111 }, 6112 6113 after: function() { 6114 return domManip( this, arguments, function( elem ) { 6115 if ( this.parentNode ) { 6116 this.parentNode.insertBefore( elem, this.nextSibling ); 6117 } 6118 } ); 6119 }, 6120 6121 empty: function() { 6122 var elem, 6123 i = 0; 6124 6125 for ( ; ( elem = this[ i ] ) != null; i++ ) { 6126 if ( elem.nodeType === 1 ) { 6127 6128 // Prevent memory leaks 6129 jQuery.cleanData( getAll( elem, false ) ); 6130 6131 // Remove any remaining nodes 6132 elem.textContent = ""; 6133 } 6134 } 6135 6136 return this; 6137 }, 6138 6139 clone: function( dataAndEvents, deepDataAndEvents ) { 6140 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6141 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6142 6143 return this.map( function() { 6144 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 6145 } ); 6146 }, 6147 6148 html: function( value ) { 6149 return access( this, function( value ) { 6150 var elem = this[ 0 ] || {}, 6151 i = 0, 6152 l = this.length; 6153 6154 if ( value === undefined && elem.nodeType === 1 ) { 6155 return elem.innerHTML; 6156 } 6157 6158 // See if we can take a shortcut and just use innerHTML 6159 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 6160 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 6161 6162 value = jQuery.htmlPrefilter( value ); 6163 6164 try { 6165 for ( ; i < l; i++ ) { 6166 elem = this[ i ] || {}; 6167 6168 // Remove element nodes and prevent memory leaks 6169 if ( elem.nodeType === 1 ) { 6170 jQuery.cleanData( getAll( elem, false ) ); 6171 elem.innerHTML = value; 6172 } 6173 } 6174 6175 elem = 0; 6176 6177 // If using innerHTML throws an exception, use the fallback method 6178 } catch ( e ) {} 6179 } 6180 6181 if ( elem ) { 6182 this.empty().append( value ); 6183 } 6184 }, null, value, arguments.length ); 6185 }, 6186 6187 replaceWith: function() { 6188 var ignored = []; 6189 6190 // Make the changes, replacing each non-ignored context element with the new content 6191 return domManip( this, arguments, function( elem ) { 6192 var parent = this.parentNode; 6193 6194 if ( jQuery.inArray( this, ignored ) < 0 ) { 6195 jQuery.cleanData( getAll( this ) ); 6196 if ( parent ) { 6197 parent.replaceChild( elem, this ); 6198 } 6199 } 6200 6201 // Force callback invocation 6202 }, ignored ); 6203 } 6204} ); 6205 6206jQuery.each( { 6207 appendTo: "append", 6208 prependTo: "prepend", 6209 insertBefore: "before", 6210 insertAfter: "after", 6211 replaceAll: "replaceWith" 6212}, function( name, original ) { 6213 jQuery.fn[ name ] = function( selector ) { 6214 var elems, 6215 ret = [],
vendor: 31,588 bytes, lines 6216-7278
6216 insert = jQuery( selector ), 6217 last = insert.length - 1, 6218 i = 0; 6219 6220 for ( ; i <= last; i++ ) { 6221 elems = i === last ? this : this.clone( true ); 6222 jQuery( insert[ i ] )[ original ]( elems ); 6223 6224 // Support: Android <=4.0 only, PhantomJS 1 only 6225 // .get() because push.apply(_, arraylike) throws on ancient WebKit 6226 push.apply( ret, elems.get() ); 6227 } 6228 6229 return this.pushStack( ret ); 6230 }; 6231} ); 6232var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 6233 6234var rcustomProp = /^--/; 6235 6236 6237var getStyles = function( elem ) { 6238 6239 // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) 6240 // IE throws on elements created in popups 6241 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6242 var view = elem.ownerDocument.defaultView; 6243 6244 if ( !view || !view.opener ) { 6245 view = window; 6246 } 6247 6248 return view.getComputedStyle( elem ); 6249 }; 6250 6251var swap = function( elem, options, callback ) { 6252 var ret, name, 6253 old = {}; 6254 6255 // Remember the old values, and insert the new ones 6256 for ( name in options ) { 6257 old[ name ] = elem.style[ name ]; 6258 elem.style[ name ] = options[ name ]; 6259 } 6260 6261 ret = callback.call( elem ); 6262 6263 // Revert the old values 6264 for ( name in options ) { 6265 elem.style[ name ] = old[ name ]; 6266 } 6267 6268 return ret; 6269}; 6270 6271 6272var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 6273 6274 6275 6276( function() { 6277 6278 // Executing both pixelPosition & boxSizingReliable tests require only one layout 6279 // so they're executed at the same time to save the second computation. 6280 function computeStyleTests() { 6281 6282 // This is a singleton, we need to execute it only once 6283 if ( !div ) { 6284 return; 6285 } 6286 6287 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 6288 "margin-top:1px;padding:0;border:0"; 6289 div.style.cssText = 6290 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 6291 "margin:auto;border:1px;padding:1px;" + 6292 "width:60%;top:1%"; 6293 documentElement.appendChild( container ).appendChild( div ); 6294 6295 var divStyle = window.getComputedStyle( div ); 6296 pixelPositionVal = divStyle.top !== "1%"; 6297 6298 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 6299 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 6300 6301 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 6302 // Some styles come back with percentage values, even though they shouldn't 6303 div.style.right = "60%"; 6304 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 6305 6306 // Support: IE 9 - 11 only 6307 // Detect misreporting of content dimensions for box-sizing:border-box elements 6308 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 6309 6310 // Support: IE 9 only 6311 // Detect overflow:scroll screwiness (gh-3699) 6312 // Support: Chrome <=64 6313 // Don't get tricked when zoom affects offsetWidth (gh-4029) 6314 div.style.position = "absolute"; 6315 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 6316 6317 documentElement.removeChild( container ); 6318 6319 // Nullify the div so it wouldn't be stored in the memory and 6320 // it will also be a sign that checks already performed 6321 div = null; 6322 } 6323 6324 function roundPixelMeasures( measure ) { 6325 return Math.round( parseFloat( measure ) ); 6326 } 6327 6328 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 6329 reliableTrDimensionsVal, reliableMarginLeftVal, 6330 container = document.createElement( "div" ), 6331 div = document.createElement( "div" ); 6332 6333 // Finish early in limited (non-browser) environments 6334 if ( !div.style ) { 6335 return; 6336 } 6337 6338 // Support: IE <=9 - 11 only 6339 // Style of cloned element affects source element cloned (trac-8908) 6340 div.style.backgroundClip = "content-box"; 6341 div.cloneNode( true ).style.backgroundClip = ""; 6342 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6343 6344 jQuery.extend( support, { 6345 boxSizingReliable: function() { 6346 computeStyleTests(); 6347 return boxSizingReliableVal; 6348 }, 6349 pixelBoxStyles: function() { 6350 computeStyleTests(); 6351 return pixelBoxStylesVal; 6352 }, 6353 pixelPosition: function() { 6354 computeStyleTests(); 6355 return pixelPositionVal; 6356 }, 6357 reliableMarginLeft: function() { 6358 computeStyleTests(); 6359 return reliableMarginLeftVal; 6360 }, 6361 scrollboxSize: function() { 6362 computeStyleTests(); 6363 return scrollboxSizeVal; 6364 }, 6365 6366 // Support: IE 9 - 11+, Edge 15 - 18+ 6367 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6368 // set in CSS while `offset*` properties report correct values. 6369 // Behavior in IE 9 is more subtle than in newer versions & it passes 6370 // some versions of this test; make sure not to make it pass there! 6371 // 6372 // Support: Firefox 70+ 6373 // Only Firefox includes border widths 6374 // in computed dimensions. (gh-4529) 6375 reliableTrDimensions: function() { 6376 var table, tr, trChild, trStyle; 6377 if ( reliableTrDimensionsVal == null ) { 6378 table = document.createElement( "table" ); 6379 tr = document.createElement( "tr" ); 6380 trChild = document.createElement( "div" ); 6381 6382 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 6383 tr.style.cssText = "box-sizing:content-box;border:1px solid"; 6384 6385 // Support: Chrome 86+ 6386 // Height set through cssText does not get applied. 6387 // Computed height then comes back as 0. 6388 tr.style.height = "1px"; 6389 trChild.style.height = "9px"; 6390 6391 // Support: Android 8 Chrome 86+ 6392 // In our bodyBackground.html iframe, 6393 // display for all div elements is set to "inline", 6394 // which causes a problem only in Android 8 Chrome 86. 6395 // Ensuring the div is `display: block` 6396 // gets around this issue. 6397 trChild.style.display = "block"; 6398 6399 documentElement 6400 .appendChild( table ) 6401 .appendChild( tr ) 6402 .appendChild( trChild ); 6403 6404 trStyle = window.getComputedStyle( tr ); 6405 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 6406 parseInt( trStyle.borderTopWidth, 10 ) + 6407 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 6408 6409 documentElement.removeChild( table ); 6410 } 6411 return reliableTrDimensionsVal; 6412 } 6413 } ); 6414} )(); 6415 6416 6417function curCSS( elem, name, computed ) { 6418 var width, minWidth, maxWidth, ret, 6419 isCustomProp = rcustomProp.test( name ), 6420 6421 // Support: Firefox 51+ 6422 // Retrieving style before computed somehow 6423 // fixes an issue with getting wrong values 6424 // on detached elements 6425 style = elem.style; 6426 6427 computed = computed || getStyles( elem ); 6428 6429 // getPropertyValue is needed for: 6430 // .css('filter') (IE 9 only, trac-12537) 6431 // .css('--customProperty) (gh-3144) 6432 if ( computed ) { 6433 6434 // Support: IE <=9 - 11+ 6435 // IE only supports `"float"` in `getPropertyValue`; in computed styles 6436 // it's only available as `"cssFloat"`. We no longer modify properties 6437 // sent to `.css()` apart from camelCasing, so we need to check both. 6438 // Normally, this would create difference in behavior: if 6439 // `getPropertyValue` returns an empty string, the value returned 6440 // by `.css()` would be `undefined`. This is usually the case for 6441 // disconnected elements. However, in IE even disconnected elements 6442 // with no styles return `"none"` for `getPropertyValue( "float" )` 6443 ret = computed.getPropertyValue( name ) || computed[ name ]; 6444 6445 if ( isCustomProp && ret ) { 6446 6447 // Support: Firefox 105+, Chrome <=105+ 6448 // Spec requires trimming whitespace for custom properties (gh-4926). 6449 // Firefox only trims leading whitespace. Chrome just collapses 6450 // both leading & trailing whitespace to a single space. 6451 // 6452 // Fall back to `undefined` if empty string returned. 6453 // This collapses a missing definition with property defined 6454 // and set to an empty string but there's no standard API 6455 // allowing us to differentiate them without a performance penalty 6456 // and returning `undefined` aligns with older jQuery. 6457 // 6458 // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED 6459 // as whitespace while CSS does not, but this is not a problem 6460 // because CSS preprocessing replaces them with U+000A LINE FEED 6461 // (which *is* CSS whitespace) 6462 // https://www.w3.org/TR/css-syntax-3/#input-preprocessing 6463 ret = ret.replace( rtrimCSS, "$1" ) || undefined; 6464 } 6465 6466 if ( ret === "" && !isAttached( elem ) ) { 6467 ret = jQuery.style( elem, name ); 6468 } 6469 6470 // A tribute to the "awesome hack by Dean Edwards" 6471 // Android Browser returns percentage for some values, 6472 // but width seems to be reliably pixels. 6473 // This is against the CSSOM draft spec: 6474 // https://drafts.csswg.org/cssom/#resolved-values 6475 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 6476 6477 // Remember the original values 6478 width = style.width; 6479 minWidth = style.minWidth; 6480 maxWidth = style.maxWidth; 6481 6482 // Put in the new values to get a computed value out 6483 style.minWidth = style.maxWidth = style.width = ret; 6484 ret = computed.width; 6485 6486 // Revert the changed values 6487 style.width = width; 6488 style.minWidth = minWidth; 6489 style.maxWidth = maxWidth; 6490 } 6491 } 6492 6493 return ret !== undefined ? 6494 6495 // Support: IE <=9 - 11 only 6496 // IE returns zIndex value as an integer. 6497 ret + "" : 6498 ret; 6499} 6500 6501 6502function addGetHookIf( conditionFn, hookFn ) { 6503 6504 // Define the hook, we'll check on the first run if it's really needed. 6505 return { 6506 get: function() { 6507 if ( conditionFn() ) { 6508 6509 // Hook not needed (or it's not possible to use it due 6510 // to missing dependency), remove it. 6511 delete this.get; 6512 return; 6513 } 6514 6515 // Hook needed; redefine it so that the support test is not executed again. 6516 return ( this.get = hookFn ).apply( this, arguments ); 6517 } 6518 }; 6519} 6520 6521 6522var cssPrefixes = [ "Webkit", "Moz", "ms" ], 6523 emptyStyle = document.createElement( "div" ).style, 6524 vendorProps = {}; 6525 6526// Return a vendor-prefixed property or undefined 6527function vendorPropName( name ) { 6528 6529 // Check for vendor prefixed names 6530 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 6531 i = cssPrefixes.length; 6532 6533 while ( i-- ) { 6534 name = cssPrefixes[ i ] + capName; 6535 if ( name in emptyStyle ) { 6536 return name; 6537 } 6538 } 6539} 6540 6541// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 6542function finalPropName( name ) { 6543 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 6544 6545 if ( final ) { 6546 return final; 6547 } 6548 if ( name in emptyStyle ) { 6549 return name; 6550 } 6551 return vendorProps[ name ] = vendorPropName( name ) || name; 6552} 6553 6554 6555var 6556 6557 // Swappable if display is none or starts with table 6558 // except "table", "table-cell", or "table-caption" 6559 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 6560 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6561 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6562 cssNormalTransform = { 6563 letterSpacing: "0", 6564 fontWeight: "400" 6565 }; 6566 6567function setPositiveNumber( _elem, value, subtract ) { 6568 6569 // Any relative (+/-) values have already been 6570 // normalized at this point 6571 var matches = rcssNum.exec( value ); 6572 return matches ? 6573 6574 // Guard against undefined "subtract", e.g., when used as in cssHooks 6575 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 6576 value; 6577} 6578 6579function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 6580 var i = dimension === "width" ? 1 : 0, 6581 extra = 0, 6582 delta = 0, 6583 marginDelta = 0; 6584 6585 // Adjustment may not be necessary 6586 if ( box === ( isBorderBox ? "border" : "content" ) ) { 6587 return 0; 6588 } 6589 6590 for ( ; i < 4; i += 2 ) { 6591 6592 // Both box models exclude margin 6593 // Count margin delta separately to only add it after scroll gutter adjustment. 6594 // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). 6595 if ( box === "margin" ) { 6596 marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 6597 } 6598 6599 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 6600 if ( !isBorderBox ) { 6601 6602 // Add padding 6603 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6604 6605 // For "border" or "margin", add border 6606 if ( box !== "padding" ) { 6607 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6608 6609 // But still keep track of it otherwise 6610 } else { 6611 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6612 } 6613 6614 // If we get here with a border-box (content + padding + border), we're seeking "content" or 6615 // "padding" or "margin" 6616 } else { 6617 6618 // For "content", subtract padding 6619 if ( box === "content" ) { 6620 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 6621 } 6622 6623 // For "content" or "padding", subtract border 6624 if ( box !== "margin" ) { 6625 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 6626 } 6627 } 6628 } 6629 6630 // Account for positive content-box scroll gutter when requested by providing computedVal 6631 if ( !isBorderBox && computedVal >= 0 ) { 6632 6633 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 6634 // Assuming integer scroll gutter, subtract the rest and round down 6635 delta += Math.max( 0, Math.ceil( 6636 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6637 computedVal - 6638 delta - 6639 extra - 6640 0.5 6641 6642 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 6643 // Use an explicit zero to avoid NaN (gh-3964) 6644 ) ) || 0; 6645 } 6646 6647 return delta + marginDelta; 6648} 6649 6650function getWidthOrHeight( elem, dimension, extra ) { 6651 6652 // Start with computed style 6653 var styles = getStyles( elem ), 6654 6655 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 6656 // Fake content-box until we know it's needed to know the true value. 6657 boxSizingNeeded = !support.boxSizingReliable() || extra, 6658 isBorderBox = boxSizingNeeded && 6659 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6660 valueIsBorderBox = isBorderBox, 6661 6662 val = curCSS( elem, dimension, styles ), 6663 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 6664 6665 // Support: Firefox <=54 6666 // Return a confounding non-pixel value or feign ignorance, as appropriate. 6667 if ( rnumnonpx.test( val ) ) { 6668 if ( !extra ) { 6669 return val; 6670 } 6671 val = "auto"; 6672 } 6673 6674 6675 // Support: IE 9 - 11 only 6676 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 6677 // In those cases, the computed value can be trusted to be border-box. 6678 if ( ( !support.boxSizingReliable() && isBorderBox || 6679 6680 // Support: IE 10 - 11+, Edge 15 - 18+ 6681 // IE/Edge misreport `getComputedStyle` of table rows with width/height 6682 // set in CSS while `offset*` properties report correct values. 6683 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 6684 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 6685 6686 // Fall back to offsetWidth/offsetHeight when value is "auto" 6687 // This happens for inline elements with no explicit setting (gh-3571) 6688 val === "auto" || 6689 6690 // Support: Android <=4.1 - 4.3 only 6691 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 6692 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 6693 6694 // Make sure the element is visible & connected 6695 elem.getClientRects().length ) { 6696 6697 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 6698 6699 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 6700 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 6701 // retrieved value as a content box dimension. 6702 valueIsBorderBox = offsetProp in elem; 6703 if ( valueIsBorderBox ) { 6704 val = elem[ offsetProp ]; 6705 } 6706 } 6707 6708 // Normalize "" and auto 6709 val = parseFloat( val ) || 0; 6710 6711 // Adjust for the element's box model 6712 return ( val + 6713 boxModelAdjustment( 6714 elem, 6715 dimension, 6716 extra || ( isBorderBox ? "border" : "content" ), 6717 valueIsBorderBox, 6718 styles, 6719 6720 // Provide the current computed size to request scroll gutter calculation (gh-3589) 6721 val 6722 ) 6723 ) + "px"; 6724} 6725 6726jQuery.extend( { 6727 6728 // Add in style property hooks for overriding the default 6729 // behavior of getting and setting a style property 6730 cssHooks: { 6731 opacity: { 6732 get: function( elem, computed ) { 6733 if ( computed ) { 6734 6735 // We should always get a number back from opacity 6736 var ret = curCSS( elem, "opacity" ); 6737 return ret === "" ? "1" : ret; 6738 } 6739 } 6740 } 6741 }, 6742 6743 // Don't automatically add "px" to these possibly-unitless properties 6744 cssNumber: { 6745 animationIterationCount: true, 6746 aspectRatio: true, 6747 borderImageSlice: true, 6748 columnCount: true, 6749 flexGrow: true, 6750 flexShrink: true, 6751 fontWeight: true, 6752 gridArea: true, 6753 gridColumn: true, 6754 gridColumnEnd: true, 6755 gridColumnStart: true, 6756 gridRow: true, 6757 gridRowEnd: true, 6758 gridRowStart: true, 6759 lineHeight: true, 6760 opacity: true, 6761 order: true, 6762 orphans: true, 6763 scale: true, 6764 widows: true, 6765 zIndex: true, 6766 zoom: true, 6767 6768 // SVG-related 6769 fillOpacity: true, 6770 floodOpacity: true, 6771 stopOpacity: true, 6772 strokeMiterlimit: true, 6773 strokeOpacity: true 6774 }, 6775 6776 // Add in properties whose names you wish to fix before 6777 // setting or getting the value 6778 cssProps: {}, 6779 6780 // Get and set the style property on a DOM Node 6781 style: function( elem, name, value, extra ) { 6782 6783 // Don't set styles on text and comment nodes 6784 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 6785 return; 6786 } 6787 6788 // Make sure that we're working with the right name 6789 var ret, type, hooks, 6790 origName = camelCase( name ), 6791 isCustomProp = rcustomProp.test( name ), 6792 style = elem.style; 6793 6794 // Make sure that we're working with the right name. We don't 6795 // want to query the value if it is a CSS custom property 6796 // since they are user-defined. 6797 if ( !isCustomProp ) { 6798 name = finalPropName( origName ); 6799 } 6800 6801 // Gets hook for the prefixed version, then unprefixed version 6802 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6803 6804 // Check if we're setting a value 6805 if ( value !== undefined ) { 6806 type = typeof value; 6807 6808 // Convert "+=" or "-=" to relative numbers (trac-7345) 6809 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 6810 value = adjustCSS( elem, name, ret ); 6811 6812 // Fixes bug trac-9237 6813 type = "number"; 6814 } 6815 6816 // Make sure that null and NaN values aren't set (trac-7116) 6817 if ( value == null || value !== value ) { 6818 return; 6819 } 6820 6821 // If a number was passed in, add the unit (except for certain CSS properties) 6822 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 6823 // "px" to a few hardcoded values. 6824 if ( type === "number" && !isCustomProp ) { 6825 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 6826 } 6827 6828 // background-* props affect original clone's values 6829 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 6830 style[ name ] = "inherit"; 6831 } 6832 6833 // If a hook was provided, use that value, otherwise just set the specified value 6834 if ( !hooks || !( "set" in hooks ) || 6835 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 6836 6837 if ( isCustomProp ) { 6838 style.setProperty( name, value ); 6839 } else { 6840 style[ name ] = value; 6841 } 6842 } 6843 6844 } else { 6845 6846 // If a hook was provided get the non-computed value from there 6847 if ( hooks && "get" in hooks && 6848 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 6849 6850 return ret; 6851 } 6852 6853 // Otherwise just get the value from the style object 6854 return style[ name ]; 6855 } 6856 }, 6857 6858 css: function( elem, name, extra, styles ) { 6859 var val, num, hooks, 6860 origName = camelCase( name ), 6861 isCustomProp = rcustomProp.test( name ); 6862 6863 // Make sure that we're working with the right name. We don't 6864 // want to modify the value if it is a CSS custom property 6865 // since they are user-defined. 6866 if ( !isCustomProp ) { 6867 name = finalPropName( origName ); 6868 } 6869 6870 // Try prefixed name followed by the unprefixed name 6871 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 6872 6873 // If a hook was provided get the computed value from there 6874 if ( hooks && "get" in hooks ) { 6875 val = hooks.get( elem, true, extra ); 6876 } 6877 6878 // Otherwise, if a way to get the computed value exists, use that 6879 if ( val === undefined ) { 6880 val = curCSS( elem, name, styles ); 6881 } 6882 6883 // Convert "normal" to computed value 6884 if ( val === "normal" && name in cssNormalTransform ) { 6885 val = cssNormalTransform[ name ]; 6886 } 6887 6888 // Make numeric if forced or a qualifier was provided and val looks numeric 6889 if ( extra === "" || extra ) { 6890 num = parseFloat( val ); 6891 return extra === true || isFinite( num ) ? num || 0 : val; 6892 } 6893 6894 return val; 6895 } 6896} ); 6897 6898jQuery.each( [ "height", "width" ], function( _i, dimension ) { 6899 jQuery.cssHooks[ dimension ] = { 6900 get: function( elem, computed, extra ) { 6901 if ( computed ) { 6902 6903 // Certain elements can have dimension info if we invisibly show them 6904 // but it must have a current display style that would benefit 6905 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 6906 6907 // Support: Safari 8+ 6908 // Table columns in Safari have non-zero offsetWidth & zero 6909 // getBoundingClientRect().width unless display is changed. 6910 // Support: IE <=11 only 6911 // Running getBoundingClientRect on a disconnected node 6912 // in IE throws an error. 6913 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 6914 swap( elem, cssShow, function() { 6915 return getWidthOrHeight( elem, dimension, extra ); 6916 } ) : 6917 getWidthOrHeight( elem, dimension, extra ); 6918 } 6919 }, 6920 6921 set: function( elem, value, extra ) { 6922 var matches, 6923 styles = getStyles( elem ), 6924 6925 // Only read styles.position if the test has a chance to fail 6926 // to avoid forcing a reflow. 6927 scrollboxSizeBuggy = !support.scrollboxSize() && 6928 styles.position === "absolute", 6929 6930 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 6931 boxSizingNeeded = scrollboxSizeBuggy || extra, 6932 isBorderBox = boxSizingNeeded && 6933 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 6934 subtract = extra ? 6935 boxModelAdjustment( 6936 elem, 6937 dimension, 6938 extra, 6939 isBorderBox, 6940 styles 6941 ) : 6942 0; 6943 6944 // Account for unreliable border-box dimensions by comparing offset* to computed and 6945 // faking a content-box to get border and padding (gh-3699) 6946 if ( isBorderBox && scrollboxSizeBuggy ) { 6947 subtract -= Math.ceil( 6948 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 6949 parseFloat( styles[ dimension ] ) - 6950 boxModelAdjustment( elem, dimension, "border", false, styles ) - 6951 0.5 6952 ); 6953 } 6954 6955 // Convert to pixels if value adjustment is needed 6956 if ( subtract && ( matches = rcssNum.exec( value ) ) && 6957 ( matches[ 3 ] || "px" ) !== "px" ) { 6958 6959 elem.style[ dimension ] = value; 6960 value = jQuery.css( elem, dimension ); 6961 } 6962 6963 return setPositiveNumber( elem, value, subtract ); 6964 } 6965 }; 6966} ); 6967 6968jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 6969 function( elem, computed ) { 6970 if ( computed ) { 6971 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 6972 elem.getBoundingClientRect().left - 6973 swap( elem, { marginLeft: 0 }, function() { 6974 return elem.getBoundingClientRect().left; 6975 } ) 6976 ) + "px"; 6977 } 6978 } 6979); 6980 6981// These hooks are used by animate to expand properties 6982jQuery.each( { 6983 margin: "", 6984 padding: "", 6985 border: "Width" 6986}, function( prefix, suffix ) { 6987 jQuery.cssHooks[ prefix + suffix ] = { 6988 expand: function( value ) { 6989 var i = 0, 6990 expanded = {}, 6991 6992 // Assumes a single number if not a string 6993 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 6994 6995 for ( ; i < 4; i++ ) { 6996 expanded[ prefix + cssExpand[ i ] + suffix ] = 6997 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 6998 } 6999 7000 return expanded; 7001 } 7002 }; 7003 7004 if ( prefix !== "margin" ) { 7005 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7006 } 7007} ); 7008 7009jQuery.fn.extend( { 7010 css: function( name, value ) { 7011 return access( this, function( elem, name, value ) { 7012 var styles, len, 7013 map = {}, 7014 i = 0; 7015 7016 if ( Array.isArray( name ) ) { 7017 styles = getStyles( elem ); 7018 len = name.length; 7019 7020 for ( ; i < len; i++ ) { 7021 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 7022 } 7023 7024 return map; 7025 } 7026 7027 return value !== undefined ? 7028 jQuery.style( elem, name, value ) : 7029 jQuery.css( elem, name ); 7030 }, name, value, arguments.length > 1 ); 7031 } 7032} ); 7033 7034 7035function Tween( elem, options, prop, end, easing ) { 7036 return new Tween.prototype.init( elem, options, prop, end, easing ); 7037} 7038jQuery.Tween = Tween; 7039 7040Tween.prototype = { 7041 constructor: Tween, 7042 init: function( elem, options, prop, end, easing, unit ) { 7043 this.elem = elem; 7044 this.prop = prop; 7045 this.easing = easing || jQuery.easing._default; 7046 this.options = options; 7047 this.start = this.now = this.cur(); 7048 this.end = end; 7049 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 7050 }, 7051 cur: function() { 7052 var hooks = Tween.propHooks[ this.prop ]; 7053 7054 return hooks && hooks.get ? 7055 hooks.get( this ) : 7056 Tween.propHooks._default.get( this ); 7057 }, 7058 run: function( percent ) { 7059 var eased, 7060 hooks = Tween.propHooks[ this.prop ]; 7061 7062 if ( this.options.duration ) { 7063 this.pos = eased = jQuery.easing[ this.easing ]( 7064 percent, this.options.duration * percent, 0, 1, this.options.duration 7065 ); 7066 } else { 7067 this.pos = eased = percent; 7068 } 7069 this.now = ( this.end - this.start ) * eased + this.start; 7070 7071 if ( this.options.step ) { 7072 this.options.step.call( this.elem, this.now, this ); 7073 } 7074 7075 if ( hooks && hooks.set ) { 7076 hooks.set( this ); 7077 } else { 7078 Tween.propHooks._default.set( this ); 7079 } 7080 return this; 7081 } 7082}; 7083 7084Tween.prototype.init.prototype = Tween.prototype; 7085 7086Tween.propHooks = { 7087 _default: { 7088 get: function( tween ) { 7089 var result; 7090 7091 // Use a property on the element directly when it is not a DOM element, 7092 // or when there is no matching style property that exists. 7093 if ( tween.elem.nodeType !== 1 || 7094 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 7095 return tween.elem[ tween.prop ]; 7096 } 7097 7098 // Passing an empty string as a 3rd parameter to .css will automatically 7099 // attempt a parseFloat and fallback to a string if the parse fails. 7100 // Simple values such as "10px" are parsed to Float; 7101 // complex values such as "rotate(1rad)" are returned as-is. 7102 result = jQuery.css( tween.elem, tween.prop, "" ); 7103 7104 // Empty strings, null, undefined and "auto" are converted to 0. 7105 return !result || result === "auto" ? 0 : result; 7106 }, 7107 set: function( tween ) { 7108 7109 // Use step hook for back compat. 7110 // Use cssHook if its there. 7111 // Use .style if available and use plain properties where available. 7112 if ( jQuery.fx.step[ tween.prop ] ) { 7113 jQuery.fx.step[ tween.prop ]( tween ); 7114 } else if ( tween.elem.nodeType === 1 && ( 7115 jQuery.cssHooks[ tween.prop ] || 7116 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 7117 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 7118 } else { 7119 tween.elem[ tween.prop ] = tween.now; 7120 } 7121 } 7122 } 7123}; 7124 7125// Support: IE <=9 only 7126// Panic based approach to setting things on disconnected nodes 7127Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7128 set: function( tween ) { 7129 if ( tween.elem.nodeType && tween.elem.parentNode ) { 7130 tween.elem[ tween.prop ] = tween.now; 7131 } 7132 } 7133}; 7134 7135jQuery.easing = { 7136 linear: function( p ) { 7137 return p; 7138 }, 7139 swing: function( p ) { 7140 return 0.5 - Math.cos( p * Math.PI ) / 2; 7141 }, 7142 _default: "swing" 7143}; 7144 7145jQuery.fx = Tween.prototype.init; 7146 7147// Back compat <1.8 extension point 7148jQuery.fx.step = {}; 7149 7150 7151 7152 7153var 7154 fxNow, inProgress, 7155 rfxtypes = /^(?:toggle|show|hide)$/, 7156 rrun = /queueHooks$/; 7157 7158function schedule() { 7159 if ( inProgress ) { 7160 if ( document.hidden === false && window.requestAnimationFrame ) { 7161 window.requestAnimationFrame( schedule ); 7162 } else { 7163 window.setTimeout( schedule, jQuery.fx.interval ); 7164 } 7165 7166 jQuery.fx.tick(); 7167 } 7168} 7169 7170// Animations created synchronously will run synchronously 7171function createFxNow() { 7172 window.setTimeout( function() { 7173 fxNow = undefined; 7174 } ); 7175 return ( fxNow = Date.now() ); 7176} 7177 7178// Generate parameters to create a standard animation 7179function genFx( type, includeWidth ) { 7180 var which, 7181 i = 0, 7182 attrs = { height: type }; 7183 7184 // If we include width, step value is 1 to do all cssExpand values, 7185 // otherwise step value is 2 to skip over Left and Right 7186 includeWidth = includeWidth ? 1 : 0; 7187 for ( ; i < 4; i += 2 - includeWidth ) { 7188 which = cssExpand[ i ]; 7189 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 7190 } 7191 7192 if ( includeWidth ) { 7193 attrs.opacity = attrs.width = type; 7194 } 7195 7196 return attrs; 7197} 7198 7199function createTween( value, prop, animation ) { 7200 var tween, 7201 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 7202 index = 0, 7203 length = collection.length; 7204 for ( ; index < length; index++ ) { 7205 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 7206 7207 // We're done with this property 7208 return tween; 7209 } 7210 } 7211} 7212 7213function defaultPrefilter( elem, props, opts ) { 7214 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 7215 isBox = "width" in props || "height" in props, 7216 anim = this, 7217 orig = {}, 7218 style = elem.style, 7219 hidden = elem.nodeType && isHiddenWithinTree( elem ), 7220 dataShow = dataPriv.get( elem, "fxshow" ); 7221 7222 // Queue-skipping animations hijack the fx hooks 7223 if ( !opts.queue ) { 7224 hooks = jQuery._queueHooks( elem, "fx" ); 7225 if ( hooks.unqueued == null ) { 7226 hooks.unqueued = 0; 7227 oldfire = hooks.empty.fire; 7228 hooks.empty.fire = function() { 7229 if ( !hooks.unqueued ) { 7230 oldfire(); 7231 } 7232 }; 7233 } 7234 hooks.unqueued++; 7235 7236 anim.always( function() { 7237 7238 // Ensure the complete handler is called before this completes 7239 anim.always( function() { 7240 hooks.unqueued--; 7241 if ( !jQuery.queue( elem, "fx" ).length ) { 7242 hooks.empty.fire(); 7243 } 7244 } ); 7245 } ); 7246 } 7247 7248 // Detect show/hide animations 7249 for ( prop in props ) { 7250 value = props[ prop ]; 7251 if ( rfxtypes.test( value ) ) { 7252 delete props[ prop ]; 7253 toggle = toggle || value === "toggle"; 7254 if ( value === ( hidden ? "hide" : "show" ) ) { 7255 7256 // Pretend to be hidden if this is a "show" and 7257 // there is still data from a stopped show/hide 7258 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 7259 hidden = true; 7260 7261 // Ignore all other no-op show/hide data 7262 } else { 7263 continue; 7264 } 7265 } 7266 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 7267 } 7268 } 7269 7270 // Bail out if this is a no-op like .hide().hide() 7271 propTween = !jQuery.isEmptyObject( props ); 7272 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 7273 return; 7274 } 7275 7276 // Restrict "overflow" and "display" styles during box animations 7277 if ( isBox && elem.nodeType === 1 ) { 7278
vendor: 4,381 bytes, lines 7279-7438
7279 // Support: IE <=9 - 11, Edge 12 - 15 7280 // Record all 3 overflow attributes because IE does not infer the shorthand 7281 // from identically-valued overflowX and overflowY and Edge just mirrors 7282 // the overflowX value there. 7283 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 7284 7285 // Identify a display type, preferring old show/hide data over the CSS cascade 7286 restoreDisplay = dataShow && dataShow.display; 7287 if ( restoreDisplay == null ) { 7288 restoreDisplay = dataPriv.get( elem, "display" ); 7289 } 7290 display = jQuery.css( elem, "display" ); 7291 if ( display === "none" ) { 7292 if ( restoreDisplay ) { 7293 display = restoreDisplay; 7294 } else { 7295 7296 // Get nonempty value(s) by temporarily forcing visibility 7297 showHide( [ elem ], true ); 7298 restoreDisplay = elem.style.display || restoreDisplay; 7299 display = jQuery.css( elem, "display" ); 7300 showHide( [ elem ] ); 7301 } 7302 } 7303 7304 // Animate inline elements as inline-block 7305 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 7306 if ( jQuery.css( elem, "float" ) === "none" ) { 7307 7308 // Restore the original display value at the end of pure show/hide animations 7309 if ( !propTween ) { 7310 anim.done( function() { 7311 style.display = restoreDisplay; 7312 } ); 7313 if ( restoreDisplay == null ) { 7314 display = style.display; 7315 restoreDisplay = display === "none" ? "" : display; 7316 } 7317 } 7318 style.display = "inline-block"; 7319 } 7320 } 7321 } 7322 7323 if ( opts.overflow ) { 7324 style.overflow = "hidden"; 7325 anim.always( function() { 7326 style.overflow = opts.overflow[ 0 ]; 7327 style.overflowX = opts.overflow[ 1 ]; 7328 style.overflowY = opts.overflow[ 2 ]; 7329 } ); 7330 } 7331 7332 // Implement show/hide animations 7333 propTween = false; 7334 for ( prop in orig ) { 7335 7336 // General show/hide setup for this element animation 7337 if ( !propTween ) { 7338 if ( dataShow ) { 7339 if ( "hidden" in dataShow ) { 7340 hidden = dataShow.hidden; 7341 } 7342 } else { 7343 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 7344 } 7345 7346 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 7347 if ( toggle ) { 7348 dataShow.hidden = !hidden; 7349 } 7350 7351 // Show elements before animating them 7352 if ( hidden ) { 7353 showHide( [ elem ], true ); 7354 } 7355 7356 /* eslint-disable no-loop-func */ 7357 7358 anim.done( function() { 7359 7360 /* eslint-enable no-loop-func */ 7361 7362 // The final step of a "hide" animation is actually hiding the element 7363 if ( !hidden ) { 7364 showHide( [ elem ] ); 7365 } 7366 dataPriv.remove( elem, "fxshow" ); 7367 for ( prop in orig ) { 7368 jQuery.style( elem, prop, orig[ prop ] ); 7369 } 7370 } ); 7371 } 7372 7373 // Per-property setup 7374 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 7375 if ( !( prop in dataShow ) ) { 7376 dataShow[ prop ] = propTween.start; 7377 if ( hidden ) { 7378 propTween.end = propTween.start; 7379 propTween.start = 0; 7380 } 7381 } 7382 } 7383} 7384 7385function propFilter( props, specialEasing ) { 7386 var index, name, easing, value, hooks; 7387 7388 // camelCase, specialEasing and expand cssHook pass 7389 for ( index in props ) { 7390 name = camelCase( index ); 7391 easing = specialEasing[ name ]; 7392 value = props[ index ]; 7393 if ( Array.isArray( value ) ) { 7394 easing = value[ 1 ]; 7395 value = props[ index ] = value[ 0 ]; 7396 } 7397 7398 if ( index !== name ) { 7399 props[ name ] = value; 7400 delete props[ index ]; 7401 } 7402 7403 hooks = jQuery.cssHooks[ name ]; 7404 if ( hooks && "expand" in hooks ) { 7405 value = hooks.expand( value ); 7406 delete props[ name ]; 7407 7408 // Not quite $.extend, this won't overwrite existing keys. 7409 // Reusing 'index' because we have the correct "name" 7410 for ( index in value ) { 7411 if ( !( index in props ) ) { 7412 props[ index ] = value[ index ]; 7413 specialEasing[ index ] = easing; 7414 } 7415 } 7416 } else { 7417 specialEasing[ name ] = easing; 7418 } 7419 } 7420} 7421 7422function Animation( elem, properties, options ) { 7423 var result, 7424 stopped, 7425 index = 0, 7426 length = Animation.prefilters.length, 7427 deferred = jQuery.Deferred().always( function() { 7428 7429 // Don't match elem in the :animated selector 7430 delete tick.elem; 7431 } ), 7432 tick = function() { 7433 if ( stopped ) { 7434 return false; 7435 } 7436 var currentTime = fxNow || createFxNow(), 7437 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 7438
vendor: 39,713 bytes, lines 7439-8989
7439 // Support: Android 2.3 only 7440 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) 7441 temp = remaining / animation.duration || 0, 7442 percent = 1 - temp, 7443 index = 0, 7444 length = animation.tweens.length; 7445 7446 for ( ; index < length; index++ ) { 7447 animation.tweens[ index ].run( percent ); 7448 } 7449 7450 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 7451 7452 // If there's more to do, yield 7453 if ( percent < 1 && length ) { 7454 return remaining; 7455 } 7456 7457 // If this was an empty animation, synthesize a final progress notification 7458 if ( !length ) { 7459 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7460 } 7461 7462 // Resolve the animation and report its conclusion 7463 deferred.resolveWith( elem, [ animation ] ); 7464 return false; 7465 }, 7466 animation = deferred.promise( { 7467 elem: elem, 7468 props: jQuery.extend( {}, properties ), 7469 opts: jQuery.extend( true, { 7470 specialEasing: {}, 7471 easing: jQuery.easing._default 7472 }, options ), 7473 originalProperties: properties, 7474 originalOptions: options, 7475 startTime: fxNow || createFxNow(), 7476 duration: options.duration, 7477 tweens: [], 7478 createTween: function( prop, end ) { 7479 var tween = jQuery.Tween( elem, animation.opts, prop, end, 7480 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 7481 animation.tweens.push( tween ); 7482 return tween; 7483 }, 7484 stop: function( gotoEnd ) { 7485 var index = 0, 7486 7487 // If we are going to the end, we want to run all the tweens 7488 // otherwise we skip this part 7489 length = gotoEnd ? animation.tweens.length : 0; 7490 if ( stopped ) { 7491 return this; 7492 } 7493 stopped = true; 7494 for ( ; index < length; index++ ) { 7495 animation.tweens[ index ].run( 1 ); 7496 } 7497 7498 // Resolve when we played the last frame; otherwise, reject 7499 if ( gotoEnd ) { 7500 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 7501 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 7502 } else { 7503 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 7504 } 7505 return this; 7506 } 7507 } ), 7508 props = animation.props; 7509 7510 propFilter( props, animation.opts.specialEasing ); 7511 7512 for ( ; index < length; index++ ) { 7513 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 7514 if ( result ) { 7515 if ( isFunction( result.stop ) ) { 7516 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 7517 result.stop.bind( result ); 7518 } 7519 return result; 7520 } 7521 } 7522 7523 jQuery.map( props, createTween, animation ); 7524 7525 if ( isFunction( animation.opts.start ) ) { 7526 animation.opts.start.call( elem, animation ); 7527 } 7528 7529 // Attach callbacks from options 7530 animation 7531 .progress( animation.opts.progress ) 7532 .done( animation.opts.done, animation.opts.complete ) 7533 .fail( animation.opts.fail ) 7534 .always( animation.opts.always ); 7535 7536 jQuery.fx.timer( 7537 jQuery.extend( tick, { 7538 elem: elem, 7539 anim: animation, 7540 queue: animation.opts.queue 7541 } ) 7542 ); 7543 7544 return animation; 7545} 7546 7547jQuery.Animation = jQuery.extend( Animation, { 7548 7549 tweeners: { 7550 "*": [ function( prop, value ) { 7551 var tween = this.createTween( prop, value ); 7552 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 7553 return tween; 7554 } ] 7555 }, 7556 7557 tweener: function( props, callback ) { 7558 if ( isFunction( props ) ) { 7559 callback = props; 7560 props = [ "*" ]; 7561 } else { 7562 props = props.match( rnothtmlwhite ); 7563 } 7564 7565 var prop, 7566 index = 0, 7567 length = props.length; 7568 7569 for ( ; index < length; index++ ) { 7570 prop = props[ index ]; 7571 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 7572 Animation.tweeners[ prop ].unshift( callback ); 7573 } 7574 }, 7575 7576 prefilters: [ defaultPrefilter ], 7577 7578 prefilter: function( callback, prepend ) { 7579 if ( prepend ) { 7580 Animation.prefilters.unshift( callback ); 7581 } else { 7582 Animation.prefilters.push( callback ); 7583 } 7584 } 7585} ); 7586 7587jQuery.speed = function( speed, easing, fn ) { 7588 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 7589 complete: fn || !fn && easing || 7590 isFunction( speed ) && speed, 7591 duration: speed, 7592 easing: fn && easing || easing && !isFunction( easing ) && easing 7593 }; 7594 7595 // Go to the end state if fx are off 7596 if ( jQuery.fx.off ) { 7597 opt.duration = 0; 7598 7599 } else { 7600 if ( typeof opt.duration !== "number" ) { 7601 if ( opt.duration in jQuery.fx.speeds ) { 7602 opt.duration = jQuery.fx.speeds[ opt.duration ]; 7603 7604 } else { 7605 opt.duration = jQuery.fx.speeds._default; 7606 } 7607 } 7608 } 7609 7610 // Normalize opt.queue - true/undefined/null -> "fx" 7611 if ( opt.queue == null || opt.queue === true ) { 7612 opt.queue = "fx"; 7613 } 7614 7615 // Queueing 7616 opt.old = opt.complete; 7617 7618 opt.complete = function() { 7619 if ( isFunction( opt.old ) ) { 7620 opt.old.call( this ); 7621 } 7622 7623 if ( opt.queue ) { 7624 jQuery.dequeue( this, opt.queue ); 7625 } 7626 }; 7627 7628 return opt; 7629}; 7630 7631jQuery.fn.extend( { 7632 fadeTo: function( speed, to, easing, callback ) { 7633 7634 // Show any hidden elements after setting opacity to 0 7635 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 7636 7637 // Animate to the value specified 7638 .end().animate( { opacity: to }, speed, easing, callback ); 7639 }, 7640 animate: function( prop, speed, easing, callback ) { 7641 var empty = jQuery.isEmptyObject( prop ), 7642 optall = jQuery.speed( speed, easing, callback ), 7643 doAnimation = function() { 7644 7645 // Operate on a copy of prop so per-property easing won't be lost 7646 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 7647 7648 // Empty animations, or finishing resolves immediately 7649 if ( empty || dataPriv.get( this, "finish" ) ) { 7650 anim.stop( true ); 7651 } 7652 }; 7653 7654 doAnimation.finish = doAnimation; 7655 7656 return empty || optall.queue === false ? 7657 this.each( doAnimation ) : 7658 this.queue( optall.queue, doAnimation ); 7659 }, 7660 stop: function( type, clearQueue, gotoEnd ) { 7661 var stopQueue = function( hooks ) { 7662 var stop = hooks.stop; 7663 delete hooks.stop; 7664 stop( gotoEnd ); 7665 }; 7666 7667 if ( typeof type !== "string" ) { 7668 gotoEnd = clearQueue; 7669 clearQueue = type; 7670 type = undefined; 7671 } 7672 if ( clearQueue ) { 7673 this.queue( type || "fx", [] ); 7674 } 7675 7676 return this.each( function() { 7677 var dequeue = true, 7678 index = type != null && type + "queueHooks", 7679 timers = jQuery.timers, 7680 data = dataPriv.get( this ); 7681 7682 if ( index ) { 7683 if ( data[ index ] && data[ index ].stop ) { 7684 stopQueue( data[ index ] ); 7685 } 7686 } else { 7687 for ( index in data ) { 7688 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 7689 stopQueue( data[ index ] ); 7690 } 7691 } 7692 } 7693 7694 for ( index = timers.length; index--; ) { 7695 if ( timers[ index ].elem === this && 7696 ( type == null || timers[ index ].queue === type ) ) { 7697 7698 timers[ index ].anim.stop( gotoEnd ); 7699 dequeue = false; 7700 timers.splice( index, 1 ); 7701 } 7702 } 7703 7704 // Start the next in the queue if the last step wasn't forced. 7705 // Timers currently will call their complete callbacks, which 7706 // will dequeue but only if they were gotoEnd. 7707 if ( dequeue || !gotoEnd ) { 7708 jQuery.dequeue( this, type ); 7709 } 7710 } ); 7711 }, 7712 finish: function( type ) { 7713 if ( type !== false ) { 7714 type = type || "fx"; 7715 } 7716 return this.each( function() { 7717 var index, 7718 data = dataPriv.get( this ), 7719 queue = data[ type + "queue" ], 7720 hooks = data[ type + "queueHooks" ], 7721 timers = jQuery.timers, 7722 length = queue ? queue.length : 0; 7723 7724 // Enable finishing flag on private data 7725 data.finish = true; 7726 7727 // Empty the queue first 7728 jQuery.queue( this, type, [] ); 7729 7730 if ( hooks && hooks.stop ) { 7731 hooks.stop.call( this, true ); 7732 } 7733 7734 // Look for any active animations, and finish them 7735 for ( index = timers.length; index--; ) { 7736 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 7737 timers[ index ].anim.stop( true ); 7738 timers.splice( index, 1 ); 7739 } 7740 } 7741 7742 // Look for any animations in the old queue and finish them 7743 for ( index = 0; index < length; index++ ) { 7744 if ( queue[ index ] && queue[ index ].finish ) { 7745 queue[ index ].finish.call( this ); 7746 } 7747 } 7748 7749 // Turn off finishing flag 7750 delete data.finish; 7751 } ); 7752 } 7753} ); 7754 7755jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 7756 var cssFn = jQuery.fn[ name ]; 7757 jQuery.fn[ name ] = function( speed, easing, callback ) { 7758 return speed == null || typeof speed === "boolean" ? 7759 cssFn.apply( this, arguments ) : 7760 this.animate( genFx( name, true ), speed, easing, callback ); 7761 }; 7762} ); 7763 7764// Generate shortcuts for custom animations 7765jQuery.each( { 7766 slideDown: genFx( "show" ), 7767 slideUp: genFx( "hide" ), 7768 slideToggle: genFx( "toggle" ), 7769 fadeIn: { opacity: "show" }, 7770 fadeOut: { opacity: "hide" }, 7771 fadeToggle: { opacity: "toggle" } 7772}, function( name, props ) { 7773 jQuery.fn[ name ] = function( speed, easing, callback ) { 7774 return this.animate( props, speed, easing, callback ); 7775 }; 7776} ); 7777 7778jQuery.timers = []; 7779jQuery.fx.tick = function() { 7780 var timer, 7781 i = 0, 7782 timers = jQuery.timers; 7783 7784 fxNow = Date.now(); 7785 7786 for ( ; i < timers.length; i++ ) { 7787 timer = timers[ i ]; 7788 7789 // Run the timer and safely remove it when done (allowing for external removal) 7790 if ( !timer() && timers[ i ] === timer ) { 7791 timers.splice( i--, 1 ); 7792 } 7793 } 7794 7795 if ( !timers.length ) { 7796 jQuery.fx.stop(); 7797 } 7798 fxNow = undefined; 7799}; 7800 7801jQuery.fx.timer = function( timer ) { 7802 jQuery.timers.push( timer ); 7803 jQuery.fx.start(); 7804}; 7805 7806jQuery.fx.interval = 13; 7807jQuery.fx.start = function() { 7808 if ( inProgress ) { 7809 return; 7810 } 7811 7812 inProgress = true; 7813 schedule(); 7814}; 7815 7816jQuery.fx.stop = function() { 7817 inProgress = null; 7818}; 7819 7820jQuery.fx.speeds = { 7821 slow: 600, 7822 fast: 200, 7823 7824 // Default speed 7825 _default: 400 7826}; 7827 7828 7829// Based off of the plugin by Clint Helfers, with permission. 7830jQuery.fn.delay = function( time, type ) { 7831 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 7832 type = type || "fx"; 7833 7834 return this.queue( type, function( next, hooks ) { 7835 var timeout = window.setTimeout( next, time ); 7836 hooks.stop = function() { 7837 window.clearTimeout( timeout ); 7838 }; 7839 } ); 7840}; 7841 7842 7843( function() { 7844 var input = document.createElement( "input" ), 7845 select = document.createElement( "select" ), 7846 opt = select.appendChild( document.createElement( "option" ) ); 7847 7848 input.type = "checkbox"; 7849 7850 // Support: Android <=4.3 only 7851 // Default value for a checkbox should be "on" 7852 support.checkOn = input.value !== ""; 7853 7854 // Support: IE <=11 only 7855 // Must access selectedIndex to make default options select 7856 support.optSelected = opt.selected; 7857 7858 // Support: IE <=11 only 7859 // An input loses its value after becoming a radio 7860 input = document.createElement( "input" ); 7861 input.value = "t"; 7862 input.type = "radio"; 7863 support.radioValue = input.value === "t"; 7864} )(); 7865 7866 7867var boolHook, 7868 attrHandle = jQuery.expr.attrHandle; 7869 7870jQuery.fn.extend( { 7871 attr: function( name, value ) { 7872 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 7873 }, 7874 7875 removeAttr: function( name ) { 7876 return this.each( function() { 7877 jQuery.removeAttr( this, name ); 7878 } ); 7879 } 7880} ); 7881 7882jQuery.extend( { 7883 attr: function( elem, name, value ) { 7884 var ret, hooks, 7885 nType = elem.nodeType; 7886 7887 // Don't get/set attributes on text, comment and attribute nodes 7888 if ( nType === 3 || nType === 8 || nType === 2 ) { 7889 return; 7890 } 7891 7892 // Fallback to prop when attributes are not supported 7893 if ( typeof elem.getAttribute === "undefined" ) { 7894 return jQuery.prop( elem, name, value ); 7895 } 7896 7897 // Attribute hooks are determined by the lowercase version 7898 // Grab necessary hook if one is defined 7899 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 7900 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 7901 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 7902 } 7903 7904 if ( value !== undefined ) { 7905 if ( value === null ) { 7906 jQuery.removeAttr( elem, name ); 7907 return; 7908 } 7909 7910 if ( hooks && "set" in hooks && 7911 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 7912 return ret; 7913 } 7914 7915 elem.setAttribute( name, value + "" ); 7916 return value; 7917 } 7918 7919 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 7920 return ret; 7921 } 7922 7923 ret = jQuery.find.attr( elem, name ); 7924 7925 // Non-existent attributes return null, we normalize to undefined 7926 return ret == null ? undefined : ret; 7927 }, 7928 7929 attrHooks: { 7930 type: { 7931 set: function( elem, value ) { 7932 if ( !support.radioValue && value === "radio" && 7933 nodeName( elem, "input" ) ) { 7934 var val = elem.value; 7935 elem.setAttribute( "type", value ); 7936 if ( val ) { 7937 elem.value = val; 7938 } 7939 return value; 7940 } 7941 } 7942 } 7943 }, 7944 7945 removeAttr: function( elem, value ) { 7946 var name, 7947 i = 0, 7948 7949 // Attribute names can contain non-HTML whitespace characters 7950 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 7951 attrNames = value && value.match( rnothtmlwhite ); 7952 7953 if ( attrNames && elem.nodeType === 1 ) { 7954 while ( ( name = attrNames[ i++ ] ) ) { 7955 elem.removeAttribute( name ); 7956 } 7957 } 7958 } 7959} ); 7960 7961// Hooks for boolean attributes 7962boolHook = { 7963 set: function( elem, value, name ) { 7964 if ( value === false ) { 7965 7966 // Remove boolean attributes when set to false 7967 jQuery.removeAttr( elem, name ); 7968 } else { 7969 elem.setAttribute( name, name ); 7970 } 7971 return name; 7972 } 7973}; 7974 7975jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 7976 var getter = attrHandle[ name ] || jQuery.find.attr; 7977 7978 attrHandle[ name ] = function( elem, name, isXML ) { 7979 var ret, handle, 7980 lowercaseName = name.toLowerCase(); 7981 7982 if ( !isXML ) { 7983 7984 // Avoid an infinite loop by temporarily removing this function from the getter 7985 handle = attrHandle[ lowercaseName ]; 7986 attrHandle[ lowercaseName ] = ret; 7987 ret = getter( elem, name, isXML ) != null ? 7988 lowercaseName : 7989 null; 7990 attrHandle[ lowercaseName ] = handle; 7991 } 7992 return ret; 7993 }; 7994} ); 7995 7996 7997 7998 7999var rfocusable = /^(?:input|select|textarea|button)$/i, 8000 rclickable = /^(?:a|area)$/i; 8001 8002jQuery.fn.extend( { 8003 prop: function( name, value ) { 8004 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 8005 }, 8006 8007 removeProp: function( name ) { 8008 return this.each( function() { 8009 delete this[ jQuery.propFix[ name ] || name ]; 8010 } ); 8011 } 8012} ); 8013 8014jQuery.extend( { 8015 prop: function( elem, name, value ) { 8016 var ret, hooks, 8017 nType = elem.nodeType; 8018 8019 // Don't get/set properties on text, comment and attribute nodes 8020 if ( nType === 3 || nType === 8 || nType === 2 ) { 8021 return; 8022 } 8023 8024 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8025 8026 // Fix name and attach hooks 8027 name = jQuery.propFix[ name ] || name; 8028 hooks = jQuery.propHooks[ name ]; 8029 } 8030 8031 if ( value !== undefined ) { 8032 if ( hooks && "set" in hooks && 8033 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8034 return ret; 8035 } 8036 8037 return ( elem[ name ] = value ); 8038 } 8039 8040 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8041 return ret; 8042 } 8043 8044 return elem[ name ]; 8045 }, 8046 8047 propHooks: { 8048 tabIndex: { 8049 get: function( elem ) { 8050 8051 // Support: IE <=9 - 11 only 8052 // elem.tabIndex doesn't always return the 8053 // correct value when it hasn't been explicitly set 8054 // Use proper attribute retrieval (trac-12072) 8055 var tabindex = jQuery.find.attr( elem, "tabindex" ); 8056 8057 if ( tabindex ) { 8058 return parseInt( tabindex, 10 ); 8059 } 8060 8061 if ( 8062 rfocusable.test( elem.nodeName ) || 8063 rclickable.test( elem.nodeName ) && 8064 elem.href 8065 ) { 8066 return 0; 8067 } 8068 8069 return -1; 8070 } 8071 } 8072 }, 8073 8074 propFix: { 8075 "for": "htmlFor", 8076 "class": "className" 8077 } 8078} ); 8079 8080// Support: IE <=11 only 8081// Accessing the selectedIndex property 8082// forces the browser to respect setting selected 8083// on the option 8084// The getter ensures a default option is selected 8085// when in an optgroup 8086// eslint rule "no-unused-expressions" is disabled for this code 8087// since it considers such accessions noop 8088if ( !support.optSelected ) { 8089 jQuery.propHooks.selected = { 8090 get: function( elem ) { 8091 8092 /* eslint no-unused-expressions: "off" */ 8093 8094 var parent = elem.parentNode; 8095 if ( parent && parent.parentNode ) { 8096 parent.parentNode.selectedIndex; 8097 } 8098 return null; 8099 }, 8100 set: function( elem ) { 8101 8102 /* eslint no-unused-expressions: "off" */ 8103 8104 var parent = elem.parentNode; 8105 if ( parent ) { 8106 parent.selectedIndex; 8107 8108 if ( parent.parentNode ) { 8109 parent.parentNode.selectedIndex; 8110 } 8111 } 8112 } 8113 }; 8114} 8115 8116jQuery.each( [ 8117 "tabIndex", 8118 "readOnly", 8119 "maxLength", 8120 "cellSpacing", 8121 "cellPadding", 8122 "rowSpan", 8123 "colSpan", 8124 "useMap", 8125 "frameBorder", 8126 "contentEditable" 8127], function() { 8128 jQuery.propFix[ this.toLowerCase() ] = this; 8129} ); 8130 8131 8132 8133 8134 // Strip and collapse whitespace according to HTML spec 8135 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 8136 function stripAndCollapse( value ) { 8137 var tokens = value.match( rnothtmlwhite ) || []; 8138 return tokens.join( " " ); 8139 } 8140 8141 8142function getClass( elem ) { 8143 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 8144} 8145 8146function classesToArray( value ) { 8147 if ( Array.isArray( value ) ) { 8148 return value; 8149 } 8150 if ( typeof value === "string" ) { 8151 return value.match( rnothtmlwhite ) || []; 8152 } 8153 return []; 8154} 8155 8156jQuery.fn.extend( { 8157 addClass: function( value ) { 8158 var classNames, cur, curValue, className, i, finalValue; 8159 8160 if ( isFunction( value ) ) { 8161 return this.each( function( j ) { 8162 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 8163 } ); 8164 } 8165 8166 classNames = classesToArray( value ); 8167 8168 if ( classNames.length ) { 8169 return this.each( function() { 8170 curValue = getClass( this ); 8171 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8172 8173 if ( cur ) { 8174 for ( i = 0; i < classNames.length; i++ ) { 8175 className = classNames[ i ]; 8176 if ( cur.indexOf( " " + className + " " ) < 0 ) { 8177 cur += className + " "; 8178 } 8179 } 8180 8181 // Only assign if different to avoid unneeded rendering. 8182 finalValue = stripAndCollapse( cur ); 8183 if ( curValue !== finalValue ) { 8184 this.setAttribute( "class", finalValue ); 8185 } 8186 } 8187 } ); 8188 } 8189 8190 return this; 8191 }, 8192 8193 removeClass: function( value ) { 8194 var classNames, cur, curValue, className, i, finalValue; 8195 8196 if ( isFunction( value ) ) { 8197 return this.each( function( j ) { 8198 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 8199 } ); 8200 } 8201 8202 if ( !arguments.length ) { 8203 return this.attr( "class", "" ); 8204 } 8205 8206 classNames = classesToArray( value ); 8207 8208 if ( classNames.length ) { 8209 return this.each( function() { 8210 curValue = getClass( this ); 8211 8212 // This expression is here for better compressibility (see addClass) 8213 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 8214 8215 if ( cur ) { 8216 for ( i = 0; i < classNames.length; i++ ) { 8217 className = classNames[ i ]; 8218 8219 // Remove *all* instances 8220 while ( cur.indexOf( " " + className + " " ) > -1 ) { 8221 cur = cur.replace( " " + className + " ", " " ); 8222 } 8223 } 8224 8225 // Only assign if different to avoid unneeded rendering. 8226 finalValue = stripAndCollapse( cur ); 8227 if ( curValue !== finalValue ) { 8228 this.setAttribute( "class", finalValue ); 8229 } 8230 } 8231 } ); 8232 } 8233 8234 return this; 8235 }, 8236 8237 toggleClass: function( value, stateVal ) { 8238 var classNames, className, i, self, 8239 type = typeof value, 8240 isValidValue = type === "string" || Array.isArray( value ); 8241 8242 if ( isFunction( value ) ) { 8243 return this.each( function( i ) { 8244 jQuery( this ).toggleClass( 8245 value.call( this, i, getClass( this ), stateVal ), 8246 stateVal 8247 ); 8248 } ); 8249 } 8250 8251 if ( typeof stateVal === "boolean" && isValidValue ) { 8252 return stateVal ? this.addClass( value ) : this.removeClass( value ); 8253 } 8254 8255 classNames = classesToArray( value ); 8256 8257 return this.each( function() { 8258 if ( isValidValue ) { 8259 8260 // Toggle individual class names 8261 self = jQuery( this ); 8262 8263 for ( i = 0; i < classNames.length; i++ ) { 8264 className = classNames[ i ]; 8265 8266 // Check each className given, space separated list 8267 if ( self.hasClass( className ) ) { 8268 self.removeClass( className ); 8269 } else { 8270 self.addClass( className ); 8271 } 8272 } 8273 8274 // Toggle whole class name 8275 } else if ( value === undefined || type === "boolean" ) { 8276 className = getClass( this ); 8277 if ( className ) { 8278 8279 // Store className if set 8280 dataPriv.set( this, "__className__", className ); 8281 } 8282 8283 // If the element has a class name or if we're passed `false`, 8284 // then remove the whole classname (if there was one, the above saved it). 8285 // Otherwise bring back whatever was previously saved (if anything), 8286 // falling back to the empty string if nothing was stored. 8287 if ( this.setAttribute ) { 8288 this.setAttribute( "class", 8289 className || value === false ? 8290 "" : 8291 dataPriv.get( this, "__className__" ) || "" 8292 ); 8293 } 8294 } 8295 } ); 8296 }, 8297 8298 hasClass: function( selector ) { 8299 var className, elem, 8300 i = 0; 8301 8302 className = " " + selector + " "; 8303 while ( ( elem = this[ i++ ] ) ) { 8304 if ( elem.nodeType === 1 && 8305 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 8306 return true; 8307 } 8308 } 8309 8310 return false; 8311 } 8312} ); 8313 8314 8315 8316 8317var rreturn = /\r/g; 8318 8319jQuery.fn.extend( { 8320 val: function( value ) { 8321 var hooks, ret, valueIsFunction, 8322 elem = this[ 0 ]; 8323 8324 if ( !arguments.length ) { 8325 if ( elem ) { 8326 hooks = jQuery.valHooks[ elem.type ] || 8327 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 8328 8329 if ( hooks && 8330 "get" in hooks && 8331 ( ret = hooks.get( elem, "value" ) ) !== undefined 8332 ) { 8333 return ret; 8334 } 8335 8336 ret = elem.value; 8337 8338 // Handle most common string cases 8339 if ( typeof ret === "string" ) { 8340 return ret.replace( rreturn, "" ); 8341 } 8342 8343 // Handle cases where value is null/undef or number 8344 return ret == null ? "" : ret; 8345 } 8346 8347 return; 8348 } 8349 8350 valueIsFunction = isFunction( value ); 8351 8352 return this.each( function( i ) { 8353 var val; 8354 8355 if ( this.nodeType !== 1 ) { 8356 return; 8357 } 8358 8359 if ( valueIsFunction ) { 8360 val = value.call( this, i, jQuery( this ).val() ); 8361 } else { 8362 val = value; 8363 } 8364 8365 // Treat null/undefined as ""; convert numbers to string 8366 if ( val == null ) { 8367 val = ""; 8368 8369 } else if ( typeof val === "number" ) { 8370 val += ""; 8371 8372 } else if ( Array.isArray( val ) ) { 8373 val = jQuery.map( val, function( value ) { 8374 return value == null ? "" : value + ""; 8375 } ); 8376 } 8377 8378 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 8379 8380 // If set returns undefined, fall back to normal setting 8381 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 8382 this.value = val; 8383 } 8384 } ); 8385 } 8386} ); 8387 8388jQuery.extend( { 8389 valHooks: { 8390 option: { 8391 get: function( elem ) { 8392 8393 var val = jQuery.find.attr( elem, "value" ); 8394 return val != null ? 8395 val : 8396 8397 // Support: IE <=10 - 11 only 8398 // option.text throws exceptions (trac-14686, trac-14858) 8399 // Strip and collapse whitespace 8400 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8401 stripAndCollapse( jQuery.text( elem ) ); 8402 } 8403 }, 8404 select: { 8405 get: function( elem ) { 8406 var value, option, i, 8407 options = elem.options, 8408 index = elem.selectedIndex, 8409 one = elem.type === "select-one", 8410 values = one ? null : [], 8411 max = one ? index + 1 : options.length; 8412 8413 if ( index < 0 ) { 8414 i = max; 8415 8416 } else { 8417 i = one ? index : 0; 8418 } 8419 8420 // Loop through all the selected options 8421 for ( ; i < max; i++ ) { 8422 option = options[ i ]; 8423 8424 // Support: IE <=9 only 8425 // IE8-9 doesn't update selected after form reset (trac-2551) 8426 if ( ( option.selected || i === index ) && 8427 8428 // Don't return options that are disabled or in a disabled optgroup 8429 !option.disabled && 8430 ( !option.parentNode.disabled || 8431 !nodeName( option.parentNode, "optgroup" ) ) ) { 8432 8433 // Get the specific value for the option 8434 value = jQuery( option ).val(); 8435 8436 // We don't need an array for one selects 8437 if ( one ) { 8438 return value; 8439 } 8440 8441 // Multi-Selects return an array 8442 values.push( value ); 8443 } 8444 } 8445 8446 return values; 8447 }, 8448 8449 set: function( elem, value ) { 8450 var optionSet, option, 8451 options = elem.options, 8452 values = jQuery.makeArray( value ), 8453 i = options.length; 8454 8455 while ( i-- ) { 8456 option = options[ i ]; 8457 8458 /* eslint-disable no-cond-assign */ 8459 8460 if ( option.selected = 8461 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 8462 ) { 8463 optionSet = true; 8464 } 8465 8466 /* eslint-enable no-cond-assign */ 8467 } 8468 8469 // Force browsers to behave consistently when non-matching value is set 8470 if ( !optionSet ) { 8471 elem.selectedIndex = -1; 8472 } 8473 return values; 8474 } 8475 } 8476 } 8477} ); 8478 8479// Radios and checkboxes getter/setter 8480jQuery.each( [ "radio", "checkbox" ], function() { 8481 jQuery.valHooks[ this ] = { 8482 set: function( elem, value ) { 8483 if ( Array.isArray( value ) ) { 8484 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 8485 } 8486 } 8487 }; 8488 if ( !support.checkOn ) { 8489 jQuery.valHooks[ this ].get = function( elem ) { 8490 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 8491 }; 8492 } 8493} ); 8494 8495 8496 8497 8498// Return jQuery for attributes-only inclusion 8499var location = window.location; 8500 8501var nonce = { guid: Date.now() }; 8502 8503var rquery = ( /\?/ ); 8504 8505 8506 8507// Cross-browser xml parsing 8508jQuery.parseXML = function( data ) { 8509 var xml, parserErrorElem; 8510 if ( !data || typeof data !== "string" ) { 8511 return null; 8512 } 8513 8514 // Support: IE 9 - 11 only 8515 // IE throws on parseFromString with invalid input. 8516 try { 8517 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 8518 } catch ( e ) {} 8519 8520 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 8521 if ( !xml || parserErrorElem ) { 8522 jQuery.error( "Invalid XML: " + ( 8523 parserErrorElem ? 8524 jQuery.map( parserErrorElem.childNodes, function( el ) { 8525 return el.textContent; 8526 } ).join( "\n" ) : 8527 data 8528 ) ); 8529 } 8530 return xml; 8531}; 8532 8533 8534var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 8535 stopPropagationCallback = function( e ) { 8536 e.stopPropagation(); 8537 }; 8538 8539jQuery.extend( jQuery.event, { 8540 8541 trigger: function( event, data, elem, onlyHandlers ) { 8542 8543 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 8544 eventPath = [ elem || document ], 8545 type = hasOwn.call( event, "type" ) ? event.type : event, 8546 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 8547 8548 cur = lastElement = tmp = elem = elem || document; 8549 8550 // Don't do events on text and comment nodes 8551 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 8552 return; 8553 } 8554 8555 // focus/blur morphs to focusin/out; ensure we're not firing them right now 8556 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 8557 return; 8558 } 8559 8560 if ( type.indexOf( "." ) > -1 ) { 8561 8562 // Namespaced trigger; create a regexp to match event type in handle() 8563 namespaces = type.split( "." ); 8564 type = namespaces.shift(); 8565 namespaces.sort(); 8566 } 8567 ontype = type.indexOf( ":" ) < 0 && "on" + type; 8568 8569 // Caller can pass in a jQuery.Event object, Object, or just an event type string 8570 event = event[ jQuery.expando ] ? 8571 event : 8572 new jQuery.Event( type, typeof event === "object" && event ); 8573 8574 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 8575 event.isTrigger = onlyHandlers ? 2 : 3; 8576 event.namespace = namespaces.join( "." ); 8577 event.rnamespace = event.namespace ? 8578 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 8579 null; 8580 8581 // Clean up the event in case it is being reused 8582 event.result = undefined; 8583 if ( !event.target ) { 8584 event.target = elem; 8585 } 8586 8587 // Clone any incoming data and prepend the event, creating the handler arg list 8588 data = data == null ? 8589 [ event ] : 8590 jQuery.makeArray( data, [ event ] ); 8591 8592 // Allow special events to draw outside the lines 8593 special = jQuery.event.special[ type ] || {}; 8594 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 8595 return; 8596 } 8597 8598 // Determine event propagation path in advance, per W3C events spec (trac-9951) 8599 // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) 8600 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 8601 8602 bubbleType = special.delegateType || type; 8603 if ( !rfocusMorph.test( bubbleType + type ) ) { 8604 cur = cur.parentNode; 8605 } 8606 for ( ; cur; cur = cur.parentNode ) { 8607 eventPath.push( cur ); 8608 tmp = cur; 8609 } 8610 8611 // Only add window if we got to document (e.g., not plain obj or detached DOM) 8612 if ( tmp === ( elem.ownerDocument || document ) ) { 8613 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 8614 } 8615 } 8616 8617 // Fire handlers on the event path 8618 i = 0; 8619 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 8620 lastElement = cur; 8621 event.type = i > 1 ? 8622 bubbleType : 8623 special.bindType || type; 8624 8625 // jQuery handler 8626 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 8627 dataPriv.get( cur, "handle" ); 8628 if ( handle ) { 8629 handle.apply( cur, data ); 8630 } 8631 8632 // Native handler 8633 handle = ontype && cur[ ontype ]; 8634 if ( handle && handle.apply && acceptData( cur ) ) { 8635 event.result = handle.apply( cur, data ); 8636 if ( event.result === false ) { 8637 event.preventDefault(); 8638 } 8639 } 8640 } 8641 event.type = type; 8642 8643 // If nobody prevented the default action, do it now 8644 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 8645 8646 if ( ( !special._default || 8647 special._default.apply( eventPath.pop(), data ) === false ) && 8648 acceptData( elem ) ) { 8649 8650 // Call a native DOM method on the target with the same name as the event. 8651 // Don't do default actions on window, that's where global variables be (trac-6170) 8652 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 8653 8654 // Don't re-trigger an onFOO event when we call its FOO() method 8655 tmp = elem[ ontype ]; 8656 8657 if ( tmp ) { 8658 elem[ ontype ] = null; 8659 } 8660 8661 // Prevent re-triggering of the same event, since we already bubbled it above 8662 jQuery.event.triggered = type; 8663 8664 if ( event.isPropagationStopped() ) { 8665 lastElement.addEventListener( type, stopPropagationCallback ); 8666 } 8667 8668 elem[ type ](); 8669 8670 if ( event.isPropagationStopped() ) { 8671 lastElement.removeEventListener( type, stopPropagationCallback ); 8672 } 8673 8674 jQuery.event.triggered = undefined; 8675 8676 if ( tmp ) { 8677 elem[ ontype ] = tmp; 8678 } 8679 } 8680 } 8681 } 8682 8683 return event.result; 8684 }, 8685 8686 // Piggyback on a donor event to simulate a different one 8687 // Used only for `focus(in | out)` events 8688 simulate: function( type, elem, event ) { 8689 var e = jQuery.extend( 8690 new jQuery.Event(), 8691 event, 8692 { 8693 type: type, 8694 isSimulated: true 8695 } 8696 ); 8697 8698 jQuery.event.trigger( e, null, elem ); 8699 } 8700 8701} ); 8702 8703jQuery.fn.extend( { 8704 8705 trigger: function( type, data ) { 8706 return this.each( function() { 8707 jQuery.event.trigger( type, data, this ); 8708 } ); 8709 }, 8710 triggerHandler: function( type, data ) { 8711 var elem = this[ 0 ]; 8712 if ( elem ) { 8713 return jQuery.event.trigger( type, data, elem, true ); 8714 } 8715 } 8716} ); 8717 8718 8719var 8720 rbracket = /\[\]$/, 8721 rCRLF = /\r?\n/g, 8722 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 8723 rsubmittable = /^(?:input|select|textarea|keygen)/i; 8724 8725function buildParams( prefix, obj, traditional, add ) { 8726 var name; 8727 8728 if ( Array.isArray( obj ) ) { 8729 8730 // Serialize array item. 8731 jQuery.each( obj, function( i, v ) { 8732 if ( traditional || rbracket.test( prefix ) ) { 8733 8734 // Treat each array item as a scalar. 8735 add( prefix, v ); 8736 8737 } else { 8738 8739 // Item is non-scalar (array or object), encode its numeric index. 8740 buildParams( 8741 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 8742 v, 8743 traditional, 8744 add 8745 ); 8746 } 8747 } ); 8748 8749 } else if ( !traditional && toType( obj ) === "object" ) { 8750 8751 // Serialize object item. 8752 for ( name in obj ) { 8753 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 8754 } 8755 8756 } else { 8757 8758 // Serialize scalar item. 8759 add( prefix, obj ); 8760 } 8761} 8762 8763// Serialize an array of form elements or a set of 8764// key/values into a query string 8765jQuery.param = function( a, traditional ) { 8766 var prefix, 8767 s = [], 8768 add = function( key, valueOrFunction ) { 8769 8770 // If value is a function, invoke it and use its return value 8771 var value = isFunction( valueOrFunction ) ? 8772 valueOrFunction() : 8773 valueOrFunction; 8774 8775 s[ s.length ] = encodeURIComponent( key ) + "=" + 8776 encodeURIComponent( value == null ? "" : value ); 8777 }; 8778 8779 if ( a == null ) { 8780 return ""; 8781 } 8782 8783 // If an array was passed in, assume that it is an array of form elements. 8784 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 8785 8786 // Serialize the form elements 8787 jQuery.each( a, function() { 8788 add( this.name, this.value ); 8789 } ); 8790 8791 } else { 8792 8793 // If traditional, encode the "old" way (the way 1.3.2 or older 8794 // did it), otherwise encode params recursively. 8795 for ( prefix in a ) { 8796 buildParams( prefix, a[ prefix ], traditional, add ); 8797 } 8798 } 8799 8800 // Return the resulting serialization 8801 return s.join( "&" ); 8802}; 8803 8804jQuery.fn.extend( { 8805 serialize: function() { 8806 return jQuery.param( this.serializeArray() ); 8807 }, 8808 serializeArray: function() { 8809 return this.map( function() { 8810 8811 // Can add propHook for "elements" to filter or add form elements 8812 var elements = jQuery.prop( this, "elements" ); 8813 return elements ? jQuery.makeArray( elements ) : this; 8814 } ).filter( function() { 8815 var type = this.type; 8816 8817 // Use .is( ":disabled" ) so that fieldset[disabled] works 8818 return this.name && !jQuery( this ).is( ":disabled" ) && 8819 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 8820 ( this.checked || !rcheckableType.test( type ) ); 8821 } ).map( function( _i, elem ) { 8822 var val = jQuery( this ).val(); 8823 8824 if ( val == null ) { 8825 return null; 8826 } 8827 8828 if ( Array.isArray( val ) ) { 8829 return jQuery.map( val, function( val ) { 8830 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8831 } ); 8832 } 8833 8834 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 8835 } ).get(); 8836 } 8837} ); 8838 8839 8840var 8841 r20 = /%20/g, 8842 rhash = /#.*$/, 8843 rantiCache = /([?&])_=[^&]*/, 8844 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 8845 8846 // trac-7653, trac-8125, trac-8152: local protocol detection 8847 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8848 rnoContent = /^(?:GET|HEAD)$/, 8849 rprotocol = /^\/\//, 8850 8851 /* Prefilters 8852 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8853 * 2) These are called: 8854 * - BEFORE asking for a transport 8855 * - AFTER param serialization (s.data is a string if s.processData is true) 8856 * 3) key is the dataType 8857 * 4) the catchall symbol "*" can be used 8858 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8859 */ 8860 prefilters = {}, 8861 8862 /* Transports bindings 8863 * 1) key is the dataType 8864 * 2) the catchall symbol "*" can be used 8865 * 3) selection will start with transport dataType and THEN go to "*" if needed 8866 */ 8867 transports = {}, 8868 8869 // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression 8870 allTypes = "*/".concat( "*" ), 8871 8872 // Anchor tag for parsing the document origin 8873 originAnchor = document.createElement( "a" ); 8874 8875originAnchor.href = location.href; 8876 8877// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8878function addToPrefiltersOrTransports( structure ) { 8879 8880 // dataTypeExpression is optional and defaults to "*" 8881 return function( dataTypeExpression, func ) { 8882 8883 if ( typeof dataTypeExpression !== "string" ) { 8884 func = dataTypeExpression; 8885 dataTypeExpression = "*"; 8886 } 8887 8888 var dataType, 8889 i = 0, 8890 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 8891 8892 if ( isFunction( func ) ) { 8893 8894 // For each dataType in the dataTypeExpression 8895 while ( ( dataType = dataTypes[ i++ ] ) ) { 8896 8897 // Prepend if requested 8898 if ( dataType[ 0 ] === "+" ) { 8899 dataType = dataType.slice( 1 ) || "*"; 8900 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 8901 8902 // Otherwise append 8903 } else { 8904 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 8905 } 8906 } 8907 } 8908 }; 8909} 8910 8911// Base inspection function for prefilters and transports 8912function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 8913 8914 var inspected = {}, 8915 seekingTransport = ( structure === transports ); 8916 8917 function inspect( dataType ) { 8918 var selected; 8919 inspected[ dataType ] = true; 8920 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 8921 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 8922 if ( typeof dataTypeOrTransport === "string" && 8923 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 8924 8925 options.dataTypes.unshift( dataTypeOrTransport ); 8926 inspect( dataTypeOrTransport ); 8927 return false; 8928 } else if ( seekingTransport ) { 8929 return !( selected = dataTypeOrTransport ); 8930 } 8931 } ); 8932 return selected; 8933 } 8934 8935 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 8936} 8937 8938// A special extend for ajax options 8939// that takes "flat" options (not to be deep extended) 8940// Fixes trac-9887 8941function ajaxExtend( target, src ) { 8942 var key, deep, 8943 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8944 8945 for ( key in src ) { 8946 if ( src[ key ] !== undefined ) { 8947 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 8948 } 8949 } 8950 if ( deep ) { 8951 jQuery.extend( true, target, deep ); 8952 } 8953 8954 return target; 8955} 8956 8957/* Handles responses to an ajax request: 8958 * - finds the right dataType (mediates between content-type and expected dataType) 8959 * - returns the corresponding response 8960 */ 8961function ajaxHandleResponses( s, jqXHR, responses ) { 8962 8963 var ct, type, finalDataType, firstDataType, 8964 contents = s.contents, 8965 dataTypes = s.dataTypes; 8966 8967 // Remove auto dataType and get content-type in the process 8968 while ( dataTypes[ 0 ] === "*" ) { 8969 dataTypes.shift(); 8970 if ( ct === undefined ) { 8971 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 8972 } 8973 } 8974 8975 // Check if we're dealing with a known content-type 8976 if ( ct ) { 8977 for ( type in contents ) { 8978 if ( contents[ type ] && contents[ type ].test( ct ) ) { 8979 dataTypes.unshift( type ); 8980 break; 8981 } 8982 } 8983 } 8984 8985 // Check to see if we have a response for the expected dataType 8986 if ( dataTypes[ 0 ] in responses ) { 8987 finalDataType = dataTypes[ 0 ]; 8988 } else { 8989
vendor: 9,527 bytes, lines 8990-9365
8990 // Try convertible dataTypes 8991 for ( type in responses ) { 8992 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 8993 finalDataType = type; 8994 break; 8995 } 8996 if ( !firstDataType ) { 8997 firstDataType = type; 8998 } 8999 } 9000 9001 // Or just use first one 9002 finalDataType = finalDataType || firstDataType; 9003 } 9004 9005 // If we found a dataType 9006 // We add the dataType to the list if needed 9007 // and return the corresponding response 9008 if ( finalDataType ) { 9009 if ( finalDataType !== dataTypes[ 0 ] ) { 9010 dataTypes.unshift( finalDataType ); 9011 } 9012 return responses[ finalDataType ]; 9013 } 9014} 9015 9016/* Chain conversions given the request and the original response 9017 * Also sets the responseXXX fields on the jqXHR instance 9018 */ 9019function ajaxConvert( s, response, jqXHR, isSuccess ) { 9020 var conv2, current, conv, tmp, prev, 9021 converters = {}, 9022 9023 // Work with a copy of dataTypes in case we need to modify it for conversion 9024 dataTypes = s.dataTypes.slice(); 9025 9026 // Create converters map with lowercased keys 9027 if ( dataTypes[ 1 ] ) { 9028 for ( conv in s.converters ) { 9029 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 9030 } 9031 } 9032 9033 current = dataTypes.shift(); 9034 9035 // Convert to each sequential dataType 9036 while ( current ) { 9037 9038 if ( s.responseFields[ current ] ) { 9039 jqXHR[ s.responseFields[ current ] ] = response; 9040 } 9041 9042 // Apply the dataFilter if provided 9043 if ( !prev && isSuccess && s.dataFilter ) { 9044 response = s.dataFilter( response, s.dataType ); 9045 } 9046 9047 prev = current; 9048 current = dataTypes.shift(); 9049 9050 if ( current ) { 9051 9052 // There's only work to do if current dataType is non-auto 9053 if ( current === "*" ) { 9054 9055 current = prev; 9056 9057 // Convert response if prev dataType is non-auto and differs from current 9058 } else if ( prev !== "*" && prev !== current ) { 9059 9060 // Seek a direct converter 9061 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 9062 9063 // If none found, seek a pair 9064 if ( !conv ) { 9065 for ( conv2 in converters ) { 9066 9067 // If conv2 outputs current 9068 tmp = conv2.split( " " ); 9069 if ( tmp[ 1 ] === current ) { 9070 9071 // If prev can be converted to accepted input 9072 conv = converters[ prev + " " + tmp[ 0 ] ] || 9073 converters[ "* " + tmp[ 0 ] ]; 9074 if ( conv ) { 9075 9076 // Condense equivalence converters 9077 if ( conv === true ) { 9078 conv = converters[ conv2 ]; 9079 9080 // Otherwise, insert the intermediate dataType 9081 } else if ( converters[ conv2 ] !== true ) { 9082 current = tmp[ 0 ]; 9083 dataTypes.unshift( tmp[ 1 ] ); 9084 } 9085 break; 9086 } 9087 } 9088 } 9089 } 9090 9091 // Apply converter (if not an equivalence) 9092 if ( conv !== true ) { 9093 9094 // Unless errors are allowed to bubble, catch and return them 9095 if ( conv && s.throws ) { 9096 response = conv( response ); 9097 } else { 9098 try { 9099 response = conv( response ); 9100 } catch ( e ) { 9101 return { 9102 state: "parsererror", 9103 error: conv ? e : "No conversion from " + prev + " to " + current 9104 }; 9105 } 9106 } 9107 } 9108 } 9109 } 9110 } 9111 9112 return { state: "success", data: response }; 9113} 9114 9115jQuery.extend( { 9116 9117 // Counter for holding the number of active queries 9118 active: 0, 9119 9120 // Last-Modified header cache for next request 9121 lastModified: {}, 9122 etag: {}, 9123 9124 ajaxSettings: { 9125 url: location.href, 9126 type: "GET", 9127 isLocal: rlocalProtocol.test( location.protocol ), 9128 global: true, 9129 processData: true, 9130 async: true, 9131 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9132 9133 /* 9134 timeout: 0, 9135 data: null, 9136 dataType: null, 9137 username: null, 9138 password: null, 9139 cache: null, 9140 throws: false, 9141 traditional: false, 9142 headers: {}, 9143 */ 9144 9145 accepts: { 9146 "*": allTypes, 9147 text: "text/plain", 9148 html: "text/html", 9149 xml: "application/xml, text/xml", 9150 json: "application/json, text/javascript" 9151 }, 9152 9153 contents: { 9154 xml: /\bxml\b/, 9155 html: /\bhtml/, 9156 json: /\bjson\b/ 9157 }, 9158 9159 responseFields: { 9160 xml: "responseXML", 9161 text: "responseText", 9162 json: "responseJSON" 9163 }, 9164 9165 // Data converters 9166 // Keys separate source (or catchall "*") and destination types with a single space 9167 converters: { 9168 9169 // Convert anything to text 9170 "* text": String, 9171 9172 // Text to html (true = no transformation) 9173 "text html": true, 9174 9175 // Evaluate text as a json expression 9176 "text json": JSON.parse, 9177 9178 // Parse text as xml 9179 "text xml": jQuery.parseXML 9180 }, 9181 9182 // For options that shouldn't be deep extended: 9183 // you can add your own custom options here if 9184 // and when you create one that shouldn't be 9185 // deep extended (see ajaxExtend) 9186 flatOptions: { 9187 url: true, 9188 context: true 9189 } 9190 }, 9191 9192 // Creates a full fledged settings object into target 9193 // with both ajaxSettings and settings fields. 9194 // If target is omitted, writes into ajaxSettings. 9195 ajaxSetup: function( target, settings ) { 9196 return settings ? 9197 9198 // Building a settings object 9199 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 9200 9201 // Extending ajaxSettings 9202 ajaxExtend( jQuery.ajaxSettings, target ); 9203 }, 9204 9205 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 9206 ajaxTransport: addToPrefiltersOrTransports( transports ), 9207 9208 // Main method 9209 ajax: function( url, options ) { 9210 9211 // If url is an object, simulate pre-1.5 signature 9212 if ( typeof url === "object" ) { 9213 options = url; 9214 url = undefined; 9215 } 9216 9217 // Force options to be an object 9218 options = options || {}; 9219 9220 var transport, 9221 9222 // URL without anti-cache param 9223 cacheURL, 9224 9225 // Response headers 9226 responseHeadersString, 9227 responseHeaders, 9228 9229 // timeout handle 9230 timeoutTimer, 9231 9232 // Url cleanup var 9233 urlAnchor, 9234 9235 // Request state (becomes false upon send and true upon completion) 9236 completed, 9237 9238 // To know if global events are to be dispatched 9239 fireGlobals, 9240 9241 // Loop variable 9242 i, 9243 9244 // uncached part of the url 9245 uncached, 9246 9247 // Create the final options object 9248 s = jQuery.ajaxSetup( {}, options ), 9249 9250 // Callbacks context 9251 callbackContext = s.context || s, 9252 9253 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9254 globalEventContext = s.context && 9255 ( callbackContext.nodeType || callbackContext.jquery ) ? 9256 jQuery( callbackContext ) : 9257 jQuery.event, 9258 9259 // Deferreds 9260 deferred = jQuery.Deferred(), 9261 completeDeferred = jQuery.Callbacks( "once memory" ), 9262 9263 // Status-dependent callbacks 9264 statusCode = s.statusCode || {}, 9265 9266 // Headers (they are sent all at once) 9267 requestHeaders = {}, 9268 requestHeadersNames = {}, 9269 9270 // Default abort message 9271 strAbort = "canceled", 9272 9273 // Fake xhr 9274 jqXHR = { 9275 readyState: 0, 9276 9277 // Builds headers hashtable if needed 9278 getResponseHeader: function( key ) { 9279 var match; 9280 if ( completed ) { 9281 if ( !responseHeaders ) { 9282 responseHeaders = {}; 9283 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 9284 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 9285 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 9286 .concat( match[ 2 ] ); 9287 } 9288 } 9289 match = responseHeaders[ key.toLowerCase() + " " ]; 9290 } 9291 return match == null ? null : match.join( ", " ); 9292 }, 9293 9294 // Raw string 9295 getAllResponseHeaders: function() { 9296 return completed ? responseHeadersString : null; 9297 }, 9298 9299 // Caches the header 9300 setRequestHeader: function( name, value ) { 9301 if ( completed == null ) { 9302 name = requestHeadersNames[ name.toLowerCase() ] = 9303 requestHeadersNames[ name.toLowerCase() ] || name; 9304 requestHeaders[ name ] = value; 9305 } 9306 return this; 9307 }, 9308 9309 // Overrides response content-type header 9310 overrideMimeType: function( type ) { 9311 if ( completed == null ) { 9312 s.mimeType = type; 9313 } 9314 return this; 9315 }, 9316 9317 // Status-dependent callbacks 9318 statusCode: function( map ) { 9319 var code; 9320 if ( map ) { 9321 if ( completed ) { 9322 9323 // Execute the appropriate callbacks 9324 jqXHR.always( map[ jqXHR.status ] ); 9325 } else { 9326 9327 // Lazy-add the new callbacks in a way that preserves old ones 9328 for ( code in map ) { 9329 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 9330 } 9331 } 9332 } 9333 return this; 9334 }, 9335 9336 // Cancel the request 9337 abort: function( statusText ) { 9338 var finalText = statusText || strAbort; 9339 if ( transport ) { 9340 transport.abort( finalText ); 9341 } 9342 done( 0, finalText ); 9343 return this; 9344 } 9345 }; 9346 9347 // Attach deferreds 9348 deferred.promise( jqXHR ); 9349 9350 // Add protocol if not provided (prefilters might expect it) 9351 // Handle falsy url in the settings object (trac-10093: consistency with old signature) 9352 // We also use the url parameter if available 9353 s.url = ( ( url || s.url || location.href ) + "" ) 9354 .replace( rprotocol, location.protocol + "//" ); 9355 9356 // Alias method option to type as per ticket trac-12004 9357 s.type = options.method || options.type || s.method || s.type; 9358 9359 // Extract dataTypes list 9360 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 9361 9362 // A cross-domain request is in order when the origin doesn't match the current origin. 9363 if ( s.crossDomain == null ) { 9364 urlAnchor = document.createElement( "a" ); 9365
vendor: 32,506 bytes, lines 9366-10529
9366 // Support: IE <=8 - 11, Edge 12 - 15 9367 // IE throws exception on accessing the href property if url is malformed, 9368 // e.g. http://example.com:80x/ 9369 try { 9370 urlAnchor.href = s.url; 9371 9372 // Support: IE <=8 - 11 only 9373 // Anchor's host property isn't correctly set when s.url is relative 9374 urlAnchor.href = urlAnchor.href; 9375 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 9376 urlAnchor.protocol + "//" + urlAnchor.host; 9377 } catch ( e ) { 9378 9379 // If there is an error parsing the URL, assume it is crossDomain, 9380 // it can be rejected by the transport if it is invalid 9381 s.crossDomain = true; 9382 } 9383 } 9384 9385 // Convert data if not already a string 9386 if ( s.data && s.processData && typeof s.data !== "string" ) { 9387 s.data = jQuery.param( s.data, s.traditional ); 9388 } 9389 9390 // Apply prefilters 9391 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 9392 9393 // If request was aborted inside a prefilter, stop there 9394 if ( completed ) { 9395 return jqXHR; 9396 } 9397 9398 // We can fire global events as of now if asked to 9399 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) 9400 fireGlobals = jQuery.event && s.global; 9401 9402 // Watch for a new set of requests 9403 if ( fireGlobals && jQuery.active++ === 0 ) { 9404 jQuery.event.trigger( "ajaxStart" ); 9405 } 9406 9407 // Uppercase the type 9408 s.type = s.type.toUpperCase(); 9409 9410 // Determine if request has content 9411 s.hasContent = !rnoContent.test( s.type ); 9412 9413 // Save the URL in case we're toying with the If-Modified-Since 9414 // and/or If-None-Match header later on 9415 // Remove hash to simplify url manipulation 9416 cacheURL = s.url.replace( rhash, "" ); 9417 9418 // More options handling for requests with no content 9419 if ( !s.hasContent ) { 9420 9421 // Remember the hash so we can put it back 9422 uncached = s.url.slice( cacheURL.length ); 9423 9424 // If data is available and should be processed, append data to url 9425 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 9426 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 9427 9428 // trac-9682: remove data so that it's not used in an eventual retry 9429 delete s.data; 9430 } 9431 9432 // Add or update anti-cache param if needed 9433 if ( s.cache === false ) { 9434 cacheURL = cacheURL.replace( rantiCache, "$1" ); 9435 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 9436 uncached; 9437 } 9438 9439 // Put hash and anti-cache on the URL that will be requested (gh-1732) 9440 s.url = cacheURL + uncached; 9441 9442 // Change '%20' to '+' if this is encoded form body content (gh-2658) 9443 } else if ( s.data && s.processData && 9444 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 9445 s.data = s.data.replace( r20, "+" ); 9446 } 9447 9448 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9449 if ( s.ifModified ) { 9450 if ( jQuery.lastModified[ cacheURL ] ) { 9451 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 9452 } 9453 if ( jQuery.etag[ cacheURL ] ) { 9454 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 9455 } 9456 } 9457 9458 // Set the correct header, if data is being sent 9459 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 9460 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 9461 } 9462 9463 // Set the Accepts header for the server, depending on the dataType 9464 jqXHR.setRequestHeader( 9465 "Accept", 9466 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 9467 s.accepts[ s.dataTypes[ 0 ] ] + 9468 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 9469 s.accepts[ "*" ] 9470 ); 9471 9472 // Check for headers option 9473 for ( i in s.headers ) { 9474 jqXHR.setRequestHeader( i, s.headers[ i ] ); 9475 } 9476 9477 // Allow custom headers/mimetypes and early abort 9478 if ( s.beforeSend && 9479 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 9480 9481 // Abort if not done already and return 9482 return jqXHR.abort(); 9483 } 9484 9485 // Aborting is no longer a cancellation 9486 strAbort = "abort"; 9487 9488 // Install callbacks on deferreds 9489 completeDeferred.add( s.complete ); 9490 jqXHR.done( s.success ); 9491 jqXHR.fail( s.error ); 9492 9493 // Get transport 9494 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 9495 9496 // If no transport, we auto-abort 9497 if ( !transport ) { 9498 done( -1, "No Transport" ); 9499 } else { 9500 jqXHR.readyState = 1; 9501 9502 // Send global event 9503 if ( fireGlobals ) { 9504 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 9505 } 9506 9507 // If request was aborted inside ajaxSend, stop there 9508 if ( completed ) { 9509 return jqXHR; 9510 } 9511 9512 // Timeout 9513 if ( s.async && s.timeout > 0 ) { 9514 timeoutTimer = window.setTimeout( function() { 9515 jqXHR.abort( "timeout" ); 9516 }, s.timeout ); 9517 } 9518 9519 try { 9520 completed = false; 9521 transport.send( requestHeaders, done ); 9522 } catch ( e ) { 9523 9524 // Rethrow post-completion exceptions 9525 if ( completed ) { 9526 throw e; 9527 } 9528 9529 // Propagate others as results 9530 done( -1, e ); 9531 } 9532 } 9533 9534 // Callback for when everything is done 9535 function done( status, nativeStatusText, responses, headers ) { 9536 var isSuccess, success, error, response, modified, 9537 statusText = nativeStatusText; 9538 9539 // Ignore repeat invocations 9540 if ( completed ) { 9541 return; 9542 } 9543 9544 completed = true; 9545 9546 // Clear timeout if it exists 9547 if ( timeoutTimer ) { 9548 window.clearTimeout( timeoutTimer ); 9549 } 9550 9551 // Dereference transport for early garbage collection 9552 // (no matter how long the jqXHR object will be used) 9553 transport = undefined; 9554 9555 // Cache response headers 9556 responseHeadersString = headers || ""; 9557 9558 // Set readyState 9559 jqXHR.readyState = status > 0 ? 4 : 0; 9560 9561 // Determine if successful 9562 isSuccess = status >= 200 && status < 300 || status === 304; 9563 9564 // Get response data 9565 if ( responses ) { 9566 response = ajaxHandleResponses( s, jqXHR, responses ); 9567 } 9568 9569 // Use a noop converter for missing script but not if jsonp 9570 if ( !isSuccess && 9571 jQuery.inArray( "script", s.dataTypes ) > -1 && 9572 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 9573 s.converters[ "text script" ] = function() {}; 9574 } 9575 9576 // Convert no matter what (that way responseXXX fields are always set) 9577 response = ajaxConvert( s, response, jqXHR, isSuccess ); 9578 9579 // If successful, handle type chaining 9580 if ( isSuccess ) { 9581 9582 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9583 if ( s.ifModified ) { 9584 modified = jqXHR.getResponseHeader( "Last-Modified" ); 9585 if ( modified ) { 9586 jQuery.lastModified[ cacheURL ] = modified; 9587 } 9588 modified = jqXHR.getResponseHeader( "etag" ); 9589 if ( modified ) { 9590 jQuery.etag[ cacheURL ] = modified; 9591 } 9592 } 9593 9594 // if no content 9595 if ( status === 204 || s.type === "HEAD" ) { 9596 statusText = "nocontent"; 9597 9598 // if not modified 9599 } else if ( status === 304 ) { 9600 statusText = "notmodified"; 9601 9602 // If we have data, let's convert it 9603 } else { 9604 statusText = response.state; 9605 success = response.data; 9606 error = response.error; 9607 isSuccess = !error; 9608 } 9609 } else { 9610 9611 // Extract error from statusText and normalize for non-aborts 9612 error = statusText; 9613 if ( status || !statusText ) { 9614 statusText = "error"; 9615 if ( status < 0 ) { 9616 status = 0; 9617 } 9618 } 9619 } 9620 9621 // Set data for the fake xhr object 9622 jqXHR.status = status; 9623 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 9624 9625 // Success/Error 9626 if ( isSuccess ) { 9627 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 9628 } else { 9629 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 9630 } 9631 9632 // Status-dependent callbacks 9633 jqXHR.statusCode( statusCode ); 9634 statusCode = undefined; 9635 9636 if ( fireGlobals ) { 9637 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 9638 [ jqXHR, s, isSuccess ? success : error ] ); 9639 } 9640 9641 // Complete 9642 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 9643 9644 if ( fireGlobals ) { 9645 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 9646 9647 // Handle the global AJAX counter 9648 if ( !( --jQuery.active ) ) { 9649 jQuery.event.trigger( "ajaxStop" ); 9650 } 9651 } 9652 } 9653 9654 return jqXHR; 9655 }, 9656 9657 getJSON: function( url, data, callback ) { 9658 return jQuery.get( url, data, callback, "json" ); 9659 }, 9660 9661 getScript: function( url, callback ) { 9662 return jQuery.get( url, undefined, callback, "script" ); 9663 } 9664} ); 9665 9666jQuery.each( [ "get", "post" ], function( _i, method ) { 9667 jQuery[ method ] = function( url, data, callback, type ) { 9668 9669 // Shift arguments if data argument was omitted 9670 if ( isFunction( data ) ) { 9671 type = type || callback; 9672 callback = data; 9673 data = undefined; 9674 } 9675 9676 // The url can be an options object (which then must have .url) 9677 return jQuery.ajax( jQuery.extend( { 9678 url: url, 9679 type: method, 9680 dataType: type, 9681 data: data, 9682 success: callback 9683 }, jQuery.isPlainObject( url ) && url ) ); 9684 }; 9685} ); 9686 9687jQuery.ajaxPrefilter( function( s ) { 9688 var i; 9689 for ( i in s.headers ) { 9690 if ( i.toLowerCase() === "content-type" ) { 9691 s.contentType = s.headers[ i ] || ""; 9692 } 9693 } 9694} ); 9695 9696 9697jQuery._evalUrl = function( url, options, doc ) { 9698 return jQuery.ajax( { 9699 url: url, 9700 9701 // Make this explicit, since user can override this through ajaxSetup (trac-11264) 9702 type: "GET", 9703 dataType: "script", 9704 cache: true, 9705 async: false, 9706 global: false, 9707 9708 // Only evaluate the response if it is successful (gh-4126) 9709 // dataFilter is not invoked for failure responses, so using it instead 9710 // of the default converter is kludgy but it works. 9711 converters: { 9712 "text script": function() {} 9713 }, 9714 dataFilter: function( response ) { 9715 jQuery.globalEval( response, options, doc ); 9716 } 9717 } ); 9718}; 9719 9720 9721jQuery.fn.extend( { 9722 wrapAll: function( html ) { 9723 var wrap; 9724 9725 if ( this[ 0 ] ) { 9726 if ( isFunction( html ) ) { 9727 html = html.call( this[ 0 ] ); 9728 } 9729 9730 // The elements to wrap the target around 9731 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 9732 9733 if ( this[ 0 ].parentNode ) { 9734 wrap.insertBefore( this[ 0 ] ); 9735 } 9736 9737 wrap.map( function() { 9738 var elem = this; 9739 9740 while ( elem.firstElementChild ) { 9741 elem = elem.firstElementChild; 9742 } 9743 9744 return elem; 9745 } ).append( this ); 9746 } 9747 9748 return this; 9749 }, 9750 9751 wrapInner: function( html ) { 9752 if ( isFunction( html ) ) { 9753 return this.each( function( i ) { 9754 jQuery( this ).wrapInner( html.call( this, i ) ); 9755 } ); 9756 } 9757 9758 return this.each( function() { 9759 var self = jQuery( this ), 9760 contents = self.contents(); 9761 9762 if ( contents.length ) { 9763 contents.wrapAll( html ); 9764 9765 } else { 9766 self.append( html ); 9767 } 9768 } ); 9769 }, 9770 9771 wrap: function( html ) { 9772 var htmlIsFunction = isFunction( html ); 9773 9774 return this.each( function( i ) { 9775 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 9776 } ); 9777 }, 9778 9779 unwrap: function( selector ) { 9780 this.parent( selector ).not( "body" ).each( function() { 9781 jQuery( this ).replaceWith( this.childNodes ); 9782 } ); 9783 return this; 9784 } 9785} ); 9786 9787 9788jQuery.expr.pseudos.hidden = function( elem ) { 9789 return !jQuery.expr.pseudos.visible( elem ); 9790}; 9791jQuery.expr.pseudos.visible = function( elem ) { 9792 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 9793}; 9794 9795 9796 9797 9798jQuery.ajaxSettings.xhr = function() { 9799 try { 9800 return new window.XMLHttpRequest(); 9801 } catch ( e ) {} 9802}; 9803 9804var xhrSuccessStatus = { 9805 9806 // File protocol always yields status code 0, assume 200 9807 0: 200, 9808 9809 // Support: IE <=9 only 9810 // trac-1450: sometimes IE returns 1223 when it should be 204 9811 1223: 204 9812 }, 9813 xhrSupported = jQuery.ajaxSettings.xhr(); 9814 9815support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 9816support.ajax = xhrSupported = !!xhrSupported; 9817 9818jQuery.ajaxTransport( function( options ) { 9819 var callback, errorCallback; 9820 9821 // Cross domain only allowed if supported through XMLHttpRequest 9822 if ( support.cors || xhrSupported && !options.crossDomain ) { 9823 return { 9824 send: function( headers, complete ) { 9825 var i, 9826 xhr = options.xhr(); 9827 9828 xhr.open( 9829 options.type, 9830 options.url, 9831 options.async, 9832 options.username, 9833 options.password 9834 ); 9835 9836 // Apply custom fields if provided 9837 if ( options.xhrFields ) { 9838 for ( i in options.xhrFields ) { 9839 xhr[ i ] = options.xhrFields[ i ]; 9840 } 9841 } 9842 9843 // Override mime type if needed 9844 if ( options.mimeType && xhr.overrideMimeType ) { 9845 xhr.overrideMimeType( options.mimeType ); 9846 } 9847 9848 // X-Requested-With header 9849 // For cross-domain requests, seeing as conditions for a preflight are 9850 // akin to a jigsaw puzzle, we simply never set it to be sure. 9851 // (it can always be set on a per-request basis or even using ajaxSetup) 9852 // For same-domain requests, won't change header if already provided. 9853 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 9854 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 9855 } 9856 9857 // Set headers 9858 for ( i in headers ) { 9859 xhr.setRequestHeader( i, headers[ i ] ); 9860 } 9861 9862 // Callback 9863 callback = function( type ) { 9864 return function() { 9865 if ( callback ) { 9866 callback = errorCallback = xhr.onload = 9867 xhr.onerror = xhr.onabort = xhr.ontimeout = 9868 xhr.onreadystatechange = null; 9869 9870 if ( type === "abort" ) { 9871 xhr.abort(); 9872 } else if ( type === "error" ) { 9873 9874 // Support: IE <=9 only 9875 // On a manual native abort, IE9 throws 9876 // errors on any property access that is not readyState 9877 if ( typeof xhr.status !== "number" ) { 9878 complete( 0, "error" ); 9879 } else { 9880 complete( 9881 9882 // File: protocol always yields status 0; see trac-8605, trac-14207 9883 xhr.status, 9884 xhr.statusText 9885 ); 9886 } 9887 } else { 9888 complete( 9889 xhrSuccessStatus[ xhr.status ] || xhr.status, 9890 xhr.statusText, 9891 9892 // Support: IE <=9 only 9893 // IE9 has no XHR2 but throws on binary (trac-11426) 9894 // For XHR2 non-text, let the caller handle it (gh-2498) 9895 ( xhr.responseType || "text" ) !== "text" || 9896 typeof xhr.responseText !== "string" ? 9897 { binary: xhr.response } : 9898 { text: xhr.responseText }, 9899 xhr.getAllResponseHeaders() 9900 ); 9901 } 9902 } 9903 }; 9904 }; 9905 9906 // Listen to events 9907 xhr.onload = callback(); 9908 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 9909 9910 // Support: IE 9 only 9911 // Use onreadystatechange to replace onabort 9912 // to handle uncaught aborts 9913 if ( xhr.onabort !== undefined ) { 9914 xhr.onabort = errorCallback; 9915 } else { 9916 xhr.onreadystatechange = function() { 9917 9918 // Check readyState before timeout as it changes 9919 if ( xhr.readyState === 4 ) { 9920 9921 // Allow onerror to be called first, 9922 // but that will not handle a native abort 9923 // Also, save errorCallback to a variable 9924 // as xhr.onerror cannot be accessed 9925 window.setTimeout( function() { 9926 if ( callback ) { 9927 errorCallback(); 9928 } 9929 } ); 9930 } 9931 }; 9932 } 9933 9934 // Create the abort callback 9935 callback = callback( "abort" ); 9936 9937 try { 9938 9939 // Do send the request (this may raise an exception) 9940 xhr.send( options.hasContent && options.data || null ); 9941 } catch ( e ) { 9942 9943 // trac-14683: Only rethrow if this hasn't been notified as an error yet 9944 if ( callback ) { 9945 throw e; 9946 } 9947 } 9948 }, 9949 9950 abort: function() { 9951 if ( callback ) { 9952 callback(); 9953 } 9954 } 9955 }; 9956 } 9957} ); 9958 9959 9960 9961 9962// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 9963jQuery.ajaxPrefilter( function( s ) { 9964 if ( s.crossDomain ) { 9965 s.contents.script = false; 9966 } 9967} ); 9968 9969// Install script dataType 9970jQuery.ajaxSetup( { 9971 accepts: { 9972 script: "text/javascript, application/javascript, " + 9973 "application/ecmascript, application/x-ecmascript" 9974 }, 9975 contents: { 9976 script: /\b(?:java|ecma)script\b/ 9977 }, 9978 converters: { 9979 "text script": function( text ) { 9980 jQuery.globalEval( text ); 9981 return text; 9982 } 9983 } 9984} ); 9985 9986// Handle cache's special case and crossDomain 9987jQuery.ajaxPrefilter( "script", function( s ) { 9988 if ( s.cache === undefined ) { 9989 s.cache = false; 9990 } 9991 if ( s.crossDomain ) { 9992 s.type = "GET"; 9993 } 9994} ); 9995 9996// Bind script tag hack transport 9997jQuery.ajaxTransport( "script", function( s ) { 9998 9999 // This transport only deals with cross domain or forced-by-attrs requests 10000 if ( s.crossDomain || s.scriptAttrs ) { 10001 var script, callback; 10002 return { 10003 send: function( _, complete ) { 10004 script = jQuery( "<script>" ) 10005 .attr( s.scriptAttrs || {} ) 10006 .prop( { charset: s.scriptCharset, src: s.url } ) 10007 .on( "load error", callback = function( evt ) { 10008 script.remove(); 10009 callback = null; 10010 if ( evt ) { 10011 complete( evt.type === "error" ? 404 : 200, evt.type ); 10012 } 10013 } ); 10014 10015 // Use native DOM manipulation to avoid our domManip AJAX trickery 10016 document.head.appendChild( script[ 0 ] ); 10017 }, 10018 abort: function() { 10019 if ( callback ) { 10020 callback(); 10021 } 10022 } 10023 }; 10024 } 10025} ); 10026 10027 10028 10029 10030var oldCallbacks = [], 10031 rjsonp = /(=)\?(?=&|$)|\?\?/; 10032 10033// Default jsonp settings 10034jQuery.ajaxSetup( { 10035 jsonp: "callback", 10036 jsonpCallback: function() { 10037 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 10038 this[ callback ] = true; 10039 return callback; 10040 } 10041} ); 10042 10043// Detect, normalize options and install callbacks for jsonp requests 10044jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 10045 10046 var callbackName, overwritten, responseContainer, 10047 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 10048 "url" : 10049 typeof s.data === "string" && 10050 ( s.contentType || "" ) 10051 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 10052 rjsonp.test( s.data ) && "data" 10053 ); 10054 10055 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10056 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 10057 10058 // Get callback name, remembering preexisting value associated with it 10059 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 10060 s.jsonpCallback() : 10061 s.jsonpCallback; 10062 10063 // Insert callback into url or form data 10064 if ( jsonProp ) { 10065 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 10066 } else if ( s.jsonp !== false ) { 10067 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 10068 } 10069 10070 // Use data converter to retrieve json after script execution 10071 s.converters[ "script json" ] = function() { 10072 if ( !responseContainer ) { 10073 jQuery.error( callbackName + " was not called" ); 10074 } 10075 return responseContainer[ 0 ]; 10076 }; 10077 10078 // Force json dataType 10079 s.dataTypes[ 0 ] = "json"; 10080 10081 // Install callback 10082 overwritten = window[ callbackName ]; 10083 window[ callbackName ] = function() { 10084 responseContainer = arguments; 10085 }; 10086 10087 // Clean-up function (fires after converters) 10088 jqXHR.always( function() { 10089 10090 // If previous value didn't exist - remove it 10091 if ( overwritten === undefined ) { 10092 jQuery( window ).removeProp( callbackName ); 10093 10094 // Otherwise restore preexisting value 10095 } else { 10096 window[ callbackName ] = overwritten; 10097 } 10098 10099 // Save back as free 10100 if ( s[ callbackName ] ) { 10101 10102 // Make sure that re-using the options doesn't screw things around 10103 s.jsonpCallback = originalSettings.jsonpCallback; 10104 10105 // Save the callback name for future use 10106 oldCallbacks.push( callbackName ); 10107 } 10108 10109 // Call if it was a function and we have a response 10110 if ( responseContainer && isFunction( overwritten ) ) { 10111 overwritten( responseContainer[ 0 ] ); 10112 } 10113 10114 responseContainer = overwritten = undefined; 10115 } ); 10116 10117 // Delegate to script 10118 return "script"; 10119 } 10120} ); 10121 10122 10123 10124 10125// Support: Safari 8 only 10126// In Safari 8 documents created via document.implementation.createHTMLDocument 10127// collapse sibling forms: the second one becomes a child of the first one. 10128// Because of that, this security measure has to be disabled in Safari 8. 10129// https://bugs.webkit.org/show_bug.cgi?id=137337 10130support.createHTMLDocument = ( function() { 10131 var body = document.implementation.createHTMLDocument( "" ).body; 10132 body.innerHTML = "<form></form><form></form>"; 10133 return body.childNodes.length === 2; 10134} )(); 10135 10136 10137// Argument "data" should be string of html 10138// context (optional): If specified, the fragment will be created in this context, 10139// defaults to document 10140// keepScripts (optional): If true, will include scripts passed in the html string 10141jQuery.parseHTML = function( data, context, keepScripts ) { 10142 if ( typeof data !== "string" ) { 10143 return []; 10144 } 10145 if ( typeof context === "boolean" ) { 10146 keepScripts = context; 10147 context = false; 10148 } 10149 10150 var base, parsed, scripts; 10151 10152 if ( !context ) { 10153 10154 // Stop scripts or inline event handlers from being executed immediately 10155 // by using document.implementation 10156 if ( support.createHTMLDocument ) { 10157 context = document.implementation.createHTMLDocument( "" ); 10158 10159 // Set the base href for the created document 10160 // so any parsed elements with URLs 10161 // are based on the document's URL (gh-2965) 10162 base = context.createElement( "base" ); 10163 base.href = document.location.href; 10164 context.head.appendChild( base ); 10165 } else { 10166 context = document; 10167 } 10168 } 10169 10170 parsed = rsingleTag.exec( data ); 10171 scripts = !keepScripts && []; 10172 10173 // Single tag 10174 if ( parsed ) { 10175 return [ context.createElement( parsed[ 1 ] ) ]; 10176 } 10177 10178 parsed = buildFragment( [ data ], context, scripts ); 10179 10180 if ( scripts && scripts.length ) { 10181 jQuery( scripts ).remove(); 10182 } 10183 10184 return jQuery.merge( [], parsed.childNodes ); 10185}; 10186 10187 10188/** 10189 * Load a url into a page 10190 */ 10191jQuery.fn.load = function( url, params, callback ) { 10192 var selector, type, response, 10193 self = this, 10194 off = url.indexOf( " " ); 10195 10196 if ( off > -1 ) { 10197 selector = stripAndCollapse( url.slice( off ) ); 10198 url = url.slice( 0, off ); 10199 } 10200 10201 // If it's a function 10202 if ( isFunction( params ) ) { 10203 10204 // We assume that it's the callback 10205 callback = params; 10206 params = undefined; 10207 10208 // Otherwise, build a param string 10209 } else if ( params && typeof params === "object" ) { 10210 type = "POST"; 10211 } 10212 10213 // If we have elements to modify, make the request 10214 if ( self.length > 0 ) { 10215 jQuery.ajax( { 10216 url: url, 10217 10218 // If "type" variable is undefined, then "GET" method will be used. 10219 // Make value of this field explicit since 10220 // user can override it through ajaxSetup method 10221 type: type || "GET", 10222 dataType: "html", 10223 data: params 10224 } ).done( function( responseText ) { 10225 10226 // Save response for use in complete callback 10227 response = arguments; 10228 10229 self.html( selector ? 10230 10231 // If a selector was specified, locate the right elements in a dummy div 10232 // Exclude scripts to avoid IE 'Permission Denied' errors 10233 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 10234 10235 // Otherwise use the full result 10236 responseText ); 10237 10238 // If the request succeeds, this function gets "data", "status", "jqXHR" 10239 // but they are ignored because response was set above. 10240 // If it fails, this function gets "jqXHR", "status", "error" 10241 } ).always( callback && function( jqXHR, status ) { 10242 self.each( function() { 10243 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 10244 } ); 10245 } ); 10246 } 10247 10248 return this; 10249}; 10250 10251 10252 10253 10254jQuery.expr.pseudos.animated = function( elem ) { 10255 return jQuery.grep( jQuery.timers, function( fn ) { 10256 return elem === fn.elem; 10257 } ).length; 10258}; 10259 10260 10261 10262 10263jQuery.offset = { 10264 setOffset: function( elem, options, i ) { 10265 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 10266 position = jQuery.css( elem, "position" ), 10267 curElem = jQuery( elem ), 10268 props = {}; 10269 10270 // Set position first, in-case top/left are set even on static elem 10271 if ( position === "static" ) { 10272 elem.style.position = "relative"; 10273 } 10274 10275 curOffset = curElem.offset(); 10276 curCSSTop = jQuery.css( elem, "top" ); 10277 curCSSLeft = jQuery.css( elem, "left" ); 10278 calculatePosition = ( position === "absolute" || position === "fixed" ) && 10279 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 10280 10281 // Need to be able to calculate position if either 10282 // top or left is auto and position is either absolute or fixed 10283 if ( calculatePosition ) { 10284 curPosition = curElem.position(); 10285 curTop = curPosition.top; 10286 curLeft = curPosition.left; 10287 10288 } else { 10289 curTop = parseFloat( curCSSTop ) || 0; 10290 curLeft = parseFloat( curCSSLeft ) || 0; 10291 } 10292 10293 if ( isFunction( options ) ) { 10294 10295 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10296 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 10297 } 10298 10299 if ( options.top != null ) { 10300 props.top = ( options.top - curOffset.top ) + curTop; 10301 } 10302 if ( options.left != null ) { 10303 props.left = ( options.left - curOffset.left ) + curLeft; 10304 } 10305 10306 if ( "using" in options ) { 10307 options.using.call( elem, props ); 10308 10309 } else { 10310 curElem.css( props ); 10311 } 10312 } 10313}; 10314 10315jQuery.fn.extend( { 10316 10317 // offset() relates an element's border box to the document origin 10318 offset: function( options ) { 10319 10320 // Preserve chaining for setter 10321 if ( arguments.length ) { 10322 return options === undefined ? 10323 this : 10324 this.each( function( i ) { 10325 jQuery.offset.setOffset( this, options, i ); 10326 } ); 10327 } 10328 10329 var rect, win, 10330 elem = this[ 0 ]; 10331 10332 if ( !elem ) { 10333 return; 10334 } 10335 10336 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 10337 // Support: IE <=11 only 10338 // Running getBoundingClientRect on a 10339 // disconnected node in IE throws an error 10340 if ( !elem.getClientRects().length ) { 10341 return { top: 0, left: 0 }; 10342 } 10343 10344 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 10345 rect = elem.getBoundingClientRect(); 10346 win = elem.ownerDocument.defaultView; 10347 return { 10348 top: rect.top + win.pageYOffset, 10349 left: rect.left + win.pageXOffset 10350 }; 10351 }, 10352 10353 // position() relates an element's margin box to its offset parent's padding box 10354 // This corresponds to the behavior of CSS absolute positioning 10355 position: function() { 10356 if ( !this[ 0 ] ) { 10357 return; 10358 } 10359 10360 var offsetParent, offset, doc, 10361 elem = this[ 0 ], 10362 parentOffset = { top: 0, left: 0 }; 10363 10364 // position:fixed elements are offset from the viewport, which itself always has zero offset 10365 if ( jQuery.css( elem, "position" ) === "fixed" ) { 10366 10367 // Assume position:fixed implies availability of getBoundingClientRect 10368 offset = elem.getBoundingClientRect(); 10369 10370 } else { 10371 offset = this.offset(); 10372 10373 // Account for the *real* offset parent, which can be the document or its root element 10374 // when a statically positioned element is identified 10375 doc = elem.ownerDocument; 10376 offsetParent = elem.offsetParent || doc.documentElement; 10377 while ( offsetParent && 10378 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 10379 jQuery.css( offsetParent, "position" ) === "static" ) { 10380 10381 offsetParent = offsetParent.parentNode; 10382 } 10383 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 10384 10385 // Incorporate borders into its offset, since they are outside its content origin 10386 parentOffset = jQuery( offsetParent ).offset(); 10387 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 10388 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 10389 } 10390 } 10391 10392 // Subtract parent offsets and element margins 10393 return { 10394 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 10395 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 10396 }; 10397 }, 10398 10399 // This method will return documentElement in the following cases: 10400 // 1) For the element inside the iframe without offsetParent, this method will return 10401 // documentElement of the parent window 10402 // 2) For the hidden or detached element 10403 // 3) For body or html element, i.e. in case of the html node - it will return itself 10404 // 10405 // but those exceptions were never presented as a real life use-cases 10406 // and might be considered as more preferable results. 10407 // 10408 // This logic, however, is not guaranteed and can change at any point in the future 10409 offsetParent: function() { 10410 return this.map( function() { 10411 var offsetParent = this.offsetParent; 10412 10413 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 10414 offsetParent = offsetParent.offsetParent; 10415 } 10416 10417 return offsetParent || documentElement; 10418 } ); 10419 } 10420} ); 10421 10422// Create scrollLeft and scrollTop methods 10423jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 10424 var top = "pageYOffset" === prop; 10425 10426 jQuery.fn[ method ] = function( val ) { 10427 return access( this, function( elem, method, val ) { 10428 10429 // Coalesce documents and windows 10430 var win; 10431 if ( isWindow( elem ) ) { 10432 win = elem; 10433 } else if ( elem.nodeType === 9 ) { 10434 win = elem.defaultView; 10435 } 10436 10437 if ( val === undefined ) { 10438 return win ? win[ prop ] : elem[ method ]; 10439 } 10440 10441 if ( win ) { 10442 win.scrollTo( 10443 !top ? val : win.pageXOffset, 10444 top ? val : win.pageYOffset 10445 ); 10446 10447 } else { 10448 elem[ method ] = val; 10449 } 10450 }, method, val, arguments.length ); 10451 }; 10452} ); 10453 10454// Support: Safari <=7 - 9.1, Chrome <=37 - 49 10455// Add the top/left cssHooks using jQuery.fn.position 10456// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10457// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 10458// getComputedStyle returns percent when specified for top/left/bottom/right; 10459// rather than make the css module depend on the offset module, just check for it here 10460jQuery.each( [ "top", "left" ], function( _i, prop ) { 10461 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 10462 function( elem, computed ) { 10463 if ( computed ) { 10464 computed = curCSS( elem, prop ); 10465 10466 // If curCSS returns percentage, fallback to offset 10467 return rnumnonpx.test( computed ) ? 10468 jQuery( elem ).position()[ prop ] + "px" : 10469 computed; 10470 } 10471 } 10472 ); 10473} ); 10474 10475 10476// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10477jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 10478 jQuery.each( { 10479 padding: "inner" + name, 10480 content: type, 10481 "": "outer" + name 10482 }, function( defaultExtra, funcName ) { 10483 10484 // Margin is only for outerHeight, outerWidth 10485 jQuery.fn[ funcName ] = function( margin, value ) { 10486 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 10487 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 10488 10489 return access( this, function( elem, type, value ) { 10490 var doc; 10491 10492 if ( isWindow( elem ) ) { 10493 10494 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 10495 return funcName.indexOf( "outer" ) === 0 ? 10496 elem[ "inner" + name ] : 10497 elem.document.documentElement[ "client" + name ]; 10498 } 10499 10500 // Get document width or height 10501 if ( elem.nodeType === 9 ) { 10502 doc = elem.documentElement; 10503 10504 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10505 // whichever is greatest 10506 return Math.max( 10507 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 10508 elem.body[ "offset" + name ], doc[ "offset" + name ], 10509 doc[ "client" + name ] 10510 ); 10511 } 10512 10513 return value === undefined ? 10514 10515 // Get width or height on the element, requesting but not forcing parseFloat 10516 jQuery.css( elem, type, extra ) : 10517 10518 // Set width or height on the element 10519 jQuery.style( elem, type, value, extra ); 10520 }, type, chainable ? margin : undefined, chainable ); 10521 }; 10522 } ); 10523} ); 10524 10525 10526jQuery.each( [ 10527 "ajaxStart", 10528 "ajaxStop", 10529 "ajaxComplete",
10530 "ajaxError", 10531 "ajaxSuccess", 10532 "ajaxSend" 10533], function( _i, type ) { 10534 jQuery.fn[ type ] = function( fn ) { 10535 return this.on( type, fn ); 10536 }; 10537} ); 10538 10539 10540 10541 10542jQuery.fn.extend( { 10543 10544 bind: function( types, data, fn ) { 10545 return this.on( types, null, data, fn ); 10546 }, 10547 unbind: function( types, fn ) { 10548 return this.off( types, null, fn ); 10549 }, 10550 10551 delegate: function( selector, types, data, fn ) { 10552 return this.on( types, selector, data, fn ); 10553 }, 10554 undelegate: function( selector, types, fn ) { 10555 10556 // ( namespace ) or ( selector, types [, fn] ) 10557 return arguments.length === 1 ? 10558 this.off( selector, "**" ) : 10559 this.off( types, selector || "**", fn ); 10560 }, 10561 10562 hover: function( fnOver, fnOut ) { 10563 return this 10564 .on( "mouseenter", fnOver ) 10565 .on( "mouseleave", fnOut || fnOver ); 10566 } 10567} ); 10568 10569jQuery.each( 10570 ( "blur focus focusin focusout resize scroll click dblclick " + 10571 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 10572 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 10573 function( _i, name ) { 10574 10575 // Handle event binding 10576 jQuery.fn[ name ] = function( data, fn ) { 10577 return arguments.length > 0 ? 10578 this.on( name, null, data, fn ) : 10579 this.trigger( name ); 10580 }; 10581 } 10582); 10583 10584 10585 10586 10587// Support: Android <=4.0 only 10588// Make sure we trim BOM and NBSP 10589// Require that the "whitespace run" starts from a non-whitespace 10590// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. 10591var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; 10592 10593// Bind a function to a context, optionally partially applying any 10594// arguments. 10595// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 10596// However, it is not slated for removal any time soon 10597jQuery.proxy = function( fn, context ) { 10598 var tmp, args, proxy; 10599 10600 if ( typeof context === "string" ) { 10601 tmp = fn[ context ]; 10602 context = fn; 10603 fn = tmp; 10604 } 10605 10606 // Quick check to determine if target is callable, in the spec 10607 // this throws a TypeError, but we will just return undefined. 10608 if ( !isFunction( fn ) ) { 10609 return undefined; 10610 } 10611 10612 // Simulated bind 10613 args = slice.call( arguments, 2 ); 10614 proxy = function() { 10615 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 10616 }; 10617 10618 // Set the guid of unique handler to the same of original handler, so it can be removed 10619 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 10620 10621 return proxy; 10622}; 10623 10624jQuery.holdReady = function( hold ) { 10625 if ( hold ) { 10626 jQuery.readyWait++; 10627 } else { 10628 jQuery.ready( true ); 10629 } 10630}; 10631jQuery.isArray = Array.isArray; 10632jQuery.parseJSON = JSON.parse; 10633jQuery.nodeName = nodeName; 10634jQuery.isFunction = isFunction; 10635jQuery.isWindow = isWindow; 10636jQuery.camelCase = camelCase; 10637jQuery.type = toType; 10638 10639jQuery.now = Date.now; 10640 10641jQuery.isNumeric = function( obj ) { 10642 10643 // As of jQuery 3.0, isNumeric is limited to 10644 // strings and numbers (primitives or objects) 10645 // that can be coerced to finite numbers (gh-2662) 10646 var type = jQuery.type( obj ); 10647 return ( type === "number" || type === "string" ) && 10648 10649 // parseFloat NaNs numeric-cast false positives ("") 10650 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 10651 // subtraction forces infinities to NaN 10652 !isNaN( obj - parseFloat( obj ) ); 10653}; 10654 10655jQuery.trim = function( text ) { 10656 return text == null ? 10657 "" : 10658 ( text + "" ).replace( rtrim, "$1" ); 10659}; 10660 10661 10662 10663// Register as a named AMD module, since jQuery can be concatenated with other 10664// files that may use define, but not via a proper concatenation script that 10665// understands anonymous AMD modules. A named AMD is safest and most robust 10666// way to register. Lowercase jquery is used because AMD module names are 10667// derived from file names, and jQuery is normally delivered in a lowercase 10668// file name. Do this after creating the global so that if an AMD module wants 10669// to call noConflict to hide this version of jQuery, it will work. 10670 10671// Note that for maximum portability, libraries that are not jQuery should 10672// declare themselves as anonymous modules, and avoid setting a global if an 10673// AMD loader is present. jQuery is a special case. For more information, see 10674// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10675 10676if ( typeof define === "function" && define.amd ) { 10677 define( "jquery", [], function() { 10678 return jQuery; 10679 } ); 10680} 10681 10682 10683 10684 10685var 10686 10687 // Map over jQuery in case of overwrite 10688 _jQuery = window.jQuery, 10689 10690 // Map over the $ in case of overwrite 10691 _$ = window.$; 10692 10693jQuery.noConflict = function( deep ) { 10694 if ( window.$ === jQuery ) { 10695 window.$ = _$; 10696 } 10697 10698 if ( deep && window.jQuery === jQuery ) { 10699 window.jQuery = _jQuery; 10700 } 10701 10702 return jQuery; 10703}; 10704 10705// Expose jQuery and $ identifiers, even in AMD 10706// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557) 10707// and CommonJS for browser emulators (trac-13566) 10708if ( typeof noGlobal === "undefined" ) { 10709 window.jQuery = window.$ = jQuery; 10710} 10711 10712 10713 10714 10715return jQuery; 10716} ); 10717// To get jquery version use 10718// $.fn.jquery 10719 10720// Compatibility with legacy jquery API 10721var fn_toggle = jQuery.fn.toggle; 10722 10723jQuery.fn.extend({ 10724 size: function () { 10725 return this.length; 10726 }, 10727 bind: function( types, data, fn ) { 10728 return this.on( types, null, data, fn ); 10729 }, 10730 unbind: function( types, fn ) { 10731 return this.off( types, null, fn ); 10732 }, 10733 live: function( types, data, fn ) { 10734 jQuery(this.context).on(types, this.selector, data, fn ); 10735 return this; 10736 }, 10737 die: function( types, fn ) { 10738 jQuery(this.context).off( types, this.selector || "**", fn ); 10739 return this; 10740 }, 10741 error: function( msg ) { 10742 throw new Error( msg ); 10743 }, 10744 __eventsToggle: function( fn ) { 10745 // Save reference to arguments for access in closure 10746 var args = arguments, 10747 guid = fn.guid || jQuery.guid++, 10748 i = 0, 10749 toggler = function( event ) { 10750 // Figure out which function to execute 10751 var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; 10752 jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); 10753 10754 // Make sure that clicks stop 10755 event.preventDefault(); 10756 10757 // and execute the function 10758 return args[ lastToggle ].apply( this, arguments ) || false; 10759 }; 10760 10761 // link all the functions, so any of them can unbind this click handler 10762 toggler.guid = guid; 10763 while ( i < args.length ) { 10764 args[ i++ ].guid = guid; 10765 } 10766 10767 return this.click( toggler ); 10768 }, 10769 toggle: function( state, fn2 ) { 10770 10771 if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) {
vendor: 6,279 bytes, lines 10772-10966
10772 // EventsToggle was deprecated in 1.8 and removed in 1.9 10773 return jQuery.fn.__eventsToggle.apply( this, arguments ); 10774 } 10775 10776 return fn_toggle.apply(this, arguments); 10777 } 10778}); 10779 10780// jquery addSelf 10781jQuery.fn.andSelf = jQuery.fn.addBack; 10782 10783// jquery.browser 10784(function() { 10785 10786 var matched, browser; 10787 10788 // Use of jQuery.browser is frowned upon. 10789 // More details: http://api.jquery.com/jQuery.browser 10790 // jQuery.uaMatch maintained for back-compat 10791 jQuery.uaMatch = function( ua ) { 10792 ua = ua.toLowerCase(); 10793 10794 var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || 10795 /(webkit)[ \/]([\w.]+)/.exec( ua ) || 10796 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || 10797 /(msie) ([\w.]+)/.exec( ua ) || 10798 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || 10799 []; 10800 10801 return { 10802 browser: match[ 1 ] || "", 10803 version: match[ 2 ] || "0" 10804 }; 10805 }; 10806 10807 matched = jQuery.uaMatch( navigator.userAgent ); 10808 browser = {}; 10809 10810 if ( matched.browser ) { 10811 browser[ matched.browser ] = true; 10812 browser.version = matched.version; 10813 } 10814 10815 // Chrome is Webkit, but Webkit is also Safari. 10816 if ( browser.chrome ) { 10817 browser.webkit = true; 10818 } else if ( browser.webkit ) { 10819 browser.safari = true; 10820 } 10821 10822 jQuery.browser = browser; 10823 10824})(); 10825/*! jQuery UI - v1.13.2 - 2022-07-14 10826* http://jqueryui.com 10827* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js 10828* Copyright jQuery Foundation and other contributors; Licensed MIT */ 10829 10830( function( factory ) { 10831 "use strict"; 10832 10833 if ( typeof define === "function" && define.amd ) { 10834 10835 // AMD. Register as an anonymous module. 10836 define( [ "jquery" ], factory ); 10837 } else { 10838 10839 // Browser globals 10840 factory( jQuery ); 10841 } 10842} )( function( $ ) { 10843"use strict"; 10844 10845$.ui = $.ui || {}; 10846 10847var version = $.ui.version = "1.13.2"; 10848 10849 10850/*! 10851 * jQuery UI Widget 1.13.2 10852 * http://jqueryui.com 10853 * 10854 * Copyright jQuery Foundation and other contributors 10855 * Released under the MIT license. 10856 * http://jquery.org/license 10857 */ 10858 10859//>>label: Widget 10860//>>group: Core 10861//>>description: Provides a factory for creating stateful widgets with a common API. 10862//>>docs: http://api.jqueryui.com/jQuery.widget/ 10863//>>demos: http://jqueryui.com/widget/ 10864 10865 10866var widgetUuid = 0; 10867var widgetHasOwnProperty = Array.prototype.hasOwnProperty; 10868var widgetSlice = Array.prototype.slice; 10869 10870$.cleanData = ( function( orig ) { 10871 return function( elems ) { 10872 var events, elem, i; 10873 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { 10874 10875 // Only trigger remove when necessary to save time 10876 events = $._data( elem, "events" ); 10877 if ( events && events.remove ) { 10878 $( elem ).triggerHandler( "remove" ); 10879 } 10880 } 10881 orig( elems ); 10882 }; 10883} )( $.cleanData ); 10884 10885$.widget = function( name, base, prototype ) { 10886 var existingConstructor, constructor, basePrototype; 10887 10888 // ProxiedPrototype allows the provided prototype to remain unmodified 10889 // so that it can be used as a mixin for multiple widgets (#8876) 10890 var proxiedPrototype = {}; 10891 10892 var namespace = name.split( "." )[ 0 ]; 10893 name = name.split( "." )[ 1 ]; 10894 var fullName = namespace + "-" + name; 10895 10896 if ( !prototype ) { 10897 prototype = base; 10898 base = $.Widget; 10899 } 10900 10901 if ( Array.isArray( prototype ) ) { 10902 prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); 10903 } 10904 10905 // Create selector for plugin 10906 $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { 10907 return !!$.data( elem, fullName ); 10908 }; 10909 10910 $[ namespace ] = $[ namespace ] || {}; 10911 existingConstructor = $[ namespace ][ name ]; 10912 constructor = $[ namespace ][ name ] = function( options, element ) { 10913 10914 // Allow instantiation without "new" keyword 10915 if ( !this || !this._createWidget ) { 10916 return new constructor( options, element ); 10917 } 10918 10919 // Allow instantiation without initializing for simple inheritance 10920 // must use "new" keyword (the code above always passes args) 10921 if ( arguments.length ) { 10922 this._createWidget( options, element ); 10923 } 10924 }; 10925 10926 // Extend with the existing constructor to carry over any static properties 10927 $.extend( constructor, existingConstructor, { 10928 version: prototype.version, 10929 10930 // Copy the object used to create the prototype in case we need to 10931 // redefine the widget later 10932 _proto: $.extend( {}, prototype ), 10933 10934 // Track widgets that inherit from this widget in case this widget is 10935 // redefined after a widget inherits from it 10936 _childConstructors: [] 10937 } ); 10938 10939 basePrototype = new base(); 10940 10941 // We need to make the options hash a property directly on the new instance 10942 // otherwise we'll modify the options hash on the prototype that we're 10943 // inheriting from 10944 basePrototype.options = $.widget.extend( {}, basePrototype.options ); 10945 $.each( prototype, function( prop, value ) { 10946 if ( typeof value !== "function" ) { 10947 proxiedPrototype[ prop ] = value; 10948 return; 10949 } 10950 proxiedPrototype[ prop ] = ( function() { 10951 function _super() { 10952 return base.prototype[ prop ].apply( this, arguments ); 10953 } 10954 10955 function _superApply( args ) { 10956 return base.prototype[ prop ].apply( this, args ); 10957 } 10958 10959 return function() { 10960 var __super = this._super; 10961 var __superApply = this._superApply; 10962 var returnValue; 10963 10964 this._super = _super; 10965 this._superApply = _superApply; 10966
vendor: 32,706 bytes, lines 10967-12091
10967 returnValue = value.apply( this, arguments ); 10968 10969 this._super = __super; 10970 this._superApply = __superApply; 10971 10972 return returnValue; 10973 }; 10974 } )(); 10975 } ); 10976 constructor.prototype = $.widget.extend( basePrototype, { 10977 10978 // TODO: remove support for widgetEventPrefix 10979 // always use the name + a colon as the prefix, e.g., draggable:start 10980 // don't prefix for widgets that aren't DOM-based 10981 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name 10982 }, proxiedPrototype, { 10983 constructor: constructor, 10984 namespace: namespace, 10985 widgetName: name, 10986 widgetFullName: fullName 10987 } ); 10988 10989 // If this widget is being redefined then we need to find all widgets that 10990 // are inheriting from it and redefine all of them so that they inherit from 10991 // the new version of this widget. We're essentially trying to replace one 10992 // level in the prototype chain. 10993 if ( existingConstructor ) { 10994 $.each( existingConstructor._childConstructors, function( i, child ) { 10995 var childPrototype = child.prototype; 10996 10997 // Redefine the child widget using the same prototype that was 10998 // originally used, but inherit from the new version of the base 10999 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, 11000 child._proto ); 11001 } ); 11002 11003 // Remove the list of existing child constructors from the old constructor 11004 // so the old child constructors can be garbage collected 11005 delete existingConstructor._childConstructors; 11006 } else { 11007 base._childConstructors.push( constructor ); 11008 } 11009 11010 $.widget.bridge( name, constructor ); 11011 11012 return constructor; 11013}; 11014 11015$.widget.extend = function( target ) { 11016 var input = widgetSlice.call( arguments, 1 ); 11017 var inputIndex = 0; 11018 var inputLength = input.length; 11019 var key; 11020 var value; 11021 11022 for ( ; inputIndex < inputLength; inputIndex++ ) { 11023 for ( key in input[ inputIndex ] ) { 11024 value = input[ inputIndex ][ key ]; 11025 if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { 11026 11027 // Clone objects 11028 if ( $.isPlainObject( value ) ) { 11029 target[ key ] = $.isPlainObject( target[ key ] ) ? 11030 $.widget.extend( {}, target[ key ], value ) : 11031 11032 // Don't extend strings, arrays, etc. with objects 11033 $.widget.extend( {}, value ); 11034 11035 // Copy everything else by reference 11036 } else { 11037 target[ key ] = value; 11038 } 11039 } 11040 } 11041 } 11042 return target; 11043}; 11044 11045$.widget.bridge = function( name, object ) { 11046 var fullName = object.prototype.widgetFullName || name; 11047 $.fn[ name ] = function( options ) { 11048 var isMethodCall = typeof options === "string"; 11049 var args = widgetSlice.call( arguments, 1 ); 11050 var returnValue = this; 11051 11052 if ( isMethodCall ) { 11053 11054 // If this is an empty collection, we need to have the instance method 11055 // return undefined instead of the jQuery instance 11056 if ( !this.length && options === "instance" ) { 11057 returnValue = undefined; 11058 } else { 11059 this.each( function() { 11060 var methodValue; 11061 var instance = $.data( this, fullName ); 11062 11063 if ( options === "instance" ) { 11064 returnValue = instance; 11065 return false; 11066 } 11067 11068 if ( !instance ) { 11069 return $.error( "cannot call methods on " + name + 11070 " prior to initialization; " + 11071 "attempted to call method '" + options + "'" ); 11072 } 11073 11074 if ( typeof instance[ options ] !== "function" || 11075 options.charAt( 0 ) === "_" ) { 11076 return $.error( "no such method '" + options + "' for " + name + 11077 " widget instance" ); 11078 } 11079 11080 methodValue = instance[ options ].apply( instance, args ); 11081 11082 if ( methodValue !== instance && methodValue !== undefined ) { 11083 returnValue = methodValue && methodValue.jquery ? 11084 returnValue.pushStack( methodValue.get() ) : 11085 methodValue; 11086 return false; 11087 } 11088 } ); 11089 } 11090 } else { 11091 11092 // Allow multiple hashes to be passed on init 11093 if ( args.length ) { 11094 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 11095 } 11096 11097 this.each( function() { 11098 var instance = $.data( this, fullName ); 11099 if ( instance ) { 11100 instance.option( options || {} ); 11101 if ( instance._init ) { 11102 instance._init(); 11103 } 11104 } else { 11105 $.data( this, fullName, new object( options, this ) ); 11106 } 11107 } ); 11108 } 11109 11110 return returnValue; 11111 }; 11112}; 11113 11114$.Widget = function( /* options, element */ ) {}; 11115$.Widget._childConstructors = []; 11116 11117$.Widget.prototype = { 11118 widgetName: "widget", 11119 widgetEventPrefix: "", 11120 defaultElement: "<div>", 11121 11122 options: { 11123 classes: {}, 11124 disabled: false, 11125 11126 // Callbacks 11127 create: null 11128 }, 11129 11130 _createWidget: function( options, element ) { 11131 element = $( element || this.defaultElement || this )[ 0 ]; 11132 this.element = $( element ); 11133 this.uuid = widgetUuid++; 11134 this.eventNamespace = "." + this.widgetName + this.uuid; 11135 11136 this.bindings = $(); 11137 this.hoverable = $(); 11138 this.focusable = $(); 11139 this.classesElementLookup = {}; 11140 11141 if ( element !== this ) { 11142 $.data( element, this.widgetFullName, this ); 11143 this._on( true, this.element, { 11144 remove: function( event ) { 11145 if ( event.target === element ) { 11146 this.destroy(); 11147 } 11148 } 11149 } ); 11150 this.document = $( element.style ? 11151 11152 // Element within the document 11153 element.ownerDocument : 11154 11155 // Element is window or document 11156 element.document || element ); 11157 this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); 11158 } 11159 11160 this.options = $.widget.extend( {}, 11161 this.options, 11162 this._getCreateOptions(), 11163 options ); 11164 11165 this._create(); 11166 11167 if ( this.options.disabled ) { 11168 this._setOptionDisabled( this.options.disabled ); 11169 } 11170 11171 this._trigger( "create", null, this._getCreateEventData() ); 11172 this._init(); 11173 }, 11174 11175 _getCreateOptions: function() { 11176 return {}; 11177 }, 11178 11179 _getCreateEventData: $.noop, 11180 11181 _create: $.noop, 11182 11183 _init: $.noop, 11184 11185 destroy: function() { 11186 var that = this; 11187 11188 this._destroy(); 11189 $.each( this.classesElementLookup, function( key, value ) { 11190 that._removeClass( value, key ); 11191 } ); 11192 11193 // We can probably remove the unbind calls in 2.0 11194 // all event bindings should go through this._on() 11195 this.element 11196 .off( this.eventNamespace ) 11197 .removeData( this.widgetFullName ); 11198 this.widget() 11199 .off( this.eventNamespace ) 11200 .removeAttr( "aria-disabled" ); 11201 11202 // Clean up events and states 11203 this.bindings.off( this.eventNamespace ); 11204 }, 11205 11206 _destroy: $.noop, 11207 11208 widget: function() { 11209 return this.element; 11210 }, 11211 11212 option: function( key, value ) { 11213 var options = key; 11214 var parts; 11215 var curOption; 11216 var i; 11217 11218 if ( arguments.length === 0 ) { 11219 11220 // Don't return a reference to the internal hash 11221 return $.widget.extend( {}, this.options ); 11222 } 11223 11224 if ( typeof key === "string" ) { 11225 11226 // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } 11227 options = {}; 11228 parts = key.split( "." ); 11229 key = parts.shift(); 11230 if ( parts.length ) { 11231 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); 11232 for ( i = 0; i < parts.length - 1; i++ ) { 11233 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; 11234 curOption = curOption[ parts[ i ] ]; 11235 } 11236 key = parts.pop(); 11237 if ( arguments.length === 1 ) { 11238 return curOption[ key ] === undefined ? null : curOption[ key ]; 11239 } 11240 curOption[ key ] = value; 11241 } else { 11242 if ( arguments.length === 1 ) { 11243 return this.options[ key ] === undefined ? null : this.options[ key ]; 11244 } 11245 options[ key ] = value; 11246 } 11247 } 11248 11249 this._setOptions( options ); 11250 11251 return this; 11252 }, 11253 11254 _setOptions: function( options ) { 11255 var key; 11256 11257 for ( key in options ) { 11258 this._setOption( key, options[ key ] ); 11259 } 11260 11261 return this; 11262 }, 11263 11264 _setOption: function( key, value ) { 11265 if ( key === "classes" ) { 11266 this._setOptionClasses( value ); 11267 } 11268 11269 this.options[ key ] = value; 11270 11271 if ( key === "disabled" ) { 11272 this._setOptionDisabled( value ); 11273 } 11274 11275 return this; 11276 }, 11277 11278 _setOptionClasses: function( value ) { 11279 var classKey, elements, currentElements; 11280 11281 for ( classKey in value ) { 11282 currentElements = this.classesElementLookup[ classKey ]; 11283 if ( value[ classKey ] === this.options.classes[ classKey ] || 11284 !currentElements || 11285 !currentElements.length ) { 11286 continue; 11287 } 11288 11289 // We are doing this to create a new jQuery object because the _removeClass() call 11290 // on the next line is going to destroy the reference to the current elements being 11291 // tracked. We need to save a copy of this collection so that we can add the new classes 11292 // below. 11293 elements = $( currentElements.get() ); 11294 this._removeClass( currentElements, classKey ); 11295 11296 // We don't use _addClass() here, because that uses this.options.classes 11297 // for generating the string of classes. We want to use the value passed in from 11298 // _setOption(), this is the new value of the classes option which was passed to 11299 // _setOption(). We pass this value directly to _classes(). 11300 elements.addClass( this._classes( { 11301 element: elements, 11302 keys: classKey, 11303 classes: value, 11304 add: true 11305 } ) ); 11306 } 11307 }, 11308 11309 _setOptionDisabled: function( value ) { 11310 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); 11311 11312 // If the widget is becoming disabled, then nothing is interactive 11313 if ( value ) { 11314 this._removeClass( this.hoverable, null, "ui-state-hover" ); 11315 this._removeClass( this.focusable, null, "ui-state-focus" ); 11316 } 11317 }, 11318 11319 enable: function() { 11320 return this._setOptions( { disabled: false } ); 11321 }, 11322 11323 disable: function() { 11324 return this._setOptions( { disabled: true } ); 11325 }, 11326 11327 _classes: function( options ) { 11328 var full = []; 11329 var that = this; 11330 11331 options = $.extend( { 11332 element: this.element, 11333 classes: this.options.classes || {} 11334 }, options ); 11335 11336 function bindRemoveEvent() { 11337 var nodesToBind = []; 11338 11339 options.element.each( function( _, element ) { 11340 var isTracked = $.map( that.classesElementLookup, function( elements ) { 11341 return elements; 11342 } ) 11343 .some( function( elements ) { 11344 return elements.is( element ); 11345 } ); 11346 11347 if ( !isTracked ) { 11348 nodesToBind.push( element ); 11349 } 11350 } ); 11351 11352 that._on( $( nodesToBind ), { 11353 remove: "_untrackClassesElement" 11354 } ); 11355 } 11356 11357 function processClassString( classes, checkOption ) { 11358 var current, i; 11359 for ( i = 0; i < classes.length; i++ ) { 11360 current = that.classesElementLookup[ classes[ i ] ] || $(); 11361 if ( options.add ) { 11362 bindRemoveEvent(); 11363 current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); 11364 } else { 11365 current = $( current.not( options.element ).get() ); 11366 } 11367 that.classesElementLookup[ classes[ i ] ] = current; 11368 full.push( classes[ i ] ); 11369 if ( checkOption && options.classes[ classes[ i ] ] ) { 11370 full.push( options.classes[ classes[ i ] ] ); 11371 } 11372 } 11373 } 11374 11375 if ( options.keys ) { 11376 processClassString( options.keys.match( /\S+/g ) || [], true ); 11377 } 11378 if ( options.extra ) { 11379 processClassString( options.extra.match( /\S+/g ) || [] ); 11380 } 11381 11382 return full.join( " " ); 11383 }, 11384 11385 _untrackClassesElement: function( event ) { 11386 var that = this; 11387 $.each( that.classesElementLookup, function( key, value ) { 11388 if ( $.inArray( event.target, value ) !== -1 ) { 11389 that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); 11390 } 11391 } ); 11392 11393 this._off( $( event.target ) ); 11394 }, 11395 11396 _removeClass: function( element, keys, extra ) { 11397 return this._toggleClass( element, keys, extra, false ); 11398 }, 11399 11400 _addClass: function( element, keys, extra ) { 11401 return this._toggleClass( element, keys, extra, true ); 11402 }, 11403 11404 _toggleClass: function( element, keys, extra, add ) { 11405 add = ( typeof add === "boolean" ) ? add : extra; 11406 var shift = ( typeof element === "string" || element === null ), 11407 options = { 11408 extra: shift ? keys : extra, 11409 keys: shift ? element : keys, 11410 element: shift ? this.element : element, 11411 add: add 11412 }; 11413 options.element.toggleClass( this._classes( options ), add ); 11414 return this; 11415 }, 11416 11417 _on: function( suppressDisabledCheck, element, handlers ) { 11418 var delegateElement; 11419 var instance = this; 11420 11421 // No suppressDisabledCheck flag, shuffle arguments 11422 if ( typeof suppressDisabledCheck !== "boolean" ) { 11423 handlers = element; 11424 element = suppressDisabledCheck; 11425 suppressDisabledCheck = false; 11426 } 11427 11428 // No element argument, shuffle and use this.element 11429 if ( !handlers ) { 11430 handlers = element; 11431 element = this.element; 11432 delegateElement = this.widget(); 11433 } else { 11434 element = delegateElement = $( element ); 11435 this.bindings = this.bindings.add( element ); 11436 } 11437 11438 $.each( handlers, function( event, handler ) { 11439 function handlerProxy() { 11440 11441 // Allow widgets to customize the disabled handling 11442 // - disabled as an array instead of boolean 11443 // - disabled class as method for disabling individual parts 11444 if ( !suppressDisabledCheck && 11445 ( instance.options.disabled === true || 11446 $( this ).hasClass( "ui-state-disabled" ) ) ) { 11447 return; 11448 } 11449 return ( typeof handler === "string" ? instance[ handler ] : handler ) 11450 .apply( instance, arguments ); 11451 } 11452 11453 // Copy the guid so direct unbinding works 11454 if ( typeof handler !== "string" ) { 11455 handlerProxy.guid = handler.guid = 11456 handler.guid || handlerProxy.guid || $.guid++; 11457 } 11458 11459 var match = event.match( /^([\w:-]*)\s*(.*)$/ ); 11460 var eventName = match[ 1 ] + instance.eventNamespace; 11461 var selector = match[ 2 ]; 11462 11463 if ( selector ) { 11464 delegateElement.on( eventName, selector, handlerProxy ); 11465 } else { 11466 element.on( eventName, handlerProxy ); 11467 } 11468 } ); 11469 }, 11470 11471 _off: function( element, eventName ) { 11472 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + 11473 this.eventNamespace; 11474 element.off( eventName ); 11475 11476 // Clear the stack to avoid memory leaks (#10056) 11477 this.bindings = $( this.bindings.not( element ).get() ); 11478 this.focusable = $( this.focusable.not( element ).get() ); 11479 this.hoverable = $( this.hoverable.not( element ).get() ); 11480 }, 11481 11482 _delay: function( handler, delay ) { 11483 function handlerProxy() { 11484 return ( typeof handler === "string" ? instance[ handler ] : handler ) 11485 .apply( instance, arguments ); 11486 } 11487 var instance = this; 11488 return setTimeout( handlerProxy, delay || 0 ); 11489 }, 11490 11491 _hoverable: function( element ) { 11492 this.hoverable = this.hoverable.add( element ); 11493 this._on( element, { 11494 mouseenter: function( event ) { 11495 this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); 11496 }, 11497 mouseleave: function( event ) { 11498 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); 11499 } 11500 } ); 11501 }, 11502 11503 _focusable: function( element ) { 11504 this.focusable = this.focusable.add( element ); 11505 this._on( element, { 11506 focusin: function( event ) { 11507 this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); 11508 }, 11509 focusout: function( event ) { 11510 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); 11511 } 11512 } ); 11513 }, 11514 11515 _trigger: function( type, event, data ) { 11516 var prop, orig; 11517 var callback = this.options[ type ]; 11518 11519 data = data || {}; 11520 event = $.Event( event ); 11521 event.type = ( type === this.widgetEventPrefix ? 11522 type : 11523 this.widgetEventPrefix + type ).toLowerCase(); 11524 11525 // The original event may come from any element 11526 // so we need to reset the target on the new event 11527 event.target = this.element[ 0 ]; 11528 11529 // Copy original event properties over to the new event 11530 orig = event.originalEvent; 11531 if ( orig ) { 11532 for ( prop in orig ) { 11533 if ( !( prop in event ) ) { 11534 event[ prop ] = orig[ prop ]; 11535 } 11536 } 11537 } 11538 11539 this.element.trigger( event, data ); 11540 return !( typeof callback === "function" && 11541 callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || 11542 event.isDefaultPrevented() ); 11543 } 11544}; 11545 11546$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { 11547 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { 11548 if ( typeof options === "string" ) { 11549 options = { effect: options }; 11550 } 11551 11552 var hasOptions; 11553 var effectName = !options ? 11554 method : 11555 options === true || typeof options === "number" ? 11556 defaultEffect : 11557 options.effect || defaultEffect; 11558 11559 options = options || {}; 11560 if ( typeof options === "number" ) { 11561 options = { duration: options }; 11562 } else if ( options === true ) { 11563 options = {}; 11564 } 11565 11566 hasOptions = !$.isEmptyObject( options ); 11567 options.complete = callback; 11568 11569 if ( options.delay ) { 11570 element.delay( options.delay ); 11571 } 11572 11573 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { 11574 element[ method ]( options ); 11575 } else if ( effectName !== method && element[ effectName ] ) { 11576 element[ effectName ]( options.duration, options.easing, callback ); 11577 } else { 11578 element.queue( function( next ) { 11579 $( this )[ method ](); 11580 if ( callback ) { 11581 callback.call( element[ 0 ] ); 11582 } 11583 next(); 11584 } ); 11585 } 11586 }; 11587} ); 11588 11589var widget = $.widget; 11590 11591 11592/*! 11593 * jQuery UI Position 1.13.2 11594 * http://jqueryui.com 11595 * 11596 * Copyright jQuery Foundation and other contributors 11597 * Released under the MIT license. 11598 * http://jquery.org/license 11599 * 11600 * http://api.jqueryui.com/position/ 11601 */ 11602 11603//>>label: Position 11604//>>group: Core 11605//>>description: Positions elements relative to other elements. 11606//>>docs: http://api.jqueryui.com/position/ 11607//>>demos: http://jqueryui.com/position/ 11608 11609 11610( function() { 11611var cachedScrollbarWidth, 11612 max = Math.max, 11613 abs = Math.abs, 11614 rhorizontal = /left|center|right/, 11615 rvertical = /top|center|bottom/, 11616 roffset = /[\+\-]\d+(\.[\d]+)?%?/, 11617 rposition = /^\w+/, 11618 rpercent = /%$/, 11619 _position = $.fn.position; 11620 11621function getOffsets( offsets, width, height ) { 11622 return [ 11623 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), 11624 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) 11625 ]; 11626} 11627 11628function parseCss( element, property ) { 11629 return parseInt( $.css( element, property ), 10 ) || 0; 11630} 11631 11632function isWindow( obj ) { 11633 return obj != null && obj === obj.window; 11634} 11635 11636function getDimensions( elem ) { 11637 var raw = elem[ 0 ]; 11638 if ( raw.nodeType === 9 ) { 11639 return { 11640 width: elem.width(), 11641 height: elem.height(), 11642 offset: { top: 0, left: 0 } 11643 }; 11644 } 11645 if ( isWindow( raw ) ) { 11646 return { 11647 width: elem.width(), 11648 height: elem.height(), 11649 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } 11650 }; 11651 } 11652 if ( raw.preventDefault ) { 11653 return { 11654 width: 0, 11655 height: 0, 11656 offset: { top: raw.pageY, left: raw.pageX } 11657 }; 11658 } 11659 return { 11660 width: elem.outerWidth(), 11661 height: elem.outerHeight(), 11662 offset: elem.offset() 11663 }; 11664} 11665 11666$.position = { 11667 scrollbarWidth: function() { 11668 if ( cachedScrollbarWidth !== undefined ) { 11669 return cachedScrollbarWidth; 11670 } 11671 var w1, w2, 11672 div = $( "<div style=" + 11673 "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + 11674 "<div style='height:300px;width:auto;'></div></div>" ), 11675 innerDiv = div.children()[ 0 ]; 11676 11677 $( "body" ).append( div ); 11678 w1 = innerDiv.offsetWidth; 11679 div.css( "overflow", "scroll" ); 11680 11681 w2 = innerDiv.offsetWidth; 11682 11683 if ( w1 === w2 ) { 11684 w2 = div[ 0 ].clientWidth; 11685 } 11686 11687 div.remove(); 11688 11689 return ( cachedScrollbarWidth = w1 - w2 ); 11690 }, 11691 getScrollInfo: function( within ) { 11692 var overflowX = within.isWindow || within.isDocument ? "" : 11693 within.element.css( "overflow-x" ), 11694 overflowY = within.isWindow || within.isDocument ? "" : 11695 within.element.css( "overflow-y" ), 11696 hasOverflowX = overflowX === "scroll" || 11697 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), 11698 hasOverflowY = overflowY === "scroll" || 11699 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); 11700 return { 11701 width: hasOverflowY ? $.position.scrollbarWidth() : 0, 11702 height: hasOverflowX ? $.position.scrollbarWidth() : 0 11703 }; 11704 }, 11705 getWithinInfo: function( element ) { 11706 var withinElement = $( element || window ), 11707 isElemWindow = isWindow( withinElement[ 0 ] ), 11708 isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, 11709 hasOffset = !isElemWindow && !isDocument; 11710 return { 11711 element: withinElement, 11712 isWindow: isElemWindow, 11713 isDocument: isDocument, 11714 offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, 11715 scrollLeft: withinElement.scrollLeft(), 11716 scrollTop: withinElement.scrollTop(), 11717 width: withinElement.outerWidth(), 11718 height: withinElement.outerHeight() 11719 }; 11720 } 11721}; 11722 11723$.fn.position = function( options ) { 11724 if ( !options || !options.of ) { 11725 return _position.apply( this, arguments ); 11726 } 11727 11728 // Make a copy, we don't want to modify arguments 11729 options = $.extend( {}, options ); 11730 11731 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, 11732 11733 // Make sure string options are treated as CSS selectors 11734 target = typeof options.of === "string" ? 11735 $( document ).find( options.of ) : 11736 $( options.of ), 11737 11738 within = $.position.getWithinInfo( options.within ), 11739 scrollInfo = $.position.getScrollInfo( within ), 11740 collision = ( options.collision || "flip" ).split( " " ), 11741 offsets = {}; 11742 11743 dimensions = getDimensions( target ); 11744 if ( target[ 0 ].preventDefault ) { 11745 11746 // Force left top to allow flipping 11747 options.at = "left top"; 11748 } 11749 targetWidth = dimensions.width; 11750 targetHeight = dimensions.height; 11751 targetOffset = dimensions.offset; 11752 11753 // Clone to reuse original targetOffset later 11754 basePosition = $.extend( {}, targetOffset ); 11755 11756 // Force my and at to have valid horizontal and vertical positions 11757 // if a value is missing or invalid, it will be converted to center 11758 $.each( [ "my", "at" ], function() { 11759 var pos = ( options[ this ] || "" ).split( " " ), 11760 horizontalOffset, 11761 verticalOffset; 11762 11763 if ( pos.length === 1 ) { 11764 pos = rhorizontal.test( pos[ 0 ] ) ? 11765 pos.concat( [ "center" ] ) : 11766 rvertical.test( pos[ 0 ] ) ? 11767 [ "center" ].concat( pos ) : 11768 [ "center", "center" ]; 11769 } 11770 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; 11771 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; 11772 11773 // Calculate offsets 11774 horizontalOffset = roffset.exec( pos[ 0 ] ); 11775 verticalOffset = roffset.exec( pos[ 1 ] ); 11776 offsets[ this ] = [ 11777 horizontalOffset ? horizontalOffset[ 0 ] : 0, 11778 verticalOffset ? verticalOffset[ 0 ] : 0 11779 ]; 11780 11781 // Reduce to just the positions without the offsets 11782 options[ this ] = [ 11783 rposition.exec( pos[ 0 ] )[ 0 ], 11784 rposition.exec( pos[ 1 ] )[ 0 ] 11785 ]; 11786 } ); 11787 11788 // Normalize collision option 11789 if ( collision.length === 1 ) { 11790 collision[ 1 ] = collision[ 0 ]; 11791 } 11792 11793 if ( options.at[ 0 ] === "right" ) { 11794 basePosition.left += targetWidth; 11795 } else if ( options.at[ 0 ] === "center" ) { 11796 basePosition.left += targetWidth / 2; 11797 } 11798 11799 if ( options.at[ 1 ] === "bottom" ) { 11800 basePosition.top += targetHeight; 11801 } else if ( options.at[ 1 ] === "center" ) { 11802 basePosition.top += targetHeight / 2; 11803 } 11804 11805 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); 11806 basePosition.left += atOffset[ 0 ]; 11807 basePosition.top += atOffset[ 1 ]; 11808 11809 return this.each( function() { 11810 var collisionPosition, using, 11811 elem = $( this ), 11812 elemWidth = elem.outerWidth(), 11813 elemHeight = elem.outerHeight(), 11814 marginLeft = parseCss( this, "marginLeft" ), 11815 marginTop = parseCss( this, "marginTop" ), 11816 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + 11817 scrollInfo.width, 11818 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + 11819 scrollInfo.height, 11820 position = $.extend( {}, basePosition ), 11821 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); 11822 11823 if ( options.my[ 0 ] === "right" ) { 11824 position.left -= elemWidth; 11825 } else if ( options.my[ 0 ] === "center" ) { 11826 position.left -= elemWidth / 2; 11827 } 11828 11829 if ( options.my[ 1 ] === "bottom" ) { 11830 position.top -= elemHeight; 11831 } else if ( options.my[ 1 ] === "center" ) { 11832 position.top -= elemHeight / 2; 11833 } 11834 11835 position.left += myOffset[ 0 ]; 11836 position.top += myOffset[ 1 ]; 11837 11838 collisionPosition = { 11839 marginLeft: marginLeft, 11840 marginTop: marginTop 11841 }; 11842 11843 $.each( [ "left", "top" ], function( i, dir ) { 11844 if ( $.ui.position[ collision[ i ] ] ) { 11845 $.ui.position[ collision[ i ] ][ dir ]( position, { 11846 targetWidth: targetWidth, 11847 targetHeight: targetHeight, 11848 elemWidth: elemWidth, 11849 elemHeight: elemHeight, 11850 collisionPosition: collisionPosition, 11851 collisionWidth: collisionWidth, 11852 collisionHeight: collisionHeight, 11853 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], 11854 my: options.my, 11855 at: options.at, 11856 within: within, 11857 elem: elem 11858 } ); 11859 } 11860 } ); 11861 11862 if ( options.using ) { 11863 11864 // Adds feedback as second argument to using callback, if present 11865 using = function( props ) { 11866 var left = targetOffset.left - position.left, 11867 right = left + targetWidth - elemWidth, 11868 top = targetOffset.top - position.top, 11869 bottom = top + targetHeight - elemHeight, 11870 feedback = { 11871 target: { 11872 element: target, 11873 left: targetOffset.left, 11874 top: targetOffset.top, 11875 width: targetWidth, 11876 height: targetHeight 11877 }, 11878 element: { 11879 element: elem, 11880 left: position.left, 11881 top: position.top, 11882 width: elemWidth, 11883 height: elemHeight 11884 }, 11885 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", 11886 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" 11887 }; 11888 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { 11889 feedback.horizontal = "center"; 11890 } 11891 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { 11892 feedback.vertical = "middle"; 11893 } 11894 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { 11895 feedback.important = "horizontal"; 11896 } else { 11897 feedback.important = "vertical"; 11898 } 11899 options.using.call( this, props, feedback ); 11900 }; 11901 } 11902 11903 elem.offset( $.extend( position, { using: using } ) ); 11904 } ); 11905}; 11906 11907$.ui.position = { 11908 fit: { 11909 left: function( position, data ) { 11910 var within = data.within, 11911 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, 11912 outerWidth = within.width, 11913 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 11914 overLeft = withinOffset - collisionPosLeft, 11915 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, 11916 newOverRight; 11917 11918 // Element is wider than within 11919 if ( data.collisionWidth > outerWidth ) { 11920 11921 // Element is initially over the left side of within 11922 if ( overLeft > 0 && overRight <= 0 ) { 11923 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - 11924 withinOffset; 11925 position.left += overLeft - newOverRight; 11926 11927 // Element is initially over right side of within 11928 } else if ( overRight > 0 && overLeft <= 0 ) { 11929 position.left = withinOffset; 11930 11931 // Element is initially over both left and right sides of within 11932 } else { 11933 if ( overLeft > overRight ) { 11934 position.left = withinOffset + outerWidth - data.collisionWidth; 11935 } else { 11936 position.left = withinOffset; 11937 } 11938 } 11939 11940 // Too far left -> align with left edge 11941 } else if ( overLeft > 0 ) { 11942 position.left += overLeft; 11943 11944 // Too far right -> align with right edge 11945 } else if ( overRight > 0 ) { 11946 position.left -= overRight; 11947 11948 // Adjust based on position and margin 11949 } else { 11950 position.left = max( position.left - collisionPosLeft, position.left ); 11951 } 11952 }, 11953 top: function( position, data ) { 11954 var within = data.within, 11955 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, 11956 outerHeight = data.within.height, 11957 collisionPosTop = position.top - data.collisionPosition.marginTop, 11958 overTop = withinOffset - collisionPosTop, 11959 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, 11960 newOverBottom; 11961 11962 // Element is taller than within 11963 if ( data.collisionHeight > outerHeight ) { 11964 11965 // Element is initially over the top of within 11966 if ( overTop > 0 && overBottom <= 0 ) { 11967 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - 11968 withinOffset; 11969 position.top += overTop - newOverBottom; 11970 11971 // Element is initially over bottom of within 11972 } else if ( overBottom > 0 && overTop <= 0 ) { 11973 position.top = withinOffset; 11974 11975 // Element is initially over both top and bottom of within 11976 } else { 11977 if ( overTop > overBottom ) { 11978 position.top = withinOffset + outerHeight - data.collisionHeight; 11979 } else { 11980 position.top = withinOffset; 11981 } 11982 } 11983 11984 // Too far up -> align with top 11985 } else if ( overTop > 0 ) { 11986 position.top += overTop; 11987 11988 // Too far down -> align with bottom edge 11989 } else if ( overBottom > 0 ) { 11990 position.top -= overBottom; 11991 11992 // Adjust based on position and margin 11993 } else { 11994 position.top = max( position.top - collisionPosTop, position.top ); 11995 } 11996 } 11997 }, 11998 flip: { 11999 left: function( position, data ) { 12000 var within = data.within, 12001 withinOffset = within.offset.left + within.scrollLeft, 12002 outerWidth = within.width, 12003 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, 12004 collisionPosLeft = position.left - data.collisionPosition.marginLeft, 12005 overLeft = collisionPosLeft - offsetLeft, 12006 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, 12007 myOffset = data.my[ 0 ] === "left" ? 12008 -data.elemWidth : 12009 data.my[ 0 ] === "right" ? 12010 data.elemWidth : 12011 0, 12012 atOffset = data.at[ 0 ] === "left" ? 12013 data.targetWidth : 12014 data.at[ 0 ] === "right" ? 12015 -data.targetWidth : 12016 0, 12017 offset = -2 * data.offset[ 0 ], 12018 newOverRight, 12019 newOverLeft; 12020 12021 if ( overLeft < 0 ) { 12022 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - 12023 outerWidth - withinOffset; 12024 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { 12025 position.left += myOffset + atOffset + offset; 12026 } 12027 } else if ( overRight > 0 ) { 12028 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + 12029 atOffset + offset - offsetLeft; 12030 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { 12031 position.left += myOffset + atOffset + offset; 12032 } 12033 } 12034 }, 12035 top: function( position, data ) { 12036 var within = data.within, 12037 withinOffset = within.offset.top + within.scrollTop, 12038 outerHeight = within.height, 12039 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, 12040 collisionPosTop = position.top - data.collisionPosition.marginTop, 12041 overTop = collisionPosTop - offsetTop, 12042 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, 12043 top = data.my[ 1 ] === "top", 12044 myOffset = top ? 12045 -data.elemHeight : 12046 data.my[ 1 ] === "bottom" ? 12047 data.elemHeight : 12048 0, 12049 atOffset = data.at[ 1 ] === "top" ? 12050 data.targetHeight : 12051 data.at[ 1 ] === "bottom" ? 12052 -data.targetHeight : 12053 0, 12054 offset = -2 * data.offset[ 1 ], 12055 newOverTop, 12056 newOverBottom; 12057 if ( overTop < 0 ) { 12058 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - 12059 outerHeight - withinOffset; 12060 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { 12061 position.top += myOffset + atOffset + offset; 12062 } 12063 } else if ( overBottom > 0 ) { 12064 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + 12065 offset - offsetTop; 12066 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { 12067 position.top += myOffset + atOffset + offset; 12068 } 12069 } 12070 } 12071 }, 12072 flipfit: { 12073 left: function() { 12074 $.ui.position.flip.left.apply( this, arguments ); 12075 $.ui.position.fit.left.apply( this, arguments ); 12076 }, 12077 top: function() { 12078 $.ui.position.flip.top.apply( this, arguments ); 12079 $.ui.position.fit.top.apply( this, arguments ); 12080 } 12081 } 12082}; 12083 12084} )(); 12085 12086var position = $.ui.position; 12087 12088 12089/*! 12090 * jQuery UI :data 1.13.2 12091 * http://jqueryui.com
vendor: 29,600 bytes, lines 12092-13245
12092 * 12093 * Copyright jQuery Foundation and other contributors 12094 * Released under the MIT license. 12095 * http://jquery.org/license 12096 */ 12097 12098//>>label: :data Selector 12099//>>group: Core 12100//>>description: Selects elements which have data stored under the specified key. 12101//>>docs: http://api.jqueryui.com/data-selector/ 12102 12103 12104var data = $.extend( $.expr.pseudos, { 12105 data: $.expr.createPseudo ? 12106 $.expr.createPseudo( function( dataName ) { 12107 return function( elem ) { 12108 return !!$.data( elem, dataName ); 12109 }; 12110 } ) : 12111 12112 // Support: jQuery <1.8 12113 function( elem, i, match ) { 12114 return !!$.data( elem, match[ 3 ] ); 12115 } 12116} ); 12117 12118/*! 12119 * jQuery UI Disable Selection 1.13.2 12120 * http://jqueryui.com 12121 * 12122 * Copyright jQuery Foundation and other contributors 12123 * Released under the MIT license. 12124 * http://jquery.org/license 12125 */ 12126 12127//>>label: disableSelection 12128//>>group: Core 12129//>>description: Disable selection of text content within the set of matched elements. 12130//>>docs: http://api.jqueryui.com/disableSelection/ 12131 12132// This file is deprecated 12133 12134var disableSelection = $.fn.extend( { 12135 disableSelection: ( function() { 12136 var eventType = "onselectstart" in document.createElement( "div" ) ? 12137 "selectstart" : 12138 "mousedown"; 12139 12140 return function() { 12141 return this.on( eventType + ".ui-disableSelection", function( event ) { 12142 event.preventDefault(); 12143 } ); 12144 }; 12145 } )(), 12146 12147 enableSelection: function() { 12148 return this.off( ".ui-disableSelection" ); 12149 } 12150} ); 12151 12152 12153 12154// Create a local jQuery because jQuery Color relies on it and the 12155// global may not exist with AMD and a custom build (#10199). 12156// This module is a noop if used as a regular AMD module. 12157// eslint-disable-next-line no-unused-vars 12158var jQuery = $; 12159 12160 12161/*! 12162 * jQuery Color Animations v2.2.0 12163 * https://github.com/jquery/jquery-color 12164 * 12165 * Copyright OpenJS Foundation and other contributors 12166 * Released under the MIT license. 12167 * http://jquery.org/license 12168 * 12169 * Date: Sun May 10 09:02:36 2020 +0200 12170 */ 12171 12172 12173 12174 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + 12175 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", 12176 12177 class2type = {}, 12178 toString = class2type.toString, 12179 12180 // plusequals test for += 100 -= 100 12181 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, 12182 12183 // a set of RE's that can match strings and generate color tuples. 12184 stringParsers = [ { 12185 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12186 parse: function( execResult ) { 12187 return [ 12188 execResult[ 1 ], 12189 execResult[ 2 ], 12190 execResult[ 3 ], 12191 execResult[ 4 ] 12192 ]; 12193 } 12194 }, { 12195 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12196 parse: function( execResult ) { 12197 return [ 12198 execResult[ 1 ] * 2.55, 12199 execResult[ 2 ] * 2.55, 12200 execResult[ 3 ] * 2.55, 12201 execResult[ 4 ] 12202 ]; 12203 } 12204 }, { 12205 12206 // this regex ignores A-F because it's compared against an already lowercased string 12207 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, 12208 parse: function( execResult ) { 12209 return [ 12210 parseInt( execResult[ 1 ], 16 ), 12211 parseInt( execResult[ 2 ], 16 ), 12212 parseInt( execResult[ 3 ], 16 ), 12213 execResult[ 4 ] ? 12214 ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : 12215 1 12216 ]; 12217 } 12218 }, { 12219 12220 // this regex ignores A-F because it's compared against an already lowercased string 12221 re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, 12222 parse: function( execResult ) { 12223 return [ 12224 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), 12225 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), 12226 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), 12227 execResult[ 4 ] ? 12228 ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) 12229 .toFixed( 2 ) : 12230 1 12231 ]; 12232 } 12233 }, { 12234 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, 12235 space: "hsla", 12236 parse: function( execResult ) { 12237 return [ 12238 execResult[ 1 ], 12239 execResult[ 2 ] / 100, 12240 execResult[ 3 ] / 100, 12241 execResult[ 4 ] 12242 ]; 12243 } 12244 } ], 12245 12246 // jQuery.Color( ) 12247 color = jQuery.Color = function( color, green, blue, alpha ) { 12248 return new jQuery.Color.fn.parse( color, green, blue, alpha ); 12249 }, 12250 spaces = { 12251 rgba: { 12252 props: { 12253 red: { 12254 idx: 0, 12255 type: "byte" 12256 }, 12257 green: { 12258 idx: 1, 12259 type: "byte" 12260 }, 12261 blue: { 12262 idx: 2, 12263 type: "byte" 12264 } 12265 } 12266 }, 12267 12268 hsla: { 12269 props: { 12270 hue: { 12271 idx: 0, 12272 type: "degrees" 12273 }, 12274 saturation: { 12275 idx: 1, 12276 type: "percent" 12277 }, 12278 lightness: { 12279 idx: 2, 12280 type: "percent" 12281 } 12282 } 12283 } 12284 }, 12285 propTypes = { 12286 "byte": { 12287 floor: true, 12288 max: 255 12289 }, 12290 "percent": { 12291 max: 1 12292 }, 12293 "degrees": { 12294 mod: 360, 12295 floor: true 12296 } 12297 }, 12298 support = color.support = {}, 12299 12300 // element for support tests 12301 supportElem = jQuery( "<p>" )[ 0 ], 12302 12303 // colors = jQuery.Color.names 12304 colors, 12305 12306 // local aliases of functions called often 12307 each = jQuery.each; 12308 12309// determine rgba support immediately 12310supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; 12311support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; 12312 12313// define cache name and alpha properties 12314// for rgba and hsla spaces 12315each( spaces, function( spaceName, space ) { 12316 space.cache = "_" + spaceName; 12317 space.props.alpha = { 12318 idx: 3, 12319 type: "percent", 12320 def: 1 12321 }; 12322} ); 12323 12324// Populate the class2type map 12325jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 12326 function( _i, name ) { 12327 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 12328 } ); 12329 12330function getType( obj ) { 12331 if ( obj == null ) { 12332 return obj + ""; 12333 } 12334 12335 return typeof obj === "object" ? 12336 class2type[ toString.call( obj ) ] || "object" : 12337 typeof obj; 12338} 12339 12340function clamp( value, prop, allowEmpty ) { 12341 var type = propTypes[ prop.type ] || {}; 12342 12343 if ( value == null ) { 12344 return ( allowEmpty || !prop.def ) ? null : prop.def; 12345 } 12346 12347 // ~~ is an short way of doing floor for positive numbers 12348 value = type.floor ? ~~value : parseFloat( value ); 12349 12350 // IE will pass in empty strings as value for alpha, 12351 // which will hit this case 12352 if ( isNaN( value ) ) { 12353 return prop.def; 12354 } 12355 12356 if ( type.mod ) { 12357 12358 // we add mod before modding to make sure that negatives values 12359 // get converted properly: -10 -> 350 12360 return ( value + type.mod ) % type.mod; 12361 } 12362 12363 // for now all property types without mod have min and max 12364 return Math.min( type.max, Math.max( 0, value ) ); 12365} 12366 12367function stringParse( string ) { 12368 var inst = color(), 12369 rgba = inst._rgba = []; 12370 12371 string = string.toLowerCase(); 12372 12373 each( stringParsers, function( _i, parser ) { 12374 var parsed, 12375 match = parser.re.exec( string ), 12376 values = match && parser.parse( match ), 12377 spaceName = parser.space || "rgba"; 12378 12379 if ( values ) { 12380 parsed = inst[ spaceName ]( values ); 12381 12382 // if this was an rgba parse the assignment might happen twice 12383 // oh well.... 12384 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; 12385 rgba = inst._rgba = parsed._rgba; 12386 12387 // exit each( stringParsers ) here because we matched 12388 return false; 12389 } 12390 } ); 12391 12392 // Found a stringParser that handled it 12393 if ( rgba.length ) { 12394 12395 // if this came from a parsed string, force "transparent" when alpha is 0 12396 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) 12397 if ( rgba.join() === "0,0,0,0" ) { 12398 jQuery.extend( rgba, colors.transparent ); 12399 } 12400 return inst; 12401 } 12402 12403 // named colors 12404 return colors[ string ]; 12405} 12406 12407color.fn = jQuery.extend( color.prototype, { 12408 parse: function( red, green, blue, alpha ) { 12409 if ( red === undefined ) { 12410 this._rgba = [ null, null, null, null ]; 12411 return this; 12412 } 12413 if ( red.jquery || red.nodeType ) { 12414 red = jQuery( red ).css( green ); 12415 green = undefined; 12416 } 12417 12418 var inst = this, 12419 type = getType( red ), 12420 rgba = this._rgba = []; 12421 12422 // more than 1 argument specified - assume ( red, green, blue, alpha ) 12423 if ( green !== undefined ) { 12424 red = [ red, green, blue, alpha ]; 12425 type = "array"; 12426 } 12427 12428 if ( type === "string" ) { 12429 return this.parse( stringParse( red ) || colors._default ); 12430 } 12431 12432 if ( type === "array" ) { 12433 each( spaces.rgba.props, function( _key, prop ) { 12434 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); 12435 } ); 12436 return this; 12437 } 12438 12439 if ( type === "object" ) { 12440 if ( red instanceof color ) { 12441 each( spaces, function( _spaceName, space ) { 12442 if ( red[ space.cache ] ) { 12443 inst[ space.cache ] = red[ space.cache ].slice(); 12444 } 12445 } ); 12446 } else { 12447 each( spaces, function( _spaceName, space ) { 12448 var cache = space.cache; 12449 each( space.props, function( key, prop ) { 12450 12451 // if the cache doesn't exist, and we know how to convert 12452 if ( !inst[ cache ] && space.to ) { 12453 12454 // if the value was null, we don't need to copy it 12455 // if the key was alpha, we don't need to copy it either 12456 if ( key === "alpha" || red[ key ] == null ) { 12457 return; 12458 } 12459 inst[ cache ] = space.to( inst._rgba ); 12460 } 12461 12462 // this is the only case where we allow nulls for ALL properties. 12463 // call clamp with alwaysAllowEmpty 12464 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); 12465 } ); 12466 12467 // everything defined but alpha? 12468 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { 12469 12470 // use the default of 1 12471 if ( inst[ cache ][ 3 ] == null ) { 12472 inst[ cache ][ 3 ] = 1; 12473 } 12474 12475 if ( space.from ) { 12476 inst._rgba = space.from( inst[ cache ] ); 12477 } 12478 } 12479 } ); 12480 } 12481 return this; 12482 } 12483 }, 12484 is: function( compare ) { 12485 var is = color( compare ), 12486 same = true, 12487 inst = this; 12488 12489 each( spaces, function( _, space ) { 12490 var localCache, 12491 isCache = is[ space.cache ]; 12492 if ( isCache ) { 12493 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; 12494 each( space.props, function( _, prop ) { 12495 if ( isCache[ prop.idx ] != null ) { 12496 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); 12497 return same; 12498 } 12499 } ); 12500 } 12501 return same; 12502 } ); 12503 return same; 12504 }, 12505 _space: function() { 12506 var used = [], 12507 inst = this; 12508 each( spaces, function( spaceName, space ) { 12509 if ( inst[ space.cache ] ) { 12510 used.push( spaceName ); 12511 } 12512 } ); 12513 return used.pop(); 12514 }, 12515 transition: function( other, distance ) { 12516 var end = color( other ), 12517 spaceName = end._space(), 12518 space = spaces[ spaceName ], 12519 startColor = this.alpha() === 0 ? color( "transparent" ) : this, 12520 start = startColor[ space.cache ] || space.to( startColor._rgba ), 12521 result = start.slice(); 12522 12523 end = end[ space.cache ]; 12524 each( space.props, function( _key, prop ) { 12525 var index = prop.idx, 12526 startValue = start[ index ], 12527 endValue = end[ index ], 12528 type = propTypes[ prop.type ] || {}; 12529 12530 // if null, don't override start value 12531 if ( endValue === null ) { 12532 return; 12533 } 12534 12535 // if null - use end 12536 if ( startValue === null ) { 12537 result[ index ] = endValue; 12538 } else { 12539 if ( type.mod ) { 12540 if ( endValue - startValue > type.mod / 2 ) { 12541 startValue += type.mod; 12542 } else if ( startValue - endValue > type.mod / 2 ) { 12543 startValue -= type.mod; 12544 } 12545 } 12546 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); 12547 } 12548 } ); 12549 return this[ spaceName ]( result ); 12550 }, 12551 blend: function( opaque ) { 12552 12553 // if we are already opaque - return ourself 12554 if ( this._rgba[ 3 ] === 1 ) { 12555 return this; 12556 } 12557 12558 var rgb = this._rgba.slice(), 12559 a = rgb.pop(), 12560 blend = color( opaque )._rgba; 12561 12562 return color( jQuery.map( rgb, function( v, i ) { 12563 return ( 1 - a ) * blend[ i ] + a * v; 12564 } ) ); 12565 }, 12566 toRgbaString: function() { 12567 var prefix = "rgba(", 12568 rgba = jQuery.map( this._rgba, function( v, i ) { 12569 if ( v != null ) { 12570 return v; 12571 } 12572 return i > 2 ? 1 : 0; 12573 } ); 12574 12575 if ( rgba[ 3 ] === 1 ) { 12576 rgba.pop(); 12577 prefix = "rgb("; 12578 } 12579 12580 return prefix + rgba.join() + ")"; 12581 }, 12582 toHslaString: function() { 12583 var prefix = "hsla(", 12584 hsla = jQuery.map( this.hsla(), function( v, i ) { 12585 if ( v == null ) { 12586 v = i > 2 ? 1 : 0; 12587 } 12588 12589 // catch 1 and 2 12590 if ( i && i < 3 ) { 12591 v = Math.round( v * 100 ) + "%"; 12592 } 12593 return v; 12594 } ); 12595 12596 if ( hsla[ 3 ] === 1 ) { 12597 hsla.pop(); 12598 prefix = "hsl("; 12599 } 12600 return prefix + hsla.join() + ")"; 12601 }, 12602 toHexString: function( includeAlpha ) { 12603 var rgba = this._rgba.slice(), 12604 alpha = rgba.pop(); 12605 12606 if ( includeAlpha ) { 12607 rgba.push( ~~( alpha * 255 ) ); 12608 } 12609 12610 return "#" + jQuery.map( rgba, function( v ) { 12611 12612 // default to 0 when nulls exist 12613 v = ( v || 0 ).toString( 16 ); 12614 return v.length === 1 ? "0" + v : v; 12615 } ).join( "" ); 12616 }, 12617 toString: function() { 12618 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); 12619 } 12620} ); 12621color.fn.parse.prototype = color.fn; 12622 12623// hsla conversions adapted from: 12624// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 12625 12626function hue2rgb( p, q, h ) { 12627 h = ( h + 1 ) % 1; 12628 if ( h * 6 < 1 ) { 12629 return p + ( q - p ) * h * 6; 12630 } 12631 if ( h * 2 < 1 ) { 12632 return q; 12633 } 12634 if ( h * 3 < 2 ) { 12635 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; 12636 } 12637 return p; 12638} 12639 12640spaces.hsla.to = function( rgba ) { 12641 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { 12642 return [ null, null, null, rgba[ 3 ] ]; 12643 } 12644 var r = rgba[ 0 ] / 255, 12645 g = rgba[ 1 ] / 255, 12646 b = rgba[ 2 ] / 255, 12647 a = rgba[ 3 ], 12648 max = Math.max( r, g, b ), 12649 min = Math.min( r, g, b ), 12650 diff = max - min, 12651 add = max + min, 12652 l = add * 0.5, 12653 h, s; 12654 12655 if ( min === max ) { 12656 h = 0; 12657 } else if ( r === max ) { 12658 h = ( 60 * ( g - b ) / diff ) + 360; 12659 } else if ( g === max ) { 12660 h = ( 60 * ( b - r ) / diff ) + 120; 12661 } else { 12662 h = ( 60 * ( r - g ) / diff ) + 240; 12663 } 12664 12665 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% 12666 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) 12667 if ( diff === 0 ) { 12668 s = 0; 12669 } else if ( l <= 0.5 ) { 12670 s = diff / add; 12671 } else { 12672 s = diff / ( 2 - add ); 12673 } 12674 return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; 12675}; 12676 12677spaces.hsla.from = function( hsla ) { 12678 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { 12679 return [ null, null, null, hsla[ 3 ] ]; 12680 } 12681 var h = hsla[ 0 ] / 360, 12682 s = hsla[ 1 ], 12683 l = hsla[ 2 ], 12684 a = hsla[ 3 ], 12685 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, 12686 p = 2 * l - q; 12687 12688 return [ 12689 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), 12690 Math.round( hue2rgb( p, q, h ) * 255 ), 12691 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), 12692 a 12693 ]; 12694}; 12695 12696 12697each( spaces, function( spaceName, space ) { 12698 var props = space.props, 12699 cache = space.cache, 12700 to = space.to, 12701 from = space.from; 12702 12703 // makes rgba() and hsla() 12704 color.fn[ spaceName ] = function( value ) { 12705 12706 // generate a cache for this space if it doesn't exist 12707 if ( to && !this[ cache ] ) { 12708 this[ cache ] = to( this._rgba ); 12709 } 12710 if ( value === undefined ) { 12711 return this[ cache ].slice(); 12712 } 12713 12714 var ret, 12715 type = getType( value ), 12716 arr = ( type === "array" || type === "object" ) ? value : arguments, 12717 local = this[ cache ].slice(); 12718 12719 each( props, function( key, prop ) { 12720 var val = arr[ type === "object" ? key : prop.idx ]; 12721 if ( val == null ) { 12722 val = local[ prop.idx ]; 12723 } 12724 local[ prop.idx ] = clamp( val, prop ); 12725 } ); 12726 12727 if ( from ) { 12728 ret = color( from( local ) ); 12729 ret[ cache ] = local; 12730 return ret; 12731 } else { 12732 return color( local ); 12733 } 12734 }; 12735 12736 // makes red() green() blue() alpha() hue() saturation() lightness() 12737 each( props, function( key, prop ) { 12738 12739 // alpha is included in more than one space 12740 if ( color.fn[ key ] ) { 12741 return; 12742 } 12743 color.fn[ key ] = function( value ) { 12744 var local, cur, match, fn, 12745 vtype = getType( value ); 12746 12747 if ( key === "alpha" ) { 12748 fn = this._hsla ? "hsla" : "rgba"; 12749 } else { 12750 fn = spaceName; 12751 } 12752 local = this[ fn ](); 12753 cur = local[ prop.idx ]; 12754 12755 if ( vtype === "undefined" ) { 12756 return cur; 12757 } 12758 12759 if ( vtype === "function" ) { 12760 value = value.call( this, cur ); 12761 vtype = getType( value ); 12762 } 12763 if ( value == null && prop.empty ) { 12764 return this; 12765 } 12766 if ( vtype === "string" ) { 12767 match = rplusequals.exec( value ); 12768 if ( match ) { 12769 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); 12770 } 12771 } 12772 local[ prop.idx ] = value; 12773 return this[ fn ]( local ); 12774 }; 12775 } ); 12776} ); 12777 12778// add cssHook and .fx.step function for each named hook. 12779// accept a space separated string of properties 12780color.hook = function( hook ) { 12781 var hooks = hook.split( " " ); 12782 each( hooks, function( _i, hook ) { 12783 jQuery.cssHooks[ hook ] = { 12784 set: function( elem, value ) { 12785 var parsed, curElem, 12786 backgroundColor = ""; 12787 12788 if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { 12789 value = color( parsed || value ); 12790 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { 12791 curElem = hook === "backgroundColor" ? elem.parentNode : elem; 12792 while ( 12793 ( backgroundColor === "" || backgroundColor === "transparent" ) && 12794 curElem && curElem.style 12795 ) { 12796 try { 12797 backgroundColor = jQuery.css( curElem, "backgroundColor" ); 12798 curElem = curElem.parentNode; 12799 } catch ( e ) { 12800 } 12801 } 12802 12803 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? 12804 backgroundColor : 12805 "_default" ); 12806 } 12807 12808 value = value.toRgbaString(); 12809 } 12810 try { 12811 elem.style[ hook ] = value; 12812 } catch ( e ) { 12813 12814 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' 12815 } 12816 } 12817 }; 12818 jQuery.fx.step[ hook ] = function( fx ) { 12819 if ( !fx.colorInit ) { 12820 fx.start = color( fx.elem, hook ); 12821 fx.end = color( fx.end ); 12822 fx.colorInit = true; 12823 } 12824 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); 12825 }; 12826 } ); 12827 12828}; 12829 12830color.hook( stepHooks ); 12831 12832jQuery.cssHooks.borderColor = { 12833 expand: function( value ) { 12834 var expanded = {}; 12835 12836 each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { 12837 expanded[ "border" + part + "Color" ] = value; 12838 } ); 12839 return expanded; 12840 } 12841}; 12842 12843// Basic color names only. 12844// Usage of any of the other color names requires adding yourself or including 12845// jquery.color.svg-names.js. 12846colors = jQuery.Color.names = { 12847 12848 // 4.1. Basic color keywords 12849 aqua: "#00ffff", 12850 black: "#000000", 12851 blue: "#0000ff", 12852 fuchsia: "#ff00ff", 12853 gray: "#808080", 12854 green: "#008000", 12855 lime: "#00ff00", 12856 maroon: "#800000", 12857 navy: "#000080", 12858 olive: "#808000", 12859 purple: "#800080", 12860 red: "#ff0000", 12861 silver: "#c0c0c0", 12862 teal: "#008080", 12863 white: "#ffffff", 12864 yellow: "#ffff00", 12865 12866 // 4.2.3. "transparent" color keyword 12867 transparent: [ null, null, null, 0 ], 12868 12869 _default: "#ffffff" 12870}; 12871 12872 12873/*! 12874 * jQuery UI Effects 1.13.2 12875 * http://jqueryui.com 12876 * 12877 * Copyright jQuery Foundation and other contributors 12878 * Released under the MIT license. 12879 * http://jquery.org/license 12880 */ 12881 12882//>>label: Effects Core 12883//>>group: Effects 12884/* eslint-disable max-len */ 12885//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. 12886/* eslint-enable max-len */ 12887//>>docs: http://api.jqueryui.com/category/effects-core/ 12888//>>demos: http://jqueryui.com/effect/ 12889 12890 12891var dataSpace = "ui-effects-", 12892 dataSpaceStyle = "ui-effects-style", 12893 dataSpaceAnimated = "ui-effects-animated"; 12894 12895$.effects = { 12896 effect: {} 12897}; 12898 12899/******************************************************************************/ 12900/****************************** CLASS ANIMATIONS ******************************/ 12901/******************************************************************************/ 12902( function() { 12903 12904var classAnimationActions = [ "add", "remove", "toggle" ], 12905 shorthandStyles = { 12906 border: 1, 12907 borderBottom: 1, 12908 borderColor: 1, 12909 borderLeft: 1, 12910 borderRight: 1, 12911 borderTop: 1, 12912 borderWidth: 1, 12913 margin: 1, 12914 padding: 1 12915 }; 12916 12917$.each( 12918 [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], 12919 function( _, prop ) { 12920 $.fx.step[ prop ] = function( fx ) { 12921 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { 12922 jQuery.style( fx.elem, prop, fx.end ); 12923 fx.setAttr = true; 12924 } 12925 }; 12926 } 12927); 12928 12929function camelCase( string ) { 12930 return string.replace( /-([\da-z])/gi, function( all, letter ) { 12931 return letter.toUpperCase(); 12932 } ); 12933} 12934 12935function getElementStyles( elem ) { 12936 var key, len, 12937 style = elem.ownerDocument.defaultView ? 12938 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : 12939 elem.currentStyle, 12940 styles = {}; 12941 12942 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { 12943 len = style.length; 12944 while ( len-- ) { 12945 key = style[ len ]; 12946 if ( typeof style[ key ] === "string" ) { 12947 styles[ camelCase( key ) ] = style[ key ]; 12948 } 12949 } 12950 12951 // Support: Opera, IE <9 12952 } else { 12953 for ( key in style ) { 12954 if ( typeof style[ key ] === "string" ) { 12955 styles[ key ] = style[ key ]; 12956 } 12957 } 12958 } 12959 12960 return styles; 12961} 12962 12963function styleDifference( oldStyle, newStyle ) { 12964 var diff = {}, 12965 name, value; 12966 12967 for ( name in newStyle ) { 12968 value = newStyle[ name ]; 12969 if ( oldStyle[ name ] !== value ) { 12970 if ( !shorthandStyles[ name ] ) { 12971 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { 12972 diff[ name ] = value; 12973 } 12974 } 12975 } 12976 } 12977 12978 return diff; 12979} 12980 12981// Support: jQuery <1.8 12982if ( !$.fn.addBack ) { 12983 $.fn.addBack = function( selector ) { 12984 return this.add( selector == null ? 12985 this.prevObject : this.prevObject.filter( selector ) 12986 ); 12987 }; 12988} 12989 12990$.effects.animateClass = function( value, duration, easing, callback ) { 12991 var o = $.speed( duration, easing, callback ); 12992 12993 return this.queue( function() { 12994 var animated = $( this ), 12995 baseClass = animated.attr( "class" ) || "", 12996 applyClassChange, 12997 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; 12998 12999 // Map the animated objects to store the original styles. 13000 allAnimations = allAnimations.map( function() { 13001 var el = $( this ); 13002 return { 13003 el: el, 13004 start: getElementStyles( this ) 13005 }; 13006 } ); 13007 13008 // Apply class change 13009 applyClassChange = function() { 13010 $.each( classAnimationActions, function( i, action ) { 13011 if ( value[ action ] ) { 13012 animated[ action + "Class" ]( value[ action ] ); 13013 } 13014 } ); 13015 }; 13016 applyClassChange(); 13017 13018 // Map all animated objects again - calculate new styles and diff 13019 allAnimations = allAnimations.map( function() { 13020 this.end = getElementStyles( this.el[ 0 ] ); 13021 this.diff = styleDifference( this.start, this.end ); 13022 return this; 13023 } ); 13024 13025 // Apply original class 13026 animated.attr( "class", baseClass ); 13027 13028 // Map all animated objects again - this time collecting a promise 13029 allAnimations = allAnimations.map( function() { 13030 var styleInfo = this, 13031 dfd = $.Deferred(), 13032 opts = $.extend( {}, o, { 13033 queue: false, 13034 complete: function() { 13035 dfd.resolve( styleInfo ); 13036 } 13037 } ); 13038 13039 this.el.animate( this.diff, opts ); 13040 return dfd.promise(); 13041 } ); 13042 13043 // Once all animations have completed: 13044 $.when.apply( $, allAnimations.get() ).done( function() { 13045 13046 // Set the final class 13047 applyClassChange(); 13048 13049 // For each animated element, 13050 // clear all css properties that were animated 13051 $.each( arguments, function() { 13052 var el = this.el; 13053 $.each( this.diff, function( key ) { 13054 el.css( key, "" ); 13055 } ); 13056 } ); 13057 13058 // This is guarnteed to be there if you use jQuery.speed() 13059 // it also handles dequeuing the next anim... 13060 o.complete.call( animated[ 0 ] ); 13061 } ); 13062 } ); 13063}; 13064 13065$.fn.extend( { 13066 addClass: ( function( orig ) { 13067 return function( classNames, speed, easing, callback ) { 13068 return speed ? 13069 $.effects.animateClass.call( this, 13070 { add: classNames }, speed, easing, callback ) : 13071 orig.apply( this, arguments ); 13072 }; 13073 } )( $.fn.addClass ), 13074 13075 removeClass: ( function( orig ) { 13076 return function( classNames, speed, easing, callback ) { 13077 return arguments.length > 1 ? 13078 $.effects.animateClass.call( this, 13079 { remove: classNames }, speed, easing, callback ) : 13080 orig.apply( this, arguments ); 13081 }; 13082 } )( $.fn.removeClass ), 13083 13084 toggleClass: ( function( orig ) { 13085 return function( classNames, force, speed, easing, callback ) { 13086 if ( typeof force === "boolean" || force === undefined ) { 13087 if ( !speed ) { 13088 13089 // Without speed parameter 13090 return orig.apply( this, arguments ); 13091 } else { 13092 return $.effects.animateClass.call( this, 13093 ( force ? { add: classNames } : { remove: classNames } ), 13094 speed, easing, callback ); 13095 } 13096 } else { 13097 13098 // Without force parameter 13099 return $.effects.animateClass.call( this, 13100 { toggle: classNames }, force, speed, easing ); 13101 } 13102 }; 13103 } )( $.fn.toggleClass ), 13104 13105 switchClass: function( remove, add, speed, easing, callback ) { 13106 return $.effects.animateClass.call( this, { 13107 add: add, 13108 remove: remove 13109 }, speed, easing, callback ); 13110 } 13111} ); 13112 13113} )(); 13114 13115/******************************************************************************/ 13116/*********************************** EFFECTS **********************************/ 13117/******************************************************************************/ 13118 13119( function() { 13120 13121if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { 13122 $.expr.pseudos.animated = ( function( orig ) { 13123 return function( elem ) { 13124 return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); 13125 }; 13126 } )( $.expr.pseudos.animated ); 13127} 13128 13129if ( $.uiBackCompat !== false ) { 13130 $.extend( $.effects, { 13131 13132 // Saves a set of properties in a data storage 13133 save: function( element, set ) { 13134 var i = 0, length = set.length; 13135 for ( ; i < length; i++ ) { 13136 if ( set[ i ] !== null ) { 13137 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); 13138 } 13139 } 13140 }, 13141 13142 // Restores a set of previously saved properties from a data storage 13143 restore: function( element, set ) { 13144 var val, i = 0, length = set.length; 13145 for ( ; i < length; i++ ) { 13146 if ( set[ i ] !== null ) { 13147 val = element.data( dataSpace + set[ i ] ); 13148 element.css( set[ i ], val ); 13149 } 13150 } 13151 }, 13152 13153 setMode: function( el, mode ) { 13154 if ( mode === "toggle" ) { 13155 mode = el.is( ":hidden" ) ? "show" : "hide"; 13156 } 13157 return mode; 13158 }, 13159 13160 // Wraps the element around a wrapper that copies position properties 13161 createWrapper: function( element ) { 13162 13163 // If the element is already wrapped, return it 13164 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13165 return element.parent(); 13166 } 13167 13168 // Wrap the element 13169 var props = { 13170 width: element.outerWidth( true ), 13171 height: element.outerHeight( true ), 13172 "float": element.css( "float" ) 13173 }, 13174 wrapper = $( "<div></div>" ) 13175 .addClass( "ui-effects-wrapper" ) 13176 .css( { 13177 fontSize: "100%", 13178 background: "transparent", 13179 border: "none", 13180 margin: 0, 13181 padding: 0 13182 } ), 13183 13184 // Store the size in case width/height are defined in % - Fixes #5245 13185 size = { 13186 width: element.width(), 13187 height: element.height() 13188 }, 13189 active = document.activeElement; 13190 13191 // Support: Firefox 13192 // Firefox incorrectly exposes anonymous content 13193 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 13194 try { 13195 // eslint-disable-next-line no-unused-expressions 13196 active.id; 13197 } catch ( e ) { 13198 active = document.body; 13199 } 13200 13201 element.wrap( wrapper ); 13202 13203 // Fixes #7595 - Elements lose focus when wrapped. 13204 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13205 $( active ).trigger( "focus" ); 13206 } 13207 13208 // Hotfix for jQuery 1.4 since some change in wrap() seems to actually 13209 // lose the reference to the wrapped element 13210 wrapper = element.parent(); 13211 13212 // Transfer positioning properties to the wrapper 13213 if ( element.css( "position" ) === "static" ) { 13214 wrapper.css( { position: "relative" } ); 13215 element.css( { position: "relative" } ); 13216 } else { 13217 $.extend( props, { 13218 position: element.css( "position" ), 13219 zIndex: element.css( "z-index" ) 13220 } ); 13221 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { 13222 props[ pos ] = element.css( pos ); 13223 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { 13224 props[ pos ] = "auto"; 13225 } 13226 } ); 13227 element.css( { 13228 position: "relative", 13229 top: 0, 13230 left: 0, 13231 right: "auto", 13232 bottom: "auto" 13233 } ); 13234 } 13235 element.css( size ); 13236 13237 return wrapper.css( props ).show(); 13238 }, 13239 13240 removeWrapper: function( element ) { 13241 var active = document.activeElement; 13242 13243 if ( element.parent().is( ".ui-effects-wrapper" ) ) { 13244 element.parent().replaceWith( element ); 13245
vendor: 6,832 bytes, lines 13246-13526
13246 // Fixes #7595 - Elements lose focus when wrapped. 13247 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { 13248 $( active ).trigger( "focus" ); 13249 } 13250 } 13251 13252 return element; 13253 } 13254 } ); 13255} 13256 13257$.extend( $.effects, { 13258 version: "1.13.2", 13259 13260 define: function( name, mode, effect ) { 13261 if ( !effect ) { 13262 effect = mode; 13263 mode = "effect"; 13264 } 13265 13266 $.effects.effect[ name ] = effect; 13267 $.effects.effect[ name ].mode = mode; 13268 13269 return effect; 13270 }, 13271 13272 scaledDimensions: function( element, percent, direction ) { 13273 if ( percent === 0 ) { 13274 return { 13275 height: 0, 13276 width: 0, 13277 outerHeight: 0, 13278 outerWidth: 0 13279 }; 13280 } 13281 13282 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, 13283 y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; 13284 13285 return { 13286 height: element.height() * y, 13287 width: element.width() * x, 13288 outerHeight: element.outerHeight() * y, 13289 outerWidth: element.outerWidth() * x 13290 }; 13291 13292 }, 13293 13294 clipToBox: function( animation ) { 13295 return { 13296 width: animation.clip.right - animation.clip.left, 13297 height: animation.clip.bottom - animation.clip.top, 13298 left: animation.clip.left, 13299 top: animation.clip.top 13300 }; 13301 }, 13302 13303 // Injects recently queued functions to be first in line (after "inprogress") 13304 unshift: function( element, queueLength, count ) { 13305 var queue = element.queue(); 13306 13307 if ( queueLength > 1 ) { 13308 queue.splice.apply( queue, 13309 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); 13310 } 13311 element.dequeue(); 13312 }, 13313 13314 saveStyle: function( element ) { 13315 element.data( dataSpaceStyle, element[ 0 ].style.cssText ); 13316 }, 13317 13318 restoreStyle: function( element ) { 13319 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; 13320 element.removeData( dataSpaceStyle ); 13321 }, 13322 13323 mode: function( element, mode ) { 13324 var hidden = element.is( ":hidden" ); 13325 13326 if ( mode === "toggle" ) { 13327 mode = hidden ? "show" : "hide"; 13328 } 13329 if ( hidden ? mode === "hide" : mode === "show" ) { 13330 mode = "none"; 13331 } 13332 return mode; 13333 }, 13334 13335 // Translates a [top,left] array into a baseline value 13336 getBaseline: function( origin, original ) { 13337 var y, x; 13338 13339 switch ( origin[ 0 ] ) { 13340 case "top": 13341 y = 0; 13342 break; 13343 case "middle": 13344 y = 0.5; 13345 break; 13346 case "bottom": 13347 y = 1; 13348 break; 13349 default: 13350 y = origin[ 0 ] / original.height; 13351 } 13352 13353 switch ( origin[ 1 ] ) { 13354 case "left": 13355 x = 0; 13356 break; 13357 case "center": 13358 x = 0.5; 13359 break; 13360 case "right": 13361 x = 1; 13362 break; 13363 default: 13364 x = origin[ 1 ] / original.width; 13365 } 13366 13367 return { 13368 x: x, 13369 y: y 13370 }; 13371 }, 13372 13373 // Creates a placeholder element so that the original element can be made absolute 13374 createPlaceholder: function( element ) { 13375 var placeholder, 13376 cssPosition = element.css( "position" ), 13377 position = element.position(); 13378 13379 // Lock in margins first to account for form elements, which 13380 // will change margin if you explicitly set height 13381 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 13382 // Support: Safari 13383 element.css( { 13384 marginTop: element.css( "marginTop" ), 13385 marginBottom: element.css( "marginBottom" ), 13386 marginLeft: element.css( "marginLeft" ), 13387 marginRight: element.css( "marginRight" ) 13388 } ) 13389 .outerWidth( element.outerWidth() ) 13390 .outerHeight( element.outerHeight() ); 13391 13392 if ( /^(static|relative)/.test( cssPosition ) ) { 13393 cssPosition = "absolute"; 13394 13395 placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { 13396 13397 // Convert inline to inline block to account for inline elements 13398 // that turn to inline block based on content (like img) 13399 display: /^(inline|ruby)/.test( element.css( "display" ) ) ? 13400 "inline-block" : 13401 "block", 13402 visibility: "hidden", 13403 13404 // Margins need to be set to account for margin collapse 13405 marginTop: element.css( "marginTop" ), 13406 marginBottom: element.css( "marginBottom" ), 13407 marginLeft: element.css( "marginLeft" ), 13408 marginRight: element.css( "marginRight" ), 13409 "float": element.css( "float" ) 13410 } ) 13411 .outerWidth( element.outerWidth() ) 13412 .outerHeight( element.outerHeight() ) 13413 .addClass( "ui-effects-placeholder" ); 13414 13415 element.data( dataSpace + "placeholder", placeholder ); 13416 } 13417 13418 element.css( { 13419 position: cssPosition, 13420 left: position.left, 13421 top: position.top 13422 } ); 13423 13424 return placeholder; 13425 }, 13426 13427 removePlaceholder: function( element ) { 13428 var dataKey = dataSpace + "placeholder", 13429 placeholder = element.data( dataKey ); 13430 13431 if ( placeholder ) { 13432 placeholder.remove(); 13433 element.removeData( dataKey ); 13434 } 13435 }, 13436 13437 // Removes a placeholder if it exists and restores 13438 // properties that were modified during placeholder creation 13439 cleanUp: function( element ) { 13440 $.effects.restoreStyle( element ); 13441 $.effects.removePlaceholder( element ); 13442 }, 13443 13444 setTransition: function( element, list, factor, value ) { 13445 value = value || {}; 13446 $.each( list, function( i, x ) { 13447 var unit = element.cssUnit( x ); 13448 if ( unit[ 0 ] > 0 ) { 13449 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; 13450 } 13451 } ); 13452 return value; 13453 } 13454} ); 13455 13456// Return an effect options object for the given parameters: 13457function _normalizeArguments( effect, options, speed, callback ) { 13458 13459 // Allow passing all options as the first parameter 13460 if ( $.isPlainObject( effect ) ) { 13461 options = effect; 13462 effect = effect.effect; 13463 } 13464 13465 // Convert to an object 13466 effect = { effect: effect }; 13467 13468 // Catch (effect, null, ...) 13469 if ( options == null ) { 13470 options = {}; 13471 } 13472 13473 // Catch (effect, callback) 13474 if ( typeof options === "function" ) { 13475 callback = options; 13476 speed = null; 13477 options = {}; 13478 } 13479 13480 // Catch (effect, speed, ?) 13481 if ( typeof options === "number" || $.fx.speeds[ options ] ) { 13482 callback = speed; 13483 speed = options; 13484 options = {}; 13485 } 13486 13487 // Catch (effect, options, callback) 13488 if ( typeof speed === "function" ) { 13489 callback = speed; 13490 speed = null; 13491 } 13492 13493 // Add options to effect 13494 if ( options ) { 13495 $.extend( effect, options ); 13496 } 13497 13498 speed = speed || options.duration; 13499 effect.duration = $.fx.off ? 0 : 13500 typeof speed === "number" ? speed : 13501 speed in $.fx.speeds ? $.fx.speeds[ speed ] : 13502 $.fx.speeds._default; 13503 13504 effect.complete = callback || options.complete; 13505 13506 return effect; 13507} 13508 13509function standardAnimationOption( option ) { 13510 13511 // Valid standard speeds (nothing, number, named speed) 13512 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { 13513 return true; 13514 } 13515 13516 // Invalid strings - treat as "normal" speed 13517 if ( typeof option === "string" && !$.effects.effect[ option ] ) { 13518 return true; 13519 } 13520 13521 // Complete callback 13522 if ( typeof option === "function" ) { 13523 return true; 13524 } 13525 13526 // Options hash (but not naming an effect)
vendor: 4,998 bytes, lines 13527-13710
13527 if ( typeof option === "object" && !option.effect ) { 13528 return true; 13529 } 13530 13531 // Didn't match any standard API 13532 return false; 13533} 13534 13535$.fn.extend( { 13536 effect: function( /* effect, options, speed, callback */ ) { 13537 var args = _normalizeArguments.apply( this, arguments ), 13538 effectMethod = $.effects.effect[ args.effect ], 13539 defaultMode = effectMethod.mode, 13540 queue = args.queue, 13541 queueName = queue || "fx", 13542 complete = args.complete, 13543 mode = args.mode, 13544 modes = [], 13545 prefilter = function( next ) { 13546 var el = $( this ), 13547 normalizedMode = $.effects.mode( el, mode ) || defaultMode; 13548 13549 // Sentinel for duck-punching the :animated pseudo-selector 13550 el.data( dataSpaceAnimated, true ); 13551 13552 // Save effect mode for later use, 13553 // we can't just call $.effects.mode again later, 13554 // as the .show() below destroys the initial state 13555 modes.push( normalizedMode ); 13556 13557 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 13558 if ( defaultMode && ( normalizedMode === "show" || 13559 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { 13560 el.show(); 13561 } 13562 13563 if ( !defaultMode || normalizedMode !== "none" ) { 13564 $.effects.saveStyle( el ); 13565 } 13566 13567 if ( typeof next === "function" ) { 13568 next(); 13569 } 13570 }; 13571 13572 if ( $.fx.off || !effectMethod ) { 13573 13574 // Delegate to the original method (e.g., .show()) if possible 13575 if ( mode ) { 13576 return this[ mode ]( args.duration, complete ); 13577 } else { 13578 return this.each( function() { 13579 if ( complete ) { 13580 complete.call( this ); 13581 } 13582 } ); 13583 } 13584 } 13585 13586 function run( next ) { 13587 var elem = $( this ); 13588 13589 function cleanup() { 13590 elem.removeData( dataSpaceAnimated ); 13591 13592 $.effects.cleanUp( elem ); 13593 13594 if ( args.mode === "hide" ) { 13595 elem.hide(); 13596 } 13597 13598 done(); 13599 } 13600 13601 function done() { 13602 if ( typeof complete === "function" ) { 13603 complete.call( elem[ 0 ] ); 13604 } 13605 13606 if ( typeof next === "function" ) { 13607 next(); 13608 } 13609 } 13610 13611 // Override mode option on a per element basis, 13612 // as toggle can be either show or hide depending on element state 13613 args.mode = modes.shift(); 13614 13615 if ( $.uiBackCompat !== false && !defaultMode ) { 13616 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { 13617 13618 // Call the core method to track "olddisplay" properly 13619 elem[ mode ](); 13620 done(); 13621 } else { 13622 effectMethod.call( elem[ 0 ], args, done ); 13623 } 13624 } else { 13625 if ( args.mode === "none" ) { 13626 13627 // Call the core method to track "olddisplay" properly 13628 elem[ mode ](); 13629 done(); 13630 } else { 13631 effectMethod.call( elem[ 0 ], args, cleanup ); 13632 } 13633 } 13634 } 13635 13636 // Run prefilter on all elements first to ensure that 13637 // any showing or hiding happens before placeholder creation, 13638 // which ensures that any layout changes are correctly captured. 13639 return queue === false ? 13640 this.each( prefilter ).each( run ) : 13641 this.queue( queueName, prefilter ).queue( queueName, run ); 13642 }, 13643 13644 show: ( function( orig ) { 13645 return function( option ) { 13646 if ( standardAnimationOption( option ) ) { 13647 return orig.apply( this, arguments ); 13648 } else { 13649 var args = _normalizeArguments.apply( this, arguments ); 13650 args.mode = "show"; 13651 return this.effect.call( this, args ); 13652 } 13653 }; 13654 } )( $.fn.show ), 13655 13656 hide: ( function( orig ) { 13657 return function( option ) { 13658 if ( standardAnimationOption( option ) ) { 13659 return orig.apply( this, arguments ); 13660 } else { 13661 var args = _normalizeArguments.apply( this, arguments ); 13662 args.mode = "hide"; 13663 return this.effect.call( this, args ); 13664 } 13665 }; 13666 } )( $.fn.hide ), 13667 13668 toggle: ( function( orig ) { 13669 return function( option ) { 13670 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { 13671 return orig.apply( this, arguments ); 13672 } else { 13673 var args = _normalizeArguments.apply( this, arguments ); 13674 args.mode = "toggle"; 13675 return this.effect.call( this, args ); 13676 } 13677 }; 13678 } )( $.fn.toggle ), 13679 13680 cssUnit: function( key ) { 13681 var style = this.css( key ), 13682 val = []; 13683 13684 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { 13685 if ( style.indexOf( unit ) > 0 ) { 13686 val = [ parseFloat( style ), unit ]; 13687 } 13688 } ); 13689 return val; 13690 }, 13691 13692 cssClip: function( clipObj ) { 13693 if ( clipObj ) { 13694 return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + 13695 clipObj.bottom + "px " + clipObj.left + "px)" ); 13696 } 13697 return parseClip( this.css( "clip" ), this ); 13698 }, 13699 13700 transfer: function( options, done ) { 13701 var element = $( this ), 13702 target = $( options.to ), 13703 targetFixed = target.css( "position" ) === "fixed", 13704 body = $( "body" ), 13705 fixTop = targetFixed ? body.scrollTop() : 0, 13706 fixLeft = targetFixed ? body.scrollLeft() : 0, 13707 endPosition = target.offset(), 13708 animation = { 13709 top: endPosition.top - fixTop, 13710 left: endPosition.left - fixLeft,
vendor: 26,433 bytes, lines 13711-14677
13711 height: target.innerHeight(), 13712 width: target.innerWidth() 13713 }, 13714 startPosition = element.offset(), 13715 transfer = $( "<div class='ui-effects-transfer'></div>" ); 13716 13717 transfer 13718 .appendTo( "body" ) 13719 .addClass( options.className ) 13720 .css( { 13721 top: startPosition.top - fixTop, 13722 left: startPosition.left - fixLeft, 13723 height: element.innerHeight(), 13724 width: element.innerWidth(), 13725 position: targetFixed ? "fixed" : "absolute" 13726 } ) 13727 .animate( animation, options.duration, options.easing, function() { 13728 transfer.remove(); 13729 if ( typeof done === "function" ) { 13730 done(); 13731 } 13732 } ); 13733 } 13734} ); 13735 13736function parseClip( str, element ) { 13737 var outerWidth = element.outerWidth(), 13738 outerHeight = element.outerHeight(), 13739 clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, 13740 values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; 13741 13742 return { 13743 top: parseFloat( values[ 1 ] ) || 0, 13744 right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), 13745 bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), 13746 left: parseFloat( values[ 4 ] ) || 0 13747 }; 13748} 13749 13750$.fx.step.clip = function( fx ) { 13751 if ( !fx.clipInit ) { 13752 fx.start = $( fx.elem ).cssClip(); 13753 if ( typeof fx.end === "string" ) { 13754 fx.end = parseClip( fx.end, fx.elem ); 13755 } 13756 fx.clipInit = true; 13757 } 13758 13759 $( fx.elem ).cssClip( { 13760 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, 13761 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, 13762 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, 13763 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left 13764 } ); 13765}; 13766 13767} )(); 13768 13769/******************************************************************************/ 13770/*********************************** EASING ***********************************/ 13771/******************************************************************************/ 13772 13773( function() { 13774 13775// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) 13776 13777var baseEasings = {}; 13778 13779$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { 13780 baseEasings[ name ] = function( p ) { 13781 return Math.pow( p, i + 2 ); 13782 }; 13783} ); 13784 13785$.extend( baseEasings, { 13786 Sine: function( p ) { 13787 return 1 - Math.cos( p * Math.PI / 2 ); 13788 }, 13789 Circ: function( p ) { 13790 return 1 - Math.sqrt( 1 - p * p ); 13791 }, 13792 Elastic: function( p ) { 13793 return p === 0 || p === 1 ? p : 13794 -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); 13795 }, 13796 Back: function( p ) { 13797 return p * p * ( 3 * p - 2 ); 13798 }, 13799 Bounce: function( p ) { 13800 var pow2, 13801 bounce = 4; 13802 13803 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} 13804 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); 13805 } 13806} ); 13807 13808$.each( baseEasings, function( name, easeIn ) { 13809 $.easing[ "easeIn" + name ] = easeIn; 13810 $.easing[ "easeOut" + name ] = function( p ) { 13811 return 1 - easeIn( 1 - p ); 13812 }; 13813 $.easing[ "easeInOut" + name ] = function( p ) { 13814 return p < 0.5 ? 13815 easeIn( p * 2 ) / 2 : 13816 1 - easeIn( p * -2 + 2 ) / 2; 13817 }; 13818} ); 13819 13820} )(); 13821 13822var effect = $.effects; 13823 13824 13825/*! 13826 * jQuery UI Effects Blind 1.13.2 13827 * http://jqueryui.com 13828 * 13829 * Copyright jQuery Foundation and other contributors 13830 * Released under the MIT license. 13831 * http://jquery.org/license 13832 */ 13833 13834//>>label: Blind Effect 13835//>>group: Effects 13836//>>description: Blinds the element. 13837//>>docs: http://api.jqueryui.com/blind-effect/ 13838//>>demos: http://jqueryui.com/effect/ 13839 13840 13841var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { 13842 var map = { 13843 up: [ "bottom", "top" ], 13844 vertical: [ "bottom", "top" ], 13845 down: [ "top", "bottom" ], 13846 left: [ "right", "left" ], 13847 horizontal: [ "right", "left" ], 13848 right: [ "left", "right" ] 13849 }, 13850 element = $( this ), 13851 direction = options.direction || "up", 13852 start = element.cssClip(), 13853 animate = { clip: $.extend( {}, start ) }, 13854 placeholder = $.effects.createPlaceholder( element ); 13855 13856 animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; 13857 13858 if ( options.mode === "show" ) { 13859 element.cssClip( animate.clip ); 13860 if ( placeholder ) { 13861 placeholder.css( $.effects.clipToBox( animate ) ); 13862 } 13863 13864 animate.clip = start; 13865 } 13866 13867 if ( placeholder ) { 13868 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); 13869 } 13870 13871 element.animate( animate, { 13872 queue: false, 13873 duration: options.duration, 13874 easing: options.easing, 13875 complete: done 13876 } ); 13877} ); 13878 13879 13880/*! 13881 * jQuery UI Effects Bounce 1.13.2 13882 * http://jqueryui.com 13883 * 13884 * Copyright jQuery Foundation and other contributors 13885 * Released under the MIT license. 13886 * http://jquery.org/license 13887 */ 13888 13889//>>label: Bounce Effect 13890//>>group: Effects 13891//>>description: Bounces an element horizontally or vertically n times. 13892//>>docs: http://api.jqueryui.com/bounce-effect/ 13893//>>demos: http://jqueryui.com/effect/ 13894 13895 13896var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { 13897 var upAnim, downAnim, refValue, 13898 element = $( this ), 13899 13900 // Defaults: 13901 mode = options.mode, 13902 hide = mode === "hide", 13903 show = mode === "show", 13904 direction = options.direction || "up", 13905 distance = options.distance, 13906 times = options.times || 5, 13907 13908 // Number of internal animations 13909 anims = times * 2 + ( show || hide ? 1 : 0 ), 13910 speed = options.duration / anims, 13911 easing = options.easing, 13912 13913 // Utility: 13914 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 13915 motion = ( direction === "up" || direction === "left" ), 13916 i = 0, 13917 13918 queuelen = element.queue().length; 13919 13920 $.effects.createPlaceholder( element ); 13921 13922 refValue = element.css( ref ); 13923 13924 // Default distance for the BIGGEST bounce is the outer Distance / 3 13925 if ( !distance ) { 13926 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; 13927 } 13928 13929 if ( show ) { 13930 downAnim = { opacity: 1 }; 13931 downAnim[ ref ] = refValue; 13932 13933 // If we are showing, force opacity 0 and set the initial position 13934 // then do the "first" animation 13935 element 13936 .css( "opacity", 0 ) 13937 .css( ref, motion ? -distance * 2 : distance * 2 ) 13938 .animate( downAnim, speed, easing ); 13939 } 13940 13941 // Start at the smallest distance if we are hiding 13942 if ( hide ) { 13943 distance = distance / Math.pow( 2, times - 1 ); 13944 } 13945 13946 downAnim = {}; 13947 downAnim[ ref ] = refValue; 13948 13949 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here 13950 for ( ; i < times; i++ ) { 13951 upAnim = {}; 13952 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 13953 13954 element 13955 .animate( upAnim, speed, easing ) 13956 .animate( downAnim, speed, easing ); 13957 13958 distance = hide ? distance * 2 : distance / 2; 13959 } 13960 13961 // Last Bounce when Hiding 13962 if ( hide ) { 13963 upAnim = { opacity: 0 }; 13964 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; 13965 13966 element.animate( upAnim, speed, easing ); 13967 } 13968 13969 element.queue( done ); 13970 13971 $.effects.unshift( element, queuelen, anims + 1 ); 13972} ); 13973 13974 13975/*! 13976 * jQuery UI Effects Clip 1.13.2 13977 * http://jqueryui.com 13978 * 13979 * Copyright jQuery Foundation and other contributors 13980 * Released under the MIT license. 13981 * http://jquery.org/license 13982 */ 13983 13984//>>label: Clip Effect 13985//>>group: Effects 13986//>>description: Clips the element on and off like an old TV. 13987//>>docs: http://api.jqueryui.com/clip-effect/ 13988//>>demos: http://jqueryui.com/effect/ 13989 13990 13991var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { 13992 var start, 13993 animate = {}, 13994 element = $( this ), 13995 direction = options.direction || "vertical", 13996 both = direction === "both", 13997 horizontal = both || direction === "horizontal", 13998 vertical = both || direction === "vertical"; 13999 14000 start = element.cssClip(); 14001 animate.clip = { 14002 top: vertical ? ( start.bottom - start.top ) / 2 : start.top, 14003 right: horizontal ? ( start.right - start.left ) / 2 : start.right, 14004 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, 14005 left: horizontal ? ( start.right - start.left ) / 2 : start.left 14006 }; 14007 14008 $.effects.createPlaceholder( element ); 14009 14010 if ( options.mode === "show" ) { 14011 element.cssClip( animate.clip ); 14012 animate.clip = start; 14013 } 14014 14015 element.animate( animate, { 14016 queue: false, 14017 duration: options.duration, 14018 easing: options.easing, 14019 complete: done 14020 } ); 14021 14022} ); 14023 14024 14025/*! 14026 * jQuery UI Effects Drop 1.13.2 14027 * http://jqueryui.com 14028 * 14029 * Copyright jQuery Foundation and other contributors 14030 * Released under the MIT license. 14031 * http://jquery.org/license 14032 */ 14033 14034//>>label: Drop Effect 14035//>>group: Effects 14036//>>description: Moves an element in one direction and hides it at the same time. 14037//>>docs: http://api.jqueryui.com/drop-effect/ 14038//>>demos: http://jqueryui.com/effect/ 14039 14040 14041var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { 14042 14043 var distance, 14044 element = $( this ), 14045 mode = options.mode, 14046 show = mode === "show", 14047 direction = options.direction || "left", 14048 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14049 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", 14050 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", 14051 animation = { 14052 opacity: 0 14053 }; 14054 14055 $.effects.createPlaceholder( element ); 14056 14057 distance = options.distance || 14058 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; 14059 14060 animation[ ref ] = motion + distance; 14061 14062 if ( show ) { 14063 element.css( animation ); 14064 14065 animation[ ref ] = oppositeMotion + distance; 14066 animation.opacity = 1; 14067 } 14068 14069 // Animate 14070 element.animate( animation, { 14071 queue: false, 14072 duration: options.duration, 14073 easing: options.easing, 14074 complete: done 14075 } ); 14076} ); 14077 14078 14079/*! 14080 * jQuery UI Effects Explode 1.13.2 14081 * http://jqueryui.com 14082 * 14083 * Copyright jQuery Foundation and other contributors 14084 * Released under the MIT license. 14085 * http://jquery.org/license 14086 */ 14087 14088//>>label: Explode Effect 14089//>>group: Effects 14090/* eslint-disable max-len */ 14091//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. 14092/* eslint-enable max-len */ 14093//>>docs: http://api.jqueryui.com/explode-effect/ 14094//>>demos: http://jqueryui.com/effect/ 14095 14096 14097var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { 14098 14099 var i, j, left, top, mx, my, 14100 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, 14101 cells = rows, 14102 element = $( this ), 14103 mode = options.mode, 14104 show = mode === "show", 14105 14106 // Show and then visibility:hidden the element before calculating offset 14107 offset = element.show().css( "visibility", "hidden" ).offset(), 14108 14109 // Width and height of a piece 14110 width = Math.ceil( element.outerWidth() / cells ), 14111 height = Math.ceil( element.outerHeight() / rows ), 14112 pieces = []; 14113 14114 // Children animate complete: 14115 function childComplete() { 14116 pieces.push( this ); 14117 if ( pieces.length === rows * cells ) { 14118 animComplete(); 14119 } 14120 } 14121 14122 // Clone the element for each row and cell. 14123 for ( i = 0; i < rows; i++ ) { // ===> 14124 top = offset.top + i * height; 14125 my = i - ( rows - 1 ) / 2; 14126 14127 for ( j = 0; j < cells; j++ ) { // ||| 14128 left = offset.left + j * width; 14129 mx = j - ( cells - 1 ) / 2; 14130 14131 // Create a clone of the now hidden main element that will be absolute positioned 14132 // within a wrapper div off the -left and -top equal to size of our pieces 14133 element 14134 .clone() 14135 .appendTo( "body" ) 14136 .wrap( "<div></div>" ) 14137 .css( { 14138 position: "absolute", 14139 visibility: "visible", 14140 left: -j * width, 14141 top: -i * height 14142 } ) 14143 14144 // Select the wrapper - make it overflow: hidden and absolute positioned based on 14145 // where the original was located +left and +top equal to the size of pieces 14146 .parent() 14147 .addClass( "ui-effects-explode" ) 14148 .css( { 14149 position: "absolute", 14150 overflow: "hidden", 14151 width: width, 14152 height: height, 14153 left: left + ( show ? mx * width : 0 ), 14154 top: top + ( show ? my * height : 0 ), 14155 opacity: show ? 0 : 1 14156 } ) 14157 .animate( { 14158 left: left + ( show ? 0 : mx * width ), 14159 top: top + ( show ? 0 : my * height ), 14160 opacity: show ? 1 : 0 14161 }, options.duration || 500, options.easing, childComplete ); 14162 } 14163 } 14164 14165 function animComplete() { 14166 element.css( { 14167 visibility: "visible" 14168 } ); 14169 $( pieces ).remove(); 14170 done(); 14171 } 14172} ); 14173 14174 14175/*! 14176 * jQuery UI Effects Fade 1.13.2 14177 * http://jqueryui.com 14178 * 14179 * Copyright jQuery Foundation and other contributors 14180 * Released under the MIT license. 14181 * http://jquery.org/license 14182 */ 14183 14184//>>label: Fade Effect 14185//>>group: Effects 14186//>>description: Fades the element. 14187//>>docs: http://api.jqueryui.com/fade-effect/ 14188//>>demos: http://jqueryui.com/effect/ 14189 14190 14191var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { 14192 var show = options.mode === "show"; 14193 14194 $( this ) 14195 .css( "opacity", show ? 0 : 1 ) 14196 .animate( { 14197 opacity: show ? 1 : 0 14198 }, { 14199 queue: false, 14200 duration: options.duration, 14201 easing: options.easing, 14202 complete: done 14203 } ); 14204} ); 14205 14206 14207/*! 14208 * jQuery UI Effects Fold 1.13.2 14209 * http://jqueryui.com 14210 * 14211 * Copyright jQuery Foundation and other contributors 14212 * Released under the MIT license. 14213 * http://jquery.org/license 14214 */ 14215 14216//>>label: Fold Effect 14217//>>group: Effects 14218//>>description: Folds an element first horizontally and then vertically. 14219//>>docs: http://api.jqueryui.com/fold-effect/ 14220//>>demos: http://jqueryui.com/effect/ 14221 14222 14223var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { 14224 14225 // Create element 14226 var element = $( this ), 14227 mode = options.mode, 14228 show = mode === "show", 14229 hide = mode === "hide", 14230 size = options.size || 15, 14231 percent = /([0-9]+)%/.exec( size ), 14232 horizFirst = !!options.horizFirst, 14233 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], 14234 duration = options.duration / 2, 14235 14236 placeholder = $.effects.createPlaceholder( element ), 14237 14238 start = element.cssClip(), 14239 animation1 = { clip: $.extend( {}, start ) }, 14240 animation2 = { clip: $.extend( {}, start ) }, 14241 14242 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], 14243 14244 queuelen = element.queue().length; 14245 14246 if ( percent ) { 14247 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; 14248 } 14249 animation1.clip[ ref[ 0 ] ] = size; 14250 animation2.clip[ ref[ 0 ] ] = size; 14251 animation2.clip[ ref[ 1 ] ] = 0; 14252 14253 if ( show ) { 14254 element.cssClip( animation2.clip ); 14255 if ( placeholder ) { 14256 placeholder.css( $.effects.clipToBox( animation2 ) ); 14257 } 14258 14259 animation2.clip = start; 14260 } 14261 14262 // Animate 14263 element 14264 .queue( function( next ) { 14265 if ( placeholder ) { 14266 placeholder 14267 .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) 14268 .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); 14269 } 14270 14271 next(); 14272 } ) 14273 .animate( animation1, duration, options.easing ) 14274 .animate( animation2, duration, options.easing ) 14275 .queue( done ); 14276 14277 $.effects.unshift( element, queuelen, 4 ); 14278} ); 14279 14280 14281/*! 14282 * jQuery UI Effects Highlight 1.13.2 14283 * http://jqueryui.com 14284 * 14285 * Copyright jQuery Foundation and other contributors 14286 * Released under the MIT license. 14287 * http://jquery.org/license 14288 */ 14289 14290//>>label: Highlight Effect 14291//>>group: Effects 14292//>>description: Highlights the background of an element in a defined color for a custom duration. 14293//>>docs: http://api.jqueryui.com/highlight-effect/ 14294//>>demos: http://jqueryui.com/effect/ 14295 14296 14297var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { 14298 var element = $( this ), 14299 animation = { 14300 backgroundColor: element.css( "backgroundColor" ) 14301 }; 14302 14303 if ( options.mode === "hide" ) { 14304 animation.opacity = 0; 14305 } 14306 14307 $.effects.saveStyle( element ); 14308 14309 element 14310 .css( { 14311 backgroundImage: "none", 14312 backgroundColor: options.color || "#ffff99" 14313 } ) 14314 .animate( animation, { 14315 queue: false, 14316 duration: options.duration, 14317 easing: options.easing, 14318 complete: done 14319 } ); 14320} ); 14321 14322 14323/*! 14324 * jQuery UI Effects Size 1.13.2 14325 * http://jqueryui.com 14326 * 14327 * Copyright jQuery Foundation and other contributors 14328 * Released under the MIT license. 14329 * http://jquery.org/license 14330 */ 14331 14332//>>label: Size Effect 14333//>>group: Effects 14334//>>description: Resize an element to a specified width and height. 14335//>>docs: http://api.jqueryui.com/size-effect/ 14336//>>demos: http://jqueryui.com/effect/ 14337 14338 14339var effectsEffectSize = $.effects.define( "size", function( options, done ) { 14340 14341 // Create element 14342 var baseline, factor, temp, 14343 element = $( this ), 14344 14345 // Copy for children 14346 cProps = [ "fontSize" ], 14347 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 14348 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 14349 14350 // Set options 14351 mode = options.mode, 14352 restore = mode !== "effect", 14353 scale = options.scale || "both", 14354 origin = options.origin || [ "middle", "center" ], 14355 position = element.css( "position" ), 14356 pos = element.position(), 14357 original = $.effects.scaledDimensions( element ), 14358 from = options.from || original, 14359 to = options.to || $.effects.scaledDimensions( element, 0 ); 14360 14361 $.effects.createPlaceholder( element ); 14362 14363 if ( mode === "show" ) { 14364 temp = from; 14365 from = to; 14366 to = temp; 14367 } 14368 14369 // Set scaling factor 14370 factor = { 14371 from: { 14372 y: from.height / original.height, 14373 x: from.width / original.width 14374 }, 14375 to: { 14376 y: to.height / original.height, 14377 x: to.width / original.width 14378 } 14379 }; 14380 14381 // Scale the css box 14382 if ( scale === "box" || scale === "both" ) { 14383 14384 // Vertical props scaling 14385 if ( factor.from.y !== factor.to.y ) { 14386 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 14387 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 14388 } 14389 14390 // Horizontal props scaling 14391 if ( factor.from.x !== factor.to.x ) { 14392 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 14393 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 14394 } 14395 } 14396 14397 // Scale the content 14398 if ( scale === "content" || scale === "both" ) { 14399 14400 // Vertical props scaling 14401 if ( factor.from.y !== factor.to.y ) { 14402 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 14403 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 14404 } 14405 } 14406 14407 // Adjust the position properties based on the provided origin points 14408 if ( origin ) { 14409 baseline = $.effects.getBaseline( origin, original ); 14410 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 14411 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 14412 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 14413 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 14414 } 14415 delete from.outerHeight; 14416 delete from.outerWidth; 14417 element.css( from ); 14418 14419 // Animate the children if desired 14420 if ( scale === "content" || scale === "both" ) { 14421 14422 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 14423 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 14424 14425 // Only animate children with width attributes specified 14426 // TODO: is this right? should we include anything with css width specified as well 14427 element.find( "*[width]" ).each( function() { 14428 var child = $( this ), 14429 childOriginal = $.effects.scaledDimensions( child ), 14430 childFrom = { 14431 height: childOriginal.height * factor.from.y, 14432 width: childOriginal.width * factor.from.x, 14433 outerHeight: childOriginal.outerHeight * factor.from.y, 14434 outerWidth: childOriginal.outerWidth * factor.from.x 14435 }, 14436 childTo = { 14437 height: childOriginal.height * factor.to.y, 14438 width: childOriginal.width * factor.to.x, 14439 outerHeight: childOriginal.height * factor.to.y, 14440 outerWidth: childOriginal.width * factor.to.x 14441 }; 14442 14443 // Vertical props scaling 14444 if ( factor.from.y !== factor.to.y ) { 14445 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 14446 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 14447 } 14448 14449 // Horizontal props scaling 14450 if ( factor.from.x !== factor.to.x ) { 14451 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 14452 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 14453 } 14454 14455 if ( restore ) { 14456 $.effects.saveStyle( child ); 14457 } 14458 14459 // Animate children 14460 child.css( childFrom ); 14461 child.animate( childTo, options.duration, options.easing, function() { 14462 14463 // Restore children 14464 if ( restore ) { 14465 $.effects.restoreStyle( child ); 14466 } 14467 } ); 14468 } ); 14469 } 14470 14471 // Animate 14472 element.animate( to, { 14473 queue: false, 14474 duration: options.duration, 14475 easing: options.easing, 14476 complete: function() { 14477 14478 var offset = element.offset(); 14479 14480 if ( to.opacity === 0 ) { 14481 element.css( "opacity", from.opacity ); 14482 } 14483 14484 if ( !restore ) { 14485 element 14486 .css( "position", position === "static" ? "relative" : position ) 14487 .offset( offset ); 14488 14489 // Need to save style here so that automatic style restoration 14490 // doesn't restore to the original styles from before the animation. 14491 $.effects.saveStyle( element ); 14492 } 14493 14494 done(); 14495 } 14496 } ); 14497 14498} ); 14499 14500 14501/*! 14502 * jQuery UI Effects Scale 1.13.2 14503 * http://jqueryui.com 14504 * 14505 * Copyright jQuery Foundation and other contributors 14506 * Released under the MIT license. 14507 * http://jquery.org/license 14508 */ 14509 14510//>>label: Scale Effect 14511//>>group: Effects 14512//>>description: Grows or shrinks an element and its content. 14513//>>docs: http://api.jqueryui.com/scale-effect/ 14514//>>demos: http://jqueryui.com/effect/ 14515 14516 14517var effectsEffectScale = $.effects.define( "scale", function( options, done ) { 14518 14519 // Create element 14520 var el = $( this ), 14521 mode = options.mode, 14522 percent = parseInt( options.percent, 10 ) || 14523 ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), 14524 14525 newOptions = $.extend( true, { 14526 from: $.effects.scaledDimensions( el ), 14527 to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), 14528 origin: options.origin || [ "middle", "center" ] 14529 }, options ); 14530 14531 // Fade option to support puff 14532 if ( options.fade ) { 14533 newOptions.from.opacity = 1; 14534 newOptions.to.opacity = 0; 14535 } 14536 14537 $.effects.effect.size.call( this, newOptions, done ); 14538} ); 14539 14540 14541/*! 14542 * jQuery UI Effects Puff 1.13.2 14543 * http://jqueryui.com 14544 * 14545 * Copyright jQuery Foundation and other contributors 14546 * Released under the MIT license. 14547 * http://jquery.org/license 14548 */ 14549 14550//>>label: Puff Effect 14551//>>group: Effects 14552//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. 14553//>>docs: http://api.jqueryui.com/puff-effect/ 14554//>>demos: http://jqueryui.com/effect/ 14555 14556 14557var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { 14558 var newOptions = $.extend( true, {}, options, { 14559 fade: true, 14560 percent: parseInt( options.percent, 10 ) || 150 14561 } ); 14562 14563 $.effects.effect.scale.call( this, newOptions, done ); 14564} ); 14565 14566 14567/*! 14568 * jQuery UI Effects Pulsate 1.13.2 14569 * http://jqueryui.com 14570 * 14571 * Copyright jQuery Foundation and other contributors 14572 * Released under the MIT license. 14573 * http://jquery.org/license 14574 */ 14575 14576//>>label: Pulsate Effect 14577//>>group: Effects 14578//>>description: Pulsates an element n times by changing the opacity to zero and back. 14579//>>docs: http://api.jqueryui.com/pulsate-effect/ 14580//>>demos: http://jqueryui.com/effect/ 14581 14582 14583var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { 14584 var element = $( this ), 14585 mode = options.mode, 14586 show = mode === "show", 14587 hide = mode === "hide", 14588 showhide = show || hide, 14589 14590 // Showing or hiding leaves off the "last" animation 14591 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), 14592 duration = options.duration / anims, 14593 animateTo = 0, 14594 i = 1, 14595 queuelen = element.queue().length; 14596 14597 if ( show || !element.is( ":visible" ) ) { 14598 element.css( "opacity", 0 ).show(); 14599 animateTo = 1; 14600 } 14601 14602 // Anims - 1 opacity "toggles" 14603 for ( ; i < anims; i++ ) { 14604 element.animate( { opacity: animateTo }, duration, options.easing ); 14605 animateTo = 1 - animateTo; 14606 } 14607 14608 element.animate( { opacity: animateTo }, duration, options.easing ); 14609 14610 element.queue( done ); 14611 14612 $.effects.unshift( element, queuelen, anims + 1 ); 14613} ); 14614 14615 14616/*! 14617 * jQuery UI Effects Shake 1.13.2 14618 * http://jqueryui.com 14619 * 14620 * Copyright jQuery Foundation and other contributors 14621 * Released under the MIT license. 14622 * http://jquery.org/license 14623 */ 14624 14625//>>label: Shake Effect 14626//>>group: Effects 14627//>>description: Shakes an element horizontally or vertically n times. 14628//>>docs: http://api.jqueryui.com/shake-effect/ 14629//>>demos: http://jqueryui.com/effect/ 14630 14631 14632var effectsEffectShake = $.effects.define( "shake", function( options, done ) { 14633 14634 var i = 1, 14635 element = $( this ), 14636 direction = options.direction || "left", 14637 distance = options.distance || 20, 14638 times = options.times || 3, 14639 anims = times * 2 + 1, 14640 speed = Math.round( options.duration / anims ), 14641 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14642 positiveMotion = ( direction === "up" || direction === "left" ), 14643 animation = {}, 14644 animation1 = {}, 14645 animation2 = {}, 14646 14647 queuelen = element.queue().length; 14648 14649 $.effects.createPlaceholder( element ); 14650 14651 // Animation 14652 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; 14653 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; 14654 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; 14655 14656 // Animate 14657 element.animate( animation, speed, options.easing ); 14658 14659 // Shakes 14660 for ( ; i < times; i++ ) { 14661 element 14662 .animate( animation1, speed, options.easing ) 14663 .animate( animation2, speed, options.easing ); 14664 } 14665 14666 element 14667 .animate( animation1, speed, options.easing ) 14668 .animate( animation, speed / 2, options.easing ) 14669 .queue( done ); 14670 14671 $.effects.unshift( element, queuelen, anims + 1 ); 14672} ); 14673 14674 14675/*! 14676 * jQuery UI Effects Slide 1.13.2 14677 * http://jqueryui.com
vendor: 19,531 bytes, lines 14678-15425
14678 * 14679 * Copyright jQuery Foundation and other contributors 14680 * Released under the MIT license. 14681 * http://jquery.org/license 14682 */ 14683 14684//>>label: Slide Effect 14685//>>group: Effects 14686//>>description: Slides an element in and out of the viewport. 14687//>>docs: http://api.jqueryui.com/slide-effect/ 14688//>>demos: http://jqueryui.com/effect/ 14689 14690 14691var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { 14692 var startClip, startRef, 14693 element = $( this ), 14694 map = { 14695 up: [ "bottom", "top" ], 14696 down: [ "top", "bottom" ], 14697 left: [ "right", "left" ], 14698 right: [ "left", "right" ] 14699 }, 14700 mode = options.mode, 14701 direction = options.direction || "left", 14702 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", 14703 positiveMotion = ( direction === "up" || direction === "left" ), 14704 distance = options.distance || 14705 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), 14706 animation = {}; 14707 14708 $.effects.createPlaceholder( element ); 14709 14710 startClip = element.cssClip(); 14711 startRef = element.position()[ ref ]; 14712 14713 // Define hide animation 14714 animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; 14715 animation.clip = element.cssClip(); 14716 animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; 14717 14718 // Reverse the animation if we're showing 14719 if ( mode === "show" ) { 14720 element.cssClip( animation.clip ); 14721 element.css( ref, animation[ ref ] ); 14722 animation.clip = startClip; 14723 animation[ ref ] = startRef; 14724 } 14725 14726 // Actually animate 14727 element.animate( animation, { 14728 queue: false, 14729 duration: options.duration, 14730 easing: options.easing, 14731 complete: done 14732 } ); 14733} ); 14734 14735 14736/*! 14737 * jQuery UI Effects Transfer 1.13.2 14738 * http://jqueryui.com 14739 * 14740 * Copyright jQuery Foundation and other contributors 14741 * Released under the MIT license. 14742 * http://jquery.org/license 14743 */ 14744 14745//>>label: Transfer Effect 14746//>>group: Effects 14747//>>description: Displays a transfer effect from one element to another. 14748//>>docs: http://api.jqueryui.com/transfer-effect/ 14749//>>demos: http://jqueryui.com/effect/ 14750 14751 14752var effect; 14753if ( $.uiBackCompat !== false ) { 14754 effect = $.effects.define( "transfer", function( options, done ) { 14755 $( this ).transfer( options, done ); 14756 } ); 14757} 14758var effectsEffectTransfer = effect; 14759 14760 14761/*! 14762 * jQuery UI Focusable 1.13.2 14763 * http://jqueryui.com 14764 * 14765 * Copyright jQuery Foundation and other contributors 14766 * Released under the MIT license. 14767 * http://jquery.org/license 14768 */ 14769 14770//>>label: :focusable Selector 14771//>>group: Core 14772//>>description: Selects elements which can be focused. 14773//>>docs: http://api.jqueryui.com/focusable-selector/ 14774 14775 14776// Selectors 14777$.ui.focusable = function( element, hasTabindex ) { 14778 var map, mapName, img, focusableIfVisible, fieldset, 14779 nodeName = element.nodeName.toLowerCase(); 14780 14781 if ( "area" === nodeName ) { 14782 map = element.parentNode; 14783 mapName = map.name; 14784 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { 14785 return false; 14786 } 14787 img = $( "img[usemap='#" + mapName + "']" ); 14788 return img.length > 0 && img.is( ":visible" ); 14789 } 14790 14791 if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { 14792 focusableIfVisible = !element.disabled; 14793 14794 if ( focusableIfVisible ) { 14795 14796 // Form controls within a disabled fieldset are disabled. 14797 // However, controls within the fieldset's legend do not get disabled. 14798 // Since controls generally aren't placed inside legends, we skip 14799 // this portion of the check. 14800 fieldset = $( element ).closest( "fieldset" )[ 0 ]; 14801 if ( fieldset ) { 14802 focusableIfVisible = !fieldset.disabled; 14803 } 14804 } 14805 } else if ( "a" === nodeName ) { 14806 focusableIfVisible = element.href || hasTabindex; 14807 } else { 14808 focusableIfVisible = hasTabindex; 14809 } 14810 14811 return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); 14812}; 14813 14814// Support: IE 8 only 14815// IE 8 doesn't resolve inherit to visible/hidden for computed values 14816function visible( element ) { 14817 var visibility = element.css( "visibility" ); 14818 while ( visibility === "inherit" ) { 14819 element = element.parent(); 14820 visibility = element.css( "visibility" ); 14821 } 14822 return visibility === "visible"; 14823} 14824 14825$.extend( $.expr.pseudos, { 14826 focusable: function( element ) { 14827 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); 14828 } 14829} ); 14830 14831var focusable = $.ui.focusable; 14832 14833 14834 14835// Support: IE8 Only 14836// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop 14837// with a string, so we need to find the proper form. 14838var form = $.fn._form = function() { 14839 return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); 14840}; 14841 14842 14843/*! 14844 * jQuery UI Form Reset Mixin 1.13.2 14845 * http://jqueryui.com 14846 * 14847 * Copyright jQuery Foundation and other contributors 14848 * Released under the MIT license. 14849 * http://jquery.org/license 14850 */ 14851 14852//>>label: Form Reset Mixin 14853//>>group: Core 14854//>>description: Refresh input widgets when their form is reset 14855//>>docs: http://api.jqueryui.com/form-reset-mixin/ 14856 14857 14858var formResetMixin = $.ui.formResetMixin = { 14859 _formResetHandler: function() { 14860 var form = $( this ); 14861 14862 // Wait for the form reset to actually happen before refreshing 14863 setTimeout( function() { 14864 var instances = form.data( "ui-form-reset-instances" ); 14865 $.each( instances, function() { 14866 this.refresh(); 14867 } ); 14868 } ); 14869 }, 14870 14871 _bindFormResetHandler: function() { 14872 this.form = this.element._form(); 14873 if ( !this.form.length ) { 14874 return; 14875 } 14876 14877 var instances = this.form.data( "ui-form-reset-instances" ) || []; 14878 if ( !instances.length ) { 14879 14880 // We don't use _on() here because we use a single event handler per form 14881 this.form.on( "reset.ui-form-reset", this._formResetHandler ); 14882 } 14883 instances.push( this ); 14884 this.form.data( "ui-form-reset-instances", instances ); 14885 }, 14886 14887 _unbindFormResetHandler: function() { 14888 if ( !this.form.length ) { 14889 return; 14890 } 14891 14892 var instances = this.form.data( "ui-form-reset-instances" ); 14893 instances.splice( $.inArray( this, instances ), 1 ); 14894 if ( instances.length ) { 14895 this.form.data( "ui-form-reset-instances", instances ); 14896 } else { 14897 this.form 14898 .removeData( "ui-form-reset-instances" ) 14899 .off( "reset.ui-form-reset" ); 14900 } 14901 } 14902}; 14903 14904 14905/*! 14906 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 14907 * http://jqueryui.com 14908 * 14909 * Copyright jQuery Foundation and other contributors 14910 * Released under the MIT license. 14911 * http://jquery.org/license 14912 * 14913 */ 14914 14915//>>label: jQuery 1.8+ Support 14916//>>group: Core 14917//>>description: Support version 1.8.x and newer of jQuery core 14918 14919 14920// Support: jQuery 1.9.x or older 14921// $.expr[ ":" ] is deprecated. 14922if ( !$.expr.pseudos ) { 14923 $.expr.pseudos = $.expr[ ":" ]; 14924} 14925 14926// Support: jQuery 1.11.x or older 14927// $.unique has been renamed to $.uniqueSort 14928if ( !$.uniqueSort ) { 14929 $.uniqueSort = $.unique; 14930} 14931 14932// Support: jQuery 2.2.x or older. 14933// This method has been defined in jQuery 3.0.0. 14934// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js 14935if ( !$.escapeSelector ) { 14936 14937 // CSS string/identifier serialization 14938 // https://drafts.csswg.org/cssom/#common-serializing-idioms 14939 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 14940 14941 var fcssescape = function( ch, asCodePoint ) { 14942 if ( asCodePoint ) { 14943 14944 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 14945 if ( ch === "\0" ) { 14946 return "\uFFFD"; 14947 } 14948 14949 // Control characters and (dependent upon position) numbers get escaped as code points 14950 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 14951 } 14952 14953 // Other potentially-special ASCII characters get backslash-escaped 14954 return "\\" + ch; 14955 }; 14956 14957 $.escapeSelector = function( sel ) { 14958 return ( sel + "" ).replace( rcssescape, fcssescape ); 14959 }; 14960} 14961 14962// Support: jQuery 3.4.x or older 14963// These methods have been defined in jQuery 3.5.0. 14964if ( !$.fn.even || !$.fn.odd ) { 14965 $.fn.extend( { 14966 even: function() { 14967 return this.filter( function( i ) { 14968 return i % 2 === 0; 14969 } ); 14970 }, 14971 odd: function() { 14972 return this.filter( function( i ) { 14973 return i % 2 === 1; 14974 } ); 14975 } 14976 } ); 14977} 14978 14979; 14980/*! 14981 * jQuery UI Keycode 1.13.2 14982 * http://jqueryui.com 14983 * 14984 * Copyright jQuery Foundation and other contributors 14985 * Released under the MIT license. 14986 * http://jquery.org/license 14987 */ 14988 14989//>>label: Keycode 14990//>>group: Core 14991//>>description: Provide keycodes as keynames 14992//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ 14993 14994 14995var keycode = $.ui.keyCode = { 14996 BACKSPACE: 8, 14997 COMMA: 188, 14998 DELETE: 46, 14999 DOWN: 40, 15000 END: 35, 15001 ENTER: 13, 15002 ESCAPE: 27, 15003 HOME: 36, 15004 LEFT: 37, 15005 PAGE_DOWN: 34, 15006 PAGE_UP: 33, 15007 PERIOD: 190, 15008 RIGHT: 39, 15009 SPACE: 32, 15010 TAB: 9, 15011 UP: 38 15012}; 15013 15014 15015/*! 15016 * jQuery UI Labels 1.13.2 15017 * http://jqueryui.com 15018 * 15019 * Copyright jQuery Foundation and other contributors 15020 * Released under the MIT license. 15021 * http://jquery.org/license 15022 */ 15023 15024//>>label: labels 15025//>>group: Core 15026//>>description: Find all the labels associated with a given input 15027//>>docs: http://api.jqueryui.com/labels/ 15028 15029 15030var labels = $.fn.labels = function() { 15031 var ancestor, selector, id, labels, ancestors; 15032 15033 if ( !this.length ) { 15034 return this.pushStack( [] ); 15035 } 15036 15037 // Check control.labels first 15038 if ( this[ 0 ].labels && this[ 0 ].labels.length ) { 15039 return this.pushStack( this[ 0 ].labels ); 15040 } 15041 15042 // Support: IE <= 11, FF <= 37, Android <= 2.3 only 15043 // Above browsers do not support control.labels. Everything below is to support them 15044 // as well as document fragments. control.labels does not work on document fragments 15045 labels = this.eq( 0 ).parents( "label" ); 15046 15047 // Look for the label based on the id 15048 id = this.attr( "id" ); 15049 if ( id ) { 15050 15051 // We don't search against the document in case the element 15052 // is disconnected from the DOM 15053 ancestor = this.eq( 0 ).parents().last(); 15054 15055 // Get a full set of top level ancestors 15056 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); 15057 15058 // Create a selector for the label based on the id 15059 selector = "label[for='" + $.escapeSelector( id ) + "']"; 15060 15061 labels = labels.add( ancestors.find( selector ).addBack( selector ) ); 15062 15063 } 15064 15065 // Return whatever we have found for labels 15066 return this.pushStack( labels ); 15067}; 15068 15069 15070/*! 15071 * jQuery UI Scroll Parent 1.13.2 15072 * http://jqueryui.com 15073 * 15074 * Copyright jQuery Foundation and other contributors 15075 * Released under the MIT license. 15076 * http://jquery.org/license 15077 */ 15078 15079//>>label: scrollParent 15080//>>group: Core 15081//>>description: Get the closest ancestor element that is scrollable. 15082//>>docs: http://api.jqueryui.com/scrollParent/ 15083 15084 15085var scrollParent = $.fn.scrollParent = function( includeHidden ) { 15086 var position = this.css( "position" ), 15087 excludeStaticParent = position === "absolute", 15088 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, 15089 scrollParent = this.parents().filter( function() { 15090 var parent = $( this ); 15091 if ( excludeStaticParent && parent.css( "position" ) === "static" ) { 15092 return false; 15093 } 15094 return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + 15095 parent.css( "overflow-x" ) ); 15096 } ).eq( 0 ); 15097 15098 return position === "fixed" || !scrollParent.length ? 15099 $( this[ 0 ].ownerDocument || document ) : 15100 scrollParent; 15101}; 15102 15103 15104/*! 15105 * jQuery UI Tabbable 1.13.2 15106 * http://jqueryui.com 15107 * 15108 * Copyright jQuery Foundation and other contributors 15109 * Released under the MIT license. 15110 * http://jquery.org/license 15111 */ 15112 15113//>>label: :tabbable Selector 15114//>>group: Core 15115//>>description: Selects elements which can be tabbed to. 15116//>>docs: http://api.jqueryui.com/tabbable-selector/ 15117 15118 15119var tabbable = $.extend( $.expr.pseudos, { 15120 tabbable: function( element ) { 15121 var tabIndex = $.attr( element, "tabindex" ), 15122 hasTabindex = tabIndex != null; 15123 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); 15124 } 15125} ); 15126 15127 15128/*! 15129 * jQuery UI Unique ID 1.13.2 15130 * http://jqueryui.com 15131 * 15132 * Copyright jQuery Foundation and other contributors 15133 * Released under the MIT license. 15134 * http://jquery.org/license 15135 */ 15136 15137//>>label: uniqueId 15138//>>group: Core 15139//>>description: Functions to generate and remove uniqueId's 15140//>>docs: http://api.jqueryui.com/uniqueId/ 15141 15142 15143var uniqueId = $.fn.extend( { 15144 uniqueId: ( function() { 15145 var uuid = 0; 15146 15147 return function() { 15148 return this.each( function() { 15149 if ( !this.id ) { 15150 this.id = "ui-id-" + ( ++uuid ); 15151 } 15152 } ); 15153 }; 15154 } )(), 15155 15156 removeUniqueId: function() { 15157 return this.each( function() { 15158 if ( /^ui-id-\d+$/.test( this.id ) ) { 15159 $( this ).removeAttr( "id" ); 15160 } 15161 } ); 15162 } 15163} ); 15164 15165 15166/*! 15167 * jQuery UI Accordion 1.13.2 15168 * http://jqueryui.com 15169 * 15170 * Copyright jQuery Foundation and other contributors 15171 * Released under the MIT license. 15172 * http://jquery.org/license 15173 */ 15174 15175//>>label: Accordion 15176//>>group: Widgets 15177/* eslint-disable max-len */ 15178//>>description: Displays collapsible content panels for presenting information in a limited amount of space. 15179/* eslint-enable max-len */ 15180//>>docs: http://api.jqueryui.com/accordion/ 15181//>>demos: http://jqueryui.com/accordion/ 15182//>>css.structure: ../../themes/base/core.css 15183//>>css.structure: ../../themes/base/accordion.css 15184//>>css.theme: ../../themes/base/theme.css 15185 15186 15187var widgetsAccordion = $.widget( "ui.accordion", { 15188 version: "1.13.2", 15189 options: { 15190 active: 0, 15191 animate: {}, 15192 classes: { 15193 "ui-accordion-header": "ui-corner-top", 15194 "ui-accordion-header-collapsed": "ui-corner-all", 15195 "ui-accordion-content": "ui-corner-bottom" 15196 }, 15197 collapsible: false, 15198 event: "click", 15199 header: function( elem ) { 15200 return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); 15201 }, 15202 heightStyle: "auto", 15203 icons: { 15204 activeHeader: "ui-icon-triangle-1-s", 15205 header: "ui-icon-triangle-1-e" 15206 }, 15207 15208 // Callbacks 15209 activate: null, 15210 beforeActivate: null 15211 }, 15212 15213 hideProps: { 15214 borderTopWidth: "hide", 15215 borderBottomWidth: "hide", 15216 paddingTop: "hide", 15217 paddingBottom: "hide", 15218 height: "hide" 15219 }, 15220 15221 showProps: { 15222 borderTopWidth: "show", 15223 borderBottomWidth: "show", 15224 paddingTop: "show", 15225 paddingBottom: "show", 15226 height: "show" 15227 }, 15228 15229 _create: function() { 15230 var options = this.options; 15231 15232 this.prevShow = this.prevHide = $(); 15233 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); 15234 this.element.attr( "role", "tablist" ); 15235 15236 // Don't allow collapsible: false and active: false / null 15237 if ( !options.collapsible && ( options.active === false || options.active == null ) ) { 15238 options.active = 0; 15239 } 15240 15241 this._processPanels(); 15242 15243 // handle negative values 15244 if ( options.active < 0 ) { 15245 options.active += this.headers.length; 15246 } 15247 this._refresh(); 15248 }, 15249 15250 _getCreateEventData: function() { 15251 return { 15252 header: this.active, 15253 panel: !this.active.length ? $() : this.active.next() 15254 }; 15255 }, 15256 15257 _createIcons: function() { 15258 var icon, children, 15259 icons = this.options.icons; 15260 15261 if ( icons ) { 15262 icon = $( "<span>" ); 15263 this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); 15264 icon.prependTo( this.headers ); 15265 children = this.active.children( ".ui-accordion-header-icon" ); 15266 this._removeClass( children, icons.header ) 15267 ._addClass( children, null, icons.activeHeader ) 15268 ._addClass( this.headers, "ui-accordion-icons" ); 15269 } 15270 }, 15271 15272 _destroyIcons: function() { 15273 this._removeClass( this.headers, "ui-accordion-icons" ); 15274 this.headers.children( ".ui-accordion-header-icon" ).remove(); 15275 }, 15276 15277 _destroy: function() { 15278 var contents; 15279 15280 // Clean up main element 15281 this.element.removeAttr( "role" ); 15282 15283 // Clean up headers 15284 this.headers 15285 .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) 15286 .removeUniqueId(); 15287 15288 this._destroyIcons(); 15289 15290 // Clean up content panels 15291 contents = this.headers.next() 15292 .css( "display", "" ) 15293 .removeAttr( "role aria-hidden aria-labelledby" ) 15294 .removeUniqueId(); 15295 15296 if ( this.options.heightStyle !== "content" ) { 15297 contents.css( "height", "" ); 15298 } 15299 }, 15300 15301 _setOption: function( key, value ) { 15302 if ( key === "active" ) { 15303 15304 // _activate() will handle invalid values and update this.options 15305 this._activate( value ); 15306 return; 15307 } 15308 15309 if ( key === "event" ) { 15310 if ( this.options.event ) { 15311 this._off( this.headers, this.options.event ); 15312 } 15313 this._setupEvents( value ); 15314 } 15315 15316 this._super( key, value ); 15317 15318 // Setting collapsible: false while collapsed; open first panel 15319 if ( key === "collapsible" && !value && this.options.active === false ) { 15320 this._activate( 0 ); 15321 } 15322 15323 if ( key === "icons" ) { 15324 this._destroyIcons(); 15325 if ( value ) { 15326 this._createIcons(); 15327 } 15328 } 15329 }, 15330 15331 _setOptionDisabled: function( value ) { 15332 this._super( value ); 15333 15334 this.element.attr( "aria-disabled", value ); 15335 15336 // Support: IE8 Only 15337 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE 15338 // so we need to add the disabled class to the headers and panels 15339 this._toggleClass( null, "ui-state-disabled", !!value ); 15340 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", 15341 !!value ); 15342 }, 15343 15344 _keydown: function( event ) { 15345 if ( event.altKey || event.ctrlKey ) { 15346 return; 15347 } 15348 15349 var keyCode = $.ui.keyCode, 15350 length = this.headers.length, 15351 currentIndex = this.headers.index( event.target ), 15352 toFocus = false; 15353 15354 switch ( event.keyCode ) { 15355 case keyCode.RIGHT: 15356 case keyCode.DOWN: 15357 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; 15358 break; 15359 case keyCode.LEFT: 15360 case keyCode.UP: 15361 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; 15362 break; 15363 case keyCode.SPACE: 15364 case keyCode.ENTER: 15365 this._eventHandler( event ); 15366 break; 15367 case keyCode.HOME: 15368 toFocus = this.headers[ 0 ]; 15369 break; 15370 case keyCode.END: 15371 toFocus = this.headers[ length - 1 ]; 15372 break; 15373 } 15374 15375 if ( toFocus ) { 15376 $( event.target ).attr( "tabIndex", -1 ); 15377 $( toFocus ).attr( "tabIndex", 0 ); 15378 $( toFocus ).trigger( "focus" ); 15379 event.preventDefault(); 15380 } 15381 }, 15382 15383 _panelKeyDown: function( event ) { 15384 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { 15385 $( event.currentTarget ).prev().trigger( "focus" ); 15386 } 15387 }, 15388 15389 refresh: function() { 15390 var options = this.options; 15391 this._processPanels(); 15392 15393 // Was collapsed or no panel 15394 if ( ( options.active === false && options.collapsible === true ) || 15395 !this.headers.length ) { 15396 options.active = false; 15397 this.active = $(); 15398 15399 // active false only when collapsible is true 15400 } else if ( options.active === false ) { 15401 this._activate( 0 ); 15402 15403 // was active, but active panel is gone 15404 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 15405 15406 // all remaining panel are disabled 15407 if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { 15408 options.active = false; 15409 this.active = $(); 15410 15411 // activate previous panel 15412 } else { 15413 this._activate( Math.max( 0, options.active - 1 ) ); 15414 } 15415 15416 // was active, active panel still exists 15417 } else { 15418 15419 // make sure active index is correct 15420 options.active = this.headers.index( this.active ); 15421 } 15422 15423 this._destroyIcons(); 15424 15425 this._refresh();
vendor: 6,928 bytes, lines 15426-15667
15426 }, 15427 15428 _processPanels: function() { 15429 var prevHeaders = this.headers, 15430 prevPanels = this.panels; 15431 15432 if ( typeof this.options.header === "function" ) { 15433 this.headers = this.options.header( this.element ); 15434 } else { 15435 this.headers = this.element.find( this.options.header ); 15436 } 15437 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", 15438 "ui-state-default" ); 15439 15440 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); 15441 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); 15442 15443 // Avoid memory leaks (#10056) 15444 if ( prevPanels ) { 15445 this._off( prevHeaders.not( this.headers ) ); 15446 this._off( prevPanels.not( this.panels ) ); 15447 } 15448 }, 15449 15450 _refresh: function() { 15451 var maxHeight, 15452 options = this.options, 15453 heightStyle = options.heightStyle, 15454 parent = this.element.parent(); 15455 15456 this.active = this._findActive( options.active ); 15457 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) 15458 ._removeClass( this.active, "ui-accordion-header-collapsed" ); 15459 this._addClass( this.active.next(), "ui-accordion-content-active" ); 15460 this.active.next().show(); 15461 15462 this.headers 15463 .attr( "role", "tab" ) 15464 .each( function() { 15465 var header = $( this ), 15466 headerId = header.uniqueId().attr( "id" ), 15467 panel = header.next(), 15468 panelId = panel.uniqueId().attr( "id" ); 15469 header.attr( "aria-controls", panelId ); 15470 panel.attr( "aria-labelledby", headerId ); 15471 } ) 15472 .next() 15473 .attr( "role", "tabpanel" ); 15474 15475 this.headers 15476 .not( this.active ) 15477 .attr( { 15478 "aria-selected": "false", 15479 "aria-expanded": "false", 15480 tabIndex: -1 15481 } ) 15482 .next() 15483 .attr( { 15484 "aria-hidden": "true" 15485 } ) 15486 .hide(); 15487 15488 // Make sure at least one header is in the tab order 15489 if ( !this.active.length ) { 15490 this.headers.eq( 0 ).attr( "tabIndex", 0 ); 15491 } else { 15492 this.active.attr( { 15493 "aria-selected": "true", 15494 "aria-expanded": "true", 15495 tabIndex: 0 15496 } ) 15497 .next() 15498 .attr( { 15499 "aria-hidden": "false" 15500 } ); 15501 } 15502 15503 this._createIcons(); 15504 15505 this._setupEvents( options.event ); 15506 15507 if ( heightStyle === "fill" ) { 15508 maxHeight = parent.height(); 15509 this.element.siblings( ":visible" ).each( function() { 15510 var elem = $( this ), 15511 position = elem.css( "position" ); 15512 15513 if ( position === "absolute" || position === "fixed" ) { 15514 return; 15515 } 15516 maxHeight -= elem.outerHeight( true ); 15517 } ); 15518 15519 this.headers.each( function() { 15520 maxHeight -= $( this ).outerHeight( true ); 15521 } ); 15522 15523 this.headers.next() 15524 .each( function() { 15525 $( this ).height( Math.max( 0, maxHeight - 15526 $( this ).innerHeight() + $( this ).height() ) ); 15527 } ) 15528 .css( "overflow", "auto" ); 15529 } else if ( heightStyle === "auto" ) { 15530 maxHeight = 0; 15531 this.headers.next() 15532 .each( function() { 15533 var isVisible = $( this ).is( ":visible" ); 15534 if ( !isVisible ) { 15535 $( this ).show(); 15536 } 15537 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); 15538 if ( !isVisible ) { 15539 $( this ).hide(); 15540 } 15541 } ) 15542 .height( maxHeight ); 15543 } 15544 }, 15545 15546 _activate: function( index ) { 15547 var active = this._findActive( index )[ 0 ]; 15548 15549 // Trying to activate the already active panel 15550 if ( active === this.active[ 0 ] ) { 15551 return; 15552 } 15553 15554 // Trying to collapse, simulate a click on the currently active header 15555 active = active || this.active[ 0 ]; 15556 15557 this._eventHandler( { 15558 target: active, 15559 currentTarget: active, 15560 preventDefault: $.noop 15561 } ); 15562 }, 15563 15564 _findActive: function( selector ) { 15565 return typeof selector === "number" ? this.headers.eq( selector ) : $(); 15566 }, 15567 15568 _setupEvents: function( event ) { 15569 var events = { 15570 keydown: "_keydown" 15571 }; 15572 if ( event ) { 15573 $.each( event.split( " " ), function( index, eventName ) { 15574 events[ eventName ] = "_eventHandler"; 15575 } ); 15576 } 15577 15578 this._off( this.headers.add( this.headers.next() ) ); 15579 this._on( this.headers, events ); 15580 this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); 15581 this._hoverable( this.headers ); 15582 this._focusable( this.headers ); 15583 }, 15584 15585 _eventHandler: function( event ) { 15586 var activeChildren, clickedChildren, 15587 options = this.options, 15588 active = this.active, 15589 clicked = $( event.currentTarget ), 15590 clickedIsActive = clicked[ 0 ] === active[ 0 ], 15591 collapsing = clickedIsActive && options.collapsible, 15592 toShow = collapsing ? $() : clicked.next(), 15593 toHide = active.next(), 15594 eventData = { 15595 oldHeader: active, 15596 oldPanel: toHide, 15597 newHeader: collapsing ? $() : clicked, 15598 newPanel: toShow 15599 }; 15600 15601 event.preventDefault(); 15602 15603 if ( 15604 15605 // click on active header, but not collapsible 15606 ( clickedIsActive && !options.collapsible ) || 15607 15608 // allow canceling activation 15609 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 15610 return; 15611 } 15612 15613 options.active = collapsing ? false : this.headers.index( clicked ); 15614 15615 // When the call to ._toggle() comes after the class changes 15616 // it causes a very odd bug in IE 8 (see #6720) 15617 this.active = clickedIsActive ? $() : clicked; 15618 this._toggle( eventData ); 15619 15620 // Switch classes 15621 // corner classes on the previously active header stay after the animation 15622 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); 15623 if ( options.icons ) { 15624 activeChildren = active.children( ".ui-accordion-header-icon" ); 15625 this._removeClass( activeChildren, null, options.icons.activeHeader ) 15626 ._addClass( activeChildren, null, options.icons.header ); 15627 } 15628 15629 if ( !clickedIsActive ) { 15630 this._removeClass( clicked, "ui-accordion-header-collapsed" ) 15631 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); 15632 if ( options.icons ) { 15633 clickedChildren = clicked.children( ".ui-accordion-header-icon" ); 15634 this._removeClass( clickedChildren, null, options.icons.header ) 15635 ._addClass( clickedChildren, null, options.icons.activeHeader ); 15636 } 15637 15638 this._addClass( clicked.next(), "ui-accordion-content-active" ); 15639 } 15640 }, 15641 15642 _toggle: function( data ) { 15643 var toShow = data.newPanel, 15644 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; 15645 15646 // Handle activating a panel during the animation for another activation 15647 this.prevShow.add( this.prevHide ).stop( true, true ); 15648 this.prevShow = toShow; 15649 this.prevHide = toHide; 15650 15651 if ( this.options.animate ) { 15652 this._animate( toShow, toHide, data ); 15653 } else { 15654 toHide.hide(); 15655 toShow.show(); 15656 this._toggleComplete( data ); 15657 } 15658 15659 toHide.attr( { 15660 "aria-hidden": "true" 15661 } ); 15662 toHide.prev().attr( { 15663 "aria-selected": "false", 15664 "aria-expanded": "false" 15665 } ); 15666 15667 // if we're switching panels, remove the old header from the tab order
vendor: 6,870 bytes, lines 15668-15919
15668 // if we're opening from collapsed state, remove the previous header from the tab order 15669 // if we're collapsing, then keep the collapsing header in the tab order 15670 if ( toShow.length && toHide.length ) { 15671 toHide.prev().attr( { 15672 "tabIndex": -1, 15673 "aria-expanded": "false" 15674 } ); 15675 } else if ( toShow.length ) { 15676 this.headers.filter( function() { 15677 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; 15678 } ) 15679 .attr( "tabIndex", -1 ); 15680 } 15681 15682 toShow 15683 .attr( "aria-hidden", "false" ) 15684 .prev() 15685 .attr( { 15686 "aria-selected": "true", 15687 "aria-expanded": "true", 15688 tabIndex: 0 15689 } ); 15690 }, 15691 15692 _animate: function( toShow, toHide, data ) { 15693 var total, easing, duration, 15694 that = this, 15695 adjust = 0, 15696 boxSizing = toShow.css( "box-sizing" ), 15697 down = toShow.length && 15698 ( !toHide.length || ( toShow.index() < toHide.index() ) ), 15699 animate = this.options.animate || {}, 15700 options = down && animate.down || animate, 15701 complete = function() { 15702 that._toggleComplete( data ); 15703 }; 15704 15705 if ( typeof options === "number" ) { 15706 duration = options; 15707 } 15708 if ( typeof options === "string" ) { 15709 easing = options; 15710 } 15711 15712 // fall back from options to animation in case of partial down settings 15713 easing = easing || options.easing || animate.easing; 15714 duration = duration || options.duration || animate.duration; 15715 15716 if ( !toHide.length ) { 15717 return toShow.animate( this.showProps, duration, easing, complete ); 15718 } 15719 if ( !toShow.length ) { 15720 return toHide.animate( this.hideProps, duration, easing, complete ); 15721 } 15722 15723 total = toShow.show().outerHeight(); 15724 toHide.animate( this.hideProps, { 15725 duration: duration, 15726 easing: easing, 15727 step: function( now, fx ) { 15728 fx.now = Math.round( now ); 15729 } 15730 } ); 15731 toShow 15732 .hide() 15733 .animate( this.showProps, { 15734 duration: duration, 15735 easing: easing, 15736 complete: complete, 15737 step: function( now, fx ) { 15738 fx.now = Math.round( now ); 15739 if ( fx.prop !== "height" ) { 15740 if ( boxSizing === "content-box" ) { 15741 adjust += fx.now; 15742 } 15743 } else if ( that.options.heightStyle !== "content" ) { 15744 fx.now = Math.round( total - toHide.outerHeight() - adjust ); 15745 adjust = 0; 15746 } 15747 } 15748 } ); 15749 }, 15750 15751 _toggleComplete: function( data ) { 15752 var toHide = data.oldPanel, 15753 prev = toHide.prev(); 15754 15755 this._removeClass( toHide, "ui-accordion-content-active" ); 15756 this._removeClass( prev, "ui-accordion-header-active" ) 15757 ._addClass( prev, "ui-accordion-header-collapsed" ); 15758 15759 // Work around for rendering bug in IE (#5421) 15760 if ( toHide.length ) { 15761 toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; 15762 } 15763 this._trigger( "activate", null, data ); 15764 } 15765} ); 15766 15767 15768 15769var safeActiveElement = $.ui.safeActiveElement = function( document ) { 15770 var activeElement; 15771 15772 // Support: IE 9 only 15773 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> 15774 try { 15775 activeElement = document.activeElement; 15776 } catch ( error ) { 15777 activeElement = document.body; 15778 } 15779 15780 // Support: IE 9 - 11 only 15781 // IE may return null instead of an element 15782 // Interestingly, this only seems to occur when NOT in an iframe 15783 if ( !activeElement ) { 15784 activeElement = document.body; 15785 } 15786 15787 // Support: IE 11 only 15788 // IE11 returns a seemingly empty object in some cases when accessing 15789 // document.activeElement from an <iframe> 15790 if ( !activeElement.nodeName ) { 15791 activeElement = document.body; 15792 } 15793 15794 return activeElement; 15795}; 15796 15797 15798/*! 15799 * jQuery UI Menu 1.13.2 15800 * http://jqueryui.com 15801 * 15802 * Copyright jQuery Foundation and other contributors 15803 * Released under the MIT license. 15804 * http://jquery.org/license 15805 */ 15806 15807//>>label: Menu 15808//>>group: Widgets 15809//>>description: Creates nestable menus. 15810//>>docs: http://api.jqueryui.com/menu/ 15811//>>demos: http://jqueryui.com/menu/ 15812//>>css.structure: ../../themes/base/core.css 15813//>>css.structure: ../../themes/base/menu.css 15814//>>css.theme: ../../themes/base/theme.css 15815 15816 15817var widgetsMenu = $.widget( "ui.menu", { 15818 version: "1.13.2", 15819 defaultElement: "<ul>", 15820 delay: 300, 15821 options: { 15822 icons: { 15823 submenu: "ui-icon-caret-1-e" 15824 }, 15825 items: "> *", 15826 menus: "ul", 15827 position: { 15828 my: "left top", 15829 at: "right top" 15830 }, 15831 role: "menu", 15832 15833 // Callbacks 15834 blur: null, 15835 focus: null, 15836 select: null 15837 }, 15838 15839 _create: function() { 15840 this.activeMenu = this.element; 15841 15842 // Flag used to prevent firing of the click handler 15843 // as the event bubbles up through nested menus 15844 this.mouseHandled = false; 15845 this.lastMousePosition = { x: null, y: null }; 15846 this.element 15847 .uniqueId() 15848 .attr( { 15849 role: this.options.role, 15850 tabIndex: 0 15851 } ); 15852 15853 this._addClass( "ui-menu", "ui-widget ui-widget-content" ); 15854 this._on( { 15855 15856 // Prevent focus from sticking to links inside menu after clicking 15857 // them (focus should always stay on UL during navigation). 15858 "mousedown .ui-menu-item": function( event ) { 15859 event.preventDefault(); 15860 15861 this._activateItem( event ); 15862 }, 15863 "click .ui-menu-item": function( event ) { 15864 var target = $( event.target ); 15865 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 15866 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { 15867 this.select( event ); 15868 15869 // Only set the mouseHandled flag if the event will bubble, see #9469. 15870 if ( !event.isPropagationStopped() ) { 15871 this.mouseHandled = true; 15872 } 15873 15874 // Open submenu on click 15875 if ( target.has( ".ui-menu" ).length ) { 15876 this.expand( event ); 15877 } else if ( !this.element.is( ":focus" ) && 15878 active.closest( ".ui-menu" ).length ) { 15879 15880 // Redirect focus to the menu 15881 this.element.trigger( "focus", [ true ] ); 15882 15883 // If the active item is on the top level, let it stay active. 15884 // Otherwise, blur the active item since it is no longer visible. 15885 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { 15886 clearTimeout( this.timer ); 15887 } 15888 } 15889 } 15890 }, 15891 "mouseenter .ui-menu-item": "_activateItem", 15892 "mousemove .ui-menu-item": "_activateItem", 15893 mouseleave: "collapseAll", 15894 "mouseleave .ui-menu": "collapseAll", 15895 focus: function( event, keepActiveItem ) { 15896 15897 // If there's already an active item, keep it active 15898 // If not, activate the first item 15899 var item = this.active || this._menuItems().first(); 15900 15901 if ( !keepActiveItem ) { 15902 this.focus( event, item ); 15903 } 15904 }, 15905 blur: function( event ) { 15906 this._delay( function() { 15907 var notContained = !$.contains( 15908 this.element[ 0 ], 15909 $.ui.safeActiveElement( this.document[ 0 ] ) 15910 ); 15911 if ( notContained ) { 15912 this.collapseAll( event ); 15913 } 15914 } ); 15915 }, 15916 keydown: "_keydown" 15917 } ); 15918 15919 this.refresh();
vendor: 13,612 bytes, lines 15920-16408
15920 15921 // Clicks outside of a menu collapse any open menus 15922 this._on( this.document, { 15923 click: function( event ) { 15924 if ( this._closeOnDocumentClick( event ) ) { 15925 this.collapseAll( event, true ); 15926 } 15927 15928 // Reset the mouseHandled flag 15929 this.mouseHandled = false; 15930 } 15931 } ); 15932 }, 15933 15934 _activateItem: function( event ) { 15935 15936 // Ignore mouse events while typeahead is active, see #10458. 15937 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse 15938 // is over an item in the menu 15939 if ( this.previousFilter ) { 15940 return; 15941 } 15942 15943 // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) 15944 if ( event.clientX === this.lastMousePosition.x && 15945 event.clientY === this.lastMousePosition.y ) { 15946 return; 15947 } 15948 15949 this.lastMousePosition = { 15950 x: event.clientX, 15951 y: event.clientY 15952 }; 15953 15954 var actualTarget = $( event.target ).closest( ".ui-menu-item" ), 15955 target = $( event.currentTarget ); 15956 15957 // Ignore bubbled events on parent items, see #11641 15958 if ( actualTarget[ 0 ] !== target[ 0 ] ) { 15959 return; 15960 } 15961 15962 // If the item is already active, there's nothing to do 15963 if ( target.is( ".ui-state-active" ) ) { 15964 return; 15965 } 15966 15967 // Remove ui-state-active class from siblings of the newly focused menu item 15968 // to avoid a jump caused by adjacent elements both having a class with a border 15969 this._removeClass( target.siblings().children( ".ui-state-active" ), 15970 null, "ui-state-active" ); 15971 this.focus( event, target ); 15972 }, 15973 15974 _destroy: function() { 15975 var items = this.element.find( ".ui-menu-item" ) 15976 .removeAttr( "role aria-disabled" ), 15977 submenus = items.children( ".ui-menu-item-wrapper" ) 15978 .removeUniqueId() 15979 .removeAttr( "tabIndex role aria-haspopup" ); 15980 15981 // Destroy (sub)menus 15982 this.element 15983 .removeAttr( "aria-activedescendant" ) 15984 .find( ".ui-menu" ).addBack() 15985 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + 15986 "tabIndex" ) 15987 .removeUniqueId() 15988 .show(); 15989 15990 submenus.children().each( function() { 15991 var elem = $( this ); 15992 if ( elem.data( "ui-menu-submenu-caret" ) ) { 15993 elem.remove(); 15994 } 15995 } ); 15996 }, 15997 15998 _keydown: function( event ) { 15999 var match, prev, character, skip, 16000 preventDefault = true; 16001 16002 switch ( event.keyCode ) { 16003 case $.ui.keyCode.PAGE_UP: 16004 this.previousPage( event ); 16005 break; 16006 case $.ui.keyCode.PAGE_DOWN: 16007 this.nextPage( event ); 16008 break; 16009 case $.ui.keyCode.HOME: 16010 this._move( "first", "first", event ); 16011 break; 16012 case $.ui.keyCode.END: 16013 this._move( "last", "last", event ); 16014 break; 16015 case $.ui.keyCode.UP: 16016 this.previous( event ); 16017 break; 16018 case $.ui.keyCode.DOWN: 16019 this.next( event ); 16020 break; 16021 case $.ui.keyCode.LEFT: 16022 this.collapse( event ); 16023 break; 16024 case $.ui.keyCode.RIGHT: 16025 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 16026 this.expand( event ); 16027 } 16028 break; 16029 case $.ui.keyCode.ENTER: 16030 case $.ui.keyCode.SPACE: 16031 this._activate( event ); 16032 break; 16033 case $.ui.keyCode.ESCAPE: 16034 this.collapse( event ); 16035 break; 16036 default: 16037 preventDefault = false; 16038 prev = this.previousFilter || ""; 16039 skip = false; 16040 16041 // Support number pad values 16042 character = event.keyCode >= 96 && event.keyCode <= 105 ? 16043 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); 16044 16045 clearTimeout( this.filterTimer ); 16046 16047 if ( character === prev ) { 16048 skip = true; 16049 } else { 16050 character = prev + character; 16051 } 16052 16053 match = this._filterMenuItems( character ); 16054 match = skip && match.index( this.active.next() ) !== -1 ? 16055 this.active.nextAll( ".ui-menu-item" ) : 16056 match; 16057 16058 // If no matches on the current filter, reset to the last character pressed 16059 // to move down the menu to the first item that starts with that character 16060 if ( !match.length ) { 16061 character = String.fromCharCode( event.keyCode ); 16062 match = this._filterMenuItems( character ); 16063 } 16064 16065 if ( match.length ) { 16066 this.focus( event, match ); 16067 this.previousFilter = character; 16068 this.filterTimer = this._delay( function() { 16069 delete this.previousFilter; 16070 }, 1000 ); 16071 } else { 16072 delete this.previousFilter; 16073 } 16074 } 16075 16076 if ( preventDefault ) { 16077 event.preventDefault(); 16078 } 16079 }, 16080 16081 _activate: function( event ) { 16082 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { 16083 if ( this.active.children( "[aria-haspopup='true']" ).length ) { 16084 this.expand( event ); 16085 } else { 16086 this.select( event ); 16087 } 16088 } 16089 }, 16090 16091 refresh: function() { 16092 var menus, items, newSubmenus, newItems, newWrappers, 16093 that = this, 16094 icon = this.options.icons.submenu, 16095 submenus = this.element.find( this.options.menus ); 16096 16097 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); 16098 16099 // Initialize nested menus 16100 newSubmenus = submenus.filter( ":not(.ui-menu)" ) 16101 .hide() 16102 .attr( { 16103 role: this.options.role, 16104 "aria-hidden": "true", 16105 "aria-expanded": "false" 16106 } ) 16107 .each( function() { 16108 var menu = $( this ), 16109 item = menu.prev(), 16110 submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); 16111 16112 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); 16113 item 16114 .attr( "aria-haspopup", "true" ) 16115 .prepend( submenuCaret ); 16116 menu.attr( "aria-labelledby", item.attr( "id" ) ); 16117 } ); 16118 16119 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); 16120 16121 menus = submenus.add( this.element ); 16122 items = menus.find( this.options.items ); 16123 16124 // Initialize menu-items containing spaces and/or dashes only as dividers 16125 items.not( ".ui-menu-item" ).each( function() { 16126 var item = $( this ); 16127 if ( that._isDivider( item ) ) { 16128 that._addClass( item, "ui-menu-divider", "ui-widget-content" ); 16129 } 16130 } ); 16131 16132 // Don't refresh list items that are already adapted 16133 newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); 16134 newWrappers = newItems.children() 16135 .not( ".ui-menu" ) 16136 .uniqueId() 16137 .attr( { 16138 tabIndex: -1, 16139 role: this._itemRole() 16140 } ); 16141 this._addClass( newItems, "ui-menu-item" ) 16142 ._addClass( newWrappers, "ui-menu-item-wrapper" ); 16143 16144 // Add aria-disabled attribute to any disabled menu item 16145 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); 16146 16147 // If the active item has been removed, blur the menu 16148 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { 16149 this.blur(); 16150 } 16151 }, 16152 16153 _itemRole: function() { 16154 return { 16155 menu: "menuitem", 16156 listbox: "option" 16157 }[ this.options.role ]; 16158 }, 16159 16160 _setOption: function( key, value ) { 16161 if ( key === "icons" ) { 16162 var icons = this.element.find( ".ui-menu-icon" ); 16163 this._removeClass( icons, null, this.options.icons.submenu ) 16164 ._addClass( icons, null, value.submenu ); 16165 } 16166 this._super( key, value ); 16167 }, 16168 16169 _setOptionDisabled: function( value ) { 16170 this._super( value ); 16171 16172 this.element.attr( "aria-disabled", String( value ) ); 16173 this._toggleClass( null, "ui-state-disabled", !!value ); 16174 }, 16175 16176 focus: function( event, item ) { 16177 var nested, focused, activeParent; 16178 this.blur( event, event && event.type === "focus" ); 16179 16180 this._scrollIntoView( item ); 16181 16182 this.active = item.first(); 16183 16184 focused = this.active.children( ".ui-menu-item-wrapper" ); 16185 this._addClass( focused, null, "ui-state-active" ); 16186 16187 // Only update aria-activedescendant if there's a role 16188 // otherwise we assume focus is managed elsewhere 16189 if ( this.options.role ) { 16190 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); 16191 } 16192 16193 // Highlight active parent menu item, if any 16194 activeParent = this.active 16195 .parent() 16196 .closest( ".ui-menu-item" ) 16197 .children( ".ui-menu-item-wrapper" ); 16198 this._addClass( activeParent, null, "ui-state-active" ); 16199 16200 if ( event && event.type === "keydown" ) { 16201 this._close(); 16202 } else { 16203 this.timer = this._delay( function() { 16204 this._close(); 16205 }, this.delay ); 16206 } 16207 16208 nested = item.children( ".ui-menu" ); 16209 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { 16210 this._startOpening( nested ); 16211 } 16212 this.activeMenu = item.parent(); 16213 16214 this._trigger( "focus", event, { item: item } ); 16215 }, 16216 16217 _scrollIntoView: function( item ) { 16218 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; 16219 if ( this._hasScroll() ) { 16220 borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; 16221 paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; 16222 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; 16223 scroll = this.activeMenu.scrollTop(); 16224 elementHeight = this.activeMenu.height(); 16225 itemHeight = item.outerHeight(); 16226 16227 if ( offset < 0 ) { 16228 this.activeMenu.scrollTop( scroll + offset ); 16229 } else if ( offset + itemHeight > elementHeight ) { 16230 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); 16231 } 16232 } 16233 }, 16234 16235 blur: function( event, fromFocus ) { 16236 if ( !fromFocus ) { 16237 clearTimeout( this.timer ); 16238 } 16239 16240 if ( !this.active ) { 16241 return; 16242 } 16243 16244 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), 16245 null, "ui-state-active" ); 16246 16247 this._trigger( "blur", event, { item: this.active } ); 16248 this.active = null; 16249 }, 16250 16251 _startOpening: function( submenu ) { 16252 clearTimeout( this.timer ); 16253 16254 // Don't open if already open fixes a Firefox bug that caused a .5 pixel 16255 // shift in the submenu position when mousing over the caret icon 16256 if ( submenu.attr( "aria-hidden" ) !== "true" ) { 16257 return; 16258 } 16259 16260 this.timer = this._delay( function() { 16261 this._close(); 16262 this._open( submenu ); 16263 }, this.delay ); 16264 }, 16265 16266 _open: function( submenu ) { 16267 var position = $.extend( { 16268 of: this.active 16269 }, this.options.position ); 16270 16271 clearTimeout( this.timer ); 16272 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) 16273 .hide() 16274 .attr( "aria-hidden", "true" ); 16275 16276 submenu 16277 .show() 16278 .removeAttr( "aria-hidden" ) 16279 .attr( "aria-expanded", "true" ) 16280 .position( position ); 16281 }, 16282 16283 collapseAll: function( event, all ) { 16284 clearTimeout( this.timer ); 16285 this.timer = this._delay( function() { 16286 16287 // If we were passed an event, look for the submenu that contains the event 16288 var currentMenu = all ? this.element : 16289 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); 16290 16291 // If we found no valid submenu ancestor, use the main menu to close all 16292 // sub menus anyway 16293 if ( !currentMenu.length ) { 16294 currentMenu = this.element; 16295 } 16296 16297 this._close( currentMenu ); 16298 16299 this.blur( event ); 16300 16301 // Work around active item staying active after menu is blurred 16302 this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); 16303 16304 this.activeMenu = currentMenu; 16305 }, all ? 0 : this.delay ); 16306 }, 16307 16308 // With no arguments, closes the currently active menu - if nothing is active 16309 // it closes all menus. If passed an argument, it will search for menus BELOW 16310 _close: function( startMenu ) { 16311 if ( !startMenu ) { 16312 startMenu = this.active ? this.active.parent() : this.element; 16313 } 16314 16315 startMenu.find( ".ui-menu" ) 16316 .hide() 16317 .attr( "aria-hidden", "true" ) 16318 .attr( "aria-expanded", "false" ); 16319 }, 16320 16321 _closeOnDocumentClick: function( event ) { 16322 return !$( event.target ).closest( ".ui-menu" ).length; 16323 }, 16324 16325 _isDivider: function( item ) { 16326 16327 // Match hyphen, em dash, en dash 16328 return !/[^\-\u2014\u2013\s]/.test( item.text() ); 16329 }, 16330 16331 collapse: function( event ) { 16332 var newItem = this.active && 16333 this.active.parent().closest( ".ui-menu-item", this.element ); 16334 if ( newItem && newItem.length ) { 16335 this._close(); 16336 this.focus( event, newItem ); 16337 } 16338 }, 16339 16340 expand: function( event ) { 16341 var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); 16342 16343 if ( newItem && newItem.length ) { 16344 this._open( newItem.parent() ); 16345 16346 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT 16347 this._delay( function() { 16348 this.focus( event, newItem ); 16349 } ); 16350 } 16351 }, 16352 16353 next: function( event ) { 16354 this._move( "next", "first", event ); 16355 }, 16356 16357 previous: function( event ) { 16358 this._move( "prev", "last", event ); 16359 }, 16360 16361 isFirstItem: function() { 16362 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; 16363 }, 16364 16365 isLastItem: function() { 16366 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; 16367 }, 16368 16369 _menuItems: function( menu ) { 16370 return ( menu || this.element ) 16371 .find( this.options.items ) 16372 .filter( ".ui-menu-item" ); 16373 }, 16374 16375 _move: function( direction, filter, event ) { 16376 var next; 16377 if ( this.active ) { 16378 if ( direction === "first" || direction === "last" ) { 16379 next = this.active 16380 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) 16381 .last(); 16382 } else { 16383 next = this.active 16384 [ direction + "All" ]( ".ui-menu-item" ) 16385 .first(); 16386 } 16387 } 16388 if ( !next || !next.length || !this.active ) { 16389 next = this._menuItems( this.activeMenu )[ filter ](); 16390 } 16391 16392 this.focus( event, next ); 16393 }, 16394 16395 nextPage: function( event ) { 16396 var item, base, height; 16397 16398 if ( !this.active ) { 16399 this.next( event ); 16400 return; 16401 } 16402 if ( this.isLastItem() ) { 16403 return; 16404 } 16405 if ( this._hasScroll() ) { 16406 base = this.active.offset().top; 16407 height = this.element.innerHeight(); 16408
vendor: 20,225 bytes, lines 16409-17147
16409 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 16410 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 16411 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 16412 } 16413 16414 this.active.nextAll( ".ui-menu-item" ).each( function() { 16415 item = $( this ); 16416 return item.offset().top - base - height < 0; 16417 } ); 16418 16419 this.focus( event, item ); 16420 } else { 16421 this.focus( event, this._menuItems( this.activeMenu ) 16422 [ !this.active ? "first" : "last" ]() ); 16423 } 16424 }, 16425 16426 previousPage: function( event ) { 16427 var item, base, height; 16428 if ( !this.active ) { 16429 this.next( event ); 16430 return; 16431 } 16432 if ( this.isFirstItem() ) { 16433 return; 16434 } 16435 if ( this._hasScroll() ) { 16436 base = this.active.offset().top; 16437 height = this.element.innerHeight(); 16438 16439 // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. 16440 if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { 16441 height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); 16442 } 16443 16444 this.active.prevAll( ".ui-menu-item" ).each( function() { 16445 item = $( this ); 16446 return item.offset().top - base + height > 0; 16447 } ); 16448 16449 this.focus( event, item ); 16450 } else { 16451 this.focus( event, this._menuItems( this.activeMenu ).first() ); 16452 } 16453 }, 16454 16455 _hasScroll: function() { 16456 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); 16457 }, 16458 16459 select: function( event ) { 16460 16461 // TODO: It should never be possible to not have an active item at this 16462 // point, but the tests don't trigger mouseenter before click. 16463 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); 16464 var ui = { item: this.active }; 16465 if ( !this.active.has( ".ui-menu" ).length ) { 16466 this.collapseAll( event, true ); 16467 } 16468 this._trigger( "select", event, ui ); 16469 }, 16470 16471 _filterMenuItems: function( character ) { 16472 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), 16473 regex = new RegExp( "^" + escapedCharacter, "i" ); 16474 16475 return this.activeMenu 16476 .find( this.options.items ) 16477 16478 // Only match on items, not dividers or other content (#10571) 16479 .filter( ".ui-menu-item" ) 16480 .filter( function() { 16481 return regex.test( 16482 String.prototype.trim.call( 16483 $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); 16484 } ); 16485 } 16486} ); 16487 16488 16489/*! 16490 * jQuery UI Autocomplete 1.13.2 16491 * http://jqueryui.com 16492 * 16493 * Copyright jQuery Foundation and other contributors 16494 * Released under the MIT license. 16495 * http://jquery.org/license 16496 */ 16497 16498//>>label: Autocomplete 16499//>>group: Widgets 16500//>>description: Lists suggested words as the user is typing. 16501//>>docs: http://api.jqueryui.com/autocomplete/ 16502//>>demos: http://jqueryui.com/autocomplete/ 16503//>>css.structure: ../../themes/base/core.css 16504//>>css.structure: ../../themes/base/autocomplete.css 16505//>>css.theme: ../../themes/base/theme.css 16506 16507 16508$.widget( "ui.autocomplete", { 16509 version: "1.13.2", 16510 defaultElement: "<input>", 16511 options: { 16512 appendTo: null, 16513 autoFocus: false, 16514 delay: 300, 16515 minLength: 1, 16516 position: { 16517 my: "left top", 16518 at: "left bottom", 16519 collision: "none" 16520 }, 16521 source: null, 16522 16523 // Callbacks 16524 change: null, 16525 close: null, 16526 focus: null, 16527 open: null, 16528 response: null, 16529 search: null, 16530 select: null 16531 }, 16532 16533 requestIndex: 0, 16534 pending: 0, 16535 liveRegionTimer: null, 16536 16537 _create: function() { 16538 16539 // Some browsers only repeat keydown events, not keypress events, 16540 // so we use the suppressKeyPress flag to determine if we've already 16541 // handled the keydown event. #7269 16542 // Unfortunately the code for & in keypress is the same as the up arrow, 16543 // so we use the suppressKeyPressRepeat flag to avoid handling keypress 16544 // events when we know the keydown event was used to modify the 16545 // search term. #7799 16546 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, 16547 nodeName = this.element[ 0 ].nodeName.toLowerCase(), 16548 isTextarea = nodeName === "textarea", 16549 isInput = nodeName === "input"; 16550 16551 // Textareas are always multi-line 16552 // Inputs are always single-line, even if inside a contentEditable element 16553 // IE also treats inputs as contentEditable 16554 // All other element types are determined by whether or not they're contentEditable 16555 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); 16556 16557 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; 16558 this.isNewMenu = true; 16559 16560 this._addClass( "ui-autocomplete-input" ); 16561 this.element.attr( "autocomplete", "off" ); 16562 16563 this._on( this.element, { 16564 keydown: function( event ) { 16565 if ( this.element.prop( "readOnly" ) ) { 16566 suppressKeyPress = true; 16567 suppressInput = true; 16568 suppressKeyPressRepeat = true; 16569 return; 16570 } 16571 16572 suppressKeyPress = false; 16573 suppressInput = false; 16574 suppressKeyPressRepeat = false; 16575 var keyCode = $.ui.keyCode; 16576 switch ( event.keyCode ) { 16577 case keyCode.PAGE_UP: 16578 suppressKeyPress = true; 16579 this._move( "previousPage", event ); 16580 break; 16581 case keyCode.PAGE_DOWN: 16582 suppressKeyPress = true; 16583 this._move( "nextPage", event ); 16584 break; 16585 case keyCode.UP: 16586 suppressKeyPress = true; 16587 this._keyEvent( "previous", event ); 16588 break; 16589 case keyCode.DOWN: 16590 suppressKeyPress = true; 16591 this._keyEvent( "next", event ); 16592 break; 16593 case keyCode.ENTER: 16594 16595 // when menu is open and has focus 16596 if ( this.menu.active ) { 16597 16598 // #6055 - Opera still allows the keypress to occur 16599 // which causes forms to submit 16600 suppressKeyPress = true; 16601 event.preventDefault(); 16602 this.menu.select( event ); 16603 } 16604 break; 16605 case keyCode.TAB: 16606 if ( this.menu.active ) { 16607 this.menu.select( event ); 16608 } 16609 break; 16610 case keyCode.ESCAPE: 16611 if ( this.menu.element.is( ":visible" ) ) { 16612 if ( !this.isMultiLine ) { 16613 this._value( this.term ); 16614 } 16615 this.close( event ); 16616 16617 // Different browsers have different default behavior for escape 16618 // Single press can mean undo or clear 16619 // Double press in IE means clear the whole form 16620 event.preventDefault(); 16621 } 16622 break; 16623 default: 16624 suppressKeyPressRepeat = true; 16625 16626 // search timeout should be triggered before the input value is changed 16627 this._searchTimeout( event ); 16628 break; 16629 } 16630 }, 16631 keypress: function( event ) { 16632 if ( suppressKeyPress ) { 16633 suppressKeyPress = false; 16634 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 16635 event.preventDefault(); 16636 } 16637 return; 16638 } 16639 if ( suppressKeyPressRepeat ) { 16640 return; 16641 } 16642 16643 // Replicate some key handlers to allow them to repeat in Firefox and Opera 16644 var keyCode = $.ui.keyCode; 16645 switch ( event.keyCode ) { 16646 case keyCode.PAGE_UP: 16647 this._move( "previousPage", event ); 16648 break; 16649 case keyCode.PAGE_DOWN: 16650 this._move( "nextPage", event ); 16651 break; 16652 case keyCode.UP: 16653 this._keyEvent( "previous", event ); 16654 break; 16655 case keyCode.DOWN: 16656 this._keyEvent( "next", event ); 16657 break; 16658 } 16659 }, 16660 input: function( event ) { 16661 if ( suppressInput ) { 16662 suppressInput = false; 16663 event.preventDefault(); 16664 return; 16665 } 16666 this._searchTimeout( event ); 16667 }, 16668 focus: function() { 16669 this.selectedItem = null; 16670 this.previous = this._value(); 16671 }, 16672 blur: function( event ) { 16673 clearTimeout( this.searching ); 16674 this.close( event ); 16675 this._change( event ); 16676 } 16677 } ); 16678 16679 this._initSource(); 16680 this.menu = $( "<ul>" ) 16681 .appendTo( this._appendTo() ) 16682 .menu( { 16683 16684 // disable ARIA support, the live region takes care of that 16685 role: null 16686 } ) 16687 .hide() 16688 16689 // Support: IE 11 only, Edge <= 14 16690 // For other browsers, we preventDefault() on the mousedown event 16691 // to keep the dropdown from taking focus from the input. This doesn't 16692 // work for IE/Edge, causing problems with selection and scrolling (#9638) 16693 // Happily, IE and Edge support an "unselectable" attribute that 16694 // prevents an element from receiving focus, exactly what we want here. 16695 .attr( { 16696 "unselectable": "on" 16697 } ) 16698 .menu( "instance" ); 16699 16700 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); 16701 this._on( this.menu.element, { 16702 mousedown: function( event ) { 16703 16704 // Prevent moving focus out of the text field 16705 event.preventDefault(); 16706 }, 16707 menufocus: function( event, ui ) { 16708 var label, item; 16709 16710 // support: Firefox 16711 // Prevent accidental activation of menu items in Firefox (#7024 #9118) 16712 if ( this.isNewMenu ) { 16713 this.isNewMenu = false; 16714 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { 16715 this.menu.blur(); 16716 16717 this.document.one( "mousemove", function() { 16718 $( event.target ).trigger( event.originalEvent ); 16719 } ); 16720 16721 return; 16722 } 16723 } 16724 16725 item = ui.item.data( "ui-autocomplete-item" ); 16726 if ( false !== this._trigger( "focus", event, { item: item } ) ) { 16727 16728 // use value to match what will end up in the input, if it was a key event 16729 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { 16730 this._value( item.value ); 16731 } 16732 } 16733 16734 // Announce the value in the liveRegion 16735 label = ui.item.attr( "aria-label" ) || item.value; 16736 if ( label && String.prototype.trim.call( label ).length ) { 16737 clearTimeout( this.liveRegionTimer ); 16738 this.liveRegionTimer = this._delay( function() { 16739 this.liveRegion.html( $( "<div>" ).text( label ) ); 16740 }, 100 ); 16741 } 16742 }, 16743 menuselect: function( event, ui ) { 16744 var item = ui.item.data( "ui-autocomplete-item" ), 16745 previous = this.previous; 16746 16747 // Only trigger when focus was lost (click on menu) 16748 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { 16749 this.element.trigger( "focus" ); 16750 this.previous = previous; 16751 16752 // #6109 - IE triggers two focus events and the second 16753 // is asynchronous, so we need to reset the previous 16754 // term synchronously and asynchronously :-( 16755 this._delay( function() { 16756 this.previous = previous; 16757 this.selectedItem = item; 16758 } ); 16759 } 16760 16761 if ( false !== this._trigger( "select", event, { item: item } ) ) { 16762 this._value( item.value ); 16763 } 16764 16765 // reset the term after the select event 16766 // this allows custom select handling to work properly 16767 this.term = this._value(); 16768 16769 this.close( event ); 16770 this.selectedItem = item; 16771 } 16772 } ); 16773 16774 this.liveRegion = $( "<div>", { 16775 role: "status", 16776 "aria-live": "assertive", 16777 "aria-relevant": "additions" 16778 } ) 16779 .appendTo( this.document[ 0 ].body ); 16780 16781 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 16782 16783 // Turning off autocomplete prevents the browser from remembering the 16784 // value when navigating through history, so we re-enable autocomplete 16785 // if the page is unloaded before the widget is destroyed. #7790 16786 this._on( this.window, { 16787 beforeunload: function() { 16788 this.element.removeAttr( "autocomplete" ); 16789 } 16790 } ); 16791 }, 16792 16793 _destroy: function() { 16794 clearTimeout( this.searching ); 16795 this.element.removeAttr( "autocomplete" ); 16796 this.menu.element.remove(); 16797 this.liveRegion.remove(); 16798 }, 16799 16800 _setOption: function( key, value ) { 16801 this._super( key, value ); 16802 if ( key === "source" ) { 16803 this._initSource(); 16804 } 16805 if ( key === "appendTo" ) { 16806 this.menu.element.appendTo( this._appendTo() ); 16807 } 16808 if ( key === "disabled" && value && this.xhr ) { 16809 this.xhr.abort(); 16810 } 16811 }, 16812 16813 _isEventTargetInWidget: function( event ) { 16814 var menuElement = this.menu.element[ 0 ]; 16815 16816 return event.target === this.element[ 0 ] || 16817 event.target === menuElement || 16818 $.contains( menuElement, event.target ); 16819 }, 16820 16821 _closeOnClickOutside: function( event ) { 16822 if ( !this._isEventTargetInWidget( event ) ) { 16823 this.close(); 16824 } 16825 }, 16826 16827 _appendTo: function() { 16828 var element = this.options.appendTo; 16829 16830 if ( element ) { 16831 element = element.jquery || element.nodeType ? 16832 $( element ) : 16833 this.document.find( element ).eq( 0 ); 16834 } 16835 16836 if ( !element || !element[ 0 ] ) { 16837 element = this.element.closest( ".ui-front, dialog" ); 16838 } 16839 16840 if ( !element.length ) { 16841 element = this.document[ 0 ].body; 16842 } 16843 16844 return element; 16845 }, 16846 16847 _initSource: function() { 16848 var array, url, 16849 that = this; 16850 if ( Array.isArray( this.options.source ) ) { 16851 array = this.options.source; 16852 this.source = function( request, response ) { 16853 response( $.ui.autocomplete.filter( array, request.term ) ); 16854 }; 16855 } else if ( typeof this.options.source === "string" ) { 16856 url = this.options.source; 16857 this.source = function( request, response ) { 16858 if ( that.xhr ) { 16859 that.xhr.abort(); 16860 } 16861 that.xhr = $.ajax( { 16862 url: url, 16863 data: request, 16864 dataType: "json", 16865 success: function( data ) { 16866 response( data ); 16867 }, 16868 error: function() { 16869 response( [] ); 16870 } 16871 } ); 16872 }; 16873 } else { 16874 this.source = this.options.source; 16875 } 16876 }, 16877 16878 _searchTimeout: function( event ) { 16879 clearTimeout( this.searching ); 16880 this.searching = this._delay( function() { 16881 16882 // Search if the value has changed, or if the user retypes the same value (see #7434) 16883 var equalValues = this.term === this._value(), 16884 menuVisible = this.menu.element.is( ":visible" ), 16885 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; 16886 16887 if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { 16888 this.selectedItem = null; 16889 this.search( null, event ); 16890 } 16891 }, this.options.delay ); 16892 }, 16893 16894 search: function( value, event ) { 16895 value = value != null ? value : this._value(); 16896 16897 // Always save the actual value, not the one passed as an argument 16898 this.term = this._value(); 16899 16900 if ( value.length < this.options.minLength ) { 16901 return this.close( event ); 16902 } 16903 16904 if ( this._trigger( "search", event ) === false ) { 16905 return; 16906 } 16907 16908 return this._search( value ); 16909 }, 16910 16911 _search: function( value ) { 16912 this.pending++; 16913 this._addClass( "ui-autocomplete-loading" ); 16914 this.cancelSearch = false; 16915 16916 this.source( { term: value }, this._response() ); 16917 }, 16918 16919 _response: function() { 16920 var index = ++this.requestIndex; 16921 16922 return function( content ) { 16923 if ( index === this.requestIndex ) { 16924 this.__response( content ); 16925 } 16926 16927 this.pending--; 16928 if ( !this.pending ) { 16929 this._removeClass( "ui-autocomplete-loading" ); 16930 } 16931 }.bind( this ); 16932 }, 16933 16934 __response: function( content ) { 16935 if ( content ) { 16936 content = this._normalize( content ); 16937 } 16938 this._trigger( "response", null, { content: content } ); 16939 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { 16940 this._suggest( content ); 16941 this._trigger( "open" ); 16942 } else { 16943 16944 // use ._close() instead of .close() so we don't cancel future searches 16945 this._close(); 16946 } 16947 }, 16948 16949 close: function( event ) { 16950 this.cancelSearch = true; 16951 this._close( event ); 16952 }, 16953 16954 _close: function( event ) { 16955 16956 // Remove the handler that closes the menu on outside clicks 16957 this._off( this.document, "mousedown" ); 16958 16959 if ( this.menu.element.is( ":visible" ) ) { 16960 this.menu.element.hide(); 16961 this.menu.blur(); 16962 this.isNewMenu = true; 16963 this._trigger( "close", event ); 16964 } 16965 }, 16966 16967 _change: function( event ) { 16968 if ( this.previous !== this._value() ) { 16969 this._trigger( "change", event, { item: this.selectedItem } ); 16970 } 16971 }, 16972 16973 _normalize: function( items ) { 16974 16975 // assume all items have the right format when the first item is complete 16976 if ( items.length && items[ 0 ].label && items[ 0 ].value ) { 16977 return items; 16978 } 16979 return $.map( items, function( item ) { 16980 if ( typeof item === "string" ) { 16981 return { 16982 label: item, 16983 value: item 16984 }; 16985 } 16986 return $.extend( {}, item, { 16987 label: item.label || item.value, 16988 value: item.value || item.label 16989 } ); 16990 } ); 16991 }, 16992 16993 _suggest: function( items ) { 16994 var ul = this.menu.element.empty(); 16995 this._renderMenu( ul, items ); 16996 this.isNewMenu = true; 16997 this.menu.refresh(); 16998 16999 // Size and position menu 17000 ul.show(); 17001 this._resizeMenu(); 17002 ul.position( $.extend( { 17003 of: this.element 17004 }, this.options.position ) ); 17005 17006 if ( this.options.autoFocus ) { 17007 this.menu.next(); 17008 } 17009 17010 // Listen for interactions outside of the widget (#6642) 17011 this._on( this.document, { 17012 mousedown: "_closeOnClickOutside" 17013 } ); 17014 }, 17015 17016 _resizeMenu: function() { 17017 var ul = this.menu.element; 17018 ul.outerWidth( Math.max( 17019 17020 // Firefox wraps long text (possibly a rounding bug) 17021 // so we add 1px to avoid the wrapping (#7513) 17022 ul.width( "" ).outerWidth() + 1, 17023 this.element.outerWidth() 17024 ) ); 17025 }, 17026 17027 _renderMenu: function( ul, items ) { 17028 var that = this; 17029 $.each( items, function( index, item ) { 17030 that._renderItemData( ul, item ); 17031 } ); 17032 }, 17033 17034 _renderItemData: function( ul, item ) { 17035 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); 17036 }, 17037 17038 _renderItem: function( ul, item ) { 17039 return $( "<li>" ) 17040 .append( $( "<div>" ).text( item.label ) ) 17041 .appendTo( ul ); 17042 }, 17043 17044 _move: function( direction, event ) { 17045 if ( !this.menu.element.is( ":visible" ) ) { 17046 this.search( null, event ); 17047 return; 17048 } 17049 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || 17050 this.menu.isLastItem() && /^next/.test( direction ) ) { 17051 17052 if ( !this.isMultiLine ) { 17053 this._value( this.term ); 17054 } 17055 17056 this.menu.blur(); 17057 return; 17058 } 17059 this.menu[ direction ]( event ); 17060 }, 17061 17062 widget: function() { 17063 return this.menu.element; 17064 }, 17065 17066 _value: function() { 17067 return this.valueMethod.apply( this.element, arguments ); 17068 }, 17069 17070 _keyEvent: function( keyEvent, event ) { 17071 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { 17072 this._move( keyEvent, event ); 17073 17074 // Prevents moving cursor to beginning/end of the text field in some browsers 17075 event.preventDefault(); 17076 } 17077 }, 17078 17079 // Support: Chrome <=50 17080 // We should be able to just use this.element.prop( "isContentEditable" ) 17081 // but hidden elements always report false in Chrome. 17082 // https://code.google.com/p/chromium/issues/detail?id=313082 17083 _isContentEditable: function( element ) { 17084 if ( !element.length ) { 17085 return false; 17086 } 17087 17088 var editable = element.prop( "contentEditable" ); 17089 17090 if ( editable === "inherit" ) { 17091 return this._isContentEditable( element.parent() ); 17092 } 17093 17094 return editable === "true"; 17095 } 17096} ); 17097 17098$.extend( $.ui.autocomplete, { 17099 escapeRegex: function( value ) { 17100 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); 17101 }, 17102 filter: function( array, term ) { 17103 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); 17104 return $.grep( array, function( value ) { 17105 return matcher.test( value.label || value.value || value ); 17106 } ); 17107 } 17108} ); 17109 17110// Live region extension, adding a `messages` option 17111// NOTE: This is an experimental API. We are still investigating 17112// a full solution for string manipulation and internationalization. 17113$.widget( "ui.autocomplete", $.ui.autocomplete, { 17114 options: { 17115 messages: { 17116 noResults: "No search results.", 17117 results: function( amount ) { 17118 return amount + ( amount > 1 ? " results are" : " result is" ) + 17119 " available, use up and down arrow keys to navigate."; 17120 } 17121 } 17122 }, 17123 17124 __response: function( content ) { 17125 var message; 17126 this._superApply( arguments ); 17127 if ( this.options.disabled || this.cancelSearch ) { 17128 return; 17129 } 17130 if ( content && content.length ) { 17131 message = this.options.messages.results( content.length ); 17132 } else { 17133 message = this.options.messages.noResults; 17134 } 17135 clearTimeout( this.liveRegionTimer ); 17136 this.liveRegionTimer = this._delay( function() { 17137 this.liveRegion.html( $( "<div>" ).text( message ) ); 17138 }, 100 ); 17139 } 17140} ); 17141 17142var widgetsAutocomplete = $.ui.autocomplete; 17143 17144 17145/*! 17146 * jQuery UI Controlgroup 1.13.2 17147 * http://jqueryui.com
vendor: 7,245 bytes, lines 17148-17385
17148 * 17149 * Copyright jQuery Foundation and other contributors 17150 * Released under the MIT license. 17151 * http://jquery.org/license 17152 */ 17153 17154//>>label: Controlgroup 17155//>>group: Widgets 17156//>>description: Visually groups form control widgets 17157//>>docs: http://api.jqueryui.com/controlgroup/ 17158//>>demos: http://jqueryui.com/controlgroup/ 17159//>>css.structure: ../../themes/base/core.css 17160//>>css.structure: ../../themes/base/controlgroup.css 17161//>>css.theme: ../../themes/base/theme.css 17162 17163 17164var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; 17165 17166var widgetsControlgroup = $.widget( "ui.controlgroup", { 17167 version: "1.13.2", 17168 defaultElement: "<div>", 17169 options: { 17170 direction: "horizontal", 17171 disabled: null, 17172 onlyVisible: true, 17173 items: { 17174 "button": "input[type=button], input[type=submit], input[type=reset], button, a", 17175 "controlgroupLabel": ".ui-controlgroup-label", 17176 "checkboxradio": "input[type='checkbox'], input[type='radio']", 17177 "selectmenu": "select", 17178 "spinner": ".ui-spinner-input" 17179 } 17180 }, 17181 17182 _create: function() { 17183 this._enhance(); 17184 }, 17185 17186 // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation 17187 _enhance: function() { 17188 this.element.attr( "role", "toolbar" ); 17189 this.refresh(); 17190 }, 17191 17192 _destroy: function() { 17193 this._callChildMethod( "destroy" ); 17194 this.childWidgets.removeData( "ui-controlgroup-data" ); 17195 this.element.removeAttr( "role" ); 17196 if ( this.options.items.controlgroupLabel ) { 17197 this.element 17198 .find( this.options.items.controlgroupLabel ) 17199 .find( ".ui-controlgroup-label-contents" ) 17200 .contents().unwrap(); 17201 } 17202 }, 17203 17204 _initWidgets: function() { 17205 var that = this, 17206 childWidgets = []; 17207 17208 // First we iterate over each of the items options 17209 $.each( this.options.items, function( widget, selector ) { 17210 var labels; 17211 var options = {}; 17212 17213 // Make sure the widget has a selector set 17214 if ( !selector ) { 17215 return; 17216 } 17217 17218 if ( widget === "controlgroupLabel" ) { 17219 labels = that.element.find( selector ); 17220 labels.each( function() { 17221 var element = $( this ); 17222 17223 if ( element.children( ".ui-controlgroup-label-contents" ).length ) { 17224 return; 17225 } 17226 element.contents() 17227 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); 17228 } ); 17229 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); 17230 childWidgets = childWidgets.concat( labels.get() ); 17231 return; 17232 } 17233 17234 // Make sure the widget actually exists 17235 if ( !$.fn[ widget ] ) { 17236 return; 17237 } 17238 17239 // We assume everything is in the middle to start because we can't determine 17240 // first / last elements until all enhancments are done. 17241 if ( that[ "_" + widget + "Options" ] ) { 17242 options = that[ "_" + widget + "Options" ]( "middle" ); 17243 } else { 17244 options = { classes: {} }; 17245 } 17246 17247 // Find instances of this widget inside controlgroup and init them 17248 that.element 17249 .find( selector ) 17250 .each( function() { 17251 var element = $( this ); 17252 var instance = element[ widget ]( "instance" ); 17253 17254 // We need to clone the default options for this type of widget to avoid 17255 // polluting the variable options which has a wider scope than a single widget. 17256 var instanceOptions = $.widget.extend( {}, options ); 17257 17258 // If the button is the child of a spinner ignore it 17259 // TODO: Find a more generic solution 17260 if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { 17261 return; 17262 } 17263 17264 // Create the widget if it doesn't exist 17265 if ( !instance ) { 17266 instance = element[ widget ]()[ widget ]( "instance" ); 17267 } 17268 if ( instance ) { 17269 instanceOptions.classes = 17270 that._resolveClassesValues( instanceOptions.classes, instance ); 17271 } 17272 element[ widget ]( instanceOptions ); 17273 17274 // Store an instance of the controlgroup to be able to reference 17275 // from the outermost element for changing options and refresh 17276 var widgetElement = element[ widget ]( "widget" ); 17277 $.data( widgetElement[ 0 ], "ui-controlgroup-data", 17278 instance ? instance : element[ widget ]( "instance" ) ); 17279 17280 childWidgets.push( widgetElement[ 0 ] ); 17281 } ); 17282 } ); 17283 17284 this.childWidgets = $( $.uniqueSort( childWidgets ) ); 17285 this._addClass( this.childWidgets, "ui-controlgroup-item" ); 17286 }, 17287 17288 _callChildMethod: function( method ) { 17289 this.childWidgets.each( function() { 17290 var element = $( this ), 17291 data = element.data( "ui-controlgroup-data" ); 17292 if ( data && data[ method ] ) { 17293 data[ method ](); 17294 } 17295 } ); 17296 }, 17297 17298 _updateCornerClass: function( element, position ) { 17299 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; 17300 var add = this._buildSimpleOptions( position, "label" ).classes.label; 17301 17302 this._removeClass( element, null, remove ); 17303 this._addClass( element, null, add ); 17304 }, 17305 17306 _buildSimpleOptions: function( position, key ) { 17307 var direction = this.options.direction === "vertical"; 17308 var result = { 17309 classes: {} 17310 }; 17311 result.classes[ key ] = { 17312 "middle": "", 17313 "first": "ui-corner-" + ( direction ? "top" : "left" ), 17314 "last": "ui-corner-" + ( direction ? "bottom" : "right" ), 17315 "only": "ui-corner-all" 17316 }[ position ]; 17317 17318 return result; 17319 }, 17320 17321 _spinnerOptions: function( position ) { 17322 var options = this._buildSimpleOptions( position, "ui-spinner" ); 17323 17324 options.classes[ "ui-spinner-up" ] = ""; 17325 options.classes[ "ui-spinner-down" ] = ""; 17326 17327 return options; 17328 }, 17329 17330 _buttonOptions: function( position ) { 17331 return this._buildSimpleOptions( position, "ui-button" ); 17332 }, 17333 17334 _checkboxradioOptions: function( position ) { 17335 return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); 17336 }, 17337 17338 _selectmenuOptions: function( position ) { 17339 var direction = this.options.direction === "vertical"; 17340 return { 17341 width: direction ? "auto" : false, 17342 classes: { 17343 middle: { 17344 "ui-selectmenu-button-open": "", 17345 "ui-selectmenu-button-closed": "" 17346 }, 17347 first: { 17348 "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), 17349 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) 17350 }, 17351 last: { 17352 "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", 17353 "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) 17354 }, 17355 only: { 17356 "ui-selectmenu-button-open": "ui-corner-top", 17357 "ui-selectmenu-button-closed": "ui-corner-all" 17358 } 17359 17360 }[ position ] 17361 }; 17362 }, 17363 17364 _resolveClassesValues: function( classes, instance ) { 17365 var result = {}; 17366 $.each( classes, function( key ) { 17367 var current = instance.options.classes[ key ] || ""; 17368 current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); 17369 result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); 17370 } ); 17371 return result; 17372 }, 17373 17374 _setOption: function( key, value ) { 17375 if ( key === "direction" ) { 17376 this._removeClass( "ui-controlgroup-" + this.options.direction ); 17377 } 17378 17379 this._super( key, value ); 17380 if ( key === "disabled" ) { 17381 this._callChildMethod( value ? "disable" : "enable" ); 17382 return; 17383 } 17384 17385 this.refresh();
vendor: 6,618 bytes, lines 17386-17614
17386 }, 17387 17388 refresh: function() { 17389 var children, 17390 that = this; 17391 17392 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); 17393 17394 if ( this.options.direction === "horizontal" ) { 17395 this._addClass( null, "ui-helper-clearfix" ); 17396 } 17397 this._initWidgets(); 17398 17399 children = this.childWidgets; 17400 17401 // We filter here because we need to track all childWidgets not just the visible ones 17402 if ( this.options.onlyVisible ) { 17403 children = children.filter( ":visible" ); 17404 } 17405 17406 if ( children.length ) { 17407 17408 // We do this last because we need to make sure all enhancment is done 17409 // before determining first and last 17410 $.each( [ "first", "last" ], function( index, value ) { 17411 var instance = children[ value ]().data( "ui-controlgroup-data" ); 17412 17413 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { 17414 var options = that[ "_" + instance.widgetName + "Options" ]( 17415 children.length === 1 ? "only" : value 17416 ); 17417 options.classes = that._resolveClassesValues( options.classes, instance ); 17418 instance.element[ instance.widgetName ]( options ); 17419 } else { 17420 that._updateCornerClass( children[ value ](), value ); 17421 } 17422 } ); 17423 17424 // Finally call the refresh method on each of the child widgets. 17425 this._callChildMethod( "refresh" ); 17426 } 17427 } 17428} ); 17429 17430/*! 17431 * jQuery UI Checkboxradio 1.13.2 17432 * http://jqueryui.com 17433 * 17434 * Copyright jQuery Foundation and other contributors 17435 * Released under the MIT license. 17436 * http://jquery.org/license 17437 */ 17438 17439//>>label: Checkboxradio 17440//>>group: Widgets 17441//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. 17442//>>docs: http://api.jqueryui.com/checkboxradio/ 17443//>>demos: http://jqueryui.com/checkboxradio/ 17444//>>css.structure: ../../themes/base/core.css 17445//>>css.structure: ../../themes/base/button.css 17446//>>css.structure: ../../themes/base/checkboxradio.css 17447//>>css.theme: ../../themes/base/theme.css 17448 17449 17450$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { 17451 version: "1.13.2", 17452 options: { 17453 disabled: null, 17454 label: null, 17455 icon: true, 17456 classes: { 17457 "ui-checkboxradio-label": "ui-corner-all", 17458 "ui-checkboxradio-icon": "ui-corner-all" 17459 } 17460 }, 17461 17462 _getCreateOptions: function() { 17463 var disabled, labels, labelContents; 17464 var options = this._super() || {}; 17465 17466 // We read the type here, because it makes more sense to throw a element type error first, 17467 // rather then the error for lack of a label. Often if its the wrong type, it 17468 // won't have a label (e.g. calling on a div, btn, etc) 17469 this._readType(); 17470 17471 labels = this.element.labels(); 17472 17473 // If there are multiple labels, use the last one 17474 this.label = $( labels[ labels.length - 1 ] ); 17475 if ( !this.label.length ) { 17476 $.error( "No label found for checkboxradio widget" ); 17477 } 17478 17479 this.originalLabel = ""; 17480 17481 // We need to get the label text but this may also need to make sure it does not contain the 17482 // input itself. 17483 // The label contents could be text, html, or a mix. We wrap all elements 17484 // and read the wrapper's `innerHTML` to get a string representation of 17485 // the label, without the input as part of it. 17486 labelContents = this.label.contents().not( this.element[ 0 ] ); 17487 17488 if ( labelContents.length ) { 17489 this.originalLabel += labelContents 17490 .clone() 17491 .wrapAll( "<div></div>" ) 17492 .parent() 17493 .html(); 17494 } 17495 17496 // Set the label option if we found label text 17497 if ( this.originalLabel ) { 17498 options.label = this.originalLabel; 17499 } 17500 17501 disabled = this.element[ 0 ].disabled; 17502 if ( disabled != null ) { 17503 options.disabled = disabled; 17504 } 17505 return options; 17506 }, 17507 17508 _create: function() { 17509 var checked = this.element[ 0 ].checked; 17510 17511 this._bindFormResetHandler(); 17512 17513 if ( this.options.disabled == null ) { 17514 this.options.disabled = this.element[ 0 ].disabled; 17515 } 17516 17517 this._setOption( "disabled", this.options.disabled ); 17518 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); 17519 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); 17520 17521 if ( this.type === "radio" ) { 17522 this._addClass( this.label, "ui-checkboxradio-radio-label" ); 17523 } 17524 17525 if ( this.options.label && this.options.label !== this.originalLabel ) { 17526 this._updateLabel(); 17527 } else if ( this.originalLabel ) { 17528 this.options.label = this.originalLabel; 17529 } 17530 17531 this._enhance(); 17532 17533 if ( checked ) { 17534 this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); 17535 } 17536 17537 this._on( { 17538 change: "_toggleClasses", 17539 focus: function() { 17540 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); 17541 }, 17542 blur: function() { 17543 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); 17544 } 17545 } ); 17546 }, 17547 17548 _readType: function() { 17549 var nodeName = this.element[ 0 ].nodeName.toLowerCase(); 17550 this.type = this.element[ 0 ].type; 17551 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { 17552 $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + 17553 " and element.type=" + this.type ); 17554 } 17555 }, 17556 17557 // Support jQuery Mobile enhanced option 17558 _enhance: function() { 17559 this._updateIcon( this.element[ 0 ].checked ); 17560 }, 17561 17562 widget: function() { 17563 return this.label; 17564 }, 17565 17566 _getRadioGroup: function() { 17567 var group; 17568 var name = this.element[ 0 ].name; 17569 var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; 17570 17571 if ( !name ) { 17572 return $( [] ); 17573 } 17574 17575 if ( this.form.length ) { 17576 group = $( this.form[ 0 ].elements ).filter( nameSelector ); 17577 } else { 17578 17579 // Not inside a form, check all inputs that also are not inside a form 17580 group = $( nameSelector ).filter( function() { 17581 return $( this )._form().length === 0; 17582 } ); 17583 } 17584 17585 return group.not( this.element ); 17586 }, 17587 17588 _toggleClasses: function() { 17589 var checked = this.element[ 0 ].checked; 17590 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 17591 17592 if ( this.options.icon && this.type === "checkbox" ) { 17593 this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) 17594 ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); 17595 } 17596 17597 if ( this.type === "radio" ) { 17598 this._getRadioGroup() 17599 .each( function() { 17600 var instance = $( this ).checkboxradio( "instance" ); 17601 17602 if ( instance ) { 17603 instance._removeClass( instance.label, 17604 "ui-checkboxradio-checked", "ui-state-active" ); 17605 } 17606 } ); 17607 } 17608 }, 17609 17610 _destroy: function() { 17611 this._unbindFormResetHandler(); 17612 17613 if ( this.icon ) { 17614 this.icon.remove();
vendor: 4,657 bytes, lines 17615-17787
17615 this.iconSpace.remove(); 17616 } 17617 }, 17618 17619 _setOption: function( key, value ) { 17620 17621 // We don't allow the value to be set to nothing 17622 if ( key === "label" && !value ) { 17623 return; 17624 } 17625 17626 this._super( key, value ); 17627 17628 if ( key === "disabled" ) { 17629 this._toggleClass( this.label, null, "ui-state-disabled", value ); 17630 this.element[ 0 ].disabled = value; 17631 17632 // Don't refresh when setting disabled 17633 return; 17634 } 17635 this.refresh(); 17636 }, 17637 17638 _updateIcon: function( checked ) { 17639 var toAdd = "ui-icon ui-icon-background "; 17640 17641 if ( this.options.icon ) { 17642 if ( !this.icon ) { 17643 this.icon = $( "<span>" ); 17644 this.iconSpace = $( "<span> </span>" ); 17645 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); 17646 } 17647 17648 if ( this.type === "checkbox" ) { 17649 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; 17650 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); 17651 } else { 17652 toAdd += "ui-icon-blank"; 17653 } 17654 this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); 17655 if ( !checked ) { 17656 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); 17657 } 17658 this.icon.prependTo( this.label ).after( this.iconSpace ); 17659 } else if ( this.icon !== undefined ) { 17660 this.icon.remove(); 17661 this.iconSpace.remove(); 17662 delete this.icon; 17663 } 17664 }, 17665 17666 _updateLabel: function() { 17667 17668 // Remove the contents of the label ( minus the icon, icon space, and input ) 17669 var contents = this.label.contents().not( this.element[ 0 ] ); 17670 if ( this.icon ) { 17671 contents = contents.not( this.icon[ 0 ] ); 17672 } 17673 if ( this.iconSpace ) { 17674 contents = contents.not( this.iconSpace[ 0 ] ); 17675 } 17676 contents.remove(); 17677 17678 this.label.append( this.options.label ); 17679 }, 17680 17681 refresh: function() { 17682 var checked = this.element[ 0 ].checked, 17683 isDisabled = this.element[ 0 ].disabled; 17684 17685 this._updateIcon( checked ); 17686 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); 17687 if ( this.options.label !== null ) { 17688 this._updateLabel(); 17689 } 17690 17691 if ( isDisabled !== this.options.disabled ) { 17692 this._setOptions( { "disabled": isDisabled } ); 17693 } 17694 } 17695 17696} ] ); 17697 17698var widgetsCheckboxradio = $.ui.checkboxradio; 17699 17700 17701/*! 17702 * jQuery UI Button 1.13.2 17703 * http://jqueryui.com 17704 * 17705 * Copyright jQuery Foundation and other contributors 17706 * Released under the MIT license. 17707 * http://jquery.org/license 17708 */ 17709 17710//>>label: Button 17711//>>group: Widgets 17712//>>description: Enhances a form with themeable buttons. 17713//>>docs: http://api.jqueryui.com/button/ 17714//>>demos: http://jqueryui.com/button/ 17715//>>css.structure: ../../themes/base/core.css 17716//>>css.structure: ../../themes/base/button.css 17717//>>css.theme: ../../themes/base/theme.css 17718 17719 17720$.widget( "ui.button", { 17721 version: "1.13.2", 17722 defaultElement: "<button>", 17723 options: { 17724 classes: { 17725 "ui-button": "ui-corner-all" 17726 }, 17727 disabled: null, 17728 icon: null, 17729 iconPosition: "beginning", 17730 label: null, 17731 showLabel: true 17732 }, 17733 17734 _getCreateOptions: function() { 17735 var disabled, 17736 17737 // This is to support cases like in jQuery Mobile where the base widget does have 17738 // an implementation of _getCreateOptions 17739 options = this._super() || {}; 17740 17741 this.isInput = this.element.is( "input" ); 17742 17743 disabled = this.element[ 0 ].disabled; 17744 if ( disabled != null ) { 17745 options.disabled = disabled; 17746 } 17747 17748 this.originalLabel = this.isInput ? this.element.val() : this.element.html(); 17749 if ( this.originalLabel ) { 17750 options.label = this.originalLabel; 17751 } 17752 17753 return options; 17754 }, 17755 17756 _create: function() { 17757 if ( !this.option.showLabel & !this.options.icon ) { 17758 this.options.showLabel = true; 17759 } 17760 17761 // We have to check the option again here even though we did in _getCreateOptions, 17762 // because null may have been passed on init which would override what was set in 17763 // _getCreateOptions 17764 if ( this.options.disabled == null ) { 17765 this.options.disabled = this.element[ 0 ].disabled || false; 17766 } 17767 17768 this.hasTitle = !!this.element.attr( "title" ); 17769 17770 // Check to see if the label needs to be set or if its already correct 17771 if ( this.options.label && this.options.label !== this.originalLabel ) { 17772 if ( this.isInput ) { 17773 this.element.val( this.options.label ); 17774 } else { 17775 this.element.html( this.options.label ); 17776 } 17777 } 17778 this._addClass( "ui-button", "ui-widget" ); 17779 this._setOption( "disabled", this.options.disabled ); 17780 this._enhance(); 17781 17782 if ( this.element.is( "a" ) ) { 17783 this._on( { 17784 "keyup": function( event ) { 17785 if ( event.keyCode === $.ui.keyCode.SPACE ) { 17786 event.preventDefault(); 17787
vendor: 8,360 bytes, lines 17788-18088
17788 // Support: PhantomJS <= 1.9, IE 8 Only 17789 // If a native click is available use it so we actually cause navigation 17790 // otherwise just trigger a click event 17791 if ( this.element[ 0 ].click ) { 17792 this.element[ 0 ].click(); 17793 } else { 17794 this.element.trigger( "click" ); 17795 } 17796 } 17797 } 17798 } ); 17799 } 17800 }, 17801 17802 _enhance: function() { 17803 if ( !this.element.is( "button" ) ) { 17804 this.element.attr( "role", "button" ); 17805 } 17806 17807 if ( this.options.icon ) { 17808 this._updateIcon( "icon", this.options.icon ); 17809 this._updateTooltip(); 17810 } 17811 }, 17812 17813 _updateTooltip: function() { 17814 this.title = this.element.attr( "title" ); 17815 17816 if ( !this.options.showLabel && !this.title ) { 17817 this.element.attr( "title", this.options.label ); 17818 } 17819 }, 17820 17821 _updateIcon: function( option, value ) { 17822 var icon = option !== "iconPosition", 17823 position = icon ? this.options.iconPosition : value, 17824 displayBlock = position === "top" || position === "bottom"; 17825 17826 // Create icon 17827 if ( !this.icon ) { 17828 this.icon = $( "<span>" ); 17829 17830 this._addClass( this.icon, "ui-button-icon", "ui-icon" ); 17831 17832 if ( !this.options.showLabel ) { 17833 this._addClass( "ui-button-icon-only" ); 17834 } 17835 } else if ( icon ) { 17836 17837 // If we are updating the icon remove the old icon class 17838 this._removeClass( this.icon, null, this.options.icon ); 17839 } 17840 17841 // If we are updating the icon add the new icon class 17842 if ( icon ) { 17843 this._addClass( this.icon, null, value ); 17844 } 17845 17846 this._attachIcon( position ); 17847 17848 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove 17849 // the iconSpace if there is one. 17850 if ( displayBlock ) { 17851 this._addClass( this.icon, null, "ui-widget-icon-block" ); 17852 if ( this.iconSpace ) { 17853 this.iconSpace.remove(); 17854 } 17855 } else { 17856 17857 // Position is beginning or end so remove the ui-widget-icon-block class and add the 17858 // space if it does not exist 17859 if ( !this.iconSpace ) { 17860 this.iconSpace = $( "<span> </span>" ); 17861 this._addClass( this.iconSpace, "ui-button-icon-space" ); 17862 } 17863 this._removeClass( this.icon, null, "ui-wiget-icon-block" ); 17864 this._attachIconSpace( position ); 17865 } 17866 }, 17867 17868 _destroy: function() { 17869 this.element.removeAttr( "role" ); 17870 17871 if ( this.icon ) { 17872 this.icon.remove(); 17873 } 17874 if ( this.iconSpace ) { 17875 this.iconSpace.remove(); 17876 } 17877 if ( !this.hasTitle ) { 17878 this.element.removeAttr( "title" ); 17879 } 17880 }, 17881 17882 _attachIconSpace: function( iconPosition ) { 17883 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); 17884 }, 17885 17886 _attachIcon: function( iconPosition ) { 17887 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); 17888 }, 17889 17890 _setOptions: function( options ) { 17891 var newShowLabel = options.showLabel === undefined ? 17892 this.options.showLabel : 17893 options.showLabel, 17894 newIcon = options.icon === undefined ? this.options.icon : options.icon; 17895 17896 if ( !newShowLabel && !newIcon ) { 17897 options.showLabel = true; 17898 } 17899 this._super( options ); 17900 }, 17901 17902 _setOption: function( key, value ) { 17903 if ( key === "icon" ) { 17904 if ( value ) { 17905 this._updateIcon( key, value ); 17906 } else if ( this.icon ) { 17907 this.icon.remove(); 17908 if ( this.iconSpace ) { 17909 this.iconSpace.remove(); 17910 } 17911 } 17912 } 17913 17914 if ( key === "iconPosition" ) { 17915 this._updateIcon( key, value ); 17916 } 17917 17918 // Make sure we can't end up with a button that has neither text nor icon 17919 if ( key === "showLabel" ) { 17920 this._toggleClass( "ui-button-icon-only", null, !value ); 17921 this._updateTooltip(); 17922 } 17923 17924 if ( key === "label" ) { 17925 if ( this.isInput ) { 17926 this.element.val( value ); 17927 } else { 17928 17929 // If there is an icon, append it, else nothing then append the value 17930 // this avoids removal of the icon when setting label text 17931 this.element.html( value ); 17932 if ( this.icon ) { 17933 this._attachIcon( this.options.iconPosition ); 17934 this._attachIconSpace( this.options.iconPosition ); 17935 } 17936 } 17937 } 17938 17939 this._super( key, value ); 17940 17941 if ( key === "disabled" ) { 17942 this._toggleClass( null, "ui-state-disabled", value ); 17943 this.element[ 0 ].disabled = value; 17944 if ( value ) { 17945 this.element.trigger( "blur" ); 17946 } 17947 } 17948 }, 17949 17950 refresh: function() { 17951 17952 // Make sure to only check disabled if its an element that supports this otherwise 17953 // check for the disabled class to determine state 17954 var isDisabled = this.element.is( "input, button" ) ? 17955 this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); 17956 17957 if ( isDisabled !== this.options.disabled ) { 17958 this._setOptions( { disabled: isDisabled } ); 17959 } 17960 17961 this._updateTooltip(); 17962 } 17963} ); 17964 17965// DEPRECATED 17966if ( $.uiBackCompat !== false ) { 17967 17968 // Text and Icons options 17969 $.widget( "ui.button", $.ui.button, { 17970 options: { 17971 text: true, 17972 icons: { 17973 primary: null, 17974 secondary: null 17975 } 17976 }, 17977 17978 _create: function() { 17979 if ( this.options.showLabel && !this.options.text ) { 17980 this.options.showLabel = this.options.text; 17981 } 17982 if ( !this.options.showLabel && this.options.text ) { 17983 this.options.text = this.options.showLabel; 17984 } 17985 if ( !this.options.icon && ( this.options.icons.primary || 17986 this.options.icons.secondary ) ) { 17987 if ( this.options.icons.primary ) { 17988 this.options.icon = this.options.icons.primary; 17989 } else { 17990 this.options.icon = this.options.icons.secondary; 17991 this.options.iconPosition = "end"; 17992 } 17993 } else if ( this.options.icon ) { 17994 this.options.icons.primary = this.options.icon; 17995 } 17996 this._super(); 17997 }, 17998 17999 _setOption: function( key, value ) { 18000 if ( key === "text" ) { 18001 this._super( "showLabel", value ); 18002 return; 18003 } 18004 if ( key === "showLabel" ) { 18005 this.options.text = value; 18006 } 18007 if ( key === "icon" ) { 18008 this.options.icons.primary = value; 18009 } 18010 if ( key === "icons" ) { 18011 if ( value.primary ) { 18012 this._super( "icon", value.primary ); 18013 this._super( "iconPosition", "beginning" ); 18014 } else if ( value.secondary ) { 18015 this._super( "icon", value.secondary ); 18016 this._super( "iconPosition", "end" ); 18017 } 18018 } 18019 this._superApply( arguments ); 18020 } 18021 } ); 18022 18023 $.fn.button = ( function( orig ) { 18024 return function( options ) { 18025 var isMethodCall = typeof options === "string"; 18026 var args = Array.prototype.slice.call( arguments, 1 ); 18027 var returnValue = this; 18028 18029 if ( isMethodCall ) { 18030 18031 // If this is an empty collection, we need to have the instance method 18032 // return undefined instead of the jQuery instance 18033 if ( !this.length && options === "instance" ) { 18034 returnValue = undefined; 18035 } else { 18036 this.each( function() { 18037 var methodValue; 18038 var type = $( this ).attr( "type" ); 18039 var name = type !== "checkbox" && type !== "radio" ? 18040 "button" : 18041 "checkboxradio"; 18042 var instance = $.data( this, "ui-" + name ); 18043 18044 if ( options === "instance" ) { 18045 returnValue = instance; 18046 return false; 18047 } 18048 18049 if ( !instance ) { 18050 return $.error( "cannot call methods on button" + 18051 " prior to initialization; " + 18052 "attempted to call method '" + options + "'" ); 18053 } 18054 18055 if ( typeof instance[ options ] !== "function" || 18056 options.charAt( 0 ) === "_" ) { 18057 return $.error( "no such method '" + options + "' for button" + 18058 " widget instance" ); 18059 } 18060 18061 methodValue = instance[ options ].apply( instance, args ); 18062 18063 if ( methodValue !== instance && methodValue !== undefined ) { 18064 returnValue = methodValue && methodValue.jquery ? 18065 returnValue.pushStack( methodValue.get() ) : 18066 methodValue; 18067 return false; 18068 } 18069 } ); 18070 } 18071 } else { 18072 18073 // Allow multiple hashes to be passed on init 18074 if ( args.length ) { 18075 options = $.widget.extend.apply( null, [ options ].concat( args ) ); 18076 } 18077 18078 this.each( function() { 18079 var type = $( this ).attr( "type" ); 18080 var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; 18081 var instance = $.data( this, "ui-" + name ); 18082 18083 if ( instance ) { 18084 instance.option( options || {} ); 18085 if ( instance._init ) { 18086 instance._init(); 18087 } 18088 } else {
vendor: 19,025 bytes, lines 18089-18533
18089 if ( name === "button" ) { 18090 orig.call( $( this ), options ); 18091 return; 18092 } 18093 18094 $( this ).checkboxradio( $.extend( { icon: false }, options ) ); 18095 } 18096 } ); 18097 } 18098 18099 return returnValue; 18100 }; 18101 } )( $.fn.button ); 18102 18103 $.fn.buttonset = function() { 18104 if ( !$.ui.controlgroup ) { 18105 $.error( "Controlgroup widget missing" ); 18106 } 18107 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { 18108 return this.controlgroup.apply( this, 18109 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); 18110 } 18111 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { 18112 return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); 18113 } 18114 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { 18115 arguments[ 0 ].items = { 18116 button: arguments[ 0 ].items 18117 }; 18118 } 18119 return this.controlgroup.apply( this, arguments ); 18120 }; 18121} 18122 18123var widgetsButton = $.ui.button; 18124 18125 18126/* eslint-disable max-len, camelcase */ 18127/*! 18128 * jQuery UI Datepicker 1.13.2 18129 * http://jqueryui.com 18130 * 18131 * Copyright jQuery Foundation and other contributors 18132 * Released under the MIT license. 18133 * http://jquery.org/license 18134 */ 18135 18136//>>label: Datepicker 18137//>>group: Widgets 18138//>>description: Displays a calendar from an input or inline for selecting dates. 18139//>>docs: http://api.jqueryui.com/datepicker/ 18140//>>demos: http://jqueryui.com/datepicker/ 18141//>>css.structure: ../../themes/base/core.css 18142//>>css.structure: ../../themes/base/datepicker.css 18143//>>css.theme: ../../themes/base/theme.css 18144 18145 18146$.extend( $.ui, { datepicker: { version: "1.13.2" } } ); 18147 18148var datepicker_instActive; 18149 18150function datepicker_getZindex( elem ) { 18151 var position, value; 18152 while ( elem.length && elem[ 0 ] !== document ) { 18153 18154 // Ignore z-index if position is set to a value where z-index is ignored by the browser 18155 // This makes behavior of this function consistent across browsers 18156 // WebKit always returns auto if the element is positioned 18157 position = elem.css( "position" ); 18158 if ( position === "absolute" || position === "relative" || position === "fixed" ) { 18159 18160 // IE returns 0 when zIndex is not specified 18161 // other browsers return a string 18162 // we ignore the case of nested elements with an explicit value of 0 18163 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> 18164 value = parseInt( elem.css( "zIndex" ), 10 ); 18165 if ( !isNaN( value ) && value !== 0 ) { 18166 return value; 18167 } 18168 } 18169 elem = elem.parent(); 18170 } 18171 18172 return 0; 18173} 18174 18175/* Date picker manager. 18176 Use the singleton instance of this class, $.datepicker, to interact with the date picker. 18177 Settings for (groups of) date pickers are maintained in an instance object, 18178 allowing multiple different settings on the same page. */ 18179 18180function Datepicker() { 18181 this._curInst = null; // The current instance in use 18182 this._keyEvent = false; // If the last event was a key event 18183 this._disabledInputs = []; // List of date picker inputs that have been disabled 18184 this._datepickerShowing = false; // True if the popup picker is showing , false if not 18185 this._inDialog = false; // True if showing within a "dialog", false if not 18186 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division 18187 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class 18188 this._appendClass = "ui-datepicker-append"; // The name of the append marker class 18189 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class 18190 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class 18191 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class 18192 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class 18193 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class 18194 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class 18195 this.regional = []; // Available regional settings, indexed by language code 18196 this.regional[ "" ] = { // Default regional settings 18197 closeText: "Done", // Display text for close link 18198 prevText: "Prev", // Display text for previous month link 18199 nextText: "Next", // Display text for next month link 18200 currentText: "Today", // Display text for current month link 18201 monthNames: [ "January", "February", "March", "April", "May", "June", 18202 "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting 18203 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting 18204 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting 18205 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting 18206 dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday 18207 weekHeader: "Wk", // Column header for week of the year 18208 dateFormat: "mm/dd/yy", // See format options on parseDate 18209 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... 18210 isRTL: false, // True if right-to-left language, false if left-to-right 18211 showMonthAfterYear: false, // True if the year select precedes month, false for month then year 18212 yearSuffix: "", // Additional text to append to the year in the month headers, 18213 selectMonthLabel: "Select month", // Invisible label for month selector 18214 selectYearLabel: "Select year" // Invisible label for year selector 18215 }; 18216 this._defaults = { // Global defaults for all the date picker instances 18217 showOn: "focus", // "focus" for popup on focus, 18218 // "button" for trigger button, or "both" for either 18219 showAnim: "fadeIn", // Name of jQuery animation for popup 18220 showOptions: {}, // Options for enhanced animations 18221 defaultDate: null, // Used when field is blank: actual date, 18222 // +/-number for offset from today, null for today 18223 appendText: "", // Display text following the input box, e.g. showing the format 18224 buttonText: "...", // Text for trigger button 18225 buttonImage: "", // URL for trigger button image 18226 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button 18227 hideIfNoPrevNext: false, // True to hide next/previous month links 18228 // if not applicable, false to just disable them 18229 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links 18230 gotoCurrent: false, // True if today link goes back to current selection instead 18231 changeMonth: false, // True if month can be selected directly, false if only prev/next 18232 changeYear: false, // True if year can be selected directly, false if only prev/next 18233 yearRange: "c-10:c+10", // Range of years to display in drop-down, 18234 // either relative to today's year (-nn:+nn), relative to currently displayed year 18235 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) 18236 showOtherMonths: false, // True to show dates in other months, false to leave blank 18237 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable 18238 showWeek: false, // True to show week of the year, false to not show it 18239 calculateWeek: this.iso8601Week, // How to calculate the week of the year, 18240 // takes a Date and returns the number of the week for it 18241 shortYearCutoff: "+10", // Short year values < this are in the current century, 18242 // > this are in the previous century, 18243 // string value starting with "+" for current year + value 18244 minDate: null, // The earliest selectable date, or null for no limit 18245 maxDate: null, // The latest selectable date, or null for no limit 18246 duration: "fast", // Duration of display/closure 18247 beforeShowDay: null, // Function that takes a date and returns an array with 18248 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", 18249 // [2] = cell title (optional), e.g. $.datepicker.noWeekends 18250 beforeShow: null, // Function that takes an input field and 18251 // returns a set of custom settings for the date picker 18252 onSelect: null, // Define a callback function when a date is selected 18253 onChangeMonthYear: null, // Define a callback function when the month or year is changed 18254 onClose: null, // Define a callback function when the datepicker is closed 18255 onUpdateDatepicker: null, // Define a callback function when the datepicker is updated 18256 numberOfMonths: 1, // Number of months to show at a time 18257 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) 18258 stepMonths: 1, // Number of months to step back/forward 18259 stepBigMonths: 12, // Number of months to step back/forward for the big links 18260 altField: "", // Selector for an alternate field to store selected dates into 18261 altFormat: "", // The date format to use for the alternate field 18262 constrainInput: true, // The input is constrained by the current date format 18263 showButtonPanel: false, // True to show button panel, false to not show it 18264 autoSize: false, // True to size the input for the date format, false to leave as is 18265 disabled: false // The initial disabled state 18266 }; 18267 $.extend( this._defaults, this.regional[ "" ] ); 18268 this.regional.en = $.extend( true, {}, this.regional[ "" ] ); 18269 this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); 18270 this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); 18271} 18272 18273$.extend( Datepicker.prototype, { 18274 18275 /* Class name added to elements to indicate already configured with a date picker. */ 18276 markerClassName: "hasDatepicker", 18277 18278 //Keep track of the maximum number of rows displayed (see #7043) 18279 maxRows: 4, 18280 18281 // TODO rename to "widget" when switching to widget factory 18282 _widgetDatepicker: function() { 18283 return this.dpDiv; 18284 }, 18285 18286 /* Override the default settings for all instances of the date picker. 18287 * @param settings object - the new settings to use as defaults (anonymous object) 18288 * @return the manager object 18289 */ 18290 setDefaults: function( settings ) { 18291 datepicker_extendRemove( this._defaults, settings || {} ); 18292 return this; 18293 }, 18294 18295 /* Attach the date picker to a jQuery selection. 18296 * @param target element - the target input field or division or span 18297 * @param settings object - the new settings to use for this date picker instance (anonymous) 18298 */ 18299 _attachDatepicker: function( target, settings ) { 18300 var nodeName, inline, inst; 18301 nodeName = target.nodeName.toLowerCase(); 18302 inline = ( nodeName === "div" || nodeName === "span" ); 18303 if ( !target.id ) { 18304 this.uuid += 1; 18305 target.id = "dp" + this.uuid; 18306 } 18307 inst = this._newInst( $( target ), inline ); 18308 inst.settings = $.extend( {}, settings || {} ); 18309 if ( nodeName === "input" ) { 18310 this._connectDatepicker( target, inst ); 18311 } else if ( inline ) { 18312 this._inlineDatepicker( target, inst ); 18313 } 18314 }, 18315 18316 /* Create a new instance object. */ 18317 _newInst: function( target, inline ) { 18318 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars 18319 return { id: id, input: target, // associated target 18320 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection 18321 drawMonth: 0, drawYear: 0, // month being drawn 18322 inline: inline, // is datepicker inline or not 18323 dpDiv: ( !inline ? this.dpDiv : // presentation div 18324 datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; 18325 }, 18326 18327 /* Attach the date picker to an input field. */ 18328 _connectDatepicker: function( target, inst ) { 18329 var input = $( target ); 18330 inst.append = $( [] ); 18331 inst.trigger = $( [] ); 18332 if ( input.hasClass( this.markerClassName ) ) { 18333 return; 18334 } 18335 this._attachments( input, inst ); 18336 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). 18337 on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); 18338 this._autoSize( inst ); 18339 $.data( target, "datepicker", inst ); 18340 18341 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) 18342 if ( inst.settings.disabled ) { 18343 this._disableDatepicker( target ); 18344 } 18345 }, 18346 18347 /* Make attachments based on settings. */ 18348 _attachments: function( input, inst ) { 18349 var showOn, buttonText, buttonImage, 18350 appendText = this._get( inst, "appendText" ), 18351 isRTL = this._get( inst, "isRTL" ); 18352 18353 if ( inst.append ) { 18354 inst.append.remove(); 18355 } 18356 if ( appendText ) { 18357 inst.append = $( "<span>" ) 18358 .addClass( this._appendClass ) 18359 .text( appendText ); 18360 input[ isRTL ? "before" : "after" ]( inst.append ); 18361 } 18362 18363 input.off( "focus", this._showDatepicker ); 18364 18365 if ( inst.trigger ) { 18366 inst.trigger.remove(); 18367 } 18368 18369 showOn = this._get( inst, "showOn" ); 18370 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field 18371 input.on( "focus", this._showDatepicker ); 18372 } 18373 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked 18374 buttonText = this._get( inst, "buttonText" ); 18375 buttonImage = this._get( inst, "buttonImage" ); 18376 18377 if ( this._get( inst, "buttonImageOnly" ) ) { 18378 inst.trigger = $( "<img>" ) 18379 .addClass( this._triggerClass ) 18380 .attr( { 18381 src: buttonImage, 18382 alt: buttonText, 18383 title: buttonText 18384 } ); 18385 } else { 18386 inst.trigger = $( "<button type='button'>" ) 18387 .addClass( this._triggerClass ); 18388 if ( buttonImage ) { 18389 inst.trigger.html( 18390 $( "<img>" ) 18391 .attr( { 18392 src: buttonImage, 18393 alt: buttonText, 18394 title: buttonText 18395 } ) 18396 ); 18397 } else { 18398 inst.trigger.text( buttonText ); 18399 } 18400 } 18401 18402 input[ isRTL ? "before" : "after" ]( inst.trigger ); 18403 inst.trigger.on( "click", function() { 18404 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { 18405 $.datepicker._hideDatepicker(); 18406 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { 18407 $.datepicker._hideDatepicker(); 18408 $.datepicker._showDatepicker( input[ 0 ] ); 18409 } else { 18410 $.datepicker._showDatepicker( input[ 0 ] ); 18411 } 18412 return false; 18413 } ); 18414 } 18415 }, 18416 18417 /* Apply the maximum length for the date format. */ 18418 _autoSize: function( inst ) { 18419 if ( this._get( inst, "autoSize" ) && !inst.inline ) { 18420 var findMax, max, maxI, i, 18421 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits 18422 dateFormat = this._get( inst, "dateFormat" ); 18423 18424 if ( dateFormat.match( /[DM]/ ) ) { 18425 findMax = function( names ) { 18426 max = 0; 18427 maxI = 0; 18428 for ( i = 0; i < names.length; i++ ) { 18429 if ( names[ i ].length > max ) { 18430 max = names[ i ].length; 18431 maxI = i; 18432 } 18433 } 18434 return maxI; 18435 }; 18436 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? 18437 "monthNames" : "monthNamesShort" ) ) ) ); 18438 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? 18439 "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); 18440 } 18441 inst.input.attr( "size", this._formatDate( inst, date ).length ); 18442 } 18443 }, 18444 18445 /* Attach an inline date picker to a div. */ 18446 _inlineDatepicker: function( target, inst ) { 18447 var divSpan = $( target ); 18448 if ( divSpan.hasClass( this.markerClassName ) ) { 18449 return; 18450 } 18451 divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); 18452 $.data( target, "datepicker", inst ); 18453 this._setDate( inst, this._getDefaultDate( inst ), true ); 18454 this._updateDatepicker( inst ); 18455 this._updateAlternate( inst ); 18456 18457 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) 18458 if ( inst.settings.disabled ) { 18459 this._disableDatepicker( target ); 18460 } 18461 18462 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements 18463 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height 18464 inst.dpDiv.css( "display", "block" ); 18465 }, 18466 18467 /* Pop-up the date picker in a "dialog" box. 18468 * @param input element - ignored 18469 * @param date string or Date - the initial date to display 18470 * @param onSelect function - the function to call when a date is selected 18471 * @param settings object - update the dialog date picker instance's settings (anonymous object) 18472 * @param pos int[2] - coordinates for the dialog's position within the screen or 18473 * event - with x/y coordinates or 18474 * leave empty for default (screen centre) 18475 * @return the manager object 18476 */ 18477 _dialogDatepicker: function( input, date, onSelect, settings, pos ) { 18478 var id, browserWidth, browserHeight, scrollX, scrollY, 18479 inst = this._dialogInst; // internal instance 18480 18481 if ( !inst ) { 18482 this.uuid += 1; 18483 id = "dp" + this.uuid; 18484 this._dialogInput = $( "<input type='text' id='" + id + 18485 "' style='position: absolute; top: -100px; width: 0px;'/>" ); 18486 this._dialogInput.on( "keydown", this._doKeyDown ); 18487 $( "body" ).append( this._dialogInput ); 18488 inst = this._dialogInst = this._newInst( this._dialogInput, false ); 18489 inst.settings = {}; 18490 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 18491 } 18492 datepicker_extendRemove( inst.settings, settings || {} ); 18493 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); 18494 this._dialogInput.val( date ); 18495 18496 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); 18497 if ( !this._pos ) { 18498 browserWidth = document.documentElement.clientWidth; 18499 browserHeight = document.documentElement.clientHeight; 18500 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; 18501 scrollY = document.documentElement.scrollTop || document.body.scrollTop; 18502 this._pos = // should use actual width/height below 18503 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; 18504 } 18505 18506 // Move input on screen for focus, but hidden behind dialog 18507 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); 18508 inst.settings.onSelect = onSelect; 18509 this._inDialog = true; 18510 this.dpDiv.addClass( this._dialogClass ); 18511 this._showDatepicker( this._dialogInput[ 0 ] ); 18512 if ( $.blockUI ) { 18513 $.blockUI( this.dpDiv ); 18514 } 18515 $.data( this._dialogInput[ 0 ], "datepicker", inst ); 18516 return this; 18517 }, 18518 18519 /* Detach a datepicker from its control. 18520 * @param target element - the target input field or division or span 18521 */ 18522 _destroyDatepicker: function( target ) { 18523 var nodeName, 18524 $target = $( target ), 18525 inst = $.data( target, "datepicker" ); 18526 18527 if ( !$target.hasClass( this.markerClassName ) ) { 18528 return; 18529 } 18530 18531 nodeName = target.nodeName.toLowerCase(); 18532 $.removeData( target, "datepicker" ); 18533 if ( nodeName === "input" ) {
vendor: 12,182 bytes, lines 18534-18885
18534 inst.append.remove(); 18535 inst.trigger.remove(); 18536 $target.removeClass( this.markerClassName ). 18537 off( "focus", this._showDatepicker ). 18538 off( "keydown", this._doKeyDown ). 18539 off( "keypress", this._doKeyPress ). 18540 off( "keyup", this._doKeyUp ); 18541 } else if ( nodeName === "div" || nodeName === "span" ) { 18542 $target.removeClass( this.markerClassName ).empty(); 18543 } 18544 18545 if ( datepicker_instActive === inst ) { 18546 datepicker_instActive = null; 18547 this._curInst = null; 18548 } 18549 }, 18550 18551 /* Enable the date picker to a jQuery selection. 18552 * @param target element - the target input field or division or span 18553 */ 18554 _enableDatepicker: function( target ) { 18555 var nodeName, inline, 18556 $target = $( target ), 18557 inst = $.data( target, "datepicker" ); 18558 18559 if ( !$target.hasClass( this.markerClassName ) ) { 18560 return; 18561 } 18562 18563 nodeName = target.nodeName.toLowerCase(); 18564 if ( nodeName === "input" ) { 18565 target.disabled = false; 18566 inst.trigger.filter( "button" ). 18567 each( function() { 18568 this.disabled = false; 18569 } ).end(). 18570 filter( "img" ).css( { opacity: "1.0", cursor: "" } ); 18571 } else if ( nodeName === "div" || nodeName === "span" ) { 18572 inline = $target.children( "." + this._inlineClass ); 18573 inline.children().removeClass( "ui-state-disabled" ); 18574 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 18575 prop( "disabled", false ); 18576 } 18577 this._disabledInputs = $.map( this._disabledInputs, 18578 18579 // Delete entry 18580 function( value ) { 18581 return ( value === target ? null : value ); 18582 } ); 18583 }, 18584 18585 /* Disable the date picker to a jQuery selection. 18586 * @param target element - the target input field or division or span 18587 */ 18588 _disableDatepicker: function( target ) { 18589 var nodeName, inline, 18590 $target = $( target ), 18591 inst = $.data( target, "datepicker" ); 18592 18593 if ( !$target.hasClass( this.markerClassName ) ) { 18594 return; 18595 } 18596 18597 nodeName = target.nodeName.toLowerCase(); 18598 if ( nodeName === "input" ) { 18599 target.disabled = true; 18600 inst.trigger.filter( "button" ). 18601 each( function() { 18602 this.disabled = true; 18603 } ).end(). 18604 filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); 18605 } else if ( nodeName === "div" || nodeName === "span" ) { 18606 inline = $target.children( "." + this._inlineClass ); 18607 inline.children().addClass( "ui-state-disabled" ); 18608 inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). 18609 prop( "disabled", true ); 18610 } 18611 this._disabledInputs = $.map( this._disabledInputs, 18612 18613 // Delete entry 18614 function( value ) { 18615 return ( value === target ? null : value ); 18616 } ); 18617 this._disabledInputs[ this._disabledInputs.length ] = target; 18618 }, 18619 18620 /* Is the first field in a jQuery collection disabled as a datepicker? 18621 * @param target element - the target input field or division or span 18622 * @return boolean - true if disabled, false if enabled 18623 */ 18624 _isDisabledDatepicker: function( target ) { 18625 if ( !target ) { 18626 return false; 18627 } 18628 for ( var i = 0; i < this._disabledInputs.length; i++ ) { 18629 if ( this._disabledInputs[ i ] === target ) { 18630 return true; 18631 } 18632 } 18633 return false; 18634 }, 18635 18636 /* Retrieve the instance data for the target control. 18637 * @param target element - the target input field or division or span 18638 * @return object - the associated instance data 18639 * @throws error if a jQuery problem getting data 18640 */ 18641 _getInst: function( target ) { 18642 try { 18643 return $.data( target, "datepicker" ); 18644 } catch ( err ) { 18645 throw "Missing instance data for this datepicker"; 18646 } 18647 }, 18648 18649 /* Update or retrieve the settings for a date picker attached to an input field or division. 18650 * @param target element - the target input field or division or span 18651 * @param name object - the new settings to update or 18652 * string - the name of the setting to change or retrieve, 18653 * when retrieving also "all" for all instance settings or 18654 * "defaults" for all global defaults 18655 * @param value any - the new value for the setting 18656 * (omit if above is an object or to retrieve a value) 18657 */ 18658 _optionDatepicker: function( target, name, value ) { 18659 var settings, date, minDate, maxDate, 18660 inst = this._getInst( target ); 18661 18662 if ( arguments.length === 2 && typeof name === "string" ) { 18663 return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : 18664 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : 18665 this._get( inst, name ) ) : null ) ); 18666 } 18667 18668 settings = name || {}; 18669 if ( typeof name === "string" ) { 18670 settings = {}; 18671 settings[ name ] = value; 18672 } 18673 18674 if ( inst ) { 18675 if ( this._curInst === inst ) { 18676 this._hideDatepicker(); 18677 } 18678 18679 date = this._getDateDatepicker( target, true ); 18680 minDate = this._getMinMaxDate( inst, "min" ); 18681 maxDate = this._getMinMaxDate( inst, "max" ); 18682 datepicker_extendRemove( inst.settings, settings ); 18683 18684 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided 18685 if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { 18686 inst.settings.minDate = this._formatDate( inst, minDate ); 18687 } 18688 if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { 18689 inst.settings.maxDate = this._formatDate( inst, maxDate ); 18690 } 18691 if ( "disabled" in settings ) { 18692 if ( settings.disabled ) { 18693 this._disableDatepicker( target ); 18694 } else { 18695 this._enableDatepicker( target ); 18696 } 18697 } 18698 this._attachments( $( target ), inst ); 18699 this._autoSize( inst ); 18700 this._setDate( inst, date ); 18701 this._updateAlternate( inst ); 18702 this._updateDatepicker( inst ); 18703 } 18704 }, 18705 18706 // Change method deprecated 18707 _changeDatepicker: function( target, name, value ) { 18708 this._optionDatepicker( target, name, value ); 18709 }, 18710 18711 /* Redraw the date picker attached to an input field or division. 18712 * @param target element - the target input field or division or span 18713 */ 18714 _refreshDatepicker: function( target ) { 18715 var inst = this._getInst( target ); 18716 if ( inst ) { 18717 this._updateDatepicker( inst ); 18718 } 18719 }, 18720 18721 /* Set the dates for a jQuery selection. 18722 * @param target element - the target input field or division or span 18723 * @param date Date - the new date 18724 */ 18725 _setDateDatepicker: function( target, date ) { 18726 var inst = this._getInst( target ); 18727 if ( inst ) { 18728 this._setDate( inst, date ); 18729 this._updateDatepicker( inst ); 18730 this._updateAlternate( inst ); 18731 } 18732 }, 18733 18734 /* Get the date(s) for the first entry in a jQuery selection. 18735 * @param target element - the target input field or division or span 18736 * @param noDefault boolean - true if no default date is to be used 18737 * @return Date - the current date 18738 */ 18739 _getDateDatepicker: function( target, noDefault ) { 18740 var inst = this._getInst( target ); 18741 if ( inst && !inst.inline ) { 18742 this._setDateFromField( inst, noDefault ); 18743 } 18744 return ( inst ? this._getDate( inst ) : null ); 18745 }, 18746 18747 /* Handle keystrokes. */ 18748 _doKeyDown: function( event ) { 18749 var onSelect, dateStr, sel, 18750 inst = $.datepicker._getInst( event.target ), 18751 handled = true, 18752 isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); 18753 18754 inst._keyEvent = true; 18755 if ( $.datepicker._datepickerShowing ) { 18756 switch ( event.keyCode ) { 18757 case 9: $.datepicker._hideDatepicker(); 18758 handled = false; 18759 break; // hide on tab out 18760 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + 18761 $.datepicker._currentClass + ")", inst.dpDiv ); 18762 if ( sel[ 0 ] ) { 18763 $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); 18764 } 18765 18766 onSelect = $.datepicker._get( inst, "onSelect" ); 18767 if ( onSelect ) { 18768 dateStr = $.datepicker._formatDate( inst ); 18769 18770 // Trigger custom callback 18771 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); 18772 } else { 18773 $.datepicker._hideDatepicker(); 18774 } 18775 18776 return false; // don't submit the form 18777 case 27: $.datepicker._hideDatepicker(); 18778 break; // hide on escape 18779 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 18780 -$.datepicker._get( inst, "stepBigMonths" ) : 18781 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 18782 break; // previous month/year on page up/+ ctrl 18783 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 18784 +$.datepicker._get( inst, "stepBigMonths" ) : 18785 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 18786 break; // next month/year on page down/+ ctrl 18787 case 35: if ( event.ctrlKey || event.metaKey ) { 18788 $.datepicker._clearDate( event.target ); 18789 } 18790 handled = event.ctrlKey || event.metaKey; 18791 break; // clear on ctrl or command +end 18792 case 36: if ( event.ctrlKey || event.metaKey ) { 18793 $.datepicker._gotoToday( event.target ); 18794 } 18795 handled = event.ctrlKey || event.metaKey; 18796 break; // current on ctrl or command +home 18797 case 37: if ( event.ctrlKey || event.metaKey ) { 18798 $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); 18799 } 18800 handled = event.ctrlKey || event.metaKey; 18801 18802 // -1 day on ctrl or command +left 18803 if ( event.originalEvent.altKey ) { 18804 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 18805 -$.datepicker._get( inst, "stepBigMonths" ) : 18806 -$.datepicker._get( inst, "stepMonths" ) ), "M" ); 18807 } 18808 18809 // next month/year on alt +left on Mac 18810 break; 18811 case 38: if ( event.ctrlKey || event.metaKey ) { 18812 $.datepicker._adjustDate( event.target, -7, "D" ); 18813 } 18814 handled = event.ctrlKey || event.metaKey; 18815 break; // -1 week on ctrl or command +up 18816 case 39: if ( event.ctrlKey || event.metaKey ) { 18817 $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); 18818 } 18819 handled = event.ctrlKey || event.metaKey; 18820 18821 // +1 day on ctrl or command +right 18822 if ( event.originalEvent.altKey ) { 18823 $.datepicker._adjustDate( event.target, ( event.ctrlKey ? 18824 +$.datepicker._get( inst, "stepBigMonths" ) : 18825 +$.datepicker._get( inst, "stepMonths" ) ), "M" ); 18826 } 18827 18828 // next month/year on alt +right 18829 break; 18830 case 40: if ( event.ctrlKey || event.metaKey ) { 18831 $.datepicker._adjustDate( event.target, +7, "D" ); 18832 } 18833 handled = event.ctrlKey || event.metaKey; 18834 break; // +1 week on ctrl or command +down 18835 default: handled = false; 18836 } 18837 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home 18838 $.datepicker._showDatepicker( this ); 18839 } else { 18840 handled = false; 18841 } 18842 18843 if ( handled ) { 18844 event.preventDefault(); 18845 event.stopPropagation(); 18846 } 18847 }, 18848 18849 /* Filter entered characters - based on date format. */ 18850 _doKeyPress: function( event ) { 18851 var chars, chr, 18852 inst = $.datepicker._getInst( event.target ); 18853 18854 if ( $.datepicker._get( inst, "constrainInput" ) ) { 18855 chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); 18856 chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); 18857 return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); 18858 } 18859 }, 18860 18861 /* Synchronise manual entry and field/alternate field. */ 18862 _doKeyUp: function( event ) { 18863 var date, 18864 inst = $.datepicker._getInst( event.target ); 18865 18866 if ( inst.input.val() !== inst.lastVal ) { 18867 try { 18868 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 18869 ( inst.input ? inst.input.val() : null ), 18870 $.datepicker._getFormatConfig( inst ) ); 18871 18872 if ( date ) { // only if valid 18873 $.datepicker._setDateFromField( inst ); 18874 $.datepicker._updateAlternate( inst ); 18875 $.datepicker._updateDatepicker( inst ); 18876 } 18877 } catch ( err ) { 18878 } 18879 } 18880 return true; 18881 }, 18882 18883 /* Pop-up the date picker for a given input field. 18884 * If false returned from beforeShow event handler do not show. 18885 * @param input element - the input field attached to the date picker or
vendor: 1,885 bytes, lines 18886-18943
18886 * event - if triggered by focus 18887 */ 18888 _showDatepicker: function( input ) { 18889 input = input.target || input; 18890 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger 18891 input = $( "input", input.parentNode )[ 0 ]; 18892 } 18893 18894 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here 18895 return; 18896 } 18897 18898 var inst, beforeShow, beforeShowSettings, isFixed, 18899 offset, showAnim, duration; 18900 18901 inst = $.datepicker._getInst( input ); 18902 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { 18903 $.datepicker._curInst.dpDiv.stop( true, true ); 18904 if ( inst && $.datepicker._datepickerShowing ) { 18905 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); 18906 } 18907 } 18908 18909 beforeShow = $.datepicker._get( inst, "beforeShow" ); 18910 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; 18911 if ( beforeShowSettings === false ) { 18912 return; 18913 } 18914 datepicker_extendRemove( inst.settings, beforeShowSettings ); 18915 18916 inst.lastVal = null; 18917 $.datepicker._lastInput = input; 18918 $.datepicker._setDateFromField( inst ); 18919 18920 if ( $.datepicker._inDialog ) { // hide cursor 18921 input.value = ""; 18922 } 18923 if ( !$.datepicker._pos ) { // position below input 18924 $.datepicker._pos = $.datepicker._findPos( input ); 18925 $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height 18926 } 18927 18928 isFixed = false; 18929 $( input ).parents().each( function() { 18930 isFixed |= $( this ).css( "position" ) === "fixed"; 18931 return !isFixed; 18932 } ); 18933 18934 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; 18935 $.datepicker._pos = null; 18936 18937 //to avoid flashes on Firefox 18938 inst.dpDiv.empty(); 18939 18940 // determine sizing offscreen 18941 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); 18942 $.datepicker._updateDatepicker( inst ); 18943
vendor: 8,237 bytes, lines 18944-19167
18944 // fix width for dynamic number of date pickers 18945 // and adjust position before showing 18946 offset = $.datepicker._checkOffset( inst, offset, isFixed ); 18947 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? 18948 "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", 18949 left: offset.left + "px", top: offset.top + "px" } ); 18950 18951 if ( !inst.inline ) { 18952 showAnim = $.datepicker._get( inst, "showAnim" ); 18953 duration = $.datepicker._get( inst, "duration" ); 18954 inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); 18955 $.datepicker._datepickerShowing = true; 18956 18957 if ( $.effects && $.effects.effect[ showAnim ] ) { 18958 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); 18959 } else { 18960 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); 18961 } 18962 18963 if ( $.datepicker._shouldFocusInput( inst ) ) { 18964 inst.input.trigger( "focus" ); 18965 } 18966 18967 $.datepicker._curInst = inst; 18968 } 18969 }, 18970 18971 /* Generate the date picker content. */ 18972 _updateDatepicker: function( inst ) { 18973 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) 18974 datepicker_instActive = inst; // for delegate hover events 18975 inst.dpDiv.empty().append( this._generateHTML( inst ) ); 18976 this._attachHandlers( inst ); 18977 18978 var origyearshtml, 18979 numMonths = this._getNumberOfMonths( inst ), 18980 cols = numMonths[ 1 ], 18981 width = 17, 18982 activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), 18983 onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); 18984 18985 if ( activeCell.length > 0 ) { 18986 datepicker_handleMouseover.apply( activeCell.get( 0 ) ); 18987 } 18988 18989 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); 18990 if ( cols > 1 ) { 18991 inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); 18992 } 18993 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + 18994 "Class" ]( "ui-datepicker-multi" ); 18995 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + 18996 "Class" ]( "ui-datepicker-rtl" ); 18997 18998 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { 18999 inst.input.trigger( "focus" ); 19000 } 19001 19002 // Deffered render of the years select (to avoid flashes on Firefox) 19003 if ( inst.yearshtml ) { 19004 origyearshtml = inst.yearshtml; 19005 setTimeout( function() { 19006 19007 //assure that inst.yearshtml didn't change. 19008 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { 19009 inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); 19010 } 19011 origyearshtml = inst.yearshtml = null; 19012 }, 0 ); 19013 } 19014 19015 if ( onUpdateDatepicker ) { 19016 onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); 19017 } 19018 }, 19019 19020 // #6694 - don't focus the input if it's already focused 19021 // this breaks the change event in IE 19022 // Support: IE and jQuery <1.9 19023 _shouldFocusInput: function( inst ) { 19024 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); 19025 }, 19026 19027 /* Check positioning to remain on screen. */ 19028 _checkOffset: function( inst, offset, isFixed ) { 19029 var dpWidth = inst.dpDiv.outerWidth(), 19030 dpHeight = inst.dpDiv.outerHeight(), 19031 inputWidth = inst.input ? inst.input.outerWidth() : 0, 19032 inputHeight = inst.input ? inst.input.outerHeight() : 0, 19033 viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), 19034 viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); 19035 19036 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); 19037 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; 19038 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; 19039 19040 // Now check if datepicker is showing outside window viewport - move to a better place if so. 19041 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? 19042 Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); 19043 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? 19044 Math.abs( dpHeight + inputHeight ) : 0 ); 19045 19046 return offset; 19047 }, 19048 19049 /* Find an object's position on the screen. */ 19050 _findPos: function( obj ) { 19051 var position, 19052 inst = this._getInst( obj ), 19053 isRTL = this._get( inst, "isRTL" ); 19054 19055 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { 19056 obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; 19057 } 19058 19059 position = $( obj ).offset(); 19060 return [ position.left, position.top ]; 19061 }, 19062 19063 /* Hide the date picker from view. 19064 * @param input element - the input field attached to the date picker 19065 */ 19066 _hideDatepicker: function( input ) { 19067 var showAnim, duration, postProcess, onClose, 19068 inst = this._curInst; 19069 19070 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { 19071 return; 19072 } 19073 19074 if ( this._datepickerShowing ) { 19075 showAnim = this._get( inst, "showAnim" ); 19076 duration = this._get( inst, "duration" ); 19077 postProcess = function() { 19078 $.datepicker._tidyDialog( inst ); 19079 }; 19080 19081 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed 19082 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { 19083 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); 19084 } else { 19085 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : 19086 ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); 19087 } 19088 19089 if ( !showAnim ) { 19090 postProcess(); 19091 } 19092 this._datepickerShowing = false; 19093 19094 onClose = this._get( inst, "onClose" ); 19095 if ( onClose ) { 19096 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); 19097 } 19098 19099 this._lastInput = null; 19100 if ( this._inDialog ) { 19101 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); 19102 if ( $.blockUI ) { 19103 $.unblockUI(); 19104 $( "body" ).append( this.dpDiv ); 19105 } 19106 } 19107 this._inDialog = false; 19108 } 19109 }, 19110 19111 /* Tidy up after a dialog display. */ 19112 _tidyDialog: function( inst ) { 19113 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); 19114 }, 19115 19116 /* Close date picker if clicked elsewhere. */ 19117 _checkExternalClick: function( event ) { 19118 if ( !$.datepicker._curInst ) { 19119 return; 19120 } 19121 19122 var $target = $( event.target ), 19123 inst = $.datepicker._getInst( $target[ 0 ] ); 19124 19125 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && 19126 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && 19127 !$target.hasClass( $.datepicker.markerClassName ) && 19128 !$target.closest( "." + $.datepicker._triggerClass ).length && 19129 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || 19130 ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { 19131 $.datepicker._hideDatepicker(); 19132 } 19133 }, 19134 19135 /* Adjust one of the date sub-fields. */ 19136 _adjustDate: function( id, offset, period ) { 19137 var target = $( id ), 19138 inst = this._getInst( target[ 0 ] ); 19139 19140 if ( this._isDisabledDatepicker( target[ 0 ] ) ) { 19141 return; 19142 } 19143 this._adjustInstDate( inst, offset, period ); 19144 this._updateDatepicker( inst ); 19145 }, 19146 19147 /* Action for current link. */ 19148 _gotoToday: function( id ) { 19149 var date, 19150 target = $( id ), 19151 inst = this._getInst( target[ 0 ] ); 19152 19153 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { 19154 inst.selectedDay = inst.currentDay; 19155 inst.drawMonth = inst.selectedMonth = inst.currentMonth; 19156 inst.drawYear = inst.selectedYear = inst.currentYear; 19157 } else { 19158 date = new Date(); 19159 inst.selectedDay = date.getDate(); 19160 inst.drawMonth = inst.selectedMonth = date.getMonth(); 19161 inst.drawYear = inst.selectedYear = date.getFullYear(); 19162 } 19163 this._notifyChange( inst ); 19164 this._adjustDate( target ); 19165 }, 19166 19167 /* Action for selecting a new month/year. */
vendor: 43,872 bytes, lines 19168-20338
19168 _selectMonthYear: function( id, select, period ) { 19169 var target = $( id ), 19170 inst = this._getInst( target[ 0 ] ); 19171 19172 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = 19173 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = 19174 parseInt( select.options[ select.selectedIndex ].value, 10 ); 19175 19176 this._notifyChange( inst ); 19177 this._adjustDate( target ); 19178 }, 19179 19180 /* Action for selecting a day. */ 19181 _selectDay: function( id, month, year, td ) { 19182 var inst, 19183 target = $( id ); 19184 19185 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { 19186 return; 19187 } 19188 19189 inst = this._getInst( target[ 0 ] ); 19190 inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); 19191 inst.selectedMonth = inst.currentMonth = month; 19192 inst.selectedYear = inst.currentYear = year; 19193 this._selectDate( id, this._formatDate( inst, 19194 inst.currentDay, inst.currentMonth, inst.currentYear ) ); 19195 }, 19196 19197 /* Erase the input field and hide the date picker. */ 19198 _clearDate: function( id ) { 19199 var target = $( id ); 19200 this._selectDate( target, "" ); 19201 }, 19202 19203 /* Update the input field with the selected date. */ 19204 _selectDate: function( id, dateStr ) { 19205 var onSelect, 19206 target = $( id ), 19207 inst = this._getInst( target[ 0 ] ); 19208 19209 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); 19210 if ( inst.input ) { 19211 inst.input.val( dateStr ); 19212 } 19213 this._updateAlternate( inst ); 19214 19215 onSelect = this._get( inst, "onSelect" ); 19216 if ( onSelect ) { 19217 onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback 19218 } else if ( inst.input ) { 19219 inst.input.trigger( "change" ); // fire the change event 19220 } 19221 19222 if ( inst.inline ) { 19223 this._updateDatepicker( inst ); 19224 } else { 19225 this._hideDatepicker(); 19226 this._lastInput = inst.input[ 0 ]; 19227 if ( typeof( inst.input[ 0 ] ) !== "object" ) { 19228 inst.input.trigger( "focus" ); // restore focus 19229 } 19230 this._lastInput = null; 19231 } 19232 }, 19233 19234 /* Update any alternate field to synchronise with the main field. */ 19235 _updateAlternate: function( inst ) { 19236 var altFormat, date, dateStr, 19237 altField = this._get( inst, "altField" ); 19238 19239 if ( altField ) { // update alternate field too 19240 altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); 19241 date = this._getDate( inst ); 19242 dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); 19243 $( document ).find( altField ).val( dateStr ); 19244 } 19245 }, 19246 19247 /* Set as beforeShowDay function to prevent selection of weekends. 19248 * @param date Date - the date to customise 19249 * @return [boolean, string] - is this date selectable?, what is its CSS class? 19250 */ 19251 noWeekends: function( date ) { 19252 var day = date.getDay(); 19253 return [ ( day > 0 && day < 6 ), "" ]; 19254 }, 19255 19256 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. 19257 * @param date Date - the date to get the week for 19258 * @return number - the number of the week within the year that contains this date 19259 */ 19260 iso8601Week: function( date ) { 19261 var time, 19262 checkDate = new Date( date.getTime() ); 19263 19264 // Find Thursday of this week starting on Monday 19265 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); 19266 19267 time = checkDate.getTime(); 19268 checkDate.setMonth( 0 ); // Compare with Jan 1 19269 checkDate.setDate( 1 ); 19270 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; 19271 }, 19272 19273 /* Parse a string value into a date object. 19274 * See formatDate below for the possible formats. 19275 * 19276 * @param format string - the expected format of the date 19277 * @param value string - the date in the above format 19278 * @param settings Object - attributes include: 19279 * shortYearCutoff number - the cutoff year for determining the century (optional) 19280 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 19281 * dayNames string[7] - names of the days from Sunday (optional) 19282 * monthNamesShort string[12] - abbreviated names of the months (optional) 19283 * monthNames string[12] - names of the months (optional) 19284 * @return Date - the extracted date value or null if value is blank 19285 */ 19286 parseDate: function( format, value, settings ) { 19287 if ( format == null || value == null ) { 19288 throw "Invalid arguments"; 19289 } 19290 19291 value = ( typeof value === "object" ? value.toString() : value + "" ); 19292 if ( value === "" ) { 19293 return null; 19294 } 19295 19296 var iFormat, dim, extra, 19297 iValue = 0, 19298 shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, 19299 shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : 19300 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), 19301 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 19302 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 19303 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 19304 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 19305 year = -1, 19306 month = -1, 19307 day = -1, 19308 doy = -1, 19309 literal = false, 19310 date, 19311 19312 // Check whether a format character is doubled 19313 lookAhead = function( match ) { 19314 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 19315 if ( matches ) { 19316 iFormat++; 19317 } 19318 return matches; 19319 }, 19320 19321 // Extract a number from the string value 19322 getNumber = function( match ) { 19323 var isDoubled = lookAhead( match ), 19324 size = ( match === "@" ? 14 : ( match === "!" ? 20 : 19325 ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), 19326 minSize = ( match === "y" ? size : 1 ), 19327 digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), 19328 num = value.substring( iValue ).match( digits ); 19329 if ( !num ) { 19330 throw "Missing number at position " + iValue; 19331 } 19332 iValue += num[ 0 ].length; 19333 return parseInt( num[ 0 ], 10 ); 19334 }, 19335 19336 // Extract a name from the string value and convert to an index 19337 getName = function( match, shortNames, longNames ) { 19338 var index = -1, 19339 names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { 19340 return [ [ k, v ] ]; 19341 } ).sort( function( a, b ) { 19342 return -( a[ 1 ].length - b[ 1 ].length ); 19343 } ); 19344 19345 $.each( names, function( i, pair ) { 19346 var name = pair[ 1 ]; 19347 if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { 19348 index = pair[ 0 ]; 19349 iValue += name.length; 19350 return false; 19351 } 19352 } ); 19353 if ( index !== -1 ) { 19354 return index + 1; 19355 } else { 19356 throw "Unknown name at position " + iValue; 19357 } 19358 }, 19359 19360 // Confirm that a literal character matches the string value 19361 checkLiteral = function() { 19362 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { 19363 throw "Unexpected literal at position " + iValue; 19364 } 19365 iValue++; 19366 }; 19367 19368 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 19369 if ( literal ) { 19370 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 19371 literal = false; 19372 } else { 19373 checkLiteral(); 19374 } 19375 } else { 19376 switch ( format.charAt( iFormat ) ) { 19377 case "d": 19378 day = getNumber( "d" ); 19379 break; 19380 case "D": 19381 getName( "D", dayNamesShort, dayNames ); 19382 break; 19383 case "o": 19384 doy = getNumber( "o" ); 19385 break; 19386 case "m": 19387 month = getNumber( "m" ); 19388 break; 19389 case "M": 19390 month = getName( "M", monthNamesShort, monthNames ); 19391 break; 19392 case "y": 19393 year = getNumber( "y" ); 19394 break; 19395 case "@": 19396 date = new Date( getNumber( "@" ) ); 19397 year = date.getFullYear(); 19398 month = date.getMonth() + 1; 19399 day = date.getDate(); 19400 break; 19401 case "!": 19402 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); 19403 year = date.getFullYear(); 19404 month = date.getMonth() + 1; 19405 day = date.getDate(); 19406 break; 19407 case "'": 19408 if ( lookAhead( "'" ) ) { 19409 checkLiteral(); 19410 } else { 19411 literal = true; 19412 } 19413 break; 19414 default: 19415 checkLiteral(); 19416 } 19417 } 19418 } 19419 19420 if ( iValue < value.length ) { 19421 extra = value.substr( iValue ); 19422 if ( !/^\s+/.test( extra ) ) { 19423 throw "Extra/unparsed characters found in date: " + extra; 19424 } 19425 } 19426 19427 if ( year === -1 ) { 19428 year = new Date().getFullYear(); 19429 } else if ( year < 100 ) { 19430 year += new Date().getFullYear() - new Date().getFullYear() % 100 + 19431 ( year <= shortYearCutoff ? 0 : -100 ); 19432 } 19433 19434 if ( doy > -1 ) { 19435 month = 1; 19436 day = doy; 19437 do { 19438 dim = this._getDaysInMonth( year, month - 1 ); 19439 if ( day <= dim ) { 19440 break; 19441 } 19442 month++; 19443 day -= dim; 19444 } while ( true ); 19445 } 19446 19447 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); 19448 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { 19449 throw "Invalid date"; // E.g. 31/02/00 19450 } 19451 return date; 19452 }, 19453 19454 /* Standard date formats. */ 19455 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) 19456 COOKIE: "D, dd M yy", 19457 ISO_8601: "yy-mm-dd", 19458 RFC_822: "D, d M y", 19459 RFC_850: "DD, dd-M-y", 19460 RFC_1036: "D, d M y", 19461 RFC_1123: "D, d M yy", 19462 RFC_2822: "D, d M yy", 19463 RSS: "D, d M y", // RFC 822 19464 TICKS: "!", 19465 TIMESTAMP: "@", 19466 W3C: "yy-mm-dd", // ISO 8601 19467 19468 _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + 19469 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), 19470 19471 /* Format a date object into a string value. 19472 * The format can be combinations of the following: 19473 * d - day of month (no leading zero) 19474 * dd - day of month (two digit) 19475 * o - day of year (no leading zeros) 19476 * oo - day of year (three digit) 19477 * D - day name short 19478 * DD - day name long 19479 * m - month of year (no leading zero) 19480 * mm - month of year (two digit) 19481 * M - month name short 19482 * MM - month name long 19483 * y - year (two digit) 19484 * yy - year (four digit) 19485 * @ - Unix timestamp (ms since 01/01/1970) 19486 * ! - Windows ticks (100ns since 01/01/0001) 19487 * "..." - literal text 19488 * '' - single quote 19489 * 19490 * @param format string - the desired format of the date 19491 * @param date Date - the date value to format 19492 * @param settings Object - attributes include: 19493 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) 19494 * dayNames string[7] - names of the days from Sunday (optional) 19495 * monthNamesShort string[12] - abbreviated names of the months (optional) 19496 * monthNames string[12] - names of the months (optional) 19497 * @return string - the date in the above format 19498 */ 19499 formatDate: function( format, date, settings ) { 19500 if ( !date ) { 19501 return ""; 19502 } 19503 19504 var iFormat, 19505 dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, 19506 dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, 19507 monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, 19508 monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, 19509 19510 // Check whether a format character is doubled 19511 lookAhead = function( match ) { 19512 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 19513 if ( matches ) { 19514 iFormat++; 19515 } 19516 return matches; 19517 }, 19518 19519 // Format a number, with leading zero if necessary 19520 formatNumber = function( match, value, len ) { 19521 var num = "" + value; 19522 if ( lookAhead( match ) ) { 19523 while ( num.length < len ) { 19524 num = "0" + num; 19525 } 19526 } 19527 return num; 19528 }, 19529 19530 // Format a name, short or long as requested 19531 formatName = function( match, value, shortNames, longNames ) { 19532 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); 19533 }, 19534 output = "", 19535 literal = false; 19536 19537 if ( date ) { 19538 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 19539 if ( literal ) { 19540 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 19541 literal = false; 19542 } else { 19543 output += format.charAt( iFormat ); 19544 } 19545 } else { 19546 switch ( format.charAt( iFormat ) ) { 19547 case "d": 19548 output += formatNumber( "d", date.getDate(), 2 ); 19549 break; 19550 case "D": 19551 output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); 19552 break; 19553 case "o": 19554 output += formatNumber( "o", 19555 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); 19556 break; 19557 case "m": 19558 output += formatNumber( "m", date.getMonth() + 1, 2 ); 19559 break; 19560 case "M": 19561 output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); 19562 break; 19563 case "y": 19564 output += ( lookAhead( "y" ) ? date.getFullYear() : 19565 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); 19566 break; 19567 case "@": 19568 output += date.getTime(); 19569 break; 19570 case "!": 19571 output += date.getTime() * 10000 + this._ticksTo1970; 19572 break; 19573 case "'": 19574 if ( lookAhead( "'" ) ) { 19575 output += "'"; 19576 } else { 19577 literal = true; 19578 } 19579 break; 19580 default: 19581 output += format.charAt( iFormat ); 19582 } 19583 } 19584 } 19585 } 19586 return output; 19587 }, 19588 19589 /* Extract all possible characters from the date format. */ 19590 _possibleChars: function( format ) { 19591 var iFormat, 19592 chars = "", 19593 literal = false, 19594 19595 // Check whether a format character is doubled 19596 lookAhead = function( match ) { 19597 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); 19598 if ( matches ) { 19599 iFormat++; 19600 } 19601 return matches; 19602 }; 19603 19604 for ( iFormat = 0; iFormat < format.length; iFormat++ ) { 19605 if ( literal ) { 19606 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { 19607 literal = false; 19608 } else { 19609 chars += format.charAt( iFormat ); 19610 } 19611 } else { 19612 switch ( format.charAt( iFormat ) ) { 19613 case "d": case "m": case "y": case "@": 19614 chars += "0123456789"; 19615 break; 19616 case "D": case "M": 19617 return null; // Accept anything 19618 case "'": 19619 if ( lookAhead( "'" ) ) { 19620 chars += "'"; 19621 } else { 19622 literal = true; 19623 } 19624 break; 19625 default: 19626 chars += format.charAt( iFormat ); 19627 } 19628 } 19629 } 19630 return chars; 19631 }, 19632 19633 /* Get a setting value, defaulting if necessary. */ 19634 _get: function( inst, name ) { 19635 return inst.settings[ name ] !== undefined ? 19636 inst.settings[ name ] : this._defaults[ name ]; 19637 }, 19638 19639 /* Parse existing date and initialise date picker. */ 19640 _setDateFromField: function( inst, noDefault ) { 19641 if ( inst.input.val() === inst.lastVal ) { 19642 return; 19643 } 19644 19645 var dateFormat = this._get( inst, "dateFormat" ), 19646 dates = inst.lastVal = inst.input ? inst.input.val() : null, 19647 defaultDate = this._getDefaultDate( inst ), 19648 date = defaultDate, 19649 settings = this._getFormatConfig( inst ); 19650 19651 try { 19652 date = this.parseDate( dateFormat, dates, settings ) || defaultDate; 19653 } catch ( event ) { 19654 dates = ( noDefault ? "" : dates ); 19655 } 19656 inst.selectedDay = date.getDate(); 19657 inst.drawMonth = inst.selectedMonth = date.getMonth(); 19658 inst.drawYear = inst.selectedYear = date.getFullYear(); 19659 inst.currentDay = ( dates ? date.getDate() : 0 ); 19660 inst.currentMonth = ( dates ? date.getMonth() : 0 ); 19661 inst.currentYear = ( dates ? date.getFullYear() : 0 ); 19662 this._adjustInstDate( inst ); 19663 }, 19664 19665 /* Retrieve the default date shown on opening. */ 19666 _getDefaultDate: function( inst ) { 19667 return this._restrictMinMax( inst, 19668 this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); 19669 }, 19670 19671 /* A date may be specified as an exact value or a relative one. */ 19672 _determineDate: function( inst, date, defaultDate ) { 19673 var offsetNumeric = function( offset ) { 19674 var date = new Date(); 19675 date.setDate( date.getDate() + offset ); 19676 return date; 19677 }, 19678 offsetString = function( offset ) { 19679 try { 19680 return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), 19681 offset, $.datepicker._getFormatConfig( inst ) ); 19682 } catch ( e ) { 19683 19684 // Ignore 19685 } 19686 19687 var date = ( offset.toLowerCase().match( /^c/ ) ? 19688 $.datepicker._getDate( inst ) : null ) || new Date(), 19689 year = date.getFullYear(), 19690 month = date.getMonth(), 19691 day = date.getDate(), 19692 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, 19693 matches = pattern.exec( offset ); 19694 19695 while ( matches ) { 19696 switch ( matches[ 2 ] || "d" ) { 19697 case "d" : case "D" : 19698 day += parseInt( matches[ 1 ], 10 ); break; 19699 case "w" : case "W" : 19700 day += parseInt( matches[ 1 ], 10 ) * 7; break; 19701 case "m" : case "M" : 19702 month += parseInt( matches[ 1 ], 10 ); 19703 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 19704 break; 19705 case "y": case "Y" : 19706 year += parseInt( matches[ 1 ], 10 ); 19707 day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); 19708 break; 19709 } 19710 matches = pattern.exec( offset ); 19711 } 19712 return new Date( year, month, day ); 19713 }, 19714 newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : 19715 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); 19716 19717 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); 19718 if ( newDate ) { 19719 newDate.setHours( 0 ); 19720 newDate.setMinutes( 0 ); 19721 newDate.setSeconds( 0 ); 19722 newDate.setMilliseconds( 0 ); 19723 } 19724 return this._daylightSavingAdjust( newDate ); 19725 }, 19726 19727 /* Handle switch to/from daylight saving. 19728 * Hours may be non-zero on daylight saving cut-over: 19729 * > 12 when midnight changeover, but then cannot generate 19730 * midnight datetime, so jump to 1AM, otherwise reset. 19731 * @param date (Date) the date to check 19732 * @return (Date) the corrected date 19733 */ 19734 _daylightSavingAdjust: function( date ) { 19735 if ( !date ) { 19736 return null; 19737 } 19738 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); 19739 return date; 19740 }, 19741 19742 /* Set the date(s) directly. */ 19743 _setDate: function( inst, date, noChange ) { 19744 var clear = !date, 19745 origMonth = inst.selectedMonth, 19746 origYear = inst.selectedYear, 19747 newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); 19748 19749 inst.selectedDay = inst.currentDay = newDate.getDate(); 19750 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); 19751 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); 19752 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { 19753 this._notifyChange( inst ); 19754 } 19755 this._adjustInstDate( inst ); 19756 if ( inst.input ) { 19757 inst.input.val( clear ? "" : this._formatDate( inst ) ); 19758 } 19759 }, 19760 19761 /* Retrieve the date(s) directly. */ 19762 _getDate: function( inst ) { 19763 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : 19764 this._daylightSavingAdjust( new Date( 19765 inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 19766 return startDate; 19767 }, 19768 19769 /* Attach the onxxx handlers. These are declared statically so 19770 * they work with static code transformers like Caja. 19771 */ 19772 _attachHandlers: function( inst ) { 19773 var stepMonths = this._get( inst, "stepMonths" ), 19774 id = "#" + inst.id.replace( /\\\\/g, "\\" ); 19775 inst.dpDiv.find( "[data-handler]" ).map( function() { 19776 var handler = { 19777 prev: function() { 19778 $.datepicker._adjustDate( id, -stepMonths, "M" ); 19779 }, 19780 next: function() { 19781 $.datepicker._adjustDate( id, +stepMonths, "M" ); 19782 }, 19783 hide: function() { 19784 $.datepicker._hideDatepicker(); 19785 }, 19786 today: function() { 19787 $.datepicker._gotoToday( id ); 19788 }, 19789 selectDay: function() { 19790 $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); 19791 return false; 19792 }, 19793 selectMonth: function() { 19794 $.datepicker._selectMonthYear( id, this, "M" ); 19795 return false; 19796 }, 19797 selectYear: function() { 19798 $.datepicker._selectMonthYear( id, this, "Y" ); 19799 return false; 19800 } 19801 }; 19802 $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); 19803 } ); 19804 }, 19805 19806 /* Generate the HTML for the current state of the date picker. */ 19807 _generateHTML: function( inst ) { 19808 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, 19809 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, 19810 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, 19811 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, 19812 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, 19813 printDate, dRow, tbody, daySettings, otherMonth, unselectable, 19814 tempDate = new Date(), 19815 today = this._daylightSavingAdjust( 19816 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time 19817 isRTL = this._get( inst, "isRTL" ), 19818 showButtonPanel = this._get( inst, "showButtonPanel" ), 19819 hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), 19820 navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), 19821 numMonths = this._getNumberOfMonths( inst ), 19822 showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), 19823 stepMonths = this._get( inst, "stepMonths" ), 19824 isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), 19825 currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : 19826 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), 19827 minDate = this._getMinMaxDate( inst, "min" ), 19828 maxDate = this._getMinMaxDate( inst, "max" ), 19829 drawMonth = inst.drawMonth - showCurrentAtPos, 19830 drawYear = inst.drawYear; 19831 19832 if ( drawMonth < 0 ) { 19833 drawMonth += 12; 19834 drawYear--; 19835 } 19836 if ( maxDate ) { 19837 maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), 19838 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); 19839 maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); 19840 while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { 19841 drawMonth--; 19842 if ( drawMonth < 0 ) { 19843 drawMonth = 11; 19844 drawYear--; 19845 } 19846 } 19847 } 19848 inst.drawMonth = drawMonth; 19849 inst.drawYear = drawYear; 19850 19851 prevText = this._get( inst, "prevText" ); 19852 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, 19853 this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), 19854 this._getFormatConfig( inst ) ) ); 19855 19856 if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { 19857 prev = $( "<a>" ) 19858 .attr( { 19859 "class": "ui-datepicker-prev ui-corner-all", 19860 "data-handler": "prev", 19861 "data-event": "click", 19862 title: prevText 19863 } ) 19864 .append( 19865 $( "<span>" ) 19866 .addClass( "ui-icon ui-icon-circle-triangle-" + 19867 ( isRTL ? "e" : "w" ) ) 19868 .text( prevText ) 19869 )[ 0 ].outerHTML; 19870 } else if ( hideIfNoPrevNext ) { 19871 prev = ""; 19872 } else { 19873 prev = $( "<a>" ) 19874 .attr( { 19875 "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", 19876 title: prevText 19877 } ) 19878 .append( 19879 $( "<span>" ) 19880 .addClass( "ui-icon ui-icon-circle-triangle-" + 19881 ( isRTL ? "e" : "w" ) ) 19882 .text( prevText ) 19883 )[ 0 ].outerHTML; 19884 } 19885 19886 nextText = this._get( inst, "nextText" ); 19887 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, 19888 this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), 19889 this._getFormatConfig( inst ) ) ); 19890 19891 if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { 19892 next = $( "<a>" ) 19893 .attr( { 19894 "class": "ui-datepicker-next ui-corner-all", 19895 "data-handler": "next", 19896 "data-event": "click", 19897 title: nextText 19898 } ) 19899 .append( 19900 $( "<span>" ) 19901 .addClass( "ui-icon ui-icon-circle-triangle-" + 19902 ( isRTL ? "w" : "e" ) ) 19903 .text( nextText ) 19904 )[ 0 ].outerHTML; 19905 } else if ( hideIfNoPrevNext ) { 19906 next = ""; 19907 } else { 19908 next = $( "<a>" ) 19909 .attr( { 19910 "class": "ui-datepicker-next ui-corner-all ui-state-disabled", 19911 title: nextText 19912 } ) 19913 .append( 19914 $( "<span>" ) 19915 .attr( "class", "ui-icon ui-icon-circle-triangle-" + 19916 ( isRTL ? "w" : "e" ) ) 19917 .text( nextText ) 19918 )[ 0 ].outerHTML; 19919 } 19920 19921 currentText = this._get( inst, "currentText" ); 19922 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); 19923 currentText = ( !navigationAsDateFormat ? currentText : 19924 this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); 19925 19926 controls = ""; 19927 if ( !inst.inline ) { 19928 controls = $( "<button>" ) 19929 .attr( { 19930 type: "button", 19931 "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", 19932 "data-handler": "hide", 19933 "data-event": "click" 19934 } ) 19935 .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; 19936 } 19937 19938 buttonPanel = ""; 19939 if ( showButtonPanel ) { 19940 buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) 19941 .append( isRTL ? controls : "" ) 19942 .append( this._isInRange( inst, gotoDate ) ? 19943 $( "<button>" ) 19944 .attr( { 19945 type: "button", 19946 "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", 19947 "data-handler": "today", 19948 "data-event": "click" 19949 } ) 19950 .text( currentText ) : 19951 "" ) 19952 .append( isRTL ? "" : controls )[ 0 ].outerHTML; 19953 } 19954 19955 firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); 19956 firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); 19957 19958 showWeek = this._get( inst, "showWeek" ); 19959 dayNames = this._get( inst, "dayNames" ); 19960 dayNamesMin = this._get( inst, "dayNamesMin" ); 19961 monthNames = this._get( inst, "monthNames" ); 19962 monthNamesShort = this._get( inst, "monthNamesShort" ); 19963 beforeShowDay = this._get( inst, "beforeShowDay" ); 19964 showOtherMonths = this._get( inst, "showOtherMonths" ); 19965 selectOtherMonths = this._get( inst, "selectOtherMonths" ); 19966 defaultDate = this._getDefaultDate( inst ); 19967 html = ""; 19968 19969 for ( row = 0; row < numMonths[ 0 ]; row++ ) { 19970 group = ""; 19971 this.maxRows = 4; 19972 for ( col = 0; col < numMonths[ 1 ]; col++ ) { 19973 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); 19974 cornerClass = " ui-corner-all"; 19975 calender = ""; 19976 if ( isMultiMonth ) { 19977 calender += "<div class='ui-datepicker-group"; 19978 if ( numMonths[ 1 ] > 1 ) { 19979 switch ( col ) { 19980 case 0: calender += " ui-datepicker-group-first"; 19981 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; 19982 case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; 19983 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; 19984 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; 19985 } 19986 } 19987 calender += "'>"; 19988 } 19989 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + 19990 ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + 19991 ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + 19992 this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, 19993 row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers 19994 "</div><table class='ui-datepicker-calendar'><thead>" + 19995 "<tr>"; 19996 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); 19997 for ( dow = 0; dow < 7; dow++ ) { // days of the week 19998 day = ( dow + firstDay ) % 7; 19999 thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + 20000 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; 20001 } 20002 calender += thead + "</tr></thead><tbody>"; 20003 daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); 20004 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { 20005 inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); 20006 } 20007 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; 20008 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate 20009 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) 20010 this.maxRows = numRows; 20011 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); 20012 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows 20013 calender += "<tr>"; 20014 tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + 20015 this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); 20016 for ( dow = 0; dow < 7; dow++ ) { // create date picker days 20017 daySettings = ( beforeShowDay ? 20018 beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); 20019 otherMonth = ( printDate.getMonth() !== drawMonth ); 20020 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || 20021 ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); 20022 tbody += "<td class='" + 20023 ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends 20024 ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months 20025 ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key 20026 ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? 20027 20028 // or defaultDate is current printedDate and defaultDate is selectedDate 20029 " " + this._dayOverClass : "" ) + // highlight selected day 20030 ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days 20031 ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates 20032 ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day 20033 ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) 20034 ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title 20035 ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions 20036 ( otherMonth && !showOtherMonths ? " " : // display for other months 20037 ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + 20038 ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + 20039 ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day 20040 ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months 20041 "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader 20042 "' data-date='" + printDate.getDate() + // store date as data 20043 "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date 20044 printDate.setDate( printDate.getDate() + 1 ); 20045 printDate = this._daylightSavingAdjust( printDate ); 20046 } 20047 calender += tbody + "</tr>"; 20048 } 20049 drawMonth++; 20050 if ( drawMonth > 11 ) { 20051 drawMonth = 0; 20052 drawYear++; 20053 } 20054 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + 20055 ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); 20056 group += calender; 20057 } 20058 html += group; 20059 } 20060 html += buttonPanel; 20061 inst._keyEvent = false; 20062 return html; 20063 }, 20064 20065 /* Generate the month and year header. */ 20066 _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, 20067 secondary, monthNames, monthNamesShort ) { 20068 20069 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, 20070 changeMonth = this._get( inst, "changeMonth" ), 20071 changeYear = this._get( inst, "changeYear" ), 20072 showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), 20073 selectMonthLabel = this._get( inst, "selectMonthLabel" ), 20074 selectYearLabel = this._get( inst, "selectYearLabel" ), 20075 html = "<div class='ui-datepicker-title'>", 20076 monthHtml = ""; 20077 20078 // Month selection 20079 if ( secondary || !changeMonth ) { 20080 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; 20081 } else { 20082 inMinYear = ( minDate && minDate.getFullYear() === drawYear ); 20083 inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); 20084 monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; 20085 for ( month = 0; month < 12; month++ ) { 20086 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { 20087 monthHtml += "<option value='" + month + "'" + 20088 ( month === drawMonth ? " selected='selected'" : "" ) + 20089 ">" + monthNamesShort[ month ] + "</option>"; 20090 } 20091 } 20092 monthHtml += "</select>"; 20093 } 20094 20095 if ( !showMonthAfterYear ) { 20096 html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); 20097 } 20098 20099 // Year selection 20100 if ( !inst.yearshtml ) { 20101 inst.yearshtml = ""; 20102 if ( secondary || !changeYear ) { 20103 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; 20104 } else { 20105 20106 // determine range of years to display 20107 years = this._get( inst, "yearRange" ).split( ":" ); 20108 thisYear = new Date().getFullYear(); 20109 determineYear = function( value ) { 20110 var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : 20111 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : 20112 parseInt( value, 10 ) ) ); 20113 return ( isNaN( year ) ? thisYear : year ); 20114 }; 20115 year = determineYear( years[ 0 ] ); 20116 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); 20117 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); 20118 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); 20119 inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; 20120 for ( ; year <= endYear; year++ ) { 20121 inst.yearshtml += "<option value='" + year + "'" + 20122 ( year === drawYear ? " selected='selected'" : "" ) + 20123 ">" + year + "</option>"; 20124 } 20125 inst.yearshtml += "</select>"; 20126 20127 html += inst.yearshtml; 20128 inst.yearshtml = null; 20129 } 20130 } 20131 20132 html += this._get( inst, "yearSuffix" ); 20133 if ( showMonthAfterYear ) { 20134 html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; 20135 } 20136 html += "</div>"; // Close datepicker_header 20137 return html; 20138 }, 20139 20140 /* Adjust one of the date sub-fields. */ 20141 _adjustInstDate: function( inst, offset, period ) { 20142 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), 20143 month = inst.selectedMonth + ( period === "M" ? offset : 0 ), 20144 day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), 20145 date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); 20146 20147 inst.selectedDay = date.getDate(); 20148 inst.drawMonth = inst.selectedMonth = date.getMonth(); 20149 inst.drawYear = inst.selectedYear = date.getFullYear(); 20150 if ( period === "M" || period === "Y" ) { 20151 this._notifyChange( inst ); 20152 } 20153 }, 20154 20155 /* Ensure a date is within any min/max bounds. */ 20156 _restrictMinMax: function( inst, date ) { 20157 var minDate = this._getMinMaxDate( inst, "min" ), 20158 maxDate = this._getMinMaxDate( inst, "max" ), 20159 newDate = ( minDate && date < minDate ? minDate : date ); 20160 return ( maxDate && newDate > maxDate ? maxDate : newDate ); 20161 }, 20162 20163 /* Notify change of month/year. */ 20164 _notifyChange: function( inst ) { 20165 var onChange = this._get( inst, "onChangeMonthYear" ); 20166 if ( onChange ) { 20167 onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), 20168 [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); 20169 } 20170 }, 20171 20172 /* Determine the number of months to show. */ 20173 _getNumberOfMonths: function( inst ) { 20174 var numMonths = this._get( inst, "numberOfMonths" ); 20175 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); 20176 }, 20177 20178 /* Determine the current maximum date - ensure no time components are set. */ 20179 _getMinMaxDate: function( inst, minMax ) { 20180 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); 20181 }, 20182 20183 /* Find the number of days in a given month. */ 20184 _getDaysInMonth: function( year, month ) { 20185 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); 20186 }, 20187 20188 /* Find the day of the week of the first of a month. */ 20189 _getFirstDayOfMonth: function( year, month ) { 20190 return new Date( year, month, 1 ).getDay(); 20191 }, 20192 20193 /* Determines if we should allow a "next/prev" month display change. */ 20194 _canAdjustMonth: function( inst, offset, curYear, curMonth ) { 20195 var numMonths = this._getNumberOfMonths( inst ), 20196 date = this._daylightSavingAdjust( new Date( curYear, 20197 curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); 20198 20199 if ( offset < 0 ) { 20200 date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); 20201 } 20202 return this._isInRange( inst, date ); 20203 }, 20204 20205 /* Is the given date in the accepted range? */ 20206 _isInRange: function( inst, date ) { 20207 var yearSplit, currentYear, 20208 minDate = this._getMinMaxDate( inst, "min" ), 20209 maxDate = this._getMinMaxDate( inst, "max" ), 20210 minYear = null, 20211 maxYear = null, 20212 years = this._get( inst, "yearRange" ); 20213 if ( years ) { 20214 yearSplit = years.split( ":" ); 20215 currentYear = new Date().getFullYear(); 20216 minYear = parseInt( yearSplit[ 0 ], 10 ); 20217 maxYear = parseInt( yearSplit[ 1 ], 10 ); 20218 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { 20219 minYear += currentYear; 20220 } 20221 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { 20222 maxYear += currentYear; 20223 } 20224 } 20225 20226 return ( ( !minDate || date.getTime() >= minDate.getTime() ) && 20227 ( !maxDate || date.getTime() <= maxDate.getTime() ) && 20228 ( !minYear || date.getFullYear() >= minYear ) && 20229 ( !maxYear || date.getFullYear() <= maxYear ) ); 20230 }, 20231 20232 /* Provide the configuration settings for formatting/parsing. */ 20233 _getFormatConfig: function( inst ) { 20234 var shortYearCutoff = this._get( inst, "shortYearCutoff" ); 20235 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : 20236 new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); 20237 return { shortYearCutoff: shortYearCutoff, 20238 dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), 20239 monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; 20240 }, 20241 20242 /* Format the given date for display. */ 20243 _formatDate: function( inst, day, month, year ) { 20244 if ( !day ) { 20245 inst.currentDay = inst.selectedDay; 20246 inst.currentMonth = inst.selectedMonth; 20247 inst.currentYear = inst.selectedYear; 20248 } 20249 var date = ( day ? ( typeof day === "object" ? day : 20250 this._daylightSavingAdjust( new Date( year, month, day ) ) ) : 20251 this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); 20252 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); 20253 } 20254} ); 20255 20256/* 20257 * Bind hover events for datepicker elements. 20258 * Done via delegate so the binding only occurs once in the lifetime of the parent div. 20259 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. 20260 */ 20261function datepicker_bindHover( dpDiv ) { 20262 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; 20263 return dpDiv.on( "mouseout", selector, function() { 20264 $( this ).removeClass( "ui-state-hover" ); 20265 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 20266 $( this ).removeClass( "ui-datepicker-prev-hover" ); 20267 } 20268 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 20269 $( this ).removeClass( "ui-datepicker-next-hover" ); 20270 } 20271 } ) 20272 .on( "mouseover", selector, datepicker_handleMouseover ); 20273} 20274 20275function datepicker_handleMouseover() { 20276 if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { 20277 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); 20278 $( this ).addClass( "ui-state-hover" ); 20279 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { 20280 $( this ).addClass( "ui-datepicker-prev-hover" ); 20281 } 20282 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { 20283 $( this ).addClass( "ui-datepicker-next-hover" ); 20284 } 20285 } 20286} 20287 20288/* jQuery extend now ignores nulls! */ 20289function datepicker_extendRemove( target, props ) { 20290 $.extend( target, props ); 20291 for ( var name in props ) { 20292 if ( props[ name ] == null ) { 20293 target[ name ] = props[ name ]; 20294 } 20295 } 20296 return target; 20297} 20298 20299/* Invoke the datepicker functionality. 20300 @param options string - a command, optionally followed by additional parameters or 20301 Object - settings for attaching new datepicker functionality 20302 @return jQuery object */ 20303$.fn.datepicker = function( options ) { 20304 20305 /* Verify an empty collection wasn't passed - Fixes #6976 */ 20306 if ( !this.length ) { 20307 return this; 20308 } 20309 20310 /* Initialise the date picker. */ 20311 if ( !$.datepicker.initialized ) { 20312 $( document ).on( "mousedown", $.datepicker._checkExternalClick ); 20313 $.datepicker.initialized = true; 20314 } 20315 20316 /* Append datepicker main container to body if not exist. */ 20317 if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { 20318 $( "body" ).append( $.datepicker.dpDiv ); 20319 } 20320 20321 var otherArgs = Array.prototype.slice.call( arguments, 1 ); 20322 if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { 20323 return $.datepicker[ "_" + options + "Datepicker" ]. 20324 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 20325 } 20326 if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { 20327 return $.datepicker[ "_" + options + "Datepicker" ]. 20328 apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); 20329 } 20330 return this.each( function() { 20331 if ( typeof options === "string" ) { 20332 $.datepicker[ "_" + options + "Datepicker" ] 20333 .apply( $.datepicker, [ this ].concat( otherArgs ) ); 20334 } else { 20335 $.datepicker._attachDatepicker( this, options ); 20336 } 20337 } ); 20338};
vendor: 14,641 bytes, lines 20339-20890
20339 20340$.datepicker = new Datepicker(); // singleton instance 20341$.datepicker.initialized = false; 20342$.datepicker.uuid = new Date().getTime(); 20343$.datepicker.version = "1.13.2"; 20344 20345var widgetsDatepicker = $.datepicker; 20346 20347 20348 20349// This file is deprecated 20350var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); 20351 20352/*! 20353 * jQuery UI Mouse 1.13.2 20354 * http://jqueryui.com 20355 * 20356 * Copyright jQuery Foundation and other contributors 20357 * Released under the MIT license. 20358 * http://jquery.org/license 20359 */ 20360 20361//>>label: Mouse 20362//>>group: Widgets 20363//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 20364//>>docs: http://api.jqueryui.com/mouse/ 20365 20366 20367var mouseHandled = false; 20368$( document ).on( "mouseup", function() { 20369 mouseHandled = false; 20370} ); 20371 20372var widgetsMouse = $.widget( "ui.mouse", { 20373 version: "1.13.2", 20374 options: { 20375 cancel: "input, textarea, button, select, option", 20376 distance: 1, 20377 delay: 0 20378 }, 20379 _mouseInit: function() { 20380 var that = this; 20381 20382 this.element 20383 .on( "mousedown." + this.widgetName, function( event ) { 20384 return that._mouseDown( event ); 20385 } ) 20386 .on( "click." + this.widgetName, function( event ) { 20387 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 20388 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 20389 event.stopImmediatePropagation(); 20390 return false; 20391 } 20392 } ); 20393 20394 this.started = false; 20395 }, 20396 20397 // TODO: make sure destroying one instance of mouse doesn't mess with 20398 // other instances of mouse 20399 _mouseDestroy: function() { 20400 this.element.off( "." + this.widgetName ); 20401 if ( this._mouseMoveDelegate ) { 20402 this.document 20403 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 20404 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 20405 } 20406 }, 20407 20408 _mouseDown: function( event ) { 20409 20410 // don't let more than one widget handle mouseStart 20411 if ( mouseHandled ) { 20412 return; 20413 } 20414 20415 this._mouseMoved = false; 20416 20417 // We may have missed mouseup (out of window) 20418 if ( this._mouseStarted ) { 20419 this._mouseUp( event ); 20420 } 20421 20422 this._mouseDownEvent = event; 20423 20424 var that = this, 20425 btnIsLeft = ( event.which === 1 ), 20426 20427 // event.target.nodeName works around a bug in IE 8 with 20428 // disabled inputs (#7620) 20429 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 20430 $( event.target ).closest( this.options.cancel ).length : false ); 20431 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 20432 return true; 20433 } 20434 20435 this.mouseDelayMet = !this.options.delay; 20436 if ( !this.mouseDelayMet ) { 20437 this._mouseDelayTimer = setTimeout( function() { 20438 that.mouseDelayMet = true; 20439 }, this.options.delay ); 20440 } 20441 20442 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 20443 this._mouseStarted = ( this._mouseStart( event ) !== false ); 20444 if ( !this._mouseStarted ) { 20445 event.preventDefault(); 20446 return true; 20447 } 20448 } 20449 20450 // Click event may never have fired (Gecko & Opera) 20451 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 20452 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 20453 } 20454 20455 // These delegates are required to keep context 20456 this._mouseMoveDelegate = function( event ) { 20457 return that._mouseMove( event ); 20458 }; 20459 this._mouseUpDelegate = function( event ) { 20460 return that._mouseUp( event ); 20461 }; 20462 20463 this.document 20464 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 20465 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 20466 20467 event.preventDefault(); 20468 20469 mouseHandled = true; 20470 return true; 20471 }, 20472 20473 _mouseMove: function( event ) { 20474 20475 // Only check for mouseups outside the document if you've moved inside the document 20476 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 20477 // fire a mousemove event if content is placed under the cursor. See #7778 20478 // Support: IE <9 20479 if ( this._mouseMoved ) { 20480 20481 // IE mouseup check - mouseup happened when mouse was out of window 20482 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 20483 !event.button ) { 20484 return this._mouseUp( event ); 20485 20486 // Iframe mouseup check - mouseup occurred in another document 20487 } else if ( !event.which ) { 20488 20489 // Support: Safari <=8 - 9 20490 // Safari sets which to 0 if you press any of the following keys 20491 // during a drag (#14461) 20492 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 20493 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 20494 this.ignoreMissingWhich = true; 20495 } else if ( !this.ignoreMissingWhich ) { 20496 return this._mouseUp( event ); 20497 } 20498 } 20499 } 20500 20501 if ( event.which || event.button ) { 20502 this._mouseMoved = true; 20503 } 20504 20505 if ( this._mouseStarted ) { 20506 this._mouseDrag( event ); 20507 return event.preventDefault(); 20508 } 20509 20510 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 20511 this._mouseStarted = 20512 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 20513 if ( this._mouseStarted ) { 20514 this._mouseDrag( event ); 20515 } else { 20516 this._mouseUp( event ); 20517 } 20518 } 20519 20520 return !this._mouseStarted; 20521 }, 20522 20523 _mouseUp: function( event ) { 20524 this.document 20525 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 20526 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 20527 20528 if ( this._mouseStarted ) { 20529 this._mouseStarted = false; 20530 20531 if ( event.target === this._mouseDownEvent.target ) { 20532 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 20533 } 20534 20535 this._mouseStop( event ); 20536 } 20537 20538 if ( this._mouseDelayTimer ) { 20539 clearTimeout( this._mouseDelayTimer ); 20540 delete this._mouseDelayTimer; 20541 } 20542 20543 this.ignoreMissingWhich = false; 20544 mouseHandled = false; 20545 event.preventDefault(); 20546 }, 20547 20548 _mouseDistanceMet: function( event ) { 20549 return ( Math.max( 20550 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 20551 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 20552 ) >= this.options.distance 20553 ); 20554 }, 20555 20556 _mouseDelayMet: function( /* event */ ) { 20557 return this.mouseDelayMet; 20558 }, 20559 20560 // These are placeholder methods, to be overriden by extending plugin 20561 _mouseStart: function( /* event */ ) {}, 20562 _mouseDrag: function( /* event */ ) {}, 20563 _mouseStop: function( /* event */ ) {}, 20564 _mouseCapture: function( /* event */ ) { 20565 return true; 20566 } 20567} ); 20568 20569 20570 20571// $.ui.plugin is deprecated. Use $.widget() extensions instead. 20572var plugin = $.ui.plugin = { 20573 add: function( module, option, set ) { 20574 var i, 20575 proto = $.ui[ module ].prototype; 20576 for ( i in set ) { 20577 proto.plugins[ i ] = proto.plugins[ i ] || []; 20578 proto.plugins[ i ].push( [ option, set[ i ] ] ); 20579 } 20580 }, 20581 call: function( instance, name, args, allowDisconnected ) { 20582 var i, 20583 set = instance.plugins[ name ]; 20584 20585 if ( !set ) { 20586 return; 20587 } 20588 20589 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || 20590 instance.element[ 0 ].parentNode.nodeType === 11 ) ) { 20591 return; 20592 } 20593 20594 for ( i = 0; i < set.length; i++ ) { 20595 if ( instance.options[ set[ i ][ 0 ] ] ) { 20596 set[ i ][ 1 ].apply( instance.element, args ); 20597 } 20598 } 20599 } 20600}; 20601 20602 20603 20604var safeBlur = $.ui.safeBlur = function( element ) { 20605 20606 // Support: IE9 - 10 only 20607 // If the <body> is blurred, IE will switch windows, see #9420 20608 if ( element && element.nodeName.toLowerCase() !== "body" ) { 20609 $( element ).trigger( "blur" ); 20610 } 20611}; 20612 20613 20614/*! 20615 * jQuery UI Draggable 1.13.2 20616 * http://jqueryui.com 20617 * 20618 * Copyright jQuery Foundation and other contributors 20619 * Released under the MIT license. 20620 * http://jquery.org/license 20621 */ 20622 20623//>>label: Draggable 20624//>>group: Interactions 20625//>>description: Enables dragging functionality for any element. 20626//>>docs: http://api.jqueryui.com/draggable/ 20627//>>demos: http://jqueryui.com/draggable/ 20628//>>css.structure: ../../themes/base/draggable.css 20629 20630 20631$.widget( "ui.draggable", $.ui.mouse, { 20632 version: "1.13.2", 20633 widgetEventPrefix: "drag", 20634 options: { 20635 addClasses: true, 20636 appendTo: "parent", 20637 axis: false, 20638 connectToSortable: false, 20639 containment: false, 20640 cursor: "auto", 20641 cursorAt: false, 20642 grid: false, 20643 handle: false, 20644 helper: "original", 20645 iframeFix: false, 20646 opacity: false, 20647 refreshPositions: false, 20648 revert: false, 20649 revertDuration: 500, 20650 scope: "default", 20651 scroll: true, 20652 scrollSensitivity: 20, 20653 scrollSpeed: 20, 20654 snap: false, 20655 snapMode: "both", 20656 snapTolerance: 20, 20657 stack: false, 20658 zIndex: false, 20659 20660 // Callbacks 20661 drag: null, 20662 start: null, 20663 stop: null 20664 }, 20665 _create: function() { 20666 20667 if ( this.options.helper === "original" ) { 20668 this._setPositionRelative(); 20669 } 20670 if ( this.options.addClasses ) { 20671 this._addClass( "ui-draggable" ); 20672 } 20673 this._setHandleClassName(); 20674 20675 this._mouseInit(); 20676 }, 20677 20678 _setOption: function( key, value ) { 20679 this._super( key, value ); 20680 if ( key === "handle" ) { 20681 this._removeHandleClassName(); 20682 this._setHandleClassName(); 20683 } 20684 }, 20685 20686 _destroy: function() { 20687 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { 20688 this.destroyOnClear = true; 20689 return; 20690 } 20691 this._removeHandleClassName(); 20692 this._mouseDestroy(); 20693 }, 20694 20695 _mouseCapture: function( event ) { 20696 var o = this.options; 20697 20698 // Among others, prevent a drag on a resizable-handle 20699 if ( this.helper || o.disabled || 20700 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { 20701 return false; 20702 } 20703 20704 //Quit if we're not on a valid handle 20705 this.handle = this._getHandle( event ); 20706 if ( !this.handle ) { 20707 return false; 20708 } 20709 20710 this._blurActiveElement( event ); 20711 20712 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); 20713 20714 return true; 20715 20716 }, 20717 20718 _blockFrames: function( selector ) { 20719 this.iframeBlocks = this.document.find( selector ).map( function() { 20720 var iframe = $( this ); 20721 20722 return $( "<div>" ) 20723 .css( "position", "absolute" ) 20724 .appendTo( iframe.parent() ) 20725 .outerWidth( iframe.outerWidth() ) 20726 .outerHeight( iframe.outerHeight() ) 20727 .offset( iframe.offset() )[ 0 ]; 20728 } ); 20729 }, 20730 20731 _unblockFrames: function() { 20732 if ( this.iframeBlocks ) { 20733 this.iframeBlocks.remove(); 20734 delete this.iframeBlocks; 20735 } 20736 }, 20737 20738 _blurActiveElement: function( event ) { 20739 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 20740 target = $( event.target ); 20741 20742 // Don't blur if the event occurred on an element that is within 20743 // the currently focused element 20744 // See #10527, #12472 20745 if ( target.closest( activeElement ).length ) { 20746 return; 20747 } 20748 20749 // Blur any element that currently has focus, see #4261 20750 $.ui.safeBlur( activeElement ); 20751 }, 20752 20753 _mouseStart: function( event ) { 20754 20755 var o = this.options; 20756 20757 //Create and append the visible helper 20758 this.helper = this._createHelper( event ); 20759 20760 this._addClass( this.helper, "ui-draggable-dragging" ); 20761 20762 //Cache the helper size 20763 this._cacheHelperProportions(); 20764 20765 //If ddmanager is used for droppables, set the global draggable 20766 if ( $.ui.ddmanager ) { 20767 $.ui.ddmanager.current = this; 20768 } 20769 20770 /* 20771 * - Position generation - 20772 * This block generates everything position related - it's the core of draggables. 20773 */ 20774 20775 //Cache the margins of the original element 20776 this._cacheMargins(); 20777 20778 //Store the helper's css position 20779 this.cssPosition = this.helper.css( "position" ); 20780 this.scrollParent = this.helper.scrollParent( true ); 20781 this.offsetParent = this.helper.offsetParent(); 20782 this.hasFixedAncestor = this.helper.parents().filter( function() { 20783 return $( this ).css( "position" ) === "fixed"; 20784 } ).length > 0; 20785 20786 //The element's absolute position on the page minus margins 20787 this.positionAbs = this.element.offset(); 20788 this._refreshOffsets( event ); 20789 20790 //Generate the original position 20791 this.originalPosition = this.position = this._generatePosition( event, false ); 20792 this.originalPageX = event.pageX; 20793 this.originalPageY = event.pageY; 20794 20795 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 20796 if ( o.cursorAt ) { 20797 this._adjustOffsetFromHelper( o.cursorAt ); 20798 } 20799 20800 //Set a containment if given in the options 20801 this._setContainment(); 20802 20803 //Trigger event + callbacks 20804 if ( this._trigger( "start", event ) === false ) { 20805 this._clear(); 20806 return false; 20807 } 20808 20809 //Recache the helper size 20810 this._cacheHelperProportions(); 20811 20812 //Prepare the droppable offsets 20813 if ( $.ui.ddmanager && !o.dropBehaviour ) { 20814 $.ui.ddmanager.prepareOffsets( this, event ); 20815 } 20816 20817 // Execute the drag once - this causes the helper not to be visible before getting its 20818 // correct position 20819 this._mouseDrag( event, true ); 20820 20821 // If the ddmanager is used for droppables, inform the manager that dragging has started 20822 // (see #5003) 20823 if ( $.ui.ddmanager ) { 20824 $.ui.ddmanager.dragStart( this, event ); 20825 } 20826 20827 return true; 20828 }, 20829 20830 _refreshOffsets: function( event ) { 20831 this.offset = { 20832 top: this.positionAbs.top - this.margins.top, 20833 left: this.positionAbs.left - this.margins.left, 20834 scroll: false, 20835 parent: this._getParentOffset(), 20836 relative: this._getRelativeOffset() 20837 }; 20838 20839 this.offset.click = { 20840 left: event.pageX - this.offset.left, 20841 top: event.pageY - this.offset.top 20842 }; 20843 }, 20844 20845 _mouseDrag: function( event, noPropagation ) { 20846 20847 // reset any necessary cached properties (see #5009) 20848 if ( this.hasFixedAncestor ) { 20849 this.offset.parent = this._getParentOffset(); 20850 } 20851 20852 //Compute the helpers position 20853 this.position = this._generatePosition( event, true ); 20854 this.positionAbs = this._convertPositionTo( "absolute" ); 20855 20856 //Call plugins and callbacks and use the resulting position if something is returned 20857 if ( !noPropagation ) { 20858 var ui = this._uiHash(); 20859 if ( this._trigger( "drag", event, ui ) === false ) { 20860 this._mouseUp( new $.Event( "mouseup", event ) ); 20861 return false; 20862 } 20863 this.position = ui.position; 20864 } 20865 20866 this.helper[ 0 ].style.left = this.position.left + "px"; 20867 this.helper[ 0 ].style.top = this.position.top + "px"; 20868 20869 if ( $.ui.ddmanager ) { 20870 $.ui.ddmanager.drag( this, event ); 20871 } 20872 20873 return false; 20874 }, 20875 20876 _mouseStop: function( event ) { 20877 20878 //If we are using droppables, inform the manager about the drop 20879 var that = this, 20880 dropped = false; 20881 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 20882 dropped = $.ui.ddmanager.drop( this, event ); 20883 } 20884 20885 //if a drop comes from outside (a sortable) 20886 if ( this.dropped ) { 20887 dropped = this.dropped; 20888 this.dropped = false; 20889 } 20890
vendor: 29,295 bytes, lines 20891-21851
20891 if ( ( this.options.revert === "invalid" && !dropped ) || 20892 ( this.options.revert === "valid" && dropped ) || 20893 this.options.revert === true || ( typeof this.options.revert === "function" && 20894 this.options.revert.call( this.element, dropped ) ) 20895 ) { 20896 $( this.helper ).animate( 20897 this.originalPosition, 20898 parseInt( this.options.revertDuration, 10 ), 20899 function() { 20900 if ( that._trigger( "stop", event ) !== false ) { 20901 that._clear(); 20902 } 20903 } 20904 ); 20905 } else { 20906 if ( this._trigger( "stop", event ) !== false ) { 20907 this._clear(); 20908 } 20909 } 20910 20911 return false; 20912 }, 20913 20914 _mouseUp: function( event ) { 20915 this._unblockFrames(); 20916 20917 // If the ddmanager is used for droppables, inform the manager that dragging has stopped 20918 // (see #5003) 20919 if ( $.ui.ddmanager ) { 20920 $.ui.ddmanager.dragStop( this, event ); 20921 } 20922 20923 // Only need to focus if the event occurred on the draggable itself, see #10527 20924 if ( this.handleElement.is( event.target ) ) { 20925 20926 // The interaction is over; whether or not the click resulted in a drag, 20927 // focus the element 20928 this.element.trigger( "focus" ); 20929 } 20930 20931 return $.ui.mouse.prototype._mouseUp.call( this, event ); 20932 }, 20933 20934 cancel: function() { 20935 20936 if ( this.helper.is( ".ui-draggable-dragging" ) ) { 20937 this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); 20938 } else { 20939 this._clear(); 20940 } 20941 20942 return this; 20943 20944 }, 20945 20946 _getHandle: function( event ) { 20947 return this.options.handle ? 20948 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : 20949 true; 20950 }, 20951 20952 _setHandleClassName: function() { 20953 this.handleElement = this.options.handle ? 20954 this.element.find( this.options.handle ) : this.element; 20955 this._addClass( this.handleElement, "ui-draggable-handle" ); 20956 }, 20957 20958 _removeHandleClassName: function() { 20959 this._removeClass( this.handleElement, "ui-draggable-handle" ); 20960 }, 20961 20962 _createHelper: function( event ) { 20963 20964 var o = this.options, 20965 helperIsFunction = typeof o.helper === "function", 20966 helper = helperIsFunction ? 20967 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : 20968 ( o.helper === "clone" ? 20969 this.element.clone().removeAttr( "id" ) : 20970 this.element ); 20971 20972 if ( !helper.parents( "body" ).length ) { 20973 helper.appendTo( ( o.appendTo === "parent" ? 20974 this.element[ 0 ].parentNode : 20975 o.appendTo ) ); 20976 } 20977 20978 // Http://bugs.jqueryui.com/ticket/9446 20979 // a helper function can return the original element 20980 // which wouldn't have been set to relative in _create 20981 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { 20982 this._setPositionRelative(); 20983 } 20984 20985 if ( helper[ 0 ] !== this.element[ 0 ] && 20986 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { 20987 helper.css( "position", "absolute" ); 20988 } 20989 20990 return helper; 20991 20992 }, 20993 20994 _setPositionRelative: function() { 20995 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { 20996 this.element[ 0 ].style.position = "relative"; 20997 } 20998 }, 20999 21000 _adjustOffsetFromHelper: function( obj ) { 21001 if ( typeof obj === "string" ) { 21002 obj = obj.split( " " ); 21003 } 21004 if ( Array.isArray( obj ) ) { 21005 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 21006 } 21007 if ( "left" in obj ) { 21008 this.offset.click.left = obj.left + this.margins.left; 21009 } 21010 if ( "right" in obj ) { 21011 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 21012 } 21013 if ( "top" in obj ) { 21014 this.offset.click.top = obj.top + this.margins.top; 21015 } 21016 if ( "bottom" in obj ) { 21017 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 21018 } 21019 }, 21020 21021 _isRootNode: function( element ) { 21022 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; 21023 }, 21024 21025 _getParentOffset: function() { 21026 21027 //Get the offsetParent and cache its position 21028 var po = this.offsetParent.offset(), 21029 document = this.document[ 0 ]; 21030 21031 // This is a special case where we need to modify a offset calculated on start, since the 21032 // following happened: 21033 // 1. The position of the helper is absolute, so it's position is calculated based on the 21034 // next positioned parent 21035 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 21036 // the document, which means that the scroll is included in the initial calculation of the 21037 // offset of the parent, and never recalculated upon drag 21038 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && 21039 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 21040 po.left += this.scrollParent.scrollLeft(); 21041 po.top += this.scrollParent.scrollTop(); 21042 } 21043 21044 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { 21045 po = { top: 0, left: 0 }; 21046 } 21047 21048 return { 21049 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 21050 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 21051 }; 21052 21053 }, 21054 21055 _getRelativeOffset: function() { 21056 if ( this.cssPosition !== "relative" ) { 21057 return { top: 0, left: 0 }; 21058 } 21059 21060 var p = this.element.position(), 21061 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 21062 21063 return { 21064 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 21065 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), 21066 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 21067 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) 21068 }; 21069 21070 }, 21071 21072 _cacheMargins: function() { 21073 this.margins = { 21074 left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), 21075 top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), 21076 right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), 21077 bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) 21078 }; 21079 }, 21080 21081 _cacheHelperProportions: function() { 21082 this.helperProportions = { 21083 width: this.helper.outerWidth(), 21084 height: this.helper.outerHeight() 21085 }; 21086 }, 21087 21088 _setContainment: function() { 21089 21090 var isUserScrollable, c, ce, 21091 o = this.options, 21092 document = this.document[ 0 ]; 21093 21094 this.relativeContainer = null; 21095 21096 if ( !o.containment ) { 21097 this.containment = null; 21098 return; 21099 } 21100 21101 if ( o.containment === "window" ) { 21102 this.containment = [ 21103 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, 21104 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, 21105 $( window ).scrollLeft() + $( window ).width() - 21106 this.helperProportions.width - this.margins.left, 21107 $( window ).scrollTop() + 21108 ( $( window ).height() || document.body.parentNode.scrollHeight ) - 21109 this.helperProportions.height - this.margins.top 21110 ]; 21111 return; 21112 } 21113 21114 if ( o.containment === "document" ) { 21115 this.containment = [ 21116 0, 21117 0, 21118 $( document ).width() - this.helperProportions.width - this.margins.left, 21119 ( $( document ).height() || document.body.parentNode.scrollHeight ) - 21120 this.helperProportions.height - this.margins.top 21121 ]; 21122 return; 21123 } 21124 21125 if ( o.containment.constructor === Array ) { 21126 this.containment = o.containment; 21127 return; 21128 } 21129 21130 if ( o.containment === "parent" ) { 21131 o.containment = this.helper[ 0 ].parentNode; 21132 } 21133 21134 c = $( o.containment ); 21135 ce = c[ 0 ]; 21136 21137 if ( !ce ) { 21138 return; 21139 } 21140 21141 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); 21142 21143 this.containment = [ 21144 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + 21145 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), 21146 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + 21147 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), 21148 ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 21149 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - 21150 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - 21151 this.helperProportions.width - 21152 this.margins.left - 21153 this.margins.right, 21154 ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 21155 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - 21156 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - 21157 this.helperProportions.height - 21158 this.margins.top - 21159 this.margins.bottom 21160 ]; 21161 this.relativeContainer = c; 21162 }, 21163 21164 _convertPositionTo: function( d, pos ) { 21165 21166 if ( !pos ) { 21167 pos = this.position; 21168 } 21169 21170 var mod = d === "absolute" ? 1 : -1, 21171 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); 21172 21173 return { 21174 top: ( 21175 21176 // The absolute mouse position 21177 pos.top + 21178 21179 // Only for relative positioned nodes: Relative offset from element to offset parent 21180 this.offset.relative.top * mod + 21181 21182 // The offsetParent's offset without borders (offset + border) 21183 this.offset.parent.top * mod - 21184 ( ( this.cssPosition === "fixed" ? 21185 -this.offset.scroll.top : 21186 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) 21187 ), 21188 left: ( 21189 21190 // The absolute mouse position 21191 pos.left + 21192 21193 // Only for relative positioned nodes: Relative offset from element to offset parent 21194 this.offset.relative.left * mod + 21195 21196 // The offsetParent's offset without borders (offset + border) 21197 this.offset.parent.left * mod - 21198 ( ( this.cssPosition === "fixed" ? 21199 -this.offset.scroll.left : 21200 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) 21201 ) 21202 }; 21203 21204 }, 21205 21206 _generatePosition: function( event, constrainPosition ) { 21207 21208 var containment, co, top, left, 21209 o = this.options, 21210 scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), 21211 pageX = event.pageX, 21212 pageY = event.pageY; 21213 21214 // Cache the scroll 21215 if ( !scrollIsRootNode || !this.offset.scroll ) { 21216 this.offset.scroll = { 21217 top: this.scrollParent.scrollTop(), 21218 left: this.scrollParent.scrollLeft() 21219 }; 21220 } 21221 21222 /* 21223 * - Position constraining - 21224 * Constrain the position to a mix of grid, containment. 21225 */ 21226 21227 // If we are not dragging yet, we won't check for options 21228 if ( constrainPosition ) { 21229 if ( this.containment ) { 21230 if ( this.relativeContainer ) { 21231 co = this.relativeContainer.offset(); 21232 containment = [ 21233 this.containment[ 0 ] + co.left, 21234 this.containment[ 1 ] + co.top, 21235 this.containment[ 2 ] + co.left, 21236 this.containment[ 3 ] + co.top 21237 ]; 21238 } else { 21239 containment = this.containment; 21240 } 21241 21242 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { 21243 pageX = containment[ 0 ] + this.offset.click.left; 21244 } 21245 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { 21246 pageY = containment[ 1 ] + this.offset.click.top; 21247 } 21248 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { 21249 pageX = containment[ 2 ] + this.offset.click.left; 21250 } 21251 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { 21252 pageY = containment[ 3 ] + this.offset.click.top; 21253 } 21254 } 21255 21256 if ( o.grid ) { 21257 21258 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid 21259 // argument errors in IE (see ticket #6950) 21260 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - 21261 this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; 21262 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || 21263 top - this.offset.click.top > containment[ 3 ] ) ? 21264 top : 21265 ( ( top - this.offset.click.top >= containment[ 1 ] ) ? 21266 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; 21267 21268 left = o.grid[ 0 ] ? this.originalPageX + 21269 Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : 21270 this.originalPageX; 21271 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || 21272 left - this.offset.click.left > containment[ 2 ] ) ? 21273 left : 21274 ( ( left - this.offset.click.left >= containment[ 0 ] ) ? 21275 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; 21276 } 21277 21278 if ( o.axis === "y" ) { 21279 pageX = this.originalPageX; 21280 } 21281 21282 if ( o.axis === "x" ) { 21283 pageY = this.originalPageY; 21284 } 21285 } 21286 21287 return { 21288 top: ( 21289 21290 // The absolute mouse position 21291 pageY - 21292 21293 // Click offset (relative to the element) 21294 this.offset.click.top - 21295 21296 // Only for relative positioned nodes: Relative offset from element to offset parent 21297 this.offset.relative.top - 21298 21299 // The offsetParent's offset without borders (offset + border) 21300 this.offset.parent.top + 21301 ( this.cssPosition === "fixed" ? 21302 -this.offset.scroll.top : 21303 ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) 21304 ), 21305 left: ( 21306 21307 // The absolute mouse position 21308 pageX - 21309 21310 // Click offset (relative to the element) 21311 this.offset.click.left - 21312 21313 // Only for relative positioned nodes: Relative offset from element to offset parent 21314 this.offset.relative.left - 21315 21316 // The offsetParent's offset without borders (offset + border) 21317 this.offset.parent.left + 21318 ( this.cssPosition === "fixed" ? 21319 -this.offset.scroll.left : 21320 ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) 21321 ) 21322 }; 21323 21324 }, 21325 21326 _clear: function() { 21327 this._removeClass( this.helper, "ui-draggable-dragging" ); 21328 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { 21329 this.helper.remove(); 21330 } 21331 this.helper = null; 21332 this.cancelHelperRemoval = false; 21333 if ( this.destroyOnClear ) { 21334 this.destroy(); 21335 } 21336 }, 21337 21338 // From now on bulk stuff - mainly helpers 21339 21340 _trigger: function( type, event, ui ) { 21341 ui = ui || this._uiHash(); 21342 $.ui.plugin.call( this, type, [ event, ui, this ], true ); 21343 21344 // Absolute position and offset (see #6884 ) have to be recalculated after plugins 21345 if ( /^(drag|start|stop)/.test( type ) ) { 21346 this.positionAbs = this._convertPositionTo( "absolute" ); 21347 ui.offset = this.positionAbs; 21348 } 21349 return $.Widget.prototype._trigger.call( this, type, event, ui ); 21350 }, 21351 21352 plugins: {}, 21353 21354 _uiHash: function() { 21355 return { 21356 helper: this.helper, 21357 position: this.position, 21358 originalPosition: this.originalPosition, 21359 offset: this.positionAbs 21360 }; 21361 } 21362 21363} ); 21364 21365$.ui.plugin.add( "draggable", "connectToSortable", { 21366 start: function( event, ui, draggable ) { 21367 var uiSortable = $.extend( {}, ui, { 21368 item: draggable.element 21369 } ); 21370 21371 draggable.sortables = []; 21372 $( draggable.options.connectToSortable ).each( function() { 21373 var sortable = $( this ).sortable( "instance" ); 21374 21375 if ( sortable && !sortable.options.disabled ) { 21376 draggable.sortables.push( sortable ); 21377 21378 // RefreshPositions is called at drag start to refresh the containerCache 21379 // which is used in drag. This ensures it's initialized and synchronized 21380 // with any changes that might have happened on the page since initialization. 21381 sortable.refreshPositions(); 21382 sortable._trigger( "activate", event, uiSortable ); 21383 } 21384 } ); 21385 }, 21386 stop: function( event, ui, draggable ) { 21387 var uiSortable = $.extend( {}, ui, { 21388 item: draggable.element 21389 } ); 21390 21391 draggable.cancelHelperRemoval = false; 21392 21393 $.each( draggable.sortables, function() { 21394 var sortable = this; 21395 21396 if ( sortable.isOver ) { 21397 sortable.isOver = 0; 21398 21399 // Allow this sortable to handle removing the helper 21400 draggable.cancelHelperRemoval = true; 21401 sortable.cancelHelperRemoval = false; 21402 21403 // Use _storedCSS To restore properties in the sortable, 21404 // as this also handles revert (#9675) since the draggable 21405 // may have modified them in unexpected ways (#8809) 21406 sortable._storedCSS = { 21407 position: sortable.placeholder.css( "position" ), 21408 top: sortable.placeholder.css( "top" ), 21409 left: sortable.placeholder.css( "left" ) 21410 }; 21411 21412 sortable._mouseStop( event ); 21413 21414 // Once drag has ended, the sortable should return to using 21415 // its original helper, not the shared helper from draggable 21416 sortable.options.helper = sortable.options._helper; 21417 } else { 21418 21419 // Prevent this Sortable from removing the helper. 21420 // However, don't set the draggable to remove the helper 21421 // either as another connected Sortable may yet handle the removal. 21422 sortable.cancelHelperRemoval = true; 21423 21424 sortable._trigger( "deactivate", event, uiSortable ); 21425 } 21426 } ); 21427 }, 21428 drag: function( event, ui, draggable ) { 21429 $.each( draggable.sortables, function() { 21430 var innermostIntersecting = false, 21431 sortable = this; 21432 21433 // Copy over variables that sortable's _intersectsWith uses 21434 sortable.positionAbs = draggable.positionAbs; 21435 sortable.helperProportions = draggable.helperProportions; 21436 sortable.offset.click = draggable.offset.click; 21437 21438 if ( sortable._intersectsWith( sortable.containerCache ) ) { 21439 innermostIntersecting = true; 21440 21441 $.each( draggable.sortables, function() { 21442 21443 // Copy over variables that sortable's _intersectsWith uses 21444 this.positionAbs = draggable.positionAbs; 21445 this.helperProportions = draggable.helperProportions; 21446 this.offset.click = draggable.offset.click; 21447 21448 if ( this !== sortable && 21449 this._intersectsWith( this.containerCache ) && 21450 $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { 21451 innermostIntersecting = false; 21452 } 21453 21454 return innermostIntersecting; 21455 } ); 21456 } 21457 21458 if ( innermostIntersecting ) { 21459 21460 // If it intersects, we use a little isOver variable and set it once, 21461 // so that the move-in stuff gets fired only once. 21462 if ( !sortable.isOver ) { 21463 sortable.isOver = 1; 21464 21465 // Store draggable's parent in case we need to reappend to it later. 21466 draggable._parent = ui.helper.parent(); 21467 21468 sortable.currentItem = ui.helper 21469 .appendTo( sortable.element ) 21470 .data( "ui-sortable-item", true ); 21471 21472 // Store helper option to later restore it 21473 sortable.options._helper = sortable.options.helper; 21474 21475 sortable.options.helper = function() { 21476 return ui.helper[ 0 ]; 21477 }; 21478 21479 // Fire the start events of the sortable with our passed browser event, 21480 // and our own helper (so it doesn't create a new one) 21481 event.target = sortable.currentItem[ 0 ]; 21482 sortable._mouseCapture( event, true ); 21483 sortable._mouseStart( event, true, true ); 21484 21485 // Because the browser event is way off the new appended portlet, 21486 // modify necessary variables to reflect the changes 21487 sortable.offset.click.top = draggable.offset.click.top; 21488 sortable.offset.click.left = draggable.offset.click.left; 21489 sortable.offset.parent.left -= draggable.offset.parent.left - 21490 sortable.offset.parent.left; 21491 sortable.offset.parent.top -= draggable.offset.parent.top - 21492 sortable.offset.parent.top; 21493 21494 draggable._trigger( "toSortable", event ); 21495 21496 // Inform draggable that the helper is in a valid drop zone, 21497 // used solely in the revert option to handle "valid/invalid". 21498 draggable.dropped = sortable.element; 21499 21500 // Need to refreshPositions of all sortables in the case that 21501 // adding to one sortable changes the location of the other sortables (#9675) 21502 $.each( draggable.sortables, function() { 21503 this.refreshPositions(); 21504 } ); 21505 21506 // Hack so receive/update callbacks work (mostly) 21507 draggable.currentItem = draggable.element; 21508 sortable.fromOutside = draggable; 21509 } 21510 21511 if ( sortable.currentItem ) { 21512 sortable._mouseDrag( event ); 21513 21514 // Copy the sortable's position because the draggable's can potentially reflect 21515 // a relative position, while sortable is always absolute, which the dragged 21516 // element has now become. (#8809) 21517 ui.position = sortable.position; 21518 } 21519 } else { 21520 21521 // If it doesn't intersect with the sortable, and it intersected before, 21522 // we fake the drag stop of the sortable, but make sure it doesn't remove 21523 // the helper by using cancelHelperRemoval. 21524 if ( sortable.isOver ) { 21525 21526 sortable.isOver = 0; 21527 sortable.cancelHelperRemoval = true; 21528 21529 // Calling sortable's mouseStop would trigger a revert, 21530 // so revert must be temporarily false until after mouseStop is called. 21531 sortable.options._revert = sortable.options.revert; 21532 sortable.options.revert = false; 21533 21534 sortable._trigger( "out", event, sortable._uiHash( sortable ) ); 21535 sortable._mouseStop( event, true ); 21536 21537 // Restore sortable behaviors that were modfied 21538 // when the draggable entered the sortable area (#9481) 21539 sortable.options.revert = sortable.options._revert; 21540 sortable.options.helper = sortable.options._helper; 21541 21542 if ( sortable.placeholder ) { 21543 sortable.placeholder.remove(); 21544 } 21545 21546 // Restore and recalculate the draggable's offset considering the sortable 21547 // may have modified them in unexpected ways. (#8809, #10669) 21548 ui.helper.appendTo( draggable._parent ); 21549 draggable._refreshOffsets( event ); 21550 ui.position = draggable._generatePosition( event, true ); 21551 21552 draggable._trigger( "fromSortable", event ); 21553 21554 // Inform draggable that the helper is no longer in a valid drop zone 21555 draggable.dropped = false; 21556 21557 // Need to refreshPositions of all sortables just in case removing 21558 // from one sortable changes the location of other sortables (#9675) 21559 $.each( draggable.sortables, function() { 21560 this.refreshPositions(); 21561 } ); 21562 } 21563 } 21564 } ); 21565 } 21566} ); 21567 21568$.ui.plugin.add( "draggable", "cursor", { 21569 start: function( event, ui, instance ) { 21570 var t = $( "body" ), 21571 o = instance.options; 21572 21573 if ( t.css( "cursor" ) ) { 21574 o._cursor = t.css( "cursor" ); 21575 } 21576 t.css( "cursor", o.cursor ); 21577 }, 21578 stop: function( event, ui, instance ) { 21579 var o = instance.options; 21580 if ( o._cursor ) { 21581 $( "body" ).css( "cursor", o._cursor ); 21582 } 21583 } 21584} ); 21585 21586$.ui.plugin.add( "draggable", "opacity", { 21587 start: function( event, ui, instance ) { 21588 var t = $( ui.helper ), 21589 o = instance.options; 21590 if ( t.css( "opacity" ) ) { 21591 o._opacity = t.css( "opacity" ); 21592 } 21593 t.css( "opacity", o.opacity ); 21594 }, 21595 stop: function( event, ui, instance ) { 21596 var o = instance.options; 21597 if ( o._opacity ) { 21598 $( ui.helper ).css( "opacity", o._opacity ); 21599 } 21600 } 21601} ); 21602 21603$.ui.plugin.add( "draggable", "scroll", { 21604 start: function( event, ui, i ) { 21605 if ( !i.scrollParentNotHidden ) { 21606 i.scrollParentNotHidden = i.helper.scrollParent( false ); 21607 } 21608 21609 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && 21610 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { 21611 i.overflowOffset = i.scrollParentNotHidden.offset(); 21612 } 21613 }, 21614 drag: function( event, ui, i ) { 21615 21616 var o = i.options, 21617 scrolled = false, 21618 scrollParent = i.scrollParentNotHidden[ 0 ], 21619 document = i.document[ 0 ]; 21620 21621 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { 21622 if ( !o.axis || o.axis !== "x" ) { 21623 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < 21624 o.scrollSensitivity ) { 21625 scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; 21626 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { 21627 scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; 21628 } 21629 } 21630 21631 if ( !o.axis || o.axis !== "y" ) { 21632 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < 21633 o.scrollSensitivity ) { 21634 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; 21635 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { 21636 scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; 21637 } 21638 } 21639 21640 } else { 21641 21642 if ( !o.axis || o.axis !== "x" ) { 21643 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { 21644 scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); 21645 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < 21646 o.scrollSensitivity ) { 21647 scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); 21648 } 21649 } 21650 21651 if ( !o.axis || o.axis !== "y" ) { 21652 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { 21653 scrolled = $( document ).scrollLeft( 21654 $( document ).scrollLeft() - o.scrollSpeed 21655 ); 21656 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < 21657 o.scrollSensitivity ) { 21658 scrolled = $( document ).scrollLeft( 21659 $( document ).scrollLeft() + o.scrollSpeed 21660 ); 21661 } 21662 } 21663 21664 } 21665 21666 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { 21667 $.ui.ddmanager.prepareOffsets( i, event ); 21668 } 21669 21670 } 21671} ); 21672 21673$.ui.plugin.add( "draggable", "snap", { 21674 start: function( event, ui, i ) { 21675 21676 var o = i.options; 21677 21678 i.snapElements = []; 21679 21680 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) 21681 .each( function() { 21682 var $t = $( this ), 21683 $o = $t.offset(); 21684 if ( this !== i.element[ 0 ] ) { 21685 i.snapElements.push( { 21686 item: this, 21687 width: $t.outerWidth(), height: $t.outerHeight(), 21688 top: $o.top, left: $o.left 21689 } ); 21690 } 21691 } ); 21692 21693 }, 21694 drag: function( event, ui, inst ) { 21695 21696 var ts, bs, ls, rs, l, r, t, b, i, first, 21697 o = inst.options, 21698 d = o.snapTolerance, 21699 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, 21700 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; 21701 21702 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { 21703 21704 l = inst.snapElements[ i ].left - inst.margins.left; 21705 r = l + inst.snapElements[ i ].width; 21706 t = inst.snapElements[ i ].top - inst.margins.top; 21707 b = t + inst.snapElements[ i ].height; 21708 21709 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || 21710 !$.contains( inst.snapElements[ i ].item.ownerDocument, 21711 inst.snapElements[ i ].item ) ) { 21712 if ( inst.snapElements[ i ].snapping ) { 21713 if ( inst.options.snap.release ) { 21714 inst.options.snap.release.call( 21715 inst.element, 21716 event, 21717 $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) 21718 ); 21719 } 21720 } 21721 inst.snapElements[ i ].snapping = false; 21722 continue; 21723 } 21724 21725 if ( o.snapMode !== "inner" ) { 21726 ts = Math.abs( t - y2 ) <= d; 21727 bs = Math.abs( b - y1 ) <= d; 21728 ls = Math.abs( l - x2 ) <= d; 21729 rs = Math.abs( r - x1 ) <= d; 21730 if ( ts ) { 21731 ui.position.top = inst._convertPositionTo( "relative", { 21732 top: t - inst.helperProportions.height, 21733 left: 0 21734 } ).top; 21735 } 21736 if ( bs ) { 21737 ui.position.top = inst._convertPositionTo( "relative", { 21738 top: b, 21739 left: 0 21740 } ).top; 21741 } 21742 if ( ls ) { 21743 ui.position.left = inst._convertPositionTo( "relative", { 21744 top: 0, 21745 left: l - inst.helperProportions.width 21746 } ).left; 21747 } 21748 if ( rs ) { 21749 ui.position.left = inst._convertPositionTo( "relative", { 21750 top: 0, 21751 left: r 21752 } ).left; 21753 } 21754 } 21755 21756 first = ( ts || bs || ls || rs ); 21757 21758 if ( o.snapMode !== "outer" ) { 21759 ts = Math.abs( t - y1 ) <= d; 21760 bs = Math.abs( b - y2 ) <= d; 21761 ls = Math.abs( l - x1 ) <= d; 21762 rs = Math.abs( r - x2 ) <= d; 21763 if ( ts ) { 21764 ui.position.top = inst._convertPositionTo( "relative", { 21765 top: t, 21766 left: 0 21767 } ).top; 21768 } 21769 if ( bs ) { 21770 ui.position.top = inst._convertPositionTo( "relative", { 21771 top: b - inst.helperProportions.height, 21772 left: 0 21773 } ).top; 21774 } 21775 if ( ls ) { 21776 ui.position.left = inst._convertPositionTo( "relative", { 21777 top: 0, 21778 left: l 21779 } ).left; 21780 } 21781 if ( rs ) { 21782 ui.position.left = inst._convertPositionTo( "relative", { 21783 top: 0, 21784 left: r - inst.helperProportions.width 21785 } ).left; 21786 } 21787 } 21788 21789 if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { 21790 if ( inst.options.snap.snap ) { 21791 inst.options.snap.snap.call( 21792 inst.element, 21793 event, 21794 $.extend( inst._uiHash(), { 21795 snapItem: inst.snapElements[ i ].item 21796 } ) ); 21797 } 21798 } 21799 inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); 21800 21801 } 21802 21803 } 21804} ); 21805 21806$.ui.plugin.add( "draggable", "stack", { 21807 start: function( event, ui, instance ) { 21808 var min, 21809 o = instance.options, 21810 group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { 21811 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - 21812 ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); 21813 } ); 21814 21815 if ( !group.length ) { 21816 return; 21817 } 21818 21819 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; 21820 $( group ).each( function( i ) { 21821 $( this ).css( "zIndex", min + i ); 21822 } ); 21823 this.css( "zIndex", ( min + group.length ) ); 21824 } 21825} ); 21826 21827$.ui.plugin.add( "draggable", "zIndex", { 21828 start: function( event, ui, instance ) { 21829 var t = $( ui.helper ), 21830 o = instance.options; 21831 21832 if ( t.css( "zIndex" ) ) { 21833 o._zIndex = t.css( "zIndex" ); 21834 } 21835 t.css( "zIndex", o.zIndex ); 21836 }, 21837 stop: function( event, ui, instance ) { 21838 var o = instance.options; 21839 21840 if ( o._zIndex ) { 21841 $( ui.helper ).css( "zIndex", o._zIndex ); 21842 } 21843 } 21844} ); 21845 21846var widgetsDraggable = $.ui.draggable; 21847 21848 21849/*! 21850 * jQuery UI Resizable 1.13.2 21851 * http://jqueryui.com
vendor: 18,161 bytes, lines 21852-22564
21852 * 21853 * Copyright jQuery Foundation and other contributors 21854 * Released under the MIT license. 21855 * http://jquery.org/license 21856 */ 21857 21858//>>label: Resizable 21859//>>group: Interactions 21860//>>description: Enables resize functionality for any element. 21861//>>docs: http://api.jqueryui.com/resizable/ 21862//>>demos: http://jqueryui.com/resizable/ 21863//>>css.structure: ../../themes/base/core.css 21864//>>css.structure: ../../themes/base/resizable.css 21865//>>css.theme: ../../themes/base/theme.css 21866 21867 21868$.widget( "ui.resizable", $.ui.mouse, { 21869 version: "1.13.2", 21870 widgetEventPrefix: "resize", 21871 options: { 21872 alsoResize: false, 21873 animate: false, 21874 animateDuration: "slow", 21875 animateEasing: "swing", 21876 aspectRatio: false, 21877 autoHide: false, 21878 classes: { 21879 "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" 21880 }, 21881 containment: false, 21882 ghost: false, 21883 grid: false, 21884 handles: "e,s,se", 21885 helper: false, 21886 maxHeight: null, 21887 maxWidth: null, 21888 minHeight: 10, 21889 minWidth: 10, 21890 21891 // See #7960 21892 zIndex: 90, 21893 21894 // Callbacks 21895 resize: null, 21896 start: null, 21897 stop: null 21898 }, 21899 21900 _num: function( value ) { 21901 return parseFloat( value ) || 0; 21902 }, 21903 21904 _isNumber: function( value ) { 21905 return !isNaN( parseFloat( value ) ); 21906 }, 21907 21908 _hasScroll: function( el, a ) { 21909 21910 if ( $( el ).css( "overflow" ) === "hidden" ) { 21911 return false; 21912 } 21913 21914 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", 21915 has = false; 21916 21917 if ( el[ scroll ] > 0 ) { 21918 return true; 21919 } 21920 21921 // TODO: determine which cases actually cause this to happen 21922 // if the element doesn't have the scroll set, see if it's possible to 21923 // set the scroll 21924 try { 21925 el[ scroll ] = 1; 21926 has = ( el[ scroll ] > 0 ); 21927 el[ scroll ] = 0; 21928 } catch ( e ) { 21929 21930 // `el` might be a string, then setting `scroll` will throw 21931 // an error in strict mode; ignore it. 21932 } 21933 return has; 21934 }, 21935 21936 _create: function() { 21937 21938 var margins, 21939 o = this.options, 21940 that = this; 21941 this._addClass( "ui-resizable" ); 21942 21943 $.extend( this, { 21944 _aspectRatio: !!( o.aspectRatio ), 21945 aspectRatio: o.aspectRatio, 21946 originalElement: this.element, 21947 _proportionallyResizeElements: [], 21948 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null 21949 } ); 21950 21951 // Wrap the element if it cannot hold child nodes 21952 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { 21953 21954 this.element.wrap( 21955 $( "<div class='ui-wrapper'></div>" ).css( { 21956 overflow: "hidden", 21957 position: this.element.css( "position" ), 21958 width: this.element.outerWidth(), 21959 height: this.element.outerHeight(), 21960 top: this.element.css( "top" ), 21961 left: this.element.css( "left" ) 21962 } ) 21963 ); 21964 21965 this.element = this.element.parent().data( 21966 "ui-resizable", this.element.resizable( "instance" ) 21967 ); 21968 21969 this.elementIsWrapper = true; 21970 21971 margins = { 21972 marginTop: this.originalElement.css( "marginTop" ), 21973 marginRight: this.originalElement.css( "marginRight" ), 21974 marginBottom: this.originalElement.css( "marginBottom" ), 21975 marginLeft: this.originalElement.css( "marginLeft" ) 21976 }; 21977 21978 this.element.css( margins ); 21979 this.originalElement.css( "margin", 0 ); 21980 21981 // support: Safari 21982 // Prevent Safari textarea resize 21983 this.originalResizeStyle = this.originalElement.css( "resize" ); 21984 this.originalElement.css( "resize", "none" ); 21985 21986 this._proportionallyResizeElements.push( this.originalElement.css( { 21987 position: "static", 21988 zoom: 1, 21989 display: "block" 21990 } ) ); 21991 21992 // Support: IE9 21993 // avoid IE jump (hard set the margin) 21994 this.originalElement.css( margins ); 21995 21996 this._proportionallyResize(); 21997 } 21998 21999 this._setupHandles(); 22000 22001 if ( o.autoHide ) { 22002 $( this.element ) 22003 .on( "mouseenter", function() { 22004 if ( o.disabled ) { 22005 return; 22006 } 22007 that._removeClass( "ui-resizable-autohide" ); 22008 that._handles.show(); 22009 } ) 22010 .on( "mouseleave", function() { 22011 if ( o.disabled ) { 22012 return; 22013 } 22014 if ( !that.resizing ) { 22015 that._addClass( "ui-resizable-autohide" ); 22016 that._handles.hide(); 22017 } 22018 } ); 22019 } 22020 22021 this._mouseInit(); 22022 }, 22023 22024 _destroy: function() { 22025 22026 this._mouseDestroy(); 22027 this._addedHandles.remove(); 22028 22029 var wrapper, 22030 _destroy = function( exp ) { 22031 $( exp ) 22032 .removeData( "resizable" ) 22033 .removeData( "ui-resizable" ) 22034 .off( ".resizable" ); 22035 }; 22036 22037 // TODO: Unwrap at same DOM position 22038 if ( this.elementIsWrapper ) { 22039 _destroy( this.element ); 22040 wrapper = this.element; 22041 this.originalElement.css( { 22042 position: wrapper.css( "position" ), 22043 width: wrapper.outerWidth(), 22044 height: wrapper.outerHeight(), 22045 top: wrapper.css( "top" ), 22046 left: wrapper.css( "left" ) 22047 } ).insertAfter( wrapper ); 22048 wrapper.remove(); 22049 } 22050 22051 this.originalElement.css( "resize", this.originalResizeStyle ); 22052 _destroy( this.originalElement ); 22053 22054 return this; 22055 }, 22056 22057 _setOption: function( key, value ) { 22058 this._super( key, value ); 22059 22060 switch ( key ) { 22061 case "handles": 22062 this._removeHandles(); 22063 this._setupHandles(); 22064 break; 22065 case "aspectRatio": 22066 this._aspectRatio = !!value; 22067 break; 22068 default: 22069 break; 22070 } 22071 }, 22072 22073 _setupHandles: function() { 22074 var o = this.options, handle, i, n, hname, axis, that = this; 22075 this.handles = o.handles || 22076 ( !$( ".ui-resizable-handle", this.element ).length ? 22077 "e,s,se" : { 22078 n: ".ui-resizable-n", 22079 e: ".ui-resizable-e", 22080 s: ".ui-resizable-s", 22081 w: ".ui-resizable-w", 22082 se: ".ui-resizable-se", 22083 sw: ".ui-resizable-sw", 22084 ne: ".ui-resizable-ne", 22085 nw: ".ui-resizable-nw" 22086 } ); 22087 22088 this._handles = $(); 22089 this._addedHandles = $(); 22090 if ( this.handles.constructor === String ) { 22091 22092 if ( this.handles === "all" ) { 22093 this.handles = "n,e,s,w,se,sw,ne,nw"; 22094 } 22095 22096 n = this.handles.split( "," ); 22097 this.handles = {}; 22098 22099 for ( i = 0; i < n.length; i++ ) { 22100 22101 handle = String.prototype.trim.call( n[ i ] ); 22102 hname = "ui-resizable-" + handle; 22103 axis = $( "<div>" ); 22104 this._addClass( axis, "ui-resizable-handle " + hname ); 22105 22106 axis.css( { zIndex: o.zIndex } ); 22107 22108 this.handles[ handle ] = ".ui-resizable-" + handle; 22109 if ( !this.element.children( this.handles[ handle ] ).length ) { 22110 this.element.append( axis ); 22111 this._addedHandles = this._addedHandles.add( axis ); 22112 } 22113 } 22114 22115 } 22116 22117 this._renderAxis = function( target ) { 22118 22119 var i, axis, padPos, padWrapper; 22120 22121 target = target || this.element; 22122 22123 for ( i in this.handles ) { 22124 22125 if ( this.handles[ i ].constructor === String ) { 22126 this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); 22127 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { 22128 this.handles[ i ] = $( this.handles[ i ] ); 22129 this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); 22130 } 22131 22132 if ( this.elementIsWrapper && 22133 this.originalElement[ 0 ] 22134 .nodeName 22135 .match( /^(textarea|input|select|button)$/i ) ) { 22136 axis = $( this.handles[ i ], this.element ); 22137 22138 padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? 22139 axis.outerHeight() : 22140 axis.outerWidth(); 22141 22142 padPos = [ "padding", 22143 /ne|nw|n/.test( i ) ? "Top" : 22144 /se|sw|s/.test( i ) ? "Bottom" : 22145 /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); 22146 22147 target.css( padPos, padWrapper ); 22148 22149 this._proportionallyResize(); 22150 } 22151 22152 this._handles = this._handles.add( this.handles[ i ] ); 22153 } 22154 }; 22155 22156 // TODO: make renderAxis a prototype function 22157 this._renderAxis( this.element ); 22158 22159 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); 22160 this._handles.disableSelection(); 22161 22162 this._handles.on( "mouseover", function() { 22163 if ( !that.resizing ) { 22164 if ( this.className ) { 22165 axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); 22166 } 22167 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; 22168 } 22169 } ); 22170 22171 if ( o.autoHide ) { 22172 this._handles.hide(); 22173 this._addClass( "ui-resizable-autohide" ); 22174 } 22175 }, 22176 22177 _removeHandles: function() { 22178 this._addedHandles.remove(); 22179 }, 22180 22181 _mouseCapture: function( event ) { 22182 var i, handle, 22183 capture = false; 22184 22185 for ( i in this.handles ) { 22186 handle = $( this.handles[ i ] )[ 0 ]; 22187 if ( handle === event.target || $.contains( handle, event.target ) ) { 22188 capture = true; 22189 } 22190 } 22191 22192 return !this.options.disabled && capture; 22193 }, 22194 22195 _mouseStart: function( event ) { 22196 22197 var curleft, curtop, cursor, 22198 o = this.options, 22199 el = this.element; 22200 22201 this.resizing = true; 22202 22203 this._renderProxy(); 22204 22205 curleft = this._num( this.helper.css( "left" ) ); 22206 curtop = this._num( this.helper.css( "top" ) ); 22207 22208 if ( o.containment ) { 22209 curleft += $( o.containment ).scrollLeft() || 0; 22210 curtop += $( o.containment ).scrollTop() || 0; 22211 } 22212 22213 this.offset = this.helper.offset(); 22214 this.position = { left: curleft, top: curtop }; 22215 22216 this.size = this._helper ? { 22217 width: this.helper.width(), 22218 height: this.helper.height() 22219 } : { 22220 width: el.width(), 22221 height: el.height() 22222 }; 22223 22224 this.originalSize = this._helper ? { 22225 width: el.outerWidth(), 22226 height: el.outerHeight() 22227 } : { 22228 width: el.width(), 22229 height: el.height() 22230 }; 22231 22232 this.sizeDiff = { 22233 width: el.outerWidth() - el.width(), 22234 height: el.outerHeight() - el.height() 22235 }; 22236 22237 this.originalPosition = { left: curleft, top: curtop }; 22238 this.originalMousePosition = { left: event.pageX, top: event.pageY }; 22239 22240 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? 22241 o.aspectRatio : 22242 ( ( this.originalSize.width / this.originalSize.height ) || 1 ); 22243 22244 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); 22245 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); 22246 22247 this._addClass( "ui-resizable-resizing" ); 22248 this._propagate( "start", event ); 22249 return true; 22250 }, 22251 22252 _mouseDrag: function( event ) { 22253 22254 var data, props, 22255 smp = this.originalMousePosition, 22256 a = this.axis, 22257 dx = ( event.pageX - smp.left ) || 0, 22258 dy = ( event.pageY - smp.top ) || 0, 22259 trigger = this._change[ a ]; 22260 22261 this._updatePrevProperties(); 22262 22263 if ( !trigger ) { 22264 return false; 22265 } 22266 22267 data = trigger.apply( this, [ event, dx, dy ] ); 22268 22269 this._updateVirtualBoundaries( event.shiftKey ); 22270 if ( this._aspectRatio || event.shiftKey ) { 22271 data = this._updateRatio( data, event ); 22272 } 22273 22274 data = this._respectSize( data, event ); 22275 22276 this._updateCache( data ); 22277 22278 this._propagate( "resize", event ); 22279 22280 props = this._applyChanges(); 22281 22282 if ( !this._helper && this._proportionallyResizeElements.length ) { 22283 this._proportionallyResize(); 22284 } 22285 22286 if ( !$.isEmptyObject( props ) ) { 22287 this._updatePrevProperties(); 22288 this._trigger( "resize", event, this.ui() ); 22289 this._applyChanges(); 22290 } 22291 22292 return false; 22293 }, 22294 22295 _mouseStop: function( event ) { 22296 22297 this.resizing = false; 22298 var pr, ista, soffseth, soffsetw, s, left, top, 22299 o = this.options, that = this; 22300 22301 if ( this._helper ) { 22302 22303 pr = this._proportionallyResizeElements; 22304 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); 22305 soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; 22306 soffsetw = ista ? 0 : that.sizeDiff.width; 22307 22308 s = { 22309 width: ( that.helper.width() - soffsetw ), 22310 height: ( that.helper.height() - soffseth ) 22311 }; 22312 left = ( parseFloat( that.element.css( "left" ) ) + 22313 ( that.position.left - that.originalPosition.left ) ) || null; 22314 top = ( parseFloat( that.element.css( "top" ) ) + 22315 ( that.position.top - that.originalPosition.top ) ) || null; 22316 22317 if ( !o.animate ) { 22318 this.element.css( $.extend( s, { top: top, left: left } ) ); 22319 } 22320 22321 that.helper.height( that.size.height ); 22322 that.helper.width( that.size.width ); 22323 22324 if ( this._helper && !o.animate ) { 22325 this._proportionallyResize(); 22326 } 22327 } 22328 22329 $( "body" ).css( "cursor", "auto" ); 22330 22331 this._removeClass( "ui-resizable-resizing" ); 22332 22333 this._propagate( "stop", event ); 22334 22335 if ( this._helper ) { 22336 this.helper.remove(); 22337 } 22338 22339 return false; 22340 22341 }, 22342 22343 _updatePrevProperties: function() { 22344 this.prevPosition = { 22345 top: this.position.top, 22346 left: this.position.left 22347 }; 22348 this.prevSize = { 22349 width: this.size.width, 22350 height: this.size.height 22351 }; 22352 }, 22353 22354 _applyChanges: function() { 22355 var props = {}; 22356 22357 if ( this.position.top !== this.prevPosition.top ) { 22358 props.top = this.position.top + "px"; 22359 } 22360 if ( this.position.left !== this.prevPosition.left ) { 22361 props.left = this.position.left + "px"; 22362 } 22363 if ( this.size.width !== this.prevSize.width ) { 22364 props.width = this.size.width + "px"; 22365 } 22366 if ( this.size.height !== this.prevSize.height ) { 22367 props.height = this.size.height + "px"; 22368 } 22369 22370 this.helper.css( props ); 22371 22372 return props; 22373 }, 22374 22375 _updateVirtualBoundaries: function( forceAspectRatio ) { 22376 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, 22377 o = this.options; 22378 22379 b = { 22380 minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, 22381 maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, 22382 minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, 22383 maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity 22384 }; 22385 22386 if ( this._aspectRatio || forceAspectRatio ) { 22387 pMinWidth = b.minHeight * this.aspectRatio; 22388 pMinHeight = b.minWidth / this.aspectRatio; 22389 pMaxWidth = b.maxHeight * this.aspectRatio; 22390 pMaxHeight = b.maxWidth / this.aspectRatio; 22391 22392 if ( pMinWidth > b.minWidth ) { 22393 b.minWidth = pMinWidth; 22394 } 22395 if ( pMinHeight > b.minHeight ) { 22396 b.minHeight = pMinHeight; 22397 } 22398 if ( pMaxWidth < b.maxWidth ) { 22399 b.maxWidth = pMaxWidth; 22400 } 22401 if ( pMaxHeight < b.maxHeight ) { 22402 b.maxHeight = pMaxHeight; 22403 } 22404 } 22405 this._vBoundaries = b; 22406 }, 22407 22408 _updateCache: function( data ) { 22409 this.offset = this.helper.offset(); 22410 if ( this._isNumber( data.left ) ) { 22411 this.position.left = data.left; 22412 } 22413 if ( this._isNumber( data.top ) ) { 22414 this.position.top = data.top; 22415 } 22416 if ( this._isNumber( data.height ) ) { 22417 this.size.height = data.height; 22418 } 22419 if ( this._isNumber( data.width ) ) { 22420 this.size.width = data.width; 22421 } 22422 }, 22423 22424 _updateRatio: function( data ) { 22425 22426 var cpos = this.position, 22427 csize = this.size, 22428 a = this.axis; 22429 22430 if ( this._isNumber( data.height ) ) { 22431 data.width = ( data.height * this.aspectRatio ); 22432 } else if ( this._isNumber( data.width ) ) { 22433 data.height = ( data.width / this.aspectRatio ); 22434 } 22435 22436 if ( a === "sw" ) { 22437 data.left = cpos.left + ( csize.width - data.width ); 22438 data.top = null; 22439 } 22440 if ( a === "nw" ) { 22441 data.top = cpos.top + ( csize.height - data.height ); 22442 data.left = cpos.left + ( csize.width - data.width ); 22443 } 22444 22445 return data; 22446 }, 22447 22448 _respectSize: function( data ) { 22449 22450 var o = this._vBoundaries, 22451 a = this.axis, 22452 ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), 22453 ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), 22454 isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), 22455 isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), 22456 dw = this.originalPosition.left + this.originalSize.width, 22457 dh = this.originalPosition.top + this.originalSize.height, 22458 cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); 22459 if ( isminw ) { 22460 data.width = o.minWidth; 22461 } 22462 if ( isminh ) { 22463 data.height = o.minHeight; 22464 } 22465 if ( ismaxw ) { 22466 data.width = o.maxWidth; 22467 } 22468 if ( ismaxh ) { 22469 data.height = o.maxHeight; 22470 } 22471 22472 if ( isminw && cw ) { 22473 data.left = dw - o.minWidth; 22474 } 22475 if ( ismaxw && cw ) { 22476 data.left = dw - o.maxWidth; 22477 } 22478 if ( isminh && ch ) { 22479 data.top = dh - o.minHeight; 22480 } 22481 if ( ismaxh && ch ) { 22482 data.top = dh - o.maxHeight; 22483 } 22484 22485 // Fixing jump error on top/left - bug #2330 22486 if ( !data.width && !data.height && !data.left && data.top ) { 22487 data.top = null; 22488 } else if ( !data.width && !data.height && !data.top && data.left ) { 22489 data.left = null; 22490 } 22491 22492 return data; 22493 }, 22494 22495 _getPaddingPlusBorderDimensions: function( element ) { 22496 var i = 0, 22497 widths = [], 22498 borders = [ 22499 element.css( "borderTopWidth" ), 22500 element.css( "borderRightWidth" ), 22501 element.css( "borderBottomWidth" ), 22502 element.css( "borderLeftWidth" ) 22503 ], 22504 paddings = [ 22505 element.css( "paddingTop" ), 22506 element.css( "paddingRight" ), 22507 element.css( "paddingBottom" ), 22508 element.css( "paddingLeft" ) 22509 ]; 22510 22511 for ( ; i < 4; i++ ) { 22512 widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); 22513 widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); 22514 } 22515 22516 return { 22517 height: widths[ 0 ] + widths[ 2 ], 22518 width: widths[ 1 ] + widths[ 3 ] 22519 }; 22520 }, 22521 22522 _proportionallyResize: function() { 22523 22524 if ( !this._proportionallyResizeElements.length ) { 22525 return; 22526 } 22527 22528 var prel, 22529 i = 0, 22530 element = this.helper || this.element; 22531 22532 for ( ; i < this._proportionallyResizeElements.length; i++ ) { 22533 22534 prel = this._proportionallyResizeElements[ i ]; 22535 22536 // TODO: Seems like a bug to cache this.outerDimensions 22537 // considering that we are in a loop. 22538 if ( !this.outerDimensions ) { 22539 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); 22540 } 22541 22542 prel.css( { 22543 height: ( element.height() - this.outerDimensions.height ) || 0, 22544 width: ( element.width() - this.outerDimensions.width ) || 0 22545 } ); 22546 22547 } 22548 22549 }, 22550 22551 _renderProxy: function() { 22552 22553 var el = this.element, o = this.options; 22554 this.elementOffset = el.offset(); 22555 22556 if ( this._helper ) { 22557 22558 this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); 22559 22560 this._addClass( this.helper, this._helper ); 22561 this.helper.css( { 22562 width: this.element.outerWidth(), 22563 height: this.element.outerHeight(), 22564 position: "absolute",
vendor: 6,636 bytes, lines 22565-22805
22565 left: this.elementOffset.left + "px", 22566 top: this.elementOffset.top + "px", 22567 zIndex: ++o.zIndex //TODO: Don't modify option 22568 } ); 22569 22570 this.helper 22571 .appendTo( "body" ) 22572 .disableSelection(); 22573 22574 } else { 22575 this.helper = this.element; 22576 } 22577 22578 }, 22579 22580 _change: { 22581 e: function( event, dx ) { 22582 return { width: this.originalSize.width + dx }; 22583 }, 22584 w: function( event, dx ) { 22585 var cs = this.originalSize, sp = this.originalPosition; 22586 return { left: sp.left + dx, width: cs.width - dx }; 22587 }, 22588 n: function( event, dx, dy ) { 22589 var cs = this.originalSize, sp = this.originalPosition; 22590 return { top: sp.top + dy, height: cs.height - dy }; 22591 }, 22592 s: function( event, dx, dy ) { 22593 return { height: this.originalSize.height + dy }; 22594 }, 22595 se: function( event, dx, dy ) { 22596 return $.extend( this._change.s.apply( this, arguments ), 22597 this._change.e.apply( this, [ event, dx, dy ] ) ); 22598 }, 22599 sw: function( event, dx, dy ) { 22600 return $.extend( this._change.s.apply( this, arguments ), 22601 this._change.w.apply( this, [ event, dx, dy ] ) ); 22602 }, 22603 ne: function( event, dx, dy ) { 22604 return $.extend( this._change.n.apply( this, arguments ), 22605 this._change.e.apply( this, [ event, dx, dy ] ) ); 22606 }, 22607 nw: function( event, dx, dy ) { 22608 return $.extend( this._change.n.apply( this, arguments ), 22609 this._change.w.apply( this, [ event, dx, dy ] ) ); 22610 } 22611 }, 22612 22613 _propagate: function( n, event ) { 22614 $.ui.plugin.call( this, n, [ event, this.ui() ] ); 22615 if ( n !== "resize" ) { 22616 this._trigger( n, event, this.ui() ); 22617 } 22618 }, 22619 22620 plugins: {}, 22621 22622 ui: function() { 22623 return { 22624 originalElement: this.originalElement, 22625 element: this.element, 22626 helper: this.helper, 22627 position: this.position, 22628 size: this.size, 22629 originalSize: this.originalSize, 22630 originalPosition: this.originalPosition 22631 }; 22632 } 22633 22634} ); 22635 22636/* 22637 * Resizable Extensions 22638 */ 22639 22640$.ui.plugin.add( "resizable", "animate", { 22641 22642 stop: function( event ) { 22643 var that = $( this ).resizable( "instance" ), 22644 o = that.options, 22645 pr = that._proportionallyResizeElements, 22646 ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), 22647 soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, 22648 soffsetw = ista ? 0 : that.sizeDiff.width, 22649 style = { 22650 width: ( that.size.width - soffsetw ), 22651 height: ( that.size.height - soffseth ) 22652 }, 22653 left = ( parseFloat( that.element.css( "left" ) ) + 22654 ( that.position.left - that.originalPosition.left ) ) || null, 22655 top = ( parseFloat( that.element.css( "top" ) ) + 22656 ( that.position.top - that.originalPosition.top ) ) || null; 22657 22658 that.element.animate( 22659 $.extend( style, top && left ? { top: top, left: left } : {} ), { 22660 duration: o.animateDuration, 22661 easing: o.animateEasing, 22662 step: function() { 22663 22664 var data = { 22665 width: parseFloat( that.element.css( "width" ) ), 22666 height: parseFloat( that.element.css( "height" ) ), 22667 top: parseFloat( that.element.css( "top" ) ), 22668 left: parseFloat( that.element.css( "left" ) ) 22669 }; 22670 22671 if ( pr && pr.length ) { 22672 $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); 22673 } 22674 22675 // Propagating resize, and updating values for each animation step 22676 that._updateCache( data ); 22677 that._propagate( "resize", event ); 22678 22679 } 22680 } 22681 ); 22682 } 22683 22684} ); 22685 22686$.ui.plugin.add( "resizable", "containment", { 22687 22688 start: function() { 22689 var element, p, co, ch, cw, width, height, 22690 that = $( this ).resizable( "instance" ), 22691 o = that.options, 22692 el = that.element, 22693 oc = o.containment, 22694 ce = ( oc instanceof $ ) ? 22695 oc.get( 0 ) : 22696 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; 22697 22698 if ( !ce ) { 22699 return; 22700 } 22701 22702 that.containerElement = $( ce ); 22703 22704 if ( /document/.test( oc ) || oc === document ) { 22705 that.containerOffset = { 22706 left: 0, 22707 top: 0 22708 }; 22709 that.containerPosition = { 22710 left: 0, 22711 top: 0 22712 }; 22713 22714 that.parentData = { 22715 element: $( document ), 22716 left: 0, 22717 top: 0, 22718 width: $( document ).width(), 22719 height: $( document ).height() || document.body.parentNode.scrollHeight 22720 }; 22721 } else { 22722 element = $( ce ); 22723 p = []; 22724 $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { 22725 p[ i ] = that._num( element.css( "padding" + name ) ); 22726 } ); 22727 22728 that.containerOffset = element.offset(); 22729 that.containerPosition = element.position(); 22730 that.containerSize = { 22731 height: ( element.innerHeight() - p[ 3 ] ), 22732 width: ( element.innerWidth() - p[ 1 ] ) 22733 }; 22734 22735 co = that.containerOffset; 22736 ch = that.containerSize.height; 22737 cw = that.containerSize.width; 22738 width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); 22739 height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); 22740 22741 that.parentData = { 22742 element: ce, 22743 left: co.left, 22744 top: co.top, 22745 width: width, 22746 height: height 22747 }; 22748 } 22749 }, 22750 22751 resize: function( event ) { 22752 var woset, hoset, isParent, isOffsetRelative, 22753 that = $( this ).resizable( "instance" ), 22754 o = that.options, 22755 co = that.containerOffset, 22756 cp = that.position, 22757 pRatio = that._aspectRatio || event.shiftKey, 22758 cop = { 22759 top: 0, 22760 left: 0 22761 }, 22762 ce = that.containerElement, 22763 continueResize = true; 22764 22765 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { 22766 cop = co; 22767 } 22768 22769 if ( cp.left < ( that._helper ? co.left : 0 ) ) { 22770 that.size.width = that.size.width + 22771 ( that._helper ? 22772 ( that.position.left - co.left ) : 22773 ( that.position.left - cop.left ) ); 22774 22775 if ( pRatio ) { 22776 that.size.height = that.size.width / that.aspectRatio; 22777 continueResize = false; 22778 } 22779 that.position.left = o.helper ? co.left : 0; 22780 } 22781 22782 if ( cp.top < ( that._helper ? co.top : 0 ) ) { 22783 that.size.height = that.size.height + 22784 ( that._helper ? 22785 ( that.position.top - co.top ) : 22786 that.position.top ); 22787 22788 if ( pRatio ) { 22789 that.size.width = that.size.height * that.aspectRatio; 22790 continueResize = false; 22791 } 22792 that.position.top = that._helper ? co.top : 0; 22793 } 22794 22795 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); 22796 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); 22797 22798 if ( isParent && isOffsetRelative ) { 22799 that.offset.left = that.parentData.left + that.position.left; 22800 that.offset.top = that.parentData.top + that.position.top; 22801 } else { 22802 that.offset.left = that.element.offset().left; 22803 that.offset.top = that.element.offset().top; 22804 } 22805
vendor: 34,793 bytes, lines 22806-24153
22806 woset = Math.abs( that.sizeDiff.width + 22807 ( that._helper ? 22808 that.offset.left - cop.left : 22809 ( that.offset.left - co.left ) ) ); 22810 22811 hoset = Math.abs( that.sizeDiff.height + 22812 ( that._helper ? 22813 that.offset.top - cop.top : 22814 ( that.offset.top - co.top ) ) ); 22815 22816 if ( woset + that.size.width >= that.parentData.width ) { 22817 that.size.width = that.parentData.width - woset; 22818 if ( pRatio ) { 22819 that.size.height = that.size.width / that.aspectRatio; 22820 continueResize = false; 22821 } 22822 } 22823 22824 if ( hoset + that.size.height >= that.parentData.height ) { 22825 that.size.height = that.parentData.height - hoset; 22826 if ( pRatio ) { 22827 that.size.width = that.size.height * that.aspectRatio; 22828 continueResize = false; 22829 } 22830 } 22831 22832 if ( !continueResize ) { 22833 that.position.left = that.prevPosition.left; 22834 that.position.top = that.prevPosition.top; 22835 that.size.width = that.prevSize.width; 22836 that.size.height = that.prevSize.height; 22837 } 22838 }, 22839 22840 stop: function() { 22841 var that = $( this ).resizable( "instance" ), 22842 o = that.options, 22843 co = that.containerOffset, 22844 cop = that.containerPosition, 22845 ce = that.containerElement, 22846 helper = $( that.helper ), 22847 ho = helper.offset(), 22848 w = helper.outerWidth() - that.sizeDiff.width, 22849 h = helper.outerHeight() - that.sizeDiff.height; 22850 22851 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { 22852 $( this ).css( { 22853 left: ho.left - cop.left - co.left, 22854 width: w, 22855 height: h 22856 } ); 22857 } 22858 22859 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { 22860 $( this ).css( { 22861 left: ho.left - cop.left - co.left, 22862 width: w, 22863 height: h 22864 } ); 22865 } 22866 } 22867} ); 22868 22869$.ui.plugin.add( "resizable", "alsoResize", { 22870 22871 start: function() { 22872 var that = $( this ).resizable( "instance" ), 22873 o = that.options; 22874 22875 $( o.alsoResize ).each( function() { 22876 var el = $( this ); 22877 el.data( "ui-resizable-alsoresize", { 22878 width: parseFloat( el.width() ), height: parseFloat( el.height() ), 22879 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) 22880 } ); 22881 } ); 22882 }, 22883 22884 resize: function( event, ui ) { 22885 var that = $( this ).resizable( "instance" ), 22886 o = that.options, 22887 os = that.originalSize, 22888 op = that.originalPosition, 22889 delta = { 22890 height: ( that.size.height - os.height ) || 0, 22891 width: ( that.size.width - os.width ) || 0, 22892 top: ( that.position.top - op.top ) || 0, 22893 left: ( that.position.left - op.left ) || 0 22894 }; 22895 22896 $( o.alsoResize ).each( function() { 22897 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, 22898 css = el.parents( ui.originalElement[ 0 ] ).length ? 22899 [ "width", "height" ] : 22900 [ "width", "height", "top", "left" ]; 22901 22902 $.each( css, function( i, prop ) { 22903 var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); 22904 if ( sum && sum >= 0 ) { 22905 style[ prop ] = sum || null; 22906 } 22907 } ); 22908 22909 el.css( style ); 22910 } ); 22911 }, 22912 22913 stop: function() { 22914 $( this ).removeData( "ui-resizable-alsoresize" ); 22915 } 22916} ); 22917 22918$.ui.plugin.add( "resizable", "ghost", { 22919 22920 start: function() { 22921 22922 var that = $( this ).resizable( "instance" ), cs = that.size; 22923 22924 that.ghost = that.originalElement.clone(); 22925 that.ghost.css( { 22926 opacity: 0.25, 22927 display: "block", 22928 position: "relative", 22929 height: cs.height, 22930 width: cs.width, 22931 margin: 0, 22932 left: 0, 22933 top: 0 22934 } ); 22935 22936 that._addClass( that.ghost, "ui-resizable-ghost" ); 22937 22938 // DEPRECATED 22939 // TODO: remove after 1.12 22940 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { 22941 22942 // Ghost option 22943 that.ghost.addClass( this.options.ghost ); 22944 } 22945 22946 that.ghost.appendTo( that.helper ); 22947 22948 }, 22949 22950 resize: function() { 22951 var that = $( this ).resizable( "instance" ); 22952 if ( that.ghost ) { 22953 that.ghost.css( { 22954 position: "relative", 22955 height: that.size.height, 22956 width: that.size.width 22957 } ); 22958 } 22959 }, 22960 22961 stop: function() { 22962 var that = $( this ).resizable( "instance" ); 22963 if ( that.ghost && that.helper ) { 22964 that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); 22965 } 22966 } 22967 22968} ); 22969 22970$.ui.plugin.add( "resizable", "grid", { 22971 22972 resize: function() { 22973 var outerDimensions, 22974 that = $( this ).resizable( "instance" ), 22975 o = that.options, 22976 cs = that.size, 22977 os = that.originalSize, 22978 op = that.originalPosition, 22979 a = that.axis, 22980 grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, 22981 gridX = ( grid[ 0 ] || 1 ), 22982 gridY = ( grid[ 1 ] || 1 ), 22983 ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, 22984 oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, 22985 newWidth = os.width + ox, 22986 newHeight = os.height + oy, 22987 isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), 22988 isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), 22989 isMinWidth = o.minWidth && ( o.minWidth > newWidth ), 22990 isMinHeight = o.minHeight && ( o.minHeight > newHeight ); 22991 22992 o.grid = grid; 22993 22994 if ( isMinWidth ) { 22995 newWidth += gridX; 22996 } 22997 if ( isMinHeight ) { 22998 newHeight += gridY; 22999 } 23000 if ( isMaxWidth ) { 23001 newWidth -= gridX; 23002 } 23003 if ( isMaxHeight ) { 23004 newHeight -= gridY; 23005 } 23006 23007 if ( /^(se|s|e)$/.test( a ) ) { 23008 that.size.width = newWidth; 23009 that.size.height = newHeight; 23010 } else if ( /^(ne)$/.test( a ) ) { 23011 that.size.width = newWidth; 23012 that.size.height = newHeight; 23013 that.position.top = op.top - oy; 23014 } else if ( /^(sw)$/.test( a ) ) { 23015 that.size.width = newWidth; 23016 that.size.height = newHeight; 23017 that.position.left = op.left - ox; 23018 } else { 23019 if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { 23020 outerDimensions = that._getPaddingPlusBorderDimensions( this ); 23021 } 23022 23023 if ( newHeight - gridY > 0 ) { 23024 that.size.height = newHeight; 23025 that.position.top = op.top - oy; 23026 } else { 23027 newHeight = gridY - outerDimensions.height; 23028 that.size.height = newHeight; 23029 that.position.top = op.top + os.height - newHeight; 23030 } 23031 if ( newWidth - gridX > 0 ) { 23032 that.size.width = newWidth; 23033 that.position.left = op.left - ox; 23034 } else { 23035 newWidth = gridX - outerDimensions.width; 23036 that.size.width = newWidth; 23037 that.position.left = op.left + os.width - newWidth; 23038 } 23039 } 23040 } 23041 23042} ); 23043 23044var widgetsResizable = $.ui.resizable; 23045 23046 23047/*! 23048 * jQuery UI Dialog 1.13.2 23049 * http://jqueryui.com 23050 * 23051 * Copyright jQuery Foundation and other contributors 23052 * Released under the MIT license. 23053 * http://jquery.org/license 23054 */ 23055 23056//>>label: Dialog 23057//>>group: Widgets 23058//>>description: Displays customizable dialog windows. 23059//>>docs: http://api.jqueryui.com/dialog/ 23060//>>demos: http://jqueryui.com/dialog/ 23061//>>css.structure: ../../themes/base/core.css 23062//>>css.structure: ../../themes/base/dialog.css 23063//>>css.theme: ../../themes/base/theme.css 23064 23065 23066$.widget( "ui.dialog", { 23067 version: "1.13.2", 23068 options: { 23069 appendTo: "body", 23070 autoOpen: true, 23071 buttons: [], 23072 classes: { 23073 "ui-dialog": "ui-corner-all", 23074 "ui-dialog-titlebar": "ui-corner-all" 23075 }, 23076 closeOnEscape: true, 23077 closeText: "Close", 23078 draggable: true, 23079 hide: null, 23080 height: "auto", 23081 maxHeight: null, 23082 maxWidth: null, 23083 minHeight: 150, 23084 minWidth: 150, 23085 modal: false, 23086 position: { 23087 my: "center", 23088 at: "center", 23089 of: window, 23090 collision: "fit", 23091 23092 // Ensure the titlebar is always visible 23093 using: function( pos ) { 23094 var topOffset = $( this ).css( pos ).offset().top; 23095 if ( topOffset < 0 ) { 23096 $( this ).css( "top", pos.top - topOffset ); 23097 } 23098 } 23099 }, 23100 resizable: true, 23101 show: null, 23102 title: null, 23103 width: 300, 23104 23105 // Callbacks 23106 beforeClose: null, 23107 close: null, 23108 drag: null, 23109 dragStart: null, 23110 dragStop: null, 23111 focus: null, 23112 open: null, 23113 resize: null, 23114 resizeStart: null, 23115 resizeStop: null 23116 }, 23117 23118 sizeRelatedOptions: { 23119 buttons: true, 23120 height: true, 23121 maxHeight: true, 23122 maxWidth: true, 23123 minHeight: true, 23124 minWidth: true, 23125 width: true 23126 }, 23127 23128 resizableRelatedOptions: { 23129 maxHeight: true, 23130 maxWidth: true, 23131 minHeight: true, 23132 minWidth: true 23133 }, 23134 23135 _create: function() { 23136 this.originalCss = { 23137 display: this.element[ 0 ].style.display, 23138 width: this.element[ 0 ].style.width, 23139 minHeight: this.element[ 0 ].style.minHeight, 23140 maxHeight: this.element[ 0 ].style.maxHeight, 23141 height: this.element[ 0 ].style.height 23142 }; 23143 this.originalPosition = { 23144 parent: this.element.parent(), 23145 index: this.element.parent().children().index( this.element ) 23146 }; 23147 this.originalTitle = this.element.attr( "title" ); 23148 if ( this.options.title == null && this.originalTitle != null ) { 23149 this.options.title = this.originalTitle; 23150 } 23151 23152 // Dialogs can't be disabled 23153 if ( this.options.disabled ) { 23154 this.options.disabled = false; 23155 } 23156 23157 this._createWrapper(); 23158 23159 this.element 23160 .show() 23161 .removeAttr( "title" ) 23162 .appendTo( this.uiDialog ); 23163 23164 this._addClass( "ui-dialog-content", "ui-widget-content" ); 23165 23166 this._createTitlebar(); 23167 this._createButtonPane(); 23168 23169 if ( this.options.draggable && $.fn.draggable ) { 23170 this._makeDraggable(); 23171 } 23172 if ( this.options.resizable && $.fn.resizable ) { 23173 this._makeResizable(); 23174 } 23175 23176 this._isOpen = false; 23177 23178 this._trackFocus(); 23179 }, 23180 23181 _init: function() { 23182 if ( this.options.autoOpen ) { 23183 this.open(); 23184 } 23185 }, 23186 23187 _appendTo: function() { 23188 var element = this.options.appendTo; 23189 if ( element && ( element.jquery || element.nodeType ) ) { 23190 return $( element ); 23191 } 23192 return this.document.find( element || "body" ).eq( 0 ); 23193 }, 23194 23195 _destroy: function() { 23196 var next, 23197 originalPosition = this.originalPosition; 23198 23199 this._untrackInstance(); 23200 this._destroyOverlay(); 23201 23202 this.element 23203 .removeUniqueId() 23204 .css( this.originalCss ) 23205 23206 // Without detaching first, the following becomes really slow 23207 .detach(); 23208 23209 this.uiDialog.remove(); 23210 23211 if ( this.originalTitle ) { 23212 this.element.attr( "title", this.originalTitle ); 23213 } 23214 23215 next = originalPosition.parent.children().eq( originalPosition.index ); 23216 23217 // Don't try to place the dialog next to itself (#8613) 23218 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { 23219 next.before( this.element ); 23220 } else { 23221 originalPosition.parent.append( this.element ); 23222 } 23223 }, 23224 23225 widget: function() { 23226 return this.uiDialog; 23227 }, 23228 23229 disable: $.noop, 23230 enable: $.noop, 23231 23232 close: function( event ) { 23233 var that = this; 23234 23235 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { 23236 return; 23237 } 23238 23239 this._isOpen = false; 23240 this._focusedElement = null; 23241 this._destroyOverlay(); 23242 this._untrackInstance(); 23243 23244 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { 23245 23246 // Hiding a focused element doesn't trigger blur in WebKit 23247 // so in case we have nothing to focus on, explicitly blur the active element 23248 // https://bugs.webkit.org/show_bug.cgi?id=47182 23249 $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); 23250 } 23251 23252 this._hide( this.uiDialog, this.options.hide, function() { 23253 that._trigger( "close", event ); 23254 } ); 23255 }, 23256 23257 isOpen: function() { 23258 return this._isOpen; 23259 }, 23260 23261 moveToTop: function() { 23262 this._moveToTop(); 23263 }, 23264 23265 _moveToTop: function( event, silent ) { 23266 var moved = false, 23267 zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { 23268 return +$( this ).css( "z-index" ); 23269 } ).get(), 23270 zIndexMax = Math.max.apply( null, zIndices ); 23271 23272 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { 23273 this.uiDialog.css( "z-index", zIndexMax + 1 ); 23274 moved = true; 23275 } 23276 23277 if ( moved && !silent ) { 23278 this._trigger( "focus", event ); 23279 } 23280 return moved; 23281 }, 23282 23283 open: function() { 23284 var that = this; 23285 if ( this._isOpen ) { 23286 if ( this._moveToTop() ) { 23287 this._focusTabbable(); 23288 } 23289 return; 23290 } 23291 23292 this._isOpen = true; 23293 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); 23294 23295 this._size(); 23296 this._position(); 23297 this._createOverlay(); 23298 this._moveToTop( null, true ); 23299 23300 // Ensure the overlay is moved to the top with the dialog, but only when 23301 // opening. The overlay shouldn't move after the dialog is open so that 23302 // modeless dialogs opened after the modal dialog stack properly. 23303 if ( this.overlay ) { 23304 this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); 23305 } 23306 23307 this._show( this.uiDialog, this.options.show, function() { 23308 that._focusTabbable(); 23309 that._trigger( "focus" ); 23310 } ); 23311 23312 // Track the dialog immediately upon opening in case a focus event 23313 // somehow occurs outside of the dialog before an element inside the 23314 // dialog is focused (#10152) 23315 this._makeFocusTarget(); 23316 23317 this._trigger( "open" ); 23318 }, 23319 23320 _focusTabbable: function() { 23321 23322 // Set focus to the first match: 23323 // 1. An element that was focused previously 23324 // 2. First element inside the dialog matching [autofocus] 23325 // 3. Tabbable element inside the content element 23326 // 4. Tabbable element inside the buttonpane 23327 // 5. The close button 23328 // 6. The dialog itself 23329 var hasFocus = this._focusedElement; 23330 if ( !hasFocus ) { 23331 hasFocus = this.element.find( "[autofocus]" ); 23332 } 23333 if ( !hasFocus.length ) { 23334 hasFocus = this.element.find( ":tabbable" ); 23335 } 23336 if ( !hasFocus.length ) { 23337 hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); 23338 } 23339 if ( !hasFocus.length ) { 23340 hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); 23341 } 23342 if ( !hasFocus.length ) { 23343 hasFocus = this.uiDialog; 23344 } 23345 hasFocus.eq( 0 ).trigger( "focus" ); 23346 }, 23347 23348 _restoreTabbableFocus: function() { 23349 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), 23350 isActive = this.uiDialog[ 0 ] === activeElement || 23351 $.contains( this.uiDialog[ 0 ], activeElement ); 23352 if ( !isActive ) { 23353 this._focusTabbable(); 23354 } 23355 }, 23356 23357 _keepFocus: function( event ) { 23358 event.preventDefault(); 23359 this._restoreTabbableFocus(); 23360 23361 // support: IE 23362 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() 23363 // so we check again later 23364 this._delay( this._restoreTabbableFocus ); 23365 }, 23366 23367 _createWrapper: function() { 23368 this.uiDialog = $( "<div>" ) 23369 .hide() 23370 .attr( { 23371 23372 // Setting tabIndex makes the div focusable 23373 tabIndex: -1, 23374 role: "dialog" 23375 } ) 23376 .appendTo( this._appendTo() ); 23377 23378 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); 23379 this._on( this.uiDialog, { 23380 keydown: function( event ) { 23381 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && 23382 event.keyCode === $.ui.keyCode.ESCAPE ) { 23383 event.preventDefault(); 23384 this.close( event ); 23385 return; 23386 } 23387 23388 // Prevent tabbing out of dialogs 23389 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { 23390 return; 23391 } 23392 var tabbables = this.uiDialog.find( ":tabbable" ), 23393 first = tabbables.first(), 23394 last = tabbables.last(); 23395 23396 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && 23397 !event.shiftKey ) { 23398 this._delay( function() { 23399 first.trigger( "focus" ); 23400 } ); 23401 event.preventDefault(); 23402 } else if ( ( event.target === first[ 0 ] || 23403 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { 23404 this._delay( function() { 23405 last.trigger( "focus" ); 23406 } ); 23407 event.preventDefault(); 23408 } 23409 }, 23410 mousedown: function( event ) { 23411 if ( this._moveToTop( event ) ) { 23412 this._focusTabbable(); 23413 } 23414 } 23415 } ); 23416 23417 // We assume that any existing aria-describedby attribute means 23418 // that the dialog content is marked up properly 23419 // otherwise we brute force the content as the description 23420 if ( !this.element.find( "[aria-describedby]" ).length ) { 23421 this.uiDialog.attr( { 23422 "aria-describedby": this.element.uniqueId().attr( "id" ) 23423 } ); 23424 } 23425 }, 23426 23427 _createTitlebar: function() { 23428 var uiDialogTitle; 23429 23430 this.uiDialogTitlebar = $( "<div>" ); 23431 this._addClass( this.uiDialogTitlebar, 23432 "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); 23433 this._on( this.uiDialogTitlebar, { 23434 mousedown: function( event ) { 23435 23436 // Don't prevent click on close button (#8838) 23437 // Focusing a dialog that is partially scrolled out of view 23438 // causes the browser to scroll it into view, preventing the click event 23439 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { 23440 23441 // Dialog isn't getting focus when dragging (#8063) 23442 this.uiDialog.trigger( "focus" ); 23443 } 23444 } 23445 } ); 23446 23447 // Support: IE 23448 // Use type="button" to prevent enter keypresses in textboxes from closing the 23449 // dialog in IE (#9312) 23450 this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) 23451 .button( { 23452 label: $( "<a>" ).text( this.options.closeText ).html(), 23453 icon: "ui-icon-closethick", 23454 showLabel: false 23455 } ) 23456 .appendTo( this.uiDialogTitlebar ); 23457 23458 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); 23459 this._on( this.uiDialogTitlebarClose, { 23460 click: function( event ) { 23461 event.preventDefault(); 23462 this.close( event ); 23463 } 23464 } ); 23465 23466 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); 23467 this._addClass( uiDialogTitle, "ui-dialog-title" ); 23468 this._title( uiDialogTitle ); 23469 23470 this.uiDialogTitlebar.prependTo( this.uiDialog ); 23471 23472 this.uiDialog.attr( { 23473 "aria-labelledby": uiDialogTitle.attr( "id" ) 23474 } ); 23475 }, 23476 23477 _title: function( title ) { 23478 if ( this.options.title ) { 23479 title.text( this.options.title ); 23480 } else { 23481 title.html( " " ); 23482 } 23483 }, 23484 23485 _createButtonPane: function() { 23486 this.uiDialogButtonPane = $( "<div>" ); 23487 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", 23488 "ui-widget-content ui-helper-clearfix" ); 23489 23490 this.uiButtonSet = $( "<div>" ) 23491 .appendTo( this.uiDialogButtonPane ); 23492 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); 23493 23494 this._createButtons(); 23495 }, 23496 23497 _createButtons: function() { 23498 var that = this, 23499 buttons = this.options.buttons; 23500 23501 // If we already have a button pane, remove it 23502 this.uiDialogButtonPane.remove(); 23503 this.uiButtonSet.empty(); 23504 23505 if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { 23506 this._removeClass( this.uiDialog, "ui-dialog-buttons" ); 23507 return; 23508 } 23509 23510 $.each( buttons, function( name, props ) { 23511 var click, buttonOptions; 23512 props = typeof props === "function" ? 23513 { click: props, text: name } : 23514 props; 23515 23516 // Default to a non-submitting button 23517 props = $.extend( { type: "button" }, props ); 23518 23519 // Change the context for the click callback to be the main element 23520 click = props.click; 23521 buttonOptions = { 23522 icon: props.icon, 23523 iconPosition: props.iconPosition, 23524 showLabel: props.showLabel, 23525 23526 // Deprecated options 23527 icons: props.icons, 23528 text: props.text 23529 }; 23530 23531 delete props.click; 23532 delete props.icon; 23533 delete props.iconPosition; 23534 delete props.showLabel; 23535 23536 // Deprecated options 23537 delete props.icons; 23538 if ( typeof props.text === "boolean" ) { 23539 delete props.text; 23540 } 23541 23542 $( "<button></button>", props ) 23543 .button( buttonOptions ) 23544 .appendTo( that.uiButtonSet ) 23545 .on( "click", function() { 23546 click.apply( that.element[ 0 ], arguments ); 23547 } ); 23548 } ); 23549 this._addClass( this.uiDialog, "ui-dialog-buttons" ); 23550 this.uiDialogButtonPane.appendTo( this.uiDialog ); 23551 }, 23552 23553 _makeDraggable: function() { 23554 var that = this, 23555 options = this.options; 23556 23557 function filteredUi( ui ) { 23558 return { 23559 position: ui.position, 23560 offset: ui.offset 23561 }; 23562 } 23563 23564 this.uiDialog.draggable( { 23565 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", 23566 handle: ".ui-dialog-titlebar", 23567 containment: "document", 23568 start: function( event, ui ) { 23569 that._addClass( $( this ), "ui-dialog-dragging" ); 23570 that._blockFrames(); 23571 that._trigger( "dragStart", event, filteredUi( ui ) ); 23572 }, 23573 drag: function( event, ui ) { 23574 that._trigger( "drag", event, filteredUi( ui ) ); 23575 }, 23576 stop: function( event, ui ) { 23577 var left = ui.offset.left - that.document.scrollLeft(), 23578 top = ui.offset.top - that.document.scrollTop(); 23579 23580 options.position = { 23581 my: "left top", 23582 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 23583 "top" + ( top >= 0 ? "+" : "" ) + top, 23584 of: that.window 23585 }; 23586 that._removeClass( $( this ), "ui-dialog-dragging" ); 23587 that._unblockFrames(); 23588 that._trigger( "dragStop", event, filteredUi( ui ) ); 23589 } 23590 } ); 23591 }, 23592 23593 _makeResizable: function() { 23594 var that = this, 23595 options = this.options, 23596 handles = options.resizable, 23597 23598 // .ui-resizable has position: relative defined in the stylesheet 23599 // but dialogs have to use absolute or fixed positioning 23600 position = this.uiDialog.css( "position" ), 23601 resizeHandles = typeof handles === "string" ? 23602 handles : 23603 "n,e,s,w,se,sw,ne,nw"; 23604 23605 function filteredUi( ui ) { 23606 return { 23607 originalPosition: ui.originalPosition, 23608 originalSize: ui.originalSize, 23609 position: ui.position, 23610 size: ui.size 23611 }; 23612 } 23613 23614 this.uiDialog.resizable( { 23615 cancel: ".ui-dialog-content", 23616 containment: "document", 23617 alsoResize: this.element, 23618 maxWidth: options.maxWidth, 23619 maxHeight: options.maxHeight, 23620 minWidth: options.minWidth, 23621 minHeight: this._minHeight(), 23622 handles: resizeHandles, 23623 start: function( event, ui ) { 23624 that._addClass( $( this ), "ui-dialog-resizing" ); 23625 that._blockFrames(); 23626 that._trigger( "resizeStart", event, filteredUi( ui ) ); 23627 }, 23628 resize: function( event, ui ) { 23629 that._trigger( "resize", event, filteredUi( ui ) ); 23630 }, 23631 stop: function( event, ui ) { 23632 var offset = that.uiDialog.offset(), 23633 left = offset.left - that.document.scrollLeft(), 23634 top = offset.top - that.document.scrollTop(); 23635 23636 options.height = that.uiDialog.height(); 23637 options.width = that.uiDialog.width(); 23638 options.position = { 23639 my: "left top", 23640 at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + 23641 "top" + ( top >= 0 ? "+" : "" ) + top, 23642 of: that.window 23643 }; 23644 that._removeClass( $( this ), "ui-dialog-resizing" ); 23645 that._unblockFrames(); 23646 that._trigger( "resizeStop", event, filteredUi( ui ) ); 23647 } 23648 } ) 23649 .css( "position", position ); 23650 }, 23651 23652 _trackFocus: function() { 23653 this._on( this.widget(), { 23654 focusin: function( event ) { 23655 this._makeFocusTarget(); 23656 this._focusedElement = $( event.target ); 23657 } 23658 } ); 23659 }, 23660 23661 _makeFocusTarget: function() { 23662 this._untrackInstance(); 23663 this._trackingInstances().unshift( this ); 23664 }, 23665 23666 _untrackInstance: function() { 23667 var instances = this._trackingInstances(), 23668 exists = $.inArray( this, instances ); 23669 if ( exists !== -1 ) { 23670 instances.splice( exists, 1 ); 23671 } 23672 }, 23673 23674 _trackingInstances: function() { 23675 var instances = this.document.data( "ui-dialog-instances" ); 23676 if ( !instances ) { 23677 instances = []; 23678 this.document.data( "ui-dialog-instances", instances ); 23679 } 23680 return instances; 23681 }, 23682 23683 _minHeight: function() { 23684 var options = this.options; 23685 23686 return options.height === "auto" ? 23687 options.minHeight : 23688 Math.min( options.minHeight, options.height ); 23689 }, 23690 23691 _position: function() { 23692 23693 // Need to show the dialog to get the actual offset in the position plugin 23694 var isVisible = this.uiDialog.is( ":visible" ); 23695 if ( !isVisible ) { 23696 this.uiDialog.show(); 23697 } 23698 this.uiDialog.position( this.options.position ); 23699 if ( !isVisible ) { 23700 this.uiDialog.hide(); 23701 } 23702 }, 23703 23704 _setOptions: function( options ) { 23705 var that = this, 23706 resize = false, 23707 resizableOptions = {}; 23708 23709 $.each( options, function( key, value ) { 23710 that._setOption( key, value ); 23711 23712 if ( key in that.sizeRelatedOptions ) { 23713 resize = true; 23714 } 23715 if ( key in that.resizableRelatedOptions ) { 23716 resizableOptions[ key ] = value; 23717 } 23718 } ); 23719 23720 if ( resize ) { 23721 this._size(); 23722 this._position(); 23723 } 23724 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 23725 this.uiDialog.resizable( "option", resizableOptions ); 23726 } 23727 }, 23728 23729 _setOption: function( key, value ) { 23730 var isDraggable, isResizable, 23731 uiDialog = this.uiDialog; 23732 23733 if ( key === "disabled" ) { 23734 return; 23735 } 23736 23737 this._super( key, value ); 23738 23739 if ( key === "appendTo" ) { 23740 this.uiDialog.appendTo( this._appendTo() ); 23741 } 23742 23743 if ( key === "buttons" ) { 23744 this._createButtons(); 23745 } 23746 23747 if ( key === "closeText" ) { 23748 this.uiDialogTitlebarClose.button( { 23749 23750 // Ensure that we always pass a string 23751 label: $( "<a>" ).text( "" + this.options.closeText ).html() 23752 } ); 23753 } 23754 23755 if ( key === "draggable" ) { 23756 isDraggable = uiDialog.is( ":data(ui-draggable)" ); 23757 if ( isDraggable && !value ) { 23758 uiDialog.draggable( "destroy" ); 23759 } 23760 23761 if ( !isDraggable && value ) { 23762 this._makeDraggable(); 23763 } 23764 } 23765 23766 if ( key === "position" ) { 23767 this._position(); 23768 } 23769 23770 if ( key === "resizable" ) { 23771 23772 // currently resizable, becoming non-resizable 23773 isResizable = uiDialog.is( ":data(ui-resizable)" ); 23774 if ( isResizable && !value ) { 23775 uiDialog.resizable( "destroy" ); 23776 } 23777 23778 // Currently resizable, changing handles 23779 if ( isResizable && typeof value === "string" ) { 23780 uiDialog.resizable( "option", "handles", value ); 23781 } 23782 23783 // Currently non-resizable, becoming resizable 23784 if ( !isResizable && value !== false ) { 23785 this._makeResizable(); 23786 } 23787 } 23788 23789 if ( key === "title" ) { 23790 this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); 23791 } 23792 }, 23793 23794 _size: function() { 23795 23796 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content 23797 // divs will both have width and height set, so we need to reset them 23798 var nonContentHeight, minContentHeight, maxContentHeight, 23799 options = this.options; 23800 23801 // Reset content sizing 23802 this.element.show().css( { 23803 width: "auto", 23804 minHeight: 0, 23805 maxHeight: "none", 23806 height: 0 23807 } ); 23808 23809 if ( options.minWidth > options.width ) { 23810 options.width = options.minWidth; 23811 } 23812 23813 // Reset wrapper sizing 23814 // determine the height of all the non-content elements 23815 nonContentHeight = this.uiDialog.css( { 23816 height: "auto", 23817 width: options.width 23818 } ) 23819 .outerHeight(); 23820 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); 23821 maxContentHeight = typeof options.maxHeight === "number" ? 23822 Math.max( 0, options.maxHeight - nonContentHeight ) : 23823 "none"; 23824 23825 if ( options.height === "auto" ) { 23826 this.element.css( { 23827 minHeight: minContentHeight, 23828 maxHeight: maxContentHeight, 23829 height: "auto" 23830 } ); 23831 } else { 23832 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); 23833 } 23834 23835 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { 23836 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); 23837 } 23838 }, 23839 23840 _blockFrames: function() { 23841 this.iframeBlocks = this.document.find( "iframe" ).map( function() { 23842 var iframe = $( this ); 23843 23844 return $( "<div>" ) 23845 .css( { 23846 position: "absolute", 23847 width: iframe.outerWidth(), 23848 height: iframe.outerHeight() 23849 } ) 23850 .appendTo( iframe.parent() ) 23851 .offset( iframe.offset() )[ 0 ]; 23852 } ); 23853 }, 23854 23855 _unblockFrames: function() { 23856 if ( this.iframeBlocks ) { 23857 this.iframeBlocks.remove(); 23858 delete this.iframeBlocks; 23859 } 23860 }, 23861 23862 _allowInteraction: function( event ) { 23863 if ( $( event.target ).closest( ".ui-dialog" ).length ) { 23864 return true; 23865 } 23866 23867 // TODO: Remove hack when datepicker implements 23868 // the .ui-front logic (#8989) 23869 return !!$( event.target ).closest( ".ui-datepicker" ).length; 23870 }, 23871 23872 _createOverlay: function() { 23873 if ( !this.options.modal ) { 23874 return; 23875 } 23876 23877 var jqMinor = $.fn.jquery.substring( 0, 4 ); 23878 23879 // We use a delay in case the overlay is created from an 23880 // event that we're going to be cancelling (#2804) 23881 var isOpening = true; 23882 this._delay( function() { 23883 isOpening = false; 23884 } ); 23885 23886 if ( !this.document.data( "ui-dialog-overlays" ) ) { 23887 23888 // Prevent use of anchors and inputs 23889 // This doesn't use `_on()` because it is a shared event handler 23890 // across all open modal dialogs. 23891 this.document.on( "focusin.ui-dialog", function( event ) { 23892 if ( isOpening ) { 23893 return; 23894 } 23895 23896 var instance = this._trackingInstances()[ 0 ]; 23897 if ( !instance._allowInteraction( event ) ) { 23898 event.preventDefault(); 23899 instance._focusTabbable(); 23900 23901 // Support: jQuery >=3.4 <3.6 only 23902 // Focus re-triggering in jQuery 3.4/3.5 makes the original element 23903 // have its focus event propagated last, breaking the re-targeting. 23904 // Trigger focus in a delay in addition if needed to avoid the issue 23905 // See https://github.com/jquery/jquery/issues/4382 23906 if ( jqMinor === "3.4." || jqMinor === "3.5." ) { 23907 instance._delay( instance._restoreTabbableFocus ); 23908 } 23909 } 23910 }.bind( this ) ); 23911 } 23912 23913 this.overlay = $( "<div>" ) 23914 .appendTo( this._appendTo() ); 23915 23916 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); 23917 this._on( this.overlay, { 23918 mousedown: "_keepFocus" 23919 } ); 23920 this.document.data( "ui-dialog-overlays", 23921 ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); 23922 }, 23923 23924 _destroyOverlay: function() { 23925 if ( !this.options.modal ) { 23926 return; 23927 } 23928 23929 if ( this.overlay ) { 23930 var overlays = this.document.data( "ui-dialog-overlays" ) - 1; 23931 23932 if ( !overlays ) { 23933 this.document.off( "focusin.ui-dialog" ); 23934 this.document.removeData( "ui-dialog-overlays" ); 23935 } else { 23936 this.document.data( "ui-dialog-overlays", overlays ); 23937 } 23938 23939 this.overlay.remove(); 23940 this.overlay = null; 23941 } 23942 } 23943} ); 23944 23945// DEPRECATED 23946// TODO: switch return back to widget declaration at top of file when this is removed 23947if ( $.uiBackCompat !== false ) { 23948 23949 // Backcompat for dialogClass option 23950 $.widget( "ui.dialog", $.ui.dialog, { 23951 options: { 23952 dialogClass: "" 23953 }, 23954 _createWrapper: function() { 23955 this._super(); 23956 this.uiDialog.addClass( this.options.dialogClass ); 23957 }, 23958 _setOption: function( key, value ) { 23959 if ( key === "dialogClass" ) { 23960 this.uiDialog 23961 .removeClass( this.options.dialogClass ) 23962 .addClass( value ); 23963 } 23964 this._superApply( arguments ); 23965 } 23966 } ); 23967} 23968 23969var widgetsDialog = $.ui.dialog; 23970 23971 23972/*! 23973 * jQuery UI Droppable 1.13.2 23974 * http://jqueryui.com 23975 * 23976 * Copyright jQuery Foundation and other contributors 23977 * Released under the MIT license. 23978 * http://jquery.org/license 23979 */ 23980 23981//>>label: Droppable 23982//>>group: Interactions 23983//>>description: Enables drop targets for draggable elements. 23984//>>docs: http://api.jqueryui.com/droppable/ 23985//>>demos: http://jqueryui.com/droppable/ 23986 23987 23988$.widget( "ui.droppable", { 23989 version: "1.13.2", 23990 widgetEventPrefix: "drop", 23991 options: { 23992 accept: "*", 23993 addClasses: true, 23994 greedy: false, 23995 scope: "default", 23996 tolerance: "intersect", 23997 23998 // Callbacks 23999 activate: null, 24000 deactivate: null, 24001 drop: null, 24002 out: null, 24003 over: null 24004 }, 24005 _create: function() { 24006 24007 var proportions, 24008 o = this.options, 24009 accept = o.accept; 24010 24011 this.isover = false; 24012 this.isout = true; 24013 24014 this.accept = typeof accept === "function" ? accept : function( d ) { 24015 return d.is( accept ); 24016 }; 24017 24018 this.proportions = function( /* valueToWrite */ ) { 24019 if ( arguments.length ) { 24020 24021 // Store the droppable's proportions 24022 proportions = arguments[ 0 ]; 24023 } else { 24024 24025 // Retrieve or derive the droppable's proportions 24026 return proportions ? 24027 proportions : 24028 proportions = { 24029 width: this.element[ 0 ].offsetWidth, 24030 height: this.element[ 0 ].offsetHeight 24031 }; 24032 } 24033 }; 24034 24035 this._addToManager( o.scope ); 24036 24037 if ( o.addClasses ) { 24038 this._addClass( "ui-droppable" ); 24039 } 24040 24041 }, 24042 24043 _addToManager: function( scope ) { 24044 24045 // Add the reference and positions to the manager 24046 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; 24047 $.ui.ddmanager.droppables[ scope ].push( this ); 24048 }, 24049 24050 _splice: function( drop ) { 24051 var i = 0; 24052 for ( ; i < drop.length; i++ ) { 24053 if ( drop[ i ] === this ) { 24054 drop.splice( i, 1 ); 24055 } 24056 } 24057 }, 24058 24059 _destroy: function() { 24060 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 24061 24062 this._splice( drop ); 24063 }, 24064 24065 _setOption: function( key, value ) { 24066 24067 if ( key === "accept" ) { 24068 this.accept = typeof value === "function" ? value : function( d ) { 24069 return d.is( value ); 24070 }; 24071 } else if ( key === "scope" ) { 24072 var drop = $.ui.ddmanager.droppables[ this.options.scope ]; 24073 24074 this._splice( drop ); 24075 this._addToManager( value ); 24076 } 24077 24078 this._super( key, value ); 24079 }, 24080 24081 _activate: function( event ) { 24082 var draggable = $.ui.ddmanager.current; 24083 24084 this._addActiveClass(); 24085 if ( draggable ) { 24086 this._trigger( "activate", event, this.ui( draggable ) ); 24087 } 24088 }, 24089 24090 _deactivate: function( event ) { 24091 var draggable = $.ui.ddmanager.current; 24092 24093 this._removeActiveClass(); 24094 if ( draggable ) { 24095 this._trigger( "deactivate", event, this.ui( draggable ) ); 24096 } 24097 }, 24098 24099 _over: function( event ) { 24100 24101 var draggable = $.ui.ddmanager.current; 24102 24103 // Bail if draggable and droppable are same element 24104 if ( !draggable || ( draggable.currentItem || 24105 draggable.element )[ 0 ] === this.element[ 0 ] ) { 24106 return; 24107 } 24108 24109 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 24110 draggable.element ) ) ) { 24111 this._addHoverClass(); 24112 this._trigger( "over", event, this.ui( draggable ) ); 24113 } 24114 24115 }, 24116 24117 _out: function( event ) { 24118 24119 var draggable = $.ui.ddmanager.current; 24120 24121 // Bail if draggable and droppable are same element 24122 if ( !draggable || ( draggable.currentItem || 24123 draggable.element )[ 0 ] === this.element[ 0 ] ) { 24124 return; 24125 } 24126 24127 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || 24128 draggable.element ) ) ) { 24129 this._removeHoverClass(); 24130 this._trigger( "out", event, this.ui( draggable ) ); 24131 } 24132 24133 }, 24134 24135 _drop: function( event, custom ) { 24136 24137 var draggable = custom || $.ui.ddmanager.current, 24138 childrenIntersection = false; 24139 24140 // Bail if draggable and droppable are same element 24141 if ( !draggable || ( draggable.currentItem || 24142 draggable.element )[ 0 ] === this.element[ 0 ] ) { 24143 return false; 24144 } 24145 24146 this.element 24147 .find( ":data(ui-droppable)" ) 24148 .not( ".ui-draggable-dragging" ) 24149 .each( function() { 24150 var inst = $( this ).droppable( "instance" ); 24151 if ( 24152 inst.options.greedy && 24153 !inst.options.disabled &&
vendor: 4,579 bytes, lines 24154-24314
24154 inst.options.scope === draggable.options.scope && 24155 inst.accept.call( 24156 inst.element[ 0 ], ( draggable.currentItem || draggable.element ) 24157 ) && 24158 $.ui.intersect( 24159 draggable, 24160 $.extend( inst, { offset: inst.element.offset() } ), 24161 inst.options.tolerance, event 24162 ) 24163 ) { 24164 childrenIntersection = true; 24165 return false; 24166 } 24167 } ); 24168 if ( childrenIntersection ) { 24169 return false; 24170 } 24171 24172 if ( this.accept.call( this.element[ 0 ], 24173 ( draggable.currentItem || draggable.element ) ) ) { 24174 this._removeActiveClass(); 24175 this._removeHoverClass(); 24176 24177 this._trigger( "drop", event, this.ui( draggable ) ); 24178 return this.element; 24179 } 24180 24181 return false; 24182 24183 }, 24184 24185 ui: function( c ) { 24186 return { 24187 draggable: ( c.currentItem || c.element ), 24188 helper: c.helper, 24189 position: c.position, 24190 offset: c.positionAbs 24191 }; 24192 }, 24193 24194 // Extension points just to make backcompat sane and avoid duplicating logic 24195 // TODO: Remove in 1.14 along with call to it below 24196 _addHoverClass: function() { 24197 this._addClass( "ui-droppable-hover" ); 24198 }, 24199 24200 _removeHoverClass: function() { 24201 this._removeClass( "ui-droppable-hover" ); 24202 }, 24203 24204 _addActiveClass: function() { 24205 this._addClass( "ui-droppable-active" ); 24206 }, 24207 24208 _removeActiveClass: function() { 24209 this._removeClass( "ui-droppable-active" ); 24210 } 24211} ); 24212 24213$.ui.intersect = ( function() { 24214 function isOverAxis( x, reference, size ) { 24215 return ( x >= reference ) && ( x < ( reference + size ) ); 24216 } 24217 24218 return function( draggable, droppable, toleranceMode, event ) { 24219 24220 if ( !droppable.offset ) { 24221 return false; 24222 } 24223 24224 var x1 = ( draggable.positionAbs || 24225 draggable.position.absolute ).left + draggable.margins.left, 24226 y1 = ( draggable.positionAbs || 24227 draggable.position.absolute ).top + draggable.margins.top, 24228 x2 = x1 + draggable.helperProportions.width, 24229 y2 = y1 + draggable.helperProportions.height, 24230 l = droppable.offset.left, 24231 t = droppable.offset.top, 24232 r = l + droppable.proportions().width, 24233 b = t + droppable.proportions().height; 24234 24235 switch ( toleranceMode ) { 24236 case "fit": 24237 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); 24238 case "intersect": 24239 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half 24240 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half 24241 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half 24242 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half 24243 case "pointer": 24244 return isOverAxis( event.pageY, t, droppable.proportions().height ) && 24245 isOverAxis( event.pageX, l, droppable.proportions().width ); 24246 case "touch": 24247 return ( 24248 ( y1 >= t && y1 <= b ) || // Top edge touching 24249 ( y2 >= t && y2 <= b ) || // Bottom edge touching 24250 ( y1 < t && y2 > b ) // Surrounded vertically 24251 ) && ( 24252 ( x1 >= l && x1 <= r ) || // Left edge touching 24253 ( x2 >= l && x2 <= r ) || // Right edge touching 24254 ( x1 < l && x2 > r ) // Surrounded horizontally 24255 ); 24256 default: 24257 return false; 24258 } 24259 }; 24260} )(); 24261 24262/* 24263 This manager tracks offsets of draggables and droppables 24264*/ 24265$.ui.ddmanager = { 24266 current: null, 24267 droppables: { "default": [] }, 24268 prepareOffsets: function( t, event ) { 24269 24270 var i, j, 24271 m = $.ui.ddmanager.droppables[ t.options.scope ] || [], 24272 type = event ? event.type : null, // workaround for #2317 24273 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); 24274 24275 droppablesLoop: for ( i = 0; i < m.length; i++ ) { 24276 24277 // No disabled and non-accepted 24278 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], 24279 ( t.currentItem || t.element ) ) ) ) { 24280 continue; 24281 } 24282 24283 // Filter out elements in the current dragged item 24284 for ( j = 0; j < list.length; j++ ) { 24285 if ( list[ j ] === m[ i ].element[ 0 ] ) { 24286 m[ i ].proportions().height = 0; 24287 continue droppablesLoop; 24288 } 24289 } 24290 24291 m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; 24292 if ( !m[ i ].visible ) { 24293 continue; 24294 } 24295 24296 // Activate the droppable if used directly from draggables 24297 if ( type === "mousedown" ) { 24298 m[ i ]._activate.call( m[ i ], event ); 24299 } 24300 24301 m[ i ].offset = m[ i ].element.offset(); 24302 m[ i ].proportions( { 24303 width: m[ i ].element[ 0 ].offsetWidth, 24304 height: m[ i ].element[ 0 ].offsetHeight 24305 } ); 24306 24307 } 24308 24309 }, 24310 drop: function( draggable, event ) { 24311 24312 var dropped = false; 24313 24314 // Create a copy of the droppables in case the list changes during the drop (#9116)
vendor: 4,304 bytes, lines 24315-24457
24315 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { 24316 24317 if ( !this.options ) { 24318 return; 24319 } 24320 if ( !this.options.disabled && this.visible && 24321 $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { 24322 dropped = this._drop.call( this, event ) || dropped; 24323 } 24324 24325 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], 24326 ( draggable.currentItem || draggable.element ) ) ) { 24327 this.isout = true; 24328 this.isover = false; 24329 this._deactivate.call( this, event ); 24330 } 24331 24332 } ); 24333 return dropped; 24334 24335 }, 24336 dragStart: function( draggable, event ) { 24337 24338 // Listen for scrolling so that if the dragging causes scrolling the position of the 24339 // droppables can be recalculated (see #5003) 24340 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { 24341 if ( !draggable.options.refreshPositions ) { 24342 $.ui.ddmanager.prepareOffsets( draggable, event ); 24343 } 24344 } ); 24345 }, 24346 drag: function( draggable, event ) { 24347 24348 // If you have a highly dynamic page, you might try this option. It renders positions 24349 // every time you move the mouse. 24350 if ( draggable.options.refreshPositions ) { 24351 $.ui.ddmanager.prepareOffsets( draggable, event ); 24352 } 24353 24354 // Run through all droppables and check their positions based on specific tolerance options 24355 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { 24356 24357 if ( this.options.disabled || this.greedyChild || !this.visible ) { 24358 return; 24359 } 24360 24361 var parentInstance, scope, parent, 24362 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), 24363 c = !intersects && this.isover ? 24364 "isout" : 24365 ( intersects && !this.isover ? "isover" : null ); 24366 if ( !c ) { 24367 return; 24368 } 24369 24370 if ( this.options.greedy ) { 24371 24372 // find droppable parents with same scope 24373 scope = this.options.scope; 24374 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { 24375 return $( this ).droppable( "instance" ).options.scope === scope; 24376 } ); 24377 24378 if ( parent.length ) { 24379 parentInstance = $( parent[ 0 ] ).droppable( "instance" ); 24380 parentInstance.greedyChild = ( c === "isover" ); 24381 } 24382 } 24383 24384 // We just moved into a greedy child 24385 if ( parentInstance && c === "isover" ) { 24386 parentInstance.isover = false; 24387 parentInstance.isout = true; 24388 parentInstance._out.call( parentInstance, event ); 24389 } 24390 24391 this[ c ] = true; 24392 this[ c === "isout" ? "isover" : "isout" ] = false; 24393 this[ c === "isover" ? "_over" : "_out" ].call( this, event ); 24394 24395 // We just moved out of a greedy child 24396 if ( parentInstance && c === "isout" ) { 24397 parentInstance.isout = false; 24398 parentInstance.isover = true; 24399 parentInstance._over.call( parentInstance, event ); 24400 } 24401 } ); 24402 24403 }, 24404 dragStop: function( draggable, event ) { 24405 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); 24406 24407 // Call prepareOffsets one final time since IE does not fire return scroll events when 24408 // overflow was caused by drag (see #5003) 24409 if ( !draggable.options.refreshPositions ) { 24410 $.ui.ddmanager.prepareOffsets( draggable, event ); 24411 } 24412 } 24413}; 24414 24415// DEPRECATED 24416// TODO: switch return back to widget declaration at top of file when this is removed 24417if ( $.uiBackCompat !== false ) { 24418 24419 // Backcompat for activeClass and hoverClass options 24420 $.widget( "ui.droppable", $.ui.droppable, { 24421 options: { 24422 hoverClass: false, 24423 activeClass: false 24424 }, 24425 _addActiveClass: function() { 24426 this._super(); 24427 if ( this.options.activeClass ) { 24428 this.element.addClass( this.options.activeClass ); 24429 } 24430 }, 24431 _removeActiveClass: function() { 24432 this._super(); 24433 if ( this.options.activeClass ) { 24434 this.element.removeClass( this.options.activeClass ); 24435 } 24436 }, 24437 _addHoverClass: function() { 24438 this._super(); 24439 if ( this.options.hoverClass ) { 24440 this.element.addClass( this.options.hoverClass ); 24441 } 24442 }, 24443 _removeHoverClass: function() { 24444 this._super(); 24445 if ( this.options.hoverClass ) { 24446 this.element.removeClass( this.options.hoverClass ); 24447 } 24448 } 24449 } ); 24450} 24451 24452var widgetsDroppable = $.ui.droppable; 24453 24454 24455/*! 24456 * jQuery UI Progressbar 1.13.2 24457 * http://jqueryui.com
vendor: 12,231 bytes, lines 24458-24918
24458 * 24459 * Copyright jQuery Foundation and other contributors 24460 * Released under the MIT license. 24461 * http://jquery.org/license 24462 */ 24463 24464//>>label: Progressbar 24465//>>group: Widgets 24466/* eslint-disable max-len */ 24467//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. 24468/* eslint-enable max-len */ 24469//>>docs: http://api.jqueryui.com/progressbar/ 24470//>>demos: http://jqueryui.com/progressbar/ 24471//>>css.structure: ../../themes/base/core.css 24472//>>css.structure: ../../themes/base/progressbar.css 24473//>>css.theme: ../../themes/base/theme.css 24474 24475 24476var widgetsProgressbar = $.widget( "ui.progressbar", { 24477 version: "1.13.2", 24478 options: { 24479 classes: { 24480 "ui-progressbar": "ui-corner-all", 24481 "ui-progressbar-value": "ui-corner-left", 24482 "ui-progressbar-complete": "ui-corner-right" 24483 }, 24484 max: 100, 24485 value: 0, 24486 24487 change: null, 24488 complete: null 24489 }, 24490 24491 min: 0, 24492 24493 _create: function() { 24494 24495 // Constrain initial value 24496 this.oldValue = this.options.value = this._constrainedValue(); 24497 24498 this.element.attr( { 24499 24500 // Only set static values; aria-valuenow and aria-valuemax are 24501 // set inside _refreshValue() 24502 role: "progressbar", 24503 "aria-valuemin": this.min 24504 } ); 24505 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); 24506 24507 this.valueDiv = $( "<div>" ).appendTo( this.element ); 24508 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); 24509 this._refreshValue(); 24510 }, 24511 24512 _destroy: function() { 24513 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); 24514 24515 this.valueDiv.remove(); 24516 }, 24517 24518 value: function( newValue ) { 24519 if ( newValue === undefined ) { 24520 return this.options.value; 24521 } 24522 24523 this.options.value = this._constrainedValue( newValue ); 24524 this._refreshValue(); 24525 }, 24526 24527 _constrainedValue: function( newValue ) { 24528 if ( newValue === undefined ) { 24529 newValue = this.options.value; 24530 } 24531 24532 this.indeterminate = newValue === false; 24533 24534 // Sanitize value 24535 if ( typeof newValue !== "number" ) { 24536 newValue = 0; 24537 } 24538 24539 return this.indeterminate ? false : 24540 Math.min( this.options.max, Math.max( this.min, newValue ) ); 24541 }, 24542 24543 _setOptions: function( options ) { 24544 24545 // Ensure "value" option is set after other values (like max) 24546 var value = options.value; 24547 delete options.value; 24548 24549 this._super( options ); 24550 24551 this.options.value = this._constrainedValue( value ); 24552 this._refreshValue(); 24553 }, 24554 24555 _setOption: function( key, value ) { 24556 if ( key === "max" ) { 24557 24558 // Don't allow a max less than min 24559 value = Math.max( this.min, value ); 24560 } 24561 this._super( key, value ); 24562 }, 24563 24564 _setOptionDisabled: function( value ) { 24565 this._super( value ); 24566 24567 this.element.attr( "aria-disabled", value ); 24568 this._toggleClass( null, "ui-state-disabled", !!value ); 24569 }, 24570 24571 _percentage: function() { 24572 return this.indeterminate ? 24573 100 : 24574 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); 24575 }, 24576 24577 _refreshValue: function() { 24578 var value = this.options.value, 24579 percentage = this._percentage(); 24580 24581 this.valueDiv 24582 .toggle( this.indeterminate || value > this.min ) 24583 .width( percentage.toFixed( 0 ) + "%" ); 24584 24585 this 24586 ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, 24587 value === this.options.max ) 24588 ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); 24589 24590 if ( this.indeterminate ) { 24591 this.element.removeAttr( "aria-valuenow" ); 24592 if ( !this.overlayDiv ) { 24593 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); 24594 this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); 24595 } 24596 } else { 24597 this.element.attr( { 24598 "aria-valuemax": this.options.max, 24599 "aria-valuenow": value 24600 } ); 24601 if ( this.overlayDiv ) { 24602 this.overlayDiv.remove(); 24603 this.overlayDiv = null; 24604 } 24605 } 24606 24607 if ( this.oldValue !== value ) { 24608 this.oldValue = value; 24609 this._trigger( "change" ); 24610 } 24611 if ( value === this.options.max ) { 24612 this._trigger( "complete" ); 24613 } 24614 } 24615} ); 24616 24617 24618/*! 24619 * jQuery UI Selectable 1.13.2 24620 * http://jqueryui.com 24621 * 24622 * Copyright jQuery Foundation and other contributors 24623 * Released under the MIT license. 24624 * http://jquery.org/license 24625 */ 24626 24627//>>label: Selectable 24628//>>group: Interactions 24629//>>description: Allows groups of elements to be selected with the mouse. 24630//>>docs: http://api.jqueryui.com/selectable/ 24631//>>demos: http://jqueryui.com/selectable/ 24632//>>css.structure: ../../themes/base/selectable.css 24633 24634 24635var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { 24636 version: "1.13.2", 24637 options: { 24638 appendTo: "body", 24639 autoRefresh: true, 24640 distance: 0, 24641 filter: "*", 24642 tolerance: "touch", 24643 24644 // Callbacks 24645 selected: null, 24646 selecting: null, 24647 start: null, 24648 stop: null, 24649 unselected: null, 24650 unselecting: null 24651 }, 24652 _create: function() { 24653 var that = this; 24654 24655 this._addClass( "ui-selectable" ); 24656 24657 this.dragged = false; 24658 24659 // Cache selectee children based on filter 24660 this.refresh = function() { 24661 that.elementPos = $( that.element[ 0 ] ).offset(); 24662 that.selectees = $( that.options.filter, that.element[ 0 ] ); 24663 that._addClass( that.selectees, "ui-selectee" ); 24664 that.selectees.each( function() { 24665 var $this = $( this ), 24666 selecteeOffset = $this.offset(), 24667 pos = { 24668 left: selecteeOffset.left - that.elementPos.left, 24669 top: selecteeOffset.top - that.elementPos.top 24670 }; 24671 $.data( this, "selectable-item", { 24672 element: this, 24673 $element: $this, 24674 left: pos.left, 24675 top: pos.top, 24676 right: pos.left + $this.outerWidth(), 24677 bottom: pos.top + $this.outerHeight(), 24678 startselected: false, 24679 selected: $this.hasClass( "ui-selected" ), 24680 selecting: $this.hasClass( "ui-selecting" ), 24681 unselecting: $this.hasClass( "ui-unselecting" ) 24682 } ); 24683 } ); 24684 }; 24685 this.refresh(); 24686 24687 this._mouseInit(); 24688 24689 this.helper = $( "<div>" ); 24690 this._addClass( this.helper, "ui-selectable-helper" ); 24691 }, 24692 24693 _destroy: function() { 24694 this.selectees.removeData( "selectable-item" ); 24695 this._mouseDestroy(); 24696 }, 24697 24698 _mouseStart: function( event ) { 24699 var that = this, 24700 options = this.options; 24701 24702 this.opos = [ event.pageX, event.pageY ]; 24703 this.elementPos = $( this.element[ 0 ] ).offset(); 24704 24705 if ( this.options.disabled ) { 24706 return; 24707 } 24708 24709 this.selectees = $( options.filter, this.element[ 0 ] ); 24710 24711 this._trigger( "start", event ); 24712 24713 $( options.appendTo ).append( this.helper ); 24714 24715 // position helper (lasso) 24716 this.helper.css( { 24717 "left": event.pageX, 24718 "top": event.pageY, 24719 "width": 0, 24720 "height": 0 24721 } ); 24722 24723 if ( options.autoRefresh ) { 24724 this.refresh(); 24725 } 24726 24727 this.selectees.filter( ".ui-selected" ).each( function() { 24728 var selectee = $.data( this, "selectable-item" ); 24729 selectee.startselected = true; 24730 if ( !event.metaKey && !event.ctrlKey ) { 24731 that._removeClass( selectee.$element, "ui-selected" ); 24732 selectee.selected = false; 24733 that._addClass( selectee.$element, "ui-unselecting" ); 24734 selectee.unselecting = true; 24735 24736 // selectable UNSELECTING callback 24737 that._trigger( "unselecting", event, { 24738 unselecting: selectee.element 24739 } ); 24740 } 24741 } ); 24742 24743 $( event.target ).parents().addBack().each( function() { 24744 var doSelect, 24745 selectee = $.data( this, "selectable-item" ); 24746 if ( selectee ) { 24747 doSelect = ( !event.metaKey && !event.ctrlKey ) || 24748 !selectee.$element.hasClass( "ui-selected" ); 24749 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) 24750 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); 24751 selectee.unselecting = !doSelect; 24752 selectee.selecting = doSelect; 24753 selectee.selected = doSelect; 24754 24755 // selectable (UN)SELECTING callback 24756 if ( doSelect ) { 24757 that._trigger( "selecting", event, { 24758 selecting: selectee.element 24759 } ); 24760 } else { 24761 that._trigger( "unselecting", event, { 24762 unselecting: selectee.element 24763 } ); 24764 } 24765 return false; 24766 } 24767 } ); 24768 24769 }, 24770 24771 _mouseDrag: function( event ) { 24772 24773 this.dragged = true; 24774 24775 if ( this.options.disabled ) { 24776 return; 24777 } 24778 24779 var tmp, 24780 that = this, 24781 options = this.options, 24782 x1 = this.opos[ 0 ], 24783 y1 = this.opos[ 1 ], 24784 x2 = event.pageX, 24785 y2 = event.pageY; 24786 24787 if ( x1 > x2 ) { 24788 tmp = x2; x2 = x1; x1 = tmp; 24789 } 24790 if ( y1 > y2 ) { 24791 tmp = y2; y2 = y1; y1 = tmp; 24792 } 24793 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); 24794 24795 this.selectees.each( function() { 24796 var selectee = $.data( this, "selectable-item" ), 24797 hit = false, 24798 offset = {}; 24799 24800 //prevent helper from being selected if appendTo: selectable 24801 if ( !selectee || selectee.element === that.element[ 0 ] ) { 24802 return; 24803 } 24804 24805 offset.left = selectee.left + that.elementPos.left; 24806 offset.right = selectee.right + that.elementPos.left; 24807 offset.top = selectee.top + that.elementPos.top; 24808 offset.bottom = selectee.bottom + that.elementPos.top; 24809 24810 if ( options.tolerance === "touch" ) { 24811 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || 24812 offset.bottom < y1 ) ); 24813 } else if ( options.tolerance === "fit" ) { 24814 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && 24815 offset.bottom < y2 ); 24816 } 24817 24818 if ( hit ) { 24819 24820 // SELECT 24821 if ( selectee.selected ) { 24822 that._removeClass( selectee.$element, "ui-selected" ); 24823 selectee.selected = false; 24824 } 24825 if ( selectee.unselecting ) { 24826 that._removeClass( selectee.$element, "ui-unselecting" ); 24827 selectee.unselecting = false; 24828 } 24829 if ( !selectee.selecting ) { 24830 that._addClass( selectee.$element, "ui-selecting" ); 24831 selectee.selecting = true; 24832 24833 // selectable SELECTING callback 24834 that._trigger( "selecting", event, { 24835 selecting: selectee.element 24836 } ); 24837 } 24838 } else { 24839 24840 // UNSELECT 24841 if ( selectee.selecting ) { 24842 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { 24843 that._removeClass( selectee.$element, "ui-selecting" ); 24844 selectee.selecting = false; 24845 that._addClass( selectee.$element, "ui-selected" ); 24846 selectee.selected = true; 24847 } else { 24848 that._removeClass( selectee.$element, "ui-selecting" ); 24849 selectee.selecting = false; 24850 if ( selectee.startselected ) { 24851 that._addClass( selectee.$element, "ui-unselecting" ); 24852 selectee.unselecting = true; 24853 } 24854 24855 // selectable UNSELECTING callback 24856 that._trigger( "unselecting", event, { 24857 unselecting: selectee.element 24858 } ); 24859 } 24860 } 24861 if ( selectee.selected ) { 24862 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { 24863 that._removeClass( selectee.$element, "ui-selected" ); 24864 selectee.selected = false; 24865 24866 that._addClass( selectee.$element, "ui-unselecting" ); 24867 selectee.unselecting = true; 24868 24869 // selectable UNSELECTING callback 24870 that._trigger( "unselecting", event, { 24871 unselecting: selectee.element 24872 } ); 24873 } 24874 } 24875 } 24876 } ); 24877 24878 return false; 24879 }, 24880 24881 _mouseStop: function( event ) { 24882 var that = this; 24883 24884 this.dragged = false; 24885 24886 $( ".ui-unselecting", this.element[ 0 ] ).each( function() { 24887 var selectee = $.data( this, "selectable-item" ); 24888 that._removeClass( selectee.$element, "ui-unselecting" ); 24889 selectee.unselecting = false; 24890 selectee.startselected = false; 24891 that._trigger( "unselected", event, { 24892 unselected: selectee.element 24893 } ); 24894 } ); 24895 $( ".ui-selecting", this.element[ 0 ] ).each( function() { 24896 var selectee = $.data( this, "selectable-item" ); 24897 that._removeClass( selectee.$element, "ui-selecting" ) 24898 ._addClass( selectee.$element, "ui-selected" ); 24899 selectee.selecting = false; 24900 selectee.selected = true; 24901 selectee.startselected = true; 24902 that._trigger( "selected", event, { 24903 selected: selectee.element 24904 } ); 24905 } ); 24906 this._trigger( "stop", event ); 24907 24908 this.helper.remove(); 24909 24910 return false; 24911 } 24912 24913} ); 24914 24915 24916/*! 24917 * jQuery UI Selectmenu 1.13.2 24918 * http://jqueryui.com
vendor: 20,756 bytes, lines 24919-25749
24919 * 24920 * Copyright jQuery Foundation and other contributors 24921 * Released under the MIT license. 24922 * http://jquery.org/license 24923 */ 24924 24925//>>label: Selectmenu 24926//>>group: Widgets 24927/* eslint-disable max-len */ 24928//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. 24929/* eslint-enable max-len */ 24930//>>docs: http://api.jqueryui.com/selectmenu/ 24931//>>demos: http://jqueryui.com/selectmenu/ 24932//>>css.structure: ../../themes/base/core.css 24933//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css 24934//>>css.theme: ../../themes/base/theme.css 24935 24936 24937var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { 24938 version: "1.13.2", 24939 defaultElement: "<select>", 24940 options: { 24941 appendTo: null, 24942 classes: { 24943 "ui-selectmenu-button-open": "ui-corner-top", 24944 "ui-selectmenu-button-closed": "ui-corner-all" 24945 }, 24946 disabled: null, 24947 icons: { 24948 button: "ui-icon-triangle-1-s" 24949 }, 24950 position: { 24951 my: "left top", 24952 at: "left bottom", 24953 collision: "none" 24954 }, 24955 width: false, 24956 24957 // Callbacks 24958 change: null, 24959 close: null, 24960 focus: null, 24961 open: null, 24962 select: null 24963 }, 24964 24965 _create: function() { 24966 var selectmenuId = this.element.uniqueId().attr( "id" ); 24967 this.ids = { 24968 element: selectmenuId, 24969 button: selectmenuId + "-button", 24970 menu: selectmenuId + "-menu" 24971 }; 24972 24973 this._drawButton(); 24974 this._drawMenu(); 24975 this._bindFormResetHandler(); 24976 24977 this._rendered = false; 24978 this.menuItems = $(); 24979 }, 24980 24981 _drawButton: function() { 24982 var icon, 24983 that = this, 24984 item = this._parseOption( 24985 this.element.find( "option:selected" ), 24986 this.element[ 0 ].selectedIndex 24987 ); 24988 24989 // Associate existing label with the new button 24990 this.labels = this.element.labels().attr( "for", this.ids.button ); 24991 this._on( this.labels, { 24992 click: function( event ) { 24993 this.button.trigger( "focus" ); 24994 event.preventDefault(); 24995 } 24996 } ); 24997 24998 // Hide original select element 24999 this.element.hide(); 25000 25001 // Create button 25002 this.button = $( "<span>", { 25003 tabindex: this.options.disabled ? -1 : 0, 25004 id: this.ids.button, 25005 role: "combobox", 25006 "aria-expanded": "false", 25007 "aria-autocomplete": "list", 25008 "aria-owns": this.ids.menu, 25009 "aria-haspopup": "true", 25010 title: this.element.attr( "title" ) 25011 } ) 25012 .insertAfter( this.element ); 25013 25014 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", 25015 "ui-button ui-widget" ); 25016 25017 icon = $( "<span>" ).appendTo( this.button ); 25018 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); 25019 this.buttonItem = this._renderButtonItem( item ) 25020 .appendTo( this.button ); 25021 25022 if ( this.options.width !== false ) { 25023 this._resizeButton(); 25024 } 25025 25026 this._on( this.button, this._buttonEvents ); 25027 this.button.one( "focusin", function() { 25028 25029 // Delay rendering the menu items until the button receives focus. 25030 // The menu may have already been rendered via a programmatic open. 25031 if ( !that._rendered ) { 25032 that._refreshMenu(); 25033 } 25034 } ); 25035 }, 25036 25037 _drawMenu: function() { 25038 var that = this; 25039 25040 // Create menu 25041 this.menu = $( "<ul>", { 25042 "aria-hidden": "true", 25043 "aria-labelledby": this.ids.button, 25044 id: this.ids.menu 25045 } ); 25046 25047 // Wrap menu 25048 this.menuWrap = $( "<div>" ).append( this.menu ); 25049 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); 25050 this.menuWrap.appendTo( this._appendTo() ); 25051 25052 // Initialize menu widget 25053 this.menuInstance = this.menu 25054 .menu( { 25055 classes: { 25056 "ui-menu": "ui-corner-bottom" 25057 }, 25058 role: "listbox", 25059 select: function( event, ui ) { 25060 event.preventDefault(); 25061 25062 // Support: IE8 25063 // If the item was selected via a click, the text selection 25064 // will be destroyed in IE 25065 that._setSelection(); 25066 25067 that._select( ui.item.data( "ui-selectmenu-item" ), event ); 25068 }, 25069 focus: function( event, ui ) { 25070 var item = ui.item.data( "ui-selectmenu-item" ); 25071 25072 // Prevent inital focus from firing and check if its a newly focused item 25073 if ( that.focusIndex != null && item.index !== that.focusIndex ) { 25074 that._trigger( "focus", event, { item: item } ); 25075 if ( !that.isOpen ) { 25076 that._select( item, event ); 25077 } 25078 } 25079 that.focusIndex = item.index; 25080 25081 that.button.attr( "aria-activedescendant", 25082 that.menuItems.eq( item.index ).attr( "id" ) ); 25083 } 25084 } ) 25085 .menu( "instance" ); 25086 25087 // Don't close the menu on mouseleave 25088 this.menuInstance._off( this.menu, "mouseleave" ); 25089 25090 // Cancel the menu's collapseAll on document click 25091 this.menuInstance._closeOnDocumentClick = function() { 25092 return false; 25093 }; 25094 25095 // Selects often contain empty items, but never contain dividers 25096 this.menuInstance._isDivider = function() { 25097 return false; 25098 }; 25099 }, 25100 25101 refresh: function() { 25102 this._refreshMenu(); 25103 this.buttonItem.replaceWith( 25104 this.buttonItem = this._renderButtonItem( 25105 25106 // Fall back to an empty object in case there are no options 25107 this._getSelectedItem().data( "ui-selectmenu-item" ) || {} 25108 ) 25109 ); 25110 if ( this.options.width === null ) { 25111 this._resizeButton(); 25112 } 25113 }, 25114 25115 _refreshMenu: function() { 25116 var item, 25117 options = this.element.find( "option" ); 25118 25119 this.menu.empty(); 25120 25121 this._parseOptions( options ); 25122 this._renderMenu( this.menu, this.items ); 25123 25124 this.menuInstance.refresh(); 25125 this.menuItems = this.menu.find( "li" ) 25126 .not( ".ui-selectmenu-optgroup" ) 25127 .find( ".ui-menu-item-wrapper" ); 25128 25129 this._rendered = true; 25130 25131 if ( !options.length ) { 25132 return; 25133 } 25134 25135 item = this._getSelectedItem(); 25136 25137 // Update the menu to have the correct item focused 25138 this.menuInstance.focus( null, item ); 25139 this._setAria( item.data( "ui-selectmenu-item" ) ); 25140 25141 // Set disabled state 25142 this._setOption( "disabled", this.element.prop( "disabled" ) ); 25143 }, 25144 25145 open: function( event ) { 25146 if ( this.options.disabled ) { 25147 return; 25148 } 25149 25150 // If this is the first time the menu is being opened, render the items 25151 if ( !this._rendered ) { 25152 this._refreshMenu(); 25153 } else { 25154 25155 // Menu clears focus on close, reset focus to selected item 25156 this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); 25157 this.menuInstance.focus( null, this._getSelectedItem() ); 25158 } 25159 25160 // If there are no options, don't open the menu 25161 if ( !this.menuItems.length ) { 25162 return; 25163 } 25164 25165 this.isOpen = true; 25166 this._toggleAttr(); 25167 this._resizeMenu(); 25168 this._position(); 25169 25170 this._on( this.document, this._documentClick ); 25171 25172 this._trigger( "open", event ); 25173 }, 25174 25175 _position: function() { 25176 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); 25177 }, 25178 25179 close: function( event ) { 25180 if ( !this.isOpen ) { 25181 return; 25182 } 25183 25184 this.isOpen = false; 25185 this._toggleAttr(); 25186 25187 this.range = null; 25188 this._off( this.document ); 25189 25190 this._trigger( "close", event ); 25191 }, 25192 25193 widget: function() { 25194 return this.button; 25195 }, 25196 25197 menuWidget: function() { 25198 return this.menu; 25199 }, 25200 25201 _renderButtonItem: function( item ) { 25202 var buttonItem = $( "<span>" ); 25203 25204 this._setText( buttonItem, item.label ); 25205 this._addClass( buttonItem, "ui-selectmenu-text" ); 25206 25207 return buttonItem; 25208 }, 25209 25210 _renderMenu: function( ul, items ) { 25211 var that = this, 25212 currentOptgroup = ""; 25213 25214 $.each( items, function( index, item ) { 25215 var li; 25216 25217 if ( item.optgroup !== currentOptgroup ) { 25218 li = $( "<li>", { 25219 text: item.optgroup 25220 } ); 25221 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + 25222 ( item.element.parent( "optgroup" ).prop( "disabled" ) ? 25223 " ui-state-disabled" : 25224 "" ) ); 25225 25226 li.appendTo( ul ); 25227 25228 currentOptgroup = item.optgroup; 25229 } 25230 25231 that._renderItemData( ul, item ); 25232 } ); 25233 }, 25234 25235 _renderItemData: function( ul, item ) { 25236 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); 25237 }, 25238 25239 _renderItem: function( ul, item ) { 25240 var li = $( "<li>" ), 25241 wrapper = $( "<div>", { 25242 title: item.element.attr( "title" ) 25243 } ); 25244 25245 if ( item.disabled ) { 25246 this._addClass( li, null, "ui-state-disabled" ); 25247 } 25248 this._setText( wrapper, item.label ); 25249 25250 return li.append( wrapper ).appendTo( ul ); 25251 }, 25252 25253 _setText: function( element, value ) { 25254 if ( value ) { 25255 element.text( value ); 25256 } else { 25257 element.html( " " ); 25258 } 25259 }, 25260 25261 _move: function( direction, event ) { 25262 var item, next, 25263 filter = ".ui-menu-item"; 25264 25265 if ( this.isOpen ) { 25266 item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 25267 } else { 25268 item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 25269 filter += ":not(.ui-state-disabled)"; 25270 } 25271 25272 if ( direction === "first" || direction === "last" ) { 25273 next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); 25274 } else { 25275 next = item[ direction + "All" ]( filter ).eq( 0 ); 25276 } 25277 25278 if ( next.length ) { 25279 this.menuInstance.focus( event, next ); 25280 } 25281 }, 25282 25283 _getSelectedItem: function() { 25284 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); 25285 }, 25286 25287 _toggle: function( event ) { 25288 this[ this.isOpen ? "close" : "open" ]( event ); 25289 }, 25290 25291 _setSelection: function() { 25292 var selection; 25293 25294 if ( !this.range ) { 25295 return; 25296 } 25297 25298 if ( window.getSelection ) { 25299 selection = window.getSelection(); 25300 selection.removeAllRanges(); 25301 selection.addRange( this.range ); 25302 25303 // Support: IE8 25304 } else { 25305 this.range.select(); 25306 } 25307 25308 // Support: IE 25309 // Setting the text selection kills the button focus in IE, but 25310 // restoring the focus doesn't kill the selection. 25311 this.button.trigger( "focus" ); 25312 }, 25313 25314 _documentClick: { 25315 mousedown: function( event ) { 25316 if ( !this.isOpen ) { 25317 return; 25318 } 25319 25320 if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + 25321 $.escapeSelector( this.ids.button ) ).length ) { 25322 this.close( event ); 25323 } 25324 } 25325 }, 25326 25327 _buttonEvents: { 25328 25329 // Prevent text selection from being reset when interacting with the selectmenu (#10144) 25330 mousedown: function() { 25331 var selection; 25332 25333 if ( window.getSelection ) { 25334 selection = window.getSelection(); 25335 if ( selection.rangeCount ) { 25336 this.range = selection.getRangeAt( 0 ); 25337 } 25338 25339 // Support: IE8 25340 } else { 25341 this.range = document.selection.createRange(); 25342 } 25343 }, 25344 25345 click: function( event ) { 25346 this._setSelection(); 25347 this._toggle( event ); 25348 }, 25349 25350 keydown: function( event ) { 25351 var preventDefault = true; 25352 switch ( event.keyCode ) { 25353 case $.ui.keyCode.TAB: 25354 case $.ui.keyCode.ESCAPE: 25355 this.close( event ); 25356 preventDefault = false; 25357 break; 25358 case $.ui.keyCode.ENTER: 25359 if ( this.isOpen ) { 25360 this._selectFocusedItem( event ); 25361 } 25362 break; 25363 case $.ui.keyCode.UP: 25364 if ( event.altKey ) { 25365 this._toggle( event ); 25366 } else { 25367 this._move( "prev", event ); 25368 } 25369 break; 25370 case $.ui.keyCode.DOWN: 25371 if ( event.altKey ) { 25372 this._toggle( event ); 25373 } else { 25374 this._move( "next", event ); 25375 } 25376 break; 25377 case $.ui.keyCode.SPACE: 25378 if ( this.isOpen ) { 25379 this._selectFocusedItem( event ); 25380 } else { 25381 this._toggle( event ); 25382 } 25383 break; 25384 case $.ui.keyCode.LEFT: 25385 this._move( "prev", event ); 25386 break; 25387 case $.ui.keyCode.RIGHT: 25388 this._move( "next", event ); 25389 break; 25390 case $.ui.keyCode.HOME: 25391 case $.ui.keyCode.PAGE_UP: 25392 this._move( "first", event ); 25393 break; 25394 case $.ui.keyCode.END: 25395 case $.ui.keyCode.PAGE_DOWN: 25396 this._move( "last", event ); 25397 break; 25398 default: 25399 this.menu.trigger( event ); 25400 preventDefault = false; 25401 } 25402 25403 if ( preventDefault ) { 25404 event.preventDefault(); 25405 } 25406 } 25407 }, 25408 25409 _selectFocusedItem: function( event ) { 25410 var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); 25411 if ( !item.hasClass( "ui-state-disabled" ) ) { 25412 this._select( item.data( "ui-selectmenu-item" ), event ); 25413 } 25414 }, 25415 25416 _select: function( item, event ) { 25417 var oldIndex = this.element[ 0 ].selectedIndex; 25418 25419 // Change native select element 25420 this.element[ 0 ].selectedIndex = item.index; 25421 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); 25422 this._setAria( item ); 25423 this._trigger( "select", event, { item: item } ); 25424 25425 if ( item.index !== oldIndex ) { 25426 this._trigger( "change", event, { item: item } ); 25427 } 25428 25429 this.close( event ); 25430 }, 25431 25432 _setAria: function( item ) { 25433 var id = this.menuItems.eq( item.index ).attr( "id" ); 25434 25435 this.button.attr( { 25436 "aria-labelledby": id, 25437 "aria-activedescendant": id 25438 } ); 25439 this.menu.attr( "aria-activedescendant", id ); 25440 }, 25441 25442 _setOption: function( key, value ) { 25443 if ( key === "icons" ) { 25444 var icon = this.button.find( "span.ui-icon" ); 25445 this._removeClass( icon, null, this.options.icons.button ) 25446 ._addClass( icon, null, value.button ); 25447 } 25448 25449 this._super( key, value ); 25450 25451 if ( key === "appendTo" ) { 25452 this.menuWrap.appendTo( this._appendTo() ); 25453 } 25454 25455 if ( key === "width" ) { 25456 this._resizeButton(); 25457 } 25458 }, 25459 25460 _setOptionDisabled: function( value ) { 25461 this._super( value ); 25462 25463 this.menuInstance.option( "disabled", value ); 25464 this.button.attr( "aria-disabled", value ); 25465 this._toggleClass( this.button, null, "ui-state-disabled", value ); 25466 25467 this.element.prop( "disabled", value ); 25468 if ( value ) { 25469 this.button.attr( "tabindex", -1 ); 25470 this.close(); 25471 } else { 25472 this.button.attr( "tabindex", 0 ); 25473 } 25474 }, 25475 25476 _appendTo: function() { 25477 var element = this.options.appendTo; 25478 25479 if ( element ) { 25480 element = element.jquery || element.nodeType ? 25481 $( element ) : 25482 this.document.find( element ).eq( 0 ); 25483 } 25484 25485 if ( !element || !element[ 0 ] ) { 25486 element = this.element.closest( ".ui-front, dialog" ); 25487 } 25488 25489 if ( !element.length ) { 25490 element = this.document[ 0 ].body; 25491 } 25492 25493 return element; 25494 }, 25495 25496 _toggleAttr: function() { 25497 this.button.attr( "aria-expanded", this.isOpen ); 25498 25499 // We can't use two _toggleClass() calls here, because we need to make sure 25500 // we always remove classes first and add them second, otherwise if both classes have the 25501 // same theme class, it will be removed after we add it. 25502 this._removeClass( this.button, "ui-selectmenu-button-" + 25503 ( this.isOpen ? "closed" : "open" ) ) 25504 ._addClass( this.button, "ui-selectmenu-button-" + 25505 ( this.isOpen ? "open" : "closed" ) ) 25506 ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); 25507 25508 this.menu.attr( "aria-hidden", !this.isOpen ); 25509 }, 25510 25511 _resizeButton: function() { 25512 var width = this.options.width; 25513 25514 // For `width: false`, just remove inline style and stop 25515 if ( width === false ) { 25516 this.button.css( "width", "" ); 25517 return; 25518 } 25519 25520 // For `width: null`, match the width of the original element 25521 if ( width === null ) { 25522 width = this.element.show().outerWidth(); 25523 this.element.hide(); 25524 } 25525 25526 this.button.outerWidth( width ); 25527 }, 25528 25529 _resizeMenu: function() { 25530 this.menu.outerWidth( Math.max( 25531 this.button.outerWidth(), 25532 25533 // Support: IE10 25534 // IE10 wraps long text (possibly a rounding bug) 25535 // so we add 1px to avoid the wrapping 25536 this.menu.width( "" ).outerWidth() + 1 25537 ) ); 25538 }, 25539 25540 _getCreateOptions: function() { 25541 var options = this._super(); 25542 25543 options.disabled = this.element.prop( "disabled" ); 25544 25545 return options; 25546 }, 25547 25548 _parseOptions: function( options ) { 25549 var that = this, 25550 data = []; 25551 options.each( function( index, item ) { 25552 if ( item.hidden ) { 25553 return; 25554 } 25555 25556 data.push( that._parseOption( $( item ), index ) ); 25557 } ); 25558 this.items = data; 25559 }, 25560 25561 _parseOption: function( option, index ) { 25562 var optgroup = option.parent( "optgroup" ); 25563 25564 return { 25565 element: option, 25566 index: index, 25567 value: option.val(), 25568 label: option.text(), 25569 optgroup: optgroup.attr( "label" ) || "", 25570 disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) 25571 }; 25572 }, 25573 25574 _destroy: function() { 25575 this._unbindFormResetHandler(); 25576 this.menuWrap.remove(); 25577 this.button.remove(); 25578 this.element.show(); 25579 this.element.removeUniqueId(); 25580 this.labels.attr( "for", this.ids.element ); 25581 } 25582} ] ); 25583 25584 25585/*! 25586 * jQuery UI Slider 1.13.2 25587 * http://jqueryui.com 25588 * 25589 * Copyright jQuery Foundation and other contributors 25590 * Released under the MIT license. 25591 * http://jquery.org/license 25592 */ 25593 25594//>>label: Slider 25595//>>group: Widgets 25596//>>description: Displays a flexible slider with ranges and accessibility via keyboard. 25597//>>docs: http://api.jqueryui.com/slider/ 25598//>>demos: http://jqueryui.com/slider/ 25599//>>css.structure: ../../themes/base/core.css 25600//>>css.structure: ../../themes/base/slider.css 25601//>>css.theme: ../../themes/base/theme.css 25602 25603 25604var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { 25605 version: "1.13.2", 25606 widgetEventPrefix: "slide", 25607 25608 options: { 25609 animate: false, 25610 classes: { 25611 "ui-slider": "ui-corner-all", 25612 "ui-slider-handle": "ui-corner-all", 25613 25614 // Note: ui-widget-header isn't the most fittingly semantic framework class for this 25615 // element, but worked best visually with a variety of themes 25616 "ui-slider-range": "ui-corner-all ui-widget-header" 25617 }, 25618 distance: 0, 25619 max: 100, 25620 min: 0, 25621 orientation: "horizontal", 25622 range: false, 25623 step: 1, 25624 value: 0, 25625 values: null, 25626 25627 // Callbacks 25628 change: null, 25629 slide: null, 25630 start: null, 25631 stop: null 25632 }, 25633 25634 // Number of pages in a slider 25635 // (how many times can you page up/down to go through the whole range) 25636 numPages: 5, 25637 25638 _create: function() { 25639 this._keySliding = false; 25640 this._mouseSliding = false; 25641 this._animateOff = true; 25642 this._handleIndex = null; 25643 this._detectOrientation(); 25644 this._mouseInit(); 25645 this._calculateNewMax(); 25646 25647 this._addClass( "ui-slider ui-slider-" + this.orientation, 25648 "ui-widget ui-widget-content" ); 25649 25650 this._refresh(); 25651 25652 this._animateOff = false; 25653 }, 25654 25655 _refresh: function() { 25656 this._createRange(); 25657 this._createHandles(); 25658 this._setupEvents(); 25659 this._refreshValue(); 25660 }, 25661 25662 _createHandles: function() { 25663 var i, handleCount, 25664 options = this.options, 25665 existingHandles = this.element.find( ".ui-slider-handle" ), 25666 handle = "<span tabindex='0'></span>", 25667 handles = []; 25668 25669 handleCount = ( options.values && options.values.length ) || 1; 25670 25671 if ( existingHandles.length > handleCount ) { 25672 existingHandles.slice( handleCount ).remove(); 25673 existingHandles = existingHandles.slice( 0, handleCount ); 25674 } 25675 25676 for ( i = existingHandles.length; i < handleCount; i++ ) { 25677 handles.push( handle ); 25678 } 25679 25680 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); 25681 25682 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); 25683 25684 this.handle = this.handles.eq( 0 ); 25685 25686 this.handles.each( function( i ) { 25687 $( this ) 25688 .data( "ui-slider-handle-index", i ) 25689 .attr( "tabIndex", 0 ); 25690 } ); 25691 }, 25692 25693 _createRange: function() { 25694 var options = this.options; 25695 25696 if ( options.range ) { 25697 if ( options.range === true ) { 25698 if ( !options.values ) { 25699 options.values = [ this._valueMin(), this._valueMin() ]; 25700 } else if ( options.values.length && options.values.length !== 2 ) { 25701 options.values = [ options.values[ 0 ], options.values[ 0 ] ]; 25702 } else if ( Array.isArray( options.values ) ) { 25703 options.values = options.values.slice( 0 ); 25704 } 25705 } 25706 25707 if ( !this.range || !this.range.length ) { 25708 this.range = $( "<div>" ) 25709 .appendTo( this.element ); 25710 25711 this._addClass( this.range, "ui-slider-range" ); 25712 } else { 25713 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); 25714 25715 // Handle range switching from true to min/max 25716 this.range.css( { 25717 "left": "", 25718 "bottom": "" 25719 } ); 25720 } 25721 if ( options.range === "min" || options.range === "max" ) { 25722 this._addClass( this.range, "ui-slider-range-" + options.range ); 25723 } 25724 } else { 25725 if ( this.range ) { 25726 this.range.remove(); 25727 } 25728 this.range = null; 25729 } 25730 }, 25731 25732 _setupEvents: function() { 25733 this._off( this.handles ); 25734 this._on( this.handles, this._handleEvents ); 25735 this._hoverable( this.handles ); 25736 this._focusable( this.handles ); 25737 }, 25738 25739 _destroy: function() { 25740 this.handles.remove(); 25741 if ( this.range ) { 25742 this.range.remove(); 25743 } 25744 25745 this._mouseDestroy(); 25746 }, 25747 25748 _mouseCapture: function( event ) { 25749 var position, normValue, distance, closestHandle, index, allowed, offset, mou
vendor: 22,163 bytes, lines 25749-26575
25749seOverHandle, 25750 that = this, 25751 o = this.options; 25752 25753 if ( o.disabled ) { 25754 return false; 25755 } 25756 25757 this.elementSize = { 25758 width: this.element.outerWidth(), 25759 height: this.element.outerHeight() 25760 }; 25761 this.elementOffset = this.element.offset(); 25762 25763 position = { x: event.pageX, y: event.pageY }; 25764 normValue = this._normValueFromMouse( position ); 25765 distance = this._valueMax() - this._valueMin() + 1; 25766 this.handles.each( function( i ) { 25767 var thisDistance = Math.abs( normValue - that.values( i ) ); 25768 if ( ( distance > thisDistance ) || 25769 ( distance === thisDistance && 25770 ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { 25771 distance = thisDistance; 25772 closestHandle = $( this ); 25773 index = i; 25774 } 25775 } ); 25776 25777 allowed = this._start( event, index ); 25778 if ( allowed === false ) { 25779 return false; 25780 } 25781 this._mouseSliding = true; 25782 25783 this._handleIndex = index; 25784 25785 this._addClass( closestHandle, null, "ui-state-active" ); 25786 closestHandle.trigger( "focus" ); 25787 25788 offset = closestHandle.offset(); 25789 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); 25790 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { 25791 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), 25792 top: event.pageY - offset.top - 25793 ( closestHandle.height() / 2 ) - 25794 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - 25795 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + 25796 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) 25797 }; 25798 25799 if ( !this.handles.hasClass( "ui-state-hover" ) ) { 25800 this._slide( event, index, normValue ); 25801 } 25802 this._animateOff = true; 25803 return true; 25804 }, 25805 25806 _mouseStart: function() { 25807 return true; 25808 }, 25809 25810 _mouseDrag: function( event ) { 25811 var position = { x: event.pageX, y: event.pageY }, 25812 normValue = this._normValueFromMouse( position ); 25813 25814 this._slide( event, this._handleIndex, normValue ); 25815 25816 return false; 25817 }, 25818 25819 _mouseStop: function( event ) { 25820 this._removeClass( this.handles, null, "ui-state-active" ); 25821 this._mouseSliding = false; 25822 25823 this._stop( event, this._handleIndex ); 25824 this._change( event, this._handleIndex ); 25825 25826 this._handleIndex = null; 25827 this._clickOffset = null; 25828 this._animateOff = false; 25829 25830 return false; 25831 }, 25832 25833 _detectOrientation: function() { 25834 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; 25835 }, 25836 25837 _normValueFromMouse: function( position ) { 25838 var pixelTotal, 25839 pixelMouse, 25840 percentMouse, 25841 valueTotal, 25842 valueMouse; 25843 25844 if ( this.orientation === "horizontal" ) { 25845 pixelTotal = this.elementSize.width; 25846 pixelMouse = position.x - this.elementOffset.left - 25847 ( this._clickOffset ? this._clickOffset.left : 0 ); 25848 } else { 25849 pixelTotal = this.elementSize.height; 25850 pixelMouse = position.y - this.elementOffset.top - 25851 ( this._clickOffset ? this._clickOffset.top : 0 ); 25852 } 25853 25854 percentMouse = ( pixelMouse / pixelTotal ); 25855 if ( percentMouse > 1 ) { 25856 percentMouse = 1; 25857 } 25858 if ( percentMouse < 0 ) { 25859 percentMouse = 0; 25860 } 25861 if ( this.orientation === "vertical" ) { 25862 percentMouse = 1 - percentMouse; 25863 } 25864 25865 valueTotal = this._valueMax() - this._valueMin(); 25866 valueMouse = this._valueMin() + percentMouse * valueTotal; 25867 25868 return this._trimAlignValue( valueMouse ); 25869 }, 25870 25871 _uiHash: function( index, value, values ) { 25872 var uiHash = { 25873 handle: this.handles[ index ], 25874 handleIndex: index, 25875 value: value !== undefined ? value : this.value() 25876 }; 25877 25878 if ( this._hasMultipleValues() ) { 25879 uiHash.value = value !== undefined ? value : this.values( index ); 25880 uiHash.values = values || this.values(); 25881 } 25882 25883 return uiHash; 25884 }, 25885 25886 _hasMultipleValues: function() { 25887 return this.options.values && this.options.values.length; 25888 }, 25889 25890 _start: function( event, index ) { 25891 return this._trigger( "start", event, this._uiHash( index ) ); 25892 }, 25893 25894 _slide: function( event, index, newVal ) { 25895 var allowed, otherVal, 25896 currentValue = this.value(), 25897 newValues = this.values(); 25898 25899 if ( this._hasMultipleValues() ) { 25900 otherVal = this.values( index ? 0 : 1 ); 25901 currentValue = this.values( index ); 25902 25903 if ( this.options.values.length === 2 && this.options.range === true ) { 25904 newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); 25905 } 25906 25907 newValues[ index ] = newVal; 25908 } 25909 25910 if ( newVal === currentValue ) { 25911 return; 25912 } 25913 25914 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); 25915 25916 // A slide can be canceled by returning false from the slide callback 25917 if ( allowed === false ) { 25918 return; 25919 } 25920 25921 if ( this._hasMultipleValues() ) { 25922 this.values( index, newVal ); 25923 } else { 25924 this.value( newVal ); 25925 } 25926 }, 25927 25928 _stop: function( event, index ) { 25929 this._trigger( "stop", event, this._uiHash( index ) ); 25930 }, 25931 25932 _change: function( event, index ) { 25933 if ( !this._keySliding && !this._mouseSliding ) { 25934 25935 //store the last changed value index for reference when handles overlap 25936 this._lastChangedValue = index; 25937 this._trigger( "change", event, this._uiHash( index ) ); 25938 } 25939 }, 25940 25941 value: function( newValue ) { 25942 if ( arguments.length ) { 25943 this.options.value = this._trimAlignValue( newValue ); 25944 this._refreshValue(); 25945 this._change( null, 0 ); 25946 return; 25947 } 25948 25949 return this._value(); 25950 }, 25951 25952 values: function( index, newValue ) { 25953 var vals, 25954 newValues, 25955 i; 25956 25957 if ( arguments.length > 1 ) { 25958 this.options.values[ index ] = this._trimAlignValue( newValue ); 25959 this._refreshValue(); 25960 this._change( null, index ); 25961 return; 25962 } 25963 25964 if ( arguments.length ) { 25965 if ( Array.isArray( arguments[ 0 ] ) ) { 25966 vals = this.options.values; 25967 newValues = arguments[ 0 ]; 25968 for ( i = 0; i < vals.length; i += 1 ) { 25969 vals[ i ] = this._trimAlignValue( newValues[ i ] ); 25970 this._change( null, i ); 25971 } 25972 this._refreshValue(); 25973 } else { 25974 if ( this._hasMultipleValues() ) { 25975 return this._values( index ); 25976 } else { 25977 return this.value(); 25978 } 25979 } 25980 } else { 25981 return this._values(); 25982 } 25983 }, 25984 25985 _setOption: function( key, value ) { 25986 var i, 25987 valsLength = 0; 25988 25989 if ( key === "range" && this.options.range === true ) { 25990 if ( value === "min" ) { 25991 this.options.value = this._values( 0 ); 25992 this.options.values = null; 25993 } else if ( value === "max" ) { 25994 this.options.value = this._values( this.options.values.length - 1 ); 25995 this.options.values = null; 25996 } 25997 } 25998 25999 if ( Array.isArray( this.options.values ) ) { 26000 valsLength = this.options.values.length; 26001 } 26002 26003 this._super( key, value ); 26004 26005 switch ( key ) { 26006 case "orientation": 26007 this._detectOrientation(); 26008 this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) 26009 ._addClass( "ui-slider-" + this.orientation ); 26010 this._refreshValue(); 26011 if ( this.options.range ) { 26012 this._refreshRange( value ); 26013 } 26014 26015 // Reset positioning from previous orientation 26016 this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); 26017 break; 26018 case "value": 26019 this._animateOff = true; 26020 this._refreshValue(); 26021 this._change( null, 0 ); 26022 this._animateOff = false; 26023 break; 26024 case "values": 26025 this._animateOff = true; 26026 this._refreshValue(); 26027 26028 // Start from the last handle to prevent unreachable handles (#9046) 26029 for ( i = valsLength - 1; i >= 0; i-- ) { 26030 this._change( null, i ); 26031 } 26032 this._animateOff = false; 26033 break; 26034 case "step": 26035 case "min": 26036 case "max": 26037 this._animateOff = true; 26038 this._calculateNewMax(); 26039 this._refreshValue(); 26040 this._animateOff = false; 26041 break; 26042 case "range": 26043 this._animateOff = true; 26044 this._refresh(); 26045 this._animateOff = false; 26046 break; 26047 } 26048 }, 26049 26050 _setOptionDisabled: function( value ) { 26051 this._super( value ); 26052 26053 this._toggleClass( null, "ui-state-disabled", !!value ); 26054 }, 26055 26056 //internal value getter 26057 // _value() returns value trimmed by min and max, aligned by step 26058 _value: function() { 26059 var val = this.options.value; 26060 val = this._trimAlignValue( val ); 26061 26062 return val; 26063 }, 26064 26065 //internal values getter 26066 // _values() returns array of values trimmed by min and max, aligned by step 26067 // _values( index ) returns single value trimmed by min and max, aligned by step 26068 _values: function( index ) { 26069 var val, 26070 vals, 26071 i; 26072 26073 if ( arguments.length ) { 26074 val = this.options.values[ index ]; 26075 val = this._trimAlignValue( val ); 26076 26077 return val; 26078 } else if ( this._hasMultipleValues() ) { 26079 26080 // .slice() creates a copy of the array 26081 // this copy gets trimmed by min and max and then returned 26082 vals = this.options.values.slice(); 26083 for ( i = 0; i < vals.length; i += 1 ) { 26084 vals[ i ] = this._trimAlignValue( vals[ i ] ); 26085 } 26086 26087 return vals; 26088 } else { 26089 return []; 26090 } 26091 }, 26092 26093 // Returns the step-aligned value that val is closest to, between (inclusive) min and max 26094 _trimAlignValue: function( val ) { 26095 if ( val <= this._valueMin() ) { 26096 return this._valueMin(); 26097 } 26098 if ( val >= this._valueMax() ) { 26099 return this._valueMax(); 26100 } 26101 var step = ( this.options.step > 0 ) ? this.options.step : 1, 26102 valModStep = ( val - this._valueMin() ) % step, 26103 alignValue = val - valModStep; 26104 26105 if ( Math.abs( valModStep ) * 2 >= step ) { 26106 alignValue += ( valModStep > 0 ) ? step : ( -step ); 26107 } 26108 26109 // Since JavaScript has problems with large floats, round 26110 // the final value to 5 digits after the decimal point (see #4124) 26111 return parseFloat( alignValue.toFixed( 5 ) ); 26112 }, 26113 26114 _calculateNewMax: function() { 26115 var max = this.options.max, 26116 min = this._valueMin(), 26117 step = this.options.step, 26118 aboveMin = Math.round( ( max - min ) / step ) * step; 26119 max = aboveMin + min; 26120 if ( max > this.options.max ) { 26121 26122 //If max is not divisible by step, rounding off may increase its value 26123 max -= step; 26124 } 26125 this.max = parseFloat( max.toFixed( this._precision() ) ); 26126 }, 26127 26128 _precision: function() { 26129 var precision = this._precisionOf( this.options.step ); 26130 if ( this.options.min !== null ) { 26131 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 26132 } 26133 return precision; 26134 }, 26135 26136 _precisionOf: function( num ) { 26137 var str = num.toString(), 26138 decimal = str.indexOf( "." ); 26139 return decimal === -1 ? 0 : str.length - decimal - 1; 26140 }, 26141 26142 _valueMin: function() { 26143 return this.options.min; 26144 }, 26145 26146 _valueMax: function() { 26147 return this.max; 26148 }, 26149 26150 _refreshRange: function( orientation ) { 26151 if ( orientation === "vertical" ) { 26152 this.range.css( { "width": "", "left": "" } ); 26153 } 26154 if ( orientation === "horizontal" ) { 26155 this.range.css( { "height": "", "bottom": "" } ); 26156 } 26157 }, 26158 26159 _refreshValue: function() { 26160 var lastValPercent, valPercent, value, valueMin, valueMax, 26161 oRange = this.options.range, 26162 o = this.options, 26163 that = this, 26164 animate = ( !this._animateOff ) ? o.animate : false, 26165 _set = {}; 26166 26167 if ( this._hasMultipleValues() ) { 26168 this.handles.each( function( i ) { 26169 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - 26170 that._valueMin() ) * 100; 26171 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 26172 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 26173 if ( that.options.range === true ) { 26174 if ( that.orientation === "horizontal" ) { 26175 if ( i === 0 ) { 26176 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26177 left: valPercent + "%" 26178 }, o.animate ); 26179 } 26180 if ( i === 1 ) { 26181 that.range[ animate ? "animate" : "css" ]( { 26182 width: ( valPercent - lastValPercent ) + "%" 26183 }, { 26184 queue: false, 26185 duration: o.animate 26186 } ); 26187 } 26188 } else { 26189 if ( i === 0 ) { 26190 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26191 bottom: ( valPercent ) + "%" 26192 }, o.animate ); 26193 } 26194 if ( i === 1 ) { 26195 that.range[ animate ? "animate" : "css" ]( { 26196 height: ( valPercent - lastValPercent ) + "%" 26197 }, { 26198 queue: false, 26199 duration: o.animate 26200 } ); 26201 } 26202 } 26203 } 26204 lastValPercent = valPercent; 26205 } ); 26206 } else { 26207 value = this.value(); 26208 valueMin = this._valueMin(); 26209 valueMax = this._valueMax(); 26210 valPercent = ( valueMax !== valueMin ) ? 26211 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : 26212 0; 26213 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; 26214 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); 26215 26216 if ( oRange === "min" && this.orientation === "horizontal" ) { 26217 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26218 width: valPercent + "%" 26219 }, o.animate ); 26220 } 26221 if ( oRange === "max" && this.orientation === "horizontal" ) { 26222 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26223 width: ( 100 - valPercent ) + "%" 26224 }, o.animate ); 26225 } 26226 if ( oRange === "min" && this.orientation === "vertical" ) { 26227 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26228 height: valPercent + "%" 26229 }, o.animate ); 26230 } 26231 if ( oRange === "max" && this.orientation === "vertical" ) { 26232 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { 26233 height: ( 100 - valPercent ) + "%" 26234 }, o.animate ); 26235 } 26236 } 26237 }, 26238 26239 _handleEvents: { 26240 keydown: function( event ) { 26241 var allowed, curVal, newVal, step, 26242 index = $( event.target ).data( "ui-slider-handle-index" ); 26243 26244 switch ( event.keyCode ) { 26245 case $.ui.keyCode.HOME: 26246 case $.ui.keyCode.END: 26247 case $.ui.keyCode.PAGE_UP: 26248 case $.ui.keyCode.PAGE_DOWN: 26249 case $.ui.keyCode.UP: 26250 case $.ui.keyCode.RIGHT: 26251 case $.ui.keyCode.DOWN: 26252 case $.ui.keyCode.LEFT: 26253 event.preventDefault(); 26254 if ( !this._keySliding ) { 26255 this._keySliding = true; 26256 this._addClass( $( event.target ), null, "ui-state-active" ); 26257 allowed = this._start( event, index ); 26258 if ( allowed === false ) { 26259 return; 26260 } 26261 } 26262 break; 26263 } 26264 26265 step = this.options.step; 26266 if ( this._hasMultipleValues() ) { 26267 curVal = newVal = this.values( index ); 26268 } else { 26269 curVal = newVal = this.value(); 26270 } 26271 26272 switch ( event.keyCode ) { 26273 case $.ui.keyCode.HOME: 26274 newVal = this._valueMin(); 26275 break; 26276 case $.ui.keyCode.END: 26277 newVal = this._valueMax(); 26278 break; 26279 case $.ui.keyCode.PAGE_UP: 26280 newVal = this._trimAlignValue( 26281 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) 26282 ); 26283 break; 26284 case $.ui.keyCode.PAGE_DOWN: 26285 newVal = this._trimAlignValue( 26286 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); 26287 break; 26288 case $.ui.keyCode.UP: 26289 case $.ui.keyCode.RIGHT: 26290 if ( curVal === this._valueMax() ) { 26291 return; 26292 } 26293 newVal = this._trimAlignValue( curVal + step ); 26294 break; 26295 case $.ui.keyCode.DOWN: 26296 case $.ui.keyCode.LEFT: 26297 if ( curVal === this._valueMin() ) { 26298 return; 26299 } 26300 newVal = this._trimAlignValue( curVal - step ); 26301 break; 26302 } 26303 26304 this._slide( event, index, newVal ); 26305 }, 26306 keyup: function( event ) { 26307 var index = $( event.target ).data( "ui-slider-handle-index" ); 26308 26309 if ( this._keySliding ) { 26310 this._keySliding = false; 26311 this._stop( event, index ); 26312 this._change( event, index ); 26313 this._removeClass( $( event.target ), null, "ui-state-active" ); 26314 } 26315 } 26316 } 26317} ); 26318 26319 26320/*! 26321 * jQuery UI Sortable 1.13.2 26322 * http://jqueryui.com 26323 * 26324 * Copyright jQuery Foundation and other contributors 26325 * Released under the MIT license. 26326 * http://jquery.org/license 26327 */ 26328 26329//>>label: Sortable 26330//>>group: Interactions 26331//>>description: Enables items in a list to be sorted using the mouse. 26332//>>docs: http://api.jqueryui.com/sortable/ 26333//>>demos: http://jqueryui.com/sortable/ 26334//>>css.structure: ../../themes/base/sortable.css 26335 26336 26337var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { 26338 version: "1.13.2", 26339 widgetEventPrefix: "sort", 26340 ready: false, 26341 options: { 26342 appendTo: "parent", 26343 axis: false, 26344 connectWith: false, 26345 containment: false, 26346 cursor: "auto", 26347 cursorAt: false, 26348 dropOnEmpty: true, 26349 forcePlaceholderSize: false, 26350 forceHelperSize: false, 26351 grid: false, 26352 handle: false, 26353 helper: "original", 26354 items: "> *", 26355 opacity: false, 26356 placeholder: false, 26357 revert: false, 26358 scroll: true, 26359 scrollSensitivity: 20, 26360 scrollSpeed: 20, 26361 scope: "default", 26362 tolerance: "intersect", 26363 zIndex: 1000, 26364 26365 // Callbacks 26366 activate: null, 26367 beforeStop: null, 26368 change: null, 26369 deactivate: null, 26370 out: null, 26371 over: null, 26372 receive: null, 26373 remove: null, 26374 sort: null, 26375 start: null, 26376 stop: null, 26377 update: null 26378 }, 26379 26380 _isOverAxis: function( x, reference, size ) { 26381 return ( x >= reference ) && ( x < ( reference + size ) ); 26382 }, 26383 26384 _isFloating: function( item ) { 26385 return ( /left|right/ ).test( item.css( "float" ) ) || 26386 ( /inline|table-cell/ ).test( item.css( "display" ) ); 26387 }, 26388 26389 _create: function() { 26390 this.containerCache = {}; 26391 this._addClass( "ui-sortable" ); 26392 26393 //Get the items 26394 this.refresh(); 26395 26396 //Let's determine the parent's offset 26397 this.offset = this.element.offset(); 26398 26399 //Initialize mouse events for interaction 26400 this._mouseInit(); 26401 26402 this._setHandleClassName(); 26403 26404 //We're ready to go 26405 this.ready = true; 26406 26407 }, 26408 26409 _setOption: function( key, value ) { 26410 this._super( key, value ); 26411 26412 if ( key === "handle" ) { 26413 this._setHandleClassName(); 26414 } 26415 }, 26416 26417 _setHandleClassName: function() { 26418 var that = this; 26419 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); 26420 $.each( this.items, function() { 26421 that._addClass( 26422 this.instance.options.handle ? 26423 this.item.find( this.instance.options.handle ) : 26424 this.item, 26425 "ui-sortable-handle" 26426 ); 26427 } ); 26428 }, 26429 26430 _destroy: function() { 26431 this._mouseDestroy(); 26432 26433 for ( var i = this.items.length - 1; i >= 0; i-- ) { 26434 this.items[ i ].item.removeData( this.widgetName + "-item" ); 26435 } 26436 26437 return this; 26438 }, 26439 26440 _mouseCapture: function( event, overrideHandle ) { 26441 var currentItem = null, 26442 validHandle = false, 26443 that = this; 26444 26445 if ( this.reverting ) { 26446 return false; 26447 } 26448 26449 if ( this.options.disabled || this.options.type === "static" ) { 26450 return false; 26451 } 26452 26453 //We have to refresh the items data once first 26454 this._refreshItems( event ); 26455 26456 //Find out if the clicked node (or one of its parents) is a actual item in this.items 26457 $( event.target ).parents().each( function() { 26458 if ( $.data( this, that.widgetName + "-item" ) === that ) { 26459 currentItem = $( this ); 26460 return false; 26461 } 26462 } ); 26463 if ( $.data( event.target, that.widgetName + "-item" ) === that ) { 26464 currentItem = $( event.target ); 26465 } 26466 26467 if ( !currentItem ) { 26468 return false; 26469 } 26470 if ( this.options.handle && !overrideHandle ) { 26471 $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { 26472 if ( this === event.target ) { 26473 validHandle = true; 26474 } 26475 } ); 26476 if ( !validHandle ) { 26477 return false; 26478 } 26479 } 26480 26481 this.currentItem = currentItem; 26482 this._removeCurrentsFromItems(); 26483 return true; 26484 26485 }, 26486 26487 _mouseStart: function( event, overrideHandle, noActivation ) { 26488 26489 var i, body, 26490 o = this.options; 26491 26492 this.currentContainer = this; 26493 26494 //We only need to call refreshPositions, because the refreshItems call has been moved to 26495 // mouseCapture 26496 this.refreshPositions(); 26497 26498 //Prepare the dragged items parent 26499 this.appendTo = $( o.appendTo !== "parent" ? 26500 o.appendTo : 26501 this.currentItem.parent() ); 26502 26503 //Create and append the visible helper 26504 this.helper = this._createHelper( event ); 26505 26506 //Cache the helper size 26507 this._cacheHelperProportions(); 26508 26509 /* 26510 * - Position generation - 26511 * This block generates everything position related - it's the core of draggables. 26512 */ 26513 26514 //Cache the margins of the original element 26515 this._cacheMargins(); 26516 26517 //The element's absolute position on the page minus margins 26518 this.offset = this.currentItem.offset(); 26519 this.offset = { 26520 top: this.offset.top - this.margins.top, 26521 left: this.offset.left - this.margins.left 26522 }; 26523 26524 $.extend( this.offset, { 26525 click: { //Where the click happened, relative to the element 26526 left: event.pageX - this.offset.left, 26527 top: event.pageY - this.offset.top 26528 }, 26529 26530 // This is a relative to absolute position minus the actual position calculation - 26531 // only used for relative positioned helper 26532 relative: this._getRelativeOffset() 26533 } ); 26534 26535 // After we get the helper offset, but before we get the parent offset we can 26536 // change the helper's position to absolute 26537 // TODO: Still need to figure out a way to make relative sorting possible 26538 this.helper.css( "position", "absolute" ); 26539 this.cssPosition = this.helper.css( "position" ); 26540 26541 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 26542 if ( o.cursorAt ) { 26543 this._adjustOffsetFromHelper( o.cursorAt ); 26544 } 26545 26546 //Cache the former DOM position 26547 this.domPosition = { 26548 prev: this.currentItem.prev()[ 0 ], 26549 parent: this.currentItem.parent()[ 0 ] 26550 }; 26551 26552 // If the helper is not the original, hide the original so it's not playing any role during 26553 // the drag, won't cause anything bad this way 26554 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 26555 this.currentItem.hide(); 26556 } 26557 26558 //Create the placeholder 26559 this._createPlaceholder(); 26560 26561 //Get the next scrolling parent 26562 this.scrollParent = this.placeholder.scrollParent(); 26563 26564 $.extend( this.offset, { 26565 parent: this._getParentOffset() 26566 } ); 26567 26568 //Set a containment if given in the options 26569 if ( o.containment ) { 26570 this._setContainment(); 26571 } 26572 26573 if ( o.cursor && o.cursor !== "auto" ) { // cursor option 26574 body = this.document.find( "body" ); 26575
vendor: 10,284 bytes, lines 26576-26936
26576 // Support: IE 26577 this.storedCursor = body.css( "cursor" ); 26578 body.css( "cursor", o.cursor ); 26579 26580 this.storedStylesheet = 26581 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); 26582 } 26583 26584 // We need to make sure to grab the zIndex before setting the 26585 // opacity, because setting the opacity to anything lower than 1 26586 // causes the zIndex to change from "auto" to 0. 26587 if ( o.zIndex ) { // zIndex option 26588 if ( this.helper.css( "zIndex" ) ) { 26589 this._storedZIndex = this.helper.css( "zIndex" ); 26590 } 26591 this.helper.css( "zIndex", o.zIndex ); 26592 } 26593 26594 if ( o.opacity ) { // opacity option 26595 if ( this.helper.css( "opacity" ) ) { 26596 this._storedOpacity = this.helper.css( "opacity" ); 26597 } 26598 this.helper.css( "opacity", o.opacity ); 26599 } 26600 26601 //Prepare scrolling 26602 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 26603 this.scrollParent[ 0 ].tagName !== "HTML" ) { 26604 this.overflowOffset = this.scrollParent.offset(); 26605 } 26606 26607 //Call callbacks 26608 this._trigger( "start", event, this._uiHash() ); 26609 26610 //Recache the helper size 26611 if ( !this._preserveHelperProportions ) { 26612 this._cacheHelperProportions(); 26613 } 26614 26615 //Post "activate" events to possible containers 26616 if ( !noActivation ) { 26617 for ( i = this.containers.length - 1; i >= 0; i-- ) { 26618 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); 26619 } 26620 } 26621 26622 //Prepare possible droppables 26623 if ( $.ui.ddmanager ) { 26624 $.ui.ddmanager.current = this; 26625 } 26626 26627 if ( $.ui.ddmanager && !o.dropBehaviour ) { 26628 $.ui.ddmanager.prepareOffsets( this, event ); 26629 } 26630 26631 this.dragging = true; 26632 26633 this._addClass( this.helper, "ui-sortable-helper" ); 26634 26635 //Move the helper, if needed 26636 if ( !this.helper.parent().is( this.appendTo ) ) { 26637 this.helper.detach().appendTo( this.appendTo ); 26638 26639 //Update position 26640 this.offset.parent = this._getParentOffset(); 26641 } 26642 26643 //Generate the original position 26644 this.position = this.originalPosition = this._generatePosition( event ); 26645 this.originalPageX = event.pageX; 26646 this.originalPageY = event.pageY; 26647 this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); 26648 26649 this._mouseDrag( event ); 26650 26651 return true; 26652 26653 }, 26654 26655 _scroll: function( event ) { 26656 var o = this.options, 26657 scrolled = false; 26658 26659 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 26660 this.scrollParent[ 0 ].tagName !== "HTML" ) { 26661 26662 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - 26663 event.pageY < o.scrollSensitivity ) { 26664 this.scrollParent[ 0 ].scrollTop = 26665 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 26666 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { 26667 this.scrollParent[ 0 ].scrollTop = 26668 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 26669 } 26670 26671 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - 26672 event.pageX < o.scrollSensitivity ) { 26673 this.scrollParent[ 0 ].scrollLeft = scrolled = 26674 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 26675 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { 26676 this.scrollParent[ 0 ].scrollLeft = scrolled = 26677 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 26678 } 26679 26680 } else { 26681 26682 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { 26683 scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); 26684 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < 26685 o.scrollSensitivity ) { 26686 scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); 26687 } 26688 26689 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { 26690 scrolled = this.document.scrollLeft( 26691 this.document.scrollLeft() - o.scrollSpeed 26692 ); 26693 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < 26694 o.scrollSensitivity ) { 26695 scrolled = this.document.scrollLeft( 26696 this.document.scrollLeft() + o.scrollSpeed 26697 ); 26698 } 26699 26700 } 26701 26702 return scrolled; 26703 }, 26704 26705 _mouseDrag: function( event ) { 26706 var i, item, itemElement, intersection, 26707 o = this.options; 26708 26709 //Compute the helpers position 26710 this.position = this._generatePosition( event ); 26711 this.positionAbs = this._convertPositionTo( "absolute" ); 26712 26713 //Set the helper position 26714 if ( !this.options.axis || this.options.axis !== "y" ) { 26715 this.helper[ 0 ].style.left = this.position.left + "px"; 26716 } 26717 if ( !this.options.axis || this.options.axis !== "x" ) { 26718 this.helper[ 0 ].style.top = this.position.top + "px"; 26719 } 26720 26721 //Do scrolling 26722 if ( o.scroll ) { 26723 if ( this._scroll( event ) !== false ) { 26724 26725 //Update item positions used in position checks 26726 this._refreshItemPositions( true ); 26727 26728 if ( $.ui.ddmanager && !o.dropBehaviour ) { 26729 $.ui.ddmanager.prepareOffsets( this, event ); 26730 } 26731 } 26732 } 26733 26734 this.dragDirection = { 26735 vertical: this._getDragVerticalDirection(), 26736 horizontal: this._getDragHorizontalDirection() 26737 }; 26738 26739 //Rearrange 26740 for ( i = this.items.length - 1; i >= 0; i-- ) { 26741 26742 //Cache variables and intersection, continue if no intersection 26743 item = this.items[ i ]; 26744 itemElement = item.item[ 0 ]; 26745 intersection = this._intersectsWithPointer( item ); 26746 if ( !intersection ) { 26747 continue; 26748 } 26749 26750 // Only put the placeholder inside the current Container, skip all 26751 // items from other containers. This works because when moving 26752 // an item from one container to another the 26753 // currentContainer is switched before the placeholder is moved. 26754 // 26755 // Without this, moving items in "sub-sortables" can cause 26756 // the placeholder to jitter between the outer and inner container. 26757 if ( item.instance !== this.currentContainer ) { 26758 continue; 26759 } 26760 26761 // Cannot intersect with itself 26762 // no useless actions that have been done before 26763 // no action if the item moved is the parent of the item checked 26764 if ( itemElement !== this.currentItem[ 0 ] && 26765 this.placeholder[ intersection === 1 ? 26766 "next" : "prev" ]()[ 0 ] !== itemElement && 26767 !$.contains( this.placeholder[ 0 ], itemElement ) && 26768 ( this.options.type === "semi-dynamic" ? 26769 !$.contains( this.element[ 0 ], itemElement ) : 26770 true 26771 ) 26772 ) { 26773 26774 this.direction = intersection === 1 ? "down" : "up"; 26775 26776 if ( this.options.tolerance === "pointer" || 26777 this._intersectsWithSides( item ) ) { 26778 this._rearrange( event, item ); 26779 } else { 26780 break; 26781 } 26782 26783 this._trigger( "change", event, this._uiHash() ); 26784 break; 26785 } 26786 } 26787 26788 //Post events to containers 26789 this._contactContainers( event ); 26790 26791 //Interconnect with droppables 26792 if ( $.ui.ddmanager ) { 26793 $.ui.ddmanager.drag( this, event ); 26794 } 26795 26796 //Call callbacks 26797 this._trigger( "sort", event, this._uiHash() ); 26798 26799 this.lastPositionAbs = this.positionAbs; 26800 return false; 26801 26802 }, 26803 26804 _mouseStop: function( event, noPropagation ) { 26805 26806 if ( !event ) { 26807 return; 26808 } 26809 26810 //If we are using droppables, inform the manager about the drop 26811 if ( $.ui.ddmanager && !this.options.dropBehaviour ) { 26812 $.ui.ddmanager.drop( this, event ); 26813 } 26814 26815 if ( this.options.revert ) { 26816 var that = this, 26817 cur = this.placeholder.offset(), 26818 axis = this.options.axis, 26819 animation = {}; 26820 26821 if ( !axis || axis === "x" ) { 26822 animation.left = cur.left - this.offset.parent.left - this.margins.left + 26823 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 26824 0 : 26825 this.offsetParent[ 0 ].scrollLeft 26826 ); 26827 } 26828 if ( !axis || axis === "y" ) { 26829 animation.top = cur.top - this.offset.parent.top - this.margins.top + 26830 ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 26831 0 : 26832 this.offsetParent[ 0 ].scrollTop 26833 ); 26834 } 26835 this.reverting = true; 26836 $( this.helper ).animate( 26837 animation, 26838 parseInt( this.options.revert, 10 ) || 500, 26839 function() { 26840 that._clear( event ); 26841 } 26842 ); 26843 } else { 26844 this._clear( event, noPropagation ); 26845 } 26846 26847 return false; 26848 26849 }, 26850 26851 cancel: function() { 26852 26853 if ( this.dragging ) { 26854 26855 this._mouseUp( new $.Event( "mouseup", { target: null } ) ); 26856 26857 if ( this.options.helper === "original" ) { 26858 this.currentItem.css( this._storedCSS ); 26859 this._removeClass( this.currentItem, "ui-sortable-helper" ); 26860 } else { 26861 this.currentItem.show(); 26862 } 26863 26864 //Post deactivating events to containers 26865 for ( var i = this.containers.length - 1; i >= 0; i-- ) { 26866 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); 26867 if ( this.containers[ i ].containerCache.over ) { 26868 this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); 26869 this.containers[ i ].containerCache.over = 0; 26870 } 26871 } 26872 26873 } 26874 26875 if ( this.placeholder ) { 26876 26877 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 26878 // it unbinds ALL events from the original node! 26879 if ( this.placeholder[ 0 ].parentNode ) { 26880 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 26881 } 26882 if ( this.options.helper !== "original" && this.helper && 26883 this.helper[ 0 ].parentNode ) { 26884 this.helper.remove(); 26885 } 26886 26887 $.extend( this, { 26888 helper: null, 26889 dragging: false, 26890 reverting: false, 26891 _noFinalSort: null 26892 } ); 26893 26894 if ( this.domPosition.prev ) { 26895 $( this.domPosition.prev ).after( this.currentItem ); 26896 } else { 26897 $( this.domPosition.parent ).prepend( this.currentItem ); 26898 } 26899 } 26900 26901 return this; 26902 26903 }, 26904 26905 serialize: function( o ) { 26906 26907 var items = this._getItemsAsjQuery( o && o.connected ), 26908 str = []; 26909 o = o || {}; 26910 26911 $( items ).each( function() { 26912 var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) 26913 .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); 26914 if ( res ) { 26915 str.push( 26916 ( o.key || res[ 1 ] + "[]" ) + 26917 "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); 26918 } 26919 } ); 26920 26921 if ( !str.length && o.key ) { 26922 str.push( o.key + "=" ); 26923 } 26924 26925 return str.join( "&" ); 26926 26927 }, 26928 26929 toArray: function( o ) { 26930 26931 var items = this._getItemsAsjQuery( o && o.connected ), 26932 ret = []; 26933 26934 o = o || {}; 26935 26936 items.each( function() {
vendor: 9,873 bytes, lines 26937-27249
26937 ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); 26938 } ); 26939 return ret; 26940 26941 }, 26942 26943 /* Be careful with the following core functions */ 26944 _intersectsWith: function( item ) { 26945 26946 var x1 = this.positionAbs.left, 26947 x2 = x1 + this.helperProportions.width, 26948 y1 = this.positionAbs.top, 26949 y2 = y1 + this.helperProportions.height, 26950 l = item.left, 26951 r = l + item.width, 26952 t = item.top, 26953 b = t + item.height, 26954 dyClick = this.offset.click.top, 26955 dxClick = this.offset.click.left, 26956 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && 26957 ( y1 + dyClick ) < b ), 26958 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && 26959 ( x1 + dxClick ) < r ), 26960 isOverElement = isOverElementHeight && isOverElementWidth; 26961 26962 if ( this.options.tolerance === "pointer" || 26963 this.options.forcePointerForContainers || 26964 ( this.options.tolerance !== "pointer" && 26965 this.helperProportions[ this.floating ? "width" : "height" ] > 26966 item[ this.floating ? "width" : "height" ] ) 26967 ) { 26968 return isOverElement; 26969 } else { 26970 26971 return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half 26972 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half 26973 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half 26974 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half 26975 26976 } 26977 }, 26978 26979 _intersectsWithPointer: function( item ) { 26980 var verticalDirection, horizontalDirection, 26981 isOverElementHeight = ( this.options.axis === "x" ) || 26982 this._isOverAxis( 26983 this.positionAbs.top + this.offset.click.top, item.top, item.height ), 26984 isOverElementWidth = ( this.options.axis === "y" ) || 26985 this._isOverAxis( 26986 this.positionAbs.left + this.offset.click.left, item.left, item.width ), 26987 isOverElement = isOverElementHeight && isOverElementWidth; 26988 26989 if ( !isOverElement ) { 26990 return false; 26991 } 26992 26993 verticalDirection = this.dragDirection.vertical; 26994 horizontalDirection = this.dragDirection.horizontal; 26995 26996 return this.floating ? 26997 ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : 26998 ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); 26999 27000 }, 27001 27002 _intersectsWithSides: function( item ) { 27003 27004 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + 27005 this.offset.click.top, item.top + ( item.height / 2 ), item.height ), 27006 isOverRightHalf = this._isOverAxis( this.positionAbs.left + 27007 this.offset.click.left, item.left + ( item.width / 2 ), item.width ), 27008 verticalDirection = this.dragDirection.vertical, 27009 horizontalDirection = this.dragDirection.horizontal; 27010 27011 if ( this.floating && horizontalDirection ) { 27012 return ( ( horizontalDirection === "right" && isOverRightHalf ) || 27013 ( horizontalDirection === "left" && !isOverRightHalf ) ); 27014 } else { 27015 return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || 27016 ( verticalDirection === "up" && !isOverBottomHalf ) ); 27017 } 27018 27019 }, 27020 27021 _getDragVerticalDirection: function() { 27022 var delta = this.positionAbs.top - this.lastPositionAbs.top; 27023 return delta !== 0 && ( delta > 0 ? "down" : "up" ); 27024 }, 27025 27026 _getDragHorizontalDirection: function() { 27027 var delta = this.positionAbs.left - this.lastPositionAbs.left; 27028 return delta !== 0 && ( delta > 0 ? "right" : "left" ); 27029 }, 27030 27031 refresh: function( event ) { 27032 this._refreshItems( event ); 27033 this._setHandleClassName(); 27034 this.refreshPositions(); 27035 return this; 27036 }, 27037 27038 _connectWith: function() { 27039 var options = this.options; 27040 return options.connectWith.constructor === String ? 27041 [ options.connectWith ] : 27042 options.connectWith; 27043 }, 27044 27045 _getItemsAsjQuery: function( connected ) { 27046 27047 var i, j, cur, inst, 27048 items = [], 27049 queries = [], 27050 connectWith = this._connectWith(); 27051 27052 if ( connectWith && connected ) { 27053 for ( i = connectWith.length - 1; i >= 0; i-- ) { 27054 cur = $( connectWith[ i ], this.document[ 0 ] ); 27055 for ( j = cur.length - 1; j >= 0; j-- ) { 27056 inst = $.data( cur[ j ], this.widgetFullName ); 27057 if ( inst && inst !== this && !inst.options.disabled ) { 27058 queries.push( [ typeof inst.options.items === "function" ? 27059 inst.options.items.call( inst.element ) : 27060 $( inst.options.items, inst.element ) 27061 .not( ".ui-sortable-helper" ) 27062 .not( ".ui-sortable-placeholder" ), inst ] ); 27063 } 27064 } 27065 } 27066 } 27067 27068 queries.push( [ typeof this.options.items === "function" ? 27069 this.options.items 27070 .call( this.element, null, { options: this.options, item: this.currentItem } ) : 27071 $( this.options.items, this.element ) 27072 .not( ".ui-sortable-helper" ) 27073 .not( ".ui-sortable-placeholder" ), this ] ); 27074 27075 function addItems() { 27076 items.push( this ); 27077 } 27078 for ( i = queries.length - 1; i >= 0; i-- ) { 27079 queries[ i ][ 0 ].each( addItems ); 27080 } 27081 27082 return $( items ); 27083 27084 }, 27085 27086 _removeCurrentsFromItems: function() { 27087 27088 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); 27089 27090 this.items = $.grep( this.items, function( item ) { 27091 for ( var j = 0; j < list.length; j++ ) { 27092 if ( list[ j ] === item.item[ 0 ] ) { 27093 return false; 27094 } 27095 } 27096 return true; 27097 } ); 27098 27099 }, 27100 27101 _refreshItems: function( event ) { 27102 27103 this.items = []; 27104 this.containers = [ this ]; 27105 27106 var i, j, cur, inst, targetData, _queries, item, queriesLength, 27107 items = this.items, 27108 queries = [ [ typeof this.options.items === "function" ? 27109 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : 27110 $( this.options.items, this.element ), this ] ], 27111 connectWith = this._connectWith(); 27112 27113 //Shouldn't be run the first time through due to massive slow-down 27114 if ( connectWith && this.ready ) { 27115 for ( i = connectWith.length - 1; i >= 0; i-- ) { 27116 cur = $( connectWith[ i ], this.document[ 0 ] ); 27117 for ( j = cur.length - 1; j >= 0; j-- ) { 27118 inst = $.data( cur[ j ], this.widgetFullName ); 27119 if ( inst && inst !== this && !inst.options.disabled ) { 27120 queries.push( [ typeof inst.options.items === "function" ? 27121 inst.options.items 27122 .call( inst.element[ 0 ], event, { item: this.currentItem } ) : 27123 $( inst.options.items, inst.element ), inst ] ); 27124 this.containers.push( inst ); 27125 } 27126 } 27127 } 27128 } 27129 27130 for ( i = queries.length - 1; i >= 0; i-- ) { 27131 targetData = queries[ i ][ 1 ]; 27132 _queries = queries[ i ][ 0 ]; 27133 27134 for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { 27135 item = $( _queries[ j ] ); 27136 27137 // Data for target checking (mouse manager) 27138 item.data( this.widgetName + "-item", targetData ); 27139 27140 items.push( { 27141 item: item, 27142 instance: targetData, 27143 width: 0, height: 0, 27144 left: 0, top: 0 27145 } ); 27146 } 27147 } 27148 27149 }, 27150 27151 _refreshItemPositions: function( fast ) { 27152 var i, item, t, p; 27153 27154 for ( i = this.items.length - 1; i >= 0; i-- ) { 27155 item = this.items[ i ]; 27156 27157 //We ignore calculating positions of all connected containers when we're not over them 27158 if ( this.currentContainer && item.instance !== this.currentContainer && 27159 item.item[ 0 ] !== this.currentItem[ 0 ] ) { 27160 continue; 27161 } 27162 27163 t = this.options.toleranceElement ? 27164 $( this.options.toleranceElement, item.item ) : 27165 item.item; 27166 27167 if ( !fast ) { 27168 item.width = t.outerWidth(); 27169 item.height = t.outerHeight(); 27170 } 27171 27172 p = t.offset(); 27173 item.left = p.left; 27174 item.top = p.top; 27175 } 27176 }, 27177 27178 refreshPositions: function( fast ) { 27179 27180 // Determine whether items are being displayed horizontally 27181 this.floating = this.items.length ? 27182 this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : 27183 false; 27184 27185 // This has to be redone because due to the item being moved out/into the offsetParent, 27186 // the offsetParent's position will change 27187 if ( this.offsetParent && this.helper ) { 27188 this.offset.parent = this._getParentOffset(); 27189 } 27190 27191 this._refreshItemPositions( fast ); 27192 27193 var i, p; 27194 27195 if ( this.options.custom && this.options.custom.refreshContainers ) { 27196 this.options.custom.refreshContainers.call( this ); 27197 } else { 27198 for ( i = this.containers.length - 1; i >= 0; i-- ) { 27199 p = this.containers[ i ].element.offset(); 27200 this.containers[ i ].containerCache.left = p.left; 27201 this.containers[ i ].containerCache.top = p.top; 27202 this.containers[ i ].containerCache.width = 27203 this.containers[ i ].element.outerWidth(); 27204 this.containers[ i ].containerCache.height = 27205 this.containers[ i ].element.outerHeight(); 27206 } 27207 } 27208 27209 return this; 27210 }, 27211 27212 _createPlaceholder: function( that ) { 27213 that = that || this; 27214 var className, nodeName, 27215 o = that.options; 27216 27217 if ( !o.placeholder || o.placeholder.constructor === String ) { 27218 className = o.placeholder; 27219 nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); 27220 o.placeholder = { 27221 element: function() { 27222 27223 var element = $( "<" + nodeName + ">", that.document[ 0 ] ); 27224 27225 that._addClass( element, "ui-sortable-placeholder", 27226 className || that.currentItem[ 0 ].className ) 27227 ._removeClass( element, "ui-sortable-helper" ); 27228 27229 if ( nodeName === "tbody" ) { 27230 that._createTrPlaceholder( 27231 that.currentItem.find( "tr" ).eq( 0 ), 27232 $( "<tr>", that.document[ 0 ] ).appendTo( element ) 27233 ); 27234 } else if ( nodeName === "tr" ) { 27235 that._createTrPlaceholder( that.currentItem, element ); 27236 } else if ( nodeName === "img" ) { 27237 element.attr( "src", that.currentItem.attr( "src" ) ); 27238 } 27239 27240 if ( !className ) { 27241 element.css( "visibility", "hidden" ); 27242 } 27243 27244 return element; 27245 }, 27246 update: function( container, p ) { 27247 27248 // 1. If a className is set as 'placeholder option, we don't force sizes - 27249 // the class is responsible for that
vendor: 10,802 bytes, lines 27250-27564
27250 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a 27251 // class name is specified 27252 if ( className && !o.forcePlaceholderSize ) { 27253 return; 27254 } 27255 27256 // If the element doesn't have a actual height or width by itself (without 27257 // styles coming from a stylesheet), it receives the inline height and width 27258 // from the dragged item. Or, if it's a tbody or tr, it's going to have a height 27259 // anyway since we're populating them with <td>s above, but they're unlikely to 27260 // be the correct height on their own if the row heights are dynamic, so we'll 27261 // always assign the height of the dragged item given forcePlaceholderSize 27262 // is true. 27263 if ( !p.height() || ( o.forcePlaceholderSize && 27264 ( nodeName === "tbody" || nodeName === "tr" ) ) ) { 27265 p.height( 27266 that.currentItem.innerHeight() - 27267 parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - 27268 parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); 27269 } 27270 if ( !p.width() ) { 27271 p.width( 27272 that.currentItem.innerWidth() - 27273 parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - 27274 parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); 27275 } 27276 } 27277 }; 27278 } 27279 27280 //Create the placeholder 27281 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); 27282 27283 //Append it after the actual current item 27284 that.currentItem.after( that.placeholder ); 27285 27286 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) 27287 o.placeholder.update( that, that.placeholder ); 27288 27289 }, 27290 27291 _createTrPlaceholder: function( sourceTr, targetTr ) { 27292 var that = this; 27293 27294 sourceTr.children().each( function() { 27295 $( "<td> </td>", that.document[ 0 ] ) 27296 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) 27297 .appendTo( targetTr ); 27298 } ); 27299 }, 27300 27301 _contactContainers: function( event ) { 27302 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, 27303 floating, axis, 27304 innermostContainer = null, 27305 innermostIndex = null; 27306 27307 // Get innermost container that intersects with item 27308 for ( i = this.containers.length - 1; i >= 0; i-- ) { 27309 27310 // Never consider a container that's located within the item itself 27311 if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { 27312 continue; 27313 } 27314 27315 if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { 27316 27317 // If we've already found a container and it's more "inner" than this, then continue 27318 if ( innermostContainer && 27319 $.contains( 27320 this.containers[ i ].element[ 0 ], 27321 innermostContainer.element[ 0 ] ) ) { 27322 continue; 27323 } 27324 27325 innermostContainer = this.containers[ i ]; 27326 innermostIndex = i; 27327 27328 } else { 27329 27330 // container doesn't intersect. trigger "out" event if necessary 27331 if ( this.containers[ i ].containerCache.over ) { 27332 this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); 27333 this.containers[ i ].containerCache.over = 0; 27334 } 27335 } 27336 27337 } 27338 27339 // If no intersecting containers found, return 27340 if ( !innermostContainer ) { 27341 return; 27342 } 27343 27344 // Move the item into the container if it's not there already 27345 if ( this.containers.length === 1 ) { 27346 if ( !this.containers[ innermostIndex ].containerCache.over ) { 27347 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 27348 this.containers[ innermostIndex ].containerCache.over = 1; 27349 } 27350 } else { 27351 27352 // When entering a new container, we will find the item with the least distance and 27353 // append our item near it 27354 dist = 10000; 27355 itemWithLeastDistance = null; 27356 floating = innermostContainer.floating || this._isFloating( this.currentItem ); 27357 posProperty = floating ? "left" : "top"; 27358 sizeProperty = floating ? "width" : "height"; 27359 axis = floating ? "pageX" : "pageY"; 27360 27361 for ( j = this.items.length - 1; j >= 0; j-- ) { 27362 if ( !$.contains( 27363 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) 27364 ) { 27365 continue; 27366 } 27367 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { 27368 continue; 27369 } 27370 27371 cur = this.items[ j ].item.offset()[ posProperty ]; 27372 nearBottom = false; 27373 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { 27374 nearBottom = true; 27375 } 27376 27377 if ( Math.abs( event[ axis ] - cur ) < dist ) { 27378 dist = Math.abs( event[ axis ] - cur ); 27379 itemWithLeastDistance = this.items[ j ]; 27380 this.direction = nearBottom ? "up" : "down"; 27381 } 27382 } 27383 27384 //Check if dropOnEmpty is enabled 27385 if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { 27386 return; 27387 } 27388 27389 if ( this.currentContainer === this.containers[ innermostIndex ] ) { 27390 if ( !this.currentContainer.containerCache.over ) { 27391 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); 27392 this.currentContainer.containerCache.over = 1; 27393 } 27394 return; 27395 } 27396 27397 if ( itemWithLeastDistance ) { 27398 this._rearrange( event, itemWithLeastDistance, null, true ); 27399 } else { 27400 this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); 27401 } 27402 this._trigger( "change", event, this._uiHash() ); 27403 this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); 27404 this.currentContainer = this.containers[ innermostIndex ]; 27405 27406 //Update the placeholder 27407 this.options.placeholder.update( this.currentContainer, this.placeholder ); 27408 27409 //Update scrollParent 27410 this.scrollParent = this.placeholder.scrollParent(); 27411 27412 //Update overflowOffset 27413 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27414 this.scrollParent[ 0 ].tagName !== "HTML" ) { 27415 this.overflowOffset = this.scrollParent.offset(); 27416 } 27417 27418 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); 27419 this.containers[ innermostIndex ].containerCache.over = 1; 27420 } 27421 27422 }, 27423 27424 _createHelper: function( event ) { 27425 27426 var o = this.options, 27427 helper = typeof o.helper === "function" ? 27428 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : 27429 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); 27430 27431 //Add the helper to the DOM if that didn't happen already 27432 if ( !helper.parents( "body" ).length ) { 27433 this.appendTo[ 0 ].appendChild( helper[ 0 ] ); 27434 } 27435 27436 if ( helper[ 0 ] === this.currentItem[ 0 ] ) { 27437 this._storedCSS = { 27438 width: this.currentItem[ 0 ].style.width, 27439 height: this.currentItem[ 0 ].style.height, 27440 position: this.currentItem.css( "position" ), 27441 top: this.currentItem.css( "top" ), 27442 left: this.currentItem.css( "left" ) 27443 }; 27444 } 27445 27446 if ( !helper[ 0 ].style.width || o.forceHelperSize ) { 27447 helper.width( this.currentItem.width() ); 27448 } 27449 if ( !helper[ 0 ].style.height || o.forceHelperSize ) { 27450 helper.height( this.currentItem.height() ); 27451 } 27452 27453 return helper; 27454 27455 }, 27456 27457 _adjustOffsetFromHelper: function( obj ) { 27458 if ( typeof obj === "string" ) { 27459 obj = obj.split( " " ); 27460 } 27461 if ( Array.isArray( obj ) ) { 27462 obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; 27463 } 27464 if ( "left" in obj ) { 27465 this.offset.click.left = obj.left + this.margins.left; 27466 } 27467 if ( "right" in obj ) { 27468 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; 27469 } 27470 if ( "top" in obj ) { 27471 this.offset.click.top = obj.top + this.margins.top; 27472 } 27473 if ( "bottom" in obj ) { 27474 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; 27475 } 27476 }, 27477 27478 _getParentOffset: function() { 27479 27480 //Get the offsetParent and cache its position 27481 this.offsetParent = this.helper.offsetParent(); 27482 var po = this.offsetParent.offset(); 27483 27484 // This is a special case where we need to modify a offset calculated on start, since the 27485 // following happened: 27486 // 1. The position of the helper is absolute, so it's position is calculated based on the 27487 // next positioned parent 27488 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't 27489 // the document, which means that the scroll is included in the initial calculation of the 27490 // offset of the parent, and never recalculated upon drag 27491 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && 27492 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { 27493 po.left += this.scrollParent.scrollLeft(); 27494 po.top += this.scrollParent.scrollTop(); 27495 } 27496 27497 // This needs to be actually done for all browsers, since pageX/pageY includes this 27498 // information with an ugly IE fix 27499 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || 27500 ( this.offsetParent[ 0 ].tagName && 27501 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { 27502 po = { top: 0, left: 0 }; 27503 } 27504 27505 return { 27506 top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), 27507 left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) 27508 }; 27509 27510 }, 27511 27512 _getRelativeOffset: function() { 27513 27514 if ( this.cssPosition === "relative" ) { 27515 var p = this.currentItem.position(); 27516 return { 27517 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + 27518 this.scrollParent.scrollTop(), 27519 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + 27520 this.scrollParent.scrollLeft() 27521 }; 27522 } else { 27523 return { top: 0, left: 0 }; 27524 } 27525 27526 }, 27527 27528 _cacheMargins: function() { 27529 this.margins = { 27530 left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), 27531 top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) 27532 }; 27533 }, 27534 27535 _cacheHelperProportions: function() { 27536 this.helperProportions = { 27537 width: this.helper.outerWidth(), 27538 height: this.helper.outerHeight() 27539 }; 27540 }, 27541 27542 _setContainment: function() { 27543 27544 var ce, co, over, 27545 o = this.options; 27546 if ( o.containment === "parent" ) { 27547 o.containment = this.helper[ 0 ].parentNode; 27548 } 27549 if ( o.containment === "document" || o.containment === "window" ) { 27550 this.containment = [ 27551 0 - this.offset.relative.left - this.offset.parent.left, 27552 0 - this.offset.relative.top - this.offset.parent.top, 27553 o.containment === "document" ? 27554 this.document.width() : 27555 this.window.width() - this.helperProportions.width - this.margins.left, 27556 ( o.containment === "document" ? 27557 ( this.document.height() || document.body.parentNode.scrollHeight ) : 27558 this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight 27559 ) - this.helperProportions.height - this.margins.top 27560 ]; 27561 } 27562 27563 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { 27564 ce = $( o.containment )[ 0 ];
vendor: 2,294 bytes, lines 27565-27625
27565 co = $( o.containment ).offset(); 27566 over = ( $( ce ).css( "overflow" ) !== "hidden" ); 27567 27568 this.containment = [ 27569 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + 27570 ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, 27571 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + 27572 ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, 27573 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - 27574 ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - 27575 ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - 27576 this.helperProportions.width - this.margins.left, 27577 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - 27578 ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - 27579 ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - 27580 this.helperProportions.height - this.margins.top 27581 ]; 27582 } 27583 27584 }, 27585 27586 _convertPositionTo: function( d, pos ) { 27587 27588 if ( !pos ) { 27589 pos = this.position; 27590 } 27591 var mod = d === "absolute" ? 1 : -1, 27592 scroll = this.cssPosition === "absolute" && 27593 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27594 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 27595 this.offsetParent : 27596 this.scrollParent, 27597 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 27598 27599 return { 27600 top: ( 27601 27602 // The absolute mouse position 27603 pos.top + 27604 27605 // Only for relative positioned nodes: Relative offset from element to offset parent 27606 this.offset.relative.top * mod + 27607 27608 // The offsetParent's offset without borders (offset + border) 27609 this.offset.parent.top * mod - 27610 ( ( this.cssPosition === "fixed" ? 27611 -this.scrollParent.scrollTop() : 27612 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) 27613 ), 27614 left: ( 27615 27616 // The absolute mouse position 27617 pos.left + 27618 27619 // Only for relative positioned nodes: Relative offset from element to offset parent 27620 this.offset.relative.left * mod + 27621 27622 // The offsetParent's offset without borders (offset + border) 27623 this.offset.parent.left * mod - 27624 ( ( this.cssPosition === "fixed" ? 27625 -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 42,069 bytes, lines 27626-29139
27626 scroll.scrollLeft() ) * mod ) 27627 ) 27628 }; 27629 27630 }, 27631 27632 _generatePosition: function( event ) { 27633 27634 var top, left, 27635 o = this.options, 27636 pageX = event.pageX, 27637 pageY = event.pageY, 27638 scroll = this.cssPosition === "absolute" && 27639 !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27640 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? 27641 this.offsetParent : 27642 this.scrollParent, 27643 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 27644 27645 // This is another very weird special case that only happens for relative elements: 27646 // 1. If the css position is relative 27647 // 2. and the scroll parent is the document or similar to the offset parent 27648 // we have to refresh the relative offset during the scroll so there are no jumps 27649 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && 27650 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { 27651 this.offset.relative = this._getRelativeOffset(); 27652 } 27653 27654 /* 27655 * - Position constraining - 27656 * Constrain the position to a mix of grid, containment. 27657 */ 27658 27659 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options 27660 27661 if ( this.containment ) { 27662 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { 27663 pageX = this.containment[ 0 ] + this.offset.click.left; 27664 } 27665 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { 27666 pageY = this.containment[ 1 ] + this.offset.click.top; 27667 } 27668 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { 27669 pageX = this.containment[ 2 ] + this.offset.click.left; 27670 } 27671 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { 27672 pageY = this.containment[ 3 ] + this.offset.click.top; 27673 } 27674 } 27675 27676 if ( o.grid ) { 27677 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / 27678 o.grid[ 1 ] ) * o.grid[ 1 ]; 27679 pageY = this.containment ? 27680 ( ( top - this.offset.click.top >= this.containment[ 1 ] && 27681 top - this.offset.click.top <= this.containment[ 3 ] ) ? 27682 top : 27683 ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? 27684 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : 27685 top; 27686 27687 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / 27688 o.grid[ 0 ] ) * o.grid[ 0 ]; 27689 pageX = this.containment ? 27690 ( ( left - this.offset.click.left >= this.containment[ 0 ] && 27691 left - this.offset.click.left <= this.containment[ 2 ] ) ? 27692 left : 27693 ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? 27694 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : 27695 left; 27696 } 27697 27698 } 27699 27700 return { 27701 top: ( 27702 27703 // The absolute mouse position 27704 pageY - 27705 27706 // Click offset (relative to the element) 27707 this.offset.click.top - 27708 27709 // Only for relative positioned nodes: Relative offset from element to offset parent 27710 this.offset.relative.top - 27711 27712 // The offsetParent's offset without borders (offset + border) 27713 this.offset.parent.top + 27714 ( ( this.cssPosition === "fixed" ? 27715 -this.scrollParent.scrollTop() : 27716 ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) 27717 ), 27718 left: ( 27719 27720 // The absolute mouse position 27721 pageX - 27722 27723 // Click offset (relative to the element) 27724 this.offset.click.left - 27725 27726 // Only for relative positioned nodes: Relative offset from element to offset parent 27727 this.offset.relative.left - 27728 27729 // The offsetParent's offset without borders (offset + border) 27730 this.offset.parent.left + 27731 ( ( this.cssPosition === "fixed" ? 27732 -this.scrollParent.scrollLeft() : 27733 scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) 27734 ) 27735 }; 27736 27737 }, 27738 27739 _rearrange: function( event, i, a, hardRefresh ) { 27740 27741 if ( a ) { 27742 a[ 0 ].appendChild( this.placeholder[ 0 ] ); 27743 } else { 27744 i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], 27745 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); 27746 } 27747 27748 //Various things done here to improve the performance: 27749 // 1. we create a setTimeout, that calls refreshPositions 27750 // 2. on the instance, we have a counter variable, that get's higher after every append 27751 // 3. on the local scope, we copy the counter variable, and check in the timeout, 27752 // if it's still the same 27753 // 4. this lets only the last addition to the timeout stack through 27754 this.counter = this.counter ? ++this.counter : 1; 27755 var counter = this.counter; 27756 27757 this._delay( function() { 27758 if ( counter === this.counter ) { 27759 27760 //Precompute after each DOM insertion, NOT on mousemove 27761 this.refreshPositions( !hardRefresh ); 27762 } 27763 } ); 27764 27765 }, 27766 27767 _clear: function( event, noPropagation ) { 27768 27769 this.reverting = false; 27770 27771 // We delay all events that have to be triggered to after the point where the placeholder 27772 // has been removed and everything else normalized again 27773 var i, 27774 delayedTriggers = []; 27775 27776 // We first have to update the dom position of the actual currentItem 27777 // Note: don't do it if the current item is already removed (by a user), or it gets 27778 // reappended (see #4088) 27779 if ( !this._noFinalSort && this.currentItem.parent().length ) { 27780 this.placeholder.before( this.currentItem ); 27781 } 27782 this._noFinalSort = null; 27783 27784 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { 27785 for ( i in this._storedCSS ) { 27786 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { 27787 this._storedCSS[ i ] = ""; 27788 } 27789 } 27790 this.currentItem.css( this._storedCSS ); 27791 this._removeClass( this.currentItem, "ui-sortable-helper" ); 27792 } else { 27793 this.currentItem.show(); 27794 } 27795 27796 if ( this.fromOutside && !noPropagation ) { 27797 delayedTriggers.push( function( event ) { 27798 this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); 27799 } ); 27800 } 27801 if ( ( this.fromOutside || 27802 this.domPosition.prev !== 27803 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || 27804 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { 27805 27806 // Trigger update callback if the DOM position has changed 27807 delayedTriggers.push( function( event ) { 27808 this._trigger( "update", event, this._uiHash() ); 27809 } ); 27810 } 27811 27812 // Check if the items Container has Changed and trigger appropriate 27813 // events. 27814 if ( this !== this.currentContainer ) { 27815 if ( !noPropagation ) { 27816 delayedTriggers.push( function( event ) { 27817 this._trigger( "remove", event, this._uiHash() ); 27818 } ); 27819 delayedTriggers.push( ( function( c ) { 27820 return function( event ) { 27821 c._trigger( "receive", event, this._uiHash( this ) ); 27822 }; 27823 } ).call( this, this.currentContainer ) ); 27824 delayedTriggers.push( ( function( c ) { 27825 return function( event ) { 27826 c._trigger( "update", event, this._uiHash( this ) ); 27827 }; 27828 } ).call( this, this.currentContainer ) ); 27829 } 27830 } 27831 27832 //Post events to containers 27833 function delayEvent( type, instance, container ) { 27834 return function( event ) { 27835 container._trigger( type, event, instance._uiHash( instance ) ); 27836 }; 27837 } 27838 for ( i = this.containers.length - 1; i >= 0; i-- ) { 27839 if ( !noPropagation ) { 27840 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); 27841 } 27842 if ( this.containers[ i ].containerCache.over ) { 27843 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); 27844 this.containers[ i ].containerCache.over = 0; 27845 } 27846 } 27847 27848 //Do what was originally in plugins 27849 if ( this.storedCursor ) { 27850 this.document.find( "body" ).css( "cursor", this.storedCursor ); 27851 this.storedStylesheet.remove(); 27852 } 27853 if ( this._storedOpacity ) { 27854 this.helper.css( "opacity", this._storedOpacity ); 27855 } 27856 if ( this._storedZIndex ) { 27857 this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); 27858 } 27859 27860 this.dragging = false; 27861 27862 if ( !noPropagation ) { 27863 this._trigger( "beforeStop", event, this._uiHash() ); 27864 } 27865 27866 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, 27867 // it unbinds ALL events from the original node! 27868 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); 27869 27870 if ( !this.cancelHelperRemoval ) { 27871 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { 27872 this.helper.remove(); 27873 } 27874 this.helper = null; 27875 } 27876 27877 if ( !noPropagation ) { 27878 for ( i = 0; i < delayedTriggers.length; i++ ) { 27879 27880 // Trigger all delayed events 27881 delayedTriggers[ i ].call( this, event ); 27882 } 27883 this._trigger( "stop", event, this._uiHash() ); 27884 } 27885 27886 this.fromOutside = false; 27887 return !this.cancelHelperRemoval; 27888 27889 }, 27890 27891 _trigger: function() { 27892 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { 27893 this.cancel(); 27894 } 27895 }, 27896 27897 _uiHash: function( _inst ) { 27898 var inst = _inst || this; 27899 return { 27900 helper: inst.helper, 27901 placeholder: inst.placeholder || $( [] ), 27902 position: inst.position, 27903 originalPosition: inst.originalPosition, 27904 offset: inst.positionAbs, 27905 item: inst.currentItem, 27906 sender: _inst ? _inst.element : null 27907 }; 27908 } 27909 27910} ); 27911 27912 27913/*! 27914 * jQuery UI Spinner 1.13.2 27915 * http://jqueryui.com 27916 * 27917 * Copyright jQuery Foundation and other contributors 27918 * Released under the MIT license. 27919 * http://jquery.org/license 27920 */ 27921 27922//>>label: Spinner 27923//>>group: Widgets 27924//>>description: Displays buttons to easily input numbers via the keyboard or mouse. 27925//>>docs: http://api.jqueryui.com/spinner/ 27926//>>demos: http://jqueryui.com/spinner/ 27927//>>css.structure: ../../themes/base/core.css 27928//>>css.structure: ../../themes/base/spinner.css 27929//>>css.theme: ../../themes/base/theme.css 27930 27931 27932function spinnerModifier( fn ) { 27933 return function() { 27934 var previous = this.element.val(); 27935 fn.apply( this, arguments ); 27936 this._refresh(); 27937 if ( previous !== this.element.val() ) { 27938 this._trigger( "change" ); 27939 } 27940 }; 27941} 27942 27943$.widget( "ui.spinner", { 27944 version: "1.13.2", 27945 defaultElement: "<input>", 27946 widgetEventPrefix: "spin", 27947 options: { 27948 classes: { 27949 "ui-spinner": "ui-corner-all", 27950 "ui-spinner-down": "ui-corner-br", 27951 "ui-spinner-up": "ui-corner-tr" 27952 }, 27953 culture: null, 27954 icons: { 27955 down: "ui-icon-triangle-1-s", 27956 up: "ui-icon-triangle-1-n" 27957 }, 27958 incremental: true, 27959 max: null, 27960 min: null, 27961 numberFormat: null, 27962 page: 10, 27963 step: 1, 27964 27965 change: null, 27966 spin: null, 27967 start: null, 27968 stop: null 27969 }, 27970 27971 _create: function() { 27972 27973 // handle string values that need to be parsed 27974 this._setOption( "max", this.options.max ); 27975 this._setOption( "min", this.options.min ); 27976 this._setOption( "step", this.options.step ); 27977 27978 // Only format if there is a value, prevents the field from being marked 27979 // as invalid in Firefox, see #9573. 27980 if ( this.value() !== "" ) { 27981 27982 // Format the value, but don't constrain. 27983 this._value( this.element.val(), true ); 27984 } 27985 27986 this._draw(); 27987 this._on( this._events ); 27988 this._refresh(); 27989 27990 // Turning off autocomplete prevents the browser from remembering the 27991 // value when navigating through history, so we re-enable autocomplete 27992 // if the page is unloaded before the widget is destroyed. #7790 27993 this._on( this.window, { 27994 beforeunload: function() { 27995 this.element.removeAttr( "autocomplete" ); 27996 } 27997 } ); 27998 }, 27999 28000 _getCreateOptions: function() { 28001 var options = this._super(); 28002 var element = this.element; 28003 28004 $.each( [ "min", "max", "step" ], function( i, option ) { 28005 var value = element.attr( option ); 28006 if ( value != null && value.length ) { 28007 options[ option ] = value; 28008 } 28009 } ); 28010 28011 return options; 28012 }, 28013 28014 _events: { 28015 keydown: function( event ) { 28016 if ( this._start( event ) && this._keydown( event ) ) { 28017 event.preventDefault(); 28018 } 28019 }, 28020 keyup: "_stop", 28021 focus: function() { 28022 this.previous = this.element.val(); 28023 }, 28024 blur: function( event ) { 28025 if ( this.cancelBlur ) { 28026 delete this.cancelBlur; 28027 return; 28028 } 28029 28030 this._stop(); 28031 this._refresh(); 28032 if ( this.previous !== this.element.val() ) { 28033 this._trigger( "change", event ); 28034 } 28035 }, 28036 mousewheel: function( event, delta ) { 28037 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); 28038 var isActive = this.element[ 0 ] === activeElement; 28039 28040 if ( !isActive || !delta ) { 28041 return; 28042 } 28043 28044 if ( !this.spinning && !this._start( event ) ) { 28045 return false; 28046 } 28047 28048 this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); 28049 clearTimeout( this.mousewheelTimer ); 28050 this.mousewheelTimer = this._delay( function() { 28051 if ( this.spinning ) { 28052 this._stop( event ); 28053 } 28054 }, 100 ); 28055 event.preventDefault(); 28056 }, 28057 "mousedown .ui-spinner-button": function( event ) { 28058 var previous; 28059 28060 // We never want the buttons to have focus; whenever the user is 28061 // interacting with the spinner, the focus should be on the input. 28062 // If the input is focused then this.previous is properly set from 28063 // when the input first received focus. If the input is not focused 28064 // then we need to set this.previous based on the value before spinning. 28065 previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? 28066 this.previous : this.element.val(); 28067 function checkFocus() { 28068 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); 28069 if ( !isActive ) { 28070 this.element.trigger( "focus" ); 28071 this.previous = previous; 28072 28073 // support: IE 28074 // IE sets focus asynchronously, so we need to check if focus 28075 // moved off of the input because the user clicked on the button. 28076 this._delay( function() { 28077 this.previous = previous; 28078 } ); 28079 } 28080 } 28081 28082 // Ensure focus is on (or stays on) the text field 28083 event.preventDefault(); 28084 checkFocus.call( this ); 28085 28086 // Support: IE 28087 // IE doesn't prevent moving focus even with event.preventDefault() 28088 // so we set a flag to know when we should ignore the blur event 28089 // and check (again) if focus moved off of the input. 28090 this.cancelBlur = true; 28091 this._delay( function() { 28092 delete this.cancelBlur; 28093 checkFocus.call( this ); 28094 } ); 28095 28096 if ( this._start( event ) === false ) { 28097 return; 28098 } 28099 28100 this._repeat( null, $( event.currentTarget ) 28101 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 28102 }, 28103 "mouseup .ui-spinner-button": "_stop", 28104 "mouseenter .ui-spinner-button": function( event ) { 28105 28106 // button will add ui-state-active if mouse was down while mouseleave and kept down 28107 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { 28108 return; 28109 } 28110 28111 if ( this._start( event ) === false ) { 28112 return false; 28113 } 28114 this._repeat( null, $( event.currentTarget ) 28115 .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); 28116 }, 28117 28118 // TODO: do we really want to consider this a stop? 28119 // shouldn't we just stop the repeater and wait until mouseup before 28120 // we trigger the stop event? 28121 "mouseleave .ui-spinner-button": "_stop" 28122 }, 28123 28124 // Support mobile enhanced option and make backcompat more sane 28125 _enhance: function() { 28126 this.uiSpinner = this.element 28127 .attr( "autocomplete", "off" ) 28128 .wrap( "<span>" ) 28129 .parent() 28130 28131 // Add buttons 28132 .append( 28133 "<a></a><a></a>" 28134 ); 28135 }, 28136 28137 _draw: function() { 28138 this._enhance(); 28139 28140 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); 28141 this._addClass( "ui-spinner-input" ); 28142 28143 this.element.attr( "role", "spinbutton" ); 28144 28145 // Button bindings 28146 this.buttons = this.uiSpinner.children( "a" ) 28147 .attr( "tabIndex", -1 ) 28148 .attr( "aria-hidden", true ) 28149 .button( { 28150 classes: { 28151 "ui-button": "" 28152 } 28153 } ); 28154 28155 // TODO: Right now button does not support classes this is already updated in button PR 28156 this._removeClass( this.buttons, "ui-corner-all" ); 28157 28158 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); 28159 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); 28160 this.buttons.first().button( { 28161 "icon": this.options.icons.up, 28162 "showLabel": false 28163 } ); 28164 this.buttons.last().button( { 28165 "icon": this.options.icons.down, 28166 "showLabel": false 28167 } ); 28168 28169 // IE 6 doesn't understand height: 50% for the buttons 28170 // unless the wrapper has an explicit height 28171 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && 28172 this.uiSpinner.height() > 0 ) { 28173 this.uiSpinner.height( this.uiSpinner.height() ); 28174 } 28175 }, 28176 28177 _keydown: function( event ) { 28178 var options = this.options, 28179 keyCode = $.ui.keyCode; 28180 28181 switch ( event.keyCode ) { 28182 case keyCode.UP: 28183 this._repeat( null, 1, event ); 28184 return true; 28185 case keyCode.DOWN: 28186 this._repeat( null, -1, event ); 28187 return true; 28188 case keyCode.PAGE_UP: 28189 this._repeat( null, options.page, event ); 28190 return true; 28191 case keyCode.PAGE_DOWN: 28192 this._repeat( null, -options.page, event ); 28193 return true; 28194 } 28195 28196 return false; 28197 }, 28198 28199 _start: function( event ) { 28200 if ( !this.spinning && this._trigger( "start", event ) === false ) { 28201 return false; 28202 } 28203 28204 if ( !this.counter ) { 28205 this.counter = 1; 28206 } 28207 this.spinning = true; 28208 return true; 28209 }, 28210 28211 _repeat: function( i, steps, event ) { 28212 i = i || 500; 28213 28214 clearTimeout( this.timer ); 28215 this.timer = this._delay( function() { 28216 this._repeat( 40, steps, event ); 28217 }, i ); 28218 28219 this._spin( steps * this.options.step, event ); 28220 }, 28221 28222 _spin: function( step, event ) { 28223 var value = this.value() || 0; 28224 28225 if ( !this.counter ) { 28226 this.counter = 1; 28227 } 28228 28229 value = this._adjustValue( value + step * this._increment( this.counter ) ); 28230 28231 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { 28232 this._value( value ); 28233 this.counter++; 28234 } 28235 }, 28236 28237 _increment: function( i ) { 28238 var incremental = this.options.incremental; 28239 28240 if ( incremental ) { 28241 return typeof incremental === "function" ? 28242 incremental( i ) : 28243 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); 28244 } 28245 28246 return 1; 28247 }, 28248 28249 _precision: function() { 28250 var precision = this._precisionOf( this.options.step ); 28251 if ( this.options.min !== null ) { 28252 precision = Math.max( precision, this._precisionOf( this.options.min ) ); 28253 } 28254 return precision; 28255 }, 28256 28257 _precisionOf: function( num ) { 28258 var str = num.toString(), 28259 decimal = str.indexOf( "." ); 28260 return decimal === -1 ? 0 : str.length - decimal - 1; 28261 }, 28262 28263 _adjustValue: function( value ) { 28264 var base, aboveMin, 28265 options = this.options; 28266 28267 // Make sure we're at a valid step 28268 // - find out where we are relative to the base (min or 0) 28269 base = options.min !== null ? options.min : 0; 28270 aboveMin = value - base; 28271 28272 // - round to the nearest step 28273 aboveMin = Math.round( aboveMin / options.step ) * options.step; 28274 28275 // - rounding is based on 0, so adjust back to our base 28276 value = base + aboveMin; 28277 28278 // Fix precision from bad JS floating point math 28279 value = parseFloat( value.toFixed( this._precision() ) ); 28280 28281 // Clamp the value 28282 if ( options.max !== null && value > options.max ) { 28283 return options.max; 28284 } 28285 if ( options.min !== null && value < options.min ) { 28286 return options.min; 28287 } 28288 28289 return value; 28290 }, 28291 28292 _stop: function( event ) { 28293 if ( !this.spinning ) { 28294 return; 28295 } 28296 28297 clearTimeout( this.timer ); 28298 clearTimeout( this.mousewheelTimer ); 28299 this.counter = 0; 28300 this.spinning = false; 28301 this._trigger( "stop", event ); 28302 }, 28303 28304 _setOption: function( key, value ) { 28305 var prevValue, first, last; 28306 28307 if ( key === "culture" || key === "numberFormat" ) { 28308 prevValue = this._parse( this.element.val() ); 28309 this.options[ key ] = value; 28310 this.element.val( this._format( prevValue ) ); 28311 return; 28312 } 28313 28314 if ( key === "max" || key === "min" || key === "step" ) { 28315 if ( typeof value === "string" ) { 28316 value = this._parse( value ); 28317 } 28318 } 28319 if ( key === "icons" ) { 28320 first = this.buttons.first().find( ".ui-icon" ); 28321 this._removeClass( first, null, this.options.icons.up ); 28322 this._addClass( first, null, value.up ); 28323 last = this.buttons.last().find( ".ui-icon" ); 28324 this._removeClass( last, null, this.options.icons.down ); 28325 this._addClass( last, null, value.down ); 28326 } 28327 28328 this._super( key, value ); 28329 }, 28330 28331 _setOptionDisabled: function( value ) { 28332 this._super( value ); 28333 28334 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); 28335 this.element.prop( "disabled", !!value ); 28336 this.buttons.button( value ? "disable" : "enable" ); 28337 }, 28338 28339 _setOptions: spinnerModifier( function( options ) { 28340 this._super( options ); 28341 } ), 28342 28343 _parse: function( val ) { 28344 if ( typeof val === "string" && val !== "" ) { 28345 val = window.Globalize && this.options.numberFormat ? 28346 Globalize.parseFloat( val, 10, this.options.culture ) : +val; 28347 } 28348 return val === "" || isNaN( val ) ? null : val; 28349 }, 28350 28351 _format: function( value ) { 28352 if ( value === "" ) { 28353 return ""; 28354 } 28355 return window.Globalize && this.options.numberFormat ? 28356 Globalize.format( value, this.options.numberFormat, this.options.culture ) : 28357 value; 28358 }, 28359 28360 _refresh: function() { 28361 this.element.attr( { 28362 "aria-valuemin": this.options.min, 28363 "aria-valuemax": this.options.max, 28364 28365 // TODO: what should we do with values that can't be parsed? 28366 "aria-valuenow": this._parse( this.element.val() ) 28367 } ); 28368 }, 28369 28370 isValid: function() { 28371 var value = this.value(); 28372 28373 // Null is invalid 28374 if ( value === null ) { 28375 return false; 28376 } 28377 28378 // If value gets adjusted, it's invalid 28379 return value === this._adjustValue( value ); 28380 }, 28381 28382 // Update the value without triggering change 28383 _value: function( value, allowAny ) { 28384 var parsed; 28385 if ( value !== "" ) { 28386 parsed = this._parse( value ); 28387 if ( parsed !== null ) { 28388 if ( !allowAny ) { 28389 parsed = this._adjustValue( parsed ); 28390 } 28391 value = this._format( parsed ); 28392 } 28393 } 28394 this.element.val( value ); 28395 this._refresh(); 28396 }, 28397 28398 _destroy: function() { 28399 this.element 28400 .prop( "disabled", false ) 28401 .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); 28402 28403 this.uiSpinner.replaceWith( this.element ); 28404 }, 28405 28406 stepUp: spinnerModifier( function( steps ) { 28407 this._stepUp( steps ); 28408 } ), 28409 _stepUp: function( steps ) { 28410 if ( this._start() ) { 28411 this._spin( ( steps || 1 ) * this.options.step ); 28412 this._stop(); 28413 } 28414 }, 28415 28416 stepDown: spinnerModifier( function( steps ) { 28417 this._stepDown( steps ); 28418 } ), 28419 _stepDown: function( steps ) { 28420 if ( this._start() ) { 28421 this._spin( ( steps || 1 ) * -this.options.step ); 28422 this._stop(); 28423 } 28424 }, 28425 28426 pageUp: spinnerModifier( function( pages ) { 28427 this._stepUp( ( pages || 1 ) * this.options.page ); 28428 } ), 28429 28430 pageDown: spinnerModifier( function( pages ) { 28431 this._stepDown( ( pages || 1 ) * this.options.page ); 28432 } ), 28433 28434 value: function( newVal ) { 28435 if ( !arguments.length ) { 28436 return this._parse( this.element.val() ); 28437 } 28438 spinnerModifier( this._value ).call( this, newVal ); 28439 }, 28440 28441 widget: function() { 28442 return this.uiSpinner; 28443 } 28444} ); 28445 28446// DEPRECATED 28447// TODO: switch return back to widget declaration at top of file when this is removed 28448if ( $.uiBackCompat !== false ) { 28449 28450 // Backcompat for spinner html extension points 28451 $.widget( "ui.spinner", $.ui.spinner, { 28452 _enhance: function() { 28453 this.uiSpinner = this.element 28454 .attr( "autocomplete", "off" ) 28455 .wrap( this._uiSpinnerHtml() ) 28456 .parent() 28457 28458 // Add buttons 28459 .append( this._buttonHtml() ); 28460 }, 28461 _uiSpinnerHtml: function() { 28462 return "<span>"; 28463 }, 28464 28465 _buttonHtml: function() { 28466 return "<a></a><a></a>"; 28467 } 28468 } ); 28469} 28470 28471var widgetsSpinner = $.ui.spinner; 28472 28473 28474/*! 28475 * jQuery UI Tabs 1.13.2 28476 * http://jqueryui.com 28477 * 28478 * Copyright jQuery Foundation and other contributors 28479 * Released under the MIT license. 28480 * http://jquery.org/license 28481 */ 28482 28483//>>label: Tabs 28484//>>group: Widgets 28485//>>description: Transforms a set of container elements into a tab structure. 28486//>>docs: http://api.jqueryui.com/tabs/ 28487//>>demos: http://jqueryui.com/tabs/ 28488//>>css.structure: ../../themes/base/core.css 28489//>>css.structure: ../../themes/base/tabs.css 28490//>>css.theme: ../../themes/base/theme.css 28491 28492 28493$.widget( "ui.tabs", { 28494 version: "1.13.2", 28495 delay: 300, 28496 options: { 28497 active: null, 28498 classes: { 28499 "ui-tabs": "ui-corner-all", 28500 "ui-tabs-nav": "ui-corner-all", 28501 "ui-tabs-panel": "ui-corner-bottom", 28502 "ui-tabs-tab": "ui-corner-top" 28503 }, 28504 collapsible: false, 28505 event: "click", 28506 heightStyle: "content", 28507 hide: null, 28508 show: null, 28509 28510 // Callbacks 28511 activate: null, 28512 beforeActivate: null, 28513 beforeLoad: null, 28514 load: null 28515 }, 28516 28517 _isLocal: ( function() { 28518 var rhash = /#.*$/; 28519 28520 return function( anchor ) { 28521 var anchorUrl, locationUrl; 28522 28523 anchorUrl = anchor.href.replace( rhash, "" ); 28524 locationUrl = location.href.replace( rhash, "" ); 28525 28526 // Decoding may throw an error if the URL isn't UTF-8 (#9518) 28527 try { 28528 anchorUrl = decodeURIComponent( anchorUrl ); 28529 } catch ( error ) {} 28530 try { 28531 locationUrl = decodeURIComponent( locationUrl ); 28532 } catch ( error ) {} 28533 28534 return anchor.hash.length > 1 && anchorUrl === locationUrl; 28535 }; 28536 } )(), 28537 28538 _create: function() { 28539 var that = this, 28540 options = this.options; 28541 28542 this.running = false; 28543 28544 this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); 28545 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); 28546 28547 this._processTabs(); 28548 options.active = this._initialActive(); 28549 28550 // Take disabling tabs via class attribute from HTML 28551 // into account and update option properly. 28552 if ( Array.isArray( options.disabled ) ) { 28553 options.disabled = $.uniqueSort( options.disabled.concat( 28554 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { 28555 return that.tabs.index( li ); 28556 } ) 28557 ) ).sort(); 28558 } 28559 28560 // Check for length avoids error when initializing empty list 28561 if ( this.options.active !== false && this.anchors.length ) { 28562 this.active = this._findActive( options.active ); 28563 } else { 28564 this.active = $(); 28565 } 28566 28567 this._refresh(); 28568 28569 if ( this.active.length ) { 28570 this.load( options.active ); 28571 } 28572 }, 28573 28574 _initialActive: function() { 28575 var active = this.options.active, 28576 collapsible = this.options.collapsible, 28577 locationHash = location.hash.substring( 1 ); 28578 28579 if ( active === null ) { 28580 28581 // check the fragment identifier in the URL 28582 if ( locationHash ) { 28583 this.tabs.each( function( i, tab ) { 28584 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { 28585 active = i; 28586 return false; 28587 } 28588 } ); 28589 } 28590 28591 // Check for a tab marked active via a class 28592 if ( active === null ) { 28593 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); 28594 } 28595 28596 // No active tab, set to false 28597 if ( active === null || active === -1 ) { 28598 active = this.tabs.length ? 0 : false; 28599 } 28600 } 28601 28602 // Handle numbers: negative, out of range 28603 if ( active !== false ) { 28604 active = this.tabs.index( this.tabs.eq( active ) ); 28605 if ( active === -1 ) { 28606 active = collapsible ? false : 0; 28607 } 28608 } 28609 28610 // Don't allow collapsible: false and active: false 28611 if ( !collapsible && active === false && this.anchors.length ) { 28612 active = 0; 28613 } 28614 28615 return active; 28616 }, 28617 28618 _getCreateEventData: function() { 28619 return { 28620 tab: this.active, 28621 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) 28622 }; 28623 }, 28624 28625 _tabKeydown: function( event ) { 28626 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), 28627 selectedIndex = this.tabs.index( focusedTab ), 28628 goingForward = true; 28629 28630 if ( this._handlePageNav( event ) ) { 28631 return; 28632 } 28633 28634 switch ( event.keyCode ) { 28635 case $.ui.keyCode.RIGHT: 28636 case $.ui.keyCode.DOWN: 28637 selectedIndex++; 28638 break; 28639 case $.ui.keyCode.UP: 28640 case $.ui.keyCode.LEFT: 28641 goingForward = false; 28642 selectedIndex--; 28643 break; 28644 case $.ui.keyCode.END: 28645 selectedIndex = this.anchors.length - 1; 28646 break; 28647 case $.ui.keyCode.HOME: 28648 selectedIndex = 0; 28649 break; 28650 case $.ui.keyCode.SPACE: 28651 28652 // Activate only, no collapsing 28653 event.preventDefault(); 28654 clearTimeout( this.activating ); 28655 this._activate( selectedIndex ); 28656 return; 28657 case $.ui.keyCode.ENTER: 28658 28659 // Toggle (cancel delayed activation, allow collapsing) 28660 event.preventDefault(); 28661 clearTimeout( this.activating ); 28662 28663 // Determine if we should collapse or activate 28664 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); 28665 return; 28666 default: 28667 return; 28668 } 28669 28670 // Focus the appropriate tab, based on which key was pressed 28671 event.preventDefault(); 28672 clearTimeout( this.activating ); 28673 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); 28674 28675 // Navigating with control/command key will prevent automatic activation 28676 if ( !event.ctrlKey && !event.metaKey ) { 28677 28678 // Update aria-selected immediately so that AT think the tab is already selected. 28679 // Otherwise AT may confuse the user by stating that they need to activate the tab, 28680 // but the tab will already be activated by the time the announcement finishes. 28681 focusedTab.attr( "aria-selected", "false" ); 28682 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); 28683 28684 this.activating = this._delay( function() { 28685 this.option( "active", selectedIndex ); 28686 }, this.delay ); 28687 } 28688 }, 28689 28690 _panelKeydown: function( event ) { 28691 if ( this._handlePageNav( event ) ) { 28692 return; 28693 } 28694 28695 // Ctrl+up moves focus to the current tab 28696 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { 28697 event.preventDefault(); 28698 this.active.trigger( "focus" ); 28699 } 28700 }, 28701 28702 // Alt+page up/down moves focus to the previous/next tab (and activates) 28703 _handlePageNav: function( event ) { 28704 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { 28705 this._activate( this._focusNextTab( this.options.active - 1, false ) ); 28706 return true; 28707 } 28708 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { 28709 this._activate( this._focusNextTab( this.options.active + 1, true ) ); 28710 return true; 28711 } 28712 }, 28713 28714 _findNextTab: function( index, goingForward ) { 28715 var lastTabIndex = this.tabs.length - 1; 28716 28717 function constrain() { 28718 if ( index > lastTabIndex ) { 28719 index = 0; 28720 } 28721 if ( index < 0 ) { 28722 index = lastTabIndex; 28723 } 28724 return index; 28725 } 28726 28727 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { 28728 index = goingForward ? index + 1 : index - 1; 28729 } 28730 28731 return index; 28732 }, 28733 28734 _focusNextTab: function( index, goingForward ) { 28735 index = this._findNextTab( index, goingForward ); 28736 this.tabs.eq( index ).trigger( "focus" ); 28737 return index; 28738 }, 28739 28740 _setOption: function( key, value ) { 28741 if ( key === "active" ) { 28742 28743 // _activate() will handle invalid values and update this.options 28744 this._activate( value ); 28745 return; 28746 } 28747 28748 this._super( key, value ); 28749 28750 if ( key === "collapsible" ) { 28751 this._toggleClass( "ui-tabs-collapsible", null, value ); 28752 28753 // Setting collapsible: false while collapsed; open first panel 28754 if ( !value && this.options.active === false ) { 28755 this._activate( 0 ); 28756 } 28757 } 28758 28759 if ( key === "event" ) { 28760 this._setupEvents( value ); 28761 } 28762 28763 if ( key === "heightStyle" ) { 28764 this._setupHeightStyle( value ); 28765 } 28766 }, 28767 28768 _sanitizeSelector: function( hash ) { 28769 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; 28770 }, 28771 28772 refresh: function() { 28773 var options = this.options, 28774 lis = this.tablist.children( ":has(a[href])" ); 28775 28776 // Get disabled tabs from class attribute from HTML 28777 // this will get converted to a boolean if needed in _refresh() 28778 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { 28779 return lis.index( tab ); 28780 } ); 28781 28782 this._processTabs(); 28783 28784 // Was collapsed or no tabs 28785 if ( options.active === false || !this.anchors.length ) { 28786 options.active = false; 28787 this.active = $(); 28788 28789 // was active, but active tab is gone 28790 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { 28791 28792 // all remaining tabs are disabled 28793 if ( this.tabs.length === options.disabled.length ) { 28794 options.active = false; 28795 this.active = $(); 28796 28797 // activate previous tab 28798 } else { 28799 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); 28800 } 28801 28802 // was active, active tab still exists 28803 } else { 28804 28805 // make sure active index is correct 28806 options.active = this.tabs.index( this.active ); 28807 } 28808 28809 this._refresh(); 28810 }, 28811 28812 _refresh: function() { 28813 this._setOptionDisabled( this.options.disabled ); 28814 this._setupEvents( this.options.event ); 28815 this._setupHeightStyle( this.options.heightStyle ); 28816 28817 this.tabs.not( this.active ).attr( { 28818 "aria-selected": "false", 28819 "aria-expanded": "false", 28820 tabIndex: -1 28821 } ); 28822 this.panels.not( this._getPanelForTab( this.active ) ) 28823 .hide() 28824 .attr( { 28825 "aria-hidden": "true" 28826 } ); 28827 28828 // Make sure one tab is in the tab order 28829 if ( !this.active.length ) { 28830 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); 28831 } else { 28832 this.active 28833 .attr( { 28834 "aria-selected": "true", 28835 "aria-expanded": "true", 28836 tabIndex: 0 28837 } ); 28838 this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); 28839 this._getPanelForTab( this.active ) 28840 .show() 28841 .attr( { 28842 "aria-hidden": "false" 28843 } ); 28844 } 28845 }, 28846 28847 _processTabs: function() { 28848 var that = this, 28849 prevTabs = this.tabs, 28850 prevAnchors = this.anchors, 28851 prevPanels = this.panels; 28852 28853 this.tablist = this._getList().attr( "role", "tablist" ); 28854 this._addClass( this.tablist, "ui-tabs-nav", 28855 "ui-helper-reset ui-helper-clearfix ui-widget-header" ); 28856 28857 // Prevent users from focusing disabled tabs via click 28858 this.tablist 28859 .on( "mousedown" + this.eventNamespace, "> li", function( event ) { 28860 if ( $( this ).is( ".ui-state-disabled" ) ) { 28861 event.preventDefault(); 28862 } 28863 } ) 28864 28865 // Support: IE <9 28866 // Preventing the default action in mousedown doesn't prevent IE 28867 // from focusing the element, so if the anchor gets focused, blur. 28868 // We don't have to worry about focusing the previously focused 28869 // element since clicking on a non-focusable element should focus 28870 // the body anyway. 28871 .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { 28872 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { 28873 this.blur(); 28874 } 28875 } ); 28876 28877 this.tabs = this.tablist.find( "> li:has(a[href])" ) 28878 .attr( { 28879 role: "tab", 28880 tabIndex: -1 28881 } ); 28882 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); 28883 28884 this.anchors = this.tabs.map( function() { 28885 return $( "a", this )[ 0 ]; 28886 } ) 28887 .attr( { 28888 tabIndex: -1 28889 } ); 28890 this._addClass( this.anchors, "ui-tabs-anchor" ); 28891 28892 this.panels = $(); 28893 28894 this.anchors.each( function( i, anchor ) { 28895 var selector, panel, panelId, 28896 anchorId = $( anchor ).uniqueId().attr( "id" ), 28897 tab = $( anchor ).closest( "li" ), 28898 originalAriaControls = tab.attr( "aria-controls" ); 28899 28900 // Inline tab 28901 if ( that._isLocal( anchor ) ) { 28902 selector = anchor.hash; 28903 panelId = selector.substring( 1 ); 28904 panel = that.element.find( that._sanitizeSelector( selector ) ); 28905 28906 // remote tab 28907 } else { 28908 28909 // If the tab doesn't already have aria-controls, 28910 // generate an id by using a throw-away element 28911 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; 28912 selector = "#" + panelId; 28913 panel = that.element.find( selector ); 28914 if ( !panel.length ) { 28915 panel = that._createPanel( panelId ); 28916 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); 28917 } 28918 panel.attr( "aria-live", "polite" ); 28919 } 28920 28921 if ( panel.length ) { 28922 that.panels = that.panels.add( panel ); 28923 } 28924 if ( originalAriaControls ) { 28925 tab.data( "ui-tabs-aria-controls", originalAriaControls ); 28926 } 28927 tab.attr( { 28928 "aria-controls": panelId, 28929 "aria-labelledby": anchorId 28930 } ); 28931 panel.attr( "aria-labelledby", anchorId ); 28932 } ); 28933 28934 this.panels.attr( "role", "tabpanel" ); 28935 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); 28936 28937 // Avoid memory leaks (#10056) 28938 if ( prevTabs ) { 28939 this._off( prevTabs.not( this.tabs ) ); 28940 this._off( prevAnchors.not( this.anchors ) ); 28941 this._off( prevPanels.not( this.panels ) ); 28942 } 28943 }, 28944 28945 // Allow overriding how to find the list for rare usage scenarios (#7715) 28946 _getList: function() { 28947 return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); 28948 }, 28949 28950 _createPanel: function( id ) { 28951 return $( "<div>" ) 28952 .attr( "id", id ) 28953 .data( "ui-tabs-destroy", true ); 28954 }, 28955 28956 _setOptionDisabled: function( disabled ) { 28957 var currentItem, li, i; 28958 28959 if ( Array.isArray( disabled ) ) { 28960 if ( !disabled.length ) { 28961 disabled = false; 28962 } else if ( disabled.length === this.anchors.length ) { 28963 disabled = true; 28964 } 28965 } 28966 28967 // Disable tabs 28968 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { 28969 currentItem = $( li ); 28970 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { 28971 currentItem.attr( "aria-disabled", "true" ); 28972 this._addClass( currentItem, null, "ui-state-disabled" ); 28973 } else { 28974 currentItem.removeAttr( "aria-disabled" ); 28975 this._removeClass( currentItem, null, "ui-state-disabled" ); 28976 } 28977 } 28978 28979 this.options.disabled = disabled; 28980 28981 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, 28982 disabled === true ); 28983 }, 28984 28985 _setupEvents: function( event ) { 28986 var events = {}; 28987 if ( event ) { 28988 $.each( event.split( " " ), function( index, eventName ) { 28989 events[ eventName ] = "_eventHandler"; 28990 } ); 28991 } 28992 28993 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); 28994 28995 // Always prevent the default action, even when disabled 28996 this._on( true, this.anchors, { 28997 click: function( event ) { 28998 event.preventDefault(); 28999 } 29000 } ); 29001 this._on( this.anchors, events ); 29002 this._on( this.tabs, { keydown: "_tabKeydown" } ); 29003 this._on( this.panels, { keydown: "_panelKeydown" } ); 29004 29005 this._focusable( this.tabs ); 29006 this._hoverable( this.tabs ); 29007 }, 29008 29009 _setupHeightStyle: function( heightStyle ) { 29010 var maxHeight, 29011 parent = this.element.parent(); 29012 29013 if ( heightStyle === "fill" ) { 29014 maxHeight = parent.height(); 29015 maxHeight -= this.element.outerHeight() - this.element.height(); 29016 29017 this.element.siblings( ":visible" ).each( function() { 29018 var elem = $( this ), 29019 position = elem.css( "position" ); 29020 29021 if ( position === "absolute" || position === "fixed" ) { 29022 return; 29023 } 29024 maxHeight -= elem.outerHeight( true ); 29025 } ); 29026 29027 this.element.children().not( this.panels ).each( function() { 29028 maxHeight -= $( this ).outerHeight( true ); 29029 } ); 29030 29031 this.panels.each( function() { 29032 $( this ).height( Math.max( 0, maxHeight - 29033 $( this ).innerHeight() + $( this ).height() ) ); 29034 } ) 29035 .css( "overflow", "auto" ); 29036 } else if ( heightStyle === "auto" ) { 29037 maxHeight = 0; 29038 this.panels.each( function() { 29039 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); 29040 } ).height( maxHeight ); 29041 } 29042 }, 29043 29044 _eventHandler: function( event ) { 29045 var options = this.options, 29046 active = this.active, 29047 anchor = $( event.currentTarget ), 29048 tab = anchor.closest( "li" ), 29049 clickedIsActive = tab[ 0 ] === active[ 0 ], 29050 collapsing = clickedIsActive && options.collapsible, 29051 toShow = collapsing ? $() : this._getPanelForTab( tab ), 29052 toHide = !active.length ? $() : this._getPanelForTab( active ), 29053 eventData = { 29054 oldTab: active, 29055 oldPanel: toHide, 29056 newTab: collapsing ? $() : tab, 29057 newPanel: toShow 29058 }; 29059 29060 event.preventDefault(); 29061 29062 if ( tab.hasClass( "ui-state-disabled" ) || 29063 29064 // tab is already loading 29065 tab.hasClass( "ui-tabs-loading" ) || 29066 29067 // can't switch durning an animation 29068 this.running || 29069 29070 // click on active header, but not collapsible 29071 ( clickedIsActive && !options.collapsible ) || 29072 29073 // allow canceling activation 29074 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { 29075 return; 29076 } 29077 29078 options.active = collapsing ? false : this.tabs.index( tab ); 29079 29080 this.active = clickedIsActive ? $() : tab; 29081 if ( this.xhr ) { 29082 this.xhr.abort(); 29083 } 29084 29085 if ( !toHide.length && !toShow.length ) { 29086 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); 29087 } 29088 29089 if ( toShow.length ) { 29090 this.load( this.tabs.index( tab ), event ); 29091 } 29092 this._toggle( event, eventData ); 29093 }, 29094 29095 // Handles show/hide for selecting tabs 29096 _toggle: function( event, eventData ) { 29097 var that = this, 29098 toShow = eventData.newPanel, 29099 toHide = eventData.oldPanel; 29100 29101 this.running = true; 29102 29103 function complete() { 29104 that.running = false; 29105 that._trigger( "activate", event, eventData ); 29106 } 29107 29108 function show() { 29109 that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); 29110 29111 if ( toShow.length && that.options.show ) { 29112 that._show( toShow, that.options.show, complete ); 29113 } else { 29114 toShow.show(); 29115 complete(); 29116 } 29117 } 29118 29119 // Start out by hiding, then showing, then completing 29120 if ( toHide.length && this.options.hide ) { 29121 this._hide( toHide, this.options.hide, function() { 29122 that._removeClass( eventData.oldTab.closest( "li" ), 29123 "ui-tabs-active", "ui-state-active" ); 29124 show(); 29125 } ); 29126 } else { 29127 this._removeClass( eventData.oldTab.closest( "li" ), 29128 "ui-tabs-active", "ui-state-active" ); 29129 toHide.hide(); 29130 show(); 29131 } 29132 29133 toHide.attr( "aria-hidden", "true" ); 29134 eventData.oldTab.attr( { 29135 "aria-selected": "false", 29136 "aria-expanded": "false" 29137 } ); 29138 29139 // If we're switching tabs, remove the old tab from the tab order.
vendor: 4,129 bytes, lines 29140-29311
29140 // If we're opening from collapsed state, remove the previous tab from the tab order. 29141 // If we're collapsing, then keep the collapsing tab in the tab order. 29142 if ( toShow.length && toHide.length ) { 29143 eventData.oldTab.attr( "tabIndex", -1 ); 29144 } else if ( toShow.length ) { 29145 this.tabs.filter( function() { 29146 return $( this ).attr( "tabIndex" ) === 0; 29147 } ) 29148 .attr( "tabIndex", -1 ); 29149 } 29150 29151 toShow.attr( "aria-hidden", "false" ); 29152 eventData.newTab.attr( { 29153 "aria-selected": "true", 29154 "aria-expanded": "true", 29155 tabIndex: 0 29156 } ); 29157 }, 29158 29159 _activate: function( index ) { 29160 var anchor, 29161 active = this._findActive( index ); 29162 29163 // Trying to activate the already active panel 29164 if ( active[ 0 ] === this.active[ 0 ] ) { 29165 return; 29166 } 29167 29168 // Trying to collapse, simulate a click on the current active header 29169 if ( !active.length ) { 29170 active = this.active; 29171 } 29172 29173 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; 29174 this._eventHandler( { 29175 target: anchor, 29176 currentTarget: anchor, 29177 preventDefault: $.noop 29178 } ); 29179 }, 29180 29181 _findActive: function( index ) { 29182 return index === false ? $() : this.tabs.eq( index ); 29183 }, 29184 29185 _getIndex: function( index ) { 29186 29187 // meta-function to give users option to provide a href string instead of a numerical index. 29188 if ( typeof index === "string" ) { 29189 index = this.anchors.index( this.anchors.filter( "[href$='" + 29190 $.escapeSelector( index ) + "']" ) ); 29191 } 29192 29193 return index; 29194 }, 29195 29196 _destroy: function() { 29197 if ( this.xhr ) { 29198 this.xhr.abort(); 29199 } 29200 29201 this.tablist 29202 .removeAttr( "role" ) 29203 .off( this.eventNamespace ); 29204 29205 this.anchors 29206 .removeAttr( "role tabIndex" ) 29207 .removeUniqueId(); 29208 29209 this.tabs.add( this.panels ).each( function() { 29210 if ( $.data( this, "ui-tabs-destroy" ) ) { 29211 $( this ).remove(); 29212 } else { 29213 $( this ).removeAttr( "role tabIndex " + 29214 "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); 29215 } 29216 } ); 29217 29218 this.tabs.each( function() { 29219 var li = $( this ), 29220 prev = li.data( "ui-tabs-aria-controls" ); 29221 if ( prev ) { 29222 li 29223 .attr( "aria-controls", prev ) 29224 .removeData( "ui-tabs-aria-controls" ); 29225 } else { 29226 li.removeAttr( "aria-controls" ); 29227 } 29228 } ); 29229 29230 this.panels.show(); 29231 29232 if ( this.options.heightStyle !== "content" ) { 29233 this.panels.css( "height", "" ); 29234 } 29235 }, 29236 29237 enable: function( index ) { 29238 var disabled = this.options.disabled; 29239 if ( disabled === false ) { 29240 return; 29241 } 29242 29243 if ( index === undefined ) { 29244 disabled = false; 29245 } else { 29246 index = this._getIndex( index ); 29247 if ( Array.isArray( disabled ) ) { 29248 disabled = $.map( disabled, function( num ) { 29249 return num !== index ? num : null; 29250 } ); 29251 } else { 29252 disabled = $.map( this.tabs, function( li, num ) { 29253 return num !== index ? num : null; 29254 } ); 29255 } 29256 } 29257 this._setOptionDisabled( disabled ); 29258 }, 29259 29260 disable: function( index ) { 29261 var disabled = this.options.disabled; 29262 if ( disabled === true ) { 29263 return; 29264 } 29265 29266 if ( index === undefined ) { 29267 disabled = true; 29268 } else { 29269 index = this._getIndex( index ); 29270 if ( $.inArray( index, disabled ) !== -1 ) { 29271 return; 29272 } 29273 if ( Array.isArray( disabled ) ) { 29274 disabled = $.merge( [ index ], disabled ).sort(); 29275 } else { 29276 disabled = [ index ]; 29277 } 29278 } 29279 this._setOptionDisabled( disabled ); 29280 }, 29281 29282 load: function( index, event ) { 29283 index = this._getIndex( index ); 29284 var that = this, 29285 tab = this.tabs.eq( index ), 29286 anchor = tab.find( ".ui-tabs-anchor" ), 29287 panel = this._getPanelForTab( tab ), 29288 eventData = { 29289 tab: tab, 29290 panel: panel 29291 }, 29292 complete = function( jqXHR, status ) { 29293 if ( status === "abort" ) { 29294 that.panels.stop( false, true ); 29295 } 29296 29297 that._removeClass( tab, "ui-tabs-loading" ); 29298 panel.removeAttr( "aria-busy" ); 29299 29300 if ( jqXHR === that.xhr ) { 29301 delete that.xhr; 29302 } 29303 }; 29304 29305 // Not remote 29306 if ( this._isLocal( anchor[ 0 ] ) ) { 29307 return; 29308 } 29309 29310 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); 29311
vendor: 17,064 bytes, lines 29312-29910
29312 // Support: jQuery <1.8 29313 // jQuery <1.8 returns false if the request is canceled in beforeSend, 29314 // but as of 1.8, $.ajax() always returns a jqXHR object. 29315 if ( this.xhr && this.xhr.statusText !== "canceled" ) { 29316 this._addClass( tab, "ui-tabs-loading" ); 29317 panel.attr( "aria-busy", "true" ); 29318 29319 this.xhr 29320 .done( function( response, status, jqXHR ) { 29321 29322 // support: jQuery <1.8 29323 // http://bugs.jquery.com/ticket/11778 29324 setTimeout( function() { 29325 panel.html( response ); 29326 that._trigger( "load", event, eventData ); 29327 29328 complete( jqXHR, status ); 29329 }, 1 ); 29330 } ) 29331 .fail( function( jqXHR, status ) { 29332 29333 // support: jQuery <1.8 29334 // http://bugs.jquery.com/ticket/11778 29335 setTimeout( function() { 29336 complete( jqXHR, status ); 29337 }, 1 ); 29338 } ); 29339 } 29340 }, 29341 29342 _ajaxSettings: function( anchor, event, eventData ) { 29343 var that = this; 29344 return { 29345 29346 // Support: IE <11 only 29347 // Strip any hash that exists to prevent errors with the Ajax request 29348 url: anchor.attr( "href" ).replace( /#.*$/, "" ), 29349 beforeSend: function( jqXHR, settings ) { 29350 return that._trigger( "beforeLoad", event, 29351 $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); 29352 } 29353 }; 29354 }, 29355 29356 _getPanelForTab: function( tab ) { 29357 var id = $( tab ).attr( "aria-controls" ); 29358 return this.element.find( this._sanitizeSelector( "#" + id ) ); 29359 } 29360} ); 29361 29362// DEPRECATED 29363// TODO: Switch return back to widget declaration at top of file when this is removed 29364if ( $.uiBackCompat !== false ) { 29365 29366 // Backcompat for ui-tab class (now ui-tabs-tab) 29367 $.widget( "ui.tabs", $.ui.tabs, { 29368 _processTabs: function() { 29369 this._superApply( arguments ); 29370 this._addClass( this.tabs, "ui-tab" ); 29371 } 29372 } ); 29373} 29374 29375var widgetsTabs = $.ui.tabs; 29376 29377 29378/*! 29379 * jQuery UI Tooltip 1.13.2 29380 * http://jqueryui.com 29381 * 29382 * Copyright jQuery Foundation and other contributors 29383 * Released under the MIT license. 29384 * http://jquery.org/license 29385 */ 29386 29387//>>label: Tooltip 29388//>>group: Widgets 29389//>>description: Shows additional information for any element on hover or focus. 29390//>>docs: http://api.jqueryui.com/tooltip/ 29391//>>demos: http://jqueryui.com/tooltip/ 29392//>>css.structure: ../../themes/base/core.css 29393//>>css.structure: ../../themes/base/tooltip.css 29394//>>css.theme: ../../themes/base/theme.css 29395 29396 29397$.widget( "ui.tooltip", { 29398 version: "1.13.2", 29399 options: { 29400 classes: { 29401 "ui-tooltip": "ui-corner-all ui-widget-shadow" 29402 }, 29403 content: function() { 29404 var title = $( this ).attr( "title" ); 29405 29406 // Escape title, since we're going from an attribute to raw HTML 29407 return $( "<a>" ).text( title ).html(); 29408 }, 29409 hide: true, 29410 29411 // Disabled elements have inconsistent behavior across browsers (#8661) 29412 items: "[title]:not([disabled])", 29413 position: { 29414 my: "left top+15", 29415 at: "left bottom", 29416 collision: "flipfit flip" 29417 }, 29418 show: true, 29419 track: false, 29420 29421 // Callbacks 29422 close: null, 29423 open: null 29424 }, 29425 29426 _addDescribedBy: function( elem, id ) { 29427 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); 29428 describedby.push( id ); 29429 elem 29430 .data( "ui-tooltip-id", id ) 29431 .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); 29432 }, 29433 29434 _removeDescribedBy: function( elem ) { 29435 var id = elem.data( "ui-tooltip-id" ), 29436 describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), 29437 index = $.inArray( id, describedby ); 29438 29439 if ( index !== -1 ) { 29440 describedby.splice( index, 1 ); 29441 } 29442 29443 elem.removeData( "ui-tooltip-id" ); 29444 describedby = String.prototype.trim.call( describedby.join( " " ) ); 29445 if ( describedby ) { 29446 elem.attr( "aria-describedby", describedby ); 29447 } else { 29448 elem.removeAttr( "aria-describedby" ); 29449 } 29450 }, 29451 29452 _create: function() { 29453 this._on( { 29454 mouseover: "open", 29455 focusin: "open" 29456 } ); 29457 29458 // IDs of generated tooltips, needed for destroy 29459 this.tooltips = {}; 29460 29461 // IDs of parent tooltips where we removed the title attribute 29462 this.parents = {}; 29463 29464 // Append the aria-live region so tooltips announce correctly 29465 this.liveRegion = $( "<div>" ) 29466 .attr( { 29467 role: "log", 29468 "aria-live": "assertive", 29469 "aria-relevant": "additions" 29470 } ) 29471 .appendTo( this.document[ 0 ].body ); 29472 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); 29473 29474 this.disabledTitles = $( [] ); 29475 }, 29476 29477 _setOption: function( key, value ) { 29478 var that = this; 29479 29480 this._super( key, value ); 29481 29482 if ( key === "content" ) { 29483 $.each( this.tooltips, function( id, tooltipData ) { 29484 that._updateContent( tooltipData.element ); 29485 } ); 29486 } 29487 }, 29488 29489 _setOptionDisabled: function( value ) { 29490 this[ value ? "_disable" : "_enable" ](); 29491 }, 29492 29493 _disable: function() { 29494 var that = this; 29495 29496 // Close open tooltips 29497 $.each( this.tooltips, function( id, tooltipData ) { 29498 var event = $.Event( "blur" ); 29499 event.target = event.currentTarget = tooltipData.element[ 0 ]; 29500 that.close( event, true ); 29501 } ); 29502 29503 // Remove title attributes to prevent native tooltips 29504 this.disabledTitles = this.disabledTitles.add( 29505 this.element.find( this.options.items ).addBack() 29506 .filter( function() { 29507 var element = $( this ); 29508 if ( element.is( "[title]" ) ) { 29509 return element 29510 .data( "ui-tooltip-title", element.attr( "title" ) ) 29511 .removeAttr( "title" ); 29512 } 29513 } ) 29514 ); 29515 }, 29516 29517 _enable: function() { 29518 29519 // restore title attributes 29520 this.disabledTitles.each( function() { 29521 var element = $( this ); 29522 if ( element.data( "ui-tooltip-title" ) ) { 29523 element.attr( "title", element.data( "ui-tooltip-title" ) ); 29524 } 29525 } ); 29526 this.disabledTitles = $( [] ); 29527 }, 29528 29529 open: function( event ) { 29530 var that = this, 29531 target = $( event ? event.target : this.element ) 29532 29533 // we need closest here due to mouseover bubbling, 29534 // but always pointing at the same event target 29535 .closest( this.options.items ); 29536 29537 // No element to show a tooltip for or the tooltip is already open 29538 if ( !target.length || target.data( "ui-tooltip-id" ) ) { 29539 return; 29540 } 29541 29542 if ( target.attr( "title" ) ) { 29543 target.data( "ui-tooltip-title", target.attr( "title" ) ); 29544 } 29545 29546 target.data( "ui-tooltip-open", true ); 29547 29548 // Kill parent tooltips, custom or native, for hover 29549 if ( event && event.type === "mouseover" ) { 29550 target.parents().each( function() { 29551 var parent = $( this ), 29552 blurEvent; 29553 if ( parent.data( "ui-tooltip-open" ) ) { 29554 blurEvent = $.Event( "blur" ); 29555 blurEvent.target = blurEvent.currentTarget = this; 29556 that.close( blurEvent, true ); 29557 } 29558 if ( parent.attr( "title" ) ) { 29559 parent.uniqueId(); 29560 that.parents[ this.id ] = { 29561 element: this, 29562 title: parent.attr( "title" ) 29563 }; 29564 parent.attr( "title", "" ); 29565 } 29566 } ); 29567 } 29568 29569 this._registerCloseHandlers( event, target ); 29570 this._updateContent( target, event ); 29571 }, 29572 29573 _updateContent: function( target, event ) { 29574 var content, 29575 contentOption = this.options.content, 29576 that = this, 29577 eventType = event ? event.type : null; 29578 29579 if ( typeof contentOption === "string" || contentOption.nodeType || 29580 contentOption.jquery ) { 29581 return this._open( event, target, contentOption ); 29582 } 29583 29584 content = contentOption.call( target[ 0 ], function( response ) { 29585 29586 // IE may instantly serve a cached response for ajax requests 29587 // delay this call to _open so the other call to _open runs first 29588 that._delay( function() { 29589 29590 // Ignore async response if tooltip was closed already 29591 if ( !target.data( "ui-tooltip-open" ) ) { 29592 return; 29593 } 29594 29595 // JQuery creates a special event for focusin when it doesn't 29596 // exist natively. To improve performance, the native event 29597 // object is reused and the type is changed. Therefore, we can't 29598 // rely on the type being correct after the event finished 29599 // bubbling, so we set it back to the previous value. (#8740) 29600 if ( event ) { 29601 event.type = eventType; 29602 } 29603 this._open( event, target, response ); 29604 } ); 29605 } ); 29606 if ( content ) { 29607 this._open( event, target, content ); 29608 } 29609 }, 29610 29611 _open: function( event, target, content ) { 29612 var tooltipData, tooltip, delayedShow, a11yContent, 29613 positionOption = $.extend( {}, this.options.position ); 29614 29615 if ( !content ) { 29616 return; 29617 } 29618 29619 // Content can be updated multiple times. If the tooltip already 29620 // exists, then just update the content and bail. 29621 tooltipData = this._find( target ); 29622 if ( tooltipData ) { 29623 tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); 29624 return; 29625 } 29626 29627 // If we have a title, clear it to prevent the native tooltip 29628 // we have to check first to avoid defining a title if none exists 29629 // (we don't want to cause an element to start matching [title]) 29630 // 29631 // We use removeAttr only for key events, to allow IE to export the correct 29632 // accessible attributes. For mouse events, set to empty string to avoid 29633 // native tooltip showing up (happens only when removing inside mouseover). 29634 if ( target.is( "[title]" ) ) { 29635 if ( event && event.type === "mouseover" ) { 29636 target.attr( "title", "" ); 29637 } else { 29638 target.removeAttr( "title" ); 29639 } 29640 } 29641 29642 tooltipData = this._tooltip( target ); 29643 tooltip = tooltipData.tooltip; 29644 this._addDescribedBy( target, tooltip.attr( "id" ) ); 29645 tooltip.find( ".ui-tooltip-content" ).html( content ); 29646 29647 // Support: Voiceover on OS X, JAWS on IE <= 9 29648 // JAWS announces deletions even when aria-relevant="additions" 29649 // Voiceover will sometimes re-read the entire log region's contents from the beginning 29650 this.liveRegion.children().hide(); 29651 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); 29652 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); 29653 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); 29654 a11yContent.appendTo( this.liveRegion ); 29655 29656 function position( event ) { 29657 positionOption.of = event; 29658 if ( tooltip.is( ":hidden" ) ) { 29659 return; 29660 } 29661 tooltip.position( positionOption ); 29662 } 29663 if ( this.options.track && event && /^mouse/.test( event.type ) ) { 29664 this._on( this.document, { 29665 mousemove: position 29666 } ); 29667 29668 // trigger once to override element-relative positioning 29669 position( event ); 29670 } else { 29671 tooltip.position( $.extend( { 29672 of: target 29673 }, this.options.position ) ); 29674 } 29675 29676 tooltip.hide(); 29677 29678 this._show( tooltip, this.options.show ); 29679 29680 // Handle tracking tooltips that are shown with a delay (#8644). As soon 29681 // as the tooltip is visible, position the tooltip using the most recent 29682 // event. 29683 // Adds the check to add the timers only when both delay and track options are set (#14682) 29684 if ( this.options.track && this.options.show && this.options.show.delay ) { 29685 delayedShow = this.delayedShow = setInterval( function() { 29686 if ( tooltip.is( ":visible" ) ) { 29687 position( positionOption.of ); 29688 clearInterval( delayedShow ); 29689 } 29690 }, 13 ); 29691 } 29692 29693 this._trigger( "open", event, { tooltip: tooltip } ); 29694 }, 29695 29696 _registerCloseHandlers: function( event, target ) { 29697 var events = { 29698 keyup: function( event ) { 29699 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { 29700 var fakeEvent = $.Event( event ); 29701 fakeEvent.currentTarget = target[ 0 ]; 29702 this.close( fakeEvent, true ); 29703 } 29704 } 29705 }; 29706 29707 // Only bind remove handler for delegated targets. Non-delegated 29708 // tooltips will handle this in destroy. 29709 if ( target[ 0 ] !== this.element[ 0 ] ) { 29710 events.remove = function() { 29711 var targetElement = this._find( target ); 29712 if ( targetElement ) { 29713 this._removeTooltip( targetElement.tooltip ); 29714 } 29715 }; 29716 } 29717 29718 if ( !event || event.type === "mouseover" ) { 29719 events.mouseleave = "close"; 29720 } 29721 if ( !event || event.type === "focusin" ) { 29722 events.focusout = "close"; 29723 } 29724 this._on( true, target, events ); 29725 }, 29726 29727 close: function( event ) { 29728 var tooltip, 29729 that = this, 29730 target = $( event ? event.currentTarget : this.element ), 29731 tooltipData = this._find( target ); 29732 29733 // The tooltip may already be closed 29734 if ( !tooltipData ) { 29735 29736 // We set ui-tooltip-open immediately upon open (in open()), but only set the 29737 // additional data once there's actually content to show (in _open()). So even if the 29738 // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in 29739 // the period between open() and _open(). 29740 target.removeData( "ui-tooltip-open" ); 29741 return; 29742 } 29743 29744 tooltip = tooltipData.tooltip; 29745 29746 // Disabling closes the tooltip, so we need to track when we're closing 29747 // to avoid an infinite loop in case the tooltip becomes disabled on close 29748 if ( tooltipData.closing ) { 29749 return; 29750 } 29751 29752 // Clear the interval for delayed tracking tooltips 29753 clearInterval( this.delayedShow ); 29754 29755 // Only set title if we had one before (see comment in _open()) 29756 // If the title attribute has changed since open(), don't restore 29757 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { 29758 target.attr( "title", target.data( "ui-tooltip-title" ) ); 29759 } 29760 29761 this._removeDescribedBy( target ); 29762 29763 tooltipData.hiding = true; 29764 tooltip.stop( true ); 29765 this._hide( tooltip, this.options.hide, function() { 29766 that._removeTooltip( $( this ) ); 29767 } ); 29768 29769 target.removeData( "ui-tooltip-open" ); 29770 this._off( target, "mouseleave focusout keyup" ); 29771 29772 // Remove 'remove' binding only on delegated targets 29773 if ( target[ 0 ] !== this.element[ 0 ] ) { 29774 this._off( target, "remove" ); 29775 } 29776 this._off( this.document, "mousemove" ); 29777 29778 if ( event && event.type === "mouseleave" ) { 29779 $.each( this.parents, function( id, parent ) { 29780 $( parent.element ).attr( "title", parent.title ); 29781 delete that.parents[ id ]; 29782 } ); 29783 } 29784 29785 tooltipData.closing = true; 29786 this._trigger( "close", event, { tooltip: tooltip } ); 29787 if ( !tooltipData.hiding ) { 29788 tooltipData.closing = false; 29789 } 29790 }, 29791 29792 _tooltip: function( element ) { 29793 var tooltip = $( "<div>" ).attr( "role", "tooltip" ), 29794 content = $( "<div>" ).appendTo( tooltip ), 29795 id = tooltip.uniqueId().attr( "id" ); 29796 29797 this._addClass( content, "ui-tooltip-content" ); 29798 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); 29799 29800 tooltip.appendTo( this._appendTo( element ) ); 29801 29802 return this.tooltips[ id ] = { 29803 element: element, 29804 tooltip: tooltip 29805 }; 29806 }, 29807 29808 _find: function( target ) { 29809 var id = target.data( "ui-tooltip-id" ); 29810 return id ? this.tooltips[ id ] : null; 29811 }, 29812 29813 _removeTooltip: function( tooltip ) { 29814 29815 // Clear the interval for delayed tracking tooltips 29816 clearInterval( this.delayedShow ); 29817 29818 tooltip.remove(); 29819 delete this.tooltips[ tooltip.attr( "id" ) ]; 29820 }, 29821 29822 _appendTo: function( target ) { 29823 var element = target.closest( ".ui-front, dialog" ); 29824 29825 if ( !element.length ) { 29826 element = this.document[ 0 ].body; 29827 } 29828 29829 return element; 29830 }, 29831 29832 _destroy: function() { 29833 var that = this; 29834 29835 // Close open tooltips 29836 $.each( this.tooltips, function( id, tooltipData ) { 29837 29838 // Delegate to close method to handle common cleanup 29839 var event = $.Event( "blur" ), 29840 element = tooltipData.element; 29841 event.target = event.currentTarget = element[ 0 ]; 29842 that.close( event, true ); 29843 29844 // Remove immediately; destroying an open tooltip doesn't use the 29845 // hide animation 29846 $( "#" + id ).remove(); 29847 29848 // Restore the title 29849 if ( element.data( "ui-tooltip-title" ) ) { 29850 29851 // If the title attribute has changed since open(), don't restore 29852 if ( !element.attr( "title" ) ) { 29853 element.attr( "title", element.data( "ui-tooltip-title" ) ); 29854 } 29855 element.removeData( "ui-tooltip-title" ); 29856 } 29857 } ); 29858 this.liveRegion.remove(); 29859 } 29860} ); 29861 29862// DEPRECATED 29863// TODO: Switch return back to widget declaration at top of file when this is removed 29864if ( $.uiBackCompat !== false ) { 29865 29866 // Backcompat for tooltipClass option 29867 $.widget( "ui.tooltip", $.ui.tooltip, { 29868 options: { 29869 tooltipClass: null 29870 }, 29871 _tooltip: function() { 29872 var tooltipData = this._superApply( arguments ); 29873 if ( this.options.tooltipClass ) { 29874 tooltipData.tooltip.addClass( this.options.tooltipClass ); 29875 } 29876 return tooltipData; 29877 } 29878 } ); 29879} 29880 29881var widgetsTooltip = $.ui.tooltip; 29882 29883 29884 29885 29886} ); 29887// jquery.dialog 29888(function () { 29889 29890 var dialog = jQuery.fn.dialog; 29891 29892 jQuery.fn.dialog = function() { 29893 29894 var check_methods = ['destroy', 'close']; 29895 29896 if (arguments && arguments.length > 0 && check_methods.indexOf(arguments[0]) > -1) { 29897 try { 29898 return dialog.apply(this, arguments); 29899 } catch(err) { 29900 // if we call methods on dialog prior to initialization and error will be thrown, 29901 // just ignore it. 29902 return this; 29903 } 29904 } 29905 29906 return dialog.apply(this, arguments); 29907 } 29908 29909})(); 29910// ColorBox v1.3.15 - a full featured, light-weight, customizable lightbox based on jQuery 1.3+
29911// Copyright (c) 2010 Jack Moore - [email protected] 29912// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 29913(function ($, window) { 29914 29915 var 29916 // ColorBox Default Settings. 29917 // See http://colorpowered.com/colorbox for details. 29918 defaults = { 29919 transition: "elastic", 29920 speed: 300, 29921 width: false, 29922 initialWidth: "600", 29923 innerWidth: false, 29924 maxWidth: false, 29925 height: false, 29926 initialHeight: "450", 29927 innerHeight: false, 29928 maxHeight: false, 29929 scalePhotos: true, 29930 scrolling: true, 29931 inline: false, 29932 html: false, 29933 iframe: false, 29934 photo: false, 29935 href: false, 29936 title: false, 29937 rel: false, 29938 opacity: 0.9, 29939 preloading: true, 29940 current: "image {current} of {total}", 29941 previous: "previous", 29942 next: "next", 29943 close: "close", 29944 open: false, 29945 returnFocus: true, 29946 loop: true, 29947 slideshow: false, 29948 slideshowAuto: true, 29949 slideshowSpeed: 2500, 29950 slideshowStart: "start slideshow", 29951 slideshowStop: "stop slideshow", 29952 onOpen: false, 29953 onLoad: false, 29954 onComplete: false, 29955 onCleanup: false, 29956 onClosed: false, 29957 overlayClose: true, 29958 escKey: true, 29959 arrowKey: true 29960 }, 29961 29962 // Abstracting the HTML and event identifiers for easy rebranding 29963 colorbox = 'colorbox', 29964 prefix = 'cbox', 29965 29966 // Events 29967 event_open = prefix + '_open', 29968 event_load = prefix + '_load', 29969 event_complete = prefix + '_complete', 29970 event_cleanup = prefix + '_cleanup', 29971 event_closed = prefix + '_closed', 29972 event_purge = prefix + '_purge', 29973 event_loaded = prefix + '_loaded', 29974 29975 // Special Handling for IE
29976 isIE = $.browser.msie && !$.support.opacity, // feature detection alone gave a false positive on at least one phone browser and on some development versions of Chrome. 29977 isIE6 = isIE && $.browser.version < 7, 29978 event_ie6 = prefix + '_IE6', 29979 29980 // Cached jQuery Object Variables 29981 $overlay, 29982 $box, 29983 $wrap, 29984 $content, 29985 $topBorder, 29986 $leftBorder, 29987 $rightBorder, 29988 $bottomBorder, 29989 $related, 29990 $window, 29991 $loaded, 29992 $loadingBay, 29993 $loadingOverlay, 29994 $title, 29995 $current, 29996 $slideshow, 29997 $next, 29998 $prev, 29999 $close, 30000 30001 // Variables for cached values or use across multiple functions 30002 interfaceHeight, 30003 interfaceWidth, 30004 loadedHeight, 30005 loadedWidth, 30006 element, 30007 index, 30008 settings, 30009 open, 30010 active, 30011 closing = false, 30012 30013 publicMethod, 30014 boxElement = prefix + 'Element'; 30015 30016 // **************** 30017 // HELPER FUNCTIONS 30018 // **************** 30019 30020 // jQuery object generator to reduce code size 30021 function $div(id, css) { 30022 id = id ? ' id="' + prefix + id + '"' : ''; 30023 css = css ? ' style="' + css + '"' : ''; 30024 return $('<div' + id + css + '/>'); 30025 } 30026 30027 // Convert % values to pixels 30028 function setSize(size, dimension) { 30029 dimension = dimension === 'x' ? $window.width() : $window.height(); 30030 return (typeof size === 'string') ? Math.round((/%/.test(size) ? (dimension / 100) * parseInt(size, 10) : parseInt(size, 10))) : size; 30031 } 30032 30033 // Checks an href to see if it is a photo. 30034 // There is a force photo option (photo: true) for hrefs that cannot be matched by this regex. 30035 function isImage(url) { 30036 return settings.photo || /\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i.test(url); 30037 } 30038 30039 // Assigns function results to their respective settings. This allows functions to be used as values. 30040 function process(settings) { 30041 for (var i in settings) { 30042 if ($.isFunction(settings[i]) && i.substring(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time. 30043 settings[i] = settings[i].call(element); 30044 } 30045 } 30046 settings.rel = settings.rel || element.rel || 'nofollow'; 30047 settings.href = settings.href || $(element).attr('href'); 30048 settings.title = settings.title || element.title; 30049 return settings; 30050 } 30051 30052 function trigger(event, callback) { 30053 if (callback) { 30054 callback.call(element); 30055 } 30056 $.event.trigger(event); 30057 } 30058 30059 // Slideshow functionality 30060 function slideshow() { 30061 var 30062 timeOut, 30063 className = prefix + "Slideshow_", 30064 click = "click." + prefix, 30065 start, 30066 stop, 30067 clear; 30068 30069 if (settings.slideshow && $related[1]) { 30070 start = function () { 30071 $slideshow 30072 .text(settings.slideshowStop) 30073 .unbind(click) 30074 .bind(event_complete, function () { 30075 if (index < $related.length - 1 || settings.loop) { 30076 timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); 30077 } 30078 }) 30079 .bind(event_load, function () { 30080 clearTimeout(timeOut); 30081 }) 30082 .one(click + ' ' + event_cleanup, stop); 30083 $box.removeClass(className + "off").addClass(className + "on"); 30084 timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); 30085 }; 30086 30087 stop = function () { 30088 clearTimeout(timeOut); 30089 $slideshow 30090 .text(settings.slideshowStart) 30091 .unbind([event_complete, event_load, event_cleanup, click].join(' ')) 30092 .one(click, start); 30093 $box.removeClass(className + "on").addClass(className + "off"); 30094 }; 30095 30096 if (settings.slideshowAuto) { 30097 start(); 30098 } else { 30099 stop(); 30100 } 30101 } 30102 } 30103 30104 function launch(elem) { 30105 if (!closing) { 30106 30107 element = elem; 30108 30109 settings = process($.extend({}, $.data(element, colorbox))); 30110 30111 $related = $(element); 30112 30113 index = 0; 30114 30115 if (settings.rel !== 'nofollow') { 30116 $related = $('.' + boxElement).filter(function () { 30117 var relRelated = $.data(this, colorbox).rel || this.rel; 30118 return (relRelated === settings.rel); 30119 }); 30120 index = $related.index(element); 30121 30122 // Check direct calls to ColorBox. 30123 if (index === -1) { 30124 $related = $related.add(element); 30125 index = $related.length - 1; 30126 } 30127 } 30128 30129 if (!open) { 30130 open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right
30130keys. 30131 30132 $box.show(); 30133 30134 if (settings.returnFocus) { 30135 try { 30136 element.blur(); 30137 $(element).one(event_closed, function () { 30138 try { 30139 this.focus(); 30140 } catch (e) { 30141 // do nothing 30142 } 30143 }); 30144 } catch (e) { 30145 // do nothing 30146 } 30147 } 30148 30149 // +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5' 30150 $overlay.css({"opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto"}).show(); 30151 30152 // Opens inital empty ColorBox prior to content being loaded. 30153 settings.w = setSize(settings.initialWidth, 'x'); 30154 settings.h = setSize(settings.initialHeight, 'y'); 30155 publicMethod.position(0); 30156 30157 if (isIE6) { 30158 $window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () { 30159 $overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()}); 30160 }).trigger('scroll.' + event_ie6); 30161 } 30162 30163 trigger(event_open, settings.onOpen); 30164 30165 $current.add($prev).add($next).add($slideshow).add($title).hide(); 30166 30167 $close.html(settings.close).show(); 30168 } 30169 30170 publicMethod.load(true); 30171 } 30172 } 30173 30174 // **************** 30175 // PUBLIC FUNCTIONS 30176 // Usage format: $.fn.colorbox.close(); 30177 // Usage from within an iframe: parent.$.fn.colorbox.close(); 30178 // **************** 30179 30180 publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) { 30181 var $this = this, autoOpen; 30182 30183 if (!$this[0] && $this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit. 30184 return $this; 30185 } 30186 30187 options = options || {}; 30188 30189 if (callback) { 30190 options.onComplete = callback; 30191 } 30192 30193 if (!$this[0] || $this.selector === undefined) { // detects $.colorbox() and $.fn.colorbox() 30194 $this = $('<a/>'); 30195 options.open = true; // assume an immediate open 30196 } 30197 30198 $this.each(function () { 30199 $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options)); 30200 $(this).addClass(boxElement); 30201 }); 30202 30203 autoOpen = options.open; 30204 30205 if ($.isFunction(autoOpen)) { 30206 autoOpen = autoOpen.call($this); 30207 } 30208 30209 if (autoOpen) { 30210 launch($this[0]); 30211 } 30212 30213 return $this; 30214 }; 30215 30216 // Initialize ColorBox: store common calculations, preload the interface graphics, append the html. 30217 // This preps colorbox for a speedy open when clicked, and lightens the burdon on the browser by only 30218 // having to run once, instead of each time colorbox is opened. 30219 publicMethod.init = function () { 30220 // Create & Append jQuery Objects 30221 $window = $(window); 30222 $box = $div().attr({id: colorbox, 'class': isIE ? prefix + 'IE' : ''}); 30223 $overlay = $div("Overlay", isIE6 ? 'position:absolute' : '').hide(); 30224 30225 $wrap = $div("Wrapper"); 30226 $content = $div("Content").append( 30227 $loaded = $div("LoadedContent", 'width:0; height:0; overflow:hidden'), 30228 $loadingOverlay = $div("LoadingOverlay").add($div("LoadingGraphic")), 30229 $title = $div("Title"), 30230 $current = $div("Current"), 30231 $next = $div("Next"), 30232 $prev = $div("Previous"), 30233 $slideshow = $div("Slideshow").bind(event_open, slideshow), 30234 $close = $div("Close") 30235 ); 30236 $wrap.append( // The 3x3 Grid that makes up ColorBox 30237 $div().append( 30238 $div("TopLeft"), 30239 $topBorder = $div("TopCenter"), 30240 $div("TopRight") 30241 ), 30242 $div(false, 'clear:left').append( 30243 $leftBorder = $div("MiddleLeft"), 30244 $content, 30245 $rightBorder = $div("MiddleRight") 30246 ), 30247 $div(false, 'clear:left').append( 30248 $div("BottomLeft"), 30249 $bottomBorder = $div("BottomCenter"), 30250 $div("BottomRight") 30251 ) 30252 ).children().children().css({'float': 'left'}); 30253 30254 $loadingBay = $div(false, 'position:absolute; width:9999px; visibility:hidden; display:none'); 30255 30256 $('body').prepend($overlay, $box.append($wrap, $loadingBay)); 30257 30258 $content.children() 30259 .hover(function () { 30260 $(this).addClass('hover'); 30261 }, function () { 30262 $(this).removeClass('hover'); 30263 }).addClass('hover'); 30264 30265 // Cache values needed for size calculations 30266 interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6 30267 interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width(); 30268 loadedHeight = $loaded.outerHeight(true); 30269 loadedWidth = $loaded.outerWidth(true); 30270 30271 // Setting padding to remove the need to do size conversions during the animation step. 30272 $box.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth}).hide(); 30273 30274 // Setup button events. 30275 $next.click(publicMethod.next); 30276 $prev.click(publicMethod.prev); 30277 $close.click(publicMethod.close); 30278
30279 // Adding the 'hover' class allowed the browser to load the hover-state 30280 // background graphics. The class can now can be removed. 30281 $content.children().removeClass('hover'); 30282 30283 $('.' + boxElement).live('click', function (e) { 30284 // checks to see if it was a non-left mouse-click and for clicks modified with ctrl, shift, or alt. 30285 if (!((e.button !== 0 && typeof e.button !== 'undefined') || e.ctrlKey || e.shiftKey || e.altKey)) { 30286 e.preventDefault(); 30287 launch(this); 30288 } 30289 }); 30290 30291 $overlay.click(function () { 30292 if (settings.overlayClose) { 30293 publicMethod.close(); 30294 } 30295 }); 30296 30297 // Set Navigation Key Bindings 30298 $(document).bind("keydown", function (e) { 30299 if (open && settings.escKey && e.keyCode === 27) { 30300 e.preventDefault(); 30301 publicMethod.close(); 30302 } 30303 if (open && settings.arrowKey && !active && $related[1]) { 30304 if (e.keyCode === 37 && (index || settings.loop)) { 30305 e.preventDefault(); 30306 $prev.click(); 30307 } else if (e.keyCode === 39 && (index < $related.length - 1 || settings.loop)) { 30308 e.preventDefault(); 30309 $next.click(); 30310 } 30311 } 30312 }); 30313 }; 30314 30315 publicMethod.remove = function () { 30316 $box.add($overlay).remove(); 30317 $('.' + boxElement).die('click').removeData(colorbox).removeClass(boxElement); 30318 }; 30319 30320 publicMethod.position = function (speed, loadedCallback) { 30321 var 30322 animate_speed, 30323 // keeps the top and left positions within the browser's viewport. 30324 posTop = Math.max(document.documentElement.clientHeight - settings.h - loadedHeight - interfaceHeight, 0) / 2 + $window.scrollTop(), 30325 posLeft = Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2 + $window.scrollLeft(); 30326 30327 // setting the speed to 0 to reduce the delay between same-sized content. 30328 animate_speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed; 30329 30330 // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly, 30331 // but it has to be shrank down around the size of div#colorbox when it's done. If not, 30332 // it can invoke an obscure IE bug when using iframes. 30333 $wrap[0].style.width = $wrap[0].style.height = "9999px"; 30334 30335 function modalDimensions(that) { 30336 // loading overlay height has to be explicitly set for IE6. 30337 $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width; 30338 $loadingOverlay[0].style.height = $loadingOverlay[1].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height; 30339 } 30340 30341 $box.dequeue().animate({width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: posTop, left: posLeft}, { 30342 duration: animate_speed, 30343 complete: function () { 30344 modalDimensions(this); 30345 30346 active = false; 30347 30348 // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation. 30349 $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px"; 30350 $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px"; 30351 30352 if (loadedCallback) { 30353 loadedCallback(); 30354 } 30355 }, 30356 step: function () { 30357 modalDimensions(this); 30358 } 30359 }); 30360 }; 30361 30362 publicMethod.resize = function (options) { 30363 if (open) { 30364 options = options || {}; 30365 30366 if (options.width) { 30367 settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth; 30368 } 30369 if (options.innerWidth) { 30370 settings.w = setSize(options.innerWidth, 'x'); 30371 } 30372 $loaded.css({width: settings.w}); 30373 30374 if (options.height) { 30375 settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight; 30376 } 30377 if (options.innerHeight) { 30378 settings.h = setSize(options.innerHeight, 'y'); 30379 } 30380 if (!options.innerHeight && !options.height) { 30381 var $child = $loaded.wrapInner("<div style='overflow:auto'></div>").children(); // temporary wrapper to get an accurate estimate of just how high the total content should be. 30382 settings.h = $child.height(); 30383 $child.replaceWith($child.children()); // ditch the temporary wrapper div used in height calculation 30384 } 30385 $loaded.css({height: settings.h}); 30386 30387 publicMethod.position(settings.transition === "none" ? 0 : settings.speed); 30388 } 30389 }; 30390 30391 publicMethod.prep = function (object) { 30392 if (!open) { 30393 return; 30394 } 30395 30396 var photo, 30397 speed = settings.transition === "none" ? 0 : settings.speed; 30398 30399 $window.unbind('resize.' + prefix); 30400 $loaded.remove(); 30401 $loaded = $div('LoadedContent').html(object); 30402 30403 function getWidth() { 30404 settings.w = settings.w || $loaded.width(); 30405 settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w; 30406 return settings.w; 30407 } 30408 function getHeight() { 30409 settings.h = settings.h || $loaded.height(); 30410 settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h; 30411 return settings.h; 30412 } 30413 30414 $loaded.hide() 30415 .appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations. 30416 .css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'}) 30417 .css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
30418 .prependTo($content); 30419 30420 $loadingBay.hide(); 30421 30422 // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width. 30423 $('#' + prefix + 'Photo').css({cssFloat: 'none', marginLeft: 'auto', marginRight: 'auto'}); 30424 30425 // Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay. 30426 if (isIE6) { 30427 $('select').not($box.find('select')).filter(function () { 30428 return this.style.visibility !== 'hidden'; 30429 }).css({'visibility': 'hidden'}).one(event_cleanup, function () { 30430 this.style.visibility = 'inherit'; 30431 }); 30432 } 30433 30434 function setPosition(s) { 30435 var prev, prevSrc, next, nextSrc, total = $related.length, loop = settings.loop; 30436 publicMethod.position(s, function () { 30437 function defilter() { 30438 if (isIE) { 30439 //IE adds a filter when ColorBox fades in and out that can cause problems if the loaded content contains transparent pngs. 30440 $box[0].style.removeAttribute("filter"); 30441 } 30442 } 30443 30444 if (!open) { 30445 return; 30446 } 30447 30448 if (isIE) { 30449 //This fadeIn helps the bicubic resampling to kick-in. 30450 if (photo) { 30451 $loaded.fadeIn(100); 30452 } 30453 } 30454 30455 $loaded.show(); 30456 30457 trigger(event_loaded); 30458
30459 $title.show().html(settings.title); 30460 30461 if (total > 1) { // handle grouping 30462 if (typeof settings.current === "string") { 30463 $current.html(settings.current.replace(/\{current\}/, index + 1).replace(/\{total\}/, total)).show(); 30464 } 30465 30466 $next[(loop || index < total - 1) ? "show" : "hide"]().html(settings.next); 30467 $prev[(loop || index) ? "show" : "hide"]().html(settings.previous); 30468 30469 prev = index ? $related[index - 1] : $related[total - 1]; 30470 next = index < total - 1 ? $related[index + 1] : $related[0]; 30471 30472 if (settings.slideshow) { 30473 $slideshow.show(); 30474 } 30475 30476 // Preloads images within a rel group 30477 if (settings.preloading) { 30478 nextSrc = $.data(next, colorbox).href || next.href; 30479 prevSrc = $.data(prev, colorbox).href || prev.href; 30480 30481 nextSrc = $.isFunction(nextSrc) ? nextSrc.call(next) : nextSrc; 30482 prevSrc = $.isFunction(prevSrc) ? prevSrc.call(prev) : prevSrc; 30483 30484 if (isImage(nextSrc)) { 30485 $('<img/>')[0].src = nextSrc; 30486 } 30487 30488 if (isImage(prevSrc)) { 30489 $('<img/>')[0].src = prevSrc; 30490 } 30491 } 30492 } 30493 30494 $loadingOverlay.hide(); 30495 30496 if (settings.transition === 'fade') { 30497 $box.fadeTo(speed, 1, function () { 30498 defilter(); 30499 }); 30500 } else { 30501 defilter(); 30502 } 30503 30504 $window.bind('resize.' + prefix, function () { 30505 publicMethod.position(0); 30506 }); 30507 30508 trigger(event_complete, settings.onComplete); 30509 }); 30510 } 30511 30512 if (settings.transition === 'fade') { 30513 $box.fadeTo(speed, 0, function () { 30514 setPosition(0); 30515 }); 30516 } else { 30517 setPosition(speed); 30518 } 30519 }; 30520 30521 publicMethod.load = function (launched) { 30522 var href, img, setResize, prep = publicMethod.prep; 30523 30524 active = true; 30525 element = $related[index]; 30526 30527 if (!launched) { 30528 settings = process($.extend({}, $.data(element, colorbox))); 30529 } 30530 30531 trigger(event_purge); 30532 30533 trigger(event_load, settings.onLoad); 30534 30535 settings.h = settings.height ? 30536 setSize(settings.height, 'y') - loadedHeight - interfaceHeight : 30537 settings.innerHeight && setSize(settings.innerHeight, 'y'); 30538 30539 settings.w = settings.width ? 30540 setSize(settings.width, 'x') - loadedWidth - interfaceWidth : 30541 settings.innerWidth && setSize(settings.innerWidth, 'x'); 30542 30543 // Sets the minimum dimensions for use in image scaling 30544 settings.mw = settings.w; 30545 settings.mh = settings.h; 30546
30547 // Re-evaluate the minimum width and height based on maxWidth and maxHeight values. 30548 // If the width or height exceed the maxWidth or maxHeight, use the maximum values instead. 30549 if (settings.maxWidth) { 30550 settings.mw = setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth; 30551 settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw; 30552 } 30553 if (settings.maxHeight) { 30554 settings.mh = setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight; 30555 settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh; 30556 } 30557 30558 href = settings.href; 30559 30560 $loadingOverlay.show(); 30561 30562 if (settings.inline) { 30563 // Inserts an empty placeholder where inline content is being pulled from. 30564 // An event is bound to put inline content back when ColorBox closes or loads new content. 30565 $div().hide().insertBefore($(href)[0]).one(event_purge, function () { 30566 $(this).replaceWith($loaded.children()); 30567 }); 30568 prep($(href)); 30569 } else if (settings.iframe) { 30570 // IFrame element won't be added to the DOM until it is ready to be displayed, 30571 // to avoid problems with DOM-ready JS that might be trying to run in that iframe. 30572 $box.one(event_loaded, function () { 30573 var iframe = $("<iframe frameborder='0' style='width:100%; height:100%; border:0; display:block'/>")[0]; 30574 iframe.name = prefix + (+new Date()); 30575 iframe.src = settings.href; 30576 30577 if (!settings.scrolling) { 30578 iframe.scrolling = "no"; 30579 } 30580 30581 if (isIE) { 30582 iframe.allowtransparency = "true"; 30583 } 30584 30585 $(iframe).appendTo($loaded).one(event_purge, function () { 30586 iframe.src = "//about:blank"; 30587 }); 30588 }); 30589 30590 prep(" "); 30591 } else if (settings.html) { 30592 prep(settings.html); 30593 } else if (isImage(href)) { 30594 img = new Image(); 30595 img.onload = function () { 30596 var percent; 30597 img.onload = null; 30598 img.id = prefix + 'Photo'; 30599 $(img).css({border: 'none', display: 'block', cssFloat: 'left'}); 30600 if (settings.scalePhotos) { 30601 setResize = function () { 30602 img.height -= img.height * percent; 30603 img.width -= img.width * percent; 30604 }; 30605 if (settings.mw && img.width > settings.mw) { 30606 percent = (img.width - settings.mw) / img.width; 30607 setResize(); 30608 } 30609 if (settings.mh && img.height > settings.mh) { 30610 percent = (img.height - settings.mh) / img.height; 30611 setResize(); 30612 } 30613 } 30614 30615 if (settings.h) { 30616 img.style.marginTop = Math.max(settings.h - img.height, 0) / 2 + 'px'; 30617 } 30618 30619 if ($related[1] && (index < $related.length - 1 || settings.loop)) { 30620 $(img).css({cursor: 'pointer'}).click(publicMethod.next); 30621 } 30622 30623 if (isIE) { 30624 img.style.msInterpolationMode = 'bicubic'; 30625 } 30626 30627 setTimeout(function () { // Chrome will sometimes report a 0 by 0 size if there isn't pause in execution 30628 prep(img); 30629 }, 1); 30630 }; 30631 30632 setTimeout(function () { // Opera 10.6+ will sometimes load the src before the onload function is set 30633 img.src = href; 30634 }, 1); 30635 } else if (href) { 30636 $loadingBay.load(href, function (data, status, xhr) { 30637 prep(status === 'error' ? 'Request unsuccessful: ' + xhr.statusText : $(this).children()); 30638 }); 30639 } 30640 }; 30641 30642 // Navigates to the next page/image in a set. 30643 publicMethod.next = function () { 30644 if (!active) { 30645 index = index < $related.length - 1 ? index + 1 : 0; 30646 publicMethod.load(); 30647 } 30648 }; 30649 30650 publicMethod.prev = function () { 30651 if (!active) { 30652 index = index ? index - 1 : $related.length - 1; 30653 publicMethod.load(); 30654 } 30655 }; 30656 30657 // Note: to use this within an iframe use the following format: parent.$.fn.colorbox.close(); 30658 publicMethod.close = function () { 30659 if (open && !closing) { 30660 closing = true; 30661 30662 open = false; 30663 30664 trigger(event_cleanup, settings.onCleanup); 30665 30666 $window.unbind('.' + prefix + ' .' + event_ie6); 30667 30668 $overlay.fadeTo('fast', 0); 30669 30670 $box.stop().fadeTo('fast', 0, function () { 30671 30672 trigger(event_purge); 30673 30674 $loaded.remove(); 30675 30676 $box.add($overlay).css({'opacity': 1, cursor: 'auto'}).hide(); 30677 30678 setTimeout(function () { 30679 closing = false; 30680 trigger(event_closed, settings.onClosed); 30681 }, 1); 30682 }); 30683 } 30684 }; 30685 30686 // A method for fetching the current element ColorBox is referencing. 30687 // returns a jQuery object. 30688 publicMethod.element = function () { 30689 return $(element); 30690 }; 30691 30692 publicMethod.settings = defaults; 30693 30694 // Initializes ColorBox when the DOM has loaded 30695 $(publicMethod.init); 30696 30697}(jQuery, this)); 30698/* 30699 Watermark plugin for jQuery 30700 Version: 3.0.6 30701 http://jquery-watermark.googlecode.com/ 30702
30703 Copyright (c) 2009-2010 Todd Northrop 30704 http://www.speednet.biz/ 30705 30706 June 21, 2010 30707 30708 Requires: jQuery 1.2.3+ 30709 30710 Dual licensed under the MIT or GPL Version 2 licenses. 30711 See mit-license.txt and gpl2-license.txt in the project root for details. 30712------------------------------------------------------*/ 30713 30714(function ($) { 30715 30716var 30717 // Will speed up references to undefined 30718 undefined, 30719 30720 // String constants for data names 30721 dataFlag = "watermark", 30722 dataClass = "watermarkClass", 30723 dataFocus = "watermarkFocus", 30724 dataFormSubmit = "watermarkSubmit", 30725 dataMaxLen = "watermarkMaxLength", 30726 dataPassword = "watermarkPassword", 30727 dataText = "watermarkText", 30728 30729 // Includes only elements with watermark defined 30730 selWatermarkDefined = ":data(" + dataFlag + ")", 30731 30732 // Includes only elements capable of having watermark 30733 selWatermarkAble = ":text,:password,:search,textarea", 30734 30735 // triggerFns: 30736 // Array of function names to look for in the global namespace. 30737 // Any such functions found will be hijacked to trigger a call to 30738 // hideAll() any time they are called. The default value is the 30739 // ASP.NET function that validates the controls on the page 30740 // prior to a postback. 30741 // 30742 // Am I missing other important trigger function(s) to look for? 30743 // Please leave me feedback: 30744 // http://code.google.com/p/jquery-watermark/issues/list 30745 triggerFns = [ 30746 "Page_ClientValidate" 30747 ], 30748 30749 // Holds a value of true if a watermark was displayed since the last 30750 // hideAll() was executed. Avoids repeatedly calling hideAll(). 30751 pageDirty = false; 30752 30753// Extends jQuery with a custom selector - ":data(...)" 30754// :data(<name>) Includes elements that have a specific name defined in the jQuery data collection. (Only the existence of the name is checked; the value is ignored.) 30755// :data(<name>=<value>) Includes elements that have a specific jQuery data name defined, with a specific value associated with it. 30756// :data(<name>!=<value>) Includes elements that have a specific jQuery data name defined, with a value that is not equal to the value specified. 30757// :data(<name>^=<value>) Includes elements that have a specific jQuery data name defined, with a value that starts with the value specified. 30758// :data(<name>$=<value>) Includes elements that have a specific jQuery data name defined, with a value that ends with the value specified. 30759// :data(<name>*=<value>) Includes elements that have a specific jQuery data name defined, with a value that contains the value specified. 30760$.extend($.expr[":"], { 30761 "search": function (elem) { 30762 return "search" === (elem.type || ""); 30763 }, 30764 30765 "data": function (element, index, matches, set) { 30766 var data, parts = /^((?:[^=!^$*]|[!^$*](?!=))+)(?:([!^$*]?=)(.*))?$/.exec(matches[3]); 30767 30768 if (parts) { 30769 data = $(element).data(parts[1]); 30770 30771 if (data !== undefined) { 30772 30773 if (parts[2]) { 30774 data = "" + data; 30775 30776 switch (parts[2]) { 30777 case "=": 30778 return (data == parts[3]); 30779 case "!=": 30780 return (data != parts[3]); 30781 case "^=": 30782 return (data.slice(0, parts[3].length) == parts[3]); 30783 case "$=": 30784 return (data.slice(-parts[3].length) == parts[3]); 30785 case "*=": 30786 return (data.indexOf(parts[3]) !== -1); 30787 } 30788 } 30789 30790 return true; 30791 } 30792 } 30793 30794 return false; 30795 } 30796}); 30797 30798$.watermark = { 30799 30800 // Current version number of the plugin 30801 version: "3.0.6", 30802 30803 // Default options used when watermarks are instantiated. 30804 // Can be changed to affect the default behavior for all 30805 // new or updated watermarks. 30806 // BREAKING CHANGE: The $.watermark.className 30807 // property that was present prior to version 3.0.2 must 30808 // be changed to $.watermark.options.className 30809 options: { 30810 30811 // Default class name for all watermarks 30812 className: "watermark", 30813 30814 // If true, plugin will detect and use native browser support for 30815 // watermarks, if available. (e.g., WebKit's placeholder attribute.) 30816 useNative: true 30817 }, 30818 30819 // Hide one or more watermarks by specifying any selector type 30820 // i.e., DOM element, string selector, jQuery matched set, etc. 30821 hide: function (selector) { 30822 $(selector).filter(selWatermarkDefined).each( 30823 function () { 30824 $.watermark._hide($(this)); 30825 } 30826 ); 30827 }, 30828 30829 // Internal use only. 30830 _hide: function ($input, focus) { 30831 var inputVal = $input.val() || "", 30832 inputWm = $input.data(dataText) || "", 30833 maxLen = $input.data(dataMaxLen) || 0, 30834 className = $input.data(dataClass); 30835 30836 if ((inputWm.length) && (inputVal == inputWm)) { 30837 $input.val(""); 30838 30839 // Password type? 30840 if ($input.data(dataPassword)) { 30841 30842 if (($input.attr("type") || "") === "text") { 30843 var $pwd = $input.data(dataPassword) || [], 30844 $wrap = $input.parent() || []; 30845 30846 if (($pwd.length) && ($wrap.length)) { 30847 $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data 30848 $wrap[0].appendChild($pwd[0]); 30849 $input = $pwd; 30850 } 30851 } 30852 } 30853 30854 if (maxLen) { 30855 $input.attr("maxLength", maxLen); 30856 $input.removeData(dataMaxLen); 30857 } 30858 30859 if (focus) { 30860 $input.attr("autocomplete", "off"); // Avoid NS_ERROR_XPC_JS_THREW_STRING error in Firefox 30861 30862 window.setTimeout( 30863 function () { 30864 $input.select(); // Fix missing cursor in IE 30865 } 30866 , 1); 30867 } 30868 } 30869 30870 className && $input.removeClass(className); 30871 }, 30872 30873 // Display one or more watermarks by specifying any selector type 30874 // i.e., DOM element, string selector, jQuery matched set, etc. 30875 // If conditions are not right for displaying a watermark, ensures that watermark is not shown. 30876 show: function (selector) { 30877 $(selector).filter(selWatermarkDefined).each( 30878 function () { 30879 $.watermark._show($(this)); 30880 } 30881 ); 30882 }, 30883 30884 // Internal use only. 30885 _show: function ($input) { 30886 var val = $input.val() || "", 30887 text = $input.data(dataText) || "", 30888 type = $input.attr("type") || "", 30889 className = $input.data(dataClass); 30890 30891 if (((val.length == 0) || (val == text)) && (!$input.data(data
30891Focus))) { 30892 pageDirty = true; 30893 30894 // Password type? 30895 if ($input.data(dataPassword)) { 30896 30897 if (type === "password") { 30898 var $pwd = $input.data(dataPassword) || [], 30899 $wrap = $input.parent() || []; 30900 30901 if (($pwd.length) && ($wrap.length)) { 30902 $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data 30903 $wrap[0].appendChild($pwd[0]); 30904 $input = $pwd; 30905 $input.attr("maxLength", text.length); 30906 } 30907 } 30908 } 30909 30910 // Ensure maxLength big enough to hold watermark (input of type="text" or type="search" only) 30911 if ((type === "text") || (type === "search")) { 30912 var maxLen = $input.attr("maxLength") || 0; 30913 30914 if ((maxLen > 0) && (text.length > maxLen)) { 30915 $input.data(dataMaxLen, maxLen); 30916 $input.attr("maxLength", text.length); 30917 } 30918 } 30919 30920 className && $input.addClass(className); 30921 $input.val(text); 30922 } 30923 else { 30924 $.watermark._hide($input); 30925 } 30926 }, 30927 30928 // Hides all watermarks on the current page. 30929 hideAll: function () { 30930 if (pageDirty) { 30931 $.watermark.hide(selWatermarkAble); 30932 pageDirty = false; 30933 } 30934 }, 30935 30936 // Displays all watermarks on the current page. 30937 showAll: function () { 30938 $.watermark.show(selWatermarkAble); 30939 } 30940}; 30941 30942$.fn.watermark = function (text, options) { 30943 /// <summary> 30944 /// Set watermark text and class name on all input elements of type="text/password/search" and 30945 /// textareas within the matched set. If className is not specified in options, the default is 30946 /// "watermark". Within the matched set, only input elements with type="text/password/search" 30947 /// and textareas are affected; all other elements are ignored. 30948 /// </summary> 30949 /// <returns type="jQuery"> 30950 /// Returns the original jQuery matched set (not just the input and texarea elements). 30951 /// </returns> 30952 /// <param name="text" type="String"> 30953 /// Text to display as a watermark when the input or textarea element has an empty value and does not 30954 /// have focus. The first time watermark() is called on an element, if this argument is empty (or not 30955 /// a String type), then the watermark will have the net effect of only changing the class name when 30956 /// the input or textarea element's value is empty and it does not have focus. 30957 /// </param> 30958 /// <param name="options" type="Object" optional="true"> 30959 /// Provides the ability to override the default watermark options ($.watermark.options). For backward 30960 /// compatibility, if a string value is supplied, it is used as the class name that overrides the class 30961 /// name in $.watermark.options.className. Properties include: 30962 /// className: When the watermark is visible, the element will be styled using this class name. 30963 /// useNative (Boolean or Function): Specifies if native browser support for watermarks will supersede 30964 /// plugin functionality. If useNative is a function, the return value from the function will 30965 /// determine if native support is used. The function is passed one argument -- a jQuery object 30966 /// containing the element being tested as the only element in its matched set -- and the DOM 30967 /// element being tested is the object on which the function is invoked (the value of "this"). 30968 /// </param> 30969 /// <remarks> 30970 /// The effect of changing the text and class name on an input element is called a watermark because 30971 /// typically light gray text is used to provide a hint as to what type of input is required. However, 30972 /// the appearance of the watermark can be something completely different: simply change the CSS style 30973 /// pertaining to the supplied class name. 30974 /// 30975 /// The first time watermark() is called on an element, the watermark text and class name are initialized, 30976 /// and the focus and blur events are hooked in order to control the display of the watermark. Also, as 30977 /// of version 3.0, drag and drop events are hooked to guard against dropped text being appended to the 30978 /// watermark. If native watermark support is provided by the browser, it is detected and used, unless 30979 /// the useNative option is set to false. 30980 /// 30981 /// Subsequently, watermark() can be called again on an element in order to change the watermark text 30982 /// and/or class name, and it can also be called without any arguments in order to refresh the display. 30983 /// 30984 /// For example, after changing the value of the input or textarea element programmatically, watermark() 30985 /// should be called without any arguments to refresh the display, because the change event is only 30986 /// triggered by user actions, not by programmatic changes to an input or textarea element's value. 30987 /// 30988 /// The one exception to programmatic updates is for password input elements: you are strongly cautioned 30989 /// against changing the value of a password input element programmatically (after the page loads). 30990 /// The reason is that some fairly hairy code is required behind the scenes to make the watermarks bypass 30991 /// IE security and switch back and forth between clear text (for watermarks) and obscured text (for 30992 /// passwords). It is *possible* to make programmatic changes, but it must be done in a certain way, and 30993 /// overall it is not recommended. 30994 /// </remarks> 30995 30996 if (!this.length) { 30997 return this; 30998 } 30999 31000 var hasClass = false, 31001 hasText = (typeof(text) === "string"); 31002 31003 if (typeof(options) === "object") { 31004 hasClass = (typeof(options.className) === "string"); 31005 options = $.extend({}, $.watermark.options, options); 31006 } 31007 else if (typeof(options) === "string") { 31008 hasClass = true; 31009 options = $.extend({}, $.watermark.options, {className: options}); 31010 } 31011 else { 31012 options = $.watermark.options; 31013 } 31014 31015 if (typeof(options.useNative) !== "function") { 31016 options.useNative = options.useNative? function () { return true; } : function () { return false; }; 31017 } 31018 31019 return this.each( 31020 function () { 31021 var $input = $(this); 31022 31023 if (!$input.is(selWatermarkAble)) { 31024 return; 31025 } 31026 31027 // Watermark already initialized?
31028 if ($input.data(dataFlag)) { 31029 31030 // If re-defining text or class, first remove existing watermark, then make changes 31031 if (hasText || hasClass) { 31032 $.watermark._hide($input); 31033 31034 if (hasText) { 31035 $input.data(dataText, text); 31036 } 31037 31038 if (hasClass) { 31039 $input.data(dataClass, options.className); 31040 } 31041 } 31042 } 31043 else { 31044 31045 // Detect and use native browser support, if enabled in options 31046 if (options.useNative.call(this, $input)) { 31047 31048 // Placeholder attribute (WebKit) 31049 // Big thanks to Opera for the wacky test required 31050 if ((("" + $input.css("-webkit-appearance")).replace("undefined", "") !== "") && (($input.attr("tagName") || "") !== "TEXTAREA")) { 31051 31052 // className is not set because WebKit doesn't appear to have 31053 // a separate class name property for placeholders (watermarks). 31054 if (hasText) { 31055 $input.attr("placeholder", text); 31056 } 31057 31058 // Only set data flag for non-native watermarks (purposely commented-out) 31059 // $input.data(dataFlag, 1); 31060 return; 31061 } 31062 } 31063 31064 $input.data(dataText, hasText? text : ""); 31065 $input.data(dataClass, options.className); 31066 $input.data(dataFlag, 1); // Flag indicates watermark was initialized 31067 31068 // Special processing for password type 31069 if (($input.attr("type") || "") === "password") { 31070 var $wrap = $input.wrap("<span>").parent(), 31071 $wm = $($wrap.html().replace(/type=["']?password["']?/i, 'type="text"')); 31072 31073 $wm.data(dataText, $input.data(dataText)); 31074 $wm.data(dataClass, $input.data(dataClass)); 31075 $wm.data(dataFlag, 1); 31076 $wm.attr("maxLength", text.length); 31077 31078 $wm.focus( 31079 function () { 31080 $.watermark._hide($wm, true); 31081 } 31082 ).bind("dragenter", 31083 function () { 31084 $.watermark._hide($wm); 31085 } 31086 ).bind("dragend", 31087 function () { 31088 window.setTimeout(function () { $wm.blur(); }, 1); 31089 } 31090 ); 31091 $input.blur( 31092 function () { 31093 $.watermark._show($input); 31094 } 31095 ).bind("dragleave", 31096 function () { 31097 $.watermark._show($input); 31098 } 31099 ); 31100 31101 $wm.data(dataPassword, $input); 31102 $input.data(dataPassword, $wm); 31103 } 31104 else { 31105 31106 $input.focus( 31107 function () { 31108 $input.data(dataFocus, 1); 31109 $.watermark._hide($input, true); 31110 } 31111 ).blur( 31112 function () {
31113 $input.data(dataFocus, 0); 31114 $.watermark._show($input); 31115 } 31116 ).bind("dragenter", 31117 function () { 31118 $.watermark._hide($input); 31119 } 31120 ).bind("dragleave", 31121 function () { 31122 $.watermark._show($input); 31123 } 31124 ).bind("dragend", 31125 function () { 31126 window.setTimeout(function () { $.watermark._show($input); }, 1); 31127 } 31128 ).bind("drop", 31129 // Firefox makes this lovely function necessary because the dropped text 31130 // is merged with the watermark before the drop event is called. 31131 function (evt) { 31132 var dropText = evt.originalEvent.dataTransfer.getData("Text"); 31133 31134 if ($input.val().replace(dropText, "") === $input.data(dataText)) { 31135 $input.val(dropText); 31136 } 31137 31138 $input.focus(); 31139 } 31140 ); 31141 } 31142 31143 // In order to reliably clear all watermarks before form submission, 31144 // we need to replace the form's submit function with our own 31145 // function. Otherwise watermarks won't be cleared when the form 31146 // is submitted programmatically. 31147 if (this.form) { 31148 var form = this.form, 31149 $form = $(form); 31150 31151 if (!$form.data(dataFormSubmit)) { 31152 $form.submit($.watermark.hideAll); 31153 31154 // form.submit exists for all browsers except Google Chrome 31155 // (see "else" below for explanation) 31156 if (form.submit) { 31157 $form.data(dataFormSubmit, form.submit); 31158 31159 form.submit = (function (f, $f) { 31160 return function () { 31161 var nativeSubmit = $f.data(dataFormSubmit); 31162 31163 $.watermark.hideAll(); 31164 31165 if (nativeSubmit.apply) { 31166 nativeSubmit.apply(f, Array.prototype.slice.call(arguments)); 31167 } 31168 else { 31169 nativeSubmit(); 31170 } 31171 }; 31172 })(form, $form); 31173 } 31174 else { 31175 $form.data(dataFormSubmit, 1); 31176 31177 // This strangeness is due to the fact that Google Chrome's 31178 // form.submit function is not visible to JavaScript (identifies 31179 // as "undefined"). I had to invent a solution here because hours 31180 // of Googling (ironically) for an answer did not turn up anything 31181 // useful. Within my own form.submit function I delete the form's 31182 // submit function, and then call the non-existent function -- 31183 // which, in the world of Google Chrome, still exists. 31184 form.submit = (function (f) { 31185 return function () { 31186 $.watermark.hideAll(); 31187 delete f.submit; 31188 f.submit(); 31189 }; 31190 })(form); 31191 } 31192 } 31193 } 31194 } 31195 31196 $.watermark._show($input); 31197 } 31198 ); 31199}; 31200 31201// Hijack any functions found in the triggerFns list 31202if (triggerFns.length) { 31203 31204 // Wait until DOM is ready before searching 31205 $(function () { 31206 var i, name, fn; 31207 31208 for (i=triggerFns.length-1; i>=0; i--) { 31209 name = triggerFns[i]; 31210 fn = window[name]; 31211 31212 if (typeof(fn) === "function") { 31213 window[name] = (function (origFn) { 31214 return function () { 31215 $.watermark.hideAll(); 31216 return origFn.apply(null, Array.prototype.slice.call(arguments)); 31217 }; 31218 })(fn); 31219 } 31220 } 31221 }); 31222} 31223 31224})(jQuery); 31225 31226 31227/* 31228 * jQuery File Upload Plugin 3.2 31229 * 31230 * Copyright 2010, Sebastian Tschan, AQUANTUM 31231 * Licensed under the MIT license: 31232 * http://creativecommons.org/licenses/MIT/ 31233 * 31234 * https://blueimp.net 31235 * http://www.aquantum.de 31236 */ 31237 31238/*jslint browser: true */ 31239/*global File, FileReader, FormData, unescape, jQuery */ 31240 31241(function ($) { 31242 31243 var FileUpload = function (container) { 31244 var fileUpload = this, 31245 uploadForm = (container.is('form') ? container : container.find('form').first()),
31246 fileInput = uploadForm.find('input:file').first(), 31247 settings = { 31248 namespace: 'file_upload', 31249 cssClass: 'file_upload', 31250 dropZone: container, 31251 url: uploadForm.attr('action'), 31252 method: uploadForm.attr('method'), 31253 fieldName: fileInput.attr('name'), 31254 multipart: true, 31255 formData: function () { 31256 return uploadForm.serializeArray(); 31257 }, 31258 withCredentials: false 31259 }, 31260 documentListeners = {}, 31261 dropZoneListeners = {}, 31262 fileInputListeners = {}, 31263 undef = 'undefined', 31264 func = 'function', 31265 protocolRegExp = /^http(s)?:\/\//, 31266 31267 isXHRUploadCapable = function () { 31268 return typeof XMLHttpRequest !== undef && typeof File !== undef && ( 31269 !settings.multipart || typeof FormData !== undef || typeof FileReader !== undef 31270 ); 31271 }, 31272 31273 initEventHandlers = function () { 31274 if (typeof settings.onDocumentDragEnter === func) { 31275 documentListeners['dragenter.' + settings.namespace] = settings.onDocumentDragEnter; 31276 } 31277 if (typeof settings.onDocumentDragLeave === func) { 31278 documentListeners['dragleave.' + settings.namespace] = settings.onDocumentDragLeave; 31279 } 31280 documentListeners['dragover.' + settings.namespace] = fileUpload.onDocumentDragOver; 31281 documentListeners['drop.' + settings.namespace] = fileUpload.onDocumentDrop; 31282 $(document).bind(documentListeners); 31283 if (typeof settings.onDragEnter === func) { 31284 dropZoneListeners['dragenter.' + settings.namespace] = settings.onDragEnter; 31285 } 31286 if (typeof settings.onDragLeave === func) { 31287 dropZoneListeners['dragleave.' + settings.namespace] = settings.onDragLeave; 31288 } 31289 dropZoneListeners['dragover.' + settings.namespace] = fileUpload.onDragOver; 31290 dropZoneListeners['drop.' + settings.namespace] = fileUpload.onDrop; 31291 settings.dropZone.bind(dropZoneListeners); 31292 fileInputListeners['change.' + settings.namespace] = fileUpload.onChange; 31293 fileInput.bind(fileInputListeners); 31294 }, 31295 31296 removeEventHandlers = function () { 31297 $.each(documentListeners, function (key, value) { 31298 $(document).unbind(key, value); 31299 }); 31300 $.each(dropZoneListeners, function (key, value) { 31301 settings.dropZone.unbind(key, value); 31302 }); 31303 $.each(fileInputListeners, function (key, value) { 31304 fileInput.unbind(key, value); 31305 }); 31306 }, 31307 31308 initUploadEventHandlers = function (files, index, xhr, settings) { 31309 if (typeof settings.onProgress === func) { 31310 xhr.upload.onprogress = function (e) { 31311 settings.onProgress(e, files, index, xhr, settings); 31312 }; 31313 } 31314 if (typeof settings.onLoad === func) { 31315 xhr.onload = function (e) { 31316 settings.onLoad(e, files, index, xhr, settings); 31317 }; 31318 } 31319 if (typeof settings.onAbort === func) { 31320 xhr.onabort = function (e) { 31321 settings.onAbort(e, files, index, xhr, settings); 31322 }; 31323 } 31324 if (typeof settings.onError === func) { 31325 xhr.onerror = function (e) { 31326 settings.onError(e, files, index, xhr, settings); 31327 }; 31328 } 31329 }, 31330 31331 getFormData = function (settings) { 31332 if (typeof settings.formData === func) { 31333 return settings.formData(); 31334 } else if ($.isArray(settings.formData)) { 31335 return settings.formData; 31336 } else if (settings.formData) { 31337 var formData = []; 31338 $.each(settings.formData, function (name, value) { 31339 formData.push({name: name, value: value}); 31340 }); 31341 return formData; 31342 } 31343 return []; 31344 }, 31345 31346 buildMultiPartFormData = function (boundary, file, fileContent, fields) { 31347 var doubleDash = '--', 31348 crlf = '\r\n', 31349 formData = ''; 31350 $.each(fields, function (index, field) { 31351 formData += doubleDash + boundary + crlf + 31352 'Content-Disposition: form-data; name="' + 31353 unescape(encodeURIComponent(field.name)) + 31354 '"' + crlf + crlf + 31355 unescape(encodeURIComponent(field.value)) + crlf; 31356 }); 31357 formData += doubleDash + boundary + crlf + 31358 'Content-Disposition: form-data; name="' + 31359 unescape(encodeURIComponent(settings.fieldName)) + 31360 '"; filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf + 31361 'Content-Type: ' + file.type + crlf + crlf + 31362 fileContent + crlf + 31363 doubleDash + boundary + doubleDash + crlf; 31364 return formData; 31365 }, 31366 31367 isSameDomain = function (url) { 31368 if (protocolRegExp.test(url)) { 31369 var host = location.host, 31370 indexStart = location.protocol.length + 2, 31371 index = url.indexOf(host, indexStart), 31372 pathIndex = index + host.length; 31373 if ((index === indexStart || index === url.indexOf('@', indexStart) + 1) && ( 31374 url.length === pathIndex || $.inArray(url.charAt(pathIndex), ['/', '?', '#']))) { 31375 return true; 31376 } 31377 return false;
31378 } 31379 return true; 31380 }, 31381 31382 uploadFile = function (files, index, xhr, settings) { 31383 var sameDomain = isSameDomain(settings.url), 31384 file = files[index], 31385 formData, fileReader; 31386 initUploadEventHandlers(files, index, xhr, settings); 31387 xhr.open(settings.method, settings.url, true); 31388 if (sameDomain) { 31389 xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 31390 } else if (settings.withCredentials) { 31391 xhr.withCredentials = true; 31392 } 31393 if (!settings.multipart) { 31394 if (sameDomain) { 31395 xhr.setRequestHeader('X-File-Name', unescape(encodeURIComponent(file.name))); 31396 } 31397 xhr.setRequestHeader('Content-Type', file.type); 31398 xhr.send(file); 31399 } else { 31400 if (typeof FormData !== undef) { 31401 formData = new FormData(); 31402 $.each(getFormData(settings), function (index, field) { 31403 formData.append(field.name, field.value); 31404 }); 31405 formData.append(settings.fieldName, file); 31406 xhr.send(formData); 31407 } else if (typeof FileReader !== undef) { 31408 fileReader = new FileReader(); 31409 fileReader.onload = function (e) { 31410 var fileContent = e.target.result, 31411 boundary = '----MultiPartFormBoundary' + (new Date()).getTime(); 31412 xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); 31413 xhr.sendAsBinary(buildMultiPartFormData( 31414 boundary, 31415 file, 31416 fileContent, 31417 getFormData(settings) 31418 )); 31419 }; 31420 fileReader.readAsBinaryString(file); 31421 } else { 31422 $.error('Browser does neither support FormData nor FileReader interface'); 31423 } 31424 } 31425 }, 31426 31427 handleFile = function (event, files, index) { 31428 var xhr = new XMLHttpRequest(), 31429 uploadSettings = $.extend({}, settings); 31430 if (typeof settings.initUpload === func) { 31431 settings.initUpload( 31432 event, 31433 files, 31434 index, 31435 xhr, 31436 uploadSettings, 31437 function () { 31438 uploadFile(files, index, xhr, uploadSettings); 31439 } 31440 ); 31441 } else { 31442 uploadFile(files, index, xhr, uploadSettings); 31443 } 31444 }, 31445 31446 handleFiles = function (event, files) { 31447 var i; 31448 for (i = 0; i < files.length; i += 1) { 31449 handleFile(event, files, i); 31450 } 31451 }, 31452 31453 legacyUploadFormDataInit = function (input, settings) { 31454 var formData = getFormData(settings); 31455 uploadForm.find(':input').not(':disabled') 31456 .attr('disabled', true) 31457 .addClass(settings.namespace + '_disabled'); 31458 $.each(formData, function (index, field) { 31459 uploadForm.append( 31460 $('<input type="hidden"/>') 31461 .attr('name', field.name) 31462 .val(field.value) 31463 .addClass(settings.namespace + '_form_data') 31464 ); 31465 }); 31466 input.insertAfter(fileInput); 31467 }, 31468 31469 legacyUploadFormDataReset = function (input, settings) { 31470 input.remove(); 31471 uploadForm.find('.' + settings.namespace + '_disabled') 31472 .removeAttr('disabled') 31473 .removeClass(settings.namespace + '_disabled'); 31474 uploadForm.find('.' + settings.namespace + '_form_data').remove(); 31475 }, 31476 31477 legacyUpload = function (input, iframe, settings) { 31478 iframe 31479 .unbind('abort') 31480 .bind('abort', function (e) { 31481 iframe.readyState = 0; 31482 // javascript:false as iframe src prevents warning popups on HTTPS in IE6 31483 // concat is used here to prevent the "Script URL" JSLint error: 31484 iframe.unbind('load').attr('src', 'javascript'.concat(':false;')); 31485 if (typeof settings.onAbort === func) { 31486 settings.onAbort(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings); 31487 } 31488 }) 31489 .unbind('load') 31490 .bind('load', function (e) { 31491 iframe.readyState = 4; 31492 if (typeof settings.onLoad === func) { 31493 settings.onLoad(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings); 31494 } 31495 }); 31496 uploadForm 31497 .attr('action', settings.url) 31498 .attr('target', iframe.attr('name')); 31499 legacyUploadFormDataInit(input, settings); 31500 iframe.readyState = 2; 31501 uploadForm.get(0).submit(); 31502 legacyUploadFormDataReset(input, settings); 31503 }, 31504 31505 handleLegacyUpload = function (event, input) { 31506 // javascript:false as iframe src prevents warning popups on HTTPS in IE6: 31507 var iframe = $('<iframe src="javascript:false;" style="display:none" name="iframe_' +
31508 settings.namespace + (new Date()).getTime() + '"></iframe>'), 31509 uploadSettings = $.extend({}, settings); 31510 iframe.readyState = 0; 31511 iframe.abort = function () { 31512 iframe.trigger('abort'); 31513 }; 31514 iframe.bind('load', function () { 31515 iframe.unbind('load'); 31516 if (typeof settings.initUpload === func) { 31517 settings.initUpload( 31518 event, 31519 [{name: input.val(), type: null, size: null}], 31520 0, 31521 iframe, 31522 uploadSettings, 31523 function () { 31524 legacyUpload(input, iframe, uploadSettings); 31525 } 31526 ); 31527 } else { 31528 legacyUpload(input, iframe, uploadSettings); 31529 } 31530 }).appendTo(uploadForm); 31531 }, 31532 31533 resetFileInput = function () { 31534 var inputClone = fileInput.clone(true); 31535 $('<form/>').append(inputClone).get(0).reset(); 31536 fileInput.replaceWith(inputClone); 31537 fileInput = inputClone; 31538 }; 31539 31540 this.onDocumentDragOver = function (e) { 31541 if (typeof settings.onDocumentDragOver === func && 31542 settings.onDocumentDragOver(e) === false) { 31543 return false; 31544 } 31545 e.preventDefault(); 31546 }; 31547 31548 this.onDocumentDrop = function (e) { 31549 if (typeof settings.onDocumentDrop === func && 31550 settings.onDocumentDrop(e) === false) { 31551 return false; 31552 } 31553 e.preventDefault(); 31554 }; 31555 31556 this.onDragOver = function (e) { 31557 if (typeof settings.onDragOver === func && 31558 settings.onDragOver(e) === false) { 31559 return false; 31560 } 31561 var dataTransfer = e.originalEvent.dataTransfer; 31562 if (dataTransfer) { 31563 dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy'; 31564 } 31565 e.preventDefault(); 31566 }; 31567 31568 this.onDrop = function (e) { 31569 if (typeof settings.onDrop === func && 31570 settings.onDrop(e) === false) { 31571 return false; 31572 } 31573 var dataTransfer = e.originalEvent.dataTransfer; 31574 if (dataTransfer && dataTransfer.files && isXHRUploadCapable()) { 31575 handleFiles(e, dataTransfer.files); 31576 } 31577 e.preventDefault(); 31578 }; 31579 31580 this.onChange = function (e) { 31581 if (typeof settings.onChange === func && 31582 settings.onChange(e) === false) { 31583 return false; 31584 } 31585 if (e.target.files && isXHRUploadCapable()) { 31586 handleFiles(e, e.target.files); 31587 } else { 31588 handleLegacyUpload(e, $(e.target)); 31589 } 31590 resetFileInput(); 31591 }; 31592 31593 this.init = function (options) { 31594 if (options) { 31595 $.extend(settings, options); 31596 } 31597 if (container.data(settings.namespace)) { 31598 $.error('FileUpload with namespace "' + settings.namespace + '" already assigned to this element'); 31599 return; 31600 } 31601 container 31602 .data(settings.namespace, fileUpload) 31603 .addClass(settings.cssClass); 31604 settings.dropZone.addClass(settings.cssClass); 31605 initEventHandlers(); 31606 }; 31607 31608 this.destroy = function () { 31609 removeEventHandlers(); 31610 container 31611 .removeData(settings.namespace) 31612 .removeClass(settings.cssClass); 31613 settings.dropZone.removeClass(settings.cssClass); 31614 }; 31615 }, 31616 31617 methods = { 31618 init : function (options) { 31619 return this.each(function () { 31620 (new FileUpload($(this))).init(options); 31621 }); 31622 }, 31623 31624 destroy : function (namespace) { 31625 return this.each(function () { 31626 namespace = namespace ? namespace : 'file_upload'; 31627 var fileUpload = $(this).data(namespace); 31628 if (fileUpload) { 31629 fileUpload.destroy(); 31630 } else { 31631 $.error('No FileUpload with namespace "' + namespace + '" assigned to this element'); 31632 } 31633 }); 31634 31635 } 31636 }; 31637 31638 $.fn.fileUpload = function (method) { 31639 if (methods[method]) { 31640 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 31641 } else if (typeof method === 'object' || !method) { 31642 return methods.init.apply(this, arguments); 31643 } else { 31644 $.error('Method ' + method + ' does not exist on jQuery.fileUpload'); 31645 } 31646 }; 31647 31648}(jQuery)); 31649 31650/* 31651 * jQuery File Upload User Interface Plugin 3.2 31652 * 31653 * Copyright 2010, Sebastian Tschan, AQUANTUM 31654 * Licensed under the MIT license: 31655 * http://creativecommons.org/licenses/MIT/ 31656 * 31657 * https://blueimp.net 31658 * http://www.aquantum.de 31659 */ 31660 31661/*jslint browser: true */ 31662/*global jQuery */ 31663 31664(function ($) { 31665 31666 var UploadHandler = function (container, options) { 31667 var uploadHandler = this, 31668 undef = 'undefined', 31669 func = 'function', 31670 dragOverTimeout, 31671 isDropZoneEnlarged; 31672 31673 this.dropZone = container; 31674 this.progressSelector = '.file_upload_progress div'; 31675 this.cancelSelector = '.file_upload_cancel div'; 31676 this.cssClassSmall = 'file_upload_small'; 31677 this.cssClassLarge = 'file_upload_large'; 31678 this.cssClassHighlight = 'file_upload_highlight';
31679 this.dropEffect = 'highlight'; 31680 this.uploadTable = this.downloadTable = $(); 31681 31682 this.buildUploadRow = this.buildDownloadRow = function () { 31683 return null; 31684 }; 31685 31686 this.addNode = function (parentNode, node, callBack) { 31687 if (node) { 31688 node.hide().appendTo(parentNode).fadeIn(function () { 31689 if (typeof callBack === func) { 31690 try { 31691 callBack(); 31692 } catch (e) { 31693 // Fix endless exception loop: 31694 $(this).stop(); 31695 throw e; 31696 } 31697 } 31698 }); 31699 } else if (typeof callBack === func) { 31700 callBack(); 31701 } 31702 }; 31703 31704 this.removeNode = function (node, callBack) { 31705 if (node) { 31706 node.fadeOut(function () { 31707 $(this).remove(); 31708 if (typeof callBack === func) { 31709 try { 31710 callBack(); 31711 } catch (e) { 31712 // Fix endless exception loop: 31713 $(this).stop(); 31714 throw e; 31715 } 31716 } 31717 }); 31718 } else if (typeof callBack === func) { 31719 callBack(); 31720 } 31721 }; 31722 31723 this.onAbort = function (event, files, index, xhr, handler) { 31724 uploadHandler.removeNode(handler.uploadRow); 31725 }; 31726 31727 this.cancelUpload = function (event, files, index, xhr, handler) { 31728 var readyState = xhr.readyState; 31729 xhr.abort(); 31730 // If readyState is below 2, abort() has no effect: 31731 if (isNaN(readyState) || readyState < 2) { 31732 handler.onAbort(event, files, index, xhr, handler); 31733 } 31734 }; 31735 31736 this.initProgressBar = function (node, value) { 31737 if (typeof node.progressbar === func) { 31738 return node.progressbar({ 31739 value: value 31740 }); 31741 } else { 31742 var progressbar = $('<progress value="' + value + '" max="100"/>').appendTo(node); 31743 progressbar.progressbar = function (key, value) { 31744 progressbar.attr('value', value); 31745 }; 31746 return progressbar; 31747 } 31748 }; 31749 31750 this.initUploadRow = function (event, files, index, xhr, handler, callBack) { 31751 var uploadRow = handler.uploadRow = uploadHandler.buildUploadRow(files, index); 31752 if (uploadRow) { 31753 handler.progressbar = uploadHandler.initProgressBar( 31754 uploadRow.find(uploadHandler.progressSelector), 31755 (xhr.upload ? 0 : 100) 31756 ); 31757 uploadRow.find(uploadHandler.cancelSelector).click(function (e) { 31758 uploadHandler.cancelUpload(e, files, index, xhr, handler); 31759 }); 31760 } 31761 uploadHandler.addNode(uploadHandler.uploadTable, uploadRow, callBack); 31762 }; 31763 31764 this.initUpload = function (event, files, index, xhr, handler, callBack) { 31765 uploadHandler.initUploadRow(event, files, index, xhr, handler, function () { 31766 if (typeof uploadHandler.beforeSend === func) { 31767 uploadHandler.beforeSend(event, files, index, xhr, handler, callBack); 31768 } else { 31769 callBack(); 31770 } 31771 }); 31772 }; 31773 31774 this.onProgress = function (event, files, index, xhr, handler) { 31775 if (handler.progressbar) { 31776 handler.progressbar.progressbar( 31777 'value', 31778 parseInt(event.loaded / event.total * 100, 10) 31779 ); 31780 } 31781 }; 31782 31783 this.parseResponse = function (xhr) { 31784 if (typeof xhr.responseText !== undef) { 31785 return $.parseJSON(xhr.responseText); 31786 } else { 31787 // Instead of an XHR object, an iframe is used for legacy browsers: 31788 return $.parseJSON(xhr.contents().text()); 31789 } 31790 }; 31791 31792 this.initDownloadRow = function (event, files, index, xhr, handler, callBack) { 31793 var json, downloadRow; 31794 try { 31795 json = handler.response = uploadHandler.parseResponse(xhr); 31796 downloadRow = handler.downloadRow = uploadHandler.buildDownloadRow(json); 31797 uploadHandler.addNode(uploadHandler.downloadTable, downloadRow, callBack); 31798 } catch (e) { 31799 if (typeof uploadHandler.onError === func) { 31800 handler.originalEvent = event; 31801 uploadHandler.onError(e, files, index, xhr, handler); 31802 } else { 31803 throw e; 31804 } 31805 } 31806 }; 31807 31808 this.onLoad = function (event, files, index, xhr, handler) { 31809 uploadHandler.removeNode(handler.uploadRow, function () { 31810 uploadHandler.initDownloadRow(event, files, index, xhr, handler, function () {alert('Line no : 161...'); 31811 if (typeof uploadHandler.onComplete === func) { 31812 uploadHandler.onComplete(event, files, index, xhr, handler); 31813 } 31814 }); 31815 }); 31816 }; 31817 31818 this.dropZoneEnlarge = function () { 31819 if (!isDropZoneEnlarged) { 31820 if (typeof uploadHandler.dropZone.switchClass === func) { 31821 uploadHandler.dropZone.switchClass( 31822 uploadHandler.cssClassSmall, 31823 uploadHandler.cssClassLarge 31824 ); 31825 } else { 31826 uploadHandler.dropZone.addClass(uploadHandler.cssClassLarge); 31827 uploadHandler.dropZone.removeClass(uploadHandler.cssClassSmall); 31828 } 31829 isDropZoneEnlarged = true; 31830 } 31831 }; 31832 31833 this.dropZoneReduce = function () { 31834 if (typeof uploadHandler.dropZone.switchClass === func) { 31835 uploadHandler.dropZone.switchClass( 31836 uploadHandler.cssClassLarge, 31837 uploadHandler.cssClassSmall 31838 ); 31839 } else { 31840 uploadHandler.dropZone.addClass(uploadHandler.cssClassSmall); 31841 uploadHandler.dropZone.removeClass(uploadHandler.cssClassLarge); 31842 } 31843 isDropZoneEnlarged = false;
31844 }; 31845 31846 this.onDocumentDragEnter = function (event) { 31847 uploadHandler.dropZoneEnlarge(); 31848 }; 31849 31850 this.onDocumentDragOver = function (event) { 31851 if (dragOverTimeout) { 31852 clearTimeout(dragOverTimeout); 31853 } 31854 dragOverTimeout = setTimeout(function () { 31855 uploadHandler.dropZoneReduce(); 31856 }, 200); 31857 }; 31858 31859 this.onDragEnter = this.onDragLeave = function (event) { 31860 uploadHandler.dropZone.toggleClass(uploadHandler.cssClassHighlight); 31861 }; 31862 31863 this.onDrop = function (event) { 31864 if (dragOverTimeout) { 31865 clearTimeout(dragOverTimeout); 31866 } 31867 if (uploadHandler.dropEffect && typeof uploadHandler.dropZone.effect === func) { 31868 uploadHandler.dropZone.effect(uploadHandler.dropEffect, function () { 31869 uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight); 31870 uploadHandler.dropZoneReduce(); 31871 }); 31872 } else { 31873 uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight); 31874 uploadHandler.dropZoneReduce(); 31875 } 31876 }; 31877 31878 $.extend(this, options); 31879 }, 31880 31881 methods = { 31882 init : function (options) { 31883 return this.each(function () { 31884 $(this).fileUpload(new UploadHandler($(this), options)); 31885 }); 31886 }, 31887 31888 destroy : function (namespace) { 31889 return this.each(function () { 31890 $(this).fileUpload('destroy', namespace); 31891 }); 31892 } 31893 }; 31894 31895 $.fn.fileUploadUI = function (method) { 31896 if (methods[method]) { 31897 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 31898 } else if (typeof method === 'object' || !method) { 31899 return methods.init.apply(this, arguments); 31900 } else { 31901 $.error('Method ' + method + ' does not exist on jQuery.fileUploadUI'); 31902 } 31903 }; 31904 31905}(jQuery)); 31906/** 31907 * jQuery custom event "outerClick". 31908 * @author Senad Dizdar 31909 * 31910 * Copyright (C) 2010-2011, cloudHQ 31911 * All rights reserved. 31912 * 31913 * The outerClick event is fired when an element outside of all target element is clicked. 31914 * 31915 * Usage: 31916 * $(selector).bind("outerClick", fn); // Bind the function fn to the outerClick event on each of the matched elements. 31917 * $(selector).outerClick(fn); // Bind the function fn to the outerClick event on each of the matched elements. 31918 * $(selector).trigger("outerClick"); // Trigger the outerClick event on each of the matched elements. 31919 * $(selector).outerClick(); // Trigger the outerClick event on each of the matched elements. 31920 * $(selector).unbind("outerClick", fn); // Unbind the function fn from the outerClick event on each of the matched elements. 31921 * $(selector).unbind("outerClick"); // Unbind all outerClick events from each of the matched elements. 31922 */ 31923 31924/*global jQuery */ 31925(function ($, elements, OUTER_CLICK) { 31926 31927 /** 31928 * Check if the event should be fired. 31929 * @param {Object} event The click event. 31930 * @private 31931 */ 31932 function check(event) { 31933 var j = 0; 31934 for (var i = 0, l = elements.length, target = event.target, el; i < l; i++) 31935 { 31936 el = elements[i]; 31937 if (el !== target && !(el.contains ? el.contains(target) : el.compareDocumentPosition ? el.compareDocumentPosition(target) & 16 : 1)) 31938 { 31939 j++; 31940 } 31941 } 31942 if (j == elements.length) 31943 { 31944 $.event.trigger(OUTER_CLICK, event, el); 31945 } 31946 } 31947 31948 31949 $.event.special[OUTER_CLICK] = { 31950 31951 setup: function () 31952 { 31953 var i = elements.length; 31954 if (!i) 31955 { 31956 $.event.add(document, 'click', check); 31957 } 31958 if ($.inArray(this, elements) < 0) 31959 { 31960 elements[i] = this; 31961 } 31962 }, 31963 31964 teardown: function () 31965 { 31966 var i = $.inArray(this, elements); 31967 if (i >= 0) 31968 { 31969 elements.splice(i, 1); 31970 if (!elements.length) 31971 { 31972 $.event.remove(document, 'click', check); 31973 } 31974 } 31975 } 31976 31977 }; 31978 31979 /** 31980 * Event helper outerClick 31981 * 31982 * @param {Function}
31982 [fn] A function to bind to the outerClick event on each of the matched elements. 31983 * If fn is omitted the event is triggered. 31984 * @return {jQuery} Returns the jQuery object. 31985 */ 31986 $.fn[OUTER_CLICK] = function (fn) 31987 { 31988 return fn ? this.bind(OUTER_CLICK, fn) : this.trigger(OUTER_CLICK); 31989 }; 31990 31991})(jQuery, [], 'outerClick'); 31992 31993 31994 31995 31996/* 31997 * jQuery JSON Plugin 31998 * version: 1.0 (2008-04-17) 31999 * 32000 * This document is licensed as free software under the terms of the 32001 * MIT License: http://www.opensource.org/licenses/mit-license.php 32002 * 32003 * Brantley Harris technically wrote this plugin, but it is based somewhat 32004 * on the JSON.org website's http://www.json.org/json2.js, which proclaims: 32005 * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that 32006 * I uphold. I really just cleaned it up. 32007 * 32008 * It is also based heavily on MochiKit's serializeJSON, which is 32009 * copywrited 2005 by Bob Ippolito. 32010 */ 32011 32012(function($) { 32013 function toIntegersAtLease(n) 32014 // Format integers to have at least two digits. 32015 { 32016 return n < 10 ? '0' + n : n; 32017 } 32018 32019 Date.prototype.toJSON = function(date) 32020 // Yes, it polutes the Date namespace, but we'll allow it here, as 32021 // it's damned usefull. 32022 { 32023 return this.getUTCFullYear() + '-' + 32024 toIntegersAtLease(this.getUTCMonth()) + '-' + 32025 toIntegersAtLease(this.getUTCDate()); 32026 }; 32027 32028 var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g; 32029 var meta = { // table of character substitutions 32030 '\b': '\\b', 32031 '\t': '\\t', 32032 '\n': '\\n', 32033 '\f': '\\f', 32034 '\r': '\\r', 32035 '"' : '\\"', 32036 '\\': '\\\\' 32037 }; 32038 32039 $.quoteString = function(string) 32040 // Places quotes around a string, inteligently. 32041 // If the string contains no control characters, no quote characters, and no 32042 // backslash characters, then we can safely slap some quotes around it. 32043 // Otherwise we must also replace the offending characters with safe escape 32044 // sequences. 32045 { 32046 if (escapeable.test(string)) 32047 { 32048 return '"' + string.replace(escapeable, function (a) 32049 { 32050 var c = meta[a]; 32051 if (typeof c === 'string') { 32052 return c; 32053 } 32054 c = a.charCodeAt(); 32055 return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); 32056 }) + '"'; 32057 } 32058 return '"' + string + '"'; 32059 }; 32060 32061 $.toJSON = function(o, compact) 32062 { 32063 var type = typeof(o); 32064 32065 if (type == "undefined") 32066 return "undefined"; 32067 else if (type == "number" || type == "boolean") 32068 return o + ""; 32069 else if (o === null) 32070 return "null"; 32071 32072 // Is it a string? 32073 if (type == "string") 32074 { 32075 return $.quoteString(o); 32076 } 32077 32078 // Does it have a .toJSON function? 32079 if (type == "object" && typeof o.toJSON == "function") 32080 return o.toJSON(compact); 32081 32082 // Is it an array? 32083 if (type != "function" && typeof(o.length) == "number") 32084 { 32085 var ret = []; 32086 for (var i = 0; i < o.length; i++) { 32087 ret.push( $.toJSON(o[i], compact) ); 32088 } 32089 if (compact) 32090 return "[" + ret.join(",") + "]"; 32091 else 32092 return "[" + ret.join(", ") + "]"; 32093 } 32094 32095 // If it's a function, we have to warn somebody! 32096 if (type == "function") { 32097 throw new TypeError("Unable to convert object of type 'function' to json."); 32098 } 32099 32100 // It's probably an object, then. 32101 var ret = []; 32102 for (var k in o) { 32103 var name; 32104 type = typeof(k); 32105 32106 if (type == "number") 32107 name = '"' + k + '"'; 32108 else if (type == "string") 32109 name = $.quoteString(k); 32110 else 32111 continue; //skip non-string or number keys 32112 32113 var val = $.toJSON(o[k], compact); 32114 if (typeof(val) != "string") { 32115 // skip non-serializable values 32116 continue; 32117 } 32118 32119 if (compact)
32120 ret.push(name + ":" + val); 32121 else 32122 ret.push(name + ": " + val); 32123 } 32124 return "{" + ret.join(", ") + "}"; 32125 }; 32126 32127 $.compactJSON = function(o) 32128 { 32129 return $.toJSON(o, true); 32130 }; 32131 32132 $.evalJSON = function(src) 32133 // Evals JSON that we know to be safe. 32134 { 32135 return eval("(" + src + ")"); 32136 }; 32137 32138 $.secureEvalJSON = function(src) 32139 // Evals JSON in a way that is *more* secure. 32140 { 32141 var filtered = src; 32142 filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@'); 32143 filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); 32144 filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); 32145 32146 if (/^[\],:{}\s]*$/.test(filtered)) 32147 return eval("(" + src + ")"); 32148 else 32149 throw new SyntaxError("Error parsing JSON, source is not valid."); 32150 }; 32151})(jQuery); 32152 32153(function ($) { 32154 $.format = (function () { 32155 function strDay(value) { 32156 switch (parseInt(value)) { 32157 case 0: 32158 return "Sunday"; 32159 case 1: 32160 return "Monday"; 32161 case 2: 32162 return "Tuesday"; 32163 case 3: 32164 return "Wednesday"; 32165 case 4: 32166 return "Thursday"; 32167 case 5: 32168 return "Friday"; 32169 case 6: 32170 return "Saturday"; 32171 default: 32172 return value; 32173 } 32174 } 32175 32176 function strMonth(value) { 32177 switch (parseInt(value)) { 32178 case 1: 32179 return "Jan"; 32180 case 2: 32181 return "Feb"; 32182 case 3: 32183 return "Mar"; 32184 case 4: 32185 return "Apr"; 32186 case 5: 32187 return "May"; 32188 case 6: 32189 return "Jun"; 32190 case 7: 32191 return "Jul"; 32192 case 8: 32193 return "Aug"; 32194 case 9: 32195 return "Sep"; 32196 case 10: 32197 return "Oct"; 32198 case 11: 32199 return "Nov"; 32200 case 12: 32201 return "Dec"; 32202 default: 32203 return value; 32204 } 32205 } 32206 32207 var parseMonth = function (value) { 32208 switch (value) { 32209 case "Jan": 32210 return "01"; 32211 case "Feb": 32212 return "02"; 32213 case "Mar": 32214 return "03"; 32215 case "Apr": 32216 return "04"; 32217 case "May": 32218 return "05"; 32219 case "Jun": 32220 return "06"; 32221 case "Jul": 32222 return "07"; 32223 case "Aug": 32224 return "08"; 32225 case "Sep": 32226 return "09"; 32227 case "Oct": 32228 return "10"; 32229 case "Nov": 32230 return "11"; 32231 case "Dec": 32232 return "12"; 32233 default: 32234 return value; 32235 } 32236 }; 32237 32238 var parseTime = function (value) { 32239 var retValue = value; 32240 var millis = ""; 32241 if (retValue.indexOf(".") !== -1) { 32242 var delimited = retValue.split('.'); 32243 retValue = delimited[0]; 32244 millis = delimited[1]; 32245 } 32246 32247 var values3 = retValue.split(":"); 32248 32249 if (values3.length === 3) { 32250 hour = values3[0]; 32251 minute = values3[1]; 32252 second = values3[2]; 32253 32254 return { 32255 time: retValue, 32256 hour: hour, 32257 minute: minute, 32258 second: second, 32259 millis: millis 32260 }; 32261 } else { 32262 return { 32263 time: "", 32264 hour: "", 32265 minute: "", 32266 second: "", 32267 millis: "" 32268 }; 32269 } 32270 }; 32271 32272 return { 32273 date: function (value, format) { 32274 /* 32275 value = new java.util.Date() 32276 2009-12-18 10:54:50.546 32277 */ 32278 try { 32279 var date = null; 32280 var year = null;
32281 var month = null; 32282 var dayOfMonth = null; 32283 var dayOfWeek = null; 32284 var time = null; 32285 if (typeof value.getFullYear === "function") { 32286 year = value.getFullYear(); 32287 month = value.getMonth() + 1; 32288 dayOfMonth = value.getDate(); 32289 dayOfWeek = value.getDay(); 32290 time = parseTime(value.toTimeString()); 32291 } else if (value.search(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.?\d{0,3}[-+]?\d{2}:\d{2}/) != -1) { /* 2009-04-19T16:11:05+02:00 */ 32292 var values = value.split(/[T\+-]/); 32293 year = values[0]; 32294 month = values[1]; 32295 dayOfMonth = values[2]; 32296 time = parseTime(values[3].split(".")[0]); 32297 date = new Date(year, month - 1, dayOfMonth); 32298 dayOfWeek = date.getDay(); 32299 } else { 32300 var values = value.split(" "); 32301 switch (values.length) { 32302 case 6: 32303 /* Wed Jan 13 10:43:41 CET 2010 */ 32304 year = values[5]; 32305 month = parseMonth(values[1]); 32306 dayOfMonth = values[2]; 32307 time = parseTime(values[3]); 32308 date = new Date(year, month - 1, dayOfMonth); 32309 dayOfWeek = date.getDay(); 32310 break; 32311 case 2: 32312 /* 2009-12-18 10:54:50.546 */ 32313 var values2 = values[0].split("-"); 32314 year = values2[0]; 32315 month = values2[1]; 32316 dayOfMonth = values2[2]; 32317 time = parseTime(values[1]); 32318 date = new Date(year, month - 1, dayOfMonth); 32319 dayOfWeek = date.getDay(); 32320 break; 32321 case 7: 32322 /* Tue Mar 01 2011 12:01:42 GMT-0800 (PST) */ 32323 case 9: 32324 /*added by Larry, for Fri Apr 08 2011 00:00:00 GMT+0800 (China Standard Time) */ 32325 case 10: 32326 /* added by Larry, for Fri Apr 08 2011 00:00:00 GMT+0200 (W. Europe Daylight Time) */ 32327 year = values[3]; 32328 month = parseMonth(values[1]); 32329 dayOfMonth = values[2]; 32330 time = parseTime(values[4]); 32331 date = new Date(year, month - 1, dayOfMonth); 32332 dayOfWeek = date.getDay(); 32333 break; 32334 default: 32335 return value; 32336 } 32337 } 32338 32339 var pattern = ""; 32340 var retValue = ""; 32341 /* 32342 Issue 1 - variable scope issue in format.date 32343 Thanks jakemonO 32344 */ 32345 for (var i = 0; i < format.length; i++) { 32346 var currentPattern = format.charAt(i); 32347 pattern += currentPattern; 32348 switch (pattern) { 32349 case "ddd": 32350 retValue += strDay(dayOfWeek); 32351 pattern = ""; 32352 break; 32353 case "dd": 32354 if (format.charAt(i + 1) == "d") { 32355 break; 32356 } 32357 if (String(dayOfMonth).length === 1) { 32358 dayOfMonth = '0' + dayOfMonth; 32359 } 32360 retValue += dayOfMonth; 32361 pattern = ""; 32362 break; 32363 case "MMM": 32364 retValue += strMonth(month); 32365 pattern = ""; 32366 break; 32367 case "MM": 32368 if (format.charAt(i + 1) == "M") { 32369 break; 32370 } 32371 if (String(month).length === 1) {
32372 month = '0' + month; 32373 } 32374 retValue += month; 32375 pattern = ""; 32376 break; 32377 case "yyyy": 32378 retValue += year; 32379 pattern = ""; 32380 break; 32381 case "HH": 32382 retValue += time.hour; 32383 pattern = ""; 32384 break; 32385 case "hh": 32386 /* time.hour is "00" as string == is used instead of === */ 32387 retValue += (time.hour == 0 ? 12 : time.hour < 13 ? time.hour : time.hour - 12); 32388 pattern = ""; 32389 break; 32390 case "mm": 32391 retValue += time.minute; 32392 pattern = ""; 32393 break; 32394 case "ss": 32395 /* ensure only seconds are added to the return string */ 32396 retValue += time.second.substring(0, 2); 32397 pattern = ""; 32398 break; 32399 case "SSS": 32400 retValue += time.millis.substring(0, 3); 32401 pattern = ""; 32402 break; 32403 case "a": 32404 retValue += time.hour >= 12 ? "PM" : "AM"; 32405 pattern = ""; 32406 break; 32407 case " ": 32408 retValue += currentPattern; 32409 pattern = ""; 32410 break; 32411 case "/": 32412 retValue += currentPattern; 32413 pattern = ""; 32414 break; 32415 case ":": 32416 retValue += currentPattern; 32417 pattern = ""; 32418 break; 32419 default: 32420 if (pattern.length === 2 && pattern.indexOf("y") !== 0 && pattern != "SS") { 32421 retValue += pattern.substring(0, 1); 32422 pattern = pattern.substring(1, 2); 32423 } else if ((pattern.length === 3 && pattern.indexOf("yyy") === -1)) { 32424 pattern = ""; 32425 } 32426 } 32427 } 32428 return retValue; 32429 } catch (e) { 32430 console.log(e); 32431 return value; 32432 } 32433 } 32434 }; 32435 }()); 32436}(jQuery)); 32437 32438(function ($) { 32439 $.fn.localTimeFromUTC = function (format) { 32440 return this.each(function () { 32441 32442 // get time offset from browser 32443 var currentDate = new Date(); 32444 var offset = -(currentDate.getTimezoneOffset() / 60); 32445 32446 // get provided date 32447 var tagText = $(this).html(); 32448 var givenDate = new Date($.format.date(tagText, format)); 32449 32450 // format the date 32451 var localDateString = $.format.date(givenDate, format); 32452 $(this).html(localDateString + ' ' + givenDate); 32453 }); 32454 }; 32455 })(jQuery); 32456 32457$(document).ready(function () { 32458 $(".shortDateFormat").each(function (idx, elem) { 32459 if ($(elem).is(":input")) { 32460 $(elem).val($.format.date($(elem).val(), "dd/MM/yyyy")); 32461 } else { 32462 $(elem).text($.format.date($(elem).text(), "dd/MM/yyyy")); 32463 } 32464 }); 32465 $(".longDateFormat").each(function (idx, elem) { 32466 if ($(elem).is(":input")) { 32467 $(elem).val($.format.date($(elem).val(), "dd/MM/yyyy hh:mm:ss")); 32468 } else { 32469 $(elem).text($.format.date($(elem).text(), "dd/MM/yyyy hh:mm:ss")); 32470 } 32471 }); 32472}); 32473// Domain Public by Eric Wendelin http://eriwen.com/ (2008) 32474// Luke Smith http://lucassmith.name/ (2008) 32475// Loic Dachary <[email protected]> (2008) 32476// Johan Euphrosine <[email protected]> (2008) 32477// Ãyvind Sean Kinsey http://kinsey.no/blog (2010) 32478// 32479// Information and discussions 32480// http://jspoker.pokersource.info/skin/test-printstacktrace.html 32481// http://eriwen.com/javascript/js-stack-trace/ 32482// http://eriwen.com/javascript/stacktrace-update/ 32483// http://pastie.org/253058 32484// 32485// guessFunctionNameFromLines comes from firebug 32486// 32487// Software License Agreement (BSD License) 32488// 32489// Copyright (c) 2007, Parakey Inc. 32490// All rights reserved. 32491// 32492// Redistribution and use of this software in source and binary forms, with or without modification, 32493// are permitted provided that the following conditions are met: 32494// 32495// * Redistributions of source code must retain the above 32496// copyright notice, this list of conditions and the 32497// following disclaimer. 32498// 32499// * Redistributions in binary form must reproduce the above 32500// copyright notice, this list of conditions and the 32501// following disclaimer in the documentation and/or other 32502// materials provided with the distribution. 32503// 32504// * Neither the name of Parakey Inc. nor the names of its 32505// contributors may be used to endorse or promote products 32506// derived from this software without specific prior 32507// written permission of Parakey Inc. 32508// 32509// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 32510// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 32511// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32512// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32513// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32514// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32515// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 32516// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32517 32518/** 32519 * Main function giving a function stack trace with a forced or passed in Error 32520 * 32521 * @cfg {Error} e The error to create a stacktrace from (optional) 32522 * @cfg {Boolean} guess If we should try to resolve the names of anonymous functions 32523 * @return {Array} of Strings with functions, lines, files, and arguments where possible 32524 */ 32525function printStackTrace(options) { 32526 var ex = (options && options.e) ? options.e : null; 32527 var guess = options ? !!options.guess : true; 32528 32529 var p = new printStackTrace.implementation(); 32530 var result = p.run(ex); 32531 return (guess) ? p.guessFunctions(result) : result; 32532} 32533 32534printStackTrace.implementation = function() {}; 32535 32536printStackTrace.implementation.prototype = { 32537 run: function(ex) { 32538 ex = ex || 32539 (function() { 32540 try { 32541 var _err = __undef__ << 1; 32542 } catch (e) { 32543 return e; 32544 } 32545 })(); 32546 // Use either the stored mode, or resolve it 32547 var mode = this._mode || this.mode(ex); 32548 if (mode === 'other') { 32549 return this.other(arguments.callee); 32550 } else { 32551 return this[mode](ex); 32552 } 32553 }, 32554 32555 /** 32556 * @return {String} mode of operation for the environment in question. 32557 */ 32558 mode: function(e) { 32559 if (e['arguments']) { 32560 return (this._mode = 'chrome'); 32561 } else if (window.opera && e.stacktrace) { 32562 return (this._mode = 'opera10'); 32563 } else if (e.stack) { 32564 return (this._mode = 'firefox'); 32565 } else if (window.opera && !('stacktrace' in e)) { //Opera 9- 32566 return (this._mode = 'opera'); 32567 } 32568 return (this._mode = 'other'); 32569 }, 32570 32571 /** 32572 * Given a context, function name, and callback function, overwrite it so that it calls 32573 * printStackTrace() first with a callback and then runs the rest of the body. 32574 * 32575 * @param {Object} context of execution (e.g. window) 32576 * @param {String} functionName to instrument 32577 * @param {Function} function to call with a stack trace on invocation 32578 */ 32579 instrumentFunction: function(context, functionName, callback) { 32580 context = context || window; 32581 context['_old' + functionName] = context[functionName]; 32582 context[functionName] = function() { 32583 callback.call(this, printStackTrace()); 32584 return context['_old' + functionName].apply(this, arguments); 32585 }; 32586 context[functionName]._instrumented = true; 32587 }, 32588 32589 /** 32590 * Given a context and function name of a function that has been 32591 * instrumented, revert the function to it's original (non-instrumented) 32592 * state. 32593 * 32594 * @param {Object} context of execution (e.g. window) 32595 * @param {String} functionName to de-instrument 32596 */ 32597 deinstrumentFunction: function(context, functionName) { 32598 if (context[functionName].constructor === Function && 32599 context[functionName]._instrumented && 32600 context['_old' + functionName].constructor === Function) { 32601 context[functionName] = context['_old' + functionName]; 32602 } 32603 }, 32604 32605 /** 32606 * Given an Error object, return a formatted Array based on Chrome's stack string. 32607 * 32608 * @param e - Error object to inspect 32609 * @return Array<String> of function calls, files and line numbers 32610 */ 32611 chrome: function(e) { 32612 return e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@').split('\n'); 32613 }, 32614 32615 /** 32616 * Given an Error object, return a formatted Array based on Firefox's stack string. 32617 * 32618 * @param e - Error object to inspect 32619 * @return Array<String> of function calls, files and line numbers 32620 */ 32621 firefox: function(e) { 32622 return e.stack.replace(/(?:\n@:0)?\s+$/m, '').replace(/^\(/gm, '{anonymous}(').split('\n'); 32623 }, 32624 32625 /** 32626 * Given an Error object, return a formatted Array based on Opera 10's stacktrace string. 32627 * 32628 * @param e - Error object to inspect 32629 * @return Array<String> of function calls, files and line numbers 32630 */ 32631 opera10: function(e) { 32632 var stack = e.stacktrace; 32633 var lines = stack.split('\n'), ANON = '{anonymous}', 32634 lineRE = /.*line (\d+), column (\d+) in ((<anonymous function\:?\s*(\S+))|([^\(]+)\([^\)]*\))(?: in )?(.*)\s*$/i, i, j, len; 32635 for (i = 2, j = 0, len = lines.length; i < len - 2; i++) { 32636 if (lineRE.test(lines[i])) { 32637 var location = RegExp.$6 + ':' + RegExp.$1 + ':' + RegExp.$2; 32638 var fnName = RegExp.$3; 32639 fnName = fnName.replace(/<anonymous function\:?\s?(\S+)?>/g, ANON); 32640 lines[j++] = fnName + '@' + location; 32641 } 32642 } 32643 32644 lines.splice(j, lines.length - j); 32645 return lines; 32646 }, 32647 32648 // Opera 7.x-9.x only! 32649 opera: function(e) { 32650 var lines = e.message.split('\n'), ANON = '{anonymous}', 32651 lineRE = /Line\s+(\d+).*script\s+(http\S+)(?:.*in\s+function\s+(\S+))?/i, 32652 i, j, len; 32653 32654 for (i = 4, j = 0, len = lines.length; i < len; i += 2) { 32655 //TODO: RegExp.exec() would probably be cleaner here 32656 if (lineRE.test(lines[i])) { 32657 lines[j++] = (RegExp.$3 ? RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 : ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) + ' -- ' + lines[i + 1].replace(/^\s+/, ''); 32658 } 32659 } 32660 32661 lines.splice(j, lines.length - j); 32662 return lines; 32663 }, 32664 32665 // Safari, IE, and others 32666 other: function(curr) { 32667 var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, 32668 stack = [], j = 0, fn, args; 32669 32670 var maxStackSize = 10; 32671 while (curr && stack.length < maxStackSize) { 32672 fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON; 32673 args = Array.prototype.slice.call(curr['arguments']); 32674 stack[j++] = fn + '(' + this.stringifyArguments(args) + ')'; 32675 curr = curr.caller; 32676 } 32677 return stack; 32678 }, 32679 32680 /** 32681 * Given arguments array as a String, subsituting type names for non-string types. 32682 * 32683 * @param {Arguments} object 32684 * @return {Array} of Strings with stringified arguments 32685 */ 32686 stringifyArguments: function(args) { 32687 for (var i = 0; i < args.length; ++i) { 32688 var arg = args[i]; 32689 if (arg === undefined) { 32690 args[i] = 'undefined'; 32691 } else if (arg === null) { 32692 args[i] = 'null';
32693 } else if (arg.constructor) { 32694 if (arg.constructor === Array) { 32695 if (arg.length < 3) { 32696 args[i] = '[' + this.stringifyArguments(arg) + ']'; 32697 } else { 32698 args[i] = '[' + this.stringifyArguments(Array.prototype.slice.call(arg, 0, 1)) + '...' + this.stringifyArguments(Array.prototype.slice.call(arg, -1)) + ']'; 32699 } 32700 } else if (arg.constructor === Object) { 32701 args[i] = '#object'; 32702 } else if (arg.constructor === Function) { 32703 args[i] = '#function'; 32704 } else if (arg.constructor === String) { 32705 args[i] = '"' + arg + '"'; 32706 } 32707 } 32708 } 32709 return args.join(','); 32710 }, 32711 32712 sourceCache: {}, 32713 32714 /** 32715 * @return the text from a given URL. 32716 */ 32717 ajax: function(url) { 32718 var req = this.createXMLHTTPObject(); 32719 if (!req) { 32720 return; 32721 } 32722 req.open('GET', url, false); 32723 req.setRequestHeader('User-Agent', 'XMLHTTP/1.0'); 32724 req.send(''); 32725 return req.responseText; 32726 }, 32727 32728 /** 32729 * Try XHR methods in order and store XHR factory. 32730 * 32731 * @return <Function> XHR function or equivalent 32732 */ 32733 createXMLHTTPObject: function() { 32734 var xmlhttp, XMLHttpFactories = [ 32735 function() { 32736 return new XMLHttpRequest(); 32737 }, function() { 32738 return new ActiveXObject('Msxml2.XMLHTTP'); 32739 }, function() { 32740 return new ActiveXObject('Msxml3.XMLHTTP'); 32741 }, function() { 32742 return new ActiveXObject('Microsoft.XMLHTTP'); 32743 } 32744 ]; 32745 for (var i = 0; i < XMLHttpFactories.length; i++) { 32746 try { 32747 xmlhttp = XMLHttpFactories[i](); 32748 // Use memoization to cache the factory 32749 this.createXMLHTTPObject = XMLHttpFactories[i]; 32750 return xmlhttp; 32751 } catch (e) {} 32752 } 32753 }, 32754 32755 /** 32756 * Given a URL, check if it is in the same domain (so we can get the source 32757 * via Ajax). 32758 * 32759 * @param url <String> source url 32760 * @return False if we need a cross-domain request 32761 */ 32762 isSameDomain: function(url) { 32763 return url.indexOf(location.hostname) !== -1; 32764 }, 32765 32766 /** 32767 * Get source code from given URL if in the same domain. 32768 * 32769 * @param url <String> JS source URL 32770 * @return <String> Source code 32771 */ 32772 getSource: function(url) { 32773 if (!(url in this.sourceCache)) { 32774 this.sourceCache[url] = this.ajax(url).split('\n'); 32775 } 32776 return this.sourceCache[url]; 32777 }, 32778 32779 guessFunctions: function(stack) { 32780 for (var i = 0; i < stack.length; ++i) { 32781 var reStack = /\{anonymous\}\(.*\)@(\w+:\/\/([\-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/; 32782 var frame = stack[i], m = reStack.exec(frame); 32783 if (m) { 32784 var file = m[1], lineno = m[4]; //m[7] is character position in Chrome 32785 if (file && this.isSameDomain(file) && lineno) { 32786 var functionName = this.guessFunctionName(file, lineno); 32787 stack[i] = frame.replace('{anonymous}', functionName); 32788 } 32789 } 32790 } 32791 return stack; 32792 }, 32793 32794 guessFunctionName: function(url, lineNo) { 32795 try { 32796 return this.guessFunctionNameFromLines(lineNo, this.getSource(url)); 32797 } catch (e) { 32798 return 'getSource failed with url: ' + url + ', exception: ' + e.toString(); 32799 } 32800 }, 32801 32802 guessFunctionNameFromLines: function(lineNo, source) { 32803 var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/; 32804 var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/; 32805 // Walk backwards from the first line in the function until we find the line which 32806 // matches the pattern above, which is the function definition 32807 var line = "", maxLines = 10; 32808 for (var i = 0; i < maxLines; ++i) { 32809 line = source[lineNo - i] + line; 32810 if (line !== undefined) { 32811 var m = reGuessFunction.exec(line); 32812 if (m && m[1]) { 32813 return m[1]; 32814 } else { 32815 m = reFunctionArgNames.exec(line); 32816 if (m && m[1]) { 32817 return m[1]; 32818 } 32819 } 32820 } 32821 } 32822 return '(?)'; 32823 } 32824}; 32825 32826/** 32827 * @author Senad Dizdar 32828 * 32829 * Copyright (C) 2010-2011, cloudHQ 32830 * All rights reserved. 32831 * 32832 */ 32833 32834g_jstree_refresh_inprogress = 0; 32835 32836function c_files(){ 32837 var left_tree_expand_plan = new Array(); 32838 var upload = new Object(); 32839 32840 /*********************************************/ 32841 /* PUBLIC FUNCTIONS */ 32842 /*********************************************/ 32843 32844 /*** 32845 * Initilize for creating of c_files object 32846 */ 32847 this.fn_init = function fn_init(){ 32848 32849 $('input.working_link').unbind('click').bind('click', function() { 32850 if ($(this).hasClass('noclick')) { 32851 return false; 32852 } 32853 var text = "Working..."; 32854 if ($(this).attr('notif_to_display') != null) 32855 text = $(this).attr('notif_to_display');
32856 try { g_cmn.fn_working_overlay(true, text); } catch(er) { } 32857 return true; 32858 }); 32859 32860 // setup resizing of columns 32861 fn_right_jstree_columns_setup(); 32862 32863 // call server to intilize 32864 $.ajax({ 32865 type: "POST", 32866 url: g_site_url + "main_cloud_fs_interface/cloudhq_init", 32867 dataType: "json", 32868 data: { 'raise_authorization_error_flag': true }, 32869 async: true, 32870 success: function(response){ 32871 if (response.verify_credential) { 32872 var res_ver_cred = response.verify_credential; 32873 var txt = 'Authorization for <b>' + res_ver_cred.what_nice + '</b> expired. <br>'; 32874 var url = g_site_url + "modify_services/" + res_ver_cred.what + "?email_or_login=" + res_ver_cred.email_or_login; 32875 txt += 'Do you want to reauthorize cloudHQ with ' + res_ver_cred.what_nice + '?'; 32876 if (res_ver_cred.domain && res_ver_cred.domain != 'nil') 32877 url += "&domain=" + res_ver_cred.domain; 32878 32879 g_cmn.fn_error_dialog("ERROR", txt, { 32880 width: "500px", 32881 buttons: { 32882 "Ignore": function(){ 32883 fn_init_ignore_authorization_error(); 32884 $(this).dialog("close"); 32885 }, 32886 "Ok": function(){ 32887 location.href = url; 32888 $(this).dialog("close"); 32889 } 32890 } 32891 }); 32892 } 32893 else { 32894 if (response.error) { 32895 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 32896 width: "370px" 32897 }); 32898 } 32899 else { 32900 fn_display_left_jstree(response); 32901 fn_display_copy_node_jstree(response); 32902 fn_display_move_node_jstree(response); 32903 32904 fn_resize_areas(); 32905 $(window).resize(function(){ 32906 fn_resize_areas(); 32907 }); 32908 32909 } 32910 } 32911 }, 32912 failure: function(response){ 32913 alert("Failure"); 32914 } 32915 }); 32916 } 32917 32918 var fn_init_ignore_authorization_error = function fn_init_ignore_authorization_error(){ 32919 32920 // setup resizing of columns 32921 fn_right_jstree_columns_setup(); 32922 32923 // call server to intilize 32924 $.ajax({
32925 type: "POST", 32926 url: g_site_url + "main_cloud_fs_interface/cloudhq_init", 32927 dataType: "json", 32928 data: { 'raise_authorization_error_flag': false }, 32929 async: true, 32930 success: function(response){ 32931 if (response.verify_credential) { 32932 $(this).dialog("close"); 32933 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 32934 width: "370px" 32935 }); 32936 32937 } 32938 else { 32939 if (response.error) { 32940 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 32941 width: "370px" 32942 }); 32943 } 32944 else { 32945 fn_display_left_jstree(response); 32946 fn_display_copy_node_jstree(response); 32947 fn_display_move_node_jstree(response); 32948 32949 fn_resize_areas(); 32950 $(window).resize(function(){ 32951 fn_resize_areas(); 32952 }); 32953 32954 } 32955 } 32956 }, 32957 failure: function(response){ 32958 alert("Failure"); 32959 } 32960 }); 32961 } 32962 32963 /*********************************************/ 32964 /* PRIVATE FUNCTIONS */ 32965 /*********************************************/ 32966 var fn_display_left_jstree = function fn_display_left_jstree(response) { 32967 $('#left_jstree_container').jstree("destroy"); 32968 $('#left_jstree_container').bind('load_node.jstree', function(event, data){ 32969 // alert("reopen"); 32970 }) 32971 .jstree({ 32972 "core": { 32973 html_titles: true 32974 }, 32975 "json_data": { 32976 "correct_state": true, 32977 "data": response, 32978 "ajax": { 32979 "url": function(n) { 32980 if (n == -1) 32981 return false; 32982 else { 32983 g_cmn.fn_notif_win(true, "Loading...", null); 32984 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 32985 } 32986 }, 32987 "success": function(obj, t, x){ 32988 $('#loading').css('display', 'none'); 32989 32990 if (t == "success") { 32991 32992 var response = JSON.parse(x.responseText); 32993 if (response['error']) { 32994 // g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { width: "370px" }); 32995 // g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page", 5000); 32996 } 32997 else 32998 g_cmn.fn_notif_win(false, "", null); 32999 } 33000 else { 33001 g_cmn.fn_notif_win(false, "", null); 33002 } 33003 }, 33004 "error": function(obj){ 33005 // g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { width: "370px" }); 33006 // alert ("error: jQuery internal error. Please refresh the page."); 33007 }, 33008 "data": function(element) { 33009 33010 if (element.data('jstree') == null) { 33011 // g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page", 5000); 33012 g_cmn.fn_log("ERROR", "element.data('jstree') is null (1)"); 33013 } 33014 33015 return { 33016 "obj": $.toJSON(element.data('jstree')), 33017 "file_flag": $.toJSON(false) 33018 } 33019 } 33020 } 33021 }, 33022 "themes": { 33023 "theme": "cloudhq", 33024 "dots": false, 33025 "icons": true 33026 }, 33027 "plugins": ["themes", "json_data", "ui", "crrm", "types"] 33028 }); 33029 33030 // bind that on select node we call open node and display right tree 33031 $("#left_jstree_container").bind("select_node.jstree", function(e, data){ 33032 33033 // alert('event.originalEvent.type='+e.originalEvent.type); 33034 33035 // if this is not click 33036 if (!(data && data.args[2] && data.args[2].originalEvent && data.args[2].originalEvent.type == 'click')) 33037 { 33038 if (g_jstree_refresh_inprogress > 1) { 33039 if ($("#left_jstree_container .jstree-open").length >= g_jstree_refresh_inprogress - 1) 33040 g_jstree_refresh_inprogress = 0; 33041 else 33042 return false; 33043 } 33044 } 33045 33046 $("#left_jstree_container").jstree('open_node', data.rslt.obj); 33047 fn_display_right_jstree(data.rslt.obj); 33048 33049 });
33050 33051 $('#refresh_item_btn').unbind("click").bind('click', function(e, data){ 33052 fn_refresh_server(null, ''); 33053 }); 33054 33055 33056 // initilize upload logic 33057 fn_make_file_upload(); 33058 33059 // do resizable 33060 var padding_between_left_and_right = $('#files_container').width() - $('#right_container').width() - $("#left_dir_container").width(); 33061 $("#left_dir_container").resizable( 33062 { 33063 maxWidth: 650, 33064 minWidth: 250, 33065 handles: 'e', 33066 resize: function() { 33067 var total_width = $('#files_container').width(); 33068 $('#right_container').width(total_width - $("#left_dir_container").width() - padding_between_left_and_right); 33069 $('#right_dir_nofiles_wrap').width($('#right_container').width()); 33070 } 33071 }); 33072 33073 } /* fn_display_left_jstree */ 33074 33075 33076 /* 33077 * Display right jstree given root object 33078 */ 33079 var fn_display_right_jstree = function fn_display_right_jstree(data_rslt_obj){ 33080 33081 var flag = false; 33082 var dir_obj; 33083 var current_ins_id = 0; 33084 33085 if (data_rslt_obj == null) 33086 { 33087 g_cmn.fn_log("ERROR", "fn_display_right_jstree: data_rslt_obj is null (0)"); 33088 return; 33089 } 33090 33091 if (data_rslt_obj.data('jstree') == null) 33092 { 33093 g_cmn.fn_log("ERROR", "fn_display_right_jstree: data_rslt_obj.data('jstree') is null (0)"); 33094 return; 33095 } 33096 33097 // GROT: we save it into global so that 'copy' and 'move' operations know where we stand 33098 // The right way is that copy/move dialogs query jstree to see top level 33099 g_top_right_jstree_node = data_rslt_obj.clone(true, true); 33100 33101 var top_right_jstree_node = data_rslt_obj.clone(true, true); 33102 var tmp = top_right_jstree_node.data('jstree'); 33103 if (tmp && tmp['is_create_disabled']) 33104 g_is_create_disabled = true; 33105 else 33106 g_is_create_disabled = false; 33107 33108 if (tmp && tmp['is_folder_create_disabled']) 33109 g_is_folder_create_disabled = true; 33110 else 33111 g_is_folder_create_disabled = false; 33112 33113 // this variable is used to check whether we are building a new tree 33114 // if set to true, that means we still have not build a tree completly 33115 var first_call = true; 33116 33117 // display the right container 33118 $('#right_dir_container').show(); 33119 $('#right_jstree_container').show(); 33120 $('#right_doc_container').hide(); 33121 33122 // display breadcrump for right tree 33123 // As of now that is just title 33124 var fn_display_breadcrumb = function(data_rslt_obj){ 33125 var d = data_rslt_obj.data('jstree'); 33126 $('#right_dir_container .right_dir_breadcrumb').html(d['title_no_html']); 33127 $('#synch_wizard_button_form_data').empty(); 33128 if (d.is_folder && !d.is_synch_disabled) { 33129 // add input rows with obj (which is json object) and name (just string) 33130 $(document.createElement('input')).attr({'type': 'hidden', 'name': 'obj', 'value' : $.toJSON(d) }).appendTo($('#synch_wizard_button_form_data')); 33131 $('#synch_wizard_button_wrapper').show(); 33132 } 33133 else 33134 $('#synch_wizard_button_wrapper').hide(); 33135 33136 } 33137 33138 fn_display_breadcrumb(data_rslt_obj); 33139 33140 $('#main_checkbox').removeClass('toggle'); 33141 $('#main_checkbox').attr({ 33142 'checked': false 33143 }); 33144 $('#right_dir_nofiles_container').hide(); 33145 $('#right_jstree_container').jstree("destroy"); 33146 $('#right_jstree_container').bind('load_node.jstree', function(event, data){ 33147 // on load we need to resize right 33148 fn_right_jstree_columns_resize(); 33149 }).bind("before.jstree", function(e, data){ 33150 if (data.func === "open_node") { 33151 // alert("open_node"); 33152 // when server sends data it fills up metadata. This metadata puts "is_folder" flag. 33153 var jstree = data.args[0].data('jstree'); 33154 var is_folder = false; 33155 if (jstree) 33156 is_folder = jstree['is_folder']; 33157 33158 if (is_folder == true) { 33159 // find element id in left jstree and select it 33160 var n = $("#left_jstree_container " + "#" + data.args[0].attr("id")); 33161 $("#left_jstree_container").jstree('deselect_all'); 33162 $("#left_jstree_container").jstree('select_node', n, false); 33163 document.getElementById('left_jstree_container').scrollTop = document.getElementById(data.args[0].attr("id")).offsetTop; 33164 } 33165 e.stopImmediatePropagation(); 33166 return false; 33167 } 33168 }).jstree({ 33169 "core": { 33170 html_titles: true 33171 }, 33172 "json_data": { 33173 "ajax": { 33174 "url": function(n){ 33175 g_cmn.fn_notif_win(true, "Loading...", null); 33176 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 33177 }, 33178 "success": function(obj, t, x){ 33179 // We display no files *only* if this is very first call 33180 if (first_call == true) { 33181 if (obj == null || obj.length == null || obj.length == 0) { 33182 $('#right_jstree_container').jstree("destroy").hide(); 33183 $('#right_dir_nofile_content').html('Empty folder'); 33184 $('#right_dir_nofiles_container').show(); 33185 } 33186 } 33187 first_call = false; 33188 g_cmn.fn_notif_win(false, "", null); 33189 }, 33190 "error": function(obj){ 33191 // g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page", 5000); 33192 }, 33193 "data": function(element){ 33194 33195 var obj = null; 33196 if (element.attr == null || element.attr("id") == null) 33197 obj = top_right_jstree_node.data('jstree'); 33198 else 33199 obj = element.data('jstree'); 33200 33201 if (obj == null) { 33202 //g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page", 5000); 33203 g_cmn.fn_log("ERROR", "obj.data('jstree') is null (2)"); 33204 } 33205 33206 return { 33207 "obj": $.toJSON(obj), 33208 "file_flag": $.toJSON(true) 33209 } 33210 } 33211 } 33212 }, 33213 "themes": { 33214 "theme": "cloudhq", 33215 "dots": false, 33216 "icons": true 33217 }, 33218 "plugins": ["themes", "json_data", "ui", "crrm", "types" ] 33219 });
33220 33221 $("#right_jstree_container").unbind("select_node.jstree").bind("select_node.jstree", function(e, data){ 33222 // when server sends data it fills up metadata. This metadata puts "is_folder" flag. 33223 var jstree = data.rslt.obj.data('jstree'); 33224 var is_folder = false; 33225 if (jstree) 33226 is_folder = jstree['is_folder']; 33227 33228 if (is_folder == true) { 33229 // find element id in left jstree and select it 33230 var n = $("#left_jstree_container " + "#" + data.rslt.obj.attr("id")); 33231 $("#left_jstree_container").jstree('deselect_all'); 33232 $("#left_jstree_container").jstree('select_node', n, false); 33233 document.getElementById('left_jstree_container').scrollTop = document.getElementById(data.rslt.obj.attr("id")).offsetTop; 33234 fn_display_right_jstree(data.rslt.obj); 33235 } 33236 else { 33237 // maybe we should disable view of documents? 33238 // var obj = $(data.rslt.obj).data('jstree'); 33239 // fn_view_document(obj); 33240 } 33241 }); 33242 33243 $('#main_checkbox').unbind("click").bind('click', function(){ 33244 if ($(this).hasClass('checkbox_icon')) { 33245 $(this).removeClass('checkbox_icon'); 33246 $(this).addClass('checkbox_icon-checked'); 33247 $("#right_jstree_container").jstree("check_all"); 33248 } 33249 else { 33250 $(this).addClass('checkbox_icon'); 33251 $(this).removeClass('checkbox_icon-checked'); 33252 $("#right_jstree_container").jstree("uncheck_all"); 33253 } 33254 }); 33255 33256 $('#upload_new_file_btn').unbind("click").bind('click', function(e, data){ 33257 33258 if (top_right_jstree_node.length > 0 && top_right_jstree_node.data('jstree').what == 'google_gmail') 33259 fn_error_dialog('Error', 'Creating new Gmail messages is not supported.'); 33260 else if (g_is_create_disabled == false) { 33261 // The node_id is in form which will be submited on upload 33262 var d = top_right_jstree_node.data('jstree'); 33263 $('#upload_new_file_dialog #upload_obj').val($.toJSON(d)); 33264 upload_new_file_dialog.dialog('open'); 33265 } else 33266 g_cmn.fn_notif_win(true, 'Upload not allowed on this level', 5000); 33267 }); 33268 33269 $('#new_folder_btn').unbind("click").bind('click', function(){ 33270 33271 if (top_right_jstree_node.length > 0 && top_right_jstree_node.data('jstree').what == 'google_gmail') 33272 fn_error_dialog('Error', 'Creating of new Gmail labels is not supported.'); 33273 else if (g_is_create_disabled == false && g_is_folder_create_disabled == false) 33274 create_new_folder_dialog.dialog('open'); 33275 else 33276 g_cmn.fn_notif_win(true, 'New folder creation not allowed on this level', 5000); 33277 }); 33278 33279 $('#copy_item_btn').unbind("click").bind('click', function(){ 33280 if (!fn_get_checked_element_flag()) { 33281 fn_error_dialog('Error', 'Nothing selected.'); 33282 } 33283 else if (fn_is_item_gmail()) { 33284 fn_error_dialog('Error', 'Copy for Gmail is not supported.'); 33285 } 33286 else { 33287 copy_node_dialog.dialog('open'); 33288 } 33289 }); 33290 33291 $('#move_item_btn').unbind("click").bind('click', function(){ 33292 if (!fn_get_checked_element_flag()) 33293 fn_error_dialog('Error', 'Nothing selected.'); 33294 else if (fn_is_item_gmail()) { 33295 fn_error_dialog('Error', 'Move for Gmail is not supported.'); 33296 } 33297 else { 33298 move_node_dialog.dialog('open'); 33299 } 33300 }); 33301 33302 $('#delete_item_btn').unbind("click").bind('click', function(){ 33303 if (!fn_get_checked_element_flag()) 33304 fn_error_dialog('Error', 'Nothing selected.'); 33305 else if (fn_is_item_gmail()) { 33306 fn_error_dialog('Error', 'Delete for Gmail is not supported.'); 33307 } 33308 else { 33309 var checked_obj = $("#right_jstree_container").jstree("get_checked"); 33310 var doc = document; 33311 var ul_node = doc.createElement('ul'); 33312 $(checked_obj).each(function(){ 33313 var node_text = $('#left_jstree_container').jstree("get_text", this); 33314 var li_node = doc.createElement('li'); 33315 $(li_node).html(node_text); 33316 $(li_node).appendTo(ul_node); 33317 }); 33318 $('#delete_node_list').html(''); 33319 $(ul_node).appendTo($('#delete_node_list'));
33320 delete_node_dialog.dialog('open'); 33321 } 33322 }); 33323 33324 $('#download_item_btn').unbind("click").bind('click', function(){ 33325 if (!fn_get_checked_element_flag()) 33326 fn_error_dialog('Error', 'Nothing selected.'); 33327 else if (fn_is_item_gmail()) { 33328 fn_error_dialog('Error', 'Download for Gmail is not supported.'); 33329 } 33330 else { 33331 var checked_obj = $("#right_jstree_container").jstree("get_checked"); 33332 var doc = document; 33333 var ul_node = doc.createElement('ul'); 33334 $(checked_obj).each(function(){ 33335 var node_text = $('#left_jstree_container').jstree("get_text", this); 33336 var li_node = doc.createElement('li'); 33337 $(li_node).html(node_text); 33338 $(li_node).appendTo(ul_node); 33339 }); 33340 $('#download_node_list').html(''); 33341 $(ul_node).appendTo($('#download_node_list')); 33342 download_node_dialog.dialog('open'); 33343 } 33344 }); 33345 33346 $('#add_item_btn').unbind("click").bind('click', function(){ 33347 $('#add_menu').slideToggle('fast', function(){ 33348 }); 33349 $('#add_item_btn').unbind("outerClick").bind('outerClick', function(){ 33350 $('#add_menu').hide(); 33351 }); 33352 }); 33353 33354 $('#info_item_btn').unbind("click").bind('click', function(){ 33355 if (!fn_get_checked_element_flag()) 33356 fn_error_dialog('Error', 'Nothing selected.'); 33357 else { 33358 g_cmn.fn_notif_win(true, "Getting Info...", null); 33359 var obj_list = fn_get_checked_obj_list(); 33360 $.ajax({
33361 type: "POST", 33362 url: g_site_url + "main_cloud_fs_interface/info", 33363 dataType: "json", 33364 data: { 33365 "obj_list": $.toJSON(obj_list) 33366 }, 33367 async: true, 33368 success: function(response){ 33369 if (response.error) { 33370 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 33371 width: "370px" 33372 }); 33373 // g_cmn.fn_notif_win(true, "Getting info failed. <br\>" + response.error , 5000); 33374 } 33375 else { 33376 var res_len = response.length; 33377 if (res_len) { 33378 var doc = document; 33379 var node_info = doc.createElement('div'); 33380 for (var i = 0; i < res_len; i++) { 33381 var ul_node = doc.createElement('ul'); 33382 var result = response[i]; 33383 var li_node_obj = $('#right_jstree_container').find('li#dir_' + result.gid); 33384 var li_title = doc.createElement('li'); 33385 $(li_title).html(result.title).addClass('filename'); 33386 $(li_title).appendTo(ul_node); 33387 33388 var li_datetime = doc.createElement('li'); 33389 var last_modified = result.last_modified; 33390 $(li_datetime).html(last_modified).addClass('datetime'); 33391 li_node_obj.find('span.jstree_datetime').html(last_modified); 33392 $(li_datetime).appendTo(ul_node); 33393 33394 var li_sharing = doc.createElement('li'); 33395 var get_is_sharing = result.what == 'sugarsync' && result.sharing_enabled != undefined ? result.sharing_enabled : 'N/A'; 33396 $(li_sharing).html(get_is_sharing).addClass('share_enabled'); 33397 // li_node_obj.find('span.jstree_size').html(get_is_sharing); 33398 $(li_sharing).appendTo(ul_node); 33399 33400 var li_obj_type = doc.createElement('li'); 33401 var get_obj_type = result.obj_type ? result.obj_type : 'N/A'; 33402 $(li_obj_type).html(get_obj_type).addClass('media_type'); 33403 // li_node_obj.find('span.jstree_size').html(get_obj_type); 33404 $(li_obj_type).appendTo(ul_node); 33405 33406 var li_shared_people = doc.createElement('li'); 33407 var shared_people = result.acl != null ? result.acl.length : 'N/A'; 33408 $(li_shared_people).html(shared_people).addClass('shared_people'); 33409 // li_node_obj.find('span.jstree_owner').html(shared_people); 33410 $(li_shared_people).appendTo(ul_node); 33411 $(ul_node).appendTo(node_info); 33412 } 33413 $('.file_info_response').html(''); 33414 $(node_info).appendTo($('.file_info_response')); 33415 g_cmn.fn_notif_win(false, "", null); 33416 info_node_dialog.dialog('open'); 33417 } 33418 } 33419 }, 33420 failure: function(response){ 33421 g_cmn.fn_notif_win(false, "", null); 33422 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 33423 width: "370px" 33424 }); 33425 } 33426 }); 33427 } 33428 }); 33429 } /* fn_display_right_jstree */ 33430 33431 var info_node_dialog = $("#info_node_dialog").dialog({ 33432 autoOpen: false, 33433 resizable: false, 33434 width: 700, 33435 height: 350, 33436 title: "Files Info...", 33437 modal: true, 33438 buttons: { 33439 "Ok": function(){ 33440 $(this).dialog("close"); 33441 } 33442 } 33443 }); 33444 33445 var upload_new_file_dialog = $("#upload_new_file_dialog").dialog({ 33446 autoOpen: false, 33447 resizable: false, 33448 width: 450, 33449 height: 340, 33450 title: "Files Upload", 33451 modal: true, 33452 buttons: { 33453 "Cancel": function(){ 33454 $(this).dialog("close"); 33455 } 33456 } 33457 }); 33458 33459 var create_new_folder_dialog = $("#create_new_folder_dialog").dialog({ 33460 autoOpen: false, 33461 resizable: false, 33462 width: 460, 33463 height: 225, 33464 title: "Create Folder", 33465 modal: true, 33466 buttons: { 33467 "Cancel": function(){ 33468 $(this).dialog("close"); 33469 }, 33470 "Create folder": function(){ 33471 var folder_name = $('#folder_name').val(); 33472 if (folder_name == '') 33473 g_cmn.fn_notif_win(true, "Please enter the folder name", 5000); 33474 else { 33475 g_cmn.fn_notif_win(true, "Creating folder...", null); 33476 var obj = g_top_right_jstree_node.data('jstree'); 33477 $.ajax({
33478 type: "POST", 33479 url: g_site_url + "main_cloud_fs_interface/new_dir", 33480 dataType: "json", 33481 data: { 33482 "obj": $.toJSON(obj), 33483 "folder_name": $.toJSON(folder_name) 33484 }, 33485 async: true, 33486 success: function(response){ 33487 if (response.error) { 33488 fn_error_dialog("Error during folder creation", response.error); 33489 g_cmn.fn_notif_win(false, "", null); 33490 // g_cmn.fn_notif_win(true, "Folder creation failed.<br\>" + response.error , 5000); 33491 } 33492 else { 33493 g_cmn.fn_notif_win(true, "Folder created", 5000); 33494 fn_refresh_server(obj, 'new_dir'); 33495 } 33496 }, 33497 failure: function(response){ 33498 g_cmn.fn_notif_win(false, "", null); 33499 alert("Failure"); 33500 } 33501 }); 33502 $(this).dialog("close"); 33503 } 33504 } 33505 } 33506 }); 33507 33508 var copy_node_dialog = $("#copy_node_dialog").dialog({ 33509 autoOpen: false, 33510 resizable: false, 33511 width: 700, 33512 height: 550, 33513 title: "Files Copy", 33514 modal: true, 33515 buttons: { 33516 "Cancel": function(){ 33517 g_cmn.fn_notif_win(false, "", null); 33518 $(this).dialog("close"); 33519 }, 33520 "Copy": function(){ 33521 var $folder_element = $($("#copy_node_jstree_container .jstree-clicked")).parent('li'); 33522 if ($folder_element.length < 1) 33523 g_cmn.fn_notif_win(true, "Select destination to copy", 5000); 33524 else { 33525 var folder_obj = $folder_element.data('jstree'); 33526 33527 if (folder_obj['is_create_disabled'] == true) { 33528 g_cmn.fn_notif_win(true, 'Creation of files is not allowed on this level. <br/>Please select different destination.', 5000); 33529 } 33530 33531 else { 33532 33533 if ($("#copy_node_dialog input[type='checkbox']").is(':checked')) 33534 upload_convert_policy = 1 33535 else 33536 upload_convert_policy = 0 33537 var obj_list = fn_get_checked_obj_list(); 33538 g_cmn.fn_notif_win(true, "Copying...", null); 33539 $.ajax({
33540 type: "POST", 33541 url: g_site_url + "main_cloud_fs_interface/copy", 33542 dataType: "json", 33543 data: { 33544 "obj_list": $.toJSON(obj_list), 33545 "target_obj": $.toJSON(folder_obj), 33546 "upload_convert_policy" : $.toJSON(upload_convert_policy) 33547 }, 33548 async: true, 33549 success: function(response){ 33550 if (response.error) { 33551 fn_error_dialog("Error during copy", response.error); 33552 g_cmn.fn_notif_win(false, "", null); 33553 } 33554 else 33555 if (response.long_running_operation) { 33556 g_cmn.fn_notif_win(false, null); 33557 fn_refresh_server(folder_obj, 'copy'); 33558 g_cmn.fn_normal_dialog("Copy operation started", "", "Since copy will take longer than 2 minutes we started a background job which will copy the selected files.<br/><br/>You will receive an email when the job finishes.", { 33559 width: "550px" 33560 }); 33561 } 33562 else if (response.status_txt) { 33563 fn_refresh_server(folder_obj, 'copy'); 33564 g_cmn.fn_notif_win(true, response.status_txt, 5000); 33565 } 33566 else { 33567 fn_refresh_server(folder_obj, 'copy'); 33568 g_cmn.fn_notif_win(true, "Files copied", 5000); 33569 } 33570 }, 33571 failure: function(response){ 33572 g_cmn.fn_notif_win(false, "", null); 33573 } 33574 }); 33575 $(this).dialog("close"); 33576 } 33577 } 33578 } 33579 } 33580 }); 33581 33582 var move_node_dialog = $("#move_node_dialog").dialog({ 33583 autoOpen: false, 33584 resizable: false, 33585 width: 700, 33586 height: 550, 33587 title: "Files Move", 33588 modal: true, 33589 buttons: { 33590 "Cancel": function(){ 33591 g_cmn.fn_notif_win(false, "", null); 33592 $(this).dialog("close"); 33593 }, 33594 "Move": function(){ 33595 var $target_element = $($("#move_node_jstree_container .jstree-clicked")).parent('li'); 33596 if ($target_element.length < 1) 33597 g_cmn.fn_notif_win(true, "Please select destination", 5000); 33598 else { 33599 var target_obj = $target_element.data('jstree'); 33600 33601 if (target_obj['is_create_disabled'] == true) { 33602 g_cmn.fn_notif_win(true, 'Creation of files is not allowed on this level. <br/>Please select different destination.', 5000); 33603 } 33604 else { 33605 33606 var obj_list = fn_get_checked_obj_list(); 33607 33608 if ($("#copy_node_dialog input[type='checkbox']").is(':checked')) 33609 upload_convert_policy = 1 33610 else 33611 upload_convert_policy = 0 33612 g_cmn.fn_notif_win(true, "Moving...", null); 33613 $.ajax({
33614 type: "POST", 33615 url: g_site_url + "main_cloud_fs_interface/move", 33616 dataType: "json", 33617 data: { 33618 "obj_list": $.toJSON(obj_list), 33619 "target_obj": $.toJSON(target_obj), 33620 "upload_convert_policy": $.toJSON(upload_convert_policy) 33621 }, 33622 async: true, 33623 success: function(response){ 33624 if (response.error) { 33625 fn_error_dialog("Error during move", response.error); 33626 g_cmn.fn_notif_win(false, "", null); 33627 fn_refresh_server(null, 'move'); 33628 } 33629 else if (response.long_running_operation) { 33630 g_cmn.fn_notif_win(false, "Move job started", 1000); 33631 g_cmn.fn_normal_dialog("Move operation started", "", "Since move operation will take longer than 2 minutes we started a background job which will move the files.<br/><br/>You will receive an email when the move finishes.", { 33632 width: "550px" 33633 }); 33634 } 33635 else { 33636 g_cmn.fn_notif_win(true, "Success", 5000); 33637 fn_refresh_server(null, 'move'); 33638 } 33639 }, 33640 failure: function(response){ 33641 g_cmn.fn_notif_win(false, "", null); 33642 // alert("Failure"); 33643 } 33644 }); 33645 $(this).dialog("close"); 33646 } 33647 } 33648 } 33649 } 33650 }); 33651 33652 var delete_node_dialog = $("#delete_node_dialog").dialog({ 33653 autoOpen: false, 33654 resizable: false, 33655 width: 450, 33656 title: "Files Delete", 33657 modal: true, 33658 buttons: { 33659 "Cancel": function(){ 33660 $(this).dialog("close"); 33661 }, 33662 "Delete": function(){ 33663 var obj_list = fn_get_checked_obj_list(); 33664 g_cmn.fn_notif_win(true, "Deleting files...", null); 33665 $.ajax({
33666 type: "POST", 33667 url: g_site_url + "main_cloud_fs_interface/delete", 33668 dataType: "json", 33669 data: { 33670 "obj_list": $.toJSON(obj_list) 33671 }, 33672 async: true, 33673 success: function(response){ 33674 if (response.error) { 33675 fn_error_dialog("Error during delete", response.error); 33676 g_cmn.fn_notif_win(false, "", null); 33677 } 33678 else if (response.long_running_operation) { 33679 g_cmn.fn_notif_win(false, "Delete job started", 1000); 33680 g_cmn.fn_normal_dialog("Delete operation started", "", "Since delete will take longer than 2 minutes we started a background job which will finish the deletion of the files.<br/><br/>You will receive an email when the job finishes.", { 33681 width: "550px" 33682 }); 33683 } 33684 else { 33685 g_cmn.fn_notif_win(true, "Success", 5000); 33686 fn_refresh_server(null, 'delete'); 33687 } 33688 }, 33689 failure: function(response){ 33690 g_cmn.fn_notif_win(false, "", null); 33691 } 33692 }); 33693 $(this).dialog("close"); 33694 } 33695 } 33696 }); 33697 33698 var download_node_dialog = $('#download_node_dialog').dialog({ 33699 autoOpen: false, 33700 resizable: false, 33701 width: 450, 33702 title: "Files Download", 33703 modal: true, 33704 buttons: { 33705 "Cancel": function(){ 33706 $(this).dialog("close"); 33707 }, 33708 "Download": function(){ 33709 fn_download_documents(); 33710 $(this).dialog("close"); 33711 } 33712 } 33713 }); 33714 33715 /** 33716 * Display document represented by node 33717 * @param {Object} obj_id 33718 */ 33719 var fn_view_document = function fn_view_document(obj){ 33720 g_cmn.fn_working_overlay(true, "Downloading..."); 33721 var obj_list = new Array(); 33722 obj_list.push(obj); 33723 $.ajax({
33724 type: "POST", 33725 url: g_site_url + "main_cloud_fs_interface/download", 33726 dataType: "json", 33727 data: { 33728 "obj_list": $.toJSON(obj_list) 33729 }, 33730 async: true, 33731 success: function(response){ 33732 g_cmn.fn_working_overlay(false, null); 33733 if (response.error) {; 33734 fn_error_dialog("Download failed", response.error); 33735 } 33736 else if (response.long_running_operation) { 33737 fn_error_dialog("Download failed", "Operation timed out - please try again"); 33738 } 33739 else if (response.media_type == 'text/html') { 33740 var view_uri = g_site_url + 33741 'main_cloud_fs_interface/get_file?save_as=0' + 33742 '&filename=' + 33743 response.filename + 33744 '&media_type=' + 33745 response.media_type + 33746 '&title=' + 33747 response.title; 33748 $('#right_doc_container #right_doc_image_content').hide(); 33749 $('#right_doc_container #right_doc_video_content').hide(); 33750 $('#right_doc_container #right_doc_iframe_content').show().attr('src', view_uri); 33751 $('#right_dir_container').hide(); 33752 $('#right_doc_container').show(); 33753 $('#right_doc_container a').unbind('click').bind('click', function(){ 33754 $('#right_dir_container').show(); 33755 $('#right_doc_container').hide(); 33756 return false; 33757 }); 33758 } 33759 else { 33760 if (response.media_type == 'application/pdf' || 33761 response.media_type == 'application/vnd.ms-powerpoint' || 33762 response.media_type == 'application/msword' || 33763 response.media_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || 33764 response.media_type == 'application/x-vnd.oasis.opendocument.spreadsheet' || 33765 response.media_type == 'application/vnd.oasis.opendocument.text') { 33766 g_cmn.fn_notif_win(true, "File downloaded", 5000); 33767 // since users might have popup blocker, we will display document as iFrame 33768 var view_uri = 'https://docs.google.com/viewer?embedded=true&url=' + 33769 encodeURIComponent(g_site_url + 33770 'main_cloud_fs_interface/get_file?save_as=0' + 33771 '&filename=' + 33772 response.filename + 33773 '&media_type=' + 33774 response.media_type + 33775 '&title=' + 33776 response.title); 33777 $('#right_doc_container #right_doc_image_content').hide(); 33778 $('#right_doc_container #right_doc_video_content').hide(); 33779 $('#right_doc_container #right_doc_iframe_content').show().attr('src', view_uri); 33780 $('#right_dir_container').hide(); 33781 $('#right_doc_container').show(); 33782 $('#right_doc_container a').unbind('click').bind('click', function(){ 33783 $('#right_dir_container').show(); 33784 $('#right_doc_container').hide(); 33785 return false; 33786 }); 33787 } 33788 else 33789 if (response.media_type == 'image/jpeg' || 33790 response.media_type == 'image/gif' || 33791 response.media_type == 'image/tiff' || 33792 response.media_type == 'image/png' || 33793 response.media_type == 'image/bmp') { 33794 g_cmn.fn_notif_win(true, "File downloaded", 5000); 33795 // since users might have popup blocker, we will display document as iFrame 33796 var view_uri = g_site_url + 'main_cloud_fs_interface/get_file?save_as=0' + 33797 '&filename=' + 33798 encodeURIComponent(response.filename) + 33799 '&media_type=' + 33800 encodeURIComponent(response.media_type) + 33801 '&title=' + 33802 encodeURIComponent(response.title); 33803 $('#right_doc_container #right_doc_iframe_content').hide(); 33804 $('#right_doc_container #right_doc_video_content').hide(); 33805 $('#right_doc_container #right_doc_image_content').show().attr('src', view_uri);
33806 $('#right_dir_container').hide(); 33807 $('#right_doc_container').show(); 33808 $('#right_doc_container a').unbind('click').bind('click', function(){ 33809 $('#right_dir_container').show(); 33810 $('#right_doc_container').hide(); 33811 return false; 33812 }); 33813 33814 } 33815 else 33816 if (response.media_type == 'video/mpeg' || 33817 response.media_type == 'application/x-shockwave-flash' || 33818 response.media_type == 'video/x-ms-wmv') { 33819 g_cmn.fn_notif_win(true, "File downloaded", 5000); 33820 var view_uri = g_site_url + 'main_cloud_fs_interface/get_file?save_as=0' + 33821 '&filename=' + 33822 encodeURIComponent(response.filename) + 33823 '&media_type=' + 33824 encodeURIComponent(response.media_type) + 33825 '&title=' + 33826 encodeURIComponent(response.title); 33827 $('#right_doc_container #right_doc_iframe_content').hide(); 33828 $('#right_doc_container #right_doc_image_content').hide(); 33829 $('#right_doc_container #right_doc_video_content').show().attr({ 33830 'src': view_uri, 33831 'type': response.media_type 33832 }); 33833 $('#right_dir_container').hide(); 33834 $('#right_doc_container').show(); 33835 $('#right_doc_container a').unbind('click').bind('click', function(){ 33836 $('#right_dir_container').show(); 33837 $('#right_doc_container').hide(); 33838 return false; 33839 }); 33840 33841 } 33842 else { 33843 g_cmn.fn_notif_win(true, "Success", 5000); 33844 location.href = g_site_url + 'main_cloud_fs_interface/get_file?save_as=1' + 33845 '&filename=' + 33846 encodeURIComponent(response.filename) + 33847 '&media_type=' + 33848 encodeURIComponent(response.media_type) + 33849 '&title=' + 33850 encodeURIComponent(response.title); 33851 33852 } 33853 } 33854 }, 33855 failure: function(response){ 33856 g_cmn.fn_working_overlay(false, null); 33857 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 33858 width: "370px" 33859 }); 33860 } 33861 }); 33862 33863 } 33864 33865 /*** 33866 * Function used to refresh the tree on calling when click on refresh button 33867 * operation of copy , move, delete and new folder . 33868 * @param {Object} dir_id 33869 */ 33870 var fn_refresh_server = function fn_refresh_server(obj, operation){ 33871 var d = null; 33872 if (obj) 33873 d = { 33874 "obj": $.toJSON(obj) 33875 } 33876 33877 g_cmn.fn_notif_win(true, "Refreshing...", null); 33878 $.ajax({
33879 type: "POST", 33880 url: g_site_url + "main_cloud_fs_interface/refresh_cloudhq_dir", 33881 dataType: "json", 33882 data: d, 33883 async: true, 33884 success: function(response){ 33885 if (response.error) { 33886 g_cmn.fn_notif_win(false, "", null); 33887 } 33888 else { 33889 // we can just count number of open nodes in left tree and decrement them in event on 'select_node.jstree' 33890 g_jstree_refresh_inprogress = $("#left_jstree_container .jstree-open").length; 33891 $("#left_jstree_container").jstree('refresh'); 33892 $("#right_jstree_container").jstree('refresh'); 33893 33894 $('#main_checkbox').addClass('checkbox_icon'); 33895 $('#main_checkbox').removeClass('checkbox_icon-checked'); 33896 $("#right_jstree_container").jstree("uncheck_all"); 33897 33898 g_cmn.fn_notif_win(false, "", null); 33899 } 33900 }, 33901 failure: function(response){ 33902 g_cmn.fn_notif_win(false, "", null); 33903 alert("Failure"); 33904 } 33905 }); 33906 } 33907 33908 /** 33909 * Download documents given list of document ids 33910 * @param {Object} obj_list 33911 */ 33912 var fn_download_documents = function fn_download_documents(){ 33913 var obj_list = fn_get_checked_obj_list(); 33914 g_cmn.fn_notif_win(true, "Downloading...", null); 33915 g_cmn.fn_working_overlay(); 33916 $.ajax({
33917 type: "POST", 33918 url: g_site_url + "main_cloud_fs_interface/download", 33919 dataType: "json", 33920 data: { 33921 "obj_list": $.toJSON(obj_list), 33922 "download_type": $.toJSON("batch") 33923 }, 33924 async: true, 33925 success: function(response){ 33926 g_cmn.fn_working_overlay(false); 33927 if (response.error) { 33928 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 33929 width: "370px" 33930 }); 33931 } 33932 else if (response.long_running_operation) { 33933 g_cmn.fn_notif_win(false, "Download job started", 1000); 33934 g_cmn.fn_normal_dialog("Download job started", "", "Since download tool longer than 2 minutes we started a background job which will download the selected files and create a zip file.<br/><br/>You will receive an email with a download link when the job is done.", { 33935 width: "580px", 33936 close: function() { location.reload(true); } 33937 }); 33938 } 33939 else { 33940 g_cmn.fn_notif_win(true, "Success", 5000); 33941 location.href = g_site_url + 'main_cloud_fs_interface/get_file?save_as=1' + 33942 '&filename=' + 33943 encodeURIComponent(response.filename) + 33944 '&media_type=' + 33945 encodeURIComponent(response.media_type) + 33946 '&title=' + 33947 encodeURIComponent(response.title); 33948 } 33949 }, 33950 failure: function(response){ 33951 g_cmn.fn_working_overlay(false); 33952 g_cmn.fn_notif_win(false, "", null); 33953 g_cmn.fn_error_dialog("ERROR", "<center>Sorry, a temporary error has occurred.<br/>Please refresh the page.</center>", { 33954 width: "370px" 33955 }); 33956 } 33957 }); 33958 }; 33959 33960 /** 33961 * Checks wether something is checked (selected) 33962 */ 33963 var fn_get_checked_element_flag = function fn_get_checked_element_flag(){ 33964 var checked_item = $("#right_jstree_container").jstree("get_checked").length; 33965 return checked_item > 0 ? true : false; 33966 } 33967 33968 /** 33969 * Checks weather the selected item is gmail 33970 */ 33971 var fn_is_item_gmail = function fn_is_item_gmail() { 33972 var checked_item = $("#right_jstree_container").jstree("get_checked"); 33973 if (checked_item.length > 0 && checked_item.data('jstree').what == 'google_gmail') 33974 return true; 33975 else 33976 return false; 33977 } 33978 33979 /** 33980 * Checks weather the selected item is gmail 33981 */ 33982 var fn_is_item_evernote_tags = function fn_is_item_gmail() { 33983 var checked_item = $("#right_jstree_container").jstree("get_checked"); 33984 if (checked_item.length > 0 && checked_item.data('jstree').what == 'evernote' && checked_item.data('jstree')['obj_type'] == 'exp2:tags-folder' ) 33985 return true; 33986 else 33987 return false; 33988 } 33989 33990 /** 33991 * Checks weather the selected item is gmail 33992 */ 33993 var fn_is_item_evernote_top = function fn_is_item_gmail() { 33994 var checked_item = $("#right_jstree_container").jstree("get_checked"); 33995 if (checked_item.length > 0 && checked_item.data('jstree').what == 'evernote' && checked_item.data('jstree')['is_root'] == true ) 33996 return true; 33997 else 33998 return false; 33999 } 34000 34001 /** 34002 * Returns list of selected objects 34003 */ 34004 var fn_get_checked_obj_list = function fn_get_checked_obj_list(){ 34005 var obj_list = new Array(); 34006 var checked_element_list = $("#right_jstree_container").jstree("get_checked"); 34007 $(checked_element_list).each(function(){ 34008 obj_list.push($(this).data('jstree')); 34009 }); 34010 return obj_list; 34011 } 34012 34013 /** 34014 * Wrapper around displaying error dialog 34015 */ 34016 var fn_error_dialog = function fn_error_dialog(title, text){ 34017 g_cmn.fn_error_dialog(title, text); 34018 } 34019 34020 /** 34021 * generate copy node jstree given response from cloudHQ_init 34022 * @param {Object} response 34023 */ 34024 var fn_display_copy_node_jstree = function fn_display_copy_node_jstree(response){ 34025 $(function(){ 34026 $('#copy_node_jstree_container').jstree("destroy"); 34027 $('#copy_node_jstree_container').jstree({ 34028 "core": { 34029 html_titles: true 34030 }, 34031 "json_data": { 34032 "correct_state": true, 34033 "data": response, 34034 "ajax": { 34035 "url": function(n){ 34036 if (n == -1) 34037 return false; 34038 else { 34039 g_cmn.fn_notif_win(true, "Loading...", null); 34040 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 34041 } 34042 }, 34043 "success": function(obj, t, x){ 34044 g_cmn.fn_notif_win(false, "", null); 34045 }, 34046 "error": function(obj){ 34047 alert("error"); 34048 }, 34049 "data": function(obj) { 34050 return { 34051 "obj": $.toJSON(obj.data('jstree')), 34052 "file_flag": $.toJSON(false) 34053 } 34054 } 34055 } 34056 }, 34057 "themes": { 34058 "theme": "cloudhq", 34059 "dots": false, 34060 "icons": true 34061 }, 34062 "plugins": ["themes", "json_data", "ui"] 34063 }); 34064 34065 });
34066 34067 } /* fn_display_copy_node_jstree */ 34068 /** 34069 * generate jstree for move dialog given response from cloudHQ_init 34070 * @param {Object} response 34071 */ 34072 var fn_display_move_node_jstree = function fn_display_move_node_jstree(response){ 34073 $(function(){ 34074 $('#move_node_jstree_container').jstree("destroy"); 34075 $('#move_node_jstree_container').jstree({ 34076 "core": { 34077 html_titles: true 34078 }, 34079 "json_data": { 34080 "correct_state": true, 34081 "data": response, 34082 "ajax": { 34083 "url": function(n){ 34084 if (n == -1) 34085 return false; 34086 else { 34087 g_cmn.fn_notif_win(true, "Loading...", null); 34088 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 34089 } 34090 }, 34091 "success": function(obj, t, x){ 34092 g_cmn.fn_notif_win(false, "", null); 34093 }, 34094 "error": function(obj){ 34095 alert("error"); 34096 }, 34097 "data": function(obj){ 34098 return { 34099 "obj": $.toJSON(obj.data('jstree')), 34100 "file_flag": $.toJSON(false) 34101 } 34102 } 34103 } 34104 }, 34105 "themes": { 34106 "theme": "cloudhq", 34107 "dots": false, 34108 "icons": true 34109 }, 34110 "plugins": ["themes", "json_data", "ui"] 34111 }); 34112 34113 }); 34114 34115 } /* fn_display_move_node_jstree */ 34116 /** 34117 * Call ajax to upload file using fileUploadUI 34118 */ 34119 var fn_make_file_upload = function fn_make_file_upload(){ 34120 $('.upload').fileUploadUI({ 34121 uploadTable: false, 34122 downloadTable: false, 34123 buildUploadRow: false, 34124 buildDownloadRow: false, 34125 onLoad: function(event, files, index, xhr, handler){ 34126 if (xhr && xhr.responseText) { 34127 var response = JSON.parse(xhr.responseText); 34128 if (response['error']) { 34129 fn_error_dialog("Error during upload", response['error']); 34130 g_cmn.fn_notif_win(false, "", null); 34131 } 34132 else 34133 g_cmn.fn_notif_win(true, "Success", 5000); 34134 } 34135 else { 34136 g_cmn.fn_notif_win(true, "Success", 5000); 34137 } 34138 fn_refresh_server(null, ''); 34139 }, 34140 onAbort: function(event, files, index, xhr, handler){ 34141 // alert('abort'); 34142 }, 34143 onError: function(event, files, index, xhr, handler){ 34144 // alert('error'); 34145 }, 34146 initUpload: function(event, files, index, xhr, handler, callBack){ 34147 g_cmn.fn_notif_win(true, "Upload of file " + files[0].name + " in progress...", null); 34148 $("#upload_new_file_dialog").dialog("close"); 34149 callBack(); 34150 } 34151 }); 34152 } 34153 34154 34155 /** 34156 * Setup resize columns function 34157 */ 34158 var fn_right_jstree_columns_setup = function fn_right_jstree_columns_setup(){ 34159 $(".info_header .file-name-block").resizable({ 34160 containment: 'parent', 34161 handles: 'e', 34162 alsoResize: '#right_jstree_container .jstree_filename' 34163 }); 34164 $(".info_header .size").resizable({ 34165 containment: 'parent', 34166 handles: 'e', 34167 alsoResize: '#right_jstree_container .jstree_size' 34168 }); 34169 $(".info_header .date-time").resizable({ 34170 containment: 'parent', 34171 handles: 'e', 34172 alsoResize: '#right_jstree_container .jstree_datetime' 34173 }); 34174 $(".info_header .owner").resizable({ 34175 containment: 'parent', 34176 handles: 'e', 34177 alsoResize: '#right_jstree_container .jstree_owner' 34178 }); 34179 } 34180 34181 /** 34182 * Resize columns 34183 */ 34184 var fn_right_jstree_columns_resize = function fn_right_jstree_columns_resize(){ 34185 $('#right_jstree_container .jstree_filename').width($(".info_header .file-name-block").width()); 34186 $('#right_jstree_container .jstree_size').width($(".info_header .size").width()); 34187 $('#right_jstree_container .jstree_datetime').width($(".info_header .date-time").width()); 34188 // owner is last one so just 100% is ok 34189 $('#right_jstree_container .jstree_owner').width('100%'); 34190 } 34191 34192 34193 var fn_resize_areas = function fn_resize_areas(){ 34194 //$('body').height($(window).height()); 34195 //$('.main-outer-wrapper').height($(window).height() - $('.footer').height() - 9); 34196 var top_banner_height = $('#banner-top').is(':visible') ? $('#banner-top').height() * 1 : 0; 34197 $('.main_content_container').height($(window).height() - $('.footer').height() - $('#top-header').height() - 40 - top_banner_height); 34198 34199 // left tree height 34200 var lth = $('.main_content_container').height() - $('.add_chrome_extension').height() - 9; 34201 $('#left_jstree_container').height(lth - 6); 34202 34203 // right doc height 34204 var dh = $('#right_doc_container').height() - 18; 34205 $('#right_doc_container iframe').height(dh); 34206 34207 // right jstree height
34208 var rth = $('#right_dir_container').height() - 34209 $('#right_dir_breadcrumb').height() - 34210 $('#right_dir_header').height() - 34211 60; 34212 $('#right_jstree_container').height(rth); 34213 34214 } 34215}; 34216 34217/* ------------------------------------------- 34218 var fn_display_contextmenu = function(node) 34219 { 34220 return { 34221 create : false, 34222 rename : false, 34223 remove : false, 34224 ccp : false, 34225 "move_to" : { 34226 "separator_before" : false, 34227 "separator_after" : true, 34228 "label" : "Move to...", 34229 "action" : function (obj) { alert("Move to..."); } 34230 }, 34231 "copy_to" : { 34232 "separator_before" : false, 34233 "separator_after" : true, 34234 "label" : "Copy to...", 34235 "action" : function (obj) { alert("Copy to..."); } 34236 }, 34237 "delete" : { 34238 "separator_before" : false, 34239 "separator_after" : true, 34240 "label" : "Delete", 34241 "action" : function (obj) { alert("Delete..."); } 34242 }, 34243 "download" : { 34244 "separator_before" : false, 34245 "separator_after" : true, 34246 "label" : "Download", 34247 "action" : function (obj) { alert("Download..."); } 34248 }, 34249 "move_to" : { 34250 "separator_before" : false, 34251 "separator_after" : true, 34252 "label" : "Move to...", 34253 "action" : function (obj) { alert("Move to..."); } 34254 } 34255 } 34256 } 34257} 34258 34259 var fn_display_breadcrumb = function(data_rslt_obj) 34260{ 34261 34262 var fn_get_selected_left_tree_node = function() 34263 { 34264 $('#left_jstree_container .jstree-clicked').each(function() { 34265 var selected_node = $(this).parent('li'); 34266 if(selected_node) 34267 return fn_get_left_tree_bredcums(selected_node, ''); 34268 else 34269 return ""; 34270 }); 34271 } 34272 34273 var fn_get_left_tree_bredcums = function(data_rslt_obj, current_bredcums) 34274 { 34275 var current_obj_id = data_rslt_obj.attr('id'); 34276 var parent_obj = $(data_rslt_obj.parent().parent()); 34277 var parent_id = parent_obj.attr('id'); 34278 var current_node = fn_fetch_breadcum_text(data_rslt_obj); 34279 if(parent_id==('left_jstree_container' || '' || 'undefined')) 34280 { 34281 $('#right_dir_breadcrumb').html(current_node + current_bredcums); 34282 } 34283 else 34284 { 34285 current_bredcums = ' > ' + current_node + current_bredcums; 34286 fn_get_left_tree_bredcums(parent_obj, current_bredcums); 34287 } 34288 } 34289 34290 var fn_fetch_breadcum_text = function(data_rslt_obj) 34291 { 34292 var node_name = $(data_rslt_obj[0].children[1]).text(); 34293 return node_name!='' ? node_name : ''; 34294 } 34295 34296 var current_obj_id = data_rslt_obj.attr('id'); 34297 var root 34298 while () 34299 var parent_obj = $(data_rslt_obj.parent().parent()); 34300 var parent_id = parent_obj.attr('id'); 34301 var current_node = fn_fetch_breadcum_text(data_rslt_obj); 34302 34303 34304 if (parent_id==('left_jstree_container' || '' || 'undefined') || current_obj_id==('right_jstree_container' || '' || 'undefined')) 34305 { 34306 // if($.inArray(current_obj_id, left_tree_expand_plan) < 0) 34307 left_tree_expand_plan.push(current_obj_id); 34308 $('#right_dir_breadcrumb').html(''); 34309 var get_left_breadcums = ''; 34310 if(from!='left') 34311 { 34312 fn_get_selected_left_tree_node(); 34313 get_left_breadcums = $('#right_dir_breadcrumb').html(); 34314 } 34315 $('#right_dir_breadcrumb').html(get_left_breadcums + current_node + current_bredcums); 34316 } 34317 else 34318 { 34319 current_bredcums = ' > ' + current_node + current_bredcums; 34320 // if($.inArray(current_obj_id, left_tree_expand_plan) < 0) 34321 left_tree_expand_plan.push(current_obj_id); 34322 fn_display_breadcrumb(parent_obj, current_bredcums, from); 34323 } 34324} 34325 34326 */ 34327 34328/** 34329 * @author Senad Dizdar 34330 */ 34331 34332if (typeof srv_check_refresh_default === "undefined") { 34333 srv_check_refresh_default = false; 34334} 34335 34336function c_srv() 34337{ 34338 var srv_check_delay = 15000; 34339 var srv_check_timeout = null; 34340 var srv_check_refresh = srv_check_refresh_default; 34341 34342 this.name = "c_srv"; 34343 34344 this.fn_init = function() 34345 { 34346 // wait 5 secs here. if background job fails we could be constantly pinging server! 34347 if (srv_check_refresh) 34348 { 34349 window.setTimeout(check_services_state, 5000); 34350 } 34351 }; 34352 34353 function check_services_state(delay) { 34354 34355 if(delay && delay > 0) { 34356 if(srv_check_timeout) { 34357 window.clearTimeout(srv_check_timeout); 34358 } 34359 srv_check_delay = Math.max(5000, Math.min(delay, 60000)); 34360 srv_check_timeout = window.setTimeout(function() { 34361 check_services_state(false); 34362 }, srv_check_delay); 34363 return; 34364 }; 34365 34366 function check_action_name(actions, name) { 34367 return $.grep(actions, function(x) { 34368 return x.name == name; 34369 }).length > 0;
34370 }; 34371 34372 $.ajax({ 34373 type : "GET", 34374 url : g_site_url + "main_services/check_services_state", 34375 dataType : "json", 34376 success : function(response) { 34377 if (response.error) { 34378 check_services_state(srv_check_delay * 2); 34379 } else { 34380 if (response.actions && response.actions.length > 0) { 34381 if(check_action_name(response.actions, 'reconfigure_service_configs')) { 34382 // g_cmn.fn_notif_win(true, 'Cataloging and verifying your configured services ...' , 10000); 34383 } else if(check_action_name(response.actions, 'reconfigure_service_configs_and_group_them')) { 34384 // g_cmn.fn_notif_win(true, 'Cataloging and verifying your configured services ...' , 10000); 34385 34386 } else if (check_action_name(response.actions, 'refresh_google_apps_accounts')) { 34387 // g_cmn.fn_notif_win(true, 'Cataloging Google Apps accounts ...' , 10000); 34388 } 34389 srv_check_refresh = true; 34390 check_services_state(10000); 34391 } else { 34392 if(srv_check_refresh) { 34393 g_cmn.fn_working_overlay(true, "Loading services ..."); 34394 window.location.reload(); 34395 } 34396 } 34397 } 34398 }, 34399 failure : function(response) { 34400 check_services_state(srv_check_delay * 2); 34401 } 34402 }); 34403 }; 34404 34405} 34406/** 34407 * @author Senad Dizdar 34408 */ 34409 34410function c_bckp() 34411{ 34412 this.name = "c_bckp"; 34413 34414 this.fn_init = function() 34415 { 34416 34417 // call server to intilize 34418 $.ajax( 34419 { 34420 type: "GET", 34421 url: g_site_url + "main_cloud_fs_interface/cloudhq_init", 34422 dataType: "json", 34423 data: { 'call_for_backup': true}, 34424 async: true, 34425 success: function(response) 34426 { 34427 if (response.error) 34428 { 34429 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page." , 5000); 34430 } 34431 else 34432 { 34433 fn_display_dialog_jstree(response); 34434 } 34435 }, 34436 failure: function(response) 34437 { 34438 alert("Failure"); 34439 } 34440 }); 34441 34442 // If backup is not enabled but it not specified destination for backup we should display ... 34443 $('#start_stop_container form').submit(function(){ 34444 if (($('#target_obj').val() =='""' || $('#location').val() =='Not selected') && $('#is_backup_enabled').is(':checked')) 34445 { 34446 g_cmn.fn_error_dialog("ERROR", "Please specify backup destination"); 34447 return false; 34448 } 34449 }); 34450 34451 $('#save_backup_configs_form').submit(function(){ 34452 return false; 34453 }); 34454 34455 $('.service_checkbox').click(function(e) { 34456 if (!$(this).is(':checked')) { 34457 service_name = $(this).attr('service_name'); 34458 service_email_or_login = $(this).attr('service_email_or_login'); 34459 g_cmn.fn_normal_dialog("Confirmation", 34460 "Exclude " + service_name + " (" + service_email_or_login + ") from backup.<br/><br/>" + "Are you sure?", "", 34461 { 34462 width: "550px", 34463 buttons: { 34464 "No": function() { 34465 try { g_cmn.fn_working_overlay(true, 'Reverting...'); } catch(er) { } 34466 $(this).dialog("close"); 34467 document.location.reload(true); 34468 }, 34469 "Yes": function() { 34470 try { g_cmn.fn_working_overlay(true, 'Saving...'); } catch(er) { } 34471 $(this).dialog("close"); 34472 document.save_backup_configs_form.submit(); // use javascript to skip jQuery 34473 } 34474 } 34475 }); 34476 } else 34477 { 34478 try { g_cmn.fn_working_overlay(true, 'Saving...'); } catch(er) { } 34479 $(this).dialog("close"); 34480 document.save_backup_configs_form.submit(); // use javascript to skip jQuery 34481 } 34482 34483 return true; 34484 }); 34485 34486 $('#get_backup_place').unbind("click").bind('click', function(){ 34487 if ($('#is_backup_enabled').attr('value') == '0') 34488 { 34489 g_cmn.fn_normal_dialog("Notice", "Please stop the backup before modifying it", "", 34490 { width: "450px", buttons: { 34491 "OK": function() { 34492 $(this).dialog("close"); 34493 } 34494 } 34495 }); 34496 return false; 34497 } 34498 select_target_dialog.dialog('open'); 34499 });
34500 34501 } 34502 34503 34504 /*********************************************/ 34505 /* PRIVATE FUNCTIONS */ 34506 /*********************************************/ 34507 var fn_display_dialog_jstree = function(response) 34508 { 34509 $(function () { 34510 $('#select_target_jstree_container').jstree("destroy"); 34511 $('#select_target_jstree_container').bind('load_node.jstree', function(event, data) 34512 { 34513 // alert("reopen"); 34514 }).jstree({ 34515 "core": { 34516 html_titles: true 34517 }, 34518 "json_data" : { 34519 "correct_state" : true, 34520 "data" : response, 34521 "ajax" : { "url" :function (n) { 34522 if (n==-1) 34523 return false; 34524 else{ 34525 g_cmn.fn_notif_win(true, "Loading...", null); 34526 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 34527 } 34528 }, 34529 "success": function (obj, t, x) { 34530 $('#loading').css('display','none'); 34531 if ( t == "success" ) 34532 { 34533 var response = JSON.parse(x.responseText); 34534 if (response['error']) 34535 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page ." , 5000); 34536 else 34537 g_cmn.fn_notif_win(false, "", null); 34538 } 34539 else 34540 { 34541 g_cmn.fn_notif_win(false, "", null); 34542 } 34543 }, 34544 "error" : function (obj) { 34545 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page." , 5000); 34546 alert ("error: jQuery internal error. Please refresh the page."); 34547 }, 34548 "data" : function (obj) { 34549 34550 return { "obj" : $.toJSON(obj.data('jstree')), 34551 "file_flag" : $.toJSON(false) } 34552 } 34553 } 34554 }, 34555 "contextmenu" : { 34556 "items": function(node){ 34557 return fn_display_contextmenu(node); 34558 } // end function 34559 }, 34560 "themes" : { 34561 "theme" : "cloudhq", 34562 "dots" : false, 34563 "icons" : true 34564 }, 34565 "plugins" : [ "themes", "json_data", "ui", "crrm", "types" ] 34566 }); 34567 34568 }); 34569 34570 } /* fn_display_left_jstree */ 34571 34572 var select_target_dialog = $("#select_target_dialog").dialog({ 34573 autoOpen: false, resizable: false, width: 650, height: 350, title: "Select target folder for archives", 34574 modal: true, 34575 buttons: { 34576 "Cancel": function() { 34577 $(this).dialog("close"); 34578 }, 34579 "Select": function() { 34580 var folder_obj = $($("#select_target_jstree_container .jstree-clicked")).parent('li'); 34581 if( folder_obj.length < 1 ) 34582 { 34583 /* alert('cancel');*/ 34584 } 34585 else 34586 { 34587 if (folder_obj.data('jstree')['is_create_disabled'] == true) 34588 { 34589 g_cmn.fn_notif_win(true, 'New folder creation not allowed on this level' , 3000); 34590 return; 34591 } 34592 34593 var folder_obj_id = folder_obj.attr('id'); 34594 var target_obj = folder_obj.data('jstree'); 34595 var target_id = folder_obj_id.split('_')[1]; 34596 var is_not_top_parent_id = true; 34597 var target_dir = ''; 34598 var i=0; 34599 while (is_not_top_parent_id) 34600 { 34601 if(i!=0) 34602 folder_obj = $('#'+folder_obj_id).parent().parent(); 34603 34604 i++; 34605 34606 folder_obj_id = folder_obj.attr('id'); 34607 if(folder_obj_id=='select_target_jstree_container') 34608 is_not_top_parent_id = false; 34609 else 34610 { 34611 var d = folder_obj.data('jstree'); 34612 if (d) text = d['title_no_html']; 34613 text = text.replace('SugarSync Workspaces (', 'SugarSync (') 34614 if (target_dir == '') 34615 target_dir = text; 34616 else 34617 target_dir = text + " > " + target_dir; 34618 } 34619 } 34620 $('#target_obj').val($.toJSON(target_obj)); 34621 $('#target_dir').val(target_dir); 34622 $('#location').val(target_dir).attr('title', target_dir); 34623 34624 try { g_cmn.fn_working_overlay(true, 'Saving...'); } catch(er) { } 34625 $('#save_backup_location_form').submit(); 34626 34627 $(this).dialog("close"); 34628 } 34629 } 34630 } 34631 }); 34632} 34633 34634/** 34635 * @author Senad Dizdar 34636 * 34637 * Copyright (C) 2010-2011, cloudHQ 34638 * All rights reserved. 34639 * 34640 */ 34641 34642function c_synch() 34643{ 34644 /* private variables */ 34645 var synch_update_timer = null; 34646 var synch_update_timer_value = 30000; 34647 var running_flag = null; 34648 34649 function init_search() { 34650 34651 var search_box = $('.search-box'); 34652 34653 function search() { 34654 34655 var words = $(search_box).val(); 34656 words = words.replace(/^\s+|\s+$/gm,''); // trim 34657 words = words.split(' '); 34658 words = jQuery.grep(words, function(word, i){ 34659 return word != ''; 34660 }); 34661 words = jQuery.map(words, function(word, i) { 34662 return '(?=.*' + word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + ')'; 34663 }); 34664 34665 if (words.length == 0) { 34666 //$('.synch_group').removeClass('collapsed'); 34667 $('.synch_dir_rows').css('display', 'block'); 34668 search_box.css('border-color', '').css('background-color', ''); 34669 return; 34670 } 34671 34672 search_box.css('border-color', '#195070') 34673 .css('background-color', '#f3f8ff'); 34674 34675 var flag = "i"; 34676 var pattern = "" + words.join("") + ""; 34677 var regEx = new RegExp(pattern, flag); 34678 34679 $('.synch_group').addClass('collapsed'); 34680 $('.synch_dir_rows').each(function() { 34681 34682 var row = $(this); 34683 var matches = []; 34684 34685 row.find('.search-include').each(function() { 34686 var el = $(this); 34687 if(el.val && el.val() != '') { 34688 res = el.val().match(regEx); 34689 if (res != null) { 34690 for(var i = 0; i < res.length; i++) { 34691 matches.push(res[i]); 34692 } 34693 } 34694 } 34695 }); 34696 34697 if(matches.length > 0) { 34698 // found match. 34699 row.closest('.synch_group').removeClass('collapsed'); 34700 row.css('display', ''); 34701 } else { 34702 row.css('display', 'none'); 34703 } 34704 34705 }); 34706 } 34707 34708 var timeout = null; 34709 34710 search_box.keyup(function() { 34711 34712 // optimize. do a lookup only 0.5 sec after we stop typing. 34713 if (timeout != null) 34714 window.clearTimeout(timeout); 34715 34716 timeout = window.setTimeout(search, 500); 34717 34718 });
34719 34720 search(); 34721 34722 }; 34723 34724 34725 /*********************************************/ 34726 /* PUBLIC FUNCTIONS */ 34727 /*********************************************/ 34728 this.fn_init = function(input_running_flag){ 34729 34730 fn_update_buttons(); 34731 34732 $("form").bind("submit", function(e){ 34733 var notif_to_display = $('input[name="submit"]', $(this)).attr('notif_to_display'); 34734 if (notif_to_display != null) 34735 g_cmn.fn_notif_win(true, notif_to_display); 34736 34737 g_cmn.fn_working_overlay(); 34738 return true; 34739 }); 34740 34741 var tagText = $('#utc_last_job_operation').html(); 34742 if (tagText) 34743 { 34744 var givenDate = new Date($.format.date(tagText, "")); 34745 if ((givenDate + "") == 'Invalid Date') 34746 var givenDate = tagText; 34747 $('#utc_last_job_operation').html(' ' + givenDate); 34748 34749 34750 } 34751 34752 // click on checkboxes is submit 34753 $(".checkbox_enabled input:checkbox").bind("click", function(e) { 34754 try { g_cmn.fn_notif_win(true, "Saving..."); } catch(er) { } 34755 $('#synch_form').submit(); 34756 }); 34757 34758 running_flag = input_running_flag; 34759 34760 // disable monitoring status 34761 // synch_update_timer = setTimeout(function(){ fn_get_synch_status_text_ajax(); }, 30000); 34762 34763 init_search(); 34764 }; 34765 34766 /*** 34767 * Initialize jstree inside dialog 34768 * @param {Object} dir1_or_dir2 34769 */ 34770 this.fn_init_jstree_inside_dialog = function(dir1_or_dir2) 34771 { 34772 // call server to intilize 34773 $.ajax( 34774 { 34775 type: "GET", 34776 url: g_site_url + "main_cloud_fs_interface/cloudhq_init", 34777 dataType: "json", 34778 data: { 'call_for_synch': $.toJSON(true), 34779 'dir1_or_dir2' : $.toJSON(dir1_or_dir2) 34780 }, 34781 async: true, 34782 success: function(response) 34783 { 34784 if (response.error) 34785 { 34786 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page." , 5000); 34787 } 34788 else 34789 { 34790 fn_display_jstree(response, dir1_or_dir2); 34791 } 34792 }, 34793 failure: function(response) 34794 { 34795 alert("Failure"); 34796 } 34797 }); 34798 }; 34799 34800 /*********************************************/ 34801 /* PRIVATE FUNCTIONS */ 34802 /*********************************************/ 34803 34804 /* fn_display_jstree: display jstree. 34805 * response: data received from cloudhq_init 34806 * dir1_or_dir2: whether this is for dir1 or dir2 34807 */ 34808 var fn_display_jstree = function(response, dir1_or_dir2) 34809 { 34810 $(function () { 34811 $('#select_synch_jstree_container_' + dir1_or_dir2).jstree("destroy"); 34812 $('#select_synch_jstree_container_' + dir1_or_dir2).bind('load_node.jstree', function(event, data) 34813 { 34814 // alert("reopen"); 34815 }).jstree({ 34816 "core": { 34817 html_titles: true 34818 }, 34819 "json_data" : { 34820 "correct_state" : true, 34821 "data" : response, 34822 "ajax" : { "url" :function (n) { 34823 if (n==-1) 34824 return false; 34825 else{ 34826 g_cmn.fn_notif_win(true, "Loading...", null); 34827 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 34828 } 34829 }, 34830 "success": function (obj, t, x) { 34831 $('#loading').css('display','none'); 34832 if ( t == "success" ) 34833 { 34834 var response = JSON.parse(x.responseText); 34835 if (response['error']) 34836 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page ." , 5000); 34837 else 34838 g_cmn.fn_notif_win(false, "", null); 34839 } 34840 else 34841 { 34842 g_cmn.fn_notif_win(false, "", null); 34843 } 34844 }, 34845 "error" : function (obj) { 34846 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page." , 5000); 34847 alert ("error: jQuery internal error. Please refresh the page."); 34848 }, 34849 "data" : function (obj) { 34850 return { "obj" : $.toJSON(obj.data('jstree')), 34851 "file_flag" : $.toJSON(true) } 34852 } 34853 } 34854 }, 34855 "contextmenu" : { 34856 "items": function(node){ 34857 } // end function 34858 }, 34859 "themes" : { 34860 "theme" : "cloudhq", 34861 "dots" : false, 34862 "icons" : true 34863 }, 34864 "plugins" : [ "themes", "json_data", "ui", "crrm", "types" ] 34865 }); 34866 34867 });
34868 34869 } /* fn_display_jstree */ 34870 34871 /*** 34872 * 34873 * @param {Object} dir1 34874 * @param {Object} dir2 34875 */ 34876 var fn_add_dir_row = function(dir1, dir2) 34877 { 34878 var doc = document; 34879 var dir_rows = doc.createElement('div'); 34880 var dir_text = ''; 34881 var add_row_count = $('div.synch_dir_rows').length; 34882 $(dir_rows).attr({'id': 'synch_dir_rows' + add_row_count }).addClass('synch_dir_rows'); 34883 34884 var i = 1; 34885 [dir1, dir2].forEach( 34886 function(e) 34887 { 34888 var dir1_or_dir2 = 'dir' + i; // 'dir1' or 'dir2' 34889 var dir_res = e['dir_res']; 34890 34891 var dir_rows_input = doc.createElement("input"); 34892 $(dir_rows_input).attr({'readonly': 'readonly', 'title' : dir_res['name'] }).addClass('location').val(dir_res['name']); 34893 $(dir_rows_input).appendTo(dir_rows); 34894 34895 // add input rows with obj (which is json object) and name (just string) 34896 $(doc.createElement('input')) 34897 .attr({'type': 'hidden', 'name': dir1_or_dir2 + '_obj_list[]', 'id' : dir1_or_dir2 + '_id_' + add_row_count, 'value' : $.toJSON(dir_res['obj']) }) 34898 .appendTo(dir_rows); 34899 $(doc.createElement('input')) 34900 .attr({'type': 'hidden', 'name': dir1_or_dir2 + '_name_list[]', 'id' : dir1_or_dir2 + '_name_' + add_row_count, 'value' : dir_res['name'] }) 34901 .appendTo(dir_rows); 34902 34903 // add options: delete replicate is 1, upload converstion policy is 0 34904 $(doc.createElement('input')) 34905 .attr({'type': 'hidden', 'name': 'replicate_delete_list[' + add_row_count + ']', 'id' : 'replicate_delete_' + add_row_count, 'value' : '1' }) 34906 .appendTo(dir_rows); 34907 $(doc.createElement('input')) 34908 .attr({'type': 'hidden', 'name': 'upload_convert_policy_list[' + add_row_count + ']', 'id' : 'upload_convert_policy_' + add_row_count, 'value' : '0' }) 34909 .appendTo(dir_rows); 34910 34911 i = i + 1; 34912 } 34913 ); 34914 34915 var dir_rows_span = doc.createElement("span"); 34916 var dir_rows_a = doc.createElement("a"); 34917 $(dir_rows_a).attr({'href': 'javascript:void(0);', 'title' : dir_res['name'] }).html(' <img src="/images/remove.png" />'); 34918 $(dir_rows_a).appendTo(dir_rows_span); 34919 $(dir_rows_span).appendTo(dir_rows); 34920 34921 add_row_count++; 34922 34923 $('#pre_synch_folder').append(dir_rows); 34924 34925 g_cmn.fn_notif_win(true, "Saving..." , 5000); 34926 $('#synch_form').submit(); 34927 } 34928 34929 34930 /*** 34931 * 34932 */ 34933 var fn_synch_folder_dialog_on_select_folder = function($dialog, dir1_or_dir2) 34934 { 34935 var next_step = $dialog.dialog('option', 'next_step'); 34936 var folder_obj = $($("#select_synch_jstree_container_" + dir1_or_dir2 + " .jstree-clicked")).parent('li'); 34937 if (folder_obj.length < 1) 34938 { 34939 $dialog.dialog("close"); 34940 /* alert('cancel');*/ 34941 } 34942 else 34943 { 34944 if (folder_obj.data('jstree')['is_synch_disabled'] == true) 34945 { 34946 g_cmn.fn_error_dialog("ERROR", "Synchronization is not allowed on this level. Please select a child folder.", { width: "550px" }); 34947 // g_cmn.fn_notif_win(true, 'Synchronization is not allowed on this level.' , 3000); 34948 return; 34949 } 34950 34951 var selected_node = new Array(); 34952 var checked_obj = $("#select_synch_jstree_container_" + dir1_or_dir2 + " .jstree-clicked").parent('li'); 34953 34954 $(checked_obj).each( 34955 function() { 34956 dir_res = fn_get_selected_folder($(this)); 34957 34958 fn_check_selection($(this), 34959 function() { 34960 34961 // Add this to the dialog options 34962 $dialog.dialog('option', 'selected', { dir_res: dir_res }); 34963 34964 // go to next step 34965 if (jQuery.isFunction(next_step)) 34966 { 34967 $dialog.dialog("close"); 34968 next_step(); 34969 } 34970 } 34971 ); 34972 }); 34973 } 34974 } 34975 34976 var synch_folder_dialog_dir1 = $("#select_synch_folder_dialog_dir1").dialog({ 34977 autoOpen: false, resizable: false, width: 700, height: 550, title: "Select folders for synchronization", 34978 modal: true, 34979 buttons: { 34980 "Cancel": function() { 34981 $(this).dialog("close"); 34982 }, 34983 "Select Folder": function() { 34984 fn_synch_folder_dialog_on_select_folder($("#select_synch_folder_dialog_dir1"), 'dir1'); 34985 } 34986 } 34987 }); 34988 34989 var synch_folder_dialog_dir2 = $("#select_synch_folder_dialog_dir2").dialog({ 34990 autoOpen: false, resizable: false, width: 700, height: 550, title: "Select folders for synchronization", 34991 modal: true, 34992 buttons: { 34993 "Cancel": function() { 34994 $("#select_synch_folder_dialog_dir2").dialog("close"); 34995 }, 34996 "Select Folder": function(){ 34997 fn_synch_folder_dialog_on_select_folder($("#select_synch_folder_dialog_dir2"), 'dir2'); 34998 } 34999 } 35000 }); 35001 35002 /*** 35003 * 35004 * Select dir2 and then after selected call fn_add_dir_row and fn_update_buttons. 35005 */ 35006 var fn_select_dir2 = function() 35007 { 35008 $('#select_synch_jstree_container_dir1').hide(); 35009 $('#select_synch_jstree_container_dir2').show(); 35010 synch_folder_dialog_dir2.dialog('option', 'next_step', function() { 35011 fn_add_dir_row(synch_folder_dialog_dir1.dialog('option', 'selected'), synch_folder_dialog_dir2.dialog('option', 'selected')); 35012 fn_update_buttons(); 35013 });
35014 dir1_selected = synch_folder_dialog_dir1.dialog('option', 'selected')['dir_res']['obj']; 35015 if (dir1_selected['nice_path']) { 35016 $('#dialog_header_container_dir1_what').html(dir1_selected['nice_path']) 35017 } else { 35018 $('#dialog_header_container_dir1_what').html(dir1_selected['path']); 35019 } 35020 synch_folder_dialog_dir2.dialog( { title: 'Select Folder, Project, or Collection' } ); 35021 synch_folder_dialog_dir2.dialog('open'); 35022 } 35023 35024 /*** 35025 * Select dir1 and then after selected call next_step. 35026 * @param {Function} next_step 35027 */ 35028 var fn_select_dir1 = function(next_step) 35029 { 35030 $('#select_synch_jstree_container_dir1').show(); 35031 $('#select_synch_jstree_container_dir2').hide(); 35032 synch_folder_dialog_dir1.dialog('option', 'next_step', next_step); 35033 synch_folder_dialog_dir1.dialog( { title: 'Select Folder, Project, or Collection' } ); 35034 synch_folder_dialog_dir1.dialog('open'); 35035 } 35036 35037 var fn_update_buttons = function() 35038 { 35039 35040 var rows_count = $('.synch_dir_rows input').length; 35041 35042 if (rows_count > 0) 35043 { 35044 $('#get_synch_folder_button_wrapper span:eq(0)').hide(); 35045 $('#get_synch_folder_button_wrapper span:eq(1)').show(); 35046 } 35047 else 35048 { 35049 $('#get_synch_folder_button_wrapper span:eq(0)').show(); 35050 $('#get_synch_folder_button_wrapper span:eq(1)').hide(); 35051 35052 } 35053 35054 $('#add_synch_folder_or_file_pair_fast').unbind("click").bind('click', function(){ 35055 35056 fn_select_dir1(fn_select_dir2); 35057 return false; 35058 }); 35059 35060 35061 if ($('#pre_synch_folder span').length == 0) 35062 $('#synch_pairs_header').hide(); 35063 else 35064 $('#synch_pairs_header').show(); 35065 35066 /* 35067 $('#pre_synch_folder .synch_dir_rows span.button_grayed, .button_say_stop, #pre_synch_folder .synch_dir_rows .checkbox_grayed').bind('click', function() { 35068 var $t = $(this); 35069 g_cmn.fn_normal_dialog("Notice", "Please stop the synchronization before modifying it", "", 35070 { width: "450px", buttons: { 35071 "OK": function() { 35072 $(this).dialog("close"); 35073 } 35074 } 35075 }); 35076 return false; 35077 }); 35078 */ 35079 35080 $('#pre_synch_folder .synch_dir_rows .synch_config_delete').bind('click', function() { 35081 var $t = $(this); 35082 g_cmn.fn_normal_dialog("Confirmation", "Are you sure?", 35083 "When you delete a sync pair, then ALL meta-data will be lost so any new sync pair between these folders will need to copy/download/catalog all files again. <br/><br/>Note that deleting of a sync pair will not delete any files.", 35084 { width: "650px", buttons: { 35085 "No": function() { 35086 $(this).dialog("close"); 35087 return false 35088 }, 35089 "Yes": function() { 35090 // alert($t.html()); 35091 g_cmn.fn_notif_win(true, "Deleting sync pair..." , 5000); 35092 var id_of_form = $t.attr('form_id'); 35093 $('#' + id_of_form).submit(); 35094 $(this).dialog("close"); 35095 } 35096 } 35097 }); 35098 return false; 35099 }); 35100 } 35101 35102 35103 /** 35104 * Check whether user selection is valid 35105 * @param {string} dir_res: object to check agains 35106 * @param {function} func_cont: function to call if everything is ok 35107 * @return {string} Nothing 35108 * 35109 * given id of the object verify folder selection is valid 35110 * NOTE: we don't check anything here! 35111 * 35112 */ 35113 var fn_check_selection = function(f, func_cont) 35114 { 35115 func_cont(); 35116 return; 35117 /* 35118 var ref = f.data('jstree')['ref']; 35119 var elems = $('.synch_dir_rows input[name="dir1_obj_list[]"], .synch_dir_rows input[name="dir2_obj_list[]"]'); 35120 var o, e, pe; 35121 35122 35123 for (i = 0; i < elems.length; i ++) 35124 { 35125 e = $(elems[i]); 35126 35127 o = JSON.parse(e.attr('value')); 35128 if (ref == o['ref']) 35129 { 35130 g_cmn.fn_error_dialog("ERROR", "Folder is already selected for synchronization.", { width: "400px" }); 35131 return; 35132 } 35133 p = f.parents('li'); 35134 35135 for (j = 0; j < p.length; j ++) 35136 { 35137 pe = $(p[j]); 35138 o = JSON.parse(e.attr('value')); 35139 if (pe.data('jstree')['ref'] == o['ref']) 35140 { 35141 g_cmn.fn_error_dialog("ERROR", "Parent folder is already selected for synchronization.", { width: "450px" }); 35142 return; 35143 } 35144 } 35145 } 35146 35147 func_cont(); 35148 */ 35149 } 35150 35151 var fn_get_selected_folder = function(folder_element) 35152 { 35153 var folder_element_id = folder_element.attr('id'); 35154 var target_id = folder_element_id.split('_')[1]; 35155 var target_obj = folder_element.data('jstree'); 35156 35157 var is_not_top_parent_id = true; 35158 var target_name = ''; 35159 var i=0; 35160 while (is_not_top_parent_id) 35161 { 35162 if(i!=0) 35163 folder_element = $('#'+folder_element_id).parent().parent(); 35164 35165 i++; 35166 folder_element_id = folder_element.attr('id'); 35167 if(folder_element_id=='select_synch_jstree_container_dir1' || folder_element_id=='select_synch_jstree_container_dir2') 35168 is_not_top_parent_id = false; 35169 else 35170 { 35171 var d = folder_element.data('jstree'); 35172 if (d) text = d['title_no_html']; 35173 text = text.replace('SugarSync Workspaces (', 'SugarSync (') 35174 if (target_name == '') 35175 target_name = text; 35176 else 35177 target_name = text + " > " + target_name; 35178 } 35179 } 35180 return { id: target_id, obj: target_obj, name: target_name } 35181 } 35182 35183 35184 /* fn_get_synch_status_text_ajax() 35185 * loop and update #synch_status_text_content with status of the syncrhonization 35186 */ 35187 var fn_get_synch_status_text_ajax = function() 35188 { 35189 $.ajax({
35190 type: "GET", 35191 url: g_site_url + "main_synch/get_synch_status_ajax", 35192 dataType: "json", 35193 async: true, 35194 success: function(response){ 35195 if (response.error) { 35196 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page.", 5000); 35197 } 35198 else { 35199 $('#synch_status_text_content').html(response.data.text); 35200 if (response.data.running_flag == false && running_flag == true) 35201 { 35202 g_cmn.fn_normal_dialog("Notification", "", "Synchronization job finished", { buttons: { "Refresh Page": function() { location.reload(true); } }, close: function() { location.reload(true); } } ); 35203 } 35204 else if (response.data.running_flag == true && running_flag == false) 35205 { 35206 g_cmn.fn_normal_dialog("Notification", "", "Synchronization job started", { buttons: { "Refresh Page": function() { location.reload(true); } }, close: function() { location.reload(true); } } ); 35207 } 35208 else 35209 { 35210 clearTimeout(synch_update_timer); 35211 synch_update_timer_value = synch_update_timer_value + 20000; 35212 if (synch_update_timer_value < 120000) 35213 synch_update_timer_value = 120000; 35214 synch_update_timer = setTimeout(function(){ fn_get_synch_status_text_ajax();}, synch_update_timer_value); 35215 } 35216 } 35217 }, 35218 failure: function(response){ 35219 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page.", 5000); 35220 } 35221 }); 35222 } 35223 35224} 35225 35226/** 35227 * @author Senad Dizdar 35228 * 35229 * Copyright (C) 2010-2011, cloudHQ 35230 * All rights reserved. 35231 * 35232 */ 35233 35234function c_synch_wizard() 35235{ 35236 /* private variables */ 35237 35238 /*********************************************/ 35239 /* PUBLIC FUNCTIONS */ 35240 /*********************************************/ 35241 this.fn_init = function(service_what, service_email_or_login, logged_in, is_bcx_evernote_integration, is_bcx_simple_view, list_sp_web_urls) 35242 { 35243 if (service_what == "" && logged_in == false) 35244 { 35245 } 35246 else if (service_what != "" && logged_in == false) 35247 { 35248 35249 } 35250 else 35251 { 35252 $('form').bind('submit', function() { 35253 try { g_cmn.fn_working_overlay(true, "Working..."); } catch(er) { } 35254 return true; 35255 }); 35256 } 35257 35258 // disable adding 37signals for free plans 35259 /*$('.service_image_container a.not_allowed_by_selected_plan').unbind('click').bind('click', function() { 35260 g_cmn.fn_error_dialog("This service is only supported by Premium Plan", "<span>Please select 15-days free Premium Plan trial to sync this service.<br/><br/>If you have already started Personal Plan, please contact us to convert your Personal Plan to 15-days free Premium Plan trial.</span><br/><br/>", { width: "650px" }); 35261 return false; 35262 });*/ 35263 35264 try { 35265 var l = $('#select_synch_jstree_container').length; 35266 if (l > 0) { 35267 fn_init_jstree(service_what, service_email_or_login, is_bcx_evernote_integration, is_bcx_simple_view, list_sp_web_urls); 35268 $('.buttons_container #select_folder_button').unbind('click').bind('click', function(){ 35269 fn_on_select_folder(); 35270 }); 35271 35272 } 35273 } 35274 catch (er) { 35275 } 35276 35277 $('.service_path_link_dir1').unbind('click').bind('click', function() { 35278 service_path_dialog_dir1_dialog.dialog('open'); 35279 return false; 35280 }); 35281 35282 $('.service_path_link_dir2').unbind('click').bind('click', function() { 35283 service_path_dialog_dir2_dialog.dialog('open'); 35284 return false; 35285 }); 35286 35287 $('#new_folder_button').unbind("click").bind('click', function(){ 35288 35289 var parent_folder_obj = $($("#select_synch_jstree_container .jstree-clicked")).parent('li'); 35290 if (parent_folder_obj.length < 1) { 35291 g_cmn.fn_error_dialog("ERROR", "Nothing selected. Please select a parent folder.", { 35292 width: "550px" 35293 }); 35294 return; 35295 } 35296 35297 parent_folder_obj_data = parent_folder_obj.data('jstree'); 35298 if (parent_folder_obj_data['is_folder_create_disabled'] == true ) { 35299 g_cmn.fn_error_dialog("ERROR", "The parent is read-only.", { 35300 width: "550px" 35301 }); 35302 return; 35303 } 35304 new_folder_dialog.dialog('option', 'parent_folder_obj_data', parent_folder_obj_data); 35305 new_folder_dialog.dialog('option', 'is_bcx_evernote_integration', is_bcx_evernote_integration); 35306 new_folder_dialog.dialog('option', 'is_new_folder_option_selected', false); 35307 if (parent_folder_obj_data['nice_path']) { 35308 $('#dialog_header_container_dir1_what').html(parent_folder_obj_data['nice_path']) 35309 } else { 35310 $('#dialog_header_container_dir1_what').html(parent_folder_obj_data['path']); 35311 } 35312 new_folder_dialog.dialog('open'); 35313 }); 35314 35315 35316 // when user selects a service we check it whether it can be sync'd 35317 if (logged_in) 35318 { 35319 $('a.add_service_button').bind('click', function() { 35320 if ($(this).hasClass('noclick')) { 35321 return false;
35322 } 35323 g_cmn.fn_working_overlay(true, "Checking..."); 35324 var selected_elem = $(this); 35325 fn_check_selected_service($('img', $(this)).attr('id'), function() { 35326 window.location = selected_elem.attr('href'); 35327 }) 35328 return false; 35329 }); 35330 } 35331 35332 $('#evernote_exp2_read_write_enabled').bind('click', 35333 function() { 35334 if ($('#evernote_exp2_read_write_enabled').is(":checked")) { 35335 $('#evernote_exp2_read_write_enabled_div').removeClass('ui-state-disabled'); 35336 $('#evernote_exp2_read_write_enabled_div input').attr("disabled", null); 35337 $('#evernote_exp2_read_write_enabled_div input:first').attr('checked', 'checked'); 35338 $('#save_synch_config').submit(); 35339 35340 } 35341 else { 35342 $('#evernote_exp2_read_write_enabled_div').removeClass('ui-state-disabled').addClass('ui-state-disabled'); 35343 $('#evernote_exp2_read_write_enabled_div input').attr("disabled", "disabled"); 35344 $('#evernote_exp2_read_write_enabled_div input').attr("checked", null); 35345 $('#save_synch_config').submit(); 35346 } 35347 35348 } 35349 ); 35350 35351 $('#evernote_exp2_read_only_enabled').bind('click', 35352 function() { 35353 if ($('#evernote_exp2_read_only_enabled').is(":checked")) { 35354 $('#evernote_exp2_read_only_enabled_div').removeClass('ui-state-disabled'); 35355 $('#evernote_exp2_read_only_enabled_div input').attr("disabled", null); 35356 $('#evernote_exp2_read_only_enabled_div input:first').attr('checked', 'checked'); 35357 $('#save_synch_config').submit(); 35358 } 35359 else { 35360 $('#evernote_exp2_read_only_enabled_div').removeClass('ui-state-disabled').addClass('ui-state-disabled'); 35361 $('#evernote_exp2_read_only_enabled_div input').attr("disabled", "disabled"); 35362 $('#evernote_exp2_read_only_enabled_div input').attr("checked", null); 35363 $('#save_synch_config').submit(); 35364 } 35365 } 35366 ); 35367 // alert('after'); 35368 35369 } 35370 35371 $('#select_option_button').click(function() { 35372 var check = $('input[name=what_to_sync]:checked'); 35373 35374 $('#input_what_to_sync').val(check.val()); 35375 if (check.val() == 'account') { 35376 fn_select_root_folder(); 35377 } 35378 else if (check.val() == 'folder') { 35379 var obj = JSON.parse($('#what_to_sync_folder_obj').val()); 35380 fn_select_existing_folder(obj); 35381 } 35382 else if (check.val() == 'create') { 35383 $($("#select_synch_jstree_container li.jstree-root > a")).addClass('jstree-clicked'); 35384 fn_select_new_folder(); 35385 } 35386 //else if (check.val() == 'restore_email') { 35387 // $('#wrapper_select_folder').show(); 35388 // $('#wrapper_what_to_sync').remove(); 35389 //} 35390 else { 35391 $('#wrapper_select_folder').show(); 35392 $('#wrapper_what_to_sync').remove(); 35393 } 35394 }); 35395 35396 35397 var is_bcx_evernote_integration; 35398 35399 35400 new_folder_dialog_title_text = $('#new_folder_dialog_title_text').html(); 35401 var new_folder_dialog = $("#new_folder_dialog").dialog({ 35402 autoOpen: false, 35403 resizable: false, 35404 width: 805, 35405 height: 255, 35406 title: new_folder_dialog_title_text, 35407 modal: true, 35408 buttons: { 35409 "Cancel": function(){ 35410 $(this).dialog("close"); 35411 }, 35412 "Create": function(){ 35413 var folder_name = $('#folder_name').val(); 35414 if (folder_name == '') 35415 g_cmn.fn_error_dialog("", "Please enter folder name"); 35416 else { 35417 g_cmn.fn_working_overlay(true, "Creating folder..."); 35418 parent_folder_obj_data = new_folder_dialog.dialog('option', 'parent_folder_obj_data'); 35419 is_bcx_evernote_integration = new_folder_dialog.dialog('option', 'is_bcx_evernote_integration'); 35420 is_new_folder_option_selected = new_folder_dialog.dialog('option', 'is_new_folder_option_selected'); 35421 $.ajax({ 35422 type: "POST", 35423 url: g_site_url + "main_cloud_fs_interface/new_dir", 35424 dataType: "json", 35425 data: { 35426 "obj": $.toJSON(parent_folder_obj_data), 35427 "folder_name": $.toJSON(folder_name), 35428 "is_bcx_evernote_integration": $.toJSON(is_bcx_evernote_integration), 35429 35430 }, 35431 async: true, 35432 success: function(response){ 35433 if (response.error) { 35434 g_cmn.fn_working_overlay(false, null); 35435 g_cmn.fn_error_dialog("Error during folder creation", response.error); 35436 // g_cmn.fn_notif_win(true, "Folder creation failed.<br\>" + response.error , 5000); 35437 } 35438 else { 35439 if (is_new_folder_option_selected == true) { 35440 fn_select_new_folder(response); 35441 } 35442 else { 35443 g_cmn.fn_notif_win(true, "Folder created", 5000); 35444 fn_refresh_server(parent_folder_obj_data, 'new_dir'); 35445 } 35446 } 35447 }, 35448 failure: function(response){ 35449 g_cmn.fn_working_overlay(false, null); 35450 alert("Failure"); 35451 } 35452 }); 35453 $(this).dialog("close"); 35454 } 35455 } 35456 } 35457 }); 35458 35459 /*** 35460 * Function used to refresh the tree on calling when click on refresh button 35461 * operation of copy , move, delete and new folder . 35462 * @param {Object} dir_id 35463 */ 35464 var fn_refresh_server = function fn_refresh_server(obj, operation){ 35465 var d = null; 35466 if (obj) 35467 d = { 35468 "obj": $.toJSON(obj) 35469 } 35470 35471 g_cmn.fn_notif_win(true, "Refreshing...", null); 35472 $.ajax({ 35473 type: "POST", 35474 url: g_site_url + "main_cloud_fs_interface/refresh_cloudhq_dir", 35475 dataType: "json", 35476 data: d, 35477 async: true, 35478 success: function(response){ 35479 if (response.error) { 35480 g_cmn.fn_notif_win(false, "", null); 35481 } 35482 else { 35483 // we can just count number of open nodes in left tree and decrement them in event on 'select_node.jstree' 35484 $("#select_synch_jstree_container").jstree('refresh'); 35485 g_cmn.fn_working_overlay(false, null); 35486 } 35487 }, 35488 failure: function(response){ 35489 g_cmn.fn_working_overlay(false, null); 35490 alert("Failure"); 35491 } 35492 }); 35493 } 35494 35495 var service_path_dialog_dir1_dialog = $('#service_path_dialog_dir1').dialog({ 35496 autoOpen: false, resizable: false, width: 850, height: 190, title: "Synchronization Folder ", 35497 modal: true, 35498 buttons: { 35499 "OK": function() { 35500 $(this).dialog("close"); 35501 } 35502 } 35503 }); 35504 35505 var service_path_dialog_dir2_dialog = $('#service_path_dialog_dir2').dialog({ 35506 autoOpen: false, resizable: false, width: 850, height: 190, title: "Synchronization Folder ", 35507 modal: true, 35508 buttons: { 35509 "OK": function() { 35510 $(this).dialog("close"); 35511 } 35512 } 35513 }); 35514 35515 35516 /*********************************************/ 35517 /* PRIVATE FUNCTIONS */ 35518 /*********************************************/ 35519 35520 /*** 35521 * Initialize jstree inside dialog 35522 * @param {Object} service 35523 */ 35524 var fn_init_jstree = function(service_what, service_email_or_login, is_bcx_evernote_integration, is_bcx_simple_view, list_sp_web_urls) 35525 { 35526 g_cmn.fn_working_overlay(true, "Loading data..."); 35527 // call server to intilize 35528 $.ajax( 35529 { 35530 type: "GET", 35531 url: g_site_url + "main_cloud_fs_interface/cloudhq_init", 35532 dataType: "json", 35533 data: { 'call_for_synch' : $.toJSON(true),
35534 'browse_only_list' : $.toJSON([{ 'what' : service_what, 'email_or_login': service_email_or_login }]), 35535 'is_bcx_evernote_integration': $.toJSON(is_bcx_evernote_integration), 35536 'is_bcx_simple_view': $.toJSON(is_bcx_simple_view), 35537 'list_sp_web_urls': $.toJSON(list_sp_web_urls) 35538 }, 35539 async: true, 35540 success: function(response) 35541 { 35542 g_cmn.fn_working_overlay(false); 35543 if (response.error) 35544 { 35545 g_cmn.fn_error_dialog("ERROR", "Sorry, a temporary error has occurred. <br/>Please try again.", { width: "550px" }); 35546 } 35547 else 35548 { 35549 fn_display_jstree(response, is_bcx_evernote_integration, is_bcx_simple_view, list_sp_web_urls); 35550 } 35551 35552 var node = $("#select_synch_jstree_container ul li"); 35553 if (node.length == 1) { 35554 $("#select_synch_jstree_container").jstree("open_node", node.first()); 35555 } 35556 }, 35557 failure: function(response) 35558 { 35559 g_cmn.fn_working_overlay(false); 35560 g_cmn.fn_error_dialog("ERROR", "Sorry, a temporary error has occurred. <br/>Please try again.", { width: "550px" }); 35561 } 35562 }); 35563 } 35564 35565 /* fn_display_jstree: display jstree. 35566 * response: data received from cloudhq_init 35567 */ 35568 var fn_display_jstree = function(response, is_bcx_evernote_integration, is_bcx_simple_view, list_sp_web_urls) 35569 { 35570 $(function () { 35571 $('#select_synch_jstree_container').jstree("destroy"); 35572 $('#select_synch_jstree_container').bind('load_node.jstree', function(event, data) 35573 { 35574 // alert("reopen"); 35575 }).jstree({ 35576 "core": { 35577 html_titles: true 35578 }, 35579 "json_data" : { 35580 "correct_state" : true, 35581 "data" : response, 35582 "ajax" : { "url" :function (n) { 35583 if (n==-1) 35584 return false; 35585 else{ 35586 g_cmn.fn_notif_win(true, "Loading...", null); 35587 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 35588 } 35589 }, 35590 "success": function (obj, t, x) { 35591 $('#loading').css('display','none'); 35592 if ( t == "success" ) 35593 { 35594 var response = JSON.parse(x.responseText); 35595 if (response['error']) 35596 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page ." , 5000); 35597 else 35598 g_cmn.fn_notif_win(false, "", null); 35599 } 35600 else 35601 { 35602 g_cmn.fn_notif_win(false, "", null); 35603 } 35604 }, 35605 "error" : function (obj) { 35606 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page." , 5000); 35607 }, 35608 "data" : function (obj) { 35609 return { "obj" : $.toJSON(obj.data('jstree')), 35610 "file_flag" : $.toJSON(false), 35611 "is_synch_wizard" : $.toJSON(true), 35612 "is_bcx_evernote_integration": $.toJSON(is_bcx_evernote_integration), 35613 "is_bcx_simple_view" : $.toJSON(is_bcx_simple_view), 35614 "list_sp_web_urls" : $.toJSON(list_sp_web_urls) 35615 } 35616 } 35617 } 35618 }, 35619 "contextmenu" : { 35620 "items": function(node){ 35621 } // end function 35622 }, 35623 "themes" : { 35624 "theme" : "cloudhq", 35625 "dots" : false, 35626 "icons" : true 35627 }, 35628 "plugins" : [ "themes", "json_data", "ui", "crrm", "types" ] 35629 }); 35630 35631 }); 35632 35633 $("#select_synch_jstree_container").bind("select_node.jstree", function(e, data){ 35634 $("#select_synch_jstree_container").jstree('open_node', data.rslt.obj); 35635 /* now update */ 35636 $('#what_selected_container .what_selected_nothing').hide(); 35637 $('#what_selected_container .what_selected_something').show(); 35638 var max_path_length = 85; 35639 35640 var path = data.rslt.obj.data('jstree')['nice_path']; 35641 if (!path) { 35642 path = data.rslt.obj.data('jstree')['path']; 35643 } 35644 if (path.length > max_path_length) { 35645 var filename = path.replace(/^.*[\\\/]/, ''); 35646 if (filename == '') { // no file at all 35647 path = path.substring(0, max_path_length - 3) + '...'; 35648 } 35649 else { 35650 if (filename.length > max_path_length) { // there is file but too long 35651 path = filename.substring(0, max_path_length - 3) + '...'; 35652 } 35653 else { 35654 var dirname = path.replace(/\\/g, '/').replace(/\/[^\/]*$/, ''); 35655 var max_dirname_length = max_path_length - filename.length - 1; 35656 if (max_dirname_length > 3) { 35657 dirname = dirname.substring(0, max_dirname_length - 3) + '...'; 35658 path = dirname + "/" + filename; 35659 } 35660 else { 35661 path = filename; 35662 } 35663 } 35664 } 35665 } 35666 35667 $('#what_selected_container .what_selected_something .what_selected_something_value').html(path); 35668 35669 // now rename buttons 35670 var child_obj_type_user_friendly_name = data.rslt.obj.data('jstree')['child_obj_type_user_friendly_name']; 35671 if (child_obj_type_user_friendly_name != null) 35672 { 35673 $(".child_obj_type_user_friendly_name").html(child_obj_type_user_friendly_name); 35674 } 35675 35676 var is_folder_create_disabled = data.rslt.obj.data('jstree')['is_folder_create_disabled']; 35677 if (is_folder_create_disabled) 35678 { 35679 $('#new_folder_button').addClass('ui-state-disabled'); 35680 } 35681 else 35682 { 35683 $('#new_folder_button').removeClass('ui-state-disabled'); 35684 } 35685 35686 }); 35687 35688 /* 35689 var on_click_delegate = function(e) { 35690 var node_id = $(this).parent('li.jstree-closed').attr("id"); //get ID of clicked node 35691 if (node_id != null) { 35692 $("#" + node_id + " .jstree-icon").trigger('click'); 35693 $('#select_synch_jstree_container').undelegate("a","click", on_click_delegate); 35694 } 35695 return true; 35696 } 35697 35698 $('#select_synch_jstree_container').delegate("a","click", on_click_delegate); 35699 */ 35700 35701 } /* fn_display_jstree */ 35702 35703 /*** 35704 * 35705 */ 35706 var fn_select_root_folder = function() {
35707 var rootObj = $($("#select_synch_jstree_container li.jstree-root")).data('jstree'); 35708 fn_check_selected_folder(rootObj, 35709 function() 35710 { 35711 var dir_row = $('<div></div>'); 35712 dir_row.append($('<input type="hidden" name="obj_list[]" />').val($.toJSON(rootObj))); 35713 dir_row.append($('<input type="hidden" name="name_list[]" />').val(rootObj['title_no_html'])); 35714 $('#synch_folder').append(dir_row); 35715 g_cmn.fn_working_overlay(true, "Saving..."); 35716 $('#select_folder_form').submit(); 35717 } 35718 ); 35719 }; 35720 35721 var fn_select_existing_folder = function(folderObj) { 35722 folderObj['title_no_html'] = folderObj['title']; 35723 fn_select_new_folder(folderObj); 35724 }; 35725 35726 var fn_select_new_folder = function(obj) { 35727 if(obj) { 35728 fn_check_selected_folder(obj, 35729 function() 35730 { 35731 var dir_row = $('<div></div>'); 35732 dir_row.append($('<input type="hidden" name="obj_list[]" />').val($.toJSON(obj))); 35733 dir_row.append($('<input type="hidden" name="name_list[]" />').val(obj['title_no_html'])); 35734 $('#synch_folder').append(dir_row); 35735 g_cmn.fn_working_overlay(true, "Saving..."); 35736 $('#select_folder_form').submit(); 35737 } 35738 ); 35739 } else { 35740 // if we don't have an object then open dialog 35741 var rootObj = $($("#select_synch_jstree_container li.jstree-root")).data('jstree'); 35742 if (rootObj == null) { 35743 window.location = 'https://www.cloudhq.net/main_services/refresh' 35744 } 35745 35746 if (rootObj['nice_path']) { 35747 $('#dialog_header_container_dir1_what').html(rootObj['nice_path']) 35748 } else { 35749 $('#dialog_header_container_dir1_what').html(rootObj['path']); 35750 } 35751 new_folder_dialog.dialog('option', 'parent_folder_obj_data', rootObj); 35752 new_folder_dialog.dialog('option', 'is_bcx_evernote_integration', false); 35753 new_folder_dialog.dialog('option', 'is_new_folder_option_selected', true); 35754 new_folder_dialog.dialog('open'); 35755 } 35756 }; 35757 35758 var fn_on_select_folder = function() 35759 { 35760 var folder_obj = $($("#select_synch_jstree_container .jstree-clicked")).parent('li'); 35761 if (folder_obj.length < 1) 35762 { 35763 g_cmn.fn_error_dialog("ERROR", "Nothing select. Please select a folder to synchronize.", { width: "550px" }); 35764 return; 35765 } 35766 else 35767 { 35768 if (folder_obj.data('jstree')['is_synch_disabled'] == true && folder_obj.data('jstree').what == 'sugarsync') 35769 { 35770 g_cmn.fn_error_dialog("ERROR", "Synchronization is not allowed on this level. Please select a SugarSync workspace.", { width: "550px" }); 35771 return; 35772 } 35773 35774 var selected_node = new Array(); 35775 var checked_obj = $("#select_synch_jstree_container .jstree-clicked").parent('li'); 35776 35777 $(checked_obj).each( 35778 function() { 35779 dir_res = fn_get_selected_folder($(this)); 35780 fn_check_selected_folder(dir_res['obj'], 35781 function() 35782 { 35783 var dir_row = document.createElement('div'); 35784 // add input rows with obj (which is json object) and name (just string) 35785 $(document.createElement('input')) 35786 .attr({'type': 'hidden', 'name': 'obj_list[]', 'value' : $.toJSON(dir_res['obj']) }) 35787 .appendTo(dir_row); 35788 $(document.createElement('input')) 35789 .attr({'type': 'hidden', 'name': 'name_list[]', 'value' : dir_res['name'] }) 35790 .appendTo(dir_row); 35791 35792 $('#synch_folder').append(dir_row); 35793 35794 g_cmn.fn_working_overlay(true, "Saving..."); 35795 $('#select_folder_form').submit(); 35796 } 35797 ); 35798 35799 }); 35800 } 35801 } 35802 35803 var fn_check_selected_folder = function(obj, next_step) 35804 { 35805 g_cmn.fn_working_overlay(true, "Checking..."); 35806 $.ajax({ 35807 type: "POST", 35808 url: g_site_url + "synch_wizard/check_select_folder_ajax", 35809 dataType: "json", 35810 data: { 35811 "obj": $.toJSON(obj) 35812 }, 35813 async: true, 35814 success: function(response){ 35815 if (response.warning && response.warning.cancel_action == 'return_to_select_folder_dir') { 35816 g_cmn.fn_normal_dialog("Warning", response.warning.title, response.warning.body, { 35817 width: "950px", 35818 buttons: { 35819 "<< Go Back, Select Different Folder": function(){ 35820 $(this).dialog("close"); 35821 g_cmn.fn_working_overlay(false, "Working..."); 35822 window.location = response.warning.cancel_link; 35823 }, 35824 "Sync Anyway": function(){ 35825 next_step(); 35826 $(this).dialog("close"); 35827 } 35828 } 35829 }); 35830 } 35831 else if (response.warning && response.warning.cancel_action == 'return_to_start') { 35832 g_cmn.fn_normal_dialog("Warning", response.warning.title, response.warning.body, { 35833 width: "950px", 35834 buttons: { 35835 "<< Go Back": function(){ 35836 $(this).dialog("close"); 35837 g_cmn.fn_working_overlay(false, "Working..."); 35838 window.location = response.warning.cancel_link; 35839 }, 35840 "Sync Anyway": function(){ 35841 next_step(); 35842 $(this).dialog("close"); 35843 } 35844 } 35845 }); 35846 } 35847 else if (response.warning) { 35848 g_cmn.fn_normal_dialog("Warning", response.warning.title, response.warning.body, { 35849 width: "950px", 35850 buttons: { 35851 "Cancel, Try Different Folder": function(){ 35852 $(this).dialog("close"); 35853 }, 35854 "Sync Anyway": function(){ 35855 next_step(); 35856 $(this).dialog("close"); 35857 } 35858 } 35859 }); 35860 } 35861 else if (response.error && response.error.cancel_action == 'return_to_select_folder_dir') { 35862 g_cmn.fn_error_dialog_with_text("Error", response.error.title, response.error.body, { 35863 width: "950px", 35864 buttons: { 35865 "<< Go Back": function(){ 35866 $(this).dialog("close"); 35867 g_cmn.fn_working_overlay(false, "Working..."); 35868 window.location = response.error.cancel_link; 35869 },
35870 "Close": function() { 35871 $(this).dialog("close"); 35872 } 35873 } 35874 }); 35875 } 35876 else if (response.notification) { 35877 g_cmn.fn_normal_dialog("Notification", response.notification.title, response.notification.body, { 35878 width: "950px", 35879 buttons: { 35880 "OK": function(){ 35881 next_step(); 35882 $(this).dialog("close"); 35883 } 35884 } 35885 }); 35886 } 35887 else if (response.error) { 35888 g_cmn.fn_error_dialog_with_text("Error", response.error.title, response.error.body, { 35889 width: "950px", 35890 buttons: { 35891 "Close": function(){ 35892 $(this).dialog("close"); 35893 } 35894 } 35895 }); 35896 } 35897 else 35898 { 35899 next_step(); 35900 } 35901 }, 35902 failure: function(response){ 35903 next_step(); 35904 } 35905 }); 35906 35907 } 35908 35909 var fn_check_selected_service = function(what, next_step) 35910 { 35911 g_cmn.fn_working_overlay(true, "Checking..."); 35912 $.ajax({ 35913 type: "POST", 35914 url: g_site_url + "synch_wizard/check_select_service_ajax", 35915 dataType: "json", 35916 data: { 35917 "what": $.toJSON(what) 35918 }, 35919 async: true, 35920 success: function(response){ 35921 35922 if (response.warning && response.warning.cancel_action == 'return_to_select_service') { 35923 g_cmn.fn_normal_dialog("Warning", response.warning.title, response.warning.body, { 35924 width: "950px", 35925 buttons: { 35926 "<< Go Back, Select Different Service": function(){ 35927 $(this).dialog("close"); 35928 g_cmn.fn_working_overlay(false, "Working..."); 35929 window.location = response.warning.cancel_link; 35930 }, 35931 "Sync Anyway": function(){ 35932 next_step(); 35933 $(this).dialog("close"); 35934 } 35935 } 35936 }); 35937 } 35938 else if (response.error && response.error.cancel_action == 'return_to_start') { 35939 g_cmn.fn_error_dialog_with_text("Error", response.error.title, response.error.body, { 35940 width: "950px", 35941 buttons: { 35942 "<< Cancel Wizard": function(){ 35943 $(this).dialog("close"); 35944 g_cmn.fn_working_overlay(true, "Restarting..."); 35945 window.location = response.error.cancel_link; 35946 }, 35947 "Try Different Service": function(){ 35948 g_cmn.fn_working_overlay(true, "Reloading..."); 35949 $(this).dialog("close"); 35950 window.location.reload(true); 35951 } 35952 }, 35953 close: function() { 35954 g_cmn.fn_working_overlay(true, "Reloading..."); 35955 window.location.reload(true); 35956 } 35957 }); 35958 } 35959 else if (response.error && response.error.cancel_action == "return_to_select_folder_dir") { 35960 g_cmn.fn_error_dialog_with_text("Error", response.error.title, response.error.body, { 35961 width: "950px", 35962 buttons: { 35963 "<< Go Back": function(){ 35964 $(this).dialog("close"); 35965 g_cmn.fn_working_overlay(false, "Checking..."); 35966 window.location = response.error.cancel_link; 35967 }, 35968 "Try Different Service": function(){ 35969 g_cmn.fn_working_overlay(true, "Reloading..."); 35970 $(this).dialog("close"); 35971 window.location.reload(true); 35972 } 35973 }, 35974 close: function() { 35975 g_cmn.fn_working_overlay(true, "Reloading..."); 35976 window.location.reload(true); 35977 } 35978 }); 35979 35980 } 35981 else if (response.error) { 35982 g_cmn.fn_error_dialog_with_text("Error", response.error.title, response.error.body, { 35983 width: "950px", 35984 buttons: { 35985 "Try Different Service": function(){ 35986 g_cmn.fn_working_overlay(true, "Reloading..."); 35987 $(this).dialog("close"); 35988 window.location.reload(true); 35989 } 35990 }, 35991 close: function() { 35992 g_cmn.fn_working_overlay(true, "Reloading..."); 35993 window.location.reload(true); 35994 } 35995 }); 35996 } 35997 else 35998 { 35999 next_step(); 36000 } 36001 }, 36002 failure: function(response){ 36003 next_step(); 36004 } 36005 }); 36006 36007 } 36008 36009 var fn_get_selected_folder = function(folder_element) 36010 { 36011 var folder_element_id = folder_element.attr('id'); 36012 var target_id = folder_element_id.split('_')[1]; 36013 var target_obj = folder_element.data('jstree'); 36014 36015 var is_not_top_parent_id = true; 36016 var target_name = ''; 36017 var i=0; 36018 while (is_not_top_parent_id) 36019 { 36020 if(i!=0) 36021 folder_element = $('#'+folder_element_id).parent().parent(); 36022 36023 i++; 36024 folder_element_id = folder_element.attr('id'); 36025 if (folder_element_id=='select_synch_jstree_container') 36026 is_not_top_parent_id = false;
36027 else 36028 { 36029 var d = folder_element.data('jstree'); 36030 if (d) text = d['title_no_html']; 36031 text = text.replace('SugarSync Workspaces (', 'SugarSync (') 36032 if (target_name == '') 36033 target_name = text; 36034 else 36035 target_name = text + " > " + target_name; 36036 } 36037 } 36038 return { id: target_id, obj: target_obj, name: target_name } 36039 } 36040 36041 36042} 36043 36044/** 36045 * @author Senad Dizdar 36046 * 36047 * Copyright (C) 2010-2012, cloudHQ 36048 * All rights reserved. 36049 * 36050 */ 36051 36052function c_synch_new_wizard() 36053{ 36054 /* private variables */ 36055 36056 /*********************************************/ 36057 /* PUBLIC FUNCTIONS */ 36058 /*********************************************/ 36059 this.fn_init = function(service_what, service_email_or_login, logged_in) 36060 { 36061 } 36062} 36063/** 36064 * @author Senad Dizdar 36065 */ 36066 36067function c_synch_wizard_setup_synch_to_central_cloud() { 36068 var self = this; 36069 var fbrowser = null; 36070 this.name = "c_replication"; 36071 this.target_obj = null; 36072 36073 this.fn_init = function() { 36074 36075 fbrowser = FileBrowser({ 36076 fsParams : { 36077 call_for_backup : true 36078 }, 36079 selectedObj: self.target_obj, 36080 onSelect : function(path, target_obj) { 36081 self.target_obj = target_obj; 36082 $('#target_dir_ref').val(target_obj.ref); 36083 $('#target_dir_what').val(target_obj.what); 36084 $('#target_dir_email_or_login').val(target_obj.email_or_login); 36085 var target_dir = path; 36086 var dir_name = target_dir.replace(/ +/g, " "); 36087 $('#target_dir_path').val(dir_name); 36088 } 36089 }); 36090 fbrowser.create(); 36091 36092 // reset target dir 36093 $('#target_dir_ref').val(''); 36094 $('#target_dir_what').val(''); 36095 $('#target_dir_email_or_login').val(''); 36096 36097 // create steps 36098 $('.step-command').click(function() { 36099 var btn = $(this); 36100 var step = btn.attr('data-next'); 36101 var validator = btn.attr('data-validator') || ''; 36102 36103 if (validator && !step_validators[validator].call()) { 36104 return; 36105 } 36106 36107 stepInit(step); 36108 36109 $('.step').removeClass('active'); 36110 $('.step.' + step).addClass('active'); 36111 }); 36112 36113 $('#service_list_checkbox_all').checkboxAll($('.service-list-checkbox')); 36114 $('#form_synch_wizard_setup_synch_to_central_cloud').submit(function() { 36115 try { 36116 g_cmn.fn_working_overlay(true, 'Starting configuration of synch pairs ...'); 36117 } catch(er) { 36118 } 36119 $('#form_synch_wizard_setup_synch_to_central_cloud').submit(); 36120 }); 36121 36122 $('.service_checkbox').click(function(e) { 36123 if (!$(this).is(':checked')) { 36124 service_name = $(this).attr('service_name'); 36125 service_email_or_login = $(this).attr('service_email_or_login'); 36126 g_cmn.fn_normal_dialog("Confirmation", "Exclude " + service_name + " (" + service_email_or_login + ") from backup.<br/><br/>" + "Are you sure?", "", { 36127 width : "550px", 36128 buttons : { 36129 "No" : function() { 36130 try { 36131 g_cmn.fn_working_overlay(true, 'Reverting...'); 36132 } catch(er) { 36133 } 36134 $(this).dialog("close"); 36135 document.location.reload(true); 36136 }, 36137 "Yes" : function() { 36138 try { 36139 g_cmn.fn_working_overlay(true, 'Saving...'); 36140 } catch(er) { 36141 } 36142 $(this).dialog("close"); 36143 document.save_backup_configs_form.submit(); 36144 // use javascript to skip jQuery 36145 } 36146 } 36147 }); 36148 } else { 36149 try { 36150 g_cmn.fn_working_overlay(true, 'Saving...'); 36151 } catch(er) { 36152 } 36153 $(this).dialog("close"); 36154 document.save_backup_configs_form.submit(); 36155 // use javascript to skip jQuery 36156 } 36157 36158 return true; 36159 }); 36160 36161 //disableRow(); 36162 }; 36163 36164 /*********************************************/ 36165 /* PRIVATE FUNCTIONS */ 36166 /*********************************************/ 36167 36168 function stepInit(step) { 36169 if (step == 'step-3') { 36170 $('.text_number_of_sync_pairs').text($('.service-list-checkbox:checked').length); 36171 $('.text_destination_sync_folder').text(self.target_obj.path); 36172 } 36173 } 36174 36175 var step_validators = { 36176 'validate_services_selected' : function() { 36177 if ($('.service-list-checkbox:checked').length == 0) { 36178 g_cmn.fn_error_dialog("ERROR", "Please select at least one service!"); 36179 return false; 36180 } 36181 return true; 36182 }, 36183 'validate_folder_selected' : function() { 36184 if (!self.target_obj || !self.target_obj.ref || self.target_obj.ref == '') { 36185 g_cmn.fn_error_dialog("ERROR", "Please specify replication destination folder."); 36186 return false; 36187 } 36188 return true; 36189 } 36190 }; 36191 36192 var disableRow = function() { 36193 var $tr = $("#table_services tr[data-rel='" + self.target_obj.what + "_" + self.target_obj.email_or_login + "']"); 36194 $('#table_services tr').removeClass('disabled'); 36195 $('#table_services input[type=checkbox]').removeAttr('disabled'); 36196 $tr.addClass('disabled').find('input[type=checkbox]').attr('disabled', 'disabled'); 36197 }; 36198 36199} 36200 36201/** 36202 * @author Senad Dizdar 36203 */ 36204 36205function c_support_us() 36206{ 36207 this.name = "c_support_us"; 36208 36209 this.fn_init = function() 36210 { 36211 } 36212 36213} 36214/** 36215 * @author Senad Dizdar 36216 * 36217 * Copyright (C) 2010-2011, cloudHQ 36218 * All rights reserved. 36219 * 36220 */ 36221 36222 $.fn.serializeObject = function() 36223{ 36224 var o = {}; 36225 var a = this.serializeArray(); 36226 $.each(a, function() { 36227 if (o[this.name] !== undefined) { 36228 if (!o[this.name].push) { 36229 o[this.name] = [o[this.name]]; 36230 } 36231 o[this.name].push(this.value || ''); 36232 } else { 36233 o[this.name] = this.value || ''; 36234 } 36235 }); 36236 return o; 36237}; 36238 36239function c_system_report() 36240{ 36241 36242 /*********************************************/ 36243 /* PUBLIC FUNCTIONS */ 36244 /*********************************************/ 36245 this.fn_init = function() 36246 { 36247 $('.utc_time').each(function(i, el) { 36248 var tagText = $(el).html(); 36249 var givenDate = Date($.format.date(tagText, "")); 36250 if ((givenDate + "") == 'Invalid Date') 36251 givenDate = tagText;
36252 $(el).html(' ' + givenDate); 36253 }); 36254 36255 $('[type="image"]').live('click', function(e){ 36256 var $form = $(this).parents('form'); 36257 $form.data('what',$(this).attr('name')); 36258 $form.data('how', $(this).attr('value')); 36259 }); 36260 36261 $('[type="submit"]').live('click', function(e){ 36262 var $form = $(this).parents('form'); 36263 $form.data('what',$(this).attr('what')); 36264 $form.data('how', $(this).attr('how')); 36265 }); 36266 36267 $("#modify_conflicts_form, #delete_conflicts_form, #retry_conflicts_form, #not_supported_conflicts_form").bind("submit", 36268 function() 36269 { 36270 if ($(this).find(':checkbox:checked').length == 0) 36271 { 36272 g_cmn.fn_error_dialog("ERROR", "Use the checkboxes to select one or more items.", { width: "550px" }); 36273 return false; 36274 } 36275 else 36276 { 36277 var checkbox_list = $(this).find(':checkbox[name="id_list[]"]:checked'); 36278 var id_list = []; 36279 $.each(checkbox_list, function() { 36280 id_list.push(this.value); 36281 }); 36282 var what = $(this).data('what'); 36283 var how = $(this).data('how'); 36284 36285 // TODO: Add dialog to display confirmation 36286 fn_resolve_conflict_ajax(what, how, id_list); 36287 36288 } 36289 return false; 36290 } 36291 ); 36292 36293 $('.select_all').click(function () { 36294 $(this).parents('fieldset:eq(0)').find(':checkbox').filter(':not(:disabled)').attr('checked', this.checked); 36295 }); 36296 36297 $(".modify_conflicts_details, .non_supported_conflicts_details, .delete_conflicts_details").bind("click", function(ev) { 36298 var $t = $(ev.target); 36299 var text = $('#reason_' + $t.attr('id')).html(); 36300 g_cmn.fn_normal_dialog("Details", "", text, 36301 { 36302 width: "950px", 36303 buttons: { 36304 "OK": function(){ 36305 $(this).dialog("close"); 36306 } 36307 } 36308 } 36309 ); 36310 return false; 36311 }); 36312 36313 } 36314 /*** 36315 * send ajax request to resolve conflicts 36316 * @param {String} what what is operation 36317 * @param {String} how how to fix it 36318 * @param {List} id_list list of ids of conflict records 36319 */ 36320 var fn_resolve_conflict_ajax = function(what, how, id_list) 36321 { 36322 36323 g_cmn.fn_notif_win(true, "Working..."); 36324 g_cmn.fn_working_overlay(); 36325 36326 36327 // alert('what='+$(this).data('what')); 36328 // alert('how='+$(this).data('how')) 36329 // alert( $.toJSON(id_list)); 36330 $.ajax( 36331 { 36332 type: "POST", 36333 url: g_site_url + "main_system_report/resolve_conflict", 36334 dataType: "json", 36335 data: { 36336 "id_list": $.toJSON(id_list), 36337 "what": $.toJSON(what), 36338 "how": $.toJSON(how) 36339 }, 36340 async: true, 36341 success: function(response) { 36342 g_cmn.fn_working_overlay(false); 36343 g_cmn.fn_notif_win(false); 36344 if (response.error) { 36345 g_cmn.fn_error_dialog("ERROR", response.error, { 36346 width: "370px", 36347 close: function() { location.reload(true); } 36348 }); 36349 } 36350 else if (response.long_running_operation) { 36351 g_cmn.fn_notif_win(false, "Job started", 1000); 36352 g_cmn.fn_normal_dialog("Operation started in background", "", "We started a background job.<br/><br/>You will receive an email when the job finishes.", { 36353 width: "650px", 36354 close: function() { location.reload(true); } 36355 }); 36356 } 36357 else { 36358 g_cmn.fn_notif_win(false, response.message, 1000); 36359 location.reload(true); 36360 } 36361 } 36362 } 36363 ); 36364 36365 } 36366 36367 36368} 36369 36370/** 36371 * @author Senad Dizdar 36372 * 36373 * Copyright (C) 2010-2011, cloudHQ 36374 * All rights reserved. 36375 * 36376 */ 36377 36378 36379function c_account() 36380{ 36381 36382 /*********************************************/ 36383 /* PUBLIC FUNCTIONS */ 36384 /*********************************************/ 36385 this.fn_init = function(){ 36386 36387 $('#downgrade_premium_beta').unbind("click").bind('click', function(){ 36388 no_need_to_downgrade_dialog.dialog('open'); 36389 }); 36390 36391 36392 } 36393 36394 var no_need_to_downgrade_dialog = $('#no_need_to_downgrade_dialog').dialog({ 36395 autoOpen: false, resizable: false, width: 510, title: "Downgrade Service", 36396 modal: true, 36397 buttons: { 36398 "OK": function() { 36399 $(this).dialog("close"); 36400 } 36401 } 36402 }); 36403 36404} 36405/** 36406 * @author Senad Dizdar 36407 */ 36408 36409function c_synch_template_configs() 36410{ 36411 this.name = "c_synch_template_configs"; 36412 36413 this.fn_init = function() 36414 { 36415 36416 $('.delete_button').unbind('click').bind('click', function() { 36417 var $t = $(this);
36418 g_cmn.fn_normal_dialog("Confirmation", "Are you sure?", "", 36419 { width: "350px", buttons: { 36420 "No": function() { 36421 $(this).dialog("close"); 36422 }, 36423 "Yes": function() { 36424 $t.parent('form').submit(); 36425 $(this).dialog("close"); 36426 } 36427 } 36428 }); 36429 return false; 36430 }); 36431 36432 fn_set_upload_convert_policy(); 36433 $('.synch_template_configs_can_be_edited #services_service1_id').change(function() { 36434 fn_set_upload_convert_policy(); 36435 }); 36436 $('.synch_template_configs_can_be_edited #services_service2_id').change(function() { 36437 fn_set_upload_convert_policy(); 36438 }); 36439 36440 fn_set_is_one_way_synch_enabled(); 36441 $('.synch_template_configs_can_be_edited #synch_template_config_is_one_way_synch_enabled').change(function() { 36442 fn_set_is_one_way_synch_enabled(); 36443 }); 36444 36445 36446 } 36447 36448 /* PRIVATE FUNCTIONS */ 36449 var fn_set_upload_convert_policy = function() 36450 { 36451 services_service1_id_val = $('.synch_template_configs_can_be_edited #services_service1_id').val(); 36452 services_service2_id_val = $('.synch_template_configs_can_be_edited #services_service2_id').val(); 36453 services_service1_id_text = $(".synch_template_configs_can_be_edited #services_service1_id option[value='" + services_service1_id_val +"']").text(); 36454 services_service2_id_text = $(".synch_template_configs_can_be_edited #services_service2_id option[value='" + services_service2_id_val +"']").text(); 36455 36456 if (services_service1_id_text.match(/Google Docs/) || services_service2_id_text.match(/Google Docs/)) { 36457 $('.synch_template_configs_can_be_edited #synch_template_config_upload_convert_policy').removeAttr('disabled'); 36458 $(".synch_template_configs_can_be_edited label[for='synch_template_config_upload_convert_policy']").removeClass('ui-state-disabled'); 36459 } 36460 else { 36461 $('.synch_template_configs_can_be_edited #synch_template_config_upload_convert_policy').attr('disabled', true); 36462 $(".synch_template_configs_can_be_edited label[for='synch_template_config_upload_convert_policy']").addClass('ui-state-disabled'); 36463 } 36464 36465 } 36466 36467 var fn_set_is_one_way_synch_enabled = function() 36468 { 36469 if ($('.synch_template_configs_can_be_edited #synch_template_config_is_one_way_synch_enabled').is(':checked')) { 36470 $('.synch_template_configs_can_be_edited #synch_template_config_overwrite_modify_of_target').removeAttr('disabled'); 36471 $(".synch_template_configs_can_be_edited label[for='synch_template_config_overwrite_modify_of_target']").removeClass('ui-state-disabled'); 36472 } 36473 else { 36474 $('.synch_template_configs_can_be_edited #synch_template_config_overwrite_modify_of_target').attr('disabled', true); 36475 $(".synch_template_configs_can_be_edited label[for='synch_template_config_overwrite_modify_of_target']").addClass('ui-state-disabled'); 36476 } 36477 } 36478 36479} 36480/** 36481 * @author Senad Dizdar 36482 */ 36483 36484function c_synch_exclude_configs() 36485{ 36486 this.fn_init = function() 36487 { 36488 $('.delete_button').unbind('click').bind('click', function() { 36489 g_cmn.fn_working_overlay(false, ""); 36490 }); 36491 36492 } 36493 36494} 36495var FileBrowser = function(param) { 36496 36497 var selectedObj = null; 36498 var selectedPath = null; 36499 36500 var options = $.extend({ 36501 selectedObj: null, 36502 onSelect: function(path, obj) {}, 36503 fsParams: { 36504 is_bcx_evernote_integration: false, 36505 is_bcx_simple_view: false, 36506 call_for_backup: false 36507 } 36508 }, param || {}); 36509 36510 function create() { 36511 fn_init_jstree(); 36512 } 36513 36514 function enable(enable) { 36515 var container = $('#select_synch_jstree_container').parent(); 36516 container.css('position', 'relative'); 36517 container.find('.jstree_mask').remove(); 36518 if(enable == false) { 36519 var div = $('<div class="jstree_mask" style="background:#fff;position:absolute;top:0;left:0;right:0;bottom:0"> </div>'); 36520 div.css('opacity', 0.4); 36521 container.append(div); 36522 } 36523 } 36524 36525 function getSelectedPath() { 36526 return selectedPath; 36527 } 36528 36529 function getSelectedObj() { 36530 return selectedObj; 36531 } 36532 36533 /*** 36534 * Initialize jstree inside dialog 36535 * @param {Object} service 36536 */ 36537 var fn_init_jstree = function() { 36538 36539 // call server to intilize 36540 $.ajax({
36541 type : "GET", 36542 url : g_site_url + "main_cloud_fs_interface/cloudhq_init", 36543 dataType : "json", 36544 data : options.fsParams, 36545 async : true, 36546 success : function(response) { 36547 if (response.error) { 36548 g_cmn.fn_error_dialog("ERROR", "Sorry, a temporary error has occurred. <br/>Please try again.", { 36549 width : "550px" 36550 }); 36551 } else { 36552 fn_display_jstree(response); 36553 } 36554 var node = $("#select_synch_jstree_container ul li"); 36555 if (node.length == 1) { 36556 $("#select_synch_jstree_container").jstree("open_node", node.first()); 36557 } 36558 }, 36559 failure : function(response) { 36560 g_cmn.fn_error_dialog("ERROR", "Sorry, a temporary error has occurred. <br/>Please try again.", { 36561 width : "550px" 36562 }); 36563 } 36564 }); 36565 36566 var new_folder_dialog = $("#new_folder_dialog").dialog({ 36567 autoOpen : false, 36568 resizable : false, 36569 width : 805, 36570 height : 255, 36571 title : 'Create folder', 36572 modal : true, 36573 buttons : { 36574 "Cancel" : function() { 36575 $(this).dialog("close"); 36576 }, 36577 "Create" : function() { 36578 var folder_name = $('#folder_name').val(); 36579 if (folder_name == '') 36580 g_cmn.fn_error_dialog("", "Please enter folder name"); 36581 else { 36582 g_cmn.fn_working_overlay(true, "Creating folder..."); 36583 d_parent_folder_obj_data = getSelectedObj(); 36584 d_is_bcx_evernote_integration = options.fsParams.is_bcx_evernote_integration; 36585 36586 $.ajax({
36587 type : "POST", 36588 url : g_site_url + "main_cloud_fs_interface/new_dir", 36589 dataType : "json", 36590 data : { 36591 "obj" : $.toJSON(d_parent_folder_obj_data), 36592 "folder_name" : $.toJSON(folder_name), 36593 "is_bcx_evernote_integration" : $.toJSON(d_is_bcx_evernote_integration), 36594 }, 36595 async : true, 36596 success : function(response) { 36597 if (response.error) { 36598 g_cmn.fn_working_overlay(false, null); 36599 g_cmn.fn_error_dialog("Error during folder creation", response.error); 36600 // g_cmn.fn_notif_win(true, "Folder creation failed.<br\>" + response.error , 5000); 36601 } else { 36602 g_cmn.fn_notif_win(true, "Folder created", 5000); 36603 fn_refresh_server(null, 'new_dir'); 36604 } 36605 }, 36606 failure : function(response) { 36607 g_cmn.fn_working_overlay(false, null); 36608 alert("Failure"); 36609 } 36610 }); 36611 $(this).dialog("close"); 36612 } 36613 } 36614 } 36615 }); 36616 36617 $('#new_folder_button').unbind("click").bind('click', function(){ 36618 36619 var parent_folder_obj = getSelectedObj(); 36620 if (parent_folder_obj == null) { 36621 g_cmn.fn_error_dialog("ERROR", "Nothing selected. Please select a parent folder.", { 36622 width: "550px" 36623 }); 36624 return; 36625 } 36626 36627 if (parent_folder_obj['is_folder_create_disabled'] == true ) { 36628 g_cmn.fn_error_dialog("ERROR", "The parent is read-only.", { 36629 width: "550px" 36630 }); 36631 return; 36632 } 36633 36634 if (parent_folder_obj['nice_path']) { 36635 $('#dialog_header_container_dir1_what').html(parent_folder_obj['nice_path']) 36636 } else { 36637 $('#dialog_header_container_dir1_what').html(parent_folder_obj['path']); 36638 } 36639 new_folder_dialog.dialog('open'); 36640 }); 36641 36642 36643 }; 36644 36645 /*** 36646 * fn_display_jstree: display jstree. 36647 * response: data received from cloudhq_init 36648 */ 36649 var fn_display_jstree = function(response) { 36650 $(function() { 36651 var container = $('#select_synch_jstree_container'); 36652 container.jstree("destroy").css('position', 'relative'); 36653 container.bind('load_node.jstree', function(event, data) { 36654 // alert("reopen"); 36655 }).jstree({ 36656 "core" : { 36657 html_titles : true 36658 }, 36659 "json_data" : { 36660 "correct_state" : true, 36661 "data" : response, 36662 "ajax" : { 36663 "url" : function(n) { 36664 if (n == -1) 36665 return false; 36666 else { 36667 g_cmn.fn_notif_win(true, "Loading...", null); 36668 return g_site_url + "main_cloud_fs_interface/cloudhq_dir"; 36669 } 36670 }, 36671 "success" : function(obj, t, x) { 36672 $('#loading').css('display', 'none'); 36673 if (t == "success") { 36674 var response = JSON.parse(x.responseText); 36675 if (response['error']) 36676 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page .", 5000); 36677 else 36678 g_cmn.fn_notif_win(false, "", null); 36679 } else { 36680 g_cmn.fn_notif_win(false, "", null); 36681 } 36682 }, 36683 "error" : function(obj) { 36684 g_cmn.fn_notif_win(true, "Something went wrong... <br>Please refresh the page.", 5000); 36685 }, 36686 "data" : function(obj) { 36687 return { 36688 "obj" : $.toJSON(obj.data('jstree')), 36689 "file_flag" : $.toJSON(false), 36690 "is_bcx_evernote_integration" : $.toJSON(options.fsParams.is_bcx_evernote_integration), 36691 "is_bcx_simple_view" : $.toJSON(options.fsParams.is_bcx_simple_view), 36692 "without_imap": $.toJSON(options.fsParams.without_imap) 36693 }; 36694 } 36695 } 36696 }, 36697 "contextmenu" : { 36698 "items" : function(node) { 36699 } // end function 36700 }, 36701 "themes" : { 36702 "theme" : "cloudhq", 36703 "dots" : false, 36704 "icons" : true 36705 }, 36706 "plugins" : ["themes", "json_data", "ui", "crrm", "types"] 36707 }); 36708 36709 });
36710 36711 $("#select_synch_jstree_container").bind("select_node.jstree", function(e, data) { 36712 $("#select_synch_jstree_container").jstree('open_node', data.rslt.obj); 36713 /* now update */ 36714 $('#what_selected_container .what_selected_nothing').hide(); 36715 $('#what_selected_container .what_selected_something').show(); 36716 var max_path_length = 85; 36717 36718 var obj = data.rslt.obj.data('jstree'); 36719 var path = obj['path']; 36720 var short_path = obj['short_path']; 36721 var shorthen_path = path; 36722 36723 var service_what = data.rslt.obj.data('jstree')['what']; 36724 var service_email_or_login = data.rslt.obj.data('jstree')['email_or_login']; 36725 36726 if (shorthen_path.length > max_path_length) { 36727 var filename = shorthen_path.replace(/^.*[\\\/]/, ''); 36728 if (filename == '') {// no file at all 36729 shorthen_path = shorthen_path.substring(0, max_path_length - 3) + '...'; 36730 } else { 36731 if (filename.length > max_path_length) {// there is file but too long 36732 shorthen_path = filename.substring(0, max_path_length - 3) + '...'; 36733 } else { 36734 var dirname = shorthen_path.replace(/\\/g, '/').replace(/\/[^\/]*$/, ''); 36735 var max_dirname_length = max_path_length - filename.length - 1; 36736 if (max_dirname_length > 3) { 36737 dirname = dirname.substring(0, max_dirname_length - 3) + '...'; 36738 shorthen_path = dirname + "/" + filename; 36739 } else { 36740 shorthen_path = filename; 36741 } 36742 } 36743 } 36744 } 36745 36746 $('#what_selected_container .what_selected_something .what_selected_something_value').html(shorthen_path); 36747 36748 $('#what_selected_container .what_selected_something .what_selected_something_value_service_what').html(service_what); 36749 $('#what_selected_container .what_selected_something .what_selected_something_value_service_email_or_login').html(service_email_or_login); 36750 $('#what_selected_container .what_selected_something .what_selected_something_value_short_path').html(short_path); 36751 36752 selectedObj = obj; 36753 selectedPath = path; 36754 36755 options.onSelect(selectedPath, selectedObj); 36756 36757 // now rename buttons 36758 var child_obj_type_user_friendly_name = obj['child_obj_type_user_friendly_name']; 36759 if (child_obj_type_user_friendly_name != null) { 36760 $(".child_obj_type_user_friendly_name").html(child_obj_type_user_friendly_name); 36761 } 36762 36763 var is_folder_create_disabled = obj['is_folder_create_disabled']; 36764 if (is_folder_create_disabled) { 36765 $('#new_folder_button').attr('disabled', 'disabled'); 36766 } else { 36767 $('#new_folder_button').removeAttr('disabled'); 36768 } 36769 36770 }); 36771 36772 }; 36773 36774 36775 /*** 36776 * Function used to refresh the tree on calling when click on refresh button 36777 * operation of copy , move, delete and new folder . 36778 * @param {Object} dir_id 36779 */ 36780 var fn_refresh_server = function fn_refresh_server(obj, operation) { 36781 var d = null; 36782 if (obj) 36783 d = { 36784 "obj" : $.toJSON(obj) 36785 }; 36786 36787 g_cmn.fn_notif_win(true, "Refreshing...", null); 36788 $.ajax({
36789 type : "POST", 36790 url : g_site_url + "main_cloud_fs_interface/refresh_cloudhq_dir", 36791 dataType : "json", 36792 data : d, 36793 async : true, 36794 success : function(response) { 36795 if (response.error) { 36796 g_cmn.fn_notif_win(false, "", null); 36797 } else { 36798 // we can just count number of open nodes in left tree and decrement them in event on 'select_node.jstree' 36799 $("#select_synch_jstree_container").jstree('refresh'); 36800 g_cmn.fn_working_overlay(false, null); 36801 } 36802 }, 36803 failure : function(response) { 36804 g_cmn.fn_working_overlay(false, null); 36805 alert("Failure"); 36806 } 36807 }); 36808 }; 36809 36810 36811 /* Return object public methods */ 36812 return { 36813 create: create, 36814 enable: enable, 36815 getSelectedPath: getSelectedPath, 36816 getSelectedObj: getSelectedObj 36817 }; 36818 36819}; 36820 36821/** 36822 * @author Senad Dizdar 36823 * 36824 * Copyright (C) 2010-2011, cloudHQ 36825 * All rights reserved. 36826 * 36827 */ 36828 36829function c_cmn() // stands for Class_CoMmoN 36830{ 36831 this.fn_init = function() 36832 { 36833 fn_resize_areas(); 36834 36835 try { 36836 $(window).load(function(){ 36837 fn_resize_areas(); 36838 }); 36839 } catch(e) { 36840 } 36841 $(window).resize(function() { 36842 fn_resize_areas(); 36843 }); 36844 36845 $('#report_a_bug, #report_a_problem').bind('click', function() { UserVoice.Popin.show(uservoiceBugOptions); return false; } ); 36846 36847 $('input.working_link').unbind('click').bind('click', function() { 36848 if ($(this).hasClass('noclick')) { 36849 return false; 36850 } 36851 var text = "Working..."; 36852 if ($(this).attr('notif_to_display') != null) 36853 text = $(this).attr('notif_to_display');
36854 try { g_cmn.fn_working_overlay(true, text); } catch(er) { } 36855 return true; 36856 }); 36857 36858 $('a.working_link').unbind('click').bind('click', function() { 36859 if ($(this).hasClass('noclick')) { 36860 return false; 36861 } 36862 var text = "Working..."; 36863 if ($(this).attr('notif_to_display') != null) 36864 text = $(this).attr('notif_to_display'); 36865 try { g_cmn.fn_working_overlay(true, text); } catch(er) { } 36866 return true; 36867 }); 36868 36869 $('button.working_link').unbind('click').bind('click', function() { 36870 if ($(this).hasClass('noclick')) { 36871 return false; 36872 } 36873 var text = "Working..."; 36874 if ($(this).attr('notif_to_display') != null) 36875 text = $(this).attr('notif_to_display'); 36876 try { g_cmn.fn_working_overlay(true, text); } catch(er) { } 36877 return true; 36878 }); 36879 } 36880 36881 /*** 36882 * @param ref: link to a window with all paramters 36883 * @param name: name of the window 36884 * @param options: options of the window 36885 */ 36886 this.fn_open_window = function(rel, name, options) 36887 { 36888 var pop_up_title = name; 36889 if ($.browser.msie) 36890 pop_up_title = pop_up_title.replace(' ', '_'); 36891 36892 if($.browser.msie) 36893 { 36894 window.open(rel, '', options); 36895 } 36896 else 36897 { 36898 var newwindow = window.open(rel, name, options); 36899 if (window.focus && newwindow) 36900 { 36901 newwindow.focus() 36902 } 36903 } 36904 36905 } 36906 36907 36908 /*** 36909 * @param level: fatal, debug, etc. 36910 * @param message: message to log 36911 */ 36912 this.fn_log = function(level, message) 36913 { 36914 // see: https://github.com/emwendelin/javascript-stacktrace 36915 var stacktrace = null; 36916 if (level == 'ERROR') 36917 stacktrace = printStackTrace(); 36918 $.ajax({ 36919 type: "GET", 36920 url: g_site_url + "logger/ajax_message", 36921 dataType: "json", 36922 data: { 36923 'level': $.toJSON(level), 36924 'message': $.toJSON(message), 36925 'stacktrace': $.toJSON(stacktrace) 36926 }, 36927 async: true, 36928 success: function(response){} 36929 }); 36930 } 36931 36932 /*** 36933 * @param display_flag: true or false - if false then we will hide notification 36934 * @param message: text to display - only needed if display_flag is true. The text to display. 36935 * @param display_timeout: optional parameter. If set then notification will disappear after specified number of seconds. 36936 */ 36937 this.fn_notif_win = function(display_flag, message, display_timeout) 36938 { 36939 $("#notif_win_msg_content span").html(message); 36940 if (display_flag == true) 36941 { 36942 $('#notif_win_msg').show(); 36943 if (display_timeout != null) 36944 { 36945 setTimeout(function() { 36946 $("#notif_win_msg").hide(); 36947 }, display_timeout); 36948 } 36949 } 36950 else 36951 $('#notif_win_msg').hide(); 36952 } 36953 36954 this.fn_cleanup_text = function(text) 36955 { 36956 36957 text = text.replace(/</g,'__OPEN__').replace(/>/g, '__CLOSE__'); 36958 text = text.replace(/__OPEN__b__CLOSE__/g, '<b>'); 36959 text = text.replace(/__OPEN__\/b__CLOSE__/g, '</b>'); 36960 text = text.replace(/__OPEN__i__CLOSE__/g, '<i>'); 36961 text = text.replace(/__OPEN__\/i__CLOSE__/g, '</i>'); 36962 text = text.replace(/__OPEN__p__CLOSE__/g, '<p>'); 36963 text = text.replace(/__OPEN__\/p__CLOSE__/g, '</p>'); 36964 text = text.replace(/__OPEN__ol/g, '<ol'); 36965 text = text.replace(/__OPEN__\/ol__CLOSE__/g, '</ol>'); 36966 text = text.replace(/__OPEN__ul/g, '<ul'); 36967 text = text.replace(/__OPEN__\/ul__CLOSE__/g, '</ul>'); 36968 text = text.replace(/__OPEN__li/g, '<li'); 36969 text = text.replace(/__OPEN__\/li__CLOSE__/g, '</li>'); 36970 text = text.replace(/__OPEN__small/g, '<small'); 36971 text = text.replace(/__OPEN__center__CLOSE__/g, '<center>'); 36972 text = text.replace(/__OPEN__\/center__CLOSE__/g, '</center>'); 36973 text = text.replace(/__OPEN__b__CLOSE__/g, '<b>'); 36974 text = text.replace(/__OPEN__\/b__CLOSE__/g, '</b>'); 36975 text = text.replace(/__OPEN__\/small__CLOSE__/g, '</small>'); 36976 text = text.replace(/__OPEN__span/g, '<span'); 36977 text = text.replace(/__OPEN__\/span__CLOSE__/g, '</span>'); 36978 text = text.replace(/__OPEN__a/g, '<a'); 36979 text = text.replace(/__OPEN__\/a__CLOSE__/g, '</a>'); 36980 text = text.replace(/__OPEN__u/g, '<u'); 36981 text = text.replace(/__OPEN__\/u__CLOSE__/g, '</u>'); 36982 text = text.replace(/__OPEN__br\/__CLOSE__/g, '<br/>'); 36983 text = text.replace(/__OPEN__br__CLOSE__/g, '<br>'); 36984 text = text.replace(/__OPEN__td/g, '<td'); 36985 text = text.replace(/__OPEN__\/td__CLOSE__/g, '</td>'); 36986 text = text.replace(/__OPEN__tr/g, '<tr'); 36987 text = text.replace(/__OPEN__\/tr__CLOSE__/g, '</tr>'); 36988 text = text.replace(/__OPEN__table/g, '<table'); 36989 text = text.replace(/__OPEN__\/table__CLOSE__/g, '</table>'); 36990 text = text.replace(/__OPEN__tbody/g, '<tbody'); 36991 text = text.replace(/__OPEN__\/tbody__CLOSE__/g, '</tbody>'); 36992 text = text.replace(/__OPEN__/g,' ').replace(/__CLOSE__/g, '>'); 36993 36994 return text 36995 } 36996 /** 36997 * display error dialog 36998 * @param {string} text text to display 36999 * @param {string} title title of the dialog 37000 * @return {string} Nothing 37001 */ 37002 this.fn_error_dialog = function(title, text, settings) 37003 { 37004 var defaults = { 37005 autoOpen: true, 37006 resizable: true, 37007 width: 500, 37008 /* height: 170,*/ 37009 title: title, 37010 dialogClass: "operation_error", 37011 modal: true 37012 }; 37013 settings = $.extend(true, {}, defaults, settings); 37014 37015 g_cmn.fn_working_overlay(false, ""); 37016 37017 // we replace : 37018 // {small} ... __small__ to <small>.. </small> 37019 // {a} ... __a__ to <a> ... </a> 37020 // {br} 37021 text = g_cmn.fn_cleanup_text(text); 37022 37023 $('#error_dialog .dialog_header_container').html(text);
37024 $("#error_dialog").dialog('destroy').dialog(settings); 37025 37026 } 37027 37028 /** 37029 * display error dialog 37030 * @param {string} text text to display 37031 * @param {string} title title of the dialog 37032 * @return {string} Nothing 37033 */ 37034 this.fn_error_dialog_with_text = function(title, header_text, body_text, settings) 37035 { 37036 header_text = g_cmn.fn_cleanup_text(header_text); 37037 body_text = g_cmn.fn_cleanup_text(body_text); 37038 37039 var defaults = { 37040 autoOpen: true, 37041 resizable: true, 37042 /* width: 200,*/ 37043 /* height: 170,*/ 37044 title: title, 37045 dialogClass: "operation_error", 37046 modal: true 37047 }; 37048 settings = $.extend(true, {}, defaults, settings); 37049 $('#normal_dialog .dialog_header_container').html(header_text); 37050 37051 g_cmn.fn_working_overlay(false, ""); 37052 $('#normal_dialog .dialog_body_container').html(body_text); 37053 $("#normal_dialog").dialog('destroy').dialog(settings); 37054 } 37055 37056 37057 /** 37058 * display normal dialog 37059 * @param {string} text text to display 37060 * @param {string} title title of the dialog 37061 * @return {string} Nothing 37062 */ 37063 this.fn_normal_dialog = function(title, header_text, body_text, settings) 37064 { 37065 header_text = g_cmn.fn_cleanup_text(header_text); 37066 body_text = g_cmn.fn_cleanup_text(body_text); 37067 37068 var defaults = { 37069 autoOpen: true, 37070 resizable: true, 37071 /* width: 200,*/ 37072 /* height: 170,*/ 37073 title: title, 37074 modal: true 37075 }; 37076 settings = $.extend(true, {}, defaults, settings); 37077 $('#normal_dialog .dialog_header_container').html(header_text); 37078 37079 g_cmn.fn_working_overlay(false, ""); 37080 $('#normal_dialog .dialog_body_container').html(body_text); 37081 $("#normal_dialog").dialog('destroy').dialog(settings); 37082 } 37083 37084 /** 37085 * display overlay 37086 * @param {boolean} mode if false then close 37087 */ 37088 this.fn_working_overlay = function(mode, message) 37089 { 37090 if (mode == false) { 37091 $('#full_win_working_overlay').hide(); 37092 this.fn_notif_win(false); 37093 } 37094 else { 37095 $('#full_win_working_overlay').show(); 37096 if (message) this.fn_notif_win(true, message); 37097 } 37098 } 37099 37100 /** 37101 * @private 37102 */ 37103 var fn_resize_areas = function() 37104 { 37105 /*$('body').height($(window).height()); 37106 $('.footer').css('display', 'inline-block'); 37107 var min_h = $('.main_content_container').height() + $('.main_content_container').offset().top; 37108 var h = $('body').height() - $('.footer').height() - 9; 37109 $('.main-wrapper').height(Math.max(min_h, h)); 37110 $('.main-outer-wrapper').height(Math.max(min_h, h));*/ 37111 } 37112 37113}; 37114 37115window.date_format = (function() { 37116 37117 var MONTH_NAMES = [ 37118 'January', 37119 'February', 37120 'March', 37121 'April', 37122 'May', 37123 'June', 37124 'July', 37125 'August', 37126 'September', 37127 'October', 37128 'November', 37129 'December' 37130 ]; 37131 37132 function get_formatted_date(date, prefomattedDate = false, hideYear = false) { 37133 const day = date.getDate();
37134 const month = MONTH_NAMES[date.getMonth()]; 37135 const year = date.getFullYear(); 37136 const hours = date.getHours(); 37137 let minutes = date.getMinutes(); 37138 37139 if (minutes < 10) { 37140 // Adding leading zero to minutes 37141 minutes = `0${ minutes }`; 37142 } 37143 37144 if (prefomattedDate) { 37145 // Today at 10:20 37146 // Yesterday at 10:20 37147 return `${ prefomattedDate } at ${ hours }:${ minutes }`; 37148 } 37149 37150 if (hideYear) { 37151 // 10. January at 10:20 37152 return `${ day }. ${ month } at ${ hours }:${ minutes }`; 37153 } 37154 37155 // 10. January 2017. at 10:20 37156 return `${ day }. ${ month } ${ year }. at ${ hours }:${ minutes }`; 37157 } 37158 37159 var self = {}; 37160 37161 self.track_time_ago = function(element, options) { 37162 37163 options = $.extend({ 37164 date: new Date(), 37165 interval: 15000 37166 }, options || {}); 37167 37168 var $element = $(element); 37169 37170 var tick = function() { 37171 var text = date_format.time_ago(options.date).toLowerCase(); 37172 $element.text(text); 37173 } 37174 37175 window.setInterval(tick, options.interval); 37176 37177 tick(); 37178 37179 return $element; 37180 37181 }; 37182 37183 self.time_ago = function(dateParam) { 37184 37185 if (!dateParam) { 37186 return null; 37187 } 37188 37189 const date = typeof dateParam === 'object' ? dateParam : new Date(dateParam); 37190 const DAY_IN_MS = 86400000; // 24 * 60 * 60 * 1000 37191 const today = new Date(); 37192 const yesterday = new Date(today - DAY_IN_MS); 37193 const seconds = Math.round((today - date) / 1000); 37194 const minutes = Math.round(seconds / 60); 37195 const isToday = today.toDateString() === date.toDateString(); 37196 const isYesterday = yesterday.toDateString() === date.toDateString(); 37197 const isThisYear = today.getFullYear() === date.getFullYear(); 37198 37199 37200 if (seconds < 5) { 37201 return 'now'; 37202 } else if (seconds < 60) { 37203 return `${ seconds } seconds ago`; 37204 } else if (seconds < 90) { 37205 return 'about a minute ago'; 37206 } else if (minutes < 60) { 37207 return `${ minutes } minutes ago`; 37208 } else if (isToday) { 37209 return get_formatted_date(date, 'Today'); // Today at 10:20 37210 } else if (isYesterday) { 37211 return get_formatted_date(date, 'Yesterday'); // Yesterday at 10:20 37212 } else if (isThisYear) { 37213 return get_formatted_date(date, false, true); // 10. January at 10:20 37214 } 37215 37216 return get_formatted_date(date); // 10. January 2017. at 10:20 37217 } 37218 37219 return self; 37220 37221})(); 37222 37223window.c_ext = (function() { 37224 37225 function fn_is_chrome() { 37226 // please note, 37227 // that IE11 now returns undefined again for window.chrome 37228 // and new Opera 30 outputs true for window.chrome 37229 // but needs to check if window.opr is not undefined 37230 // and new IE Edge outputs to true now for window.chrome 37231 // and if not iOS Chrome check 37232 // so use the below updated condition 37233 var isChromium = window.chrome; 37234 var winNav = window.navigator; 37235 var vendorName = winNav.vendor; 37236 var isOpera = typeof window.opr !== "undefined"; 37237 var isIEedge = winNav.userAgent.indexOf("Edge") > -1; 37238 var isIOSChrome = winNav.userAgent.match("CriOS"); 37239 37240 if (isIOSChrome) { 37241 return false; 37242 } else if( 37243 isChromium !== null && 37244 typeof isChromium !== "undefined" && 37245 vendorName === "Google Inc." && 37246 isOpera === false && 37247 isIEedge === false 37248 ) { 37249 return true; 37250 } else { 37251 return false; 37252 } 37253 } 37254 37255 function fn_check_if_extension_installed_impl(extension_id, callback) { 37256 37257 if (!fn_is_chrome()) { 37258 callback({ installed: false, supported: false}); 37259 } 37260 37261 if (extension_id) { 37262 37263 // The extension's own cloudhq.js content script marks cloudhq.net pages with <head data-cloudhq-has-<ext>="true">, 37264 // where <ext> is the extension internal name with "_" replaced by "-". We read that internal name from a companion 37265 // attribute chrome-extension-{not-installed,installed,not-supported}-name on the detection element and use the 37266 // marker as a FALLBACK: first we try the resource probe, and only if that says "not installed" do we check the 37267 // marker. The marker is the only signal for MV3 extensions (e.g. the Outlook extension), which do not expose the 37268 // web_accessible_resources the probe looks for. 37269 // Require the id + name-attribute PAIRING in the selector: pages like main_dashboard/apps render a positive 37270 // [chrome-extension-installed] div (without a name attribute) BEFORE the [chrome-extension-not-installed] div, 37271 // and a plain id-only selector would match that first div and come back without the internal name. 37272 var marker_el = null;
37273 try { 37274 marker_el = document.querySelector('[chrome-extension-not-installed="' + extension_id + '"][chrome-extension-not-installed-name],[chrome-extension-installed="' + extension_id + '"][chrome-extension-installed-name],[chrome-extension-not-supported="' + extension_id + '"][chrome-extension-not-supported-name]'); 37275 } catch(e) { } 37276 var ext_internal_name = marker_el ? (marker_el.getAttribute('chrome-extension-not-installed-name') || marker_el.getAttribute('chrome-extension-installed-name') || marker_el.getAttribute('chrome-extension-not-supported-name')) : null; 37277 var marker_attr = ext_internal_name ? ('data-cloudhq-has-' + ext_internal_name.replace(/_/g, '-')) : null; 37278 37279 // Called when the resource probe below concludes the extension is not installed. cloudhq.js sets its marker at 37280 // document_end (and it is the ONLY signal for MV3 extensions), so poll the head for ~2s before finally giving up. 37281 // Keep this short: the poll only delays the NEGATIVE verdict, i.e. how late the "Install it" hint shows for users 37282 // who really do not have the extension (installed users match on the first or second check). A real marker lands 37283 // within a few hundred ms of DOMContentLoaded (watch_video.html.erb budgets 500ms for the same marker), so 2s is 37284 // already a generous multiple of the realistic tail. 37285 function fn_check_extension_via_cloudhq_marker() { 37286 if (!marker_attr || !fn_is_chrome()) { 37287 callback({ installed: false, supported: true }); 37288 return; 37289 } 37290 var marker_attempts = 0; 37291 var fn_poll_cloudhq_marker = function() { 37292 if (document.head && document.head.getAttribute(marker_attr) === 'true') { 37293 console.log(extension_id, ' is installed (' + marker_attr + ')'); 37294 callback({ installed: true, supported: true }); 37295 return; 37296 } 37297 marker_attempts++; 37298 if (marker_attempts >= 10) { 37299 console.log(extension_id, ' not installed (probe failed and ' + marker_attr + ' absent after polling)'); 37300 callback({ installed: false, supported: true }); 37301 return; 37302 } 37303 setTimeout(fn_poll_cloudhq_marker, 200); 37304 }; 37305 fn_poll_cloudhq_marker(); 37306 } 37307 37308 function fn_check_extension_via_inboxsdk_js(extension_id) { 37309
37310 var url = 'chrome-extension://'+ extension_id +'/javascripts/inboxsdk.js'; 37311 37312 var xhr = new XMLHttpRequest(); 37313 xhr.onerror = function() { 37314 console.log(extension_id, ' unable to find inboxsdk_js; trying cloudhq.js page marker'); 37315 fn_check_extension_via_cloudhq_marker(); 37316 } 37317 xhr.onload = function() { 37318 console.log(extension_id, ' is installed (inboxsdk_js)'); 37319 callback({ installed: true, supported: true}); 37320 }; 37321 try { xhr.open('GET', url); } catch(e) { } 37322 try { xhr.send(); } catch(e) { } 37323 37324 } 37325 37326 function fn_check_extension_via_background_js(extension_id) { 37327 var url = 'chrome-extension://'+ extension_id +'/javascripts/background.js'; 37328 37329 var xhr = new XMLHttpRequest(); 37330 xhr.onerror = function() { 37331 console.log(extension_id, ' unable to find background_js '); 37332 fn_check_extension_via_inboxsdk_js(extension_id); 37333 } 37334 xhr.onload = function() { 37335 console.log(extension_id, ' is installed (background_js)'); 37336 callback({ installed: true, supported: true}); 37337 }; 37338 try { xhr.open('GET', url); } catch(e) { } 37339 try { xhr.send(); } catch(e) { } 37340 37341 } 37342 37343 function fn_check_extension_via_popup_js(extension_id) {
37344 var url = 'chrome-extension://'+ extension_id +'/javascripts/popup.js'; 37345 37346 var xhr = new XMLHttpRequest(); 37347 xhr.onerror = function() { 37348 console.log(extension_id, ' unable to find popup_js '); 37349 fn_check_extension_via_background_js(extension_id); 37350 } 37351 xhr.onload = function() { 37352 console.log(extension_id, ' is installed (popup_js)'); 37353 callback({ installed: true, supported: true}); 37354 }; 37355 try { xhr.open('GET', url); } catch(e) { } 37356 try { xhr.send(); } catch(e) { } 37357 37358 } 37359 37360 function fn_check_extension_via_logo(extension_id) { 37361 var url = 'chrome-extension://'+ extension_id +'/icons/logo.png'; 37362 37363 var xhr = new XMLHttpRequest(); 37364 xhr.onerror = function() { 37365 console.log(extension_id, ' unable to find logo'); 37366 fn_check_extension_via_popup_js(extension_id); 37367 // console.log(xhr.response); 37368 } 37369 xhr.onload = function() { 37370 console.log(extension_id, ' is installed (logo)'); 37371 callback({ installed: true, supported: true}); 37372 }; 37373 try { xhr.open('GET', url); } catch(e) { } 37374 try { xhr.send(); } catch(e) { } 37375 } 37376 37377 // Old logic first: probe the extension's web_accessible_resources. On terminal failure the probe chain calls 37378 // fn_check_extension_via_cloudhq_marker() (from fn_check_extension_via_inboxsdk_js), which then polls the marker. 37379 fn_check_extension_via_logo(extension_id); 37380 } 37381 37382 return true; 37383 37384 } 37385 37386 var css_text = '[chrome-extension-installed],[chrome-extension-not-installed], [chrome-extension-not-supported] { display:none; }'; 37387 if (fn_is_chrome()) { 37388 css_text += '\n[is-chrome-browser="false"] { display: none !important; }'; 37389 } else { 37390 css_text += '\n[is-chrome-browser="true"] { display: none !important; }'; 37391 } 37392 37393 var s = $('<style />'); 37394 s.text(css_text); 37395 $(document.head).append(s); 37396 37397 $(function() { 37398 $.unique($('[chrome-extension-installed],[chrome-extension-not-installed],[chrome-extension-not-supported]').map(function() { 37399 return $(this).attr('chrome-extension-installed') || $(this).attr('chrome-extension-not-installed') || $(this).attr('chrome-extension-not-supported'); 37400 })).each(function() { 37401 var extension_id = this; 37402 if (extension_id) { 37403 37404 fn_check_if_extension_installed_impl(extension_id, function(res) { 37405 37406 var css_text = ""; 37407 37408 if(res.supported && res.installed) { 37409 css_text += '\n[chrome-extension-installed="' + extension_
37409id + '"] { display: block; }'; 37410 } 37411 37412 if(res.supported && !res.installed) { 37413 css_text += '\n[chrome-extension-not-installed="' + extension_id + '"] { display: block; }'; 37414 } 37415 37416 if(!res.supported) { 37417 css_text += '\n[chrome-extension-not-supported="' + extension_id + '"] { display: block; }'; 37418 } 37419 37420 var s = $('<style />'); 37421 s.text(css_text); 37422 $(document.head).append(s); 37423 37424 }); 37425 } 37426 }); 37427 }); 37428 37429 return { 37430 fn_is_chrome: fn_is_chrome, 37431 fn_check_if_extension_installed: fn_check_if_extension_installed_impl 37432 }; 37433 37434})(); 37435 37436/** 37437 * @author Blaz Lipuscek 37438 */ 37439(function($) { 37440 37441 $.fn.extend({ 37442 37443 timeAgo: function(options) { 37444 var $element = $(this); 37445 date_format.track_time_ago($element, options); 37446 return $element; 37447 }, 37448 37449 submitViaAjax: function(options) { 37450 37451 var submitCount = 0; 37452 37453 function run_ajax(method, action, data, options) { 37454 var ajaxOptions = $.extend({ 37455 type: method, 37456 url: action, 37457 data: data, 37458 dataType : "json", 37459 timeout: 0, // infinit 37460 success: function(response, status, xhr) { 37461 if (timeout) 37462 window.clearTimeout(timeout); 37463 if (response.resubmit == true) { 37464 // we need to resubmit this method, make sure we pass on resubmit argument. 37465 var timeout = Math.min(submitCount, 3) * 10000; 37466 window.setTimeout(function() { 37467 run_ajax(method, action, data + '&resubmit=1', options); 37468 }, timeout); 37469 return; 37470 } else if(response && response.next_page != null) { 37471 location.replace(response.next_page); 37472 return; 37473 } else if (response && response.message ) { 37474 try { g_cmn.fn_working_overlay(false); } catch(er) { } 37475 g_cmn.fn_notif_win(true, response.message, 10000); 37476 } else { 37477 window.location.reload(true); 37478 } 37479 }, 37480 error: function(json) { 37481 if (timeout) 37482 window.clearTimeout(timeout); 37483 g_cmn.fn_notif_win(true, "Looks like an error occurred on server! Please try again ...", 6000); 37484 try { g_cmn.fn_working_overlay(false); } catch(er) { } 37485 } 37486 }, (options['ajaxOptions']) || {}); 37487 submitCount = submitCount + 1; 37488 $.ajax(ajaxOptions); 37489 } 37490 37491 options = options || {}; 37492 var form = $(this); 37493 var formWorkingText = form.attr('data-working-text') || options['workingText'] || 'Working ...'; 37494 var formWorkingTextAfter = form.attr('data-working-text-after') || options['workingTextAfter'] || 'Still working! This could take a few minutes ...'; 37495 var timeout = null; 37496 var fromSubmitEvent = form.submit(function() { 37497 if (timeout) 37498 window.clearTimeout(timeout); 37499 try { g_cmn.fn_working_overlay(true, formWorkingText); } catch(er) { } 37500 timeout = window.setTimeout(function() { 37501 try { g_cmn.fn_working_overlay(true, formWorkingTextAfter); } catch(er) { } 37502 }, 10000); 37503 var values = form.serialize(); 37504 var method = form.attr('method'); 37505 var action = form.attr('action'); 37506 run_ajax(method, action, values, options); 37507 return false; 37508 }); 37509 return fromSubmitEvent; 37510 }, 37511 37512 checkboxAll : function(checkbox_selector) { 37513 37514 var $checkAll = $(this); 37515 var $checkboxes = $(checkbox_selector); 37516 37517 var checkAll = function(checked) { 37518 $checkboxes.each(function() { 37519 var $checkbox = $(this); 37520 if (checked) { 37521 if (!$checkbox.attr('disabled')) 37522 $checkbox.attr('checked', 'checked'); 37523 } else 37524 $checkbox.removeAttr('checked'); 37525 }); 37526 }; 37527 37528 var refreshCheckState = function() { 37529 var unchecked = false; 37530 $checkboxes.each(function() { 37531 var $checkbox = $(this); 37532 if (!$checkbox.is(':checked') && !$checkbox.attr('disabled')) 37533 unchecked = true; 37534 }); 37535 if (!unchecked) { 37536 $checkAll.attr('checked', 'checked'); 37537 } else { 37538 $checkAll.removeAttr('checked'); 37539 } 37540 }; 37541 37542 $checkAll.click(function() {
37543 var $check = $(this); 37544 var checked = $check.is(':checked'); 37545 checkAll(checked); 37546 refreshCheckState(); 37547 }); 37548 37549 $checkboxes.click(refreshCheckState); 37550 37551 refreshCheckState(); 37552 } 37553 }); 37554 37555 $(function() { 37556 $('.ajax-form').each(function() { 37557 $(this).submitViaAjax({}); 37558 }); 37559 }); 37560 37561})(jQuery); 37562 37563// From: http://www.quirksmode.org/js/detect.html 37564try { 37565 window.top.browserDetect = { 37566 init: function(){ 37567 this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; 37568 this.version = this.searchVersion(navigator.userAgent) || 37569 this.searchVersion(navigator.appVersion) || 37570 "an unknown version"; 37571 this.OS = this.searchString(this.dataOS) || "an unknown OS"; 37572 }, 37573 searchString: function(data){ 37574 for (var i = 0; i < data.length; i++) { 37575 var dataString = data[i].string; 37576 var dataProp = data[i].prop; 37577 this.versionSearchString = data[i].versionSearch || data[i].identity; 37578 if (dataString) { 37579 if (dataString.indexOf(data[i].subString) != -1) 37580 return data[i].identity; 37581 } 37582 else 37583 if (dataProp) 37584 return data[i].identity; 37585 } 37586 }, 37587 searchVersion: function(dataString){ 37588 var index = dataString.indexOf(this.versionSearchString); 37589 if (index == -1) 37590 return; 37591 return parseFloat(dataString.substring(index + this.versionSearchString.length + 1)); 37592 }, 37593 dataBrowser: [{ 37594 string: navigator.userAgent, 37595 subString: "Flock", 37596 identity: "Flock" 37597 }, { 37598 string: navigator.userAgent, 37599 subString: "RockMelt", 37600 identity: "RockMelt" 37601 }, { 37602 string: navigator.userAgent, 37603 subString: "Chrome", 37604 identity: "Chrome" 37605 }, { 37606 string: navigator.userAgent, 37607 subString: "OmniWeb", 37608 versionSearch: "OmniWeb/", 37609 identity: "OmniWeb" 37610 }, { 37611 string: navigator.vendor, 37612 subString: "Apple", 37613 identity: "Safari", 37614 versionSearch: "Version" 37615 }, { 37616 prop: window.opera, 37617 identity: "Opera" 37618 }, { 37619 string: navigator.vendor, 37620 subString: "iCab", 37621 identity: "iCab" 37622 }, { 37623 string: navigator.vendor, 37624 subString: "KDE", 37625 identity: "Konqueror" 37626 }, { 37627 string: navigator.userAgent, 37628 subString: "Firefox", 37629 identity: "Firefox" 37630 }, { 37631 string: navigator.userAgent, 37632 subString: "Iceweasel", 37633 identity: "Firefox" 37634 }, { 37635 string: navigator.userAgent, 37636 subString: "Shiretoko", 37637 identity: "Firefox" 37638 }, { 37639 string: navigator.userAgent, 37640 subString: "Namoroka", 37641 identity: "Firefox" 37642 }, { 37643 string: navigator.userAgent, 37644 subString: "Minefield", 37645 identity: "Firefox" 37646 }, { 37647 string: navigator.vendor, 37648 subString: "Camino", 37649 identity: "Camino" 37650 }, { // for newer Netscapes (6+) 37651 string: navigator.userAgent, 37652 subString: "Netscape", 37653 identity: "Netscape" 37654 }, { 37655 string: navigator.userAgent, 37656 subString: "MSIE", 37657 identity: "Explorer", 37658 versionSearch: "MSIE" 37659 }, { 37660 string: navigator.userAgent, 37661 subString: "Gecko", 37662 identity: "Mozilla", 37663 versionSearch: "rv" 37664 }, { // for older Netscapes (4-) 37665 string: navigator.userAgent, 37666 subString: "Mozilla", 37667 identity: "Netscape", 37668 versionSearch: "Mozilla" 37669 }], 37670 dataOS: [{ 37671 string: navigator.platform, 37672 subString: "Win", 37673 identity: "Windows" 37674 }, { 37675 string: navigator.platform, 37676 subString: "Mac", 37677 identity: "Mac" 37678 }, { 37679 string: navigator.userAgent, 37680 subString: "iPhone", 37681 identity: "iPhone/iPod" 37682 }, { 37683 string: navigator.userAgent, 37684 subString: "iPad", 37685 identity: "iPad" 37686 }, { 37687 string: navigator.userAgent, 37688 subString: "Android", 37689 identity: "Android" 37690 }, { 37691 string: navigator.platform, 37692 subString: "Linux", 37693 identity: "Linux" 37694 }] 37695 37696 }; 37697 browserDetect.init(); 37698} 37699catch(e) 37700{ 37701 37702} 37703 37704/**
37705 * Cookie plugin 37706 * 37707 * Copyright (c) 2006 Klaus Hartl (stilbuero.de) 37708 * Dual licensed under the MIT and GPL licenses: 37709 * http://www.opensource.org/licenses/mit-license.php 37710 * http://www.gnu.org/licenses/gpl.html 37711 * 37712 */ 37713 37714/** 37715 * Create a cookie with the given name and value and other optional parameters. 37716 * 37717 * @example $.cookie('the_cookie', 'the_value'); 37718 * @desc Set the value of a cookie. 37719 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); 37720 * @desc Create a cookie with all available options. 37721 * @example $.cookie('the_cookie', 'the_value'); 37722 * @desc Create a session cookie. 37723 * @example $.cookie('the_cookie', null); 37724 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain 37725 * used when the cookie was set. 37726 * 37727 * @param String name The name of the cookie. 37728 * @param String value The value of the cookie. 37729 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. 37730 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. 37731 * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. 37732 * If set to null or omitted, the cookie will be a session cookie and will not be retained 37733 * when the the browser exits. 37734 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). 37735 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). 37736 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will 37737 * require a secure protocol (like HTTPS). 37738 * @type undefined 37739 * 37740 * @name $.cookie 37741 * @cat Plugins/Cookie 37742 * @author Klaus Hartl/[email protected] 37743 */ 37744 37745/** 37746 * Get the value of a cookie with the given name. 37747 * 37748 * @example $.cookie('the_cookie'); 37749 * @desc Get the value of a cookie. 37750 * 37751 * @param String name The name of the cookie. 37752 * @return The value of the cookie. 37753 * @type String 37754 * 37755 * @name $.cookie 37756 * @cat Plugins/Cookie 37757 * @author Klaus Hartl/[email protected] 37758 */ 37759jQuery.cookie = function(name, value, options) { 37760 if (typeof value != 'undefined') { // name and value given, set cookie 37761 options = options || {}; 37762 if (value === null) { 37763 value = ''; 37764 options.expires = -1; 37765 } 37766 var expires = ''; 37767 if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { 37768 var date; 37769 if (typeof options.expires == 'number') { 37770 date = new Date(); 37771 date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); 37772 } else { 37773 date = options.expires; 37774 } 37775 expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE 37776 } 37777 // CAUTION: Needed to parenthesize options.path and options.domain 37778 // in the following expressions, otherwise they evaluate to undefined 37779 // in the packed version for some reason... 37780 var path = options.path ? '; path=' + (options.path) : ''; 37781 var domain = options.domain ? '; domain=' + (options.domain) : ''; 37782 var secure = options.secure ? '; secure' : ''; 37783 document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); 37784 } else { // only name given, get cookie 37785 var cookieValue = null; 37786 if (document.cookie && document.cookie != '') { 37787 var cookies = document.cookie.split(';'); 37788 for (var i = 0; i < cookies.length; i++) { 37789 var cookie = jQuery.trim(cookies[i]); 37790 // Does this cookie string begin with the name we want? 37791 if (cookie.substring(0, name.length + 1) == (name + '=')) { 37792 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 37793 break; 37794 } 37795 } 37796 } 37797 return cookieValue; 37798 } 37799}; 37800/* 37801 * jQuery Hotkeys Plugin 37802 * Copyright 2010, John Resig 37803 * Dual licensed under the MIT or GPL Version 2 licenses. 37804 * 37805 * Based upon the plugin by Tzury Bar Yochay: 37806 * http://github.com/tzuryby/hotkeys 37807 * 37808 * Original idea by: 37809 * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ 37810*/ 37811 37812/* 37813 * One small change is: now keys are passed by object { keys: '...' } 37814 * Might be useful, when you want to pass some other data to your handler 37815 */ 37816 37817(function(jQuery){ 37818 37819 jQuery.hotkeys = { 37820 version: "0.8", 37821 37822 specialKeys: { 37823 8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", 37824 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", 37825 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 59: ";", 61: "=", 37826 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", 37827 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", 37828 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
37829 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 173: "-", 186: ";", 187: "=", 37830 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'" 37831 }, 37832 37833 shiftNums: { 37834 "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", 37835 "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", 37836 ".": ">", "/": "?", "\\": "|" 37837 } 37838 }; 37839 37840 function keyHandler( handleObj ) { 37841 if ( typeof handleObj.data === "string" ) { 37842 handleObj.data = { keys: handleObj.data }; 37843 } 37844 37845 // Only care when a possible input has been specified 37846 if ( !handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string" ) { 37847 return; 37848 } 37849 37850 var origHandler = handleObj.handler, 37851 keys = handleObj.data.keys.toLowerCase().split(" "), 37852 textAcceptingInputTypes = ["text", "password", "number", "email", "url", "range", "date", "month", "week", 37853 "time", "datetime", "datetime-local", "search", "color", "tel"]; 37854 37855 handleObj.handler = function( event ) { 37856 // Don't fire in text-accepting inputs that we didn't directly bind to 37857 if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) || 37858 jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1 ) ) { 37859 return; 37860 } 37861 37862 var special = jQuery.hotkeys.specialKeys[ event.keyCode ], 37863 character = String.fromCharCode( event.which ).toLowerCase(), 37864 modif = "", possible = {}; 37865 37866 jQuery.each([ "alt", "ctrl", "meta", "shift" ], function(index, specialKey) { 37867 if (event[specialKey + 'Key'] && special !== specialKey) { 37868 modif += specialKey + '+'; 37869 } 37870 }); 37871 37872 37873 modif = modif.replace('alt+ctrl+meta+shift', 'hyper'); 37874 37875 if ( special ) { 37876 possible[ modif + special ] = true; 37877 } 37878 37879 if ( character ) { 37880 possible[ modif + character ] = true; 37881 possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true; 37882 37883 // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" 37884 if ( modif === "shift+" ) { 37885 possible[ jQuery.hotkeys.shiftNums[ character ] ] = true; 37886 } 37887 } 37888 37889 for ( var i = 0, l = keys.length; i < l; i++ ) { 37890 if ( possible[ keys[i] ] ) { 37891 return origHandler.apply( this, arguments ); 37892 } 37893 } 37894 }; 37895 } 37896 37897 jQuery.each([ "keydown", "keyup", "keypress" ], function() { 37898 jQuery.event.special[ this ] = { add: keyHandler }; 37899 }); 37900 37901})( this.jQuery ); 37902/* 37903 * jsTree 1.0-rc1 37904 * http://jstree.com/ 37905 * 37906 * Copyright (c) 2010 Ivan Bozhanov (vakata.com) 37907 * 37908 * Dual licensed under the MIT and GPL licenses (same as jQuery): 37909 * http://www.opensource.org/licenses/mit-license.php 37910 * http://www.gnu.org/licenses/gpl.html 37911 * 37912 * $Date: 2010-07-01 10:51:11 +0300 (ÑеÑв, 01 Ñли 2010) $ 37913 * $Revision: 191 $ 37914 */ 37915 37916/*jslint browser: true, onevar: true, undef: true, bitwise: true, strict: true */ 37917/*global window : false, clearInterval: false, clearTimeout: false, document: false, setInterval: false, setTimeout: false, jQuery: false, navigator: false, XSLTProcessor: false, DOMParser: false, XMLSerializer: false*/ 37918 37919"use strict"; 37920// Common functions not related to jsTree 37921// decided to move them to a `vakata` "namespace" 37922(function ($) { 37923 $.vakata = {}; 37924 // CSS related functions 37925 $.vakata.css = { 37926 get_css : function(rule_name, delete_flag, sheet) { 37927 rule_name = rule_name.toLowerCase(); 37928 var css_rules = sheet.cssRules || sheet.rules, 37929 j = 0; 37930 do { 37931 if(css_rules.length && j > css_rules.length + 5) { return false; } 37932 if(css_rules[j].selectorText && css_rules[j].selectorText.toLowerCase() == rule_name) { 37933 if(delete_flag === true) { 37934 if(sheet.removeRule) { sheet.removeRule(j); } 37935 if(sheet.deleteRule) { sheet.deleteRule(j); } 37936 return true; 37937 } 37938 else { return css_rules[j]; } 37939 } 37940 } 37941 while (css_rules[++j]); 37942 return false; 37943 }, 37944 add_css : function(rule_name, sheet) { 37945 if($.jstree.css.get_css(rule_name, false, sheet)) { return false; } 37946 if(sheet.insertRule) { sheet.insertRule(rule_name + ' { }', 0); } else { sheet.addRule(rule_name, null, 0); } 37947 return $.vakata.css.get_css(rule_name); 37948 }, 37949 remove_css : function(rule_name, sheet) { 37950 return $.vakata.css.get_css(rule_name, true, sheet); 37951 }, 37952 add_sheet : function(opts) { 37953 var tmp; 37954 if(opts.str) { 37955 tmp = document.createElement("style"); 37956 tmp.setAttribute('type',"text/css"); 37957 if(tmp.styleSheet) { 37958 document.getElementsByTagName("head")[0].appendChild(tmp); 37959 tmp.styleSheet.cssText = opts.str; 37960 } 37961 else { 37962 tmp.appendChild(document.createTextNode(opts.str)); 37963 document.getElementsByTagName("head")[0].appendChild(tmp); 37964 } 37965 return tmp.sheet || tmp.styleSheet; 37966 } 37967 if(opts.url) { 37968 if(document.createStyleSheet) { 37969 try { tmp = document.createStyleSheet(opts.url); } catch (e) { } 37970 } 37971 else { 37972 tmp = document.createElement('link'); 37973 tmp.rel = 'stylesheet'; 37974 tmp.type = 'text/css'; 37975 tmp.media = "all"; 37976 tmp.href = opts.url; 37977 document.getElementsByTagName("head")[0].appendChild(tmp); 37978 return tmp.styleSheet; 37979 } 37980 } 37981 } 37982 }; 37983})(jQuery); 37984 37985/* 37986 * jsTree core 1.0 37987 */ 37988(function ($) { 37989 // private variables
37990 var instances = [], // instance array (used by $.jstree.reference/create/focused) 37991 focused_instance = -1, // the index in the instance array of the currently focused instance 37992 plugins = {}, // list of included plugins 37993 prepared_move = {}, // for the move plugin 37994 is_ie6 = false; 37995 37996 // jQuery plugin wrapper (thanks to jquery UI widget function) 37997 $.fn.jstree = function (settings) { 37998 var isMethodCall = (typeof settings == 'string'), // is this a method call like $().jstree("open_node") 37999 args = Array.prototype.slice.call(arguments, 1), 38000 returnValue = this; 38001 38002 // extend settings and allow for multiple hashes and metadata 38003 if(!isMethodCall && $.meta) { args.push($.metadata.get(this).jstree); } 38004 settings = !isMethodCall && args.length ? $.extend.apply(null, [true, settings].concat(args)) : settings; 38005 // block calls to "private" methods 38006 if(isMethodCall && settings.substring(0, 1) == '_') { return returnValue; } 38007 38008 // if a method call execute the method on all selected instances 38009 if(isMethodCall) { 38010 this.each(function() { 38011 var instance = instances[$.data(this, "jstree-instance-id")], 38012 methodValue = (instance && $.isFunction(instance[settings])) ? instance[settings].apply(instance, args) : instance; 38013 if(typeof methodValue !== "undefined" && (settings.indexOf("is_" === 0) || (methodValue !== true && methodValue !== false))) { returnValue = methodValue; return false; } 38014 }); 38015 } 38016 else { 38017 this.each(function() { 38018 var instance_id = $.data(this, "jstree-instance-id"), 38019 s = false; 38020 // if an instance already exists, destroy it first 38021 if(typeof instance_id !== "undefined" && instances[instance_id]) { instances[instance_id].destroy(); } 38022 // push a new empty object to the instances array 38023 instance_id = parseInt(instances.push({}),10) - 1; 38024 // store the jstree instance id to the container element 38025 $.data(this, "jstree-instance-id", instance_id); 38026 // clean up all plugins 38027 if(!settings) { settings = {}; } 38028 settings.plugins = $.isArray(settings.plugins) ? settings.plugins : $.jstree.defaults.plugins; 38029 if($.inArray("core", settings.plugins) === -1) { settings.plugins.unshift("core"); } 38030 38031 // only unique plugins (NOT WORKING) 38032 // settings.plugins = settings.plugins.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(","); 38033 38034 // extend defaults with passed data 38035 s = $.extend(true, {}, $.jstree.defaults, settings); 38036 s.plugins = settings.plugins; 38037 $.each(plugins, function (i, val) { if($.inArray(i, s.plugins) === -1) { s[i] = null; delete s[i]; } }); 38038 // push the new object to the instances array (at the same time set the default classes to the container) and init 38039 instances[instance_id] = new $.jstree._instance(instance_id, $(this).addClass("jstree jstree-" + instance_id), s); 38040 // init all activated plugins for this instance 38041 $.each(instances[instance_id]._get_settings().plugins, function (i, val) { instances[instance_id].data[val] = {}; }); 38042 $.each(instances[instance_id]._get_settings().plugins, function (i, val) { if(plugins[val]) { plugins[val].__init.apply(instances[instance_id]); } }); 38043 // initialize the instance 38044 instances[instance_id].init(); 38045 }); 38046 } 38047 // return the jquery selection (or if it was a method call that returned a value - the returned value) 38048 return returnValue; 38049 }; 38050 // object to store exposed functions and objects 38051 $.jstree = { 38052 defaults : { 38053 plugins : [] 38054 }, 38055 _focused : function () { return instances[focused_instance] || null; }, 38056 _reference : function (needle) { 38057 // get by instance id 38058 if(instances[needle]) { return instances[needle]; } 38059 // get by DOM (if still no luck - return null 38060 var o = $(needle); 38061 if(!o.length && typeof needle === "string") { o = $("#" + needle); } 38062 if(!o.length) { return null; } 38063 return instances[o.closest(".jstree").data("jstree-instance-id")] || null; 38064 }, 38065 _instance : function (index, container, settings) { 38066 // for plugins to store data in 38067 this.data = { core : {} }; 38068 this.get_settings = function () { return $.extend(true, {}, settings); }; 38069 this._get_settings = function () { return settings; }; 38070 this.get_index = function () { return index; }; 38071 this.get_container = function () { return container; }; 38072 this._set_settings = function (s) { 38073 settings = $.extend(true, {}, settings, s); 38074 }; 38075 }, 38076 _fn : { }, 38077 plugin : function (pname, pdata) { 38078 pdata = $.extend({}, { 38079 __init : $.noop, 38080 __destroy : $.noop, 38081 _fn : {}, 38082 defaults : false 38083 }, pdata); 38084 plugins[pname] = pdata; 38085 38086 $.jstree.defaults[pname] = pdata.defaults; 38087 $.each(pdata._fn, function (i, val) { 38088 val.plugin = pname; 38089 val.old = $.jstree._fn[i];
38090 $.jstree._fn[i] = function () { 38091 var rslt, 38092 func = val, 38093 args = Array.prototype.slice.call(arguments), 38094 evnt = new $.Event("before.jstree"), 38095 rlbk = false; 38096 38097 // Check if function belongs to the included plugins of this instance 38098 do { 38099 if(func && func.plugin && $.inArray(func.plugin, this._get_settings().plugins) !== -1) { break; } 38100 func = func.old; 38101 } while(func); 38102 if(!func) { return; } 38103 38104 // a chance to stop execution (or change arguments): 38105 // * just bind to jstree.before 38106 // * check the additional data object (func property) 38107 // * call event.stopImmediatePropagation() 38108 // * return false (or an array of arguments) 38109 rslt = this.get_container().triggerHandler(evnt, { "func" : i, "inst" : this, "args" : args }); 38110 if(rslt === false) { return; } 38111 if(typeof rslt !== "undefined") { args = rslt; } 38112 38113 // context and function to trigger events, then finally call the function 38114 if(i.indexOf("_") === 0) { 38115 rslt = func.apply(this, args); 38116 } 38117 else { 38118 rslt = func.apply( 38119 $.extend({}, this, { 38120 __callback : function (data) { 38121 this.get_container().triggerHandler( i + '.jstree', { "inst" : this, "args" : args, "rslt" : data, "rlbk" : rlbk }); 38122 }, 38123 __rollback : function () { 38124 rlbk = this.get_rollback(); 38125 return rlbk; 38126 }, 38127 __call_old : function (replace_arguments) { 38128 return func.old.apply(this, (replace_arguments ? Array.prototype.slice.call(arguments, 1) : args ) ); 38129 } 38130 }), args); 38131 } 38132 38133 // return the result 38134 return rslt; 38135 }; 38136 $.jstree._fn[i].old = val.old; 38137 $.jstree._fn[i].plugin = pname; 38138 }); 38139 }, 38140 rollback : function (rb) { 38141 if(rb) { 38142 if(!$.isArray(rb)) { rb = [ rb ]; } 38143 $.each(rb, function (i, val) { 38144 instances[val.i].set_rollback(val.h, val.d); 38145 }); 38146 } 38147 } 38148 }; 38149 // set the prototype for all instances 38150 $.jstree._fn = $.jstree._instance.prototype = {}; 38151 38152 // css functions - used internally 38153 38154 // load the css when DOM is ready 38155 $(function() { 38156 // code is copied form jQuery ($.browser is deprecated + there is a bug in IE) 38157 var u = navigator.userAgent.toLowerCase(), 38158 v = (u.match( /.+?(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1], 38159 css_string = '' + 38160 '.jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } ' + 38161 '.jstree li { display:block; min-height:18px; line-height:18px; white-space:nowrap; margin-left:18px; } ' + 38162 '.jstree-rtl li { margin-left:0; margin-right:18px; } ' + 38163 '.jstree > ul > li { margin-left:0px; /* color:black !important; */} ' + 38164 '.jstree-rtl > ul > li { margin-right:0px; } ' + 38165 '.jstree ins { display:inline-block; text-decoration:none; width:18px; height:18px; margin:0 0 0 0; padding:0; } ' + 38166 '.jstree a { display:inline-block; line-height:16px; height:16px; /* color: black;*/ white-space:nowrap; text-decoration:none; padding:1px 2px; margin:0; } ' + 38167 '.jstree a:focus { outline: none; } ' + 38168 '.jstree a > ins { height:16px; width:16px; } ' + 38169 '.jstree a > .jstree-icon { margin-right:3px; } ' + 38170 '.jstree-rtl a > .jstree-icon { margin-left:3px; margin-right:0; } ' + 38171 'li.jstree-open > ul { display:block; } ' + 38172 'li.jstree-closed > ul { display:none; } '; 38173 // Correct IE 6 (does not support the > CSS selector) 38174 if(/msie/.test(u) && parseInt(v, 10) == 6) { 38175 is_ie6 = true; 38176 css_string += '' + 38177 '.jstree li { height:18px; margin-left:0; margin-right:0; } ' + 38178 '.jstree li li { margin-left:18px; } ' + 38179 '.jstree-rtl li li { margin-left:0px; margin-right:18px; } ' + 38180 'li.jstree-open ul { display:block; } ' + 38181 'li.jstree-closed ul { display:none !important; } ' + 38182 '.jstree li a { display:inline; border-width:0 !important; padding:0px 2px !important; } ' + 38183 '.jstree li a ins { height:16px; width:16px; margin-right:3px; } ' + 38184 '.jstree-rtl li a ins { margin-right:0px; margin-left:3px; } '; 38185 } 38186 // Correct IE 7 (shifts anchor nodes onhover) 38187 if(/msie/.test(u) && parseInt(v, 10) == 7) { 38188 css_string += '.jstree li a { border-width:0 !important; padding:0px 2px !important; } '; 38189 } 38190 $.vakata.css.add_sheet({ str : css_string });
38191 }); 38192 38193 // core functions (open, close, create, update, delete) 38194 $.jstree.plugin("core", { 38195 __init : function () { 38196 this.data.core.to_open = $.map($.makeArray(this.get_settings().core.initially_open), function (n) { return "#" + n.toString().replace(/^#/,"").replace('\\/','/').replace('/','\\/'); }); 38197 }, 38198 defaults : { 38199 html_titles : false, 38200 animation : 500, 38201 initially_open : [], 38202 rtl : false, 38203 strings : { 38204 loading : "Loading ...", 38205 new_node : "New node" 38206 } 38207 }, 38208 _fn : { 38209 init : function () { 38210 this.set_focus(); 38211 if(this._get_settings().core.rtl) { 38212 this.get_container().addClass("jstree-rtl").css("direction", "rtl"); 38213 } 38214 this.get_container().html("<ul><li class='jstree-last jstree-leaf'><ins> </ins><a class='jstree-loading' href='#'><ins class='jstree-icon'> </ins>" + this._get_settings().core.strings.loading + "</a></li></ul>"); 38215 this.data.core.li_height = this.get_container().find("ul li.jstree-closed, ul li.jstree-leaf").eq(0).height() || 18; 38216 38217 this.get_container() 38218 .delegate("li > ins", "click.jstree", $.proxy(function (event) { 38219 var trgt = $(event.target); 38220 if(trgt.is("ins") && event.pageY - trgt.offset().top < this.data.core.li_height) { this.toggle_node(trgt); } 38221 }, this)) 38222 .bind("mousedown.jstree", $.proxy(function () { 38223 this.set_focus(); // This used to be setTimeout(set_focus,0) - why? 38224 }, this)) 38225 .bind("dblclick.jstree", function (event) { 38226 var sel; 38227 if(document.selection && document.selection.empty) { document.selection.empty(); } 38228 else { 38229 if(window.getSelection) { 38230 sel = window.getSelection(); 38231 try { 38232 sel.removeAllRanges(); 38233 sel.collapse(); 38234 } catch (err) { } 38235 } 38236 } 38237 }); 38238 this.__callback(); 38239 this.load_node(-1, function () { this.loaded(); this.reopen(); }); 38240 }, 38241 destroy : function () { 38242 var i, 38243 n = this.get_index(), 38244 s = this._get_settings(), 38245 _this = this; 38246 38247 $.each(s.plugins, function (i, val) { 38248 try { plugins[val].__destroy.apply(_this); } catch(err) { } 38249 }); 38250 this.__callback(); 38251 // set focus to another instance if this one is focused 38252 if(this.is_focused()) { 38253 for(i in instances) { 38254 if(instances.hasOwnProperty(i) && i != n) { 38255 instances[i].set_focus(); 38256 break; 38257 } 38258 } 38259 } 38260 // if no other instance found 38261 if(n === focused_instance) { focused_instance = -1; } 38262 // remove all traces of jstree in the DOM (only the ones set using jstree*) and cleans all events 38263 this.get_container() 38264 .unbind(".jstree") 38265 .undelegate(".jstree") 38266 .removeData("jstree-instance-id") 38267 .find("[class^='jstree']") 38268 .andSelf() 38269 .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); 38270 // remove the actual data 38271 instances[n] = null; 38272 delete instances[n]; 38273 }, 38274 save_opened : function () { 38275 var _this = this; 38276 this.data.core.to_open = []; 38277 this.get_container().find(".jstree-open").each(function () { 38278 _this.data.core.to_open.push("#" + this.id.toString().replace(/^#/,"").replace('\\/','/').replace('/','\\/')); 38279 }); 38280 this.__callback(_this.data.core.to_open); 38281 }, 38282 reopen : function (is_callback) { 38283 var _this = this, 38284 done = true, 38285 current = [], 38286 remaining = []; 38287 if(!is_callback) { this.data.core.reopen = false; this.data.core.refreshing = true; } 38288 if(this.data.core.to_open.length) { 38289 $.each(this.data.core.to_open, function (i, val) { 38290 if(val == "#") { return true; } 38291 if($(val).length && $(val).is(".jstree-closed")) { current.push(val); } 38292 else { remaining.push(val); } 38293 }); 38294 if(current.length) { 38295 this.data.core.to_open = remaining; 38296 $.each(current, function (i, val) { 38297 _this.open_node(val, function () { _this.reopen(true); }, true); 38298 }); 38299 done = false; 38300 } 38301 } 38302 if(done) {
38303 // TODO: find a more elegant approach to syncronizing returning requests 38304 if(this.data.core.reopen) { clearTimeout(this.data.core.reopen); } 38305 this.data.core.reopen = setTimeout(function () { _this.__callback({}, _this); }, 50); 38306 this.data.core.refreshing = false; 38307 } 38308 }, 38309 refresh : function (obj) { 38310 var _this = this; 38311 this.save_opened(); 38312 if(!obj) { obj = -1; } 38313 obj = this._get_node(obj); 38314 if(!obj) { obj = -1; } 38315 if(obj !== -1) { obj.children("UL").remove(); } 38316 this.load_node(obj, function () { _this.__callback({ "obj" : obj}); _this.reopen(); }); 38317 }, 38318 // Dummy function to fire after the first load (so that there is a jstree.loaded event) 38319 loaded : function () { 38320 this.__callback(); 38321 }, 38322 // deal with focus 38323 set_focus : function () { 38324 var f = $.jstree._focused(); 38325 if(f && f !== this) { 38326 f.get_container().removeClass("jstree-focused"); 38327 } 38328 if(f !== this) { 38329 this.get_container().addClass("jstree-focused"); 38330 focused_instance = this.get_index(); 38331 } 38332 this.__callback(); 38333 }, 38334 is_focused : function () { 38335 return focused_instance == this.get_index(); 38336 }, 38337 38338 // traverse 38339 _get_node : function (obj) { 38340 var $obj = $(obj, this.get_container()); 38341 if($obj.is(".jstree") || obj == -1) { return -1; } 38342 $obj = $obj.closest("li", this.get_container()); 38343 return $obj.length ? $obj : false; 38344 }, 38345 _get_next : function (obj, strict) { 38346 obj = this._get_node(obj); 38347 if(obj === -1) { return this.get_container().find("> ul > li:first-child"); } 38348 if(!obj.length) { return false; } 38349 if(strict) { return (obj.nextAll("li").size() > 0) ? obj.nextAll("li:eq(0)") : false; } 38350 38351 if(obj.hasClass("jstree-open")) { return obj.find("li:eq(0)"); } 38352 else if(obj.nextAll("li").size() > 0) { return obj.nextAll("li:eq(0)"); } 38353 else { return obj.parentsUntil(".jstree","li").next("li").eq(0); } 38354 }, 38355 _get_prev : function (obj, strict) { 38356 obj = this._get_node(obj); 38357 if(obj === -1) { return this.get_container().find("> ul > li:last-child"); } 38358 if(!obj.length) { return false; } 38359 if(strict) { return (obj.prevAll("li").length > 0) ? obj.prevAll("li:eq(0)") : false; } 38360 38361 if(obj.prev("li").length) { 38362 obj = obj.prev("li").eq(0); 38363 while(obj.hasClass("jstree-open")) { obj = obj.children("ul:eq(0)").children("li:last"); } 38364 return obj; 38365 } 38366 else { var o = obj.parentsUntil(".jstree","li:eq(0)"); return o.length ? o : false; } 38367 }, 38368 _get_parent : function (obj) { 38369 obj = this._get_node(obj); 38370 if(obj == -1 || !obj.length) { return false; } 38371 var o = obj.parentsUntil(".jstree", "li:eq(0)"); 38372 return o.length ? o : -1; 38373 }, 38374 _get_children : function (obj) { 38375 obj = this._get_node(obj); 38376 if(obj === -1) { return this.get_container().children("ul:eq(0)").children("li"); } 38377 if(!obj.length) { return false; } 38378 return obj.children("ul:eq(0)").children("li"); 38379 }, 38380 get_path : function (obj, id_mode) { 38381 var p = [], 38382 _this = this; 38383 obj = this._get_node(obj); 38384 if(obj === -1 || !obj || !obj.length) { return false; } 38385 obj.parentsUntil(".jstree", "li").each(function () { 38386 p.push( id_mode ? this.id : _this.get_text(this) ); 38387 }); 38388 p.reverse(); 38389 p.push( id_mode ? obj.attr("id") : this.get_text(obj) ); 38390 return p; 38391 }, 38392 38393 is_open : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-open"); }, 38394 is_closed : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-closed"); }, 38395 is_leaf : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-leaf"); }, 38396 // open/close 38397 open_node : function (obj, callback, skip_animation) { 38398 obj = this._get_node(obj); 38399 if(!obj.length) { return false; } 38400 if(!obj.hasClass("jstree-closed")) { if(callback) { callback.call(); } return false; } 38401 var s = skip_animation || is_ie6 ? 0 : this._get_settings().core.animation, 38402 t = this; 38403 if(!this._is_loaded(obj)) { 38404 // obj.children("a").addClass("jstree-loading"); 38405 obj.children("ins").addClass("jstree-loading"); 38406 this.load_node(obj, function () { t.open_node(obj, callback, skip_animation); }, callback); 38407 } 38408 else { 38409 if(s) { obj.children("ul").css("display","none"); } 38410 obj.removeClass("jstree-closed").addClass("jstree-open").children("a").removeClass("jstree-loading"); 38411 if(s) { obj.children("ul").stop(true).slideDown(s, function () { this.style.display = ""; }); } 38412 this.__callback({ "obj" : obj }); 38413 if(callback) { callback.call(); } 38414 } 38415 }, 38416 close_node : function (obj, skip_animation) { 38417 obj = this._get_node(obj); 38418 var s = skip_animation || is_ie6 ? 0 : this._get_settings().core.animation; 38419 if(!obj.length || !obj.hasClass("jstree-open")) { return false; } 38420 if(s) { obj.children("ul").attr("style","display:block !important"); } 38421 obj.removeClass("jstree-open").addClass("jstree-closed");
38422 if(s) { obj.children("ul").stop(true).slideUp(s, function () { this.style.display = ""; }); } 38423 this.__callback({ "obj" : obj }); 38424 }, 38425 toggle_node : function (obj) { 38426 obj = this._get_node(obj); 38427 if(obj.hasClass("jstree-closed")) { return this.open_node(obj); } 38428 if(obj.hasClass("jstree-open")) { return this.close_node(obj); } 38429 }, 38430 open_all : function (obj, original_obj) { 38431 obj = obj ? this._get_node(obj) : this.get_container(); 38432 if(!obj || obj === -1) { obj = this.get_container(); } 38433 if(original_obj) { 38434 obj = obj.find("li.jstree-closed"); 38435 } 38436 else { 38437 original_obj = obj; 38438 if(obj.is(".jstree-closed")) { obj = obj.find("li.jstree-closed").andSelf(); } 38439 else { obj = obj.find("li.jstree-closed"); } 38440 } 38441 var _this = this; 38442 obj.each(function () { 38443 var __this = this; 38444 if(!_this._is_loaded(this)) { _this.open_node(this, function() { _this.open_all(__this, original_obj); }, true); } 38445 else { _this.open_node(this, false, true); } 38446 }); 38447 // so that callback is fired AFTER all nodes are open 38448 if(original_obj.find('li.jstree-closed').length === 0) { this.__callback({ "obj" : original_obj }); } 38449 }, 38450 close_all : function (obj) { 38451 var _this = this; 38452 obj = obj ? this._get_node(obj) : this.get_container(); 38453 if(!obj || obj === -1) { obj = this.get_container(); } 38454 obj.find("li.jstree-open").andSelf().each(function () { _this.close_node(this); }); 38455 this.__callback({ "obj" : obj }); 38456 }, 38457 clean_node : function (obj) { 38458 obj = obj && obj != -1 ? $(obj) : this.get_container(); 38459 obj = obj.is("li") ? obj.find("li").andSelf() : obj.find("li"); 38460 obj.removeClass("jstree-last") 38461 .filter("li:last-child").addClass("jstree-last").end() 38462 .filter(":has(li)") 38463 .not(".jstree-open").removeClass("jstree-leaf").addClass("jstree-closed"); 38464 obj.not(".jstree-open, .jstree-closed").addClass("jstree-leaf").children("ul").remove(); 38465 this.__callback({ "obj" : obj }); 38466 }, 38467 // rollback 38468 get_rollback : function () { 38469 this.__callback(); 38470 return { i : this.get_index(), h : this.get_container().children("ul").clone(true), d : this.data }; 38471 }, 38472 set_rollback : function (html, data) { 38473 this.get_container().empty().append(html); 38474 this.data = data; 38475 this.__callback(); 38476 }, 38477 // Dummy functions to be overwritten by any datastore plugin included 38478 load_node : function (obj, s_call, e_call) { this.__callback({ "obj" : obj }); }, 38479 _is_loaded : function (obj) { return true; }, 38480 38481 // Basic operations: create 38482 create_node : function (obj, position, js, callback, is_loaded) { 38483 obj = this._get_node(obj); 38484 position = typeof position === "undefined" ? "last" : position; 38485 var d = $("<li>"), 38486 s = this._get_settings().core, 38487 tmp; 38488 38489 if(obj !== -1 && !obj.length) { return false; } 38490 if(!is_loaded && !this._is_loaded(obj)) { this.load_node(obj, function () { this.create_node(obj, position, js, callback, true); }); return false; } 38491 38492 this.__rollback(); 38493 38494 if(typeof js === "string") { js = { "data" : js }; } 38495 if(!js) { js = {}; } 38496 if(js.attr) { d.attr(js.attr); } 38497 if(js.state) { d.addClass("jstree-" + js.state); } 38498 if(!js.data) { js.data = s.strings.new_node; } 38499 if(!$.isArray(js.data)) { tmp = js.data; js.data = []; js.data.push(tmp); } 38500 $.each(js.data, function (i, m) { 38501 tmp = $("<a>"); 38502 if($.isFunction(m)) { m = m.call(this, js); } 38503 if(typeof m == "string") { tmp.attr('href','#')[ s.html_titles ? "html" : "text" ](m); } 38504 else { 38505 if(!m.attr) { m.attr = {}; } 38506 if(!m.attr.href) { m.attr.href = '#'; } 38507 tmp.attr(m.attr)[ s.html_titles ? "html" : "text" ](m.title); 38508 if(m.language) { tmp.addClass(m.language); } 38509 } 38510 tmp.prepend("<ins class='jstree-icon'> </ins>"); 38511 if(m.icon) { 38512 if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); } 38513 else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); } 38514 } 38515 d.append(tmp); 38516 }); 38517 d.prepend("<ins class='jstree-icon'> </ins>"); 38518 if(obj === -1) { 38519 obj = this.get_container(); 38520 if(position === "before") { position = "first"; } 38521 if(position === "after") { position = "last"; } 38522 } 38523 switch(position) { 38524 case "before": obj.before(d); tmp = this._get_parent(obj); break; 38525 case "after" : obj.after(d); tmp = this._get_parent(obj); break; 38526 case "inside": 38527 case "first" : 38528 if(!obj.children("ul").length) { obj.append("<ul>"); } 38529 obj.children("ul").prepend(d); 38530 tmp = obj;
38531 break; 38532 case "last": 38533 if(!obj.children("ul").length) { obj.append("<ul>"); } 38534 obj.children("ul").append(d); 38535 tmp = obj; 38536 break; 38537 default: 38538 if(!obj.children("ul").length) { obj.append("<ul>"); } 38539 if(!position) { position = 0; } 38540 tmp = obj.children("ul").children("li").eq(position); 38541 if(tmp.length) { tmp.before(d); } 38542 else { obj.children("ul").append(d); } 38543 tmp = obj; 38544 break; 38545 } 38546 if(tmp === -1 || tmp.get(0) === this.get_container().get(0)) { tmp = -1; } 38547 this.clean_node(tmp); 38548 this.__callback({ "obj" : d, "parent" : tmp }); 38549 if(callback) { callback.call(this, d); } 38550 return d; 38551 }, 38552 // Basic operations: rename (deal with text) 38553 get_text : function (obj) { 38554 obj = this._get_node(obj); 38555 if(!obj.length) { return false; } 38556 var s = this._get_settings().core.html_titles; 38557 obj = obj.children("a:eq(0)"); 38558 if(s) { 38559 obj = obj.clone(); 38560 obj.children("INS").remove(); 38561 return obj.html(); 38562 } 38563 else { 38564 obj = obj.contents().filter(function() { return this.nodeType == 3; })[0]; 38565 return obj.nodeValue; 38566 } 38567 }, 38568 set_text : function (obj, val) { 38569 obj = this._get_node(obj); 38570 if(!obj.length) { return false; } 38571 obj = obj.children("a:eq(0)"); 38572 if(this._get_settings().core.html_titles) { 38573 var tmp = obj.children("INS").clone(); 38574 obj.html(val).prepend(tmp); 38575 this.__callback({ "obj" : obj, "name" : val }); 38576 return true; 38577 } 38578 else { 38579 obj = obj.contents().filter(function() { return this.nodeType == 3; })[0]; 38580 this.__callback({ "obj" : obj, "name" : val }); 38581 return (obj.nodeValue = val); 38582 } 38583 }, 38584 rename_node : function (obj, val) { 38585 obj = this._get_node(obj); 38586 this.__rollback(); 38587 if(obj && obj.length && this.set_text.apply(this, Array.prototype.slice.call(arguments))) { this.__callback({ "obj" : obj, "name" : val }); } 38588 }, 38589 // Basic operations: deleting nodes 38590 delete_node : function (obj) { 38591 obj = this._get_node(obj); 38592 if(!obj.length) { return false; } 38593 this.__rollback(); 38594 var p = this._get_parent(obj), prev = this._get_prev(obj); 38595 obj = obj.remove(); 38596 if(p !== -1 && p.find("> ul > li").length === 0) { 38597 p.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); 38598 } 38599 this.clean_node(p); 38600 this.__callback({ "obj" : obj, "prev" : prev }); 38601 return obj; 38602 }, 38603 prepare_move : function (o, r, pos, cb, is_cb) { 38604 var p = {}; 38605 38606 p.ot = $.jstree._reference(p.o) || this; 38607 p.o = p.ot._get_node(o); 38608 p.r = r === - 1 ? -1 : this._get_node(r); 38609 p.p = (typeof p === "undefined") ? "last" : pos; // TODO: move to a setting 38610 if(!is_cb && prepared_move.o && prepared_move.o[0] === p.o[0] && prepared_move.r[0] === p.r[0] && prepared_move.p === p.p) { 38611 this.__callback(prepared_move); 38612 if(cb) { cb.call(this, prepared_move); } 38613 return; 38614 } 38615 p.ot = $.jstree._reference(p.o) || this; 38616 p.rt = r === -1 ? p.ot : $.jstree._reference(p.r) || this; 38617 if(p.r === -1) { 38618 p.cr = -1; 38619 switch(p.p) { 38620 case "first": 38621 case "before": 38622 case "inside": 38623 p.cp = 0; 38624 break; 38625 case "after": 38626 case "last": 38627 p.cp = p.rt.get_container().find(" > ul > li").length; 38628 break; 38629 default: 38630 p.cp = p.p; 38631 break; 38632 } 38633 } 38634 else { 38635 if(!/^(before|after)$/.test(p.p) && !this._is_loaded(p.r)) { 38636 return this.load_node(p.r, function () { this.prepare_move(o, r, pos, cb, true); }); 38637 } 38638 switch(p.p) { 38639 case "before": 38640 p.cp = p.r.index(); 38641 p.cr = p.rt._get_parent(p.r); 38642 break; 38643 case "after": 38644 p.cp = p.r.index() + 1; 38645 p.cr = p.rt._get_parent(p.r); 38646 break; 38647 case "inside": 38648 case "first": 38649 p.cp = 0; 38650 p.cr = p.r; 38651 break; 38652 case "last": 38653 p.cp = p.r.find(" > ul > li").length; 38654 p.cr = p.r; 38655 break; 38656 default: 38657 p.cp = p.p; 38658 p.cr = p.r; 38659 break; 38660 } 38661 } 38662 p.np = p.cr == -1 ? p.rt.get_container() : p.cr; 38663 p.op = p.ot._get_parent(p.o); 38664 p.or = p.np.find(" > ul > li:nth-child(" + (p.cp + 1) + ")"); 38665 38666 prepared_move = p; 38667 this.__callback(prepared_move); 38668 if(cb) { cb.call(this, prepared_move); } 38669 }, 38670 check_move : function () { 38671 var obj = prepared_move, ret = true; 38672 if(obj.or[0] === obj.o[0]) { return false; } 38673 obj.o.each(function () { 38674 if(obj.r.parentsUntil(".jstree").andSelf().filter("li").index(this) !== -1) { ret = false; return false; } 38675 }); 38676 return ret; 38677 }, 38678 move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) { 38679 if(!is_prepared) { 38680 return this.prepare_move(obj, ref, position, function (p) { 38681 this.move_node(p, false, false, is_copy, true, skip_check); 38682 });
38683 } 38684 if(!skip_check && !this.check_move()) { return false; } 38685 38686 this.__rollback(); 38687 var o = false; 38688 if(is_copy) { 38689 o = obj.o.clone(); 38690 o.find("*[id]").andSelf().each(function () { 38691 if(this.id) { this.id = "copy_" + this.id; } 38692 }); 38693 } 38694 else { o = obj.o; } 38695 38696 if(obj.or.length) { obj.or.before(o); } 38697 else { 38698 if(!obj.np.children("ul").length) { $("<ul>").appendTo(obj.np); } 38699 obj.np.children("ul:eq(0)").append(o); 38700 } 38701 38702 try { 38703 obj.ot.clean_node(obj.op); 38704 obj.rt.clean_node(obj.np); 38705 if(!obj.op.find("> ul > li").length) { 38706 obj.op.removeClass("jstree-open jstree-closed").addClass("jstree-leaf").children("ul").remove(); 38707 } 38708 } catch (e) { } 38709 38710 if(is_copy) { 38711 prepared_move.cy = true; 38712 prepared_move.oc = o; 38713 } 38714 this.__callback(prepared_move); 38715 return prepared_move; 38716 }, 38717 _get_move : function () { return prepared_move; } 38718 } 38719 }); 38720})(jQuery); 38721//*/ 38722 38723/* 38724 * jsTree ui plugin 1.0 38725 * This plugins handles selecting/deselecting/hovering/dehovering nodes 38726 */ 38727(function ($) { 38728 $.jstree.plugin("ui", { 38729 __init : function () { 38730 this.data.ui.selected = $(); 38731 this.data.ui.last_selected = false; 38732 this.data.ui.hovered = null; 38733 this.data.ui.to_select = this.get_settings().ui.initially_select; 38734 38735 this.get_container() 38736 .delegate("a", "click.jstree", $.proxy(function (event) { 38737 // SENAD: don't trigger select node on checkbox 38738 if (!$(event.target).hasClass('jstree-checkbox')) 38739 { 38740 event.preventDefault(); 38741 this.select_node(event.currentTarget, true, event); 38742 } 38743 }, this)) 38744 .delegate("a", "mouseenter.jstree", $.proxy(function (event) { 38745 this.hover_node(event.target); 38746 }, this)) 38747 .delegate("a", "mouseleave.jstree", $.proxy(function (event) { 38748 this.dehover_node(event.target); 38749 }, this)) 38750 .bind("reopen.jstree", $.proxy(function () { 38751 this.reselect(); 38752 }, this)) 38753 .bind("get_rollback.jstree", $.proxy(function () { 38754 this.dehover_node(); 38755 this.save_selected(); 38756 }, this)) 38757 .bind("set_rollback.jstree", $.proxy(function () { 38758 this.reselect(); 38759 }, this)) 38760 .bind("close_node.jstree", $.proxy(function (event, data) { 38761 var s = this._get_settings().ui, 38762 obj = this._get_node(data.rslt.obj), 38763 clk = (obj && obj.length) ? obj.children("ul").find(".jstree-clicked") : $(), 38764 _this = this; 38765 if(s.selected_parent_close === false || !clk.length) { return; } 38766 clk.each(function () { 38767 _this.deselect_node(this); 38768 if(s.selected_parent_close === "select_parent") { _this.select_node(obj); } 38769 }); 38770 }, this)) 38771 .bind("delete_node.jstree", $.proxy(function (event, data) { 38772 var s = this._get_settings().ui.select_prev_on_delete, 38773 obj = this._get_node(data.rslt.obj), 38774 clk = (obj && obj.length) ? obj.find(".jstree-clicked") : [], 38775 _this = this; 38776 clk.each(function () { _this.deselect_node(this); }); 38777 if(s && clk.length) { this.select_node(data.rslt.prev); } 38778 }, this)) 38779 .bind("move_node.jstree", $.proxy(function (event, data) { 38780 if(data.rslt.cy) { 38781 data.rslt.oc.find(".jstree-clicked").removeClass("jstree-clicked"); 38782 } 38783 }, this)); 38784 }, 38785 defaults : { 38786 select_limit : -1, // 0, 1, 2 ... or -1 for unlimited 38787 select_multiple_modifier : "ctrl", // on, or ctrl, shift, alt 38788 select_range_modifier : "shift", 38789 selected_parent_close : "select_parent", // false, "deselect", "select_parent" 38790 select_prev_on_delete : true, 38791 disable_selecting_children : false, 38792 initially_select : [] 38793 }, 38794 _fn : { 38795 _get_node : function (obj, allow_multiple) { 38796 if(typeof obj === "undefined" || obj === null) { return allow_multiple ? this.data.ui.selected : this.data.ui.last_selected; } 38797 var $obj = $(obj, this.get_container()); 38798 if($obj.is(".jstree") || obj == -1) { return -1; } 38799 $obj = $obj.closest("li", this.get_container()); 38800 return $obj.length ? $obj : false; 38801 }, 38802 save_selected : function () { 38803 var _this = this; 38804 this.data.ui.to_select = []; 38805 this.data.ui.selected.each(function () { _this.data.ui.to_select.push("#" + this.id.toString().replace(/^#/,"").replace('\\/','/').replace('/','\\/')); }); 38806 this.__callback(this.data.ui.to_select); 38807 }, 38808 reselect : function () { 38809 var _this = this, 38810 s = this.data.ui.to_select; 38811 s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace('\\/','/').replace('/','\\/'); }); 38812 this.deselect_all(); 38813 $.each(s, function (i, val) { if(val && val !== "#") { _this.select_node(val); } }); 38814 this.__callback(); 38815 }, 38816 refresh : function (obj) { 38817 this.save_selected(); 38818 return this.__call_old(); 38819 }, 38820 hover_node : function (obj) { 38821 obj = this._get_node(obj); 38822 if(!obj.length) { return false; } 38823 //if(this.data.ui.hovered && obj.get(0) === this.data.ui.hovered.get(0)) { return; } 38824 if(!obj.hasClass("jstree-hovered")) { this.dehover_node(); } 38825 this.data.ui.hovered = obj.children("a").addClass("jstree-hovered").parent(); 38826 this.__callback({ "obj" : obj }); 38827 }, 38828 dehover_node : function () { 38829 var obj = this.data.ui.hovered, p; 38830 if(!obj || !obj.length) { return false; } 38831 p = obj.children("a").removeClass("jstree-hovered").parent(); 38832 if(this.data.ui.hovered[0] === p[0]) { this.data.ui.hovered = null; } 38833 this.__callback({ "obj" : obj }); 38834 }, 38835 select_node : function (obj, check, e) { 38836 obj = this._get_node(obj); 38837 if(obj == -1 || !obj || !obj.length) { return false; } 38838 var s = this._get_settings().ui, 38839 is_multiple = (s.select_multiple_modifier == "on" || (s.select_multiple_modifier !== false && e && e[s.select_multiple_modifier + "Key"])), 38840 is_range = (s.select_range_modifier !== false && e && e[s.select_range_modifier + "Key"] && 38841 this.data.ui.last_selected && this.data.ui.last_selected[0] !== obj[0] && this.data.ui.last_selected.parent()[0] === obj.parent()[0]), 38842 is_selected = this.is_selected(obj), 38843 proceed = true, 38844 t = this; 38845 if(check) { 38846 if(s.disable_selecting_children && is_multiple && obj.parents("li", this.get_container()).children(".jstree-clicked").length) { 38847 return false; 38848 } 38849 proceed = false; 38850 switch(!0) { 38851 case (is_range): 38852 this.data.ui.last_selected.addClass("jstree-last-selected"); 38853 obj = obj[ obj.index() < this.data.ui.last_selected.index() ? "nextUntil" : "prevUntil" ](".jstree-last-selected").andSelf(); 38854 this.data.ui.last_selected.removeClass("jstree-last-selected"); 38855 this.data.ui.selected.each(function () { 38856 if(this !== t.data.ui.last_selected[0]) { t.deselect_node(this); } 38857 }); 38858 is_selected = false; 38859 proceed = true; 38860 break; 38861 case (is_selected && !is_multiple): 38862 this.deselect_all(); 38863 is_selected = false; 38864 proceed = true; 38865 break;
38866 case (!is_selected && !is_multiple): 38867 if(s.select_limit == -1 || s.select_limit > 0) { 38868 this.deselect_all(); 38869 proceed = true; 38870 } 38871 break; 38872 case (is_selected && is_multiple): 38873 this.deselect_node(obj); 38874 break; 38875 case (!is_selected && is_multiple): 38876 if(s.select_limit == -1 || this.data.ui.selected.length + 1 <= s.select_limit) { 38877 proceed = true; 38878 } 38879 break; 38880 } 38881 } 38882 if(proceed && !is_selected) { 38883 if(!is_range) { this.data.ui.last_selected = obj; } 38884 obj.children("a").addClass("jstree-clicked"); 38885 this.data.ui.selected = this.data.ui.selected.add(obj); 38886 this.__callback({ "obj" : obj }); 38887 } 38888 }, 38889 deselect_node : function (obj) { 38890 obj = this._get_node(obj); 38891 if(!obj.length) { return false; } 38892 if(this.is_selected(obj)) { 38893 obj.children("a").removeClass("jstree-clicked"); 38894 this.data.ui.selected = this.data.ui.selected.not(obj); 38895 if(this.data.ui.last_selected.get(0) === obj.get(0)) { this.data.ui.last_selected = this.data.ui.selected.eq(0); } 38896 this.__callback({ "obj" : obj }); 38897 } 38898 }, 38899 toggle_select : function (obj) { 38900 obj = this._get_node(obj); 38901 if(!obj.length) { return false; } 38902 if(this.is_selected(obj)) { this.deselect_node(obj); } 38903 else { this.select_node(obj); } 38904 }, 38905 is_selected : function (obj) { return this.data.ui.selected.index(this._get_node(obj)) >= 0; }, 38906 get_selected : function (context) { 38907 return context ? $(context).find(".jstree-clicked").parent() : this.data.ui.selected; 38908 }, 38909 deselect_all : function (context) { 38910 if(context) { $(context).find(".jstree-clicked").removeClass("jstree-clicked"); } 38911 else { this.get_container().find(".jstree-clicked").removeClass("jstree-clicked"); } 38912 this.data.ui.selected = $([]); 38913 this.data.ui.last_selected = false; 38914 this.__callback(); 38915 } 38916 } 38917 }); 38918 // include the selection plugin by default 38919 $.jstree.defaults.plugins.push("ui"); 38920})(jQuery); 38921//*/ 38922 38923/* 38924 * jsTree CRRM plugin 1.0 38925 * Handles creating/renaming/removing/moving nodes by user interaction. 38926 */ 38927(function ($) { 38928 $.jstree.plugin("crrm", { 38929 __init : function () { 38930 this.get_container() 38931 .bind("move_node.jstree", $.proxy(function (e, data) { 38932 if(this._get_settings().crrm.move.open_onmove) { 38933 var t = this; 38934 data.rslt.np.parentsUntil(".jstree").andSelf().filter(".jstree-closed").each(function () { 38935 t.open_node(this, false, true); 38936 }); 38937 } 38938 }, this)); 38939 }, 38940 defaults : { 38941 input_width_limit : 200, 38942 move : { 38943 always_copy : false, // false, true or "multitree" 38944 open_onmove : true, 38945 default_position : "last", 38946 check_move : function (m) { return true; } 38947 } 38948 }, 38949 _fn : { 38950 _show_input : function (obj, callback) { 38951 obj = this._get_node(obj); 38952 var rtl = this._get_settings().core.rtl, 38953 w = this._get_settings().crrm.input_width_limit, 38954 w1 = obj.children("ins").width(), 38955 w2 = obj.find("> a:visible > ins").width() * obj.find("> a:visible > ins").length, 38956 t = this.get_text(obj), 38957 h1 = $("<div>", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"), 38958 h2 = obj.css("position","relative").append( 38959 $("<input>", { 38960 "value" : t, 38961 // "size" : t.length, 38962 "css" : { 38963 "padding" : "0", 38964 "border" : "1px solid silver", 38965 "position" : "absolute", 38966 "left" : (rtl ? "auto" : (w1 + w2 + 4) + "px"), 38967 "right" : (rtl ? (w1 + w2 + 4) + "px" : "auto"), 38968 "top" : "0px", 38969 "height" : (this.data.core.li_height - 2) + "px", 38970 "lineHeight" : (this.data.core.li_height - 2) + "px", 38971 "width" : "150px" // will be set a bit further down 38972 }, 38973 "blur" : $.proxy(function () { 38974 var i = obj.children("input"), 38975 v = i.val(); 38976 if(v === "") { v = t; } 38977 i.remove(); // rollback purposes 38978 this.set_text(obj,t); // rollback purposes 38979 this.rename_node(obj, v); 38980 callback.call(this, obj, v, t); 38981 obj.css("position",""); 38982 }, this), 38983 "keyup" : function (event) { 38984 var key = event.keyCode || event.which; 38985 if(key == 27) { this.value = t; this.blur(); return; } 38986 else if(key == 13) { this.blur(); return; } 38987 else { 38988 h2.width(Math.min(h1.text("pW" + this.value).width(),w)); 38989 } 38990 } 38991 }) 38992 ).children("input"); 38993 this.set_text(obj, ""); 38994 h1.css({ 38995 fontFamily : h2.css('fontFamily') || '', 38996 fontSize : h2.css('fontSize') || '', 38997 fontWeight : h2.css('fontWeight') || '', 38998 fontStyle : h2.css('fontStyle') || '', 38999 fontStretch : h2.css('fontStretch') || '', 39000 fontVariant : h2.css('fontVariant') || '', 39001 letterSpacing : h2.css('letterSpacing') || '', 39002 wordSpacing : h2.css('wordSpacing') || '' 39003 }); 39004 h2.width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); 39005 }, 39006 rename : function (obj) { 39007 obj = this._get_node(obj); 39008 this.__rollback(); 39009 var f = this.__callback; 39010 this._show_input(obj, function (obj, new_name, old_name) { 39011 f.call(this, { "obj" : obj, "new_name" : new_name, "old_name" : old_name }); 39012 }); 39013 }, 39014 create : function (obj, position, js, callback, skip_rename) { 39015 var t, _this = this; 39016 obj = this._get_node(obj); 39017 if(!obj) { obj = -1; } 39018 this.__rollback(); 39019 t = this.create_node(obj, position, js, function (t) { 39020 var p = this._get_parent(t), 39021 pos = $(t).index(); 39022 if(callback) { callback.call(this, t); } 39023 if(p.length && p.hasClass("jstree-closed")) { this.open_node(p, false, true); } 39024 if(!skip_rename) { 39025 this._show_input(t, function (obj, new_name, old_name) { 39026 _this.__callback({ "obj" : obj, "name" : new_name, "parent" : p, "position" : pos }); 39027 });
39028 } 39029 else { _this.__callback({ "obj" : t, "name" : this.get_text(t), "parent" : p, "position" : pos }); } 39030 }); 39031 return t; 39032 }, 39033 remove : function (obj) { 39034 obj = this._get_node(obj, true); 39035 this.__rollback(); 39036 this.delete_node(obj); 39037 this.__callback({ "obj" : obj }); 39038 }, 39039 check_move : function () { 39040 if(!this.__call_old()) { return false; } 39041 var s = this._get_settings().crrm.move; 39042 if(!s.check_move.call(this, this._get_move())) { return false; } 39043 return true; 39044 }, 39045 move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) { 39046 var s = this._get_settings().crrm.move; 39047 if(!is_prepared) { 39048 if(!position) { position = s.default_position; } 39049 if(position === "inside" && !s.default_position.match(/^(before|after)$/)) { position = s.default_position; } 39050 return this.__call_old(true, obj, ref, position, is_copy, false, skip_check); 39051 } 39052 // if the move is already prepared 39053 if(s.always_copy === true || (s.always_copy === "multitree" && obj.rt.get_index() !== obj.ot.get_index() )) { 39054 is_copy = true; 39055 } 39056 this.__call_old(true, obj, ref, position, is_copy, true, skip_check); 39057 }, 39058 39059 cut : function (obj) { 39060 obj = this._get_node(obj); 39061 this.data.crrm.cp_nodes = false; 39062 this.data.crrm.ct_nodes = false; 39063 if(!obj || !obj.length) { return false; } 39064 this.data.crrm.ct_nodes = obj; 39065 }, 39066 copy : function (obj) { 39067 obj = this._get_node(obj); 39068 this.data.crrm.cp_nodes = false; 39069 this.data.crrm.ct_nodes = false; 39070 if(!obj || !obj.length) { return false; } 39071 this.data.crrm.cp_nodes = obj; 39072 }, 39073 paste : function (obj) { 39074 obj = this._get_node(obj); 39075 if(!obj || !obj.length) { return false; } 39076 if(!this.data.crrm.ct_nodes && !this.data.crrm.cp_nodes) { return false; } 39077 if(this.data.crrm.ct_nodes) { this.move_node(this.data.crrm.ct_nodes, obj); } 39078 if(this.data.crrm.cp_nodes) { this.move_node(this.data.crrm.cp_nodes, obj, false, true); } 39079 this.data.crrm.cp_nodes = false; 39080 this.data.crrm.ct_nodes = false; 39081 } 39082 } 39083 }); 39084 // include the crr plugin by default 39085 $.jstree.defaults.plugins.push("crrm"); 39086})(jQuery); 39087 39088/* 39089 * jsTree themes plugin 1.0 39090 * Handles loading and setting themes, as well as detecting path to themes, etc. 39091 */ 39092(function ($) { 39093 var themes_loaded = []; 39094 // this variable stores the path to the themes folder - if left as false - it will be autodetected 39095 $.jstree._themes = false; 39096 $.jstree.plugin("themes", { 39097 __init : function () { 39098 this.get_container() 39099 .bind("init.jstree", $.proxy(function () { 39100 var s = this._get_settings().themes; 39101 this.data.themes.dots = s.dots; 39102 this.data.themes.icons = s.icons; 39103 //alert(s.dots); 39104 this.set_theme(s.theme, s.url); 39105 }, this)) 39106 .bind("loaded.jstree", $.proxy(function () { 39107 // bound here too, as simple HTML tree's won't honor dots & icons otherwise 39108 if(!this.data.themes.dots) { this.hide_dots(); } 39109 else { this.show_dots(); } 39110 if(!this.data.themes.icons) { this.hide_icons(); } 39111 else { this.show_icons(); } 39112 }, this)); 39113 }, 39114 defaults : { 39115 theme : "default", 39116 url : false, 39117 dots : true, 39118 icons : true 39119 }, 39120 _fn : { 39121 set_theme : function (theme_name, theme_url) { 39122 if(!theme_name) { return false; } 39123 if(!theme_url) { theme_url = $.jstree._themes + theme_name + '/style.css'; } 39124 if($.inArray(theme_url, themes_loaded) == -1) { 39125 $.vakata.css.add_sheet({ "url" : theme_url, "rel" : "jstree" }); 39126 themes_loaded.push(theme_url); 39127 } 39128 if(this.data.themes.theme != theme_name) { 39129 this.get_container().removeClass('jstree-' + this.data.themes.theme); 39130 this.data.themes.theme = theme_name; 39131 } 39132 this.get_container().addClass('jstree-' + theme_name); 39133 if(!this.data.themes.dots) { this.hide_dots(); } 39134 else { this.show_dots(); } 39135 if(!this.data.themes.icons) { this.hide_icons(); } 39136 else { this.show_icons(); } 39137 this.__callback(); 39138 }, 39139 get_theme : function () { return this.data.themes.theme; }, 39140 39141 show_dots : function () { this.data.themes.dots = true; this.get_container().children("ul").removeClass("jstree-no-dots"); }, 39142 hide_dots : function () { this.data.themes.dots = false; this.get_container().children("ul").addClass("jstree-no-dots"); }, 39143 toggle_dots : function () { if(this.data.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, 39144 39145 show_icons : function () { this.data.themes.icons = true; this.get_container().children("ul").removeClass("jstree-no-icons"); }, 39146 hide_icons : function () { this.data.themes.icons = false; this.get_container().children("ul").addClass("jstree-no-icons"); }, 39147 toggle_icons: function () { if(this.data.themes.icons) { this.hide_icons(); } else { this.show_icons(); } } 39148 } 39149 }); 39150 // autodetect themes path 39151 $(function () { 39152 if($.jstree._themes === false) { 39153 $("script").each(function () { 39154 if(this.src.toString().match(/jquery\.jstree[^\/]*?\.js(\?.*)?$/)) { 39155 $.jstree._themes = this.src.toString().replace(/jquery\.jstree[^\/]*?\.js(\?.*)?$/, "") + 'themes/'; 39156 return false; 39157 } 39158 }); 39159 } 39160 if($.jstree._themes === false) { $.jstree._themes = "/javascripts/jsTree/themes/"; } 39161 }); 39162 // include the themes plugin by default 39163 $.jstree.defaults.plugins.push("themes"); 39164})(jQuery);
39165//*/ 39166 39167/* 39168 * jsTree hotkeys plugin 1.0 39169 * Enables keyboard navigation for all tree instances 39170 * Depends on the jstree ui & jquery hotkeys plugins 39171 */ 39172(function ($) { 39173 var bound = []; 39174 function exec(i, event) { 39175 var f = $.jstree._focused(), tmp; 39176 if(f && f.data && f.data.hotkeys && f.data.hotkeys.enabled) { 39177 tmp = f._get_settings().hotkeys[i]; 39178 if(tmp) { return tmp.call(f, event); } 39179 } 39180 } 39181 $.jstree.plugin("hotkeys", { 39182 __init : function () { 39183 if(typeof $.hotkeys === "undefined") { throw "jsTree hotkeys: jQuery hotkeys plugin not included."; } 39184 if(!this.data.ui) { throw "jsTree hotkeys: jsTree UI plugin not included."; } 39185 $.each(this._get_settings().hotkeys, function (i, val) { 39186 if($.inArray(i, bound) == -1) { 39187 $(document).bind("keydown", i, function (event) { return exec(i, event); }); 39188 bound.push(i); 39189 } 39190 }); 39191 this.enable_hotkeys(); 39192 }, 39193 defaults : { 39194 "up" : function () { 39195 var o = this.data.ui.hovered || this.data.ui.last_selected || -1; 39196 this.hover_node(this._get_prev(o)); 39197 return false; 39198 }, 39199 "down" : function () { 39200 var o = this.data.ui.hovered || this.data.ui.last_selected || -1; 39201 this.hover_node(this._get_next(o)); 39202 return false; 39203 }, 39204 "left" : function () { 39205 var o = this.data.ui.hovered || this.data.ui.last_selected; 39206 if(o) { 39207 if(o.hasClass("jstree-open")) { this.close_node(o); } 39208 else { this.hover_node(this._get_prev(o)); } 39209 } 39210 return false; 39211 }, 39212 "right" : function () { 39213 var o = this.data.ui.hovered || this.data.ui.last_selected; 39214 if(o && o.length) { 39215 if(o.hasClass("jstree-closed")) { this.open_node(o); } 39216 else { this.hover_node(this._get_next(o)); } 39217 } 39218 return false; 39219 }, 39220 "space" : function () { 39221 if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click(); } 39222 return false; 39223 }, 39224 "ctrl+space" : function (event) { 39225 event.type = "click"; 39226 if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); } 39227 return false; 39228 }, 39229 "f2" : function () { this.rename(this.data.ui.hovered || this.data.ui.last_selected); }, 39230 "del" : function () { this.remove(this.data.ui.hovered || this._get_node(null)); } 39231 }, 39232 _fn : { 39233 enable_hotkeys : function () { 39234 this.data.hotkeys.enabled = true; 39235 }, 39236 disable_hotkeys : function () { 39237 this.data.hotkeys.enabled = false; 39238 } 39239 } 39240 }); 39241})(jQuery); 39242//*/ 39243 39244/* 39245 * jsTree JSON 1.0 39246 * The JSON data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions. 39247 */ 39248(function ($) { 39249 $.jstree.plugin("json_data", { 39250 defaults : { 39251 // SENAD: chrome_extension: if set to true, then we call ajax calls via chrome.extension.sendRequest 39252 chrome_extension: false, 39253 data : false, 39254 ajax : false, 39255 correct_state : true, 39256 progressive_render : false 39257 }, 39258 _fn : { 39259 load_node : function (obj, s_call, e_call) { 39260 var _this = this; 39261 this.load_node_json(obj, 39262 function () { 39263 _this.__callback({ "obj" : obj }); 39264 s_call.call(this); }, e_call); 39265 }, 39266 _is_loaded : function (obj) { 39267 var s = this._get_settings().json_data, d; 39268 obj = this._get_node(obj); 39269 if(obj && obj !== -1 && s.progressive_render && !obj.is(".jstree-open, .jstree-leaf") && obj.children("ul").children("li").length === 0 && obj.data("jstree-children")) { 39270 d = this._parse_json(obj.data("jstree-children")); 39271 if(d) { 39272 obj.append(d); 39273 $.removeData(obj, "jstree-children"); 39274 } 39275 this.clean_node(obj); 39276 return true; 39277 } 39278 return obj == -1 || !obj || !s.ajax || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0; 39279 }, 39280 load_node_json : function (obj, s_call, e_call) { 39281 var s = this.get_settings().json_data, d, 39282 error_func = function () {}, 39283 success_func = function () {}; 39284 obj = this._get_node(obj); 39285 if(obj && obj !== -1) { 39286 if(obj.data("jstree-is-loading")) { return; } 39287 else { obj.data("jstree-is-loading",true); } 39288 } 39289 switch(!0) { 39290 case (!s.data && !s.ajax): throw "Neither data nor ajax settings supplied."; 39291 case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)): 39292 if(!obj || obj == -1) { 39293 d = this._parse_json(s.data); 39294 if(d) { 39295 this.get_container().children("ul").empty().append(d.children()); 39296 this.clean_node(); 39297 } 39298 else { 39299 if(s.correct_state) { this.get_container().children("ul").empty(); } 39300 } 39301 } 39302 if(s_call) { s_call.call(this); } 39303 break; 39304 case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1): 39305 error_func = function (x, t, e) { 39306 var ef = this.get_settings().json_data.ajax.error; 39307 if(ef) { ef.call(this, x, t, e); } 39308 if(obj != -1 && obj.length) { 39309 obj.children(".jstree-loading").removeClass("jstree-loading"); 39310 obj.data("jstree-is-loading",false); 39311 if(t === "success" && s.correct_state) { obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); } 39312 } 39313 else { 39314 if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); } 39315 }
39316 if(e_call) { e_call.call(this); } 39317 }; 39318 success_func = function (d, t, x) { 39319 var sf = this.get_settings().json_data.ajax.success; 39320 if(sf) { d = sf.call(this,d,t,x) || d; } 39321 if(d === "" || (!$.isArray(d) && !$.isPlainObject(d))) { 39322 return error_func.call(this, x, t, ""); 39323 } 39324 d = this._parse_json(d); 39325 if(d) { 39326 if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); } 39327 else { obj.append(d).children(".jstree-loading").removeClass("jstree-loading"); obj.data("jstree-is-loading",false); } 39328 this.clean_node(obj); 39329 if(s_call) { s_call.call(this); } 39330 } 39331 else { 39332 if(obj === -1 || !obj) { 39333 if(s.correct_state) { 39334 this.get_container().children("ul").empty(); 39335 if(s_call) { s_call.call(this); } 39336 } 39337 } 39338 else { 39339 obj.children(".jstree-loading").removeClass("jstree-loading"); 39340 obj.data("jstree-is-loading",false); 39341 if(s.correct_state) { 39342 obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); 39343 if(s_call) { s_call.call(this); } 39344 } 39345 } 39346 } 39347 }; 39348 s.ajax.context = this; 39349 if(!s.ajax.dataType) { s.ajax.dataType = "json"; } 39350 if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); } 39351 if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); } 39352 39353 // SENAD: 39354 // In case when chrome_extension flag is set, we using background.html to execute 39355 // our ajax since we cannot do cross-domain calls from inserted page. 39356 // See backgound.js for how we are processing. 39357 if (s.chrome_extension) { 39358 var context = this; 39359 s.ajax.error = null; 39360 s.ajax.success = null; 39361 s.ajax.context = null; 39362 chrome.extension.sendRequest({'action_name' : 'fn_ajax', 'action_params': s.ajax}, 39363 function(data) { 39364 try { 39365 if (data == null) 39366 throw('Failed to call fn_ajax. Unable to connect to background.html'); 39367 if (data.error) 39368 throw('Action fn_ajax failed. error: '+ data.error); 39369 success_func.call(context, data.result.s, data.result.t, data.result.x); 39370 } catch(e) { 39371 error_func.call(context, null, null, null); 39372 } 39373 } 39374 ); 39375 } 39376 else { 39377 s.ajax.error = error_func; 39378 s.ajax.success = success_func; 39379 $.ajax(s.ajax); 39380 } 39381 break; 39382 } 39383 }, 39384 _parse_json : function (js, is_callback) { 39385 var d = false, 39386 p = this._get_settings(), 39387 s = p.json_data, 39388 t = p.core.html_titles, 39389 tmp, i, j, ul1, ul2; 39390 39391 if(!js) { return d; } 39392 if($.isFunction(js)) { 39393 js = js.call(this); 39394 } 39395 if($.isArray(js)) { 39396 d = $(); 39397 if(!js.length) { return false; } 39398 for(i = 0, j = js.length; i < j; i++) { 39399 tmp = this._parse_json(js[i], true); 39400 if(tmp.length) { d = d.add(tmp); } 39401 } 39402 } 39403 else { 39404 if(typeof js == "string") { js = { data : js }; } 39405 if(!js.data && js.data !== "") { return d; } 39406 d = $("<li>"); 39407 if(js.attr) { d.attr(js.attr); } 39408 if(js.metadata) { d.data("jstree", js.metadata); } 39409 if(js.state) { d.addClass("jstree-" + js.state); } 39410 if(!$.isArray(js.data)) { tmp = js.data; js.data = []; js.data.push(tmp); } 39411 $.each(js.data, function (i, m) { 39412 tmp = $("<a>"); 39413 if($.isFunction(m)) { m = m.call(this, js); } 39414 if(typeof m == "string") { tmp.attr('href','#')[ t ? "html" : "text" ](m); } 39415 else { 39416 if(!m.attr) { m.attr = {}; } 39417 if(!m.attr.href) { m.attr.href = '#'; } 39418 tmp.attr(m.attr)[ t ? "html" : "text" ](m.title); 39419 if(m.language) { tmp.addClass(m.language); } 39420 } 39421 tmp.prepend("<ins class='jstree-icon'> </ins>"); 39422 if(!m.icon && js.icon) { m.icon = js.icon; } 39423 if(m.icon) { 39424 if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
39425 else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); } 39426 } 39427 d.append(tmp); 39428 }); 39429 d.prepend("<ins class='jstree-icon'> </ins>"); 39430 if(js.children) { 39431 if(s.progressive_render && js.state !== "open") { 39432 d.addClass("jstree-closed").data("jstree-children", js.children); 39433 } 39434 else { 39435 if($.isFunction(js.children)) { 39436 js.children = js.children.call(this, js); 39437 } 39438 if($.isArray(js.children) && js.children.length) { 39439 tmp = this._parse_json(js.children, true); 39440 if(tmp.length) { 39441 ul2 = $("<ul>"); 39442 ul2.append(tmp); 39443 d.append(ul2); 39444 } 39445 } 39446 } 39447 } 39448 } 39449 if(!is_callback) { 39450 ul1 = $("<ul>"); 39451 ul1.append(d); 39452 d = ul1; 39453 } 39454 return d; 39455 }, 39456 get_json : function (obj, li_attr, a_attr, is_callback) { 39457 var result = [], 39458 s = this._get_settings(), 39459 _this = this, 39460 tmp1, tmp2, li, a, t, lang; 39461 obj = this._get_node(obj); 39462 if(!obj || obj === -1) { obj = this.get_container().find("> ul > li"); } 39463 li_attr = $.isArray(li_attr) ? li_attr : [ "id", "class" ]; 39464 if(!is_callback && this.data.types) { li_attr.push(s.types.type_attr); } 39465 a_attr = $.isArray(a_attr) ? a_attr : [ ]; 39466 39467 obj.each(function () { 39468 li = $(this); 39469 tmp1 = { data : [] }; 39470 if(li_attr.length) { tmp1.attr = { }; } 39471 $.each(li_attr, function (i, v) { 39472 tmp2 = li.attr(v); 39473 if(tmp2 && tmp2.length && tmp2.replace(/jstree[^ ]*|$/ig,'').length) { 39474 tmp1.attr[v] = tmp2.replace(/jstree[^ ]*|$/ig,''); 39475 } 39476 }); 39477 if(li.hasClass("jstree-open")) { tmp1.state = "open"; } 39478 if(li.hasClass("jstree-closed")) { tmp1.state = "closed"; } 39479 a = li.children("a"); 39480 a.each(function () { 39481 t = $(this); 39482 if( 39483 a_attr.length || 39484 $.inArray("languages", s.plugins) !== -1 || 39485 t.children("ins").get(0).style.backgroundImage.length || 39486 (t.children("ins").get(0).className && t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').length) 39487 ) { 39488 lang = false; 39489 if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) { 39490 $.each(s.languages, function (l, lv) { 39491 if(t.hasClass(lv)) { 39492 lang = lv; 39493 return false; 39494 } 39495 });
39496 } 39497 tmp2 = { attr : { }, title : _this.get_text(t, lang) }; 39498 $.each(a_attr, function (k, z) { 39499 tmp1.attr[z] = (t.attr(z) || "").replace(/jstree[^ ]*|$/ig,''); 39500 }); 39501 $.each(s.languages, function (k, z) { 39502 if(t.hasClass(z)) { tmp2.language = z; return true; } 39503 }); 39504 if(t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"").length) { 39505 tmp2.icon = t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,""); 39506 } 39507 if(t.children("ins").get(0).style.backgroundImage.length) { 39508 tmp2.icon = t.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")",""); 39509 } 39510 } 39511 else { 39512 tmp2 = _this.get_text(t); 39513 } 39514 if(a.length > 1) { tmp1.data.push(tmp2); } 39515 else { tmp1.data = tmp2; } 39516 }); 39517 li = li.find("> ul > li"); 39518 if(li.length) { tmp1.children = _this.get_json(li, li_attr, a_attr, true); } 39519 result.push(tmp1); 39520 }); 39521 return result; 39522 } 39523 } 39524 }); 39525})(jQuery); 39526//*/ 39527 39528/* 39529 * jsTree languages plugin 1.0 39530 * Adds support for multiple language versions in one tree 39531 * This basically allows for many titles coexisting in one node, but only one of them being visible at any given time 39532 * This is useful for maintaining the same structure in many languages (hence the name of the plugin) 39533 */ 39534(function ($) { 39535 $.jstree.plugin("languages", { 39536 __init : function () { this._load_css(); }, 39537 defaults : [], 39538 _fn : { 39539 set_lang : function (i) { 39540 var langs = this._get_settings().languages, 39541 st = false, 39542 selector = ".jstree-" + this.get_index() + ' a'; 39543 if(!$.isArray(langs) || langs.length === 0) { return false; } 39544 if($.inArray(i,langs) == -1) { 39545 if(!!langs[i]) { i = langs[i]; } 39546 else { return false; } 39547 } 39548 if(i == this.data.languages.current_language) { return true; } 39549 st = $.vakata.css.get_css(selector + "." + this.data.languages.current_language, false, this.data.languages.language_css); 39550 if(st !== false) { st.style.display = "none"; } 39551 st = $.vakata.css.get_css(selector + "." + i, false, this.data.languages.language_css); 39552 if(st !== false) { st.style.display = ""; } 39553 this.data.languages.current_language = i; 39554 this.__callback(i); 39555 return true; 39556 }, 39557 get_lang : function () { 39558 return this.data.languages.current_language; 39559 }, 39560 get_text : function (obj, lang) { 39561 obj = this._get_node(obj) || this.data.ui.last_selected; 39562 if(!obj.size()) { return false; } 39563 var langs = this._get_settings().languages, 39564 s = this._get_settings().core.html_titles;
39565 if($.isArray(langs) && langs.length) { 39566 lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language; 39567 obj = obj.children("a." + lang); 39568 } 39569 else { obj = obj.children("a:eq(0)"); } 39570 if(s) { 39571 obj = obj.clone(); 39572 obj.children("INS").remove(); 39573 return obj.html(); 39574 } 39575 else { 39576 obj = obj.contents().filter(function() { return this.nodeType == 3; })[0]; 39577 return obj.nodeValue; 39578 } 39579 }, 39580 set_text : function (obj, val, lang) { 39581 obj = this._get_node(obj) || this.data.ui.last_selected; 39582 if(!obj.size()) { return false; } 39583 var langs = this._get_settings().languages, 39584 s = this._get_settings().core.html_titles, 39585 tmp; 39586 if($.isArray(langs) && langs.length) { 39587 lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language; 39588 obj = obj.children("a." + lang); 39589 } 39590 else { obj = obj.children("a:eq(0)"); } 39591 if(s) { 39592 tmp = obj.children("INS").clone(); 39593 obj.html(val).prepend(tmp); 39594 this.__callback({ "obj" : obj, "name" : val, "lang" : lang }); 39595 return true; 39596 } 39597 else { 39598 obj = obj.contents().filter(function() { return this.nodeType == 3; })[0]; 39599 this.__callback({ "obj" : obj, "name" : val, "lang" : lang }); 39600 return (obj.nodeValue = val); 39601 } 39602 }, 39603 _load_css : function () { 39604 var langs = this._get_settings().languages, 39605 str = "/* languages css */", 39606 selector = ".jstree-" + this.get_index() + ' a', 39607 ln; 39608 if($.isArray(langs) && langs.length) { 39609 this.data.languages.current_language = langs[0]; 39610 for(ln = 0; ln < langs.length; ln++) { 39611 str += selector + "." + langs[ln] + " {"; 39612 if(langs[ln] != this.data.languages.current_language) { str += " display:none; "; } 39613 str += " } "; 39614 } 39615 this.data.languages.language_css = $.vakata.css.add_sheet({ 'str' : str }); 39616 } 39617 }, 39618 create_node : function (obj, position, js, callback) { 39619 var t = this.__call_old(true, obj, position, js, function (t) { 39620 var langs = this._get_settings().languages, 39621 a = t.children("a"), 39622 ln; 39623 if($.isArray(langs) && langs.length) { 39624 for(ln = 0; ln < langs.length; ln++) { 39625 if(!a.is("." + langs[ln])) { 39626 t.append(a.eq(0).clone().removeClass(langs.join(" ")).addClass(langs[ln])); 39627 } 39628 } 39629 a.not("." + langs.join(", .")).remove(); 39630 } 39631 if(callback) { callback.call(this, t); } 39632 }); 39633 return t; 39634 } 39635 } 39636 }); 39637})(jQuery); 39638//*/ 39639 39640/* 39641 * jsTree cookies plugin 1.0 39642 * Stores the currently opened/selected nodes in a cookie and then restores them 39643 * Depends on the jquery.cookie plugin 39644 */ 39645(function ($) { 39646 $.jstree.plugin("cookies", { 39647 __init : function () { 39648 if(typeof $.cookie === "undefined") { throw "jsTree cookie: jQuery cookie plugin not included."; } 39649 39650 var s = this._get_settings().cookies, 39651 tmp; 39652 if(!!s.save_opened) { 39653 tmp = $.cookie(s.save_opened); 39654 if(tmp && tmp.length) { this.data.core.to_open = tmp.split(","); } 39655 } 39656 if(!!s.save_selected) { 39657 tmp = $.cookie(s.save_selected); 39658 if(tmp && tmp.length && this.data.ui) { this.data.ui.to_select = tmp.split(","); } 39659 } 39660 this.get_container() 39661 .one( ( this.data.ui ? "reselect" : "reopen" ) + ".jstree", $.proxy(function () { 39662 this.get_container() 39663 .bind("open_node.jstree close_node.jstree select_node.jstree deselect_node.jstree", $.proxy(function (e) { 39664 if(this._get_settings().cookies.auto_save) { this.save_cookie((e.handleObj.namespace + e.handleObj.type).replace("jstree","")); } 39665 }, this)); 39666 }, this)); 39667 }, 39668 defaults : { 39669 save_opened : "jstree_open", 39670 save_selected : "jstree_select", 39671 auto_save : true, 39672 cookie_options : {} 39673 }, 39674 _fn : { 39675 save_cookie : function (c) { 39676 if(this.data.core.refreshing) { return; } 39677 var s = this._get_settings().cookies; 39678 if(!c) { // if called manually and not by event 39679 if(s.save_opened) { 39680 this.save_opened(); 39681 $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options); 39682 } 39683 if(s.save_selected && this.data.ui) { 39684 this.save_selected(); 39685 $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options); 39686 } 39687 return; 39688 } 39689 switch(c) { 39690 case "open_node": 39691 case "close_node": 39692 if(!!s.save_opened) { 39693 this.save_opened(); 39694 $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options); 39695 } 39696 break; 39697 case "select_node": 39698 case "deselect_node": 39699 if(!!s.save_selected && this.data.ui) { 39700 this.save_selected(); 39701 $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options); 39702 } 39703 break; 39704 } 39705 } 39706 } 39707 }); 39708 // include cookies by default 39709 $.jstree.defaults.plugins.push("cookies"); 39710})(jQuery);
39711//*/ 39712 39713/* 39714 * jsTree sort plugin 1.0 39715 * Sorts items alphabetically (or using any other function) 39716 */ 39717(function ($) { 39718 $.jstree.plugin("sort", { 39719 __init : function () { 39720 this.get_container() 39721 .bind("load_node.jstree", $.proxy(function (e, data) { 39722 var obj = this._get_node(data.rslt.obj); 39723 obj = obj === -1 ? this.get_container().children("ul") : obj.children("ul"); 39724 this.sort(obj); 39725 }, this)) 39726 .bind("rename_node.jstree", $.proxy(function (e, data) { 39727 this.sort(data.rslt.obj.parent()); 39728 }, this)) 39729 .bind("move_node.jstree", $.proxy(function (e, data) { 39730 var m = data.rslt.np == -1 ? this.get_container() : data.rslt.np; 39731 this.sort(m.children("ul")); 39732 }, this)); 39733 }, 39734 defaults : function (a, b) { return this.get_text(a) > this.get_text(b) ? 1 : -1; }, 39735 _fn : { 39736 sort : function (obj) { 39737 var s = this._get_settings().sort, 39738 t = this; 39739 obj.append($.makeArray(obj.children("li")).sort($.proxy(s, t))); 39740 obj.find("> li > ul").each(function() { t.sort($(this)); }); 39741 this.clean_node(obj); 39742 } 39743 } 39744 }); 39745})(jQuery); 39746//*/ 39747 39748/* 39749 * jsTree DND plugin 1.0 39750 * Drag and drop plugin for moving/copying nodes 39751 */ 39752(function ($) { 39753 var o = false, 39754 r = false, 39755 m = false, 39756 sli = false, 39757 sti = false, 39758 dir1 = false, 39759 dir2 = false; 39760 $.vakata.dnd = { 39761 is_down : false, 39762 is_drag : false, 39763 helper : false, 39764 scroll_spd : 10, 39765 init_x : 0, 39766 init_y : 0, 39767 threshold : 5, 39768 user_data : {}, 39769 39770 drag_start : function (e, data, html) { 39771 if($.vakata.dnd.is_drag) { $.vakata.drag_stop({}); } 39772 try { 39773 e.currentTarget.unselectable = "on"; 39774 e.currentTarget.onselectstart = function() { return false; }; 39775 if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; } 39776 } catch(err) { } 39777 $.vakata.dnd.init_x = e.pageX; 39778 $.vakata.dnd.init_y = e.pageY; 39779 $.vakata.dnd.user_data = data; 39780 $.vakata.dnd.is_down = true; 39781 $.vakata.dnd.helper = $("<div id='vakata-dragged'>").html(html).css("opacity", "0.75"); 39782 $(document).bind("mousemove", $.vakata.dnd.drag); 39783 $(document).bind("mouseup", $.vakata.dnd.drag_stop); 39784 return false; 39785 }, 39786 drag : function (e) { 39787 if(!$.vakata.dnd.is_down) { return; } 39788 if(!$.vakata.dnd.is_drag) { 39789 if(Math.abs(e.pageX - $.vakata.dnd.init_x) > 5 || Math.abs(e.pageY - $.vakata.dnd.init_y) > 5) { 39790 $.vakata.dnd.helper.appendTo("body"); 39791 $.vakata.dnd.is_drag = true; 39792 $(document).triggerHandler("drag_start.vakata", { "event" : e, "data" : $.vakata.dnd.user_data }); 39793 } 39794 else { return; } 39795 } 39796 39797 // maybe use a scrolling parent element instead of document? 39798 if(e.type === "mousemove") { // thought of adding scroll in order to move the helper, but mouse poisition is n/a 39799 var d = $(document), t = d.scrollTop(), l = d.scrollLeft(); 39800 if(e.pageY - t < 20) { 39801 if(sti && dir1 === "down") { clearInterval(sti); sti = false; } 39802 if(!sti) { dir1 = "up"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() - $.vakata.dnd.scroll_spd); }, 150); } 39803 } 39804 else { 39805 if(sti && dir1 === "up") { clearInterval(sti); sti = false; } 39806 } 39807 if($(window).height() - (e.pageY - t) < 20) { 39808 if(sti && dir1 === "up") { clearInterval(sti); sti = false; } 39809 if(!sti) { dir1 = "down"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() + $.vakata.dnd.scroll_spd); }, 150); } 39810 } 39811 else { 39812 if(sti && dir1 === "down") { clearInterval(sti); sti = false; } 39813 } 39814 39815 if(e.pageX - l < 20) { 39816 if(sli && dir2 === "right") { clearInterval(sli); sli = false; } 39817 if(!sli) { dir2 = "left"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() - $.vakata.dnd.scroll_spd); }, 150); } 39818 } 39819 else { 39820 if(sli && dir2 === "left") { clearInterval(sli); sli = false; } 39821 } 39822 if($(window).width() - (e.pageX - l) < 20) { 39823 if(sli && dir2 === "left") { clearInterval(sli); sli = false; } 39824 if(!sli) { dir2 = "right"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() + $.vakata.dnd.scroll_spd); }, 150); } 39825 } 39826 else { 39827 if(sli && dir2 === "right") { clearInterval(sli); sli = false; } 39828 } 39829 } 39830 39831 $.vakata.dnd.helper.css({ left : (e.pageX + 5) + "px", top : (e.pageY + 10) + "px" }); 39832 $(document).triggerHandler("drag.vakata", { "event" : e, "data" : $.vakata.dnd.user_data }); 39833 }, 39834 drag_stop : function (e) { 39835 $(document).unbind("mousemove", $.vakata.dnd.drag); 39836 $(document).unbind("mouseup", $.vakata.dnd.drag_stop); 39837 $(document).triggerHandler("drag_stop.vakata", { "event" : e, "data" : $.vakata.dnd.user_data }); 39838 $.vakata.dnd.helper.remove(); 39839 $.vakata.dnd.init_x = 0; 39840 $.vakata.dnd.init_y = 0; 39841 $.vakata.dnd.user_data = {}; 39842 $.vakata.dnd.is_down = false; 39843 $.vakata.dnd.is_drag = false; 39844 } 39845 }; 39846 $(function() { 39847 var css_string = '#vakata-dragged { display:block; margin:0 0 0 0; padding:4px 4px 4px 24px; position:absolute; top:-2000px; line-height:16px; z-index:10000; } '; 39848 $.vakata.css.add_sheet({ str : css_string });
39849 }); 39850 39851 $.jstree.plugin("dnd", { 39852 __init : function () { 39853 this.data.dnd = { 39854 active : false, 39855 after : false, 39856 inside : false, 39857 before : false, 39858 off : false, 39859 prepared : false, 39860 w : 0, 39861 to1 : false, 39862 to2 : false, 39863 cof : false, 39864 cw : false, 39865 ch : false, 39866 i1 : false, 39867 i2 : false 39868 }; 39869 this.get_container() 39870 .bind("mouseenter.jstree", $.proxy(function () { 39871 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && this.data.themes) { 39872 m.attr("class", "jstree-" + this.data.themes.theme); 39873 $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme); 39874 } 39875 }, this)) 39876 .bind("mouseleave.jstree", $.proxy(function () { 39877 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39878 if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); } 39879 if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); } 39880 } 39881 }, this)) 39882 .bind("mousemove.jstree", $.proxy(function (e) { 39883 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39884 var cnt = this.get_container()[0]; 39885 39886 // Horizontal scroll 39887 if(e.pageX + 24 > this.data.dnd.cof.left + this.data.dnd.cw) { 39888 if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); } 39889 this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft += $.vakata.dnd.scroll_spd; }, cnt), 100); 39890 } 39891 else if(e.pageX - 24 < this.data.dnd.cof.left) { 39892 if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); } 39893 this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft -= $.vakata.dnd.scroll_spd; }, cnt), 100); 39894 } 39895 else { 39896 if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); } 39897 } 39898 39899 // Vertical scroll 39900 if(e.pageY + 24 > this.data.dnd.cof.top + this.data.dnd.ch) { 39901 if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); } 39902 this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop += $.vakata.dnd.scroll_spd; }, cnt), 100); 39903 } 39904 else if(e.pageY - 24 < this.data.dnd.cof.top) { 39905 if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); } 39906 this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop -= $.vakata.dnd.scroll_spd; }, cnt), 100); 39907 } 39908 else { 39909 if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); } 39910 } 39911 39912 } 39913 }, this)) 39914 .delegate("a", "mousedown.jstree", $.proxy(function (e) { 39915 if(e.which === 1) { 39916 this.start_drag(e.currentTarget, e); 39917 return false; 39918 } 39919 }, this)) 39920 .delegate("a", "mouseenter.jstree", $.proxy(function (e) { 39921 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39922 this.dnd_enter(e.currentTarget); 39923 } 39924 }, this)) 39925 .delegate("a", "mousemove.jstree", $.proxy(function (e) { 39926 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39927 if(typeof this.data.dnd.off.top === "undefined") { this.data.dnd.off = $(e.target).offset(); } 39928 this.data.dnd.w = (e.pageY - (this.data.dnd.off.top || 0)) % this.data.core.li_height; 39929 if(this.data.dnd.w < 0) { this.data.dnd.w += this.data.core.li_height; } 39930 this.dnd_show(); 39931 } 39932 }, this)) 39933 .delegate("a", "mouseleave.jstree", $.proxy(function (e) { 39934 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39935 this.data.dnd.after = false; 39936 this.data.dnd.before = false; 39937 this.data.dnd.inside = false; 39938 $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); 39939 m.hide(); 39940 if(r && r[0] === e.target.parentNode) { 39941 if(this.data.dnd.to1) { 39942 clearTimeout(this.data.dnd.to1); 39943 this.data.dnd.to1 = false; 39944 } 39945 if(this.data.dnd.to2) { 39946 clearTimeout(this.data.dnd.to2); 39947 this.data.dnd.to2 = false; 39948 } 39949 } 39950 } 39951 }, this)) 39952 .delegate("a", "mouseup.jstree", $.proxy(function (e) { 39953 if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) { 39954 this.dnd_finish(e); 39955 } 39956 }, this)); 39957 39958 $(document) 39959 .bind("drag_stop.vakata", $.proxy(function () { 39960 this.data.dnd.after = false; 39961 this.data.dnd.before = false; 39962 this.data.dnd.inside = false; 39963 this.data.dnd.off = false; 39964 this.data.dnd.prepared = false; 39965 this.data.dnd.w = false; 39966 this.data.dnd.to1 = false; 39967 this.data.dnd.to2 = false; 39968 this.data.dnd.active = false; 39969 this.data.dnd.foreign = false; 39970 if(m) { m.css({ "top" : "-2000px" }); } 39971 }, this)) 39972 .bind("drag_start.vakata", $.proxy(function (e, data) { 39973 if(data.data.jstree) { 39974 var et = $(data.event.target);
39975 if(et.closest(".jstree").hasClass("jstree-" + this.get_index())) { 39976 this.dnd_enter(et); 39977 } 39978 } 39979 }, this)); 39980 39981 var s = this._get_settings().dnd; 39982 if(s.drag_target) { 39983 $(document) 39984 .delegate(s.drag_target, "mousedown.jstree", $.proxy(function (e) { 39985 o = e.target; 39986 $.vakata.dnd.drag_start(e, { jstree : true, obj : e.target }, "<ins class='jstree-icon'></ins>" + $(e.target).text() ); 39987 if(this.data.themes) { 39988 m.attr("class", "jstree-" + this.data.themes.theme); 39989 $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme); 39990 } 39991 $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); 39992 var cnt = this.get_container(); 39993 this.data.dnd.cof = cnt.offset(); 39994 this.data.dnd.cw = parseInt(cnt.width(),10); 39995 this.data.dnd.ch = parseInt(cnt.height(),10); 39996 this.data.dnd.foreign = true; 39997 return false; 39998 }, this)); 39999 } 40000 if(s.drop_target) { 40001 $(document) 40002 .delegate(s.drop_target, "mouseenter.jstree", $.proxy(function (e) { 40003 if(this.data.dnd.active && this._get_settings().dnd.drop_check.call(this, { "o" : o, "r" : $(e.target) })) { 40004 $.vakata.dnd.helper.children("ins").attr("class","jstree-ok"); 40005 } 40006 }, this)) 40007 .delegate(s.drop_target, "mouseleave.jstree", $.proxy(function (e) { 40008 if(this.data.dnd.active) { 40009 $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); 40010 } 40011 }, this)) 40012 .delegate(s.drop_target, "mouseup.jstree", $.proxy(function (e) { 40013 if(this.data.dnd.active && $.vakata.dnd.helper.children("ins").hasClass("jstree-ok")) { 40014 this._get_settings().dnd.drop_finish.call(this, { "o" : o, "r" : $(e.target) }); 40015 } 40016 }, this)); 40017 } 40018 }, 40019 defaults : { 40020 copy_modifier : "ctrl", 40021 check_timeout : 200, 40022 open_timeout : 500, 40023 drop_target : ".jstree-drop", 40024 drop_check : function (data) { return true; }, 40025 drop_finish : $.noop, 40026 drag_target : ".jstree-draggable", 40027 drag_finish : $.noop, 40028 drag_check : function (data) { return { after : false, before : false, inside : true }; } 40029 }, 40030 _fn : { 40031 dnd_prepare : function () { 40032 if(!r || !r.length) { return; } 40033 this.data.dnd.off = r.offset(); 40034 if(this._get_settings().core.rtl) { 40035 this.data.dnd.off.right = this.data.dnd.off.left + r.width(); 40036 } 40037 if(this.data.dnd.foreign) { 40038 var a = this._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : r }); 40039 this.data.dnd.after = a.after; 40040 this.data.dnd.before = a.before; 40041 this.data.dnd.inside = a.inside; 40042 this.data.dnd.prepared = true; 40043 return this.dnd_show(); 40044 } 40045 this.prepare_move(o, r, "before"); 40046 this.data.dnd.before = this.check_move(); 40047 this.prepare_move(o, r, "after"); 40048 this.data.dnd.after = this.check_move(); 40049 if(this._is_loaded(r)) { 40050 this.prepare_move(o, r, "inside"); 40051 this.data.dnd.inside = this.check_move(); 40052 } 40053 else { 40054 this.data.dnd.inside = false; 40055 } 40056 this.data.dnd.prepared = true; 40057 return this.dnd_show(); 40058 }, 40059 dnd_show : function () { 40060 if(!this.data.dnd.prepared) { return; } 40061 var o = ["before","inside","after"], 40062 r = false, 40063 rtl = this._get_settings().core.rtl, 40064 pos; 40065 if(this.data.dnd.w < this.data.core.li_height/3) { o = ["before","inside","after"]; } 40066 else if(this.data.dnd.w <= this.data.core.li_height*2/3) { 40067 o = this.data.dnd.w < this.data.core.li_height/2 ? ["inside","before","after"] : ["inside","after","before"]; 40068 } 40069 else { o = ["after","inside","before"]; } 40070 $.each(o, $.proxy(function (i, val) { 40071 if(this.data.dnd[val]) { 40072 $.vakata.dnd.helper.children("ins").attr("class","jstree-ok"); 40073 r = val; 40074 return false; 40075 } 40076 }, this)); 40077 if(r === false) { $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); } 40078 40079 pos = rtl ? (this.data.dnd.off.right - 18) : (this.data.dnd.off.left + 10); 40080 switch(r) { 40081 case "before": 40082 m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top - 6) + "px" }).show(); 40083 break; 40084 case "after": 40085 m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height - 7) + "px" }).show(); 40086 break; 40087 case "inside": 40088 m.css({ "left" : pos + ( rtl ? -4 : 4) + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height/2 - 5) + "px" }).show(); 40089 break; 40090 default: 40091 m.hide(); 40092 break; 40093 } 40094 return r; 40095 }, 40096 dnd_open : function () { 40097 this.data.dnd.to2 = false; 40098 this.open_node(r, $.proxy(this.dnd_prepare,this), true); 40099 }, 40100 dnd_finish : function (e) { 40101 if(this.data.dnd.foreign) { 40102 if(this.data.dnd.after || this.data.dnd.before || this.data.dnd.inside) { 40103 this._get_settings().dnd.drag_finish.call(this, { "o" : o, "r" : r }); 40104 } 40105 } 40106 else { 40107 this.dnd_prepare(); 40108 this.move_node(o, r, this.dnd_show(), e[this._get_settings().dnd.copy_modifier + "Key"]);
40109 } 40110 o = false; 40111 r = false; 40112 m.hide(); 40113 }, 40114 dnd_enter : function (obj) { 40115 var s = this._get_settings().dnd; 40116 this.data.dnd.prepared = false; 40117 r = this._get_node(obj); 40118 if(s.check_timeout) { 40119 // do the calculations after a minimal timeout (users tend to drag quickly to the desired location) 40120 if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); } 40121 this.data.dnd.to1 = setTimeout($.proxy(this.dnd_prepare, this), s.check_timeout); 40122 } 40123 else { 40124 this.dnd_prepare(); 40125 } 40126 if(s.open_timeout) { 40127 if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); } 40128 if(r && r.length && r.hasClass("jstree-closed")) { 40129 // if the node is closed - open it, then recalculate 40130 this.data.dnd.to2 = setTimeout($.proxy(this.dnd_open, this), s.open_timeout); 40131 } 40132 } 40133 else { 40134 if(r && r.length && r.hasClass("jstree-closed")) { 40135 this.dnd_open(); 40136 } 40137 } 40138 }, 40139 start_drag : function (obj, e) { 40140 o = this._get_node(obj); 40141 if(this.data.ui && this.is_selected(o)) { o = this._get_node(null, true); } 40142 $.vakata.dnd.drag_start(e, { jstree : true, obj : o }, "<ins class='jstree-icon'></ins>" + (o.length > 1 ? "Multiple selection" : this.get_text(o)) ); 40143 if(this.data.themes) { 40144 m.attr("class", "jstree-" + this.data.themes.theme); 40145 $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme); 40146 } 40147 var cnt = this.get_container(); 40148 this.data.dnd.cof = cnt.children("ul").offset(); 40149 this.data.dnd.cw = parseInt(cnt.width(),10); 40150 this.data.dnd.ch = parseInt(cnt.height(),10); 40151 this.data.dnd.active = true; 40152 } 40153 } 40154 }); 40155 $(function() { 40156 var css_string = '' + 40157 '#vakata-dragged ins { display:block; text-decoration:none; width:16px; height:16px; margin:0 0 0 0; padding:0; position:absolute; top:4px; left:4px; } ' + 40158 '#vakata-dragged .jstree-ok { background:green; } ' + 40159 '#vakata-dragged .jstree-invalid { background:red; } ' + 40160 '#jstree-marker { padding:0; margin:0; line-height:12px; font-size:1px; overflow:hidden; height:12px; width:8px; position:absolute; top:-30px; z-index:10000; background-repeat:no-repeat; display:none; background-color:silver; } '; 40161 $.vakata.css.add_sheet({ str : css_string });
40162 m = $("<div>").attr({ id : "jstree-marker" }).hide().appendTo("body"); 40163 $(document).bind("drag_start.vakata", function (e, data) { 40164 if(data.data.jstree) { 40165 m.show(); 40166 } 40167 }); 40168 $(document).bind("drag_stop.vakata", function (e, data) { 40169 if(data.data.jstree) { m.hide(); } 40170 }); 40171 }); 40172})(jQuery); 40173//*/ 40174 40175/* 40176 * jsTree checkbox plugin 1.0 40177 * Inserts checkboxes in front of every node 40178 * Depends on the ui plugin 40179 * DOES NOT WORK NICELY WITH MULTITREE DRAG'N'DROP 40180 */ 40181(function ($) { 40182 $.jstree.plugin("checkbox", { 40183 __init : function () { 40184 // SENAD: We are not disabling select_node. 40185 // this.select_node = this.deselect_node = this.deselect_all = $.noop; 40186 this.get_selected = this.get_checked; 40187 40188 this.get_container() 40189 .bind("open_node.jstree create_node.jstree clean_node.jstree", $.proxy(function (e, data) { 40190 this._prepare_checkboxes(data.rslt.obj); 40191 }, this)) 40192 .bind("loaded.jstree", $.proxy(function (e) { 40193 this._prepare_checkboxes(); 40194 }, this)) 40195 .delegate("a .jstree-checkbox", "click.jstree", $.proxy(function (e) { 40196 if(this._get_node(e.target).hasClass("jstree-checked")) { this.uncheck_node(e.target); } 40197 else { this.check_node(e.target); } 40198 if(this.data.ui) { this.save_selected(); } 40199 if(this.data.cookies) { this.save_cookie("select_node"); } 40200 e.preventDefault(); 40201 }, this)); 40202 }, 40203 __destroy : function () { 40204 this.get_container().find(".jstree-checkbox").remove(); 40205 }, 40206 _fn : { 40207 _prepare_checkboxes : function (obj) { 40208 obj = !obj || obj == -1 ? this.get_container() : this._get_node(obj); 40209 var c, _this = this, t; 40210 obj.each(function () { 40211 t = $(this); 40212 c = t.is("li") && t.hasClass("jstree-checked") ? "jstree-checked" : "jstree-unchecked"; 40213 t.find("a").not(":has(.jstree-checkbox)").prepend("<ins class='jstree-checkbox'> </ins>").parent().not(".jstree-checked, .jstree-unchecked").addClass(c); 40214 }); 40215 if(obj.is("li")) { this._repair_state(obj); } 40216 else { obj.find("> ul > li").each(function () { _this._repair_state(this); }); } 40217 }, 40218 change_state : function (obj, state) { 40219 obj = this._get_node(obj); 40220 state = (state === false || state === true) ? state : obj.hasClass("jstree-checked"); 40221 if(state) { obj.find("li").andSelf().removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked"); } 40222 else { 40223 obj.find("li").andSelf().removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked"); 40224 if(this.data.ui) { this.data.ui.last_selected = obj; } 40225 this.data.checkbox.last_selected = obj; 40226 } 40227 obj.parentsUntil(".jstree", "li").each(function () { 40228 var $this = $(this); 40229 if(state) { 40230 if($this.children("ul").children(".jstree-checked, .jstree-undetermined").length) { 40231 $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined"); 40232 return false; 40233 } 40234 else { 40235 $this.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked"); 40236 } 40237 } 40238 else { 40239 if($this.children("ul").children(".jstree-unchecked, .jstree-undetermined").length) { 40240 $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined"); 40241 return false; 40242 } 40243 else { 40244 $this.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked"); 40245 } 40246 } 40247 }); 40248 if(this.data.ui) { this.data.ui.selected = this.get_checked(); } 40249 this.__callback(obj); 40250 }, 40251 check_node : function (obj) { 40252 this.change_state(obj, false); 40253 }, 40254 uncheck_node : function (obj) { 40255 this.change_state(obj, true); 40256 }, 40257 check_all : function () { 40258 var _this = this; 40259 this.get_container().children("ul").children("li").each(function () { 40260 _this.check_node(this, false); 40261 }); 40262 }, 40263 uncheck_all : function () { 40264 var _this = this; 40265 this.get_container().children("ul").children("li").each(function () { 40266 _this.change_state(this, true); 40267 }); 40268 }, 40269 40270 is_checked : function(obj) { 40271 obj = this._get_node(obj); 40272 return obj.length ? obj.is(".jstree-checked") : false; 40273 }, 40274 get_checked : function (obj) { 40275 obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj); 40276 return obj.find("> ul > .jstree-checked, .jstree-undetermined > ul > .jstree-checked"); 40277 }, 40278 get_unchecked : function (obj) { 40279 obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj); 40280 return obj.find("> ul > .jstree-unchecked, .jstree-undetermined > ul > .jstree-unchecked"); 40281 }, 40282 40283 show_checkboxes : function () { this.get_container().children("ul").removeClass("jstree-no-checkboxes"); }, 40284 hide_checkboxes : function () { this.get_container().children("ul").addClass("jstree-no-checkboxes"); }, 40285 40286 _repair_state : function (obj) { 40287 obj = this._get_node(obj); 40288 if(!obj.length) { return; } 40289 var a = obj.find("> ul > .jstree-checked").length, 40290 b = obj.find("> ul > .jstree-undetermined").length, 40291 c = obj.find("> ul > li").length; 40292 40293 if(c === 0) { if(obj.hasClass("jstree-undetermined")) { this.check_node(obj); } } 40294 else if(a === 0 && b === 0) { this.uncheck_node(obj); } 40295 else if(a === c) { this.check_node(obj); } 40296 else { 40297 obj.parentsUntil(".jstree","li").removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined"); 40298 } 40299 }, 40300 reselect : function () { 40301 if(this.data.ui) { 40302 var _this = this, 40303 s = this.data.ui.to_select; 40304 s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace('\\/','/').replace('/','\\/'); }); 40305 this.deselect_all(); 40306 $.each(s, function (i, val) { _this.check_node(val); }); 40307 this.__callback(); 40308 } 40309 } 40310 } 40311 }); 40312})(jQuery);
40313//*/ 40314 40315/* 40316 * jsTree XML 1.0 40317 * The XML data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions. 40318 */ 40319(function ($) { 40320 $.vakata.xslt = function (xml, xsl, callback) { 40321 var rs = "", xm, xs, processor, support; 40322 if(document.recalc) { 40323 xm = document.createElement('xml'); 40324 xs = document.createElement('xml'); 40325 xm.innerHTML = xml; 40326 xs.innerHTML = xsl; 40327 $("body").append(xm).append(xs); 40328 setTimeout( (function (xm, xs, callback) { 40329 return function () { 40330 callback.call(null, xm.transformNode(xs.XMLDocument)); 40331 setTimeout( (function (xm, xs) { return function () { jQuery("body").remove(xm).remove(xs); }; })(xm, xs), 200); 40332 }; 40333 }) (xm, xs, callback), 100); 40334 return true; 40335 } 40336 if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor !== "undefined") { 40337 processor = new XSLTProcessor(); 40338 support = $.isFunction(processor.transformDocument) ? (typeof window.XMLSerializer !== "undefined") : true; 40339 if(!support) { return false; } 40340 xml = new DOMParser().parseFromString(xml, "text/xml"); 40341 xsl = new DOMParser().parseFromString(xsl, "text/xml"); 40342 if($.isFunction(processor.transformDocument)) { 40343 rs = document.implementation.createDocument("", "", null); 40344 processor.transformDocument(xml, xsl, rs, null); 40345 callback.call(null, XMLSerializer().serializeToString(rs)); 40346 return true; 40347 } 40348 else { 40349 processor.importStylesheet(xsl); 40350 rs = processor.transformToFragment(xml, document); 40351 callback.call(null, $("<div>").append(rs).html()); 40352 return true; 40353 } 40354 } 40355 return false; 40356 }; 40357 var xsl = { 40358 'nest' : '<?xml version="1.0" encoding="utf-8" ?>' + 40359 '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' + 40360 '<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/html" />' + 40361 '<xsl:template match="/">' + 40362 ' <xsl:call-template name="nodes">' + 40363 ' <xsl:with-param name="node" select="/root" />' + 40364 ' </xsl:call-template>' + 40365 '</xsl:template>' + 40366 '<xsl:template name="nodes">' + 40367 ' <xsl:param name="node" />' + 40368 ' <ul>' + 40369 ' <xsl:for-each select="$node/item">' + 40370 ' <xsl:variable name="children" select="count(./item) > 0" />' + 40371 ' <li>' + 40372 ' <xsl:attribute name="class">' + 40373 ' <xsl:if test="position() = last()">jstree-last </xsl:if>' + 40374 ' <xsl:choose>' + 40375 ' <xsl:when test="@state = \'open\'">jstree-open </xsl:when>' + 40376 ' <xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' + 40377 ' <xsl:otherwise>jstree-leaf </xsl:otherwise>' + 40378 ' </xsl:choose>' + 40379 ' <xsl:value-of select="@class" />' + 40380 ' </xsl:attribute>' + 40381 ' <xsl:for-each select="@*">' + 40382 ' <xsl:if test="name() != \'class\' and name() != \'state\' and name() != \'hasChildren\'">' + 40383 ' <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 40384 ' </xsl:if>' + 40385 ' </xsl:for-each>' + 40386 ' <ins class="jstree-icon"><xsl:text> </xsl:text></ins>' + 40387 ' <xsl:for-each select="content/name">' + 40388 ' <a>' + 40389 ' <xsl:attribute name="href">' + 40390 ' <xsl:choose>' + 40391 ' <xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' + 40392 ' <xsl:otherwise>#</xsl:otherwise>' + 40393 ' </xsl:choose>' + 40394 ' </xsl:attribute>' + 40395 ' <xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' + 40396 ' <xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' + 40397 ' <xsl:for-each select="@*">' + 40398 ' <xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' + 40399 ' <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 40400 ' </xsl:if>' + 40401 ' </xsl:for-each>' + 40402 ' <ins>' + 40403 ' <xsl:attribute name="class">jstree-icon ' + 40404 ' <xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' + 40405 ' </xsl:attribute>' + 40406 ' <xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' + 40407 ' <xsl:text> </xsl:text>' + 40408 ' </ins>' + 40409 ' <xsl:value-of select="current()" />' + 40410 ' </a>' + 40411 ' </xsl:for-each>' + 40412 ' <xsl:if test="$children or @hasChildren"><xsl:call-template name="nodes"><xsl:with-param name="node" select="current()" /></xsl:call-template></xsl:if>' + 40413 ' </li>' + 40414 ' </xsl:for-each>' + 40415 ' </ul>' + 40416 '</xsl:template>' + 40417 '</xsl:stylesheet>', 40418 40419 'flat' : '<?xml version="1.0" encoding="utf-8" ?>' + 40420 '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' + 40421 '<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/xml" />' + 40422 '<xsl:template match="/">' + 40423 ' <ul>' + 40424 ' <xsl:for-each select="//item[not(@parent_id) or @parent_id=0 or not(@parent_id = //item/@id)]">' + /* the last `or` may be removed */ 40425 ' <xsl:call-template name="nodes">' + 40426 ' <xsl:with-param name="node" select="." />' + 40427 ' <xsl:with-param name="is_last" select="number(position() = last())" />' + 40428 ' </xsl:call-template>' + 40429 ' </xsl:for-each>' + 40430 ' </ul>' + 40431 '</xsl:template>' + 40432 '<xsl:template name="nodes">' + 40433 ' <xsl:param name="node" />' + 40434 ' <xsl:param name="is_last" />' + 40435 ' <xsl:variable name="children" select="count(//item[@parent_id=$node/attribute::id]) > 0" />' + 40436 ' <li>' + 40437 ' <xsl:attribute name="class">' + 40438 ' <xsl:if test="$is_last = true()">jstree-last </xsl:if>' + 40439 ' <xsl:choose>' + 40440 ' <xsl:when test="@state = \'open\'">jstree-open </xsl:when>' + 40441 ' <xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' + 40442 ' <xsl:otherwise>jstree-leaf </xsl:otherwise>' + 40443 ' </xsl:choose>' + 40444 ' <xsl:value-of select="@class" />' + 40445 ' </xsl:attribute>' + 40446 ' <xsl:for-each select="@*">' + 40447 ' <xsl:if test="name() != \'parent_id\' and name() != \'hasChildren\' and name() != \'class\' and name() != \'state\'">
40447' + 40448 ' <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 40449 ' </xsl:if>' + 40450 ' </xsl:for-each>' + 40451 ' <ins class="jstree-icon"><xsl:text> </xsl:text></ins>' + 40452 ' <xsl:for-each select="content/name">' + 40453 ' <a>' + 40454 ' <xsl:attribute name="href">' + 40455 ' <xsl:choose>' + 40456 ' <xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' + 40457 ' <xsl:otherwise>#</xsl:otherwise>' + 40458 ' </xsl:choose>' + 40459 ' </xsl:attribute>' + 40460 ' <xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' + 40461 ' <xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' + 40462 ' <xsl:for-each select="@*">' + 40463 ' <xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' + 40464 ' <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' + 40465 ' </xsl:if>' + 40466 ' </xsl:for-each>' + 40467 ' <ins>' + 40468 ' <xsl:attribute name="class">jstree-icon ' + 40469 ' <xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' + 40470 ' </xsl:attribute>' + 40471 ' <xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' + 40472 ' <xsl:text> </xsl:text>' + 40473 ' </ins>' + 40474 ' <xsl:value-of select="current()" />' + 40475 ' </a>' + 40476 ' </xsl:for-each>' + 40477 ' <xsl:if test="$children">' + 40478 ' <ul>' + 40479 ' <xsl:for-each select="//item[@parent_id=$node/attribute::id]">' + 40480 ' <xsl:call-template name="nodes">' + 40481 ' <xsl:with-param name="node" select="." />' + 40482 ' <xsl:with-param name="is_last" select="number(position() = last())" />' + 40483 ' </xsl:call-template>' + 40484 ' </xsl:for-each>' + 40485 ' </ul>' + 40486 ' </xsl:if>' + 40487 ' </li>' + 40488 '</xsl:template>' + 40489 '</xsl:stylesheet>' 40490 }; 40491 $.jstree.plugin("xml_data", { 40492 defaults : { 40493 data : false, 40494 ajax : false, 40495 xsl : "flat", 40496 clean_node : false, 40497 correct_state : true 40498 }, 40499 _fn : { 40500 load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_xml(obj, function () { _this.__callback({ "obj" : obj }); s_call.call(this); }, e_call); }, 40501 _is_loaded : function (obj) { 40502 var s = this._get_settings().xml_data; 40503 obj = this._get_node(obj); 40504 return obj == -1 || !obj || !s.ajax || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0; 40505 }, 40506 load_node_xml : function (obj, s_call, e_call) { 40507 var s = this.get_settings().xml_data, 40508 error_func = function () {}, 40509 success_func = function () {}; 40510 40511 obj = this._get_node(obj); 40512 if(obj && obj !== -1) { 40513 if(obj.data("jstree-is-loading")) { return; } 40514 else { obj.data("jstree-is-loading",true); } 40515 } 40516 switch(!0) { 40517 case (!s.data && !s.ajax): throw "Neither data nor ajax settings supplied."; 40518 case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)): 40519 if(!obj || obj == -1) { 40520 this.parse_xml(s.data, $.proxy(function (d) { 40521 if(d) { 40522 d = d.replace(/ ?xmlns="[^"]*"/ig, ""); 40523 if(d.length > 10) { 40524 d = $(d); 40525 this.get_container().children("ul").empty().append(d.children()); 40526 if(s.clean_node) { this.clean_node(obj); } 40527 if(s_call) { s_call.call(this); } 40528 } 40529 } 40530 else { 40531 if(s.correct_state) { 40532 this.get_container().children("ul").empty(); 40533 if(s_call) { s_call.call(this); } 40534 } 40535 } 40536 }, this)); 40537 } 40538 break; 40539 case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1): 40540 error_func = function (x, t, e) { 40541 var ef = this.get_settings().xml_data.ajax.error; 40542 if(ef) { ef.call(this, x, t, e); } 40543 if(obj !== -1 && obj.length) { 40544 obj.children(".jstree-loading").removeClass("jstree-loading"); 40545 obj.data("jstree-is-loading",false); 40546 if(t === "success" && s.correct_state) { obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); } 40547 } 40548 else { 40549 if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); } 40550 }
40551 if(e_call) { e_call.call(this); } 40552 }; 40553 success_func = function (d, t, x) { 40554 d = x.responseText; 40555 var sf = this.get_settings().xml_data.ajax.success; 40556 if(sf) { d = sf.call(this,d,t,x) || d; } 40557 if(d == "") { 40558 return error_func.call(this, x, t, ""); 40559 } 40560 this.parse_xml(d, $.proxy(function (d) { 40561 if(d) { 40562 d = d.replace(/ ?xmlns="[^"]*"/ig, ""); 40563 if(d.length > 10) { 40564 d = $(d); 40565 if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); } 40566 else { obj.children(".jstree-loading").removeClass("jstree-loading"); obj.append(d); obj.data("jstree-is-loading",false); } 40567 if(s.clean_node) { this.clean_node(obj); } 40568 if(s_call) { s_call.call(this); } 40569 } 40570 else { 40571 if(obj && obj !== -1) { 40572 obj.children(".jstree-loading").removeClass("jstree-loading"); 40573 obj.data("jstree-is-loading",false); 40574 if(s.correct_state) { 40575 obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); 40576 if(s_call) { s_call.call(this); } 40577 } 40578 } 40579 else { 40580 if(s.correct_state) { 40581 this.get_container().children("ul").empty(); 40582 if(s_call) { s_call.call(this); } 40583 } 40584 } 40585 } 40586 } 40587 }, this)); 40588 }; 40589 s.ajax.context = this; 40590 s.ajax.error = error_func; 40591 s.ajax.success = success_func; 40592 if(!s.ajax.dataType) { s.ajax.dataType = "xml"; } 40593 if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); } 40594 if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); } 40595 $.ajax(s.ajax); 40596 break; 40597 } 40598 }, 40599 parse_xml : function (xml, callback) { 40600 var s = this._get_settings().xml_data; 40601 $.vakata.xslt(xml, xsl[s.xsl], callback); 40602 }, 40603 get_xml : function (tp, obj, li_attr, a_attr, is_callback) { 40604 var result = "", 40605 s = this._get_settings(), 40606 _this = this, 40607 tmp1, tmp2, li, a, lang; 40608 if(!tp) { tp = "flat"; } 40609 if(!is_callback) { is_callback = 0; } 40610 obj = this._get_node(obj); 40611 if(!obj || obj === -1) { obj = this.get_container().find("> ul > li"); } 40612 li_attr = $.isArray(li_attr) ? li_attr : [ "id", "class" ]; 40613 if(!is_callback && this.data.types && $.inArray(s.types.type_attr, li_attr) === -1) { li_attr.push(s.types.type_attr); } 40614 40615 a_attr = $.isArray(a_attr) ? a_attr : [ ]; 40616 40617 if(!is_callback) { result += "<root>"; } 40618 obj.each(function () { 40619 result += "<item"; 40620 li = $(this); 40621 $.each(li_attr, function (i, v) { result += " " + v + "=\"" + (li.attr(v) || "").replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"") + "\""; }); 40622 if(li.hasClass("jstree-open")) { result += " state=\"open\""; } 40623 if(li.hasClass("jstree-closed")) { result += " state=\"closed\""; } 40624 if(tp === "flat") { result += " parent_id=\"" + is_callback + "\""; } 40625 result += ">"; 40626 result += "<content>"; 40627 a = li.children("a"); 40628 a.each(function () { 40629 tmp1 = $(this); 40630 lang = false; 40631 result += "<name"; 40632 if($.inArray("languages", s.plugins) !== -1) { 40633 $.each(s.languages, function (k, z) { 40634 if(tmp1.hasClass(z)) { result += " lang=\"" + z + "\""; lang = z; return false; } 40635 }); 40636 } 40637 if(a_attr.length) { 40638 $.each(a_attr, function (k, z) { 40639 result += " " + z + "=\"" + (tmp1.attr(z) || "").replace(/jstree[^ ]*|$/ig,'') + "\""; 40640 }); 40641 } 40642 if(tmp1.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"").length) { 40643 result += ' icon="' + tmp1.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"") + '"'; 40644 } 40645 if(tmp1.children("ins").get(0).style.backgroundImage.length) { 40646 result += ' icon="' + tmp1.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","") + '"'; 40647 } 40648 result += ">"; 40649 result += "<![CDATA[" + _this.get_text(tmp1, lang) + "]]>"; 40650 result += "</name>"; 40651 });
40652 result += "</content>"; 40653 tmp2 = li[0].id; 40654 li = li.find("> ul > li"); 40655 if(li.length) { tmp2 = _this.get_xml(tp, li, li_attr, a_attr, tmp2); } 40656 else { tmp2 = ""; } 40657 if(tp == "nest") { result += tmp2; } 40658 result += "</item>"; 40659 if(tp == "flat") { result += tmp2; } 40660 }); 40661 if(!is_callback) { result += "</root>"; } 40662 return result; 40663 } 40664 } 40665 }); 40666})(jQuery); 40667//*/ 40668 40669/* 40670 * jsTree search plugin 1.0 40671 * Enables both sync and async search on the tree 40672 * DOES NOT WORK WITH JSON PROGRESSIVE RENDER 40673 */ 40674(function ($) { 40675 $.expr[':'].jstree_contains = function(a,i,m){ 40676 return (a.textContent || a.innerText || "").toLowerCase().indexOf(m[3].toLowerCase())>=0; 40677 }; 40678 $.jstree.plugin("search", { 40679 __init : function () { 40680 this.data.search.str = ""; 40681 this.data.search.result = $(); 40682 }, 40683 defaults : { 40684 ajax : false, // OR ajax object 40685 case_insensitive : false 40686 }, 40687 _fn : { 40688 search : function (str, skip_async) { 40689 if(str === "") { return; } 40690 var s = this.get_settings().search, 40691 t = this, 40692 error_func = function () { }, 40693 success_func = function () { }; 40694 this.data.search.str = str; 40695 40696 if(!skip_async && s.ajax !== false && this.get_container().find(".jstree-closed:eq(0)").length > 0) { 40697 this.search.supress_callback = true; 40698 error_func = function () { }; 40699 success_func = function (d, t, x) { 40700 var sf = this.get_settings().search.ajax.success; 40701 if(sf) { d = sf.call(this,d,t,x) || d; } 40702 this.data.search.to_open = d; 40703 this._search_open(); 40704 }; 40705 s.ajax.context = this; 40706 s.ajax.error = error_func; 40707 s.ajax.success = success_func; 40708 if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, str); } 40709 if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, str); } 40710 if(!s.ajax.data) { s.ajax.data = { "search_string" : str }; } 40711 if(!s.ajax.dataType || /^json/.exec(s.ajax.dataType)) { s.ajax.dataType = "json"; } 40712 $.ajax(s.ajax); 40713 return; 40714 } 40715 if(this.data.search.result.length) { this.clear_search(); } 40716 this.data.search.result = this.get_container().find("a" + (this.data.languages ? "." + this.get_lang() : "" ) + ":" + (s.case_insensitive ? "jstree_contains" : "contains") + "(" + this.data.search.str + ")"); 40717 this.data.search.result.addClass("jstree-search").parents(".jstree-closed").each(function () { 40718 t.open_node(this, false, true); 40719 }); 40720 this.__callback({ nodes : this.data.search.result, str : str }); 40721 }, 40722 clear_search : function (str) { 40723 this.data.search.result.removeClass("jstree-search"); 40724 this.__callback(this.data.search.result); 40725 this.data.search.result = $(); 40726 }, 40727 _search_open : function (is_callback) { 40728 var _this = this, 40729 done = true, 40730 current = [], 40731 remaining = []; 40732 if(this.data.search.to_open.length) { 40733 $.each(this.data.search.to_open, function (i, val) { 40734 if(val == "#") { return true; } 40735 if($(val).length && $(val).is(".jstree-closed")) { current.push(val); } 40736 else { remaining.push(val); } 40737 }); 40738 if(current.length) { 40739 this.data.search.to_open = remaining; 40740 $.each(current, function (i, val) { 40741 _this.open_node(val, function () { _this._search_open(true); }); 40742 }); 40743 done = false; 40744 } 40745 } 40746 if(done) { this.search(this.data.search.str, true); } 40747 } 40748 } 40749 }); 40750})(jQuery); 40751//*/ 40752 40753/* 40754 * jsTree contextmenu plugin 1.0 40755 */ 40756(function ($) { 40757 $.vakata.context = { 40758 cnt : $("<div id='vakata-contextmenu'>"), 40759 vis : false, 40760 tgt : false, 40761 par : false, 40762 func : false, 40763 data : false, 40764 show : function (s, t, x, y, d, p) { 40765 var html = $.vakata.context.parse(s), h, w; 40766 if(!html) { return; } 40767 $.vakata.context.vis = true; 40768 $.vakata.context.tgt = t; 40769 $.vakata.context.par = p || t || null; 40770 $.vakata.context.data = d || null; 40771 $.vakata.context.cnt 40772 .html(html) 40773 .css({ "visibility" : "hidden", "display" : "block", "left" : 0, "top" : 0 }); 40774 h = $.vakata.context.cnt.height(); 40775 w = $.vakata.context.cnt.width(); 40776 if(x + w >
40776 $(document).width()) { 40777 x = $(document).width() - (w + 5); 40778 $.vakata.context.cnt.find("li > ul").addClass("right"); 40779 } 40780 if(y + h > $(document).height()) { 40781 y = y - (h + t[0].offsetHeight); 40782 $.vakata.context.cnt.find("li > ul").addClass("bottom"); 40783 } 40784 40785 $.vakata.context.cnt 40786 .css({ "left" : x, "top" : y }) 40787 .find("li:has(ul)") 40788 .bind("mouseenter", function (e) { 40789 var w = $(document).width(), 40790 h = $(document).height(), 40791 ul = $(this).children("ul").show(); 40792 if(w !== $(document).width()) { ul.toggleClass("right"); } 40793 if(h !== $(document).height()) { ul.toggleClass("bottom"); } 40794 }) 40795 .bind("mouseleave", function (e) { 40796 $(this).children("ul").hide(); 40797 }) 40798 .end() 40799 .css({ "visibility" : "visible" }) 40800 .show(); 40801 $(document).triggerHandler("context_show.vakata"); 40802 }, 40803 hide : function () { 40804 $.vakata.context.vis = false; 40805 $.vakata.context.cnt.attr("class","").hide(); 40806 $(document).triggerHandler("context_hide.vakata"); 40807 }, 40808 parse : function (s, is_callback) { 40809 if(!s) { return false; } 40810 var str = "", 40811 tmp = false, 40812 was_sep = true; 40813 if(!is_callback) { $.vakata.context.func = {}; } 40814 str += "<ul>"; 40815 $.each(s, function (i, val) { 40816 if(!val) { return true; } 40817 $.vakata.context.func[i] = val.action; 40818 if(!was_sep && val.separator_before) { 40819 str += "<li class='vakata-separator vakata-separator-before'></li>"; 40820 } 40821 was_sep = false; 40822 str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins "; 40823 if(val.icon && val.icon.indexOf("/") === -1) { str += " class='" + val.icon + "' "; } 40824 if(val.icon && val.icon.indexOf("/") !== -1) { str += " style='background:url(" + val.icon + ") center center no-repeat;' "; } 40825 str += "> </ins><a href='#' rel='" + i + "'>"; 40826 if(val.submenu) { 40827 str += "<span style='float:right;'>»</span>"; 40828 } 40829 str += val.label + "</a>"; 40830 if(val.submenu) { 40831 tmp = $.vakata.context.parse(val.submenu, true); 40832 if(tmp) { str += tmp; } 40833 } 40834 str += "</li>"; 40835 if(val.separator_after) { 40836 str += "<li class='vakata-separator vakata-separator-after'></li>"; 40837 was_sep = true; 40838 } 40839 }); 40840 str = str.replace(/<li class\='vakata-separator vakata-separator-after'\><\/li\>$/,""); 40841 str += "</ul>"; 40842 return str.length > 10 ? str : false; 40843 }, 40844 exec : function (i) { 40845 if($.isFunction($.vakata.context.func[i])) { 40846 $.vakata.context.func[i].call($.vakata.context.data, $.vakata.context.par); 40847 return true; 40848 } 40849 else { return false; } 40850 } 40851 }; 40852 $(function () { 40853 var css_string = '' + 40854 '#vakata-contextmenu { display:none; position:absolute; margin:0; padding:0; min-width:180px; background:#ebebeb; border:1px solid silver; z-index:10000; *width:180px; } ' + 40855 '#vakata-contextmenu ul { min-width:180px; *width:180px; } ' + 40856 '#vakata-contextmenu ul, #vakata-contextmenu li { margin:0; padding:0; list-style-type:none; display:block; } ' + 40857 '#vakata-contextmenu li { line-height:20px; min-height:20px; position:relative; padding:0px; } ' + 40858 '#vakata-contextmenu li a { padding:1px 6px; line-height:17px; display:block; text-decoration:none; margin:1px 1px 0 1px; } ' + 40859 '#vakata-contextmenu li ins { float:left; width:16px; height:16px; text-decoration:none; margin-right:2px; } ' + 40860 '#vakata-contextmenu li a:hover, #vakata-contextmenu li.vakata-hover > a { background:gray; color:white; } ' + 40861 '#vakata-contextmenu li ul { display:none; position:absolute; top:-2px; left:100%; background:#ebebeb; border:1px solid gray; } ' + 40862 '#vakata-contextmenu .right { right:100%; left:auto; } ' + 40863 '#vakata-contextmenu .bottom { bottom:-1px; top:auto; } ' + 40864 '#vakata-contextmenu li.vakata-separator { min-height:0; height:1px; line-height:1px; font-size:1px; overflow:hidden; margin:0 2px; background:silver; /* border-top:1px solid #fefefe; */ padding:0; } '; 40865 $.vakata.css.add_sheet({ str : css_string });
40866 $.vakata.context.cnt 40867 .delegate("a","click", function (e) { e.preventDefault(); }) 40868 .delegate("a","mouseup", function (e) { 40869 if(!$(this).parent().hasClass("jstree-contextmenu-disabled") && $.vakata.context.exec($(this).attr("rel"))) { 40870 $.vakata.context.hide(); 40871 } 40872 else { $(this).blur(); } 40873 }) 40874 .delegate("a","mouseover", function () { 40875 $.vakata.context.cnt.find(".vakata-hover").removeClass("vakata-hover"); 40876 }) 40877 .appendTo("body"); 40878 $(document).bind("mousedown", function (e) { if($.vakata.context.vis && !$.contains($.vakata.context.cnt[0], e.target)) { $.vakata.context.hide(); } }); 40879 if(typeof $.hotkeys !== "undefined") { 40880 $(document) 40881 .bind("keydown", "up", function (e) { 40882 if($.vakata.context.vis) { 40883 var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").prevAll("li:not(.vakata-separator)").first(); 40884 if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").last(); } 40885 o.addClass("vakata-hover"); 40886 e.stopImmediatePropagation(); 40887 e.preventDefault(); 40888 } 40889 }) 40890 .bind("keydown", "down", function (e) { 40891 if($.vakata.context.vis) { 40892 var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").nextAll("li:not(.vakata-separator)").first(); 40893 if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").first(); } 40894 o.addClass("vakata-hover"); 40895 e.stopImmediatePropagation(); 40896 e.preventDefault(); 40897 } 40898 }) 40899 .bind("keydown", "right", function (e) { 40900 if($.vakata.context.vis) { 40901 $.vakata.context.cnt.find(".vakata-hover").children("ul").show().children("li:not(.vakata-separator)").removeClass("vakata-hover").first().addClass("vakata-hover"); 40902 e.stopImmediatePropagation(); 40903 e.preventDefault(); 40904 } 40905 }) 40906 .bind("keydown", "left", function (e) { 40907 if($.vakata.context.vis) { 40908 $.vakata.context.cnt.find(".vakata-hover").children("ul").hide().children(".vakata-separator").removeClass("vakata-hover"); 40909 e.stopImmediatePropagation(); 40910 e.preventDefault(); 40911 } 40912 }) 40913 .bind("keydown", "esc", function (e) { 40914 $.vakata.context.hide(); 40915 e.preventDefault(); 40916 }) 40917 .bind("keydown", "space", function (e) { 40918 $.vakata.context.cnt.find(".vakata-hover").last().children("a").click(); 40919 e.preventDefault(); 40920 }); 40921 } 40922 }); 40923 40924 $.jstree.plugin("contextmenu", { 40925 __init : function () { 40926 this.get_container() 40927 .delegate("a", "contextmenu.jstree", $.proxy(function (e) { 40928 e.preventDefault(); 40929 this.show_contextmenu(e.currentTarget, e.pageX, e.pageY); 40930 }, this)) 40931 .bind("destroy.jstree", $.proxy(function () { 40932 if(this.data.contextmenu) { 40933 $.vakata.context.hide(); 40934 } 40935 }, this)); 40936 $(document).bind("context_hide.vakata", $.proxy(function () { this.data.contextmenu = false; }, this)); 40937 }, 40938 defaults : { 40939 select_node : false, // requires UI plugin 40940 show_at_node : true, 40941 items : { // Could be a function that should return an object like this one 40942 "create" : { 40943 "separator_before" : false, 40944 "separator_after" : true, 40945 "label" : "Create", 40946 "action" : function (obj) { this.create(obj); } 40947 }, 40948 "rename" : { 40949 "separator_before" : false, 40950 "separator_after" : false, 40951 "label" : "Rename", 40952 "action" : function (obj) { this.rename(obj); } 40953 }, 40954 "remove" : { 40955 "separator_before" : false, 40956 "icon" : false, 40957 "separator_after" : false, 40958 "label" : "Delete", 40959 "action" : function (obj) { this.remove(obj); } 40960 }, 40961 "ccp" : { 40962 "separator_before" : true, 40963 "icon" : false, 40964 "separator_after" : false, 40965 "label" : "Edit", 40966 "action" : false, 40967 "submenu" : { 40968 "cut" : { 40969 "separator_before" : false, 40970 "separator_after" : false, 40971 "label" : "Cut", 40972 "action" : function (obj) { this.cut(obj); } 40973 }, 40974 "copy" : { 40975 "separator_before" : false, 40976 "icon" : false, 40977 "separator_after" : false, 40978 "label" : "Copy", 40979 "action" : function (obj) { this.copy(obj); } 40980 }, 40981 "paste" : { 40982 "separator_before" : false, 40983 "icon" : false, 40984 "separator_after" : false, 40985 "label" : "Paste", 40986 "action" : function (obj) { this.paste(obj); } 40987 } 40988 } 40989 } 40990 } 40991 }, 40992 _fn : { 40993 show_contextmenu : function (obj, x, y) { 40994 obj = this._get_node(obj); 40995 var s = this.get_settings().contextmenu, 40996 a = obj.children("a:visible:eq(0)"), 40997 o = false; 40998 if(s.select_node && this.data.ui && !this.is_selected(obj)) { 40999 this.deselect_all(); 41000 this.select_node(obj, true); 41001 } 41002 if(s.show_at_node || typeof x === "undefined" || typeof y === "undefined") { 41003 o = a.offset(); 41004 x = o.left; 41005 y = o.top + this.data.core.li_height; 41006 } 41007 if($.isFunction(s.items)) { s.items = s.items.call(this, obj); } 41008 this.data.contextmenu = true; 41009 $.vakata.context.show(s.items, a, x, y, this, obj); 41010 if(this.data.themes) { $.vakata.context.cnt.attr("class", "jstree-" + this.data.themes.theme + "-context"); } 41011 } 41012 } 41013 }); 41014})(jQuery);
41015//*/ 41016 41017/* 41018 * jsTree types plugin 1.0 41019 * Adds support types of nodes 41020 * You can set an attribute on each li node, that represents its type. 41021 * According to the type setting the node may get custom icon/validation rules 41022 */ 41023(function ($) { 41024 $.jstree.plugin("types", { 41025 __init : function () { 41026 var s = this._get_settings().types; 41027 this.data.types.attach_to = []; 41028 this.get_container() 41029 .bind("init.jstree", $.proxy(function () { 41030 var types = s.types, 41031 attr = s.type_attr, 41032 icons_css = "", 41033 _this = this; 41034 41035 $.each(types, function (i, tp) { 41036 $.each(tp, function (k, v) { 41037 if(!/^(max_depth|max_children|icon|valid_children)$/.test(k)) { _this.data.types.attach_to.push(k); } 41038 }); 41039 if(!tp.icon) { return true; } 41040 if( tp.icon.image || tp.icon.position) { 41041 if(i == "default") { icons_css += '.jstree-' + _this.get_index() + ' a > .jstree-icon { '; } 41042 else { icons_css += '.jstree-' + _this.get_index() + ' li[' + attr + '=' + i + '] > a > .jstree-icon { '; } 41043 if(tp.icon.image) { icons_css += ' background-image:url(' + tp.icon.image + '); '; } 41044 if(tp.icon.position){ icons_css += ' background-position:' + tp.icon.position + '; '; } 41045 else { icons_css += ' background-position:0 0; '; } 41046 icons_css += '} '; 41047 } 41048 }); 41049 if(icons_css != "") { $.vakata.css.add_sheet({ 'str' : icons_css }); } 41050 }, this)) 41051 .bind("before.jstree", $.proxy(function (e, data) { 41052 if($.inArray(data.func, this.data.types.attach_to) !== -1) { 41053 var s = this._get_settings().types.types, 41054 t = this._get_type(data.args[0]); 41055 if( 41056 ( 41057 (s[t] && typeof s[t][data.func] !== "undefined") || 41058 (s["default"] && typeof s["default"][data.func] !== "undefined") 41059 ) && !this._check(data.func, data.args[0]) 41060 ) { 41061 e.stopImmediatePropagation(); 41062 return false; 41063 } 41064 } 41065 }, this)); 41066 }, 41067 defaults : { 41068 // defines maximum number of root nodes (-1 means unlimited, -2 means disable max_children checking) 41069 max_children : -1, 41070 // defines the maximum depth of the tree (-1 means unlimited, -2 means disable max_depth checking) 41071 max_depth : -1, 41072 // defines valid node types for the root nodes 41073 valid_children : "all", 41074 41075 // where is the type stores (the rel attribute of the LI element) 41076 type_attr : "rel", 41077 // a list of types 41078 types : { 41079 // the default type 41080 "default" : { 41081 "max_children" : -1, 41082 "max_depth" : -1, 41083 "valid_children": "all" 41084 41085 // Bound functions - you can bind any other function here (using boolean or function) 41086 //"select_node" : true, 41087 //"open_node" : true, 41088 //"close_node" : true, 41089 //"create_node" : true, 41090 //"delete_node" : true 41091 } 41092 } 41093 }, 41094 _fn : { 41095 _get_type : function (obj) { 41096 obj = this._get_node(obj); 41097 return (!obj || !obj.length) ? false : obj.attr(this._get_settings().types.type_attr) || "default"; 41098 }, 41099 set_type : function (str, obj) { 41100 obj = this._get_node(obj); 41101 return (!obj.length || !str) ? false : obj.attr(this._get_settings().types.type_attr, str); 41102 }, 41103 _check : function (rule, obj, opts) { 41104 var v = false, t = this._get_type(obj), d = 0, _this = this, s = this._get_settings().types; 41105 if(obj === -1) { 41106 if(!!s[rule]) { v = s[rule]; } 41107 else { return; } 41108 } 41109 else { 41110 if(t === false) { return; } 41111 if(!!s.types[t] && !!s.types[t][rule]) { v = s.types[t][rule]; } 41112 else if(!!s.types["default"] && !!s.types["default"][rule]) { v = s.types["default"][rule]; } 41113 } 41114 if($.isFunction(v)) { v = v.call(this, obj); } 41115 if(rule === "max_depth" && obj !== -1 && opts !== false && s.max_depth !== -2 && v !== 0) { 41116 // also include the node itself - otherwise if root node it is not checked 41117 this._get_node(obj).children("a:eq(0)").parentsUntil(".jstree","li").each(function (i) { 41118 // check if current depth already exceeds global tree depth 41119 if(s.max_depth !== -1 && s.max_depth - (i + 1) <= 0) { v = 0; return false; } 41120 d = (i === 0) ? v : _this._check(rule, this, false); 41121 // check if current node max depth is already matched or exceeded 41122 if(d !== -1 && d - (i + 1) <= 0) { v = 0; return false; } 41123 // otherwise - set the max depth to the current value minus current depth 41124 if(d >= 0 && (d - (i + 1) < v || v < 0) ) { v = d - (i + 1); } 41125 // if the global tree depth exists and it minus the nodes calculated so far is less than `v` or `v` is unlimited 41126 if(s.max_depth >= 0 && (s.max_depth - (i + 1) < v || v < 0) ) { v = s.max_depth - (i + 1); } 41127 });
41128 } 41129 return v; 41130 }, 41131 check_move : function () { 41132 if(!this.__call_old()) { return false; } 41133 var m = this._get_move(), 41134 s = m.rt._get_settings().types, 41135 mc = m.rt._check("max_children", m.cr), 41136 md = m.rt._check("max_depth", m.cr), 41137 vc = m.rt._check("valid_children", m.cr), 41138 ch = 0, d = 1, t; 41139 41140 if(vc === "none") { return false; } 41141 if($.isArray(vc) && m.ot && m.ot._get_type) { 41142 m.o.each(function () { 41143 if($.inArray(m.ot._get_type(this), vc) === -1) { d = false; return false; } 41144 }); 41145 if(d === false) { return false; } 41146 } 41147 if(s.max_children !== -2 && mc !== -1) { 41148 ch = m.cr === -1 ? this.get_container().children("> ul > li").not(m.o).length : m.cr.children("> ul > li").not(m.o).length; 41149 if(ch + m.o.length > mc) { return false; } 41150 } 41151 if(s.max_depth !== -2 && md !== -1) { 41152 d = 0; 41153 if(md === 0) { return false; } 41154 if(typeof m.o.d === "undefined") { 41155 // TODO: deal with progressive rendering and async when checking max_depth (how to know the depth of the moved node) 41156 t = m.o; 41157 while(t.length > 0) { 41158 t = t.find("> ul > li"); 41159 d ++; 41160 } 41161 m.o.d = d; 41162 } 41163 if(md - m.o.d < 0) { return false; } 41164 } 41165 return true; 41166 }, 41167 create_node : function (obj, position, js, callback, is_loaded, skip_check) { 41168 if(!skip_check && (is_loaded || this._is_loaded(obj))) { 41169 var p = (position && position.match(/^before|after$/i) && obj !== -1) ? this._get_parent(obj) : this._get_node(obj), 41170 s = this._get_settings().types, 41171 mc = this._check("max_children", p), 41172 md = this._check("max_depth", p), 41173 vc = this._check("valid_children", p), 41174 ch; 41175 if(!js) { js = {}; } 41176 if(vc === "none") { return false; } 41177 if($.isArray(vc)) { 41178 if(!js.attr || !js.attr[s.type_attr]) { 41179 if(!js.attr) { js.attr = {}; } 41180 js.attr[s.type_attr] = vc[0]; 41181 } 41182 else { 41183 if($.inArray(js.attr[s.type_attr], vc) === -1) { return false; } 41184 } 41185 } 41186 if(s.max_children !== -2 && mc !== -1) { 41187 ch = p === -1 ? this.get_container().children("> ul > li").length : p.children("> ul > li").length; 41188 if(ch + 1 > mc) { return false; } 41189 } 41190 if(s.max_depth !== -2 && md !== -1 && (md - 1) < 0) { return false; } 41191 } 41192 return this.__call_old(true, obj, position, js, callback, is_loaded, skip_check); 41193 } 41194 } 41195 }); 41196})(jQuery); 41197//*/ 41198 41199/* 41200 * jsTree HTML data 1.0 41201 * The HTML data store. Datastores are build by replacing the `load_node` and `_is_loaded` functions. 41202 */ 41203(function ($) { 41204 $.jstree.plugin("html_data", { 41205 __init : function () { 41206 // this used to use html() and clean the whitespace, but this way any attached data was lost 41207 this.data.html_data.original_container_html = this.get_container().find(" > ul > li").clone(true); 41208 // remove white space from LI node - otherwise nodes appear a bit to the right 41209 this.data.html_data.original_container_html.find("li").andSelf().contents().filter(function() { return this.nodeType == 3; }).remove(); 41210 }, 41211 defaults : { 41212 data : false, 41213 ajax : false, 41214 correct_state : true 41215 }, 41216 _fn : { 41217 load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_html(obj, function () { _this.__callback({ "obj" : obj }); s_call.call(this); }, e_call); }, 41218 _is_loaded : function (obj) { 41219 obj = this._get_node(obj); 41220 return obj == -1 || !obj || !this._get_settings().html_data.ajax || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0; 41221 }, 41222 load_node_html : function (obj, s_call, e_call) { 41223 var d, 41224 s = this.get_settings().html_data, 41225 error_func = function () {}, 41226 success_func = function () {}; 41227 obj = this._get_node(obj); 41228 if(obj && obj !== -1) { 41229 if(obj.data("jstree-is-loading")) { return; } 41230 else { obj.data("jstree-is-loading",true); } 41231 } 41232 switch(!0) { 41233 case (!s.data && !s.ajax): 41234 if(!obj || obj == -1) { 41235 this.get_container() 41236 .children("ul").empty() 41237 .append(this.data.html_data.original_container_html) 41238 .find("li, a").filter(function () { return this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'> </ins>").end() 41239 .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); 41240 this.clean_node(); 41241 } 41242 if(s_call) { s_call.call(this); } 41243 break; 41244 case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)): 41245 if(!obj || obj == -1) { 41246 d = $(s.data); 41247 if(!d.is("ul")) { d = $("<ul>").append(d); } 41248 this.get_container() 41249 .children("ul").empty().append(d.children()) 41250 .find("li, a").filter(function () { return this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'> </ins>").end() 41251 .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); 41252 this.clean_node(); 41253 } 41254 if(s_call) { s_call.call(this); } 41255 break; 41256 case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1): 41257 obj = this._get_node(obj); 41258 error_func = function (x, t, e) { 41259 var ef = this.get_settings().html_data.ajax.error; 41260 if(ef) { ef.call(this, x, t, e); } 41261 if(obj != -1 && obj.length) { 41262 obj.children(".jstree-loading").removeClass("jstree-loading"); 41263 obj.data("jstree-is-loading",false); 41264 if(t === "success" && s.correct_state) { obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); } 41265 } 41266 else { 41267 if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); } 41268 }
41269 if(e_call) { e_call.call(this); } 41270 }; 41271 success_func = function (d, t, x) { 41272 var sf = this.get_settings().html_data.ajax.success; 41273 if(sf) { d = sf.call(this,d,t,x) || d; } 41274 if(d == "") { 41275 return error_func.call(this, x, t, ""); 41276 } 41277 if(d) { 41278 d = $(d); 41279 if(!d.is("ul")) { d = $("<ul>").append(d); } 41280 if(obj == -1 || !obj) { this.get_container().children("ul").empty().append(d.children()).find("li, a").filter(function () { return this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'> </ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); } 41281 else { obj.children(".jstree-loading").removeClass("jstree-loading"); obj.append(d).find("li, a").filter(function () { return this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'> </ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); obj.data("jstree-is-loading",false); } 41282 this.clean_node(obj); 41283 if(s_call) { s_call.call(this); } 41284 } 41285 else { 41286 if(obj && obj !== -1) { 41287 obj.children(".jstree-loading").removeClass("jstree-loading"); 41288 obj.data("jstree-is-loading",false); 41289 if(s.correct_state) { 41290 obj.removeClass("jstree-open jstree-closed").addClass("jstree-leaf"); 41291 if(s_call) { s_call.call(this); } 41292 } 41293 } 41294 else { 41295 if(s.correct_state) { 41296 this.get_container().children("ul").empty(); 41297 if(s_call) { s_call.call(this); } 41298 } 41299 } 41300 } 41301 }; 41302 s.ajax.context = this; 41303 s.ajax.error = error_func; 41304 s.ajax.success = success_func; 41305 if(!s.ajax.dataType) { s.ajax.dataType = "html"; } 41306 if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); } 41307 if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); } 41308 $.ajax(s.ajax); 41309 break; 41310 } 41311 } 41312 } 41313 }); 41314 // include the HTML data plugin by default 41315 $.jstree.defaults.plugins.push("html_data"); 41316})(jQuery); 41317//*/ 41318 41319/* 41320 * jsTree themeroller plugin 1.0 41321 * Adds support for jQuery UI themes. Include this at the end of your plugins list, also make sure "themes" is not included. 41322 */ 41323(function ($) { 41324 $.jstree.plugin("themeroller", { 41325 __init : function () { 41326 var s = this._get_settings().themeroller; 41327 this.get_container() 41328 .addClass("ui-widget-content") 41329 .delegate("a","mouseenter.jstree", function () { 41330 $(this).addClass(s.item_h); 41331 }) 41332 .delegate("a","mouseleave.jstree", function () { 41333 $(this).removeClass(s.item_h); 41334 }) 41335 .bind("open_node.jstree create_node.jstree", $.proxy(function (e, data) { 41336 this._themeroller(data.rslt.obj); 41337 }, this)) 41338 .bind("loaded.jstree refresh.jstree", $.proxy(function (e) { 41339 this._themeroller(); 41340 }, this)) 41341 .bind("close_node.jstree", $.proxy(function (e, data) { 41342 data.rslt.obj.children("ins").removeClass(s.opened).addClass(s.closed); 41343 }, this)) 41344 .bind("select_node.jstree", $.proxy(function (e, data) { 41345 data.rslt.obj.children("a").addClass(s.item_a); 41346 }, this)) 41347 .bind("deselect_node.jstree deselect_all.jstree", $.proxy(function (e, data) { 41348 this.get_container() 41349 .find("." + s.item_a).removeClass(s.item_a).end() 41350 .find(".jstree-clicked").addClass(s.item_a); 41351 }, this)) 41352 .bind("move_node.jstree", $.proxy(function (e, data) { 41353 this._themeroller(data.rslt.o); 41354 }, this)); 41355 }, 41356 __destroy : function () { 41357 var s = this._get_settings().themeroller, 41358 c = [ "ui-icon" ]; 41359 $.each(s, function (i, v) { 41360 v = v.split(" "); 41361 if(v.length) { c = c.concat(v); } 41362 }); 41363 this.get_container() 41364 .removeClass("ui-widget-content") 41365 .find("." + c.join(", .")).removeClass(c.join(" ")); 41366 }, 41367 _fn : { 41368 _themeroller : function (obj) { 41369 var s = this._get_settings().themeroller; 41370 obj = !obj || obj == -1 ? this.get_container() : this._get_node(obj).parent(); 41371 obj 41372 .find("li.jstree-closed > ins.jstree-icon").removeClass(s.opened).addClass("ui-icon " + s.closed).end() 41373 .find("li.jstree-open > ins.jstree-icon").removeClass(s.closed).addClass("ui-icon " + s.opened).end() 41374 .find("a").addClass(s.item) 41375 .children("ins.jstree-icon").addClass("ui-icon " + s.item_icon); 41376 } 41377 }, 41378 defaults : { 41379 "opened" : "ui-icon-triangle-1-se", 41380 "closed" : "ui-icon-triangle-1-e", 41381 "item" : "ui-state-default", 41382 "item_h" : "ui-state-hover", 41383 "item_a" : "ui-state-active", 41384 "item_icon" : "ui-icon-folder-collapsed" 41385 } 41386 }); 41387 $(function() { 41388 var css_string = '.jstree .ui-icon { overflow:visible; } .jstree a { padding:0 2px; }'; 41389 $.vakata.css.add_sheet({ str : css_string });
41390 }); 41391})(jQuery); 41392//*/ 41393 41394/* 41395 * jsTree unique plugin 1.0 41396 * Forces different names amongst siblings (still a bit experimental) 41397 * NOTE: does not check language versions (it will not be possible to have nodes with the same title, even in different languages) 41398 */ 41399(function ($) { 41400 $.jstree.plugin("unique", { 41401 __init : function () { 41402 this.get_container() 41403 .bind("before.jstree", $.proxy(function (e, data) { 41404 var nms = [], res = true, p, t; 41405 if(data.func == "move_node") { 41406 // obj, ref, position, is_copy, is_prepared, skip_check 41407 if(data.args[4] === true) { 41408 if(data.args[0].o && data.args[0].o.length) { 41409 data.args[0].o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); }); 41410 res = this._check_unique(nms, data.args[0].np.find("> ul > li").not(data.args[0].o)); 41411 } 41412 } 41413 } 41414 if(data.func == "create_node") { 41415 // obj, position, js, callback, is_loaded 41416 if(data.args[4] || this._is_loaded(data.args[0])) { 41417 p = this._get_node(data.args[0]); 41418 if(data.args[1] && (data.args[1] === "before" || data.args[1] === "after")) { 41419 p = this._get_parent(data.args[0]); 41420 if(!p || p === -1) { p = this.get_container(); } 41421 } 41422 if(typeof data.args[2] === "string") { nms.push(data.args[2]); } 41423 else if(!data.args[2] || !data.args[2].data) { nms.push(this._get_settings().core.strings.new_node); } 41424 else { nms.push(data.args[2].data); } 41425 res = this._check_unique(nms, p.find("> ul > li")); 41426 } 41427 } 41428 if(data.func == "rename_node") { 41429 // obj, val 41430 nms.push(data.args[1]); 41431 t = this._get_node(data.args[0]); 41432 p = this._get_parent(t); 41433 if(!p || p === -1) { p = this.get_container(); } 41434 res = this._check_unique(nms, p.find("> ul > li").not(t)); 41435 } 41436 if(!res) { 41437 e.stopPropagation(); 41438 return false; 41439 } 41440 }, this)); 41441 }, 41442 _fn : { 41443 _check_unique : function (nms, p) { 41444 var cnms = []; 41445 p.children("a").each(function () { cnms.push($(this).text().replace(/^\s+/g,"")); }); 41446 if(!cnms.length || !nms.length) { return true; } 41447 cnms = cnms.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(","); 41448 if((cnms.length + nms.length) != cnms.concat(nms).sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",").length) { 41449 return false; 41450 } 41451 return true; 41452 }, 41453 check_move : function () { 41454 if(!this.__call_old()) { return false; } 41455 var p = this._get_move(), nms = []; 41456 if(p.o && p.o.length) { 41457 p.o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); }); 41458 return this._check_unique(nms, p.np.find("> ul > li").not(p.o)); 41459 } 41460 return true; 41461 } 41462 } 41463 }); 41464})(jQuery); 41465//*/ 41466 41467/* FileSaver.js 41468 * A saveAs() FileSaver implementation. 41469 * 1.3.2 41470 * 2016-06-16 18:25:19 41471 * 41472 * By Eli Grey, http://eligrey.com 41473 * License: MIT 41474 * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md 41475 */ 41476 41477/*global self */ 41478/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ 41479 41480/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 41481 41482var saveAs = saveAs || (function(view) { 41483 "use strict"; 41484 // IE <10 is explicitly unsupported 41485 if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { 41486 return; 41487 } 41488 var 41489 doc = view.document 41490 // only get URL when necessary in case Blob.js hasn't overridden it yet 41491 , get_URL = function() { 41492 return view.URL || view.webkitURL || view; 41493 } 41494 , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") 41495 , can_use_save_link = "download" in save_link 41496 , click = function(node) { 41497 var event = new MouseEvent("click"); 41498 node.dispatchEvent(event); 41499 } 41500 , is_safari = /constructor/i.test(view.HTMLElement) || view.safari 41501 , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent) 41502 , throw_outside = function(ex) { 41503 (view.setImmediate || view.setTimeout)(function() { 41504 throw ex; 41505 }, 0); 41506 } 41507 , force_saveable_type = "application/octet-stream" 41508 // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to 41509 , arbitrary_revoke_timeout = 1000 * 40 // in ms 41510 , revoke = function(file) { 41511 var revoker = function() { 41512 if (typeof file === "string") { // file is an object URL 41513 get_URL().revokeObjectURL(file); 41514 } else { // file is a File 41515 file.remove(); 41516 } 41517 }; 41518 setTimeout(revoker, arbitrary_revoke_timeout); 41519 } 41520 , dispatch = function(filesaver, event_types, event) { 41521 event_types = [].concat(event_types); 41522 var i = event_types.length; 41523 while (i--) { 41524 var listener = filesaver["on" + event_types[i]]; 41525 if (typeof listener === "function") { 41526 try { 41527 listener.call(filesaver, event || filesaver); 41528 } catch (ex) { 41529 throw_outside(ex); 41530 } 41531 } 41532 } 41533 } 41534 , auto_bom = function(blob) { 41535 // prepend BOM for UTF-8 XML and text/* types (including HTML) 41536 // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF 41537 if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { 41538 return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type}); 41539 } 41540 return blob; 41541 } 41542 , FileSaver = function(blob, name, no_auto_bom) { 41543 if (!no_auto_bom) { 41544 blob = auto_bom(blob); 41545 } 41546 // First try a.download, then web filesystem, then object URLs 41547 var 41548 filesaver = this 41549 , type = blob.type 41550 , force = type === force_saveable_type 41551 , object_url 41552 , dispatch_all = function() { 41553 dispatch(filesaver, "writestart progress write writeend".split(" ")); 41554 } 41555 // on any filesys errors revert to saving with object URLs 41556 , fs_error = function() { 41557 if ((is_chrome_ios || (force && is_safari)) && view.FileReader) { 41558 // Safari doesn't allow downloading of blob urls 41559 var reader = new FileReader(); 41560 reader.onloadend = function() { 41561 var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;'); 41562 var popup = view.open(url, '_blank'); 41563 if(!popup) view.location.href = url; 41564 url=undefined; // release reference before dispatching 41565 filesaver.readyState = filesaver.DONE; 41566 dispatch_all(); 41567 };
41568 reader.readAsDataURL(blob); 41569 filesaver.readyState = filesaver.INIT; 41570 return; 41571 } 41572 // don't create more object URLs than needed 41573 if (!object_url) { 41574 object_url = get_URL().createObjectURL(blob); 41575 } 41576 if (force) { 41577 view.location.href = object_url; 41578 } else { 41579 var opened = view.open(object_url, "_blank"); 41580 if (!opened) { 41581 // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html 41582 view.location.href = object_url; 41583 } 41584 } 41585 filesaver.readyState = filesaver.DONE; 41586 dispatch_all(); 41587 revoke(object_url); 41588 } 41589 ; 41590 filesaver.readyState = filesaver.INIT; 41591 41592 if (can_use_save_link) { 41593 object_url = get_URL().createObjectURL(blob); 41594 setTimeout(function() { 41595 save_link.href = object_url; 41596 save_link.download = name; 41597 click(save_link); 41598 dispatch_all(); 41599 revoke(object_url); 41600 filesaver.readyState = filesaver.DONE; 41601 }); 41602 return; 41603 } 41604 41605 fs_error(); 41606 } 41607 , FS_proto = FileSaver.prototype 41608 , saveAs = function(blob, name, no_auto_bom) { 41609 return new FileSaver(blob, name || blob.name || "download", no_auto_bom); 41610 } 41611 ; 41612 // IE 10+ (native saveAs) 41613 if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { 41614 return function(blob, name, no_auto_bom) { 41615 name = name || blob.name || "download"; 41616 41617 if (!no_auto_bom) { 41618 blob = auto_bom(blob); 41619 } 41620 return navigator.msSaveOrOpenBlob(blob, name); 41621 }; 41622 } 41623 41624 FS_proto.abort = function(){}; 41625 FS_proto.readyState = FS_proto.INIT = 0; 41626 FS_proto.WRITING = 1; 41627 FS_proto.DONE = 2; 41628 41629 FS_proto.error = 41630 FS_proto.onwritestart = 41631 FS_proto.onprogress = 41632 FS_proto.onwrite = 41633 FS_proto.onabort = 41634 FS_proto.onerror = 41635 FS_proto.onwriteend = 41636 null; 41637 41638 return saveAs; 41639}( 41640 typeof self !== "undefined" && self 41641 || typeof window !== "undefined" && window 41642 || this.content 41643)); 41644// `self` is undefined in Firefox for Android content script context 41645// while `this` is nsIContentFrameMessageManager 41646// with an attribute `content` that corresponds to the window 41647 41648if (typeof module !== "undefined" && module.exports) { 41649 module.exports.saveAs = saveAs; 41650} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) { 41651 define("FileSaver.js", function() { 41652 return saveAs; 41653 }); 41654} 41655 41656window.saveAs = saveAs;
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.