1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { 40/******/ configurable: false, 41/******/ enumerable: true, 42/******/ get: getter 43/******/ }); 44/******/ } 45/******/ }; 46/******/ 47/******/ // getDefaultExport function for compatibility with non-harmony modules 48/******/ __webpack_require__.n = function(module) { 49/******/ var getter = module && module.__esModule ? 50/******/ function getDefault() { return module['default']; } : 51/******/ function getModuleExports() { return module; }; 52/******/ __webpack_require__.d(getter, 'a', getter); 53/******/ return getter; 54/******/ }; 55/******/ 56/******/ // Object.prototype.hasOwnProperty.call 57/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58/******/ 59/******/ // __webpack_public_path__ 60/******/ __webpack_require__.p = ""; 61/******/ 62/******/ // Load entry module and return exports 63/******/ return __webpack_require__(__webpack_require__.s = 42); 64/******/ }) 65/************************************************************************/ 66/******/ ([ 67/* 0 */ 68/***/ (function(module, exports, __webpack_require__) { 69 70var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 71 * jQuery JavaScript Library v1.12.4 72 * http://jquery.com/ 73 * 74 * Includes Sizzle.js 75 * http://sizzlejs.com/ 76 * 77 * Copyright jQuery Foundation and other contributors 78 * Released under the MIT license 79 * http://jquery.org/license 80 * 81 * Date: 2016-05-20T17:17Z 82 */ 83 84(function (global, factory) { 85 86 if (typeof module === "object" && typeof module.exports === "object") { 87 // For CommonJS and CommonJS-like environments where a proper `window` 88 // is present, execute the factory and get jQuery. 89 // For environments that do not have a `window` with a `document` 90 // (such as Node.js), expose a factory as module.exports. 91 // This accentuates the need for the creation of a real `window`. 92 // e.g. var jQuery = require("jquery")(window); 93 // See ticket #14549 for more info. 94 module.exports = global.document ? factory(global, true) : function (w) { 95 if (!w.document) { 96 throw new Error("jQuery requires a window with a document"); 97 } 98 return factory(w); 99 }; 100 } else { 101 factory(global); 102 } 103 104 // Pass this if window is not defined yet 105})(typeof window !== "undefined" ? window : this, function (window, noGlobal) { 106 107 // Support: Firefox 18+ 108 // Can't be in strict mode, several libs including ASP.NET trace 109 // the stack via arguments.caller.callee and Firefox dies if
vendor: 4,159 bytes, lines 110-294
110 // you try to trace through "use strict" call chains. (#13335) 111 //"use strict"; 112 var deletedIds = []; 113 114 var document = window.document; 115 116 var slice = deletedIds.slice; 117 118 var concat = deletedIds.concat; 119 120 var push = deletedIds.push; 121 122 var indexOf = deletedIds.indexOf; 123 124 var class2type = {}; 125 126 var toString = class2type.toString; 127 128 var hasOwn = class2type.hasOwnProperty; 129 130 var support = {}; 131 132 var version = "1.12.4", 133 134 135 // Define a local copy of jQuery 136 jQuery = function (selector, context) { 137 138 // The jQuery object is actually just the init constructor 'enhanced' 139 // Need init if jQuery is called (just allow error to be thrown if not included) 140 return new jQuery.fn.init(selector, context); 141 }, 142 143 144 // Support: Android<4.1, IE<9 145 // Make sure we trim BOM and NBSP 146 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, 147 148 149 // Matches dashed string for camelizing 150 rmsPrefix = /^-ms-/, 151 rdashAlpha = /-([\da-z])/gi, 152 153 154 // Used by jQuery.camelCase as callback to replace() 155 fcamelCase = function (all, letter) { 156 return letter.toUpperCase(); 157 }; 158 159 jQuery.fn = jQuery.prototype = { 160 161 // The current version of jQuery being used 162 jquery: version, 163 164 constructor: jQuery, 165 166 // Start with an empty selector 167 selector: "", 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 return num != null ? 180 181 // Return just the one element from the set 182 num < 0 ? this[num + this.length] : this[num] : 183 184 // Return all the elements in a clean array 185 slice.call(this); 186 }, 187 188 // Take an array of elements and push it onto the stack 189 // (returning the new matched element set) 190 pushStack: function (elems) { 191 192 // Build a new jQuery matched element set 193 var ret = jQuery.merge(this.constructor(), elems); 194 195 // Add the old object onto the stack (as a reference) 196 ret.prevObject = this; 197 ret.context = this.context; 198 199 // Return the newly-formed element set 200 return ret; 201 }, 202 203 // Execute a callback for every element in the matched set. 204 each: function (callback) { 205 return jQuery.each(this, callback); 206 }, 207 208 map: function (callback) { 209 return this.pushStack(jQuery.map(this, function (elem, i) { 210 return callback.call(elem, i, elem); 211 })); 212 }, 213 214 slice: function () { 215 return this.pushStack(slice.apply(this, arguments)); 216 }, 217 218 first: function () { 219 return this.eq(0); 220 }, 221 222 last: function () { 223 return this.eq(-1); 224 }, 225 226 eq: function (i) { 227 var len = this.length, 228 j = +i + (i < 0 ? len : 0); 229 return this.pushStack(j >= 0 && j < len ? [this[j]] : []); 230 }, 231 232 end: function () { 233 return this.prevObject || this.constructor(); 234 }, 235 236 // For internal use only. 237 // Behaves like an Array's method, not like a jQuery method. 238 push: push, 239 sort: deletedIds.sort, 240 splice: deletedIds.splice 241 }; 242 243 jQuery.extend = jQuery.fn.extend = function () { 244 var src, 245 copyIsArray, 246 copy, 247 name, 248 options, 249 clone, 250 target = arguments[0] || {}, 251 i = 1, 252 length = arguments.length, 253 deep = false; 254 255 // Handle a deep copy situation 256 if (typeof target === "boolean") { 257 deep = target; 258 259 // skip the boolean and the target 260 target = arguments[i] || {}; 261 i++; 262 } 263 264 // Handle case when target is a string or something (possible in deep copy) 265 if (typeof target !== "object" && !jQuery.isFunction(target)) { 266 target = {}; 267 } 268 269 // extend jQuery itself if only one argument is passed 270 if (i === length) { 271 target = this; 272 i--; 273 } 274 275 for (; i < length; i++) { 276 277 // Only deal with non-null/undefined values 278 if ((options = arguments[i]) != null) { 279 280 // Extend the base object 281 for (name in options) { 282 src = target[name]; 283 copy = options[name]; 284 285 // Prevent never-ending loop 286 if (target === copy) { 287 continue; 288 } 289 290 // Recurse if we're merging plain objects or arrays 291 if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) { 292 293 if (copyIsArray) { 294 copyIsArray = false;
vendor: 8,553 bytes, lines 295-636
295 clone = src && jQuery.isArray(src) ? src : []; 296 } else { 297 clone = src && jQuery.isPlainObject(src) ? src : {}; 298 } 299 300 // Never move original objects, clone them 301 target[name] = jQuery.extend(deep, clone, copy); 302 303 // Don't bring in undefined values 304 } else if (copy !== undefined) { 305 target[name] = copy; 306 } 307 } 308 } 309 } 310 311 // Return the modified object 312 return target; 313 }; 314 315 jQuery.extend({ 316 317 // Unique for each copy of jQuery on the page 318 expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""), 319 320 // Assume jQuery is ready without the ready module 321 isReady: true, 322 323 error: function (msg) { 324 throw new Error(msg); 325 }, 326 327 noop: function () {}, 328 329 // See test/unit/core.js for details concerning isFunction. 330 // Since version 1.3, DOM methods and functions like alert 331 // aren't supported. They return false on IE (#2968). 332 isFunction: function (obj) { 333 return jQuery.type(obj) === "function"; 334 }, 335 336 isArray: Array.isArray || function (obj) { 337 return jQuery.type(obj) === "array"; 338 }, 339 340 isWindow: function (obj) { 341 /* jshint eqeqeq: false */ 342 return obj != null && obj == obj.window; 343 }, 344 345 isNumeric: function (obj) { 346 347 // parseFloat NaNs numeric-cast false positives (null|true|false|"") 348 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 349 // subtraction forces infinities to NaN 350 // adding 1 corrects loss of precision from parseFloat (#15100) 351 var realStringObj = obj && obj.toString(); 352 return !jQuery.isArray(obj) && realStringObj - parseFloat(realStringObj) + 1 >= 0; 353 }, 354 355 isEmptyObject: function (obj) { 356 var name; 357 for (name in obj) { 358 return false; 359 } 360 return true; 361 }, 362 363 isPlainObject: function (obj) { 364 var key; 365 366 // Must be an Object. 367 // Because of IE, we also have to check the presence of the constructor property. 368 // Make sure that DOM nodes and window objects don't pass through, as well 369 if (!obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) { 370 return false; 371 } 372 373 try { 374 375 // Not own constructor property must be Object 376 if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) { 377 return false; 378 } 379 } catch (e) { 380 381 // IE8,9 Will throw exceptions on certain host objects #9897 382 return false; 383 } 384 385 // Support: IE<9 386 // Handle iteration over inherited properties before own properties. 387 if (!support.ownFirst) { 388 for (key in obj) { 389 return hasOwn.call(obj, key); 390 } 391 } 392 393 // Own properties are enumerated firstly, so to speed up, 394 // if last one is own, then all properties are own. 395 for (key in obj) {} 396 397 return key === undefined || hasOwn.call(obj, key); 398 }, 399 400 type: function (obj) { 401 if (obj == null) { 402 return obj + ""; 403 } 404 return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj; 405 }, 406 407 // Workarounds based on findings by Jim Driscoll 408 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context 409 globalEval: function (data) { 410 if (data && jQuery.trim(data)) { 411 412 // We use execScript on Internet Explorer 413 // We use an anonymous function so that context is window 414 // rather than jQuery in Firefox 415 (window.execScript || function (data) { 416 window["eval"].call(window, data); // jscs:ignore requireDotNotation 417 })(data); 418 } 419 }, 420 421 // Convert dashed to camelCase; used by the css and data modules 422 // Microsoft forgot to hump their vendor prefix (#9572) 423 camelCase: function (string) { 424 return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); 425 }, 426 427 nodeName: function (elem, name) { 428 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 429 }, 430 431 each: function (obj, callback) { 432 var length, 433 i = 0; 434 435 if (isArrayLike(obj)) { 436 length = obj.length; 437 for (; i < length; i++) { 438 if (callback.call(obj[i], i, obj[i]) === false) { 439 break; 440 } 441 } 442 } else { 443 for (i in obj) { 444 if (callback.call(obj[i], i, obj[i]) === false) { 445 break; 446 } 447 } 448 } 449 450 return obj; 451 }, 452 453 // Support: Android<4.1, IE<9 454 trim: function (text) { 455 return text == null ? "" : (text + "").replace(rtrim, ""); 456 }, 457 458 // results is for internal usage only 459 makeArray: function (arr, results) { 460 var ret = results || []; 461 462 if (arr != null) { 463 if (isArrayLike(Object(arr))) { 464 jQuery.merge(ret, typeof arr === "string" ? [arr] : arr); 465 } else { 466 push.call(ret, arr); 467 } 468 } 469 470 return ret; 471 }, 472 473 inArray: function (elem, arr, i) { 474 var len; 475 476 if (arr) { 477 if (indexOf) { 478 return indexOf.call(arr, elem, i); 479 } 480 481 len = arr.length; 482 i = i ? i < 0 ? Math.max(0, len + i) : i : 0; 483 484 for (; i < len; i++) { 485 486 // Skip accessing in sparse arrays 487 if (i in arr && arr[i] === elem) { 488 return i; 489 } 490 } 491 } 492 493 return -1; 494 }, 495 496 merge: function (first, second) { 497 var len = +second.length, 498 j = 0, 499 i = first.length; 500 501 while (j < len) { 502 first[i++] = second[j++]; 503 } 504 505 // Support: IE<9 506 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) 507 if (len !== len) { 508 while (second[j] !== undefined) { 509 first[i++] = second[j++]; 510 } 511 } 512 513 first.length = i; 514 515 return first; 516 }, 517 518 grep: function (elems, callback, invert) { 519 var callbackInverse, 520 matches = [], 521 i = 0, 522 length = elems.length, 523 callbackExpect = !invert; 524 525 // Go through the array, only saving the items 526 // that pass the validator function 527 for (; i < length; i++) { 528 callbackInverse = !callback(elems[i], i); 529 if (callbackInverse !== callbackExpect) { 530 matches.push(elems[i]); 531 } 532 } 533 534 return matches; 535 }, 536 537 // arg is for internal usage only 538 map: function (elems, callback, arg) { 539 var length, 540 value, 541 i = 0, 542 ret = []; 543 544 // Go through the array, translating each of the items to their new values 545 if (isArrayLike(elems)) { 546 length = elems.length; 547 for (; i < length; i++) { 548 value = callback(elems[i], i, arg); 549 550 if (value != null) { 551 ret.push(value); 552 } 553 } 554 555 // Go through every key on the object, 556 } else { 557 for (i in elems) { 558 value = callback(elems[i], i, arg); 559 560 if (value != null) { 561 ret.push(value); 562 } 563 } 564 } 565 566 // Flatten any nested arrays 567 return concat.apply([], ret); 568 }, 569 570 // A global GUID counter for objects 571 guid: 1, 572 573 // Bind a function to a context, optionally partially applying any 574 // arguments. 575 proxy: function (fn, context) { 576 var args, proxy, tmp; 577 578 if (typeof context === "string") { 579 tmp = fn[context]; 580 context = fn; 581 fn = tmp; 582 } 583 584 // Quick check to determine if target is callable, in the spec 585 // this throws a TypeError, but we will just return undefined. 586 if (!jQuery.isFunction(fn)) { 587 return undefined; 588 } 589 590 // Simulated bind 591 args = slice.call(arguments, 2); 592 proxy = function () { 593 return fn.apply(context || this, args.concat(slice.call(arguments))); 594 }; 595 596 // Set the guid of unique handler to the same of original handler, so it can be removed 597 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 598 599 return proxy; 600 }, 601 602 now: function () { 603 return +new Date(); 604 }, 605 606 // jQuery.support is not used in Core but other projects attach their 607 // properties to it so it needs to exist. 608 support: support 609 }); 610 611 // JSHint would error on this code due to the Symbol not being defined in ES5. 612 // Defining this global in .jshintrc would create a danger of using the global 613 // unguarded in another place, it seems safer to just disable JSHint for these 614 // three lines. 615 /* jshint ignore: start */ 616 if (typeof Symbol === "function") { 617 jQuery.fn[Symbol.iterator] = deletedIds[Symbol.iterator]; 618 } 619 /* jshint ignore: end */ 620 621 // Populate the class2type map 622 jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) { 623 class2type["[object " + name + "]"] = name.toLowerCase(); 624 }); 625 626 function isArrayLike(obj) { 627 628 // Support: iOS 8.2 (not reproducible in simulator) 629 // `in` check used to prevent JIT error (gh-2145) 630 // hasOwn isn't used here due to false negatives 631 // regarding Nodelist length in IE 632 var length = !!obj && "length" in obj && obj.length, 633 type = jQuery.type(obj); 634 635 if (type === "function" || jQuery.isWindow(obj)) { 636 return false;
vendor: 4,770 bytes, lines 637-782
637 } 638 639 return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj; 640 } 641 var Sizzle = 642 /*! 643 * Sizzle CSS Selector Engine v2.2.1 644 * http://sizzlejs.com/ 645 * 646 * Copyright jQuery Foundation and other contributors 647 * Released under the MIT license 648 * http://jquery.org/license 649 * 650 * Date: 2015-10-17 651 */ 652 function (window) { 653 654 var i, 655 support, 656 Expr, 657 getText, 658 isXML, 659 tokenize, 660 compile, 661 select, 662 outermostContext, 663 sortInput, 664 hasDuplicate, 665 666 667 // Local document vars 668 setDocument, 669 document, 670 docElem, 671 documentIsHTML, 672 rbuggyQSA, 673 rbuggyMatches, 674 matches, 675 contains, 676 677 678 // Instance-specific data 679 expando = "sizzle" + 1 * new Date(), 680 preferredDoc = window.document, 681 dirruns = 0, 682 done = 0, 683 classCache = createCache(), 684 tokenCache = createCache(), 685 compilerCache = createCache(), 686 sortOrder = function (a, b) { 687 if (a === b) { 688 hasDuplicate = true; 689 } 690 return 0; 691 }, 692 693 694 // General-purpose constants 695 MAX_NEGATIVE = 1 << 31, 696 697 698 // Instance methods 699 hasOwn = {}.hasOwnProperty, 700 arr = [], 701 pop = arr.pop, 702 push_native = arr.push, 703 push = arr.push, 704 slice = arr.slice, 705 706 // Use a stripped-down indexOf as it's faster than native 707 // http://jsperf.com/thor-indexof-vs-for/5 708 indexOf = function (list, elem) { 709 var i = 0, 710 len = list.length; 711 for (; i < len; i++) { 712 if (list[i] === elem) { 713 return i; 714 } 715 } 716 return -1; 717 }, 718 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 719 720 721 // Regular expressions 722 723 // http://www.w3.org/TR/css3-selectors/#whitespace 724 whitespace = "[\\x20\\t\\r\\n\\f]", 725 726 727 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 728 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", 729 730 731 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 732 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 733 // Operator (capture 2) 734 "*([*^$|!~]?=)" + whitespace + 735 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 736 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", 737 pseudos = ":(" + identifier + ")(?:\\((" + 738 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 739 // 1. quoted (capture 3; capture 4 or capture 5) 740 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 741 // 2. simple (capture 6) 742 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 743 // 3. anything else (capture 2) 744 ".*" + ")\\)|)", 745 746 747 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 748 rwhitespace = new RegExp(whitespace + "+", "g"), 749 rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), 750 rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), 751 rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), 752 rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), 753 rpseudo = new RegExp(pseudos), 754 ridentifier = new RegExp("^" + identifier + "$"), 755 matchExpr = { 756 "ID": new RegExp("^#(" + identifier + ")"), 757 "CLASS": new RegExp("^\\.(" + identifier + ")"), 758 "TAG": new RegExp("^(" + identifier + "|[*])"), 759 "ATTR": new RegExp("^" + attributes), 760 "PSEUDO": new RegExp("^" + pseudos), 761 "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"), 762 "bool": new RegExp("^(?:" + booleans + ")$", "i"), 763 // For use in libraries implementing .is() 764 // We use this for POS matching in `select` 765 "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") 766 }, 767 rinputs = /^(?:input|select|textarea|button)$/i, 768 rheader = /^h\d$/i, 769 rnative = /^[^{]+\{\s*\[native \w/, 770 771 772 // Easily-parseable/retrievable ID or TAG or CLASS selectors 773 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 774 rsibling = /[+~]/, 775 rescape = /'|\\/g, 776 777 778 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 779 runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), 780 funescape = function (_, escaped, escapedWhitespace) { 781 var high = "0x" + escaped - 0x10000; 782 // NaN means non-codepoint
783 // Support: Firefox<24 784 // Workaround erroneous numeric interpretation of +"0x" 785 return high !== high || escapedWhitespace ? escaped : high < 0 ? 786 // BMP codepoint 787 String.fromCharCode(high + 0x10000) : 788 // Supplemental Plane codepoint (surrogate pair) 789 String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); 790 }, 791 792 793 // Used for iframes 794 // See setDocument() 795 // Removing the function wrapper causes a "Permission Denied" 796 // error in IE 797 unloadHandler = function () { 798 setDocument(); 799 }; 800 801 // Optimize for push.apply( _, NodeList ) 802 try { 803 push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); 804 // Support: Android<4.0 805 // Detect silently failing push.apply 806 arr[preferredDoc.childNodes.length].nodeType; 807 } catch (e) { 808 push = { apply: arr.length ? 809 810 // Leverage slice if possible 811 function (target, els) { 812 push_native.apply(target, slice.call(els)); 813 } : 814 815 // Support: IE<9 816 // Otherwise append directly 817 function (target, els) { 818 var j = target.length, 819 i = 0; 820 // Can't trust NodeList.length 821 while (target[j++] = els[i++]) {} 822 target.length = j - 1; 823 } 824 }; 825 } 826 827 function Sizzle(selector, context, results, seed) { 828 var m, 829 i, 830 elem, 831 nid, 832 nidselect, 833 match, 834 groups, 835 newSelector, 836 newContext = context && context.ownerDocument, 837 838 839 // nodeType defaults to 9, since context defaults to document 840 nodeType = context ? context.nodeType : 9; 841 842 results = results || []; 843 844 // Return early from calls with invalid selector or context 845 if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { 846 847 return results; 848 } 849 850 // Try to shortcut find operations (as opposed to filters) in HTML documents 851 if (!seed) { 852 853 if ((context ? context.ownerDocument || context : preferredDoc) !== document) { 854 setDocument(context); 855 } 856 context = context || document; 857 858 if (documentIsHTML) { 859 860 // If the selector is sufficiently simple, try using a "get*By*" DOM method 861 // (excepting DocumentFragment context, where the methods don't exist) 862 if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { 863 864 // ID selector 865 if (m = match[1]) { 866 867 // Document context 868 if (nodeType === 9) { 869 if (elem = context.getElementById(m)) { 870 871 // Support: IE, Opera, Webkit 872 // TODO: identify versions 873 // getElementById can match elements by name instead of ID 874 if (elem.id === m) { 875 results.push(elem); 876 return results; 877 } 878 } else { 879 return results; 880 } 881 882 // Element context 883 } else { 884 885 // Support: IE, Opera, Webkit 886 // TODO: identify versions 887 // getElementById can match elements by name instead of ID 888 if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { 889 890 results.push(elem); 891 return results; 892 } 893 } 894 895 // Type selector 896 } else if (match[2]) { 897 push.apply(results, context.getElementsByTagName(selector)); 898 return results; 899 900 // Class selector 901 } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { 902 903 push.apply(results, context.getElementsByClassName(m)); 904 return results; 905 } 906 } 907 908 // Take advantage of querySelectorAll 909 if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) { 910 911 if (nodeType !== 1) { 912 newContext = context; 913 newSelector = selector; 914 915 // qSA looks outside Element context, which is not what we want 916 // Thanks to Andrew Dupont for this workaround technique 917 // Support: IE <=8 918 // Exclude object elements 919 } else if (context.nodeName.toLowerCase() !== "object") { 920 921 // Capture the context ID, setting it first if necessary 922 if (nid = context.getAttribute("id")) { 923 nid = nid.replace(rescape, "\\$&"); 924 } else { 925 context.setAttribute("id", nid = expando); 926 } 927 928 // Prefix every selector in the list 929 groups = tokenize(selector); 930 i = groups.length; 931 nidselect = ridentifier.test(nid) ? "#" + nid : "[id='" + nid + "']"; 932 while (i--) { 933 groups[i] = nidselect + " " + toSelector(groups[i]); 934 } 935 newSelector = groups.join(","); 936 937 // Expand context for sibling selectors
vendor: 18,442 bytes, lines 938-1532
938 newContext = rsibling.test(selector) && testContext(context.parentNode) || context; 939 } 940 941 if (newSelector) { 942 try { 943 push.apply(results, newContext.querySelectorAll(newSelector)); 944 return results; 945 } catch (qsaError) {} finally { 946 if (nid === expando) { 947 context.removeAttribute("id"); 948 } 949 } 950 } 951 } 952 } 953 } 954 955 // All others 956 return select(selector.replace(rtrim, "$1"), context, results, seed); 957 } 958 959 /** 960 * Create key-value caches of limited size 961 * @returns {function(string, object)} Returns the Object data after storing it on itself with 962 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 963 * deleting the oldest entry 964 */ 965 function createCache() { 966 var keys = []; 967 968 function cache(key, value) { 969 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 970 if (keys.push(key + " ") > Expr.cacheLength) { 971 // Only keep the most recent entries 972 delete cache[keys.shift()]; 973 } 974 return cache[key + " "] = value; 975 } 976 return cache; 977 } 978 979 /** 980 * Mark a function for special use by Sizzle 981 * @param {Function} fn The function to mark 982 */ 983 function markFunction(fn) { 984 fn[expando] = true; 985 return fn; 986 } 987 988 /** 989 * Support testing using an element 990 * @param {Function} fn Passed the created div and expects a boolean result 991 */ 992 function assert(fn) { 993 var div = document.createElement("div"); 994 995 try { 996 return !!fn(div); 997 } catch (e) { 998 return false; 999 } finally { 1000 // Remove from its parent by default 1001 if (div.parentNode) { 1002 div.parentNode.removeChild(div); 1003 } 1004 // release memory in IE 1005 div = null; 1006 } 1007 } 1008 1009 /** 1010 * Adds the same handler for all of the specified attrs 1011 * @param {String} attrs Pipe-separated list of attributes 1012 * @param {Function} handler The method that will be applied 1013 */ 1014 function addHandle(attrs, handler) { 1015 var arr = attrs.split("|"), 1016 i = arr.length; 1017 1018 while (i--) { 1019 Expr.attrHandle[arr[i]] = handler; 1020 } 1021 } 1022 1023 /** 1024 * Checks document order of two siblings 1025 * @param {Element} a 1026 * @param {Element} b 1027 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 1028 */ 1029 function siblingCheck(a, b) { 1030 var cur = b && a, 1031 diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE); 1032 1033 // Use IE sourceIndex if available on both nodes 1034 if (diff) { 1035 return diff; 1036 } 1037 1038 // Check if b follows a 1039 if (cur) { 1040 while (cur = cur.nextSibling) { 1041 if (cur === b) { 1042 return -1; 1043 } 1044 } 1045 } 1046 1047 return a ? 1 : -1; 1048 } 1049 1050 /** 1051 * Returns a function to use in pseudos for input types 1052 * @param {String} type 1053 */ 1054 function createInputPseudo(type) { 1055 return function (elem) { 1056 var name = elem.nodeName.toLowerCase(); 1057 return name === "input" && elem.type === type; 1058 }; 1059 } 1060 1061 /** 1062 * Returns a function to use in pseudos for buttons 1063 * @param {String} type 1064 */ 1065 function createButtonPseudo(type) { 1066 return function (elem) { 1067 var name = elem.nodeName.toLowerCase(); 1068 return (name === "input" || name === "button") && elem.type === type; 1069 }; 1070 } 1071 1072 /** 1073 * Returns a function to use in pseudos for positionals 1074 * @param {Function} fn 1075 */ 1076 function createPositionalPseudo(fn) { 1077 return markFunction(function (argument) { 1078 argument = +argument; 1079 return markFunction(function (seed, matches) { 1080 var j, 1081 matchIndexes = fn([], seed.length, argument), 1082 i = matchIndexes.length; 1083 1084 // Match elements found at the specified indexes 1085 while (i--) { 1086 if (seed[j = matchIndexes[i]]) { 1087 seed[j] = !(matches[j] = seed[j]); 1088 } 1089 } 1090 }); 1091 }); 1092 } 1093 1094 /** 1095 * Checks a node for validity as a Sizzle context 1096 * @param {Element|Object=} context 1097 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1098 */ 1099 function testContext(context) { 1100 return context && typeof context.getElementsByTagName !== "undefined" && context; 1101 } 1102 1103 // Expose support vars for convenience 1104 support = Sizzle.support = {}; 1105 1106 /** 1107 * Detects XML nodes 1108 * @param {Element|Object} elem An element or a document 1109 * @returns {Boolean} True iff elem is a non-HTML XML node 1110 */ 1111 isXML = Sizzle.isXML = function (elem) { 1112 // documentElement is verified for cases where it doesn't yet exist 1113 // (such as loading iframes in IE - #4833) 1114 var documentElement = elem && (elem.ownerDocument || elem).documentElement; 1115 return documentElement ? documentElement.nodeName !== "HTML" : false; 1116 }; 1117 1118 /** 1119 * Sets document-related variables once based on the current document 1120 * @param {Element|Object} [doc] An element or document object to use to set the document 1121 * @returns {Object} Returns the current document 1122 */ 1123 setDocument = Sizzle.setDocument = function (node) { 1124 var hasCompare, 1125 parent, 1126 doc = node ? node.ownerDocument || node : preferredDoc; 1127 1128 // Return early if doc is invalid or already selected 1129 if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { 1130 return document; 1131 } 1132 1133 // Update global variables 1134 document = doc; 1135 docElem = document.documentElement; 1136 documentIsHTML = !isXML(document); 1137 1138 // Support: IE 9-11, Edge 1139 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 1140 if ((parent = document.defaultView) && parent.top !== parent) { 1141 // Support: IE 11 1142 if (parent.addEventListener) { 1143 parent.addEventListener("unload", unloadHandler, false); 1144 1145 // Support: IE 9 - 10 only 1146 } else if (parent.attachEvent) { 1147 parent.attachEvent("onunload", unloadHandler); 1148 } 1149 } 1150 1151 /* Attributes 1152 ---------------------------------------------------------------------- */ 1153 1154 // Support: IE<8 1155 // Verify that getAttribute really returns attributes and not properties 1156 // (excepting IE8 booleans) 1157 support.attributes = assert(function (div) { 1158 div.className = "i"; 1159 return !div.getAttribute("className"); 1160 }); 1161 1162 /* getElement(s)By* 1163 ---------------------------------------------------------------------- */ 1164 1165 // Check if getElementsByTagName("*") returns only elements 1166 support.getElementsByTagName = assert(function (div) { 1167 div.appendChild(document.createComment("")); 1168 return !div.getElementsByTagName("*").length; 1169 }); 1170 1171 // Support: IE<9 1172 support.getElementsByClassName = rnative.test(document.getElementsByClassName); 1173 1174 // Support: IE<10 1175 // Check if getElementById returns elements by name 1176 // The broken getElementById methods don't pick up programatically-set names, 1177 // so use a roundabout getElementsByName test 1178 support.getById = assert(function (div) { 1179 docElem.appendChild(div).id = expando; 1180 return !document.getElementsByName || !document.getElementsByName(expando).length; 1181 }); 1182 1183 // ID find and filter 1184 if (support.getById) { 1185 Expr.find["ID"] = function (id, context) { 1186 if (typeof context.getElementById !== "undefined" && documentIsHTML) { 1187 var m = context.getElementById(id); 1188 return m ? [m] : []; 1189 } 1190 }; 1191 Expr.filter["ID"] = function (id) { 1192 var attrId = id.replace(runescape, funescape); 1193 return function (elem) { 1194 return elem.getAttribute("id") === attrId; 1195 }; 1196 }; 1197 } else { 1198 // Support: IE6/7 1199 // getElementById is not reliable as a find shortcut 1200 delete Expr.find["ID"]; 1201 1202 Expr.filter["ID"] = function (id) { 1203 var attrId = id.replace(runescape, funescape); 1204 return function (elem) { 1205 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); 1206 return node && node.value === attrId; 1207 }; 1208 }; 1209 } 1210 1211 // Tag 1212 Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) { 1213 if (typeof context.getElementsByTagName !== "undefined") { 1214 return context.getElementsByTagName(tag); 1215 1216 // DocumentFragment nodes don't have gEBTN 1217 } else if (support.qsa) { 1218 return context.querySelectorAll(tag); 1219 } 1220 } : function (tag, context) { 1221 var elem, 1222 tmp = [], 1223 i = 0, 1224 1225 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 1226 results = context.getElementsByTagName(tag); 1227 1228 // Filter out possible comments 1229 if (tag === "*") { 1230 while (elem = results[i++]) { 1231 if (elem.nodeType === 1) { 1232 tmp.push(elem); 1233 } 1234 } 1235 1236 return tmp; 1237 } 1238 return results; 1239 }; 1240 1241 // Class 1242 Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { 1243 if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { 1244 return context.getElementsByClassName(className); 1245 } 1246 }; 1247 1248 /* QSA/matchesSelector 1249 ---------------------------------------------------------------------- */ 1250 1251 // QSA and matchesSelector support 1252 1253 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 1254 rbuggyMatches = []; 1255 1256 // qSa(:focus) reports false when true (Chrome 21) 1257 // We allow this because of a bug in IE8/9 that throws an error 1258 // whenever `document.activeElement` is accessed on an iframe 1259 // So, we allow :focus to pass through QSA all the time to avoid the IE error 1260 // See http://bugs.jquery.com/ticket/13378 1261 rbuggyQSA = []; 1262 1263 if (support.qsa = rnative.test(document.querySelectorAll)) { 1264 // Build QSA regex 1265 // Regex strategy adopted from Diego Perini 1266 assert(function (div) { 1267 // Select is set to empty string on purpose 1268 // This is to test IE's treatment of not explicitly 1269 // setting a boolean content attribute, 1270 // since its presence should be enough 1271 // http://bugs.jquery.com/ticket/12359 1272 docElem.appendChild(div).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; 1273 1274 // Support: IE8, Opera 11-12.16 1275 // Nothing should be selected when empty strings follow ^= or $= or *= 1276 // The test attribute must be unknown in Opera but "safe" for WinRT 1277 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 1278 if (div.querySelectorAll("[msallowcapture^='']").length) { 1279 rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); 1280 } 1281 1282 // Support: IE8 1283 // Boolean attributes and "value" are not treated correctly 1284 if (!div.querySelectorAll("[selected]").length) { 1285 rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); 1286 } 1287 1288 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 1289 if (!div.querySelectorAll("[id~=" + expando + "-]").length) { 1290 rbuggyQSA.push("~="); 1291 } 1292 1293 // Webkit/Opera - :checked should return selected option elements 1294 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1295 // IE8 throws error here and will not see later tests 1296 if (!div.querySelectorAll(":checked").length) { 1297 rbuggyQSA.push(":checked"); 1298 } 1299 1300 // Support: Safari 8+, iOS 8+ 1301 // https://bugs.webkit.org/show_bug.cgi?id=136851 1302 // In-page `selector#id sibing-combinator selector` fails 1303 if (!div.querySelectorAll("a#" + expando + "+*").length) { 1304 rbuggyQSA.push(".#.+[+~]"); 1305 } 1306 }); 1307 1308 assert(function (div) { 1309 // Support: Windows 8 Native Apps 1310 // The type and name attributes are restricted during .innerHTML assignment 1311 var input = document.createElement("input"); 1312 input.setAttribute("type", "hidden"); 1313 div.appendChild(input).setAttribute("name", "D"); 1314 1315 // Support: IE8 1316 // Enforce case-sensitivity of name attribute 1317 if (div.querySelectorAll("[name=d]").length) { 1318 rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); 1319 } 1320 1321 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 1322 // IE8 throws error here and will not see later tests 1323 if (!div.querySelectorAll(":enabled").length) { 1324 rbuggyQSA.push(":enabled", ":disabled"); 1325 } 1326 1327 // Opera 10-11 does not throw on post-comma invalid pseudos 1328 div.querySelectorAll("*,:x"); 1329 rbuggyQSA.push(",.*:"); 1330 }); 1331 } 1332 1333 if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { 1334 1335 assert(function (div) { 1336 // Check to see if it's possible to do matchesSelector 1337 // on a disconnected node (IE 9) 1338 support.disconnectedMatch = matches.call(div, "div"); 1339 1340 // This should fail with an exception 1341 // Gecko does not error, returns false instead 1342 matches.call(div, "[s!='']:x"); 1343 rbuggyMatches.push("!=", pseudos); 1344 }); 1345 } 1346 1347 rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); 1348 rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); 1349 1350 /* Contains 1351 ---------------------------------------------------------------------- */ 1352 hasCompare = rnative.test(docElem.compareDocumentPosition); 1353 1354 // Element contains another 1355 // Purposefully self-exclusive 1356 // As in, an element does not contain itself 1357 contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { 1358 var adown = a.nodeType === 9 ? a.documentElement : a, 1359 bup = b && b.parentNode; 1360 return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); 1361 } : function (a, b) { 1362 if (b) { 1363 while (b = b.parentNode) { 1364 if (b === a) { 1365 return true; 1366 } 1367 } 1368 } 1369 return false; 1370 }; 1371 1372 /* Sorting 1373 ---------------------------------------------------------------------- */ 1374 1375 // Document order sorting 1376 sortOrder = hasCompare ? function (a, b) { 1377 1378 // Flag for duplicate removal 1379 if (a === b) { 1380 hasDuplicate = true; 1381 return 0; 1382 } 1383 1384 // Sort on method existence if only one input has compareDocumentPosition 1385 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 1386 if (compare) { 1387 return compare; 1388 } 1389 1390 // Calculate position if both inputs belong to the same document 1391 compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1392 1393 // Otherwise we know they are disconnected 1394 1; 1395 1396 // Disconnected nodes 1397 if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { 1398 1399 // Choose the first element that is related to our preferred document 1400 if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { 1401 return -1; 1402 } 1403 if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { 1404 return 1; 1405 } 1406 1407 // Maintain original order 1408 return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; 1409 } 1410 1411 return compare & 4 ? -1 : 1; 1412 } : function (a, b) { 1413 // Exit early if the nodes are identical 1414 if (a === b) { 1415 hasDuplicate = true; 1416 return 0; 1417 } 1418 1419 var cur, 1420 i = 0, 1421 aup = a.parentNode, 1422 bup = b.parentNode, 1423 ap = [a], 1424 bp = [b]; 1425 1426 // Parentless nodes are either documents or disconnected 1427 if (!aup || !bup) { 1428 return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; 1429 1430 // If the nodes are siblings, we can do a quick check 1431 } else if (aup === bup) { 1432 return siblingCheck(a, b); 1433 } 1434 1435 // Otherwise we need full lists of their ancestors for comparison 1436 cur = a; 1437 while (cur = cur.parentNode) { 1438 ap.unshift(cur); 1439 } 1440 cur = b; 1441 while (cur = cur.parentNode) { 1442 bp.unshift(cur); 1443 } 1444 1445 // Walk down the tree looking for a discrepancy 1446 while (ap[i] === bp[i]) { 1447 i++; 1448 } 1449 1450 return i ? 1451 // Do a sibling check if the nodes have a common ancestor 1452 siblingCheck(ap[i], bp[i]) : 1453 1454 // Otherwise nodes in our document sort first 1455 ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0; 1456 }; 1457 1458 return document; 1459 }; 1460 1461 Sizzle.matches = function (expr, elements) { 1462 return Sizzle(expr, null, null, elements); 1463 }; 1464 1465 Sizzle.matchesSelector = function (elem, expr) { 1466 // Set document vars if needed 1467 if ((elem.ownerDocument || elem) !== document) { 1468 setDocument(elem); 1469 } 1470 1471 // Make sure that attribute selectors are quoted 1472 expr = expr.replace(rattributeQuotes, "='$1']"); 1473 1474 if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { 1475 1476 try { 1477 var ret = matches.call(elem, expr); 1478 1479 // IE 9's matchesSelector returns false on disconnected nodes 1480 if (ret || support.disconnectedMatch || 1481 // As well, disconnected nodes are said to be in a document 1482 // fragment in IE 9 1483 elem.document && elem.document.nodeType !== 11) { 1484 return ret; 1485 } 1486 } catch (e) {} 1487 } 1488 1489 return Sizzle(expr, document, null, [elem]).length > 0; 1490 }; 1491 1492 Sizzle.contains = function (context, elem) { 1493 // Set document vars if needed 1494 if ((context.ownerDocument || context) !== document) { 1495 setDocument(context); 1496 } 1497 return contains(context, elem); 1498 }; 1499 1500 Sizzle.attr = function (elem, name) { 1501 // Set document vars if needed 1502 if ((elem.ownerDocument || elem) !== document) { 1503 setDocument(elem); 1504 } 1505 1506 var fn = Expr.attrHandle[name.toLowerCase()], 1507 1508 // Don't get fooled by Object.prototype properties (jQuery #13807) 1509 val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; 1510 1511 return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; 1512 }; 1513 1514 Sizzle.error = function (msg) { 1515 throw new Error("Syntax error, unrecognized expression: " + msg); 1516 }; 1517 1518 /** 1519 * Document sorting and removing duplicates 1520 * @param {ArrayLike} results 1521 */ 1522 Sizzle.uniqueSort = function (results) { 1523 var elem, 1524 duplicates = [], 1525 j = 0, 1526 i = 0; 1527 1528 // Unless we *know* we can detect duplicates, assume their presence 1529 hasDuplicate = !support.detectDuplicates; 1530 sortInput = !support.sortStable && results.slice(0); 1531 results.sort(sortOrder); 1532
vendor: 12,805 bytes, lines 1533-1939
1533 if (hasDuplicate) { 1534 while (elem = results[i++]) { 1535 if (elem === results[i]) { 1536 j = duplicates.push(i); 1537 } 1538 } 1539 while (j--) { 1540 results.splice(duplicates[j], 1); 1541 } 1542 } 1543 1544 // Clear input after sorting to release objects 1545 // See https://github.com/jquery/sizzle/pull/225 1546 sortInput = null; 1547 1548 return results; 1549 }; 1550 1551 /** 1552 * Utility function for retrieving the text value of an array of DOM nodes 1553 * @param {Array|Element} elem 1554 */ 1555 getText = Sizzle.getText = function (elem) { 1556 var node, 1557 ret = "", 1558 i = 0, 1559 nodeType = elem.nodeType; 1560 1561 if (!nodeType) { 1562 // If no nodeType, this is expected to be an array 1563 while (node = elem[i++]) { 1564 // Do not traverse comment nodes 1565 ret += getText(node); 1566 } 1567 } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { 1568 // Use textContent for elements 1569 // innerText usage removed for consistency of new lines (jQuery #11153) 1570 if (typeof elem.textContent === "string") { 1571 return elem.textContent; 1572 } else { 1573 // Traverse its children 1574 for (elem = elem.firstChild; elem; elem = elem.nextSibling) { 1575 ret += getText(elem); 1576 } 1577 } 1578 } else if (nodeType === 3 || nodeType === 4) { 1579 return elem.nodeValue; 1580 } 1581 // Do not include comment or processing instruction nodes 1582 1583 return ret; 1584 }; 1585 1586 Expr = Sizzle.selectors = { 1587 1588 // Can be adjusted by the user 1589 cacheLength: 50, 1590 1591 createPseudo: markFunction, 1592 1593 match: matchExpr, 1594 1595 attrHandle: {}, 1596 1597 find: {}, 1598 1599 relative: { 1600 ">": { dir: "parentNode", first: true }, 1601 " ": { dir: "parentNode" }, 1602 "+": { dir: "previousSibling", first: true }, 1603 "~": { dir: "previousSibling" } 1604 }, 1605 1606 preFilter: { 1607 "ATTR": function (match) { 1608 match[1] = match[1].replace(runescape, funescape); 1609 1610 // Move the given value to match[3] whether quoted or unquoted 1611 match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); 1612 1613 if (match[2] === "~=") { 1614 match[3] = " " + match[3] + " "; 1615 } 1616 1617 return match.slice(0, 4); 1618 }, 1619 1620 "CHILD": function (match) { 1621 /* matches from matchExpr["CHILD"] 1622 1 type (only|nth|...) 1623 2 what (child|of-type) 1624 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 1625 4 xn-component of xn+y argument ([+-]?\d*n|) 1626 5 sign of xn-component 1627 6 x of xn-component 1628 7 sign of y-component 1629 8 y of y-component 1630 */ 1631 match[1] = match[1].toLowerCase(); 1632 1633 if (match[1].slice(0, 3) === "nth") { 1634 // nth-* requires argument 1635 if (!match[3]) { 1636 Sizzle.error(match[0]); 1637 } 1638 1639 // numeric x and y parameters for Expr.filter.CHILD 1640 // remember that false/true cast respectively to 0/1 1641 match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); 1642 match[5] = +(match[7] + match[8] || match[3] === "odd"); 1643 1644 // other types prohibit arguments 1645 } else if (match[3]) { 1646 Sizzle.error(match[0]); 1647 } 1648 1649 return match; 1650 }, 1651 1652 "PSEUDO": function (match) { 1653 var excess, 1654 unquoted = !match[6] && match[2]; 1655 1656 if (matchExpr["CHILD"].test(match[0])) { 1657 return null; 1658 } 1659 1660 // Accept quoted arguments as-is 1661 if (match[3]) { 1662 match[2] = match[4] || match[5] || ""; 1663 1664 // Strip excess characters from unquoted arguments 1665 } else if (unquoted && rpseudo.test(unquoted) && ( 1666 // Get excess from tokenize (recursively) 1667 excess = tokenize(unquoted, true)) && ( 1668 // advance to the next closing parenthesis 1669 excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { 1670 1671 // excess is a negative index 1672 match[0] = match[0].slice(0, excess); 1673 match[2] = unquoted.slice(0, excess); 1674 } 1675 1676 // Return only captures needed by the pseudo filter method (type and argument) 1677 return match.slice(0, 3); 1678 } 1679 }, 1680 1681 filter: { 1682 1683 "TAG": function (nodeNameSelector) { 1684 var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); 1685 return nodeNameSelector === "*" ? function () { 1686 return true; 1687 } : function (elem) { 1688 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 1689 }; 1690 }, 1691 1692 "CLASS": function (className) { 1693 var pattern = classCache[className + " "]; 1694 1695 return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) { 1696 return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); 1697 }); 1698 }, 1699 1700 "ATTR": function (name, operator, check) { 1701 return function (elem) { 1702 var result = Sizzle.attr(elem, name); 1703 1704 if (result == null) { 1705 return operator === "!="; 1706 } 1707 if (!operator) { 1708 return true; 1709 } 1710 1711 result += ""; 1712 1713 return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false; 1714 }; 1715 }, 1716 1717 "CHILD": function (type, what, argument, first, last) { 1718 var simple = type.slice(0, 3) !== "nth", 1719 forward = type.slice(-4) !== "last", 1720 ofType = what === "of-type"; 1721 1722 return first === 1 && last === 0 ? 1723 1724 // Shortcut for :nth-*(n) 1725 function (elem) { 1726 return !!elem.parentNode; 1727 } : function (elem, context, xml) { 1728 var cache, 1729 uniqueCache, 1730 outerCache, 1731 node, 1732 nodeIndex, 1733 start, 1734 dir = simple !== forward ? "nextSibling" : "previousSibling", 1735 parent = elem.parentNode, 1736 name = ofType && elem.nodeName.toLowerCase(), 1737 useCache = !xml && !ofType, 1738 diff = false; 1739 1740 if (parent) { 1741 1742 // :(first|last|only)-(child|of-type) 1743 if (simple) { 1744 while (dir) { 1745 node = elem; 1746 while (node = node[dir]) { 1747 if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { 1748 1749 return false; 1750 } 1751 } 1752 // Reverse direction for :only-* (if we haven't yet done so) 1753 start = dir = type === "only" && !start && "nextSibling"; 1754 } 1755 return true; 1756 } 1757 1758 start = [forward ? parent.firstChild : parent.lastChild]; 1759 1760 // non-xml :nth-child(...) stores cache data on `parent` 1761 if (forward && useCache) { 1762 1763 // Seek `elem` from a previously-cached index 1764 1765 // ...in a gzip-friendly way 1766 node = parent; 1767 outerCache = node[expando] || (node[expando] = {}); 1768 1769 // Support: IE <9 only 1770 // Defend against cloned attroperties (jQuery gh-1709) 1771 uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); 1772 1773 cache = uniqueCache[type] || []; 1774 nodeIndex = cache[0] === dirruns && cache[1]; 1775 diff = nodeIndex && cache[2]; 1776 node = nodeIndex && parent.childNodes[nodeIndex]; 1777 1778 while (node = ++nodeIndex && node && node[dir] || ( 1779 1780 // Fallback to seeking `elem` from the start 1781 diff = nodeIndex = 0) || start.pop()) { 1782 1783 // When found, cache indexes on `parent` and break 1784 if (node.nodeType === 1 && ++diff && node === elem) { 1785 uniqueCache[type] = [dirruns, nodeIndex, diff]; 1786 break; 1787 } 1788 } 1789 } else { 1790 // Use previously-cached element index if available 1791 if (useCache) { 1792 // ...in a gzip-friendly way 1793 node = elem; 1794 outerCache = node[expando] || (node[expando] = {}); 1795 1796 // Support: IE <9 only 1797 // Defend against cloned attroperties (jQuery gh-1709) 1798 uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); 1799 1800 cache = uniqueCache[type] || []; 1801 nodeIndex = cache[0] === dirruns && cache[1]; 1802 diff = nodeIndex; 1803 } 1804 1805 // xml :nth-child(...) 1806 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 1807 if (diff === false) { 1808 // Use the same loop as above to seek `elem` from the start 1809 while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { 1810 1811 if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { 1812 1813 // Cache the index of each encountered element 1814 if (useCache) { 1815 outerCache = node[expando] || (node[expando] = {}); 1816 1817 // Support: IE <9 only 1818 // Defend against cloned attroperties (jQuery gh-1709) 1819 uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); 1820 1821 uniqueCache[type] = [dirruns, diff]; 1822 } 1823 1824 if (node === elem) { 1825 break; 1826 } 1827 } 1828 } 1829 } 1830 } 1831 1832 // Incorporate the offset, then check against cycle size 1833 diff -= last; 1834 return diff === first || diff % first === 0 && diff / first >= 0; 1835 } 1836 }; 1837 }, 1838 1839 "PSEUDO": function (pseudo, argument) { 1840 // pseudo-class names are case-insensitive 1841 // http://www.w3.org/TR/selectors/#pseudo-classes 1842 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 1843 // Remember that setFilters inherits from pseudos 1844 var args, 1845 fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); 1846 1847 // The user may use createPseudo to indicate that 1848 // arguments are needed to create the filter function 1849 // just as Sizzle does 1850 if (fn[expando]) { 1851 return fn(argument); 1852 } 1853 1854 // But maintain support for old signatures 1855 if (fn.length > 1) { 1856 args = [pseudo, pseudo, "", argument]; 1857 return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { 1858 var idx, 1859 matched = fn(seed, argument), 1860 i = matched.length; 1861 while (i--) { 1862 idx = indexOf(seed, matched[i]); 1863 seed[idx] = !(matches[idx] = matched[i]); 1864 } 1865 }) : function (elem) { 1866 return fn(elem, 0, args); 1867 }; 1868 } 1869 1870 return fn; 1871 } 1872 }, 1873 1874 pseudos: { 1875 // Potentially complex pseudos 1876 "not": markFunction(function (selector) { 1877 // Trim the selector passed to compile 1878 // to avoid treating leading and trailing 1879 // spaces as combinators 1880 var input = [], 1881 results = [], 1882 matcher = compile(selector.replace(rtrim, "$1")); 1883 1884 return matcher[expando] ? markFunction(function (seed, matches, context, xml) { 1885 var elem, 1886 unmatched = matcher(seed, null, xml, []), 1887 i = seed.length; 1888 1889 // Match elements unmatched by `matcher` 1890 while (i--) { 1891 if (elem = unmatched[i]) { 1892 seed[i] = !(matches[i] = elem); 1893 } 1894 } 1895 }) : function (elem, context, xml) { 1896 input[0] = elem; 1897 matcher(input, null, xml, results); 1898 // Don't keep the element (issue #299) 1899 input[0] = null; 1900 return !results.pop(); 1901 }; 1902 }), 1903 1904 "has": markFunction(function (selector) { 1905 return function (elem) { 1906 return Sizzle(selector, elem).length > 0; 1907 }; 1908 }), 1909 1910 "contains": markFunction(function (text) { 1911 text = text.replace(runescape, funescape); 1912 return function (elem) { 1913 return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; 1914 }; 1915 }), 1916 1917 // "Whether an element is represented by a :lang() selector 1918 // is based solely on the element's language value 1919 // being equal to the identifier C, 1920 // or beginning with the identifier C immediately followed by "-". 1921 // The matching of C against the element's language value is performed case-insensitively. 1922 // The identifier C does not have to be a valid language name." 1923 // http://www.w3.org/TR/selectors/#lang-pseudo 1924 "lang": markFunction(function (lang) { 1925 // lang value must be a valid identifier 1926 if (!ridentifier.test(lang || "")) { 1927 Sizzle.error("unsupported lang: " + lang); 1928 } 1929 lang = lang.replace(runescape, funescape).toLowerCase(); 1930 return function (elem) { 1931 var elemLang; 1932 do { 1933 if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) { 1934 1935 elemLang = elemLang.toLowerCase(); 1936 return elemLang === lang || elemLang.indexOf(lang + "-") === 0; 1937 } 1938 } while ((elem = elem.parentNode) && elem.nodeType === 1); 1939 return false;
vendor: 4,299 bytes, lines 1940-2093
1940 }; 1941 }), 1942 1943 // Miscellaneous 1944 "target": function (elem) { 1945 var hash = window.location && window.location.hash; 1946 return hash && hash.slice(1) === elem.id; 1947 }, 1948 1949 "root": function (elem) { 1950 return elem === docElem; 1951 }, 1952 1953 "focus": function (elem) { 1954 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 1955 }, 1956 1957 // Boolean properties 1958 "enabled": function (elem) { 1959 return elem.disabled === false; 1960 }, 1961 1962 "disabled": function (elem) { 1963 return elem.disabled === true; 1964 }, 1965 1966 "checked": function (elem) { 1967 // In CSS3, :checked should return both checked and selected elements 1968 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 1969 var nodeName = elem.nodeName.toLowerCase(); 1970 return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected; 1971 }, 1972 1973 "selected": function (elem) { 1974 // Accessing this property makes selected-by-default 1975 // options in Safari work properly 1976 if (elem.parentNode) { 1977 elem.parentNode.selectedIndex; 1978 } 1979 1980 return elem.selected === true; 1981 }, 1982 1983 // Contents 1984 "empty": function (elem) { 1985 // http://www.w3.org/TR/selectors/#empty-pseudo 1986 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 1987 // but not by others (comment: 8; processing instruction: 7; etc.) 1988 // nodeType < 6 works because attributes (2) do not appear as children 1989 for (elem = elem.firstChild; elem; elem = elem.nextSibling) { 1990 if (elem.nodeType < 6) { 1991 return false; 1992 } 1993 } 1994 return true; 1995 }, 1996 1997 "parent": function (elem) { 1998 return !Expr.pseudos["empty"](elem); 1999 }, 2000 2001 // Element/input types 2002 "header": function (elem) { 2003 return rheader.test(elem.nodeName); 2004 }, 2005 2006 "input": function (elem) { 2007 return rinputs.test(elem.nodeName); 2008 }, 2009 2010 "button": function (elem) { 2011 var name = elem.nodeName.toLowerCase(); 2012 return name === "input" && elem.type === "button" || name === "button"; 2013 }, 2014 2015 "text": function (elem) { 2016 var attr; 2017 return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( 2018 2019 // Support: IE<8 2020 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 2021 (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); 2022 }, 2023 2024 // Position-in-collection 2025 "first": createPositionalPseudo(function () { 2026 return [0]; 2027 }), 2028 2029 "last": createPositionalPseudo(function (matchIndexes, length) { 2030 return [length - 1]; 2031 }), 2032 2033 "eq": createPositionalPseudo(function (matchIndexes, length, argument) { 2034 return [argument < 0 ? argument + length : argument]; 2035 }), 2036 2037 "even": createPositionalPseudo(function (matchIndexes, length) { 2038 var i = 0; 2039 for (; i < length; i += 2) { 2040 matchIndexes.push(i); 2041 } 2042 return matchIndexes; 2043 }), 2044 2045 "odd": createPositionalPseudo(function (matchIndexes, length) { 2046 var i = 1; 2047 for (; i < length; i += 2) { 2048 matchIndexes.push(i); 2049 } 2050 return matchIndexes; 2051 }), 2052 2053 "lt": createPositionalPseudo(function (matchIndexes, length, argument) { 2054 var i = argument < 0 ? argument + length : argument; 2055 for (; --i >= 0;) { 2056 matchIndexes.push(i); 2057 } 2058 return matchIndexes; 2059 }), 2060 2061 "gt": createPositionalPseudo(function (matchIndexes, length, argument) { 2062 var i = argument < 0 ? argument + length : argument; 2063 for (; ++i < length;) { 2064 matchIndexes.push(i); 2065 } 2066 return matchIndexes; 2067 }) 2068 } 2069 }; 2070 2071 Expr.pseudos["nth"] = Expr.pseudos["eq"]; 2072 2073 // Add button/input type pseudos 2074 for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) { 2075 Expr.pseudos[i] = createInputPseudo(i); 2076 } 2077 for (i in { submit: true, reset: true }) { 2078 Expr.pseudos[i] = createButtonPseudo(i); 2079 } 2080 2081 // Easy API for creating new setFilters 2082 function setFilters() {} 2083 setFilters.prototype = Expr.filters = Expr.pseudos; 2084 Expr.setFilters = new setFilters(); 2085 2086 tokenize = Sizzle.tokenize = function (selector, parseOnly) { 2087 var matched, 2088 match, 2089 tokens, 2090 type, 2091 soFar, 2092 groups, 2093 preFilters,
vendor: 7,182 bytes, lines 2094-2359
2094 cached = tokenCache[selector + " "]; 2095 2096 if (cached) { 2097 return parseOnly ? 0 : cached.slice(0); 2098 } 2099 2100 soFar = selector; 2101 groups = []; 2102 preFilters = Expr.preFilter; 2103 2104 while (soFar) { 2105 2106 // Comma and first run 2107 if (!matched || (match = rcomma.exec(soFar))) { 2108 if (match) { 2109 // Don't consume trailing commas as valid 2110 soFar = soFar.slice(match[0].length) || soFar; 2111 } 2112 groups.push(tokens = []); 2113 } 2114 2115 matched = false; 2116 2117 // Combinators 2118 if (match = rcombinators.exec(soFar)) { 2119 matched = match.shift(); 2120 tokens.push({ 2121 value: matched, 2122 // Cast descendant combinators to space 2123 type: match[0].replace(rtrim, " ") 2124 }); 2125 soFar = soFar.slice(matched.length); 2126 } 2127 2128 // Filters 2129 for (type in Expr.filter) { 2130 if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { 2131 matched = match.shift(); 2132 tokens.push({ 2133 value: matched, 2134 type: type, 2135 matches: match 2136 }); 2137 soFar = soFar.slice(matched.length); 2138 } 2139 } 2140 2141 if (!matched) { 2142 break; 2143 } 2144 } 2145 2146 // Return the length of the invalid excess 2147 // if we're just parsing 2148 // Otherwise, throw an error or return tokens 2149 return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : 2150 // Cache the tokens 2151 tokenCache(selector, groups).slice(0); 2152 }; 2153 2154 function toSelector(tokens) { 2155 var i = 0, 2156 len = tokens.length, 2157 selector = ""; 2158 for (; i < len; i++) { 2159 selector += tokens[i].value; 2160 } 2161 return selector; 2162 } 2163 2164 function addCombinator(matcher, combinator, base) { 2165 var dir = combinator.dir, 2166 checkNonElements = base && dir === "parentNode", 2167 doneName = done++; 2168 2169 return combinator.first ? 2170 // Check against closest ancestor/preceding element 2171 function (elem, context, xml) { 2172 while (elem = elem[dir]) { 2173 if (elem.nodeType === 1 || checkNonElements) { 2174 return matcher(elem, context, xml); 2175 } 2176 } 2177 } : 2178 2179 // Check against all ancestor/preceding elements 2180 function (elem, context, xml) { 2181 var oldCache, 2182 uniqueCache, 2183 outerCache, 2184 newCache = [dirruns, doneName]; 2185 2186 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 2187 if (xml) { 2188 while (elem = elem[dir]) { 2189 if (elem.nodeType === 1 || checkNonElements) { 2190 if (matcher(elem, context, xml)) { 2191 return true; 2192 } 2193 } 2194 } 2195 } else { 2196 while (elem = elem[dir]) { 2197 if (elem.nodeType === 1 || checkNonElements) { 2198 outerCache = elem[expando] || (elem[expando] = {}); 2199 2200 // Support: IE <9 only 2201 // Defend against cloned attroperties (jQuery gh-1709) 2202 uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); 2203 2204 if ((oldCache = uniqueCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) { 2205 2206 // Assign to newCache so results back-propagate to previous elements 2207 return newCache[2] = oldCache[2]; 2208 } else { 2209 // Reuse newcache so results back-propagate to previous elements 2210 uniqueCache[dir] = newCache; 2211 2212 // A match means we're done; a fail means we have to keep checking 2213 if (newCache[2] = matcher(elem, context, xml)) { 2214 return true; 2215 } 2216 } 2217 } 2218 } 2219 } 2220 }; 2221 } 2222 2223 function elementMatcher(matchers) { 2224 return matchers.length > 1 ? function (elem, context, xml) { 2225 var i = matchers.length; 2226 while (i--) { 2227 if (!matchers[i](elem, context, xml)) { 2228 return false; 2229 } 2230 } 2231 return true; 2232 } : matchers[0]; 2233 } 2234 2235 function multipleContexts(selector, contexts, results) { 2236 var i = 0, 2237 len = contexts.length; 2238 for (; i < len; i++) { 2239 Sizzle(selector, contexts[i], results); 2240 } 2241 return results; 2242 } 2243 2244 function condense(unmatched, map, filter, context, xml) { 2245 var elem, 2246 newUnmatched = [], 2247 i = 0, 2248 len = unmatched.length, 2249 mapped = map != null; 2250 2251 for (; i < len; i++) { 2252 if (elem = unmatched[i]) { 2253 if (!filter || filter(elem, context, xml)) { 2254 newUnmatched.push(elem); 2255 if (mapped) { 2256 map.push(i); 2257 } 2258 } 2259 } 2260 } 2261 2262 return newUnmatched; 2263 } 2264 2265 function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { 2266 if (postFilter && !postFilter[expando]) { 2267 postFilter = setMatcher(postFilter); 2268 } 2269 if (postFinder && !postFinder[expando]) { 2270 postFinder = setMatcher(postFinder, postSelector); 2271 } 2272 return markFunction(function (seed, results, context, xml) { 2273 var temp, 2274 i, 2275 elem, 2276 preMap = [], 2277 postMap = [], 2278 preexisting = results.length, 2279 2280 2281 // Get initial elements from seed or context 2282 elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), 2283 2284 2285 // Prefilter to get matcher input, preserving a map for seed-results synchronization 2286 matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, 2287 matcherOut = matcher ? 2288 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 2289 postFinder || (seed ? preFilter : preexisting || postFilter) ? 2290 2291 // ...intermediate processing is necessary 2292 [] : 2293 2294 // ...otherwise use results directly 2295 results : matcherIn; 2296 2297 // Find primary matches 2298 if (matcher) { 2299 matcher(matcherIn, matcherOut, context, xml); 2300 } 2301 2302 // Apply postFilter 2303 if (postFilter) { 2304 temp = condense(matcherOut, postMap); 2305 postFilter(temp, [], context, xml); 2306 2307 // Un-match failing elements by moving them back to matcherIn 2308 i = temp.length; 2309 while (i--) { 2310 if (elem = temp[i]) { 2311 matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); 2312 } 2313 } 2314 } 2315 2316 if (seed) { 2317 if (postFinder || preFilter) { 2318 if (postFinder) { 2319 // Get the final matcherOut by condensing this intermediate into postFinder contexts 2320 temp = []; 2321 i = matcherOut.length; 2322 while (i--) { 2323 if (elem = matcherOut[i]) { 2324 // Restore matcherIn since elem is not yet a final match 2325 temp.push(matcherIn[i] = elem); 2326 } 2327 } 2328 postFinder(null, matcherOut = [], temp, xml); 2329 } 2330 2331 // Move matched elements from seed to results to keep them synchronized 2332 i = matcherOut.length; 2333 while (i--) { 2334 if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { 2335 2336 seed[temp] = !(results[temp] = elem); 2337 } 2338 } 2339 } 2340 2341 // Add elements to results, through postFinder if defined 2342 } else { 2343 matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); 2344 if (postFinder) { 2345 postFinder(null, results, matcherOut, xml); 2346 } else { 2347 push.apply(results, matcherOut); 2348 } 2349 } 2350 }); 2351 } 2352 2353 function matcherFromTokens(tokens) { 2354 var checkContext, 2355 matcher, 2356 j, 2357 len = tokens.length, 2358 leadingRelative = Expr.relative[tokens[0].type], 2359 implicitRelative = leadingRelative || Expr.relative[" "],
vendor: 7,952 bytes, lines 2360-2596
2360 i = leadingRelative ? 1 : 0, 2361 2362 2363 // The foundational matcher ensures that elements are reachable from top-level context(s) 2364 matchContext = addCombinator(function (elem) { 2365 return elem === checkContext; 2366 }, implicitRelative, true), 2367 matchAnyContext = addCombinator(function (elem) { 2368 return indexOf(checkContext, elem) > -1; 2369 }, implicitRelative, true), 2370 matchers = [function (elem, context, xml) { 2371 var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); 2372 // Avoid hanging onto element (issue #299) 2373 checkContext = null; 2374 return ret; 2375 }]; 2376 2377 for (; i < len; i++) { 2378 if (matcher = Expr.relative[tokens[i].type]) { 2379 matchers = [addCombinator(elementMatcher(matchers), matcher)]; 2380 } else { 2381 matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); 2382 2383 // Return special upon seeing a positional matcher 2384 if (matcher[expando]) { 2385 // Find the next relative operator (if any) for proper handling 2386 j = ++i; 2387 for (; j < len; j++) { 2388 if (Expr.relative[tokens[j].type]) { 2389 break; 2390 } 2391 } 2392 return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( 2393 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 2394 tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); 2395 } 2396 matchers.push(matcher); 2397 } 2398 } 2399 2400 return elementMatcher(matchers); 2401 } 2402 2403 function matcherFromGroupMatchers(elementMatchers, setMatchers) { 2404 var bySet = setMatchers.length > 0, 2405 byElement = elementMatchers.length > 0, 2406 superMatcher = function (seed, context, xml, results, outermost) { 2407 var elem, 2408 j, 2409 matcher, 2410 matchedCount = 0, 2411 i = "0", 2412 unmatched = seed && [], 2413 setMatched = [], 2414 contextBackup = outermostContext, 2415 2416 // We must always have either seed elements or outermost context 2417 elems = seed || byElement && Expr.find["TAG"]("*", outermost), 2418 2419 // Use integer dirruns iff this is the outermost matcher 2420 dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, 2421 len = elems.length; 2422 2423 if (outermost) { 2424 outermostContext = context === document || context || outermost; 2425 } 2426 2427 // Add elements passing elementMatchers directly to results 2428 // Support: IE<9, Safari 2429 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 2430 for (; i !== len && (elem = elems[i]) != null; i++) { 2431 if (byElement && elem) { 2432 j = 0; 2433 if (!context && elem.ownerDocument !== document) { 2434 setDocument(elem); 2435 xml = !documentIsHTML; 2436 } 2437 while (matcher = elementMatchers[j++]) { 2438 if (matcher(elem, context || document, xml)) { 2439 results.push(elem); 2440 break; 2441 } 2442 } 2443 if (outermost) { 2444 dirruns = dirrunsUnique; 2445 } 2446 } 2447 2448 // Track unmatched elements for set filters 2449 if (bySet) { 2450 // They will have gone through all possible matchers 2451 if (elem = !matcher && elem) { 2452 matchedCount--; 2453 } 2454 2455 // Lengthen the array for every element, matched or not 2456 if (seed) { 2457 unmatched.push(elem); 2458 } 2459 } 2460 } 2461 2462 // `i` is now the count of elements visited above, and adding it to `matchedCount` 2463 // makes the latter nonnegative. 2464 matchedCount += i; 2465 2466 // Apply set filters to unmatched elements 2467 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 2468 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 2469 // no element matchers and no seed. 2470 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 2471 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 2472 // numerically zero. 2473 if (bySet && i !== matchedCount) { 2474 j = 0; 2475 while (matcher = setMatchers[j++]) { 2476 matcher(unmatched, setMatched, context, xml); 2477 } 2478 2479 if (seed) { 2480 // Reintegrate element matches to eliminate the need for sorting 2481 if (matchedCount > 0) { 2482 while (i--) { 2483 if (!(unmatched[i] || setMatched[i])) { 2484 setMatched[i] = pop.call(results); 2485 } 2486 } 2487 } 2488 2489 // Discard index placeholder values to get only actual matches 2490 setMatched = condense(setMatched); 2491 } 2492 2493 // Add matches to results 2494 push.apply(results, setMatched); 2495 2496 // Seedless set matches succeeding multiple successful matchers stipulate sorting 2497 if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { 2498 2499 Sizzle.uniqueSort(results); 2500 } 2501 } 2502 2503 // Override manipulation of globals by nested matchers 2504 if (outermost) { 2505 dirruns = dirrunsUnique; 2506 outermostContext = contextBackup; 2507 } 2508 2509 return unmatched; 2510 }; 2511 2512 return bySet ? markFunction(superMatcher) : superMatcher; 2513 } 2514 2515 compile = Sizzle.compile = function (selector, match /* Internal Use Only */) { 2516 var i, 2517 setMatchers = [], 2518 elementMatchers = [], 2519 cached = compilerCache[selector + " "]; 2520 2521 if (!cached) { 2522 // Generate a function of recursive functions that can be used to check each element 2523 if (!match) { 2524 match = tokenize(selector); 2525 } 2526 i = match.length; 2527 while (i--) { 2528 cached = matcherFromTokens(match[i]); 2529 if (cached[expando]) { 2530 setMatchers.push(cached); 2531 } else { 2532 elementMatchers.push(cached); 2533 } 2534 } 2535 2536 // Cache the compiled function 2537 cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); 2538 2539 // Save selector and tokenization 2540 cached.selector = selector; 2541 } 2542 return cached; 2543 }; 2544 2545 /** 2546 * A low-level selection function that works with Sizzle's compiled 2547 * selector functions 2548 * @param {String|Function} selector A selector or a pre-compiled 2549 * selector function built with Sizzle.compile 2550 * @param {Element} context 2551 * @param {Array} [results] 2552 * @param {Array} [seed] A set of elements to match against 2553 */ 2554 select = Sizzle.select = function (selector, context, results, seed) { 2555 var i, 2556 tokens, 2557 token, 2558 type, 2559 find, 2560 compiled = typeof selector === "function" && selector, 2561 match = !seed && tokenize(selector = compiled.selector || selector); 2562 2563 results = results || []; 2564 2565 // Try to minimize operations if there is only one selector in the list and no seed 2566 // (the latter of which guarantees us context) 2567 if (match.length === 1) { 2568 2569 // Reduce context if the leading compound selector is an ID 2570 tokens = match[0] = match[0].slice(0); 2571 if (tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { 2572 2573 context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; 2574 if (!context) { 2575 return results; 2576 2577 // Precompiled matchers will still verify ancestry, so step up a level 2578 } else if (compiled) { 2579 context = context.parentNode; 2580 } 2581 2582 selector = selector.slice(tokens.shift().value.length); 2583 } 2584 2585 // Fetch a seed set for right-to-left matching 2586 i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; 2587 while (i--) { 2588 token = tokens[i]; 2589 2590 // Abort if we hit a combinator 2591 if (Expr.relative[type = token.type]) { 2592 break; 2593 } 2594 if (find = Expr.find[type]) { 2595 // Search, expanding context for leading sibling combinators 2596 if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
vendor: 5,935 bytes, lines 2596-2810
2596ontext(context.parentNode) || context)) { 2597 2598 // If seed is empty or no tokens remain, we can return early 2599 tokens.splice(i, 1); 2600 selector = seed.length && toSelector(tokens); 2601 if (!selector) { 2602 push.apply(results, seed); 2603 return results; 2604 } 2605 2606 break; 2607 } 2608 } 2609 } 2610 } 2611 2612 // Compile and execute a filtering function if one is not provided 2613 // Provide `match` to avoid retokenization if we modified the selector above 2614 (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); 2615 return results; 2616 }; 2617 2618 // One-time assignments 2619 2620 // Sort stability 2621 support.sortStable = expando.split("").sort(sortOrder).join("") === expando; 2622 2623 // Support: Chrome 14-35+ 2624 // Always assume duplicates if they aren't passed to the comparison function 2625 support.detectDuplicates = !!hasDuplicate; 2626 2627 // Initialize against the default document 2628 setDocument(); 2629 2630 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 2631 // Detached nodes confoundingly follow *each other* 2632 support.sortDetached = assert(function (div1) { 2633 // Should return 1, but returns 4 (following) 2634 return div1.compareDocumentPosition(document.createElement("div")) & 1; 2635 }); 2636 2637 // Support: IE<8 2638 // Prevent attribute/property "interpolation" 2639 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 2640 if (!assert(function (div) { 2641 div.innerHTML = "<a href='#'></a>"; 2642 return div.firstChild.getAttribute("href") === "#"; 2643 })) { 2644 addHandle("type|href|height|width", function (elem, name, isXML) { 2645 if (!isXML) { 2646 return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2); 2647 } 2648 }); 2649 } 2650 2651 // Support: IE<9 2652 // Use defaultValue in place of getAttribute("value") 2653 if (!support.attributes || !assert(function (div) { 2654 div.innerHTML = "<input/>"; 2655 div.firstChild.setAttribute("value", ""); 2656 return div.firstChild.getAttribute("value") === ""; 2657 })) { 2658 addHandle("value", function (elem, name, isXML) { 2659 if (!isXML && elem.nodeName.toLowerCase() === "input") { 2660 return elem.defaultValue; 2661 } 2662 }); 2663 } 2664 2665 // Support: IE<9 2666 // Use getAttributeNode to fetch booleans when getAttribute lies 2667 if (!assert(function (div) { 2668 return div.getAttribute("disabled") == null; 2669 })) { 2670 addHandle(booleans, function (elem, name, isXML) { 2671 var val; 2672 if (!isXML) { 2673 return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; 2674 } 2675 }); 2676 } 2677 2678 return Sizzle; 2679 }(window); 2680 2681 jQuery.find = Sizzle; 2682 jQuery.expr = Sizzle.selectors; 2683 jQuery.expr[":"] = jQuery.expr.pseudos; 2684 jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 2685 jQuery.text = Sizzle.getText; 2686 jQuery.isXMLDoc = Sizzle.isXML; 2687 jQuery.contains = Sizzle.contains; 2688 2689 var dir = function (elem, dir, until) { 2690 var matched = [], 2691 truncate = until !== undefined; 2692 2693 while ((elem = elem[dir]) && elem.nodeType !== 9) { 2694 if (elem.nodeType === 1) { 2695 if (truncate && jQuery(elem).is(until)) { 2696 break; 2697 } 2698 matched.push(elem); 2699 } 2700 } 2701 return matched; 2702 }; 2703 2704 var siblings = function (n, elem) { 2705 var matched = []; 2706 2707 for (; n; n = n.nextSibling) { 2708 if (n.nodeType === 1 && n !== elem) { 2709 matched.push(n); 2710 } 2711 } 2712 2713 return matched; 2714 }; 2715 2716 var rneedsContext = jQuery.expr.match.needsContext; 2717 2718 var rsingleTag = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/; 2719 2720 var risSimple = /^.[^:#\[\.,]*$/; 2721 2722 // Implement the identical functionality for filter and not 2723 function winnow(elements, qualifier, not) { 2724 if (jQuery.isFunction(qualifier)) { 2725 return jQuery.grep(elements, function (elem, i) { 2726 /* jshint -W018 */ 2727 return !!qualifier.call(elem, i, elem) !== not; 2728 }); 2729 } 2730 2731 if (qualifier.nodeType) { 2732 return jQuery.grep(elements, function (elem) { 2733 return elem === qualifier !== not; 2734 }); 2735 } 2736 2737 if (typeof qualifier === "string") { 2738 if (risSimple.test(qualifier)) { 2739 return jQuery.filter(qualifier, elements, not); 2740 } 2741 2742 qualifier = jQuery.filter(qualifier, elements); 2743 } 2744 2745 return jQuery.grep(elements, function (elem) { 2746 return jQuery.inArray(elem, qualifier) > -1 !== not; 2747 }); 2748 } 2749 2750 jQuery.filter = function (expr, elems, not) { 2751 var elem = elems[0]; 2752 2753 if (not) { 2754 expr = ":not(" + expr + ")"; 2755 } 2756 2757 return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { 2758 return elem.nodeType === 1; 2759 })); 2760 }; 2761 2762 jQuery.fn.extend({ 2763 find: function (selector) { 2764 var i, 2765 ret = [], 2766 self = this, 2767 len = self.length; 2768 2769 if (typeof selector !== "string") { 2770 return this.pushStack(jQuery(selector).filter(function () { 2771 for (i = 0; i < len; i++) { 2772 if (jQuery.contains(self[i], this)) { 2773 return true; 2774 } 2775 } 2776 })); 2777 } 2778 2779 for (i = 0; i < len; i++) { 2780 jQuery.find(selector, self[i], ret); 2781 } 2782 2783 // Needed because $( selector, context ) becomes $( context ).find( selector ) 2784 ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret); 2785 ret.selector = this.selector ? this.selector + " " + selector : selector; 2786 return ret; 2787 }, 2788 filter: function (selector) { 2789 return this.pushStack(winnow(this, selector || [], false)); 2790 }, 2791 not: function (selector) { 2792 return this.pushStack(winnow(this, selector || [], true)); 2793 }, 2794 is: function (selector) { 2795 return !!winnow(this, 2796 2797 // If this is a positional/relative selector, check membership in the returned set 2798 // so $("p:first").is("p:last") won't return true for a doc with two "p". 2799 typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; 2800 } 2801 }); 2802 2803 // Initialize a jQuery object 2804 2805 2806 // A central reference to the root jQuery(document) 2807 var rootjQuery, 2808 2809 2810 // A simple way to check for HTML strings
vendor: 9,553 bytes, lines 2811-3167
2811 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 2812 // Strict HTML recognition (#11290: must start with <) 2813 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, 2814 init = jQuery.fn.init = function (selector, context, root) { 2815 var match, elem; 2816 2817 // HANDLE: $(""), $(null), $(undefined), $(false) 2818 if (!selector) { 2819 return this; 2820 } 2821 2822 // init accepts an alternate rootjQuery 2823 // so migrate can support jQuery.sub (gh-2101) 2824 root = root || rootjQuery; 2825 2826 // Handle HTML strings 2827 if (typeof selector === "string") { 2828 if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) { 2829 2830 // Assume that strings that start and end with <> are HTML and skip the regex check 2831 match = [null, selector, null]; 2832 } else { 2833 match = rquickExpr.exec(selector); 2834 } 2835 2836 // Match html or make sure no context is specified for #id 2837 if (match && (match[1] || !context)) { 2838 2839 // HANDLE: $(html) -> $(array) 2840 if (match[1]) { 2841 context = context instanceof jQuery ? context[0] : context; 2842 2843 // scripts is true for back-compat 2844 // Intentionally let the error be thrown if parseHTML is not present 2845 jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); 2846 2847 // HANDLE: $(html, props) 2848 if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { 2849 for (match in context) { 2850 2851 // Properties of context are called as methods if possible 2852 if (jQuery.isFunction(this[match])) { 2853 this[match](context[match]); 2854 2855 // ...and otherwise set as attributes 2856 } else { 2857 this.attr(match, context[match]); 2858 } 2859 } 2860 } 2861 2862 return this; 2863 2864 // HANDLE: $(#id) 2865 } else { 2866 elem = document.getElementById(match[2]); 2867 2868 // Check parentNode to catch when Blackberry 4.6 returns 2869 // nodes that are no longer in the document #6963 2870 if (elem && elem.parentNode) { 2871 2872 // Handle the case where IE and Opera return items 2873 // by name instead of ID 2874 if (elem.id !== match[2]) { 2875 return rootjQuery.find(selector); 2876 } 2877 2878 // Otherwise, we inject the element directly into the jQuery object 2879 this.length = 1; 2880 this[0] = elem; 2881 } 2882 2883 this.context = document; 2884 this.selector = selector; 2885 return this; 2886 } 2887 2888 // HANDLE: $(expr, $(...)) 2889 } else if (!context || context.jquery) { 2890 return (context || root).find(selector); 2891 2892 // HANDLE: $(expr, context) 2893 // (which is just equivalent to: $(context).find(expr) 2894 } else { 2895 return this.constructor(context).find(selector); 2896 } 2897 2898 // HANDLE: $(DOMElement) 2899 } else if (selector.nodeType) { 2900 this.context = this[0] = selector; 2901 this.length = 1; 2902 return this; 2903 2904 // HANDLE: $(function) 2905 // Shortcut for document ready 2906 } else if (jQuery.isFunction(selector)) { 2907 return typeof root.ready !== "undefined" ? root.ready(selector) : 2908 2909 // Execute immediately if ready is not present 2910 selector(jQuery); 2911 } 2912 2913 if (selector.selector !== undefined) { 2914 this.selector = selector.selector; 2915 this.context = selector.context; 2916 } 2917 2918 return jQuery.makeArray(selector, this); 2919 }; 2920 2921 // Give the init function the jQuery prototype for later instantiation 2922 init.prototype = jQuery.fn; 2923 2924 // Initialize central reference 2925 rootjQuery = jQuery(document); 2926 2927 var rparentsprev = /^(?:parents|prev(?:Until|All))/, 2928 2929 2930 // methods guaranteed to produce a unique set when starting from a unique set 2931 guaranteedUnique = { 2932 children: true, 2933 contents: true, 2934 next: true, 2935 prev: true 2936 }; 2937 2938 jQuery.fn.extend({ 2939 has: function (target) { 2940 var i, 2941 targets = jQuery(target, this), 2942 len = targets.length; 2943 2944 return this.filter(function () { 2945 for (i = 0; i < len; i++) { 2946 if (jQuery.contains(this, targets[i])) { 2947 return true; 2948 } 2949 } 2950 }); 2951 }, 2952 2953 closest: function (selectors, context) { 2954 var cur, 2955 i = 0, 2956 l = this.length, 2957 matched = [], 2958 pos = rneedsContext.test(selectors) || typeof selectors !== "string" ? jQuery(selectors, context || this.context) : 0; 2959 2960 for (; i < l; i++) { 2961 for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { 2962 2963 // Always skip document fragments 2964 if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 : 2965 2966 // Don't pass non-elements to Sizzle 2967 cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { 2968 2969 matched.push(cur); 2970 break; 2971 } 2972 } 2973 } 2974 2975 return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); 2976 }, 2977 2978 // Determine the position of an element within 2979 // the matched set of elements 2980 index: function (elem) { 2981 2982 // No argument, return index in parent 2983 if (!elem) { 2984 return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; 2985 } 2986 2987 // index in selector 2988 if (typeof elem === "string") { 2989 return jQuery.inArray(this[0], jQuery(elem)); 2990 } 2991 2992 // Locate the position of the desired element 2993 return jQuery.inArray( 2994 2995 // If it receives a jQuery object, the first element is used 2996 elem.jquery ? elem[0] : elem, this); 2997 }, 2998 2999 add: function (selector, context) { 3000 return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); 3001 }, 3002 3003 addBack: function (selector) { 3004 return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); 3005 } 3006 }); 3007 3008 function sibling(cur, dir) { 3009 do { 3010 cur = cur[dir]; 3011 } while (cur && cur.nodeType !== 1); 3012 3013 return cur; 3014 } 3015 3016 jQuery.each({ 3017 parent: function (elem) { 3018 var parent = elem.parentNode; 3019 return parent && parent.nodeType !== 11 ? parent : null; 3020 }, 3021 parents: function (elem) { 3022 return dir(elem, "parentNode"); 3023 }, 3024 parentsUntil: function (elem, i, until) { 3025 return dir(elem, "parentNode", until); 3026 }, 3027 next: function (elem) { 3028 return sibling(elem, "nextSibling"); 3029 }, 3030 prev: function (elem) { 3031 return sibling(elem, "previousSibling"); 3032 }, 3033 nextAll: function (elem) { 3034 return dir(elem, "nextSibling"); 3035 }, 3036 prevAll: function (elem) { 3037 return dir(elem, "previousSibling"); 3038 }, 3039 nextUntil: function (elem, i, until) { 3040 return dir(elem, "nextSibling", until); 3041 }, 3042 prevUntil: function (elem, i, until) { 3043 return dir(elem, "previousSibling", until); 3044 }, 3045 siblings: function (elem) { 3046 return siblings((elem.parentNode || {}).firstChild, elem); 3047 }, 3048 children: function (elem) { 3049 return siblings(elem.firstChild); 3050 }, 3051 contents: function (elem) { 3052 return jQuery.nodeName(elem, "iframe") ? elem.contentDocument || elem.contentWindow.document : jQuery.merge([], elem.childNodes); 3053 } 3054 }, function (name, fn) { 3055 jQuery.fn[name] = function (until, selector) { 3056 var ret = jQuery.map(this, fn, until); 3057 3058 if (name.slice(-5) !== "Until") { 3059 selector = until; 3060 } 3061 3062 if (selector && typeof selector === "string") { 3063 ret = jQuery.filter(selector, ret); 3064 } 3065 3066 if (this.length > 1) { 3067 3068 // Remove duplicates 3069 if (!guaranteedUnique[name]) { 3070 ret = jQuery.uniqueSort(ret); 3071 } 3072 3073 // Reverse order for parents* and prev-derivatives 3074 if (rparentsprev.test(name)) { 3075 ret = ret.reverse(); 3076 } 3077 } 3078 3079 return this.pushStack(ret); 3080 }; 3081 }); 3082 var rnotwhite = /\S+/g; 3083 3084 // Convert String-formatted options into Object-formatted ones 3085 function createOptions(options) { 3086 var object = {}; 3087 jQuery.each(options.match(rnotwhite) || [], function (_, flag) { 3088 object[flag] = true; 3089 }); 3090 return object; 3091 } 3092 3093 /* 3094 * Create a callback list using the following parameters: 3095 * 3096 * options: an optional list of space-separated options that will change how 3097 * the callback list behaves or a more traditional option object 3098 * 3099 * By default a callback list will act like an event callback list and can be 3100 * "fired" multiple times. 3101 * 3102 * Possible options: 3103 * 3104 * once: will ensure the callback list can only be fired once (like a Deferred) 3105 * 3106 * memory: will keep track of previous values and will call any callback added 3107 * after the list has been fired right away with the latest "memorized" 3108 * values (like a Deferred) 3109 * 3110 * unique: will ensure a callback can only be added once (no duplicate in the list) 3111 * 3112 * stopOnFalse: interrupt callings when a callback returns false 3113 * 3114 */ 3115 jQuery.Callbacks = function (options) { 3116 3117 // Convert options from String-formatted to Object-formatted if needed 3118 // (we check in cache first) 3119 options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options); 3120 3121 var // Flag to know if list is currently firing 3122 firing, 3123 3124 3125 // Last fire value for non-forgettable lists 3126 memory, 3127 3128 3129 // Flag to know if list was already fired 3130 fired, 3131 3132 3133 // Flag to prevent firing 3134 locked, 3135 3136 3137 // Actual callback list 3138 list = [], 3139 3140 3141 // Queue of execution data for repeatable lists 3142 queue = [], 3143 3144 3145 // Index of currently firing callback (modified by add/remove as needed) 3146 firingIndex = -1, 3147 3148 3149 // Fire callbacks 3150 fire = function () { 3151 3152 // Enforce single-firing 3153 locked = options.once; 3154 3155 // Execute callbacks for all pending executions, 3156 // respecting firingIndex overrides and runtime changes 3157 fired = firing = true; 3158 for (; queue.length; firingIndex = -1) { 3159 memory = queue.shift(); 3160 while (++firingIndex < list.length) { 3161 3162 // Run callback and check for early termination 3163 if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { 3164 3165 // Jump to end and forget the data so .add doesn't re-fire 3166 firingIndex = list.length; 3167 memory = false;
vendor: 8,134 bytes, lines 3168-3497
3168 } 3169 } 3170 } 3171 3172 // Forget the data if we're done with it 3173 if (!options.memory) { 3174 memory = false; 3175 } 3176 3177 firing = false; 3178 3179 // Clean up if we're done firing for good 3180 if (locked) { 3181 3182 // Keep an empty list if we have data for future add calls 3183 if (memory) { 3184 list = []; 3185 3186 // Otherwise, this object is spent 3187 } else { 3188 list = ""; 3189 } 3190 } 3191 }, 3192 3193 3194 // Actual Callbacks object 3195 self = { 3196 3197 // Add a callback or a collection of callbacks to the list 3198 add: function () { 3199 if (list) { 3200 3201 // If we have memory from a past run, we should fire after adding 3202 if (memory && !firing) { 3203 firingIndex = list.length - 1; 3204 queue.push(memory); 3205 } 3206 3207 (function add(args) { 3208 jQuery.each(args, function (_, arg) { 3209 if (jQuery.isFunction(arg)) { 3210 if (!options.unique || !self.has(arg)) { 3211 list.push(arg); 3212 } 3213 } else if (arg && arg.length && jQuery.type(arg) !== "string") { 3214 3215 // Inspect recursively 3216 add(arg); 3217 } 3218 }); 3219 })(arguments); 3220 3221 if (memory && !firing) { 3222 fire(); 3223 } 3224 } 3225 return this; 3226 }, 3227 3228 // Remove a callback from the list 3229 remove: function () { 3230 jQuery.each(arguments, function (_, arg) { 3231 var index; 3232 while ((index = jQuery.inArray(arg, list, index)) > -1) { 3233 list.splice(index, 1); 3234 3235 // Handle firing indexes 3236 if (index <= firingIndex) { 3237 firingIndex--; 3238 } 3239 } 3240 }); 3241 return this; 3242 }, 3243 3244 // Check if a given callback is in the list. 3245 // If no argument is given, return whether or not list has callbacks attached. 3246 has: function (fn) { 3247 return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; 3248 }, 3249 3250 // Remove all callbacks from the list 3251 empty: function () { 3252 if (list) { 3253 list = []; 3254 } 3255 return this; 3256 }, 3257 3258 // Disable .fire and .add 3259 // Abort any current/pending executions 3260 // Clear all callbacks and values 3261 disable: function () { 3262 locked = queue = []; 3263 list = memory = ""; 3264 return this; 3265 }, 3266 disabled: function () { 3267 return !list; 3268 }, 3269 3270 // Disable .fire 3271 // Also disable .add unless we have memory (since it would have no effect) 3272 // Abort any pending executions 3273 lock: function () { 3274 locked = true; 3275 if (!memory) { 3276 self.disable(); 3277 } 3278 return this; 3279 }, 3280 locked: function () { 3281 return !!locked; 3282 }, 3283 3284 // Call all callbacks with the given context and arguments 3285 fireWith: function (context, args) { 3286 if (!locked) { 3287 args = args || []; 3288 args = [context, args.slice ? args.slice() : args]; 3289 queue.push(args); 3290 if (!firing) { 3291 fire(); 3292 } 3293 } 3294 return this; 3295 }, 3296 3297 // Call all the callbacks with the given arguments 3298 fire: function () { 3299 self.fireWith(this, arguments); 3300 return this; 3301 }, 3302 3303 // To know if the callbacks have already been called at least once 3304 fired: function () { 3305 return !!fired; 3306 } 3307 }; 3308 3309 return self; 3310 }; 3311 3312 jQuery.extend({ 3313 3314 Deferred: function (func) { 3315 var tuples = [ 3316 3317 // action, add listener, listener list, final state 3318 ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]], 3319 state = "pending", 3320 promise = { 3321 state: function () { 3322 return state; 3323 }, 3324 always: function () { 3325 deferred.done(arguments).fail(arguments); 3326 return this; 3327 }, 3328 then: function () /* fnDone, fnFail, fnProgress */{ 3329 var fns = arguments; 3330 return jQuery.Deferred(function (newDefer) { 3331 jQuery.each(tuples, function (i, tuple) { 3332 var fn = jQuery.isFunction(fns[i]) && fns[i]; 3333 3334 // deferred[ done | fail | progress ] for forwarding actions to newDefer 3335 deferred[tuple[1]](function () { 3336 var returned = fn && fn.apply(this, arguments); 3337 if (returned && jQuery.isFunction(returned.promise)) { 3338 returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); 3339 } else { 3340 newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments); 3341 } 3342 }); 3343 }); 3344 fns = null; 3345 }).promise(); 3346 }, 3347 3348 // Get a promise for this deferred 3349 // If obj is provided, the promise aspect is added to the object 3350 promise: function (obj) { 3351 return obj != null ? jQuery.extend(obj, promise) : promise; 3352 } 3353 }, 3354 deferred = {}; 3355 3356 // Keep pipe for back-compat 3357 promise.pipe = promise.then; 3358 3359 // Add list-specific methods 3360 jQuery.each(tuples, function (i, tuple) { 3361 var list = tuple[2], 3362 stateString = tuple[3]; 3363 3364 // promise[ done | fail | progress ] = list.add 3365 promise[tuple[1]] = list.add; 3366 3367 // Handle state 3368 if (stateString) { 3369 list.add(function () { 3370 3371 // state = [ resolved | rejected ] 3372 state = stateString; 3373 3374 // [ reject_list | resolve_list ].disable; progress_list.lock 3375 }, tuples[i ^ 1][2].disable, tuples[2][2].lock); 3376 } 3377 3378 // deferred[ resolve | reject | notify ] 3379 deferred[tuple[0]] = function () { 3380 deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments); 3381 return this; 3382 }; 3383 deferred[tuple[0] + "With"] = list.fireWith; 3384 }); 3385 3386 // Make the deferred a promise 3387 promise.promise(deferred); 3388 3389 // Call given func if any 3390 if (func) { 3391 func.call(deferred, deferred); 3392 } 3393 3394 // All done! 3395 return deferred; 3396 }, 3397 3398 // Deferred helper 3399 when: function (subordinate /* , ..., subordinateN */) { 3400 var i = 0, 3401 resolveValues = slice.call(arguments), 3402 length = resolveValues.length, 3403 3404 3405 // the count of uncompleted subordinates 3406 remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length : 0, 3407 3408 3409 // the master Deferred. 3410 // If resolveValues consist of only a single Deferred, just use that. 3411 deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 3412 3413 3414 // Update function for both resolve and progress values 3415 updateFunc = function (i, contexts, values) { 3416 return function (value) { 3417 contexts[i] = this; 3418 values[i] = arguments.length > 1 ? slice.call(arguments) : value; 3419 if (values === progressValues) { 3420 deferred.notifyWith(contexts, values); 3421 } else if (! --remaining) { 3422 deferred.resolveWith(contexts, values); 3423 } 3424 }; 3425 }, 3426 progressValues, 3427 progressContexts, 3428 resolveContexts; 3429 3430 // add listeners to Deferred subordinates; treat others as resolved 3431 if (length > 1) { 3432 progressValues = new Array(length); 3433 progressContexts = new Array(length); 3434 resolveContexts = new Array(length); 3435 for (; i < length; i++) { 3436 if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) { 3437 resolveValues[i].promise().progress(updateFunc(i, progressContexts, progressValues)).done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject); 3438 } else { 3439 --remaining; 3440 } 3441 } 3442 } 3443 3444 // if we're not waiting on anything, resolve the master 3445 if (!remaining) { 3446 deferred.resolveWith(resolveContexts, resolveValues); 3447 } 3448 3449 return deferred.promise(); 3450 } 3451 }); 3452 3453 // The deferred used on DOM ready 3454 var readyList; 3455 3456 jQuery.fn.ready = function (fn) { 3457 3458 // Add the callback 3459 jQuery.ready.promise().done(fn); 3460 3461 return this; 3462 }; 3463 3464 jQuery.extend({ 3465 3466 // Is the DOM ready to be used? Set to true once it occurs. 3467 isReady: false, 3468 3469 // A counter to track how many items to wait for before 3470 // the ready event fires. See #6781 3471 readyWait: 1, 3472 3473 // Hold (or release) the ready event 3474 holdReady: function (hold) { 3475 if (hold) { 3476 jQuery.readyWait++; 3477 } else { 3478 jQuery.ready(true); 3479 } 3480 }, 3481 3482 // Handle when the DOM is ready 3483 ready: function (wait) { 3484 3485 // Abort if there are pending holds or we're already ready 3486 if (wait === true ? --jQuery.readyWait : jQuery.isReady) { 3487 return; 3488 } 3489 3490 // Remember that the DOM is ready 3491 jQuery.isReady = true; 3492 3493 // If a normal DOM Ready event fired, decrement, and wait if need be 3494 if (wait !== true && --jQuery.readyWait > 0) { 3495 return; 3496 } 3497
3498 // If there are functions bound, to execute 3499 readyList.resolveWith(document, [jQuery]); 3500 3501 // Trigger any bound ready events 3502 if (jQuery.fn.triggerHandler) { 3503 jQuery(document).triggerHandler("ready"); 3504 jQuery(document).off("ready"); 3505 } 3506 } 3507 }); 3508 3509 /** 3510 * Clean-up method for dom ready events 3511 */ 3512 function detach() { 3513 if (document.addEventListener) { 3514 document.removeEventListener("DOMContentLoaded", completed); 3515 window.removeEventListener("load", completed); 3516 } else { 3517 document.detachEvent("onreadystatechange", completed); 3518 window.detachEvent("onload", completed); 3519 } 3520 } 3521 3522 /** 3523 * The ready event handler and self cleanup method 3524 */ 3525 function completed() { 3526 3527 // readyState === "complete" is good enough for us to call the dom ready in oldIE 3528 if (document.addEventListener || window.event.type === "load" || document.readyState === "complete") { 3529 3530 detach(); 3531 jQuery.ready(); 3532 } 3533 } 3534 3535 jQuery.ready.promise = function (obj) { 3536 if (!readyList) { 3537 3538 readyList = jQuery.Deferred(); 3539 3540 // Catch cases where $(document).ready() is called 3541 // after the browser event has already occurred. 3542 // Support: IE6-10 3543 // Older IE sometimes signals "interactive" too soon 3544 if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) { 3545 3546 // Handle it asynchronously to allow scripts the opportunity to delay ready 3547 window.setTimeout(jQuery.ready); 3548 3549 // Standards-based browsers support DOMContentLoaded 3550 } else if (document.addEventListener) { 3551 3552 // Use the handy event callback 3553 document.addEventListener("DOMContentLoaded", completed); 3554 3555 // A fallback to window.onload, that will always work 3556 window.addEventListener("load", completed); 3557 3558 // If IE event model is used 3559 } else { 3560 3561 // Ensure firing before onload, maybe late but safe also for iframes 3562 document.attachEvent("onreadystatechange", completed); 3563 3564 // A fallback to window.onload, that will always work 3565 window.attachEvent("onload", completed); 3566 3567 // If IE and not a frame 3568 // continually check to see if the document is ready 3569 var top = false; 3570 3571 try { 3572 top = window.frameElement == null && document.documentElement; 3573 } catch (e) {} 3574 3575 if (top && top.doScroll) { 3576 (function doScrollCheck() { 3577 if (!jQuery.isReady) { 3578 3579 try { 3580 3581 // Use the trick by Diego Perini 3582 // http://javascript.nwbox.com/IEContentLoaded/ 3583 top.doScroll("left"); 3584 } catch (e) { 3585 return window.setTimeout(doScrollCheck, 50); 3586 } 3587 3588 // detach all dom ready events 3589 detach(); 3590 3591 // and execute any waiting functions 3592 jQuery.ready(); 3593 } 3594 })(); 3595 } 3596 } 3597 } 3598 return readyList.promise(obj); 3599 }; 3600 3601 // Kick off the DOM ready check even if the user does not 3602 jQuery.ready.promise(); 3603 3604 // Support: IE<9 3605 // Iteration over object's inherited properties before its own 3606 var i; 3607 for (i in jQuery(support)) { 3608 break; 3609 } 3610 support.ownFirst = i === "0"; 3611 3612 // Note: most support tests are defined in their respective modules. 3613 // false until the test is run 3614 support.inlineBlockNeedsLayout = false; 3615 3616 // Execute ASAP in case we need to set body.style.zoom 3617 jQuery(function () { 3618 3619 // Minified: var a,b,c,d 3620 var val, div, body, container; 3621 3622 body = document.getElementsByTagName("body")[0]; 3623 if (!body || !body.style) { 3624 3625 // Return for frameset docs that don't have a body 3626 return; 3627 } 3628 3629 // Setup 3630 div = document.createElement("div"); 3631 container = document.createElement("div"); 3632 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; 3633 body.appendChild(container).appendChild(div); 3634 3635 if (typeof div.style.zoom !== "undefined") { 3636 3637 // Support: IE<8 3638 // Check if natively block-level elements act like inline-block 3639 // elements when setting their display to 'inline' and giving 3640 // them layout 3641 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; 3642 3643 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; 3644 if (val) { 3645 3646 // Prevent IE 6 from affecting layout for positioned elements #11048 3647 // Prevent IE from shrinking the body in IE 7 mode #12869
vendor: 12,463 bytes, lines 3648-4159
3648 // Support: IE<8 3649 body.style.zoom = 1; 3650 } 3651 } 3652 3653 body.removeChild(container); 3654 }); 3655 3656 (function () { 3657 var div = document.createElement("div"); 3658 3659 // Support: IE<9 3660 support.deleteExpando = true; 3661 try { 3662 delete div.test; 3663 } catch (e) { 3664 support.deleteExpando = false; 3665 } 3666 3667 // Null elements to avoid leaks in IE. 3668 div = null; 3669 })(); 3670 var acceptData = function (elem) { 3671 var noData = jQuery.noData[(elem.nodeName + " ").toLowerCase()], 3672 nodeType = +elem.nodeType || 1; 3673 3674 // Do not set data on non-element DOM nodes because it will not be cleared (#8335). 3675 return nodeType !== 1 && nodeType !== 9 ? false : 3676 3677 // Nodes accept data unless otherwise specified; rejection can be conditional 3678 !noData || noData !== true && elem.getAttribute("classid") === noData; 3679 }; 3680 3681 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 3682 rmultiDash = /([A-Z])/g; 3683 3684 function dataAttr(elem, key, data) { 3685 3686 // If nothing was found internally, try to fetch any 3687 // data from the HTML5 data-* attribute 3688 if (data === undefined && elem.nodeType === 1) { 3689 3690 var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase(); 3691 3692 data = elem.getAttribute(name); 3693 3694 if (typeof data === "string") { 3695 try { 3696 data = data === "true" ? true : data === "false" ? false : data === "null" ? null : 3697 3698 // Only convert to a number if it doesn't change the string 3699 +data + "" === data ? +data : rbrace.test(data) ? jQuery.parseJSON(data) : data; 3700 } catch (e) {} 3701 3702 // Make sure we set the data so it isn't changed later 3703 jQuery.data(elem, key, data); 3704 } else { 3705 data = undefined; 3706 } 3707 } 3708 3709 return data; 3710 } 3711 3712 // checks a cache object for emptiness 3713 function isEmptyDataObject(obj) { 3714 var name; 3715 for (name in obj) { 3716 3717 // if the public data object is empty, the private is still empty 3718 if (name === "data" && jQuery.isEmptyObject(obj[name])) { 3719 continue; 3720 } 3721 if (name !== "toJSON") { 3722 return false; 3723 } 3724 } 3725 3726 return true; 3727 } 3728 3729 function internalData(elem, name, data, pvt /* Internal Use Only */) { 3730 if (!acceptData(elem)) { 3731 return; 3732 } 3733 3734 var ret, 3735 thisCache, 3736 internalKey = jQuery.expando, 3737 3738 3739 // We have to handle DOM nodes and JS objects differently because IE6-7 3740 // can't GC object references properly across the DOM-JS boundary 3741 isNode = elem.nodeType, 3742 3743 3744 // Only DOM nodes need the global jQuery cache; JS object data is 3745 // attached directly to the object so GC can occur automatically 3746 cache = isNode ? jQuery.cache : elem, 3747 3748 3749 // Only defining an ID for JS objects if its cache already exists allows 3750 // the code to shortcut on the same path as a DOM node with no cache 3751 id = isNode ? elem[internalKey] : elem[internalKey] && internalKey; 3752 3753 // Avoid doing any more work than we need to when trying to get data on an 3754 // object that has no data at all 3755 if ((!id || !cache[id] || !pvt && !cache[id].data) && data === undefined && typeof name === "string") { 3756 return; 3757 } 3758 3759 if (!id) { 3760 3761 // Only DOM nodes need a new unique ID for each element since their data 3762 // ends up in the global cache 3763 if (isNode) { 3764 id = elem[internalKey] = deletedIds.pop() || jQuery.guid++; 3765 } else { 3766 id = internalKey; 3767 } 3768 } 3769 3770 if (!cache[id]) { 3771 3772 // Avoid exposing jQuery metadata on plain JS objects when the object 3773 // is serialized using JSON.stringify 3774 cache[id] = isNode ? {} : { toJSON: jQuery.noop }; 3775 } 3776 3777 // An object can be passed to jQuery.data instead of a key/value pair; this gets 3778 // shallow copied over onto the existing cache 3779 if (typeof name === "object" || typeof name === "function") { 3780 if (pvt) { 3781 cache[id] = jQuery.extend(cache[id], name); 3782 } else { 3783 cache[id].data = jQuery.extend(cache[id].data, name); 3784 } 3785 } 3786 3787 thisCache = cache[id]; 3788 3789 // jQuery data() is stored in a separate object inside the object's internal data 3790 // cache in order to avoid key collisions between internal data and user-defined 3791 // data. 3792 if (!pvt) { 3793 if (!thisCache.data) { 3794 thisCache.data = {}; 3795 } 3796 3797 thisCache = thisCache.data; 3798 } 3799 3800 if (data !== undefined) { 3801 thisCache[jQuery.camelCase(name)] = data; 3802 } 3803 3804 // Check for both converted-to-camel and non-converted data property names 3805 // If a data property was specified 3806 if (typeof name === "string") { 3807 3808 // First Try to find as-is property data 3809 ret = thisCache[name]; 3810 3811 // Test for null|undefined property data 3812 if (ret == null) { 3813 3814 // Try to find the camelCased property 3815 ret = thisCache[jQuery.camelCase(name)]; 3816 } 3817 } else { 3818 ret = thisCache; 3819 } 3820 3821 return ret; 3822 } 3823 3824 function internalRemoveData(elem, name, pvt) { 3825 if (!acceptData(elem)) { 3826 return; 3827 } 3828 3829 var thisCache, 3830 i, 3831 isNode = elem.nodeType, 3832 3833 3834 // See jQuery.data for more information 3835 cache = isNode ? jQuery.cache : elem, 3836 id = isNode ? elem[jQuery.expando] : jQuery.expando; 3837 3838 // If there is already no cache entry for this object, there is no 3839 // purpose in continuing 3840 if (!cache[id]) { 3841 return; 3842 } 3843 3844 if (name) { 3845 3846 thisCache = pvt ? cache[id] : cache[id].data; 3847 3848 if (thisCache) { 3849 3850 // Support array or space separated string names for data keys 3851 if (!jQuery.isArray(name)) { 3852 3853 // try the string as a key before any manipulation 3854 if (name in thisCache) { 3855 name = [name]; 3856 } else { 3857 3858 // split the camel cased version by spaces unless a key with the spaces exists 3859 name = jQuery.camelCase(name); 3860 if (name in thisCache) { 3861 name = [name]; 3862 } else { 3863 name = name.split(" "); 3864 } 3865 } 3866 } else { 3867 3868 // If "name" is an array of keys... 3869 // When data is initially created, via ("key", "val") signature, 3870 // keys will be converted to camelCase. 3871 // Since there is no way to tell _how_ a key was added, remove 3872 // both plain key and camelCase key. #12786 3873 // This will only penalize the array argument path. 3874 name = name.concat(jQuery.map(name, jQuery.camelCase)); 3875 } 3876 3877 i = name.length; 3878 while (i--) { 3879 delete thisCache[name[i]]; 3880 } 3881 3882 // If there is no data left in the cache, we want to continue 3883 // and let the cache object itself get destroyed 3884 if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) { 3885 return; 3886 } 3887 } 3888 } 3889 3890 // See jQuery.data for more information 3891 if (!pvt) { 3892 delete cache[id].data; 3893 3894 // Don't destroy the parent cache unless the internal data object 3895 // had been the only thing left in it 3896 if (!isEmptyDataObject(cache[id])) { 3897 return; 3898 } 3899 } 3900 3901 // Destroy the cache 3902 if (isNode) { 3903 jQuery.cleanData([elem], true); 3904 3905 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) 3906 /* jshint eqeqeq: false */ 3907 } else if (support.deleteExpando || cache != cache.window) { 3908 /* jshint eqeqeq: true */ 3909 delete cache[id]; 3910 3911 // When all else fails, undefined 3912 } else { 3913 cache[id] = undefined; 3914 } 3915 } 3916 3917 jQuery.extend({ 3918 cache: {}, 3919 3920 // The following elements (space-suffixed to avoid Object.prototype collisions) 3921 // throw uncatchable exceptions if you attempt to set expando properties 3922 noData: { 3923 "applet ": true, 3924 "embed ": true, 3925 3926 // ...but Flash objects (which have this classid) *can* handle expandos 3927 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 3928 }, 3929 3930 hasData: function (elem) { 3931 elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando]; 3932 return !!elem && !isEmptyDataObject(elem); 3933 }, 3934 3935 data: function (elem, name, data) { 3936 return internalData(elem, name, data); 3937 }, 3938 3939 removeData: function (elem, name) { 3940 return internalRemoveData(elem, name); 3941 }, 3942 3943 // For internal use only. 3944 _data: function (elem, name, data) { 3945 return internalData(elem, name, data, true); 3946 }, 3947 3948 _removeData: function (elem, name) { 3949 return internalRemoveData(elem, name, true); 3950 } 3951 }); 3952 3953 jQuery.fn.extend({ 3954 data: function (key, value) { 3955 var i, 3956 name, 3957 data, 3958 elem = this[0], 3959 attrs = elem && elem.attributes; 3960 3961 // Special expections of .data basically thwart jQuery.access, 3962 // so implement the relevant behavior ourselves 3963 3964 // Gets all values 3965 if (key === undefined) { 3966 if (this.length) { 3967 data = jQuery.data(elem); 3968 3969 if (elem.nodeType === 1 && !jQuery._data(elem, "parsedAttrs")) { 3970 i = attrs.length; 3971 while (i--) { 3972 3973 // Support: IE11+ 3974 // The attrs elements can be null (#14894) 3975 if (attrs[i]) { 3976 name = attrs[i].name; 3977 if (name.indexOf("data-") === 0) { 3978 name = jQuery.camelCase(name.slice(5)); 3979 dataAttr(elem, name, data[name]); 3980 } 3981 } 3982 } 3983 jQuery._data(elem, "parsedAttrs", true); 3984 } 3985 } 3986 3987 return data; 3988 } 3989 3990 // Sets multiple values 3991 if (typeof key === "object") { 3992 return this.each(function () { 3993 jQuery.data(this, key); 3994 }); 3995 } 3996 3997 return arguments.length > 1 ? 3998 3999 // Sets one value 4000 this.each(function () { 4001 jQuery.data(this, key, value); 4002 }) : 4003 4004 // Gets one value 4005 // Try to fetch any internally stored data first 4006 elem ? dataAttr(elem, key, jQuery.data(elem, key)) : undefined; 4007 }, 4008 4009 removeData: function (key) { 4010 return this.each(function () { 4011 jQuery.removeData(this, key); 4012 }); 4013 } 4014 }); 4015 4016 jQuery.extend({ 4017 queue: function (elem, type, data) { 4018 var queue; 4019 4020 if (elem) { 4021 type = (type || "fx") + "queue"; 4022 queue = jQuery._data(elem, type); 4023 4024 // Speed up dequeue by getting out quickly if this is just a lookup 4025 if (data) { 4026 if (!queue || jQuery.isArray(data)) { 4027 queue = jQuery._data(elem, type, jQuery.makeArray(data)); 4028 } else { 4029 queue.push(data); 4030 } 4031 } 4032 return queue || []; 4033 } 4034 }, 4035 4036 dequeue: function (elem, type) { 4037 type = type || "fx"; 4038 4039 var queue = jQuery.queue(elem, type), 4040 startLength = queue.length, 4041 fn = queue.shift(), 4042 hooks = jQuery._queueHooks(elem, type), 4043 next = function () { 4044 jQuery.dequeue(elem, type); 4045 }; 4046 4047 // If the fx queue is dequeued, always remove the progress sentinel 4048 if (fn === "inprogress") { 4049 fn = queue.shift(); 4050 startLength--; 4051 } 4052 4053 if (fn) { 4054 4055 // Add a progress sentinel to prevent the fx queue from being 4056 // automatically dequeued 4057 if (type === "fx") { 4058 queue.unshift("inprogress"); 4059 } 4060 4061 // clear up the last queue stop function 4062 delete hooks.stop; 4063 fn.call(elem, next, hooks); 4064 } 4065 4066 if (!startLength && hooks) { 4067 hooks.empty.fire(); 4068 } 4069 }, 4070 4071 // not intended for public consumption - generates a queueHooks object, 4072 // or returns the current one 4073 _queueHooks: function (elem, type) { 4074 var key = type + "queueHooks"; 4075 return jQuery._data(elem, key) || jQuery._data(elem, key, { 4076 empty: jQuery.Callbacks("once memory").add(function () { 4077 jQuery._removeData(elem, type + "queue"); 4078 jQuery._removeData(elem, key); 4079 }) 4080 }); 4081 } 4082 }); 4083 4084 jQuery.fn.extend({ 4085 queue: function (type, data) { 4086 var setter = 2; 4087 4088 if (typeof type !== "string") { 4089 data = type; 4090 type = "fx"; 4091 setter--; 4092 } 4093 4094 if (arguments.length < setter) { 4095 return jQuery.queue(this[0], type); 4096 } 4097 4098 return data === undefined ? this : this.each(function () { 4099 var queue = jQuery.queue(this, type, data); 4100 4101 // ensure a hooks for this queue 4102 jQuery._queueHooks(this, type); 4103 4104 if (type === "fx" && queue[0] !== "inprogress") { 4105 jQuery.dequeue(this, type); 4106 } 4107 }); 4108 }, 4109 dequeue: function (type) { 4110 return this.each(function () { 4111 jQuery.dequeue(this, type); 4112 }); 4113 }, 4114 clearQueue: function (type) { 4115 return this.queue(type || "fx", []); 4116 }, 4117 4118 // Get a promise resolved when queues of a certain type 4119 // are emptied (fx is the type by default) 4120 promise: function (type, obj) { 4121 var tmp, 4122 count = 1, 4123 defer = jQuery.Deferred(), 4124 elements = this, 4125 i = this.length, 4126 resolve = function () { 4127 if (! --count) { 4128 defer.resolveWith(elements, [elements]); 4129 } 4130 }; 4131 4132 if (typeof type !== "string") { 4133 obj = type; 4134 type = undefined; 4135 } 4136 type = type || "fx"; 4137 4138 while (i--) { 4139 tmp = jQuery._data(elements[i], type + "queueHooks"); 4140 if (tmp && tmp.empty) { 4141 count++; 4142 tmp.empty.add(resolve); 4143 } 4144 } 4145 resolve(); 4146 return defer.promise(obj); 4147 } 4148 }); 4149 4150 (function () { 4151 var shrinkWrapBlocksVal; 4152 4153 support.shrinkWrapBlocks = function () { 4154 if (shrinkWrapBlocksVal != null) { 4155 return shrinkWrapBlocksVal; 4156 } 4157 4158 // Will be changed later if needed. 4159 shrinkWrapBlocksVal = false;
4160 4161 // Minified: var b,c,d 4162 var div, body, container; 4163 4164 body = document.getElementsByTagName("body")[0]; 4165 if (!body || !body.style) { 4166 4167 // Test fired too early or in an unsupported environment, exit. 4168 return; 4169 } 4170 4171 // Setup 4172 div = document.createElement("div"); 4173 container = document.createElement("div"); 4174 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; 4175 body.appendChild(container).appendChild(div); 4176 4177 // Support: IE6 4178 // Check if elements with layout shrink-wrap their children 4179 if (typeof div.style.zoom !== "undefined") { 4180 4181 // Reset CSS: box-sizing; display; margin; border 4182 div.style.cssText = 4183 4184 // Support: Firefox<29, Android 2.3 4185 // Vendor-prefix box-sizing 4186 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + "box-sizing:content-box;display:block;margin:0;border:0;" + "padding:1px;width:1px;zoom:1"; 4187 div.appendChild(document.createElement("div")).style.width = "5px"; 4188 shrinkWrapBlocksVal = div.offsetWidth !== 3; 4189 } 4190 4191 body.removeChild(container); 4192 4193 return shrinkWrapBlocksVal; 4194 }; 4195 })(); 4196 var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; 4197 4198 var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); 4199 4200 var cssExpand = ["Top", "Right", "Bottom", "Left"]; 4201 4202 var isHidden = function (elem, el) { 4203 4204 // isHidden might be called from jQuery#filter function; 4205 // in that case, element will be second argument 4206 elem = el || elem; 4207 return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem); 4208 }; 4209 4210 function adjustCSS(elem, prop, valueParts, tween) { 4211 var adjusted, 4212 scale = 1, 4213 maxIterations = 20, 4214 currentValue = tween ? function () { 4215 return tween.cur(); 4216 } : function () { 4217 return jQuery.css(elem, prop, ""); 4218 }, 4219 initial = currentValue(), 4220 unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), 4221 4222 4223 // Starting value computation is required for potential unit mismatches 4224 initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop)); 4225 4226 if (initialInUnit && initialInUnit[3] !== unit) { 4227 4228 // Trust units reported by jQuery.css 4229 unit = unit || initialInUnit[3]; 4230 4231 // Make sure we update the tween properties later on 4232 valueParts = valueParts || []; 4233 4234 // Iteratively approximate from a nonzero starting point 4235 initialInUnit = +initial || 1; 4236 4237 do { 4238 4239 // If previous iteration zeroed out, double until we get *something*. 4240 // Use string for doubling so we don't accidentally see scale as unchanged below 4241 scale = scale || ".5"; 4242 4243 // Adjust and apply 4244 initialInUnit = initialInUnit / scale; 4245 jQuery.style(elem, prop, initialInUnit + unit); 4246 4247 // Update scale, tolerating zero or NaN from tween.cur() 4248 // Break the loop if scale is unchanged or perfect, or if we've just had enough. 4249 } while (scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations); 4250 } 4251 4252 if (valueParts) { 4253 initialInUnit = +initialInUnit || +initial || 0; 4254 4255 // Apply relative offset (+=/-=) if specified 4256 adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; 4257 if (tween) { 4258 tween.unit = unit; 4259 tween.start = initialInUnit; 4260 tween.end = adjusted; 4261 } 4262 } 4263 return adjusted; 4264 } 4265 4266 // Multifunctional method to get and set values of a collection 4267 // The value/s can optionally be executed if it's a function 4268 var access = function (elems, fn, key, value, chainable, emptyGet, raw) { 4269 var i = 0, 4270 length = elems.length, 4271 bulk = key == null; 4272 4273 // Sets many values 4274 if (jQuery.type(key) === "object") { 4275 chainable = true; 4276 for (i in key) { 4277 access(elems, fn, i, key[i], true, emptyGet, raw); 4278 } 4279 4280 // Sets one value 4281 } else if (value !== undefined) { 4282 chainable = true; 4283 4284 if (!jQuery.isFunction(value)) { 4285 raw = true; 4286 } 4287 4288 if (bulk) { 4289 4290 // Bulk operations run against the entire set 4291 if (raw) { 4292 fn.call(elems, value); 4293 fn = null; 4294 4295 // ...except when executing function values 4296 } else { 4297 bulk = fn; 4298 fn = function (elem, key, value) {
4299 return bulk.call(jQuery(elem), value); 4300 }; 4301 } 4302 } 4303 4304 if (fn) { 4305 for (; i < length; i++) { 4306 fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); 4307 } 4308 } 4309 } 4310 4311 return chainable ? elems : 4312 4313 // Gets 4314 bulk ? fn.call(elems) : length ? fn(elems[0], key) : emptyGet; 4315 }; 4316 var rcheckableType = /^(?:checkbox|radio)$/i; 4317 4318 var rtagName = /<([\w:-]+)/; 4319 4320 var rscriptType = /^$|\/(?:java|ecma)script/i; 4321 4322 var rleadingWhitespace = /^\s+/; 4323 4324 var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + "details|dialog|figcaption|figure|footer|header|hgroup|main|" + "mark|meter|nav|output|picture|progress|section|summary|template|time|video"; 4325 4326 function createSafeFragment(document) { 4327 var list = nodeNames.split("|"), 4328 safeFrag = document.createDocumentFragment(); 4329 4330 if (safeFrag.createElement) { 4331 while (list.length) { 4332 safeFrag.createElement(list.pop()); 4333 } 4334 } 4335 return safeFrag; 4336 } 4337 4338 (function () { 4339 var div = document.createElement("div"), 4340 fragment = document.createDocumentFragment(), 4341 input = document.createElement("input"); 4342 4343 // Setup 4344 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; 4345 4346 // IE strips leading whitespace when .innerHTML is used 4347 support.leadingWhitespace = div.firstChild.nodeType === 3; 4348 4349 // Make sure that tbody elements aren't automatically inserted 4350 // IE will insert them into empty tables 4351 support.tbody = !div.getElementsByTagName("tbody").length; 4352 4353 // Make sure that link elements get serialized correctly by innerHTML 4354 // This requires a wrapper element in IE 4355 support.htmlSerialize = !!div.getElementsByTagName("link").length; 4356 4357 // Makes sure cloning an html5 element does not cause problems 4358 // Where outerHTML is undefined, this still works 4359 support.html5Clone = document.createElement("nav").cloneNode(true).outerHTML !== "<:nav></:nav>"; 4360 4361 // Check if a disconnected checkbox will retain its checked 4362 // value of true after appended to the DOM (IE6/7) 4363 input.type = "checkbox"; 4364 input.checked = true; 4365 fragment.appendChild(input); 4366 support.appendChecked = input.checked; 4367 4368 // Make sure textarea (and checkbox) defaultValue is properly cloned 4369 // Support: IE6-IE11+ 4370 div.innerHTML = "<textarea>x</textarea>"; 4371 support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; 4372 4373 // #11217 - WebKit loses check when the name is after the checked attribute 4374 fragment.appendChild(div); 4375 4376 // Support: Windows Web Apps (WWA) 4377 // `name` and `type` must use .setAttribute for WWA (#14901) 4378 input = document.createElement("input"); 4379 input.setAttribute("type", "radio"); 4380 input.setAttribute("checked", "checked"); 4381 input.setAttribute("name", "t"); 4382 4383 div.appendChild(input); 4384 4385 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 4386 // old WebKit doesn't clone checked state correctly in fragments 4387 support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; 4388 4389 // Support: IE<9 4390 // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ 4391 support.noCloneEvent = !!div.addEventListener; 4392 4393 // Support: IE<9 4394 // Since attributes and properties are the same in IE, 4395 // cleanData must set properties to undefined rather than use removeAttribute 4396 div[jQuery.expando] = 1; 4397 support.attributes = !div.getAttribute(jQuery.expando); 4398 })(); 4399 4400 // We have to close these tags to support XHTML (#13200) 4401 var wrapMap = { 4402 option: [1, "<select multiple='multiple'>", "</select>"], 4403 legend: [1, "<fieldset>", "</fieldset>"], 4404 area: [1, "<map>", "</map>"], 4405 4406 // Support: IE8 4407 param: [1, "<object>", "</object>"], 4408 thead: [1, "<table>", "</table>"], 4409 tr: [2, "<table><tbody>", "</tbody></table>"], 4410 col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"], 4411 td: [3, "<table><tbody><tr>", "</tr></tbody></table>"], 4412 4413 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, 4414 // unless wrapped in a div with non-breaking characters in front of it. 4415 _default: support.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"] 4416 }; 4417 4418 // Support: IE8-IE9 4419 wrapMap.optgroup = wrapMap.option; 4420 4421 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 4422 wrapMap.th = wrapMap.td; 4423 4424 function getAll(context, tag) { 4425 var elems, 4426 elem, 4427 i = 0, 4428 found = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName(tag || "*") : typeof context.querySelectorAll !== "undefined" ? context.querySelectorAll(tag || "*") : undefined; 4429 4430 if (!found) { 4431 for (found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++) { 4432 if (!tag || jQuery.nodeName(elem, tag)) { 4433 found.push(elem); 4434 } else { 4435 jQuery.merge(found, getAll(elem, tag)); 4436 } 4437 } 4438 } 4439 4440 return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery.merge([context], found) : found; 4441 } 4442 4443 // Mark scripts as having already been evaluated 4444 function setGlobalEval(elems, refElements) { 4445 var elem, 4446 i = 0; 4447 for (; (elem = elems[i]) != null; i++) { 4448 jQuery._data(elem, "globalEval", !refElements || jQuery._data(refElements[i], "globalEval")); 4449 } 4450 } 4451
4452 var rhtml = /<|&#?\w+;/, 4453 rtbody = /<tbody/i; 4454 4455 function fixDefaultChecked(elem) { 4456 if (rcheckableType.test(elem.type)) { 4457 elem.defaultChecked = elem.checked; 4458 } 4459 } 4460 4461 function buildFragment(elems, context, scripts, selection, ignored) { 4462 var j, 4463 elem, 4464 contains, 4465 tmp, 4466 tag, 4467 tbody, 4468 wrap, 4469 l = elems.length, 4470 4471 4472 // Ensure a safe fragment 4473 safe = createSafeFragment(context), 4474 nodes = [], 4475 i = 0; 4476 4477 for (; i < l; i++) { 4478 elem = elems[i]; 4479 4480 if (elem || elem === 0) { 4481 4482 // Add nodes directly 4483 if (jQuery.type(elem) === "object") { 4484 jQuery.merge(nodes, elem.nodeType ? [elem] : elem); 4485 4486 // Convert non-html into a text node 4487 } else if (!rhtml.test(elem)) { 4488 nodes.push(context.createTextNode(elem)); 4489 4490 // Convert html into DOM nodes 4491 } else { 4492 tmp = tmp || safe.appendChild(context.createElement("div")); 4493 4494 // Deserialize a standard representation 4495 tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); 4496 wrap = wrapMap[tag] || wrapMap._default; 4497 4498 tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; 4499 4500 // Descend through wrappers to the right content 4501 j = wrap[0]; 4502 while (j--) { 4503 tmp = tmp.lastChild; 4504 } 4505 4506 // Manually add leading whitespace removed by IE 4507 if (!support.leadingWhitespace && rleadingWhitespace.test(elem)) { 4508 nodes.push(context.createTextNode(rleadingWhitespace.exec(elem)[0])); 4509 } 4510 4511 // Remove IE's autoinserted <tbody> from table fragments 4512 if (!support.tbody) { 4513 4514 // String was a <table>, *may* have spurious <tbody> 4515 elem = tag === "table" && !rtbody.test(elem) ? tmp.firstChild : 4516 4517 // String was a bare <thead> or <tfoot> 4518 wrap[1] === "<table>" && !rtbody.test(elem) ? tmp : 0; 4519 4520 j = elem && elem.childNodes.length; 4521 while (j--) { 4522 if (jQuery.nodeName(tbody = elem.childNodes[j], "tbody") && !tbody.childNodes.length) { 4523 4524 elem.removeChild(tbody); 4525 } 4526 } 4527 } 4528 4529 jQuery.merge(nodes, tmp.childNodes); 4530 4531 // Fix #12392 for WebKit and IE > 9 4532 tmp.textContent = ""; 4533 4534 // Fix #12392 for oldIE 4535 while (tmp.firstChild) { 4536 tmp.removeChild(tmp.firstChild); 4537 } 4538 4539 // Remember the top-level container for proper cleanup 4540 tmp = safe.lastChild; 4541 } 4542 } 4543 } 4544 4545 // Fix #11356: Clear elements from fragment 4546 if (tmp) { 4547 safe.removeChild(tmp); 4548 } 4549 4550 // Reset defaultChecked for any radios and checkboxes 4551 // about to be appended to the DOM in IE 6/7 (#8060) 4552 if (!support.appendChecked) { 4553 jQuery.grep(getAll(nodes, "input"), fixDefaultChecked); 4554 } 4555 4556 i = 0; 4557 while (elem = nodes[i++]) { 4558 4559 // Skip elements already in the context collection (trac-4087) 4560 if (selection && jQuery.inArray(elem, selection) > -1) { 4561 if (ignored) { 4562 ignored.push(elem); 4563 } 4564 4565 continue; 4566 } 4567 4568 contains = jQuery.contains(elem.ownerDocument, elem); 4569 4570 // Append to fragment 4571 tmp = getAll(safe.appendChild(elem), "script"); 4572 4573 // Preserve script evaluation history 4574 if (contains) { 4575 setGlobalEval(tmp); 4576 } 4577 4578 // Capture executables 4579 if (scripts) { 4580 j = 0; 4581 while (elem = tmp[j++]) { 4582 if (rscriptType.test(elem.type || "")) { 4583 scripts.push(elem); 4584 } 4585 } 4586 } 4587 } 4588 4589 tmp = null; 4590 4591 return safe; 4592 } 4593 4594 (function () { 4595 var i, 4596 eventName, 4597 div = document.createElement("div"); 4598 4599 // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events) 4600 for (i in { submit: true, change: true, focusin: true }) { 4601 eventName = "on" + i; 4602
vendor: 28,100 bytes, lines 4603-5571
4603 if (!(support[i] = eventName in window)) { 4604 4605 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) 4606 div.setAttribute(eventName, "t"); 4607 support[i] = div.attributes[eventName].expando === false; 4608 } 4609 } 4610 4611 // Null elements to avoid leaks in IE. 4612 div = null; 4613 })(); 4614 4615 var rformElems = /^(?:input|select|textarea)$/i, 4616 rkeyEvent = /^key/, 4617 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 4618 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 4619 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 4620 4621 function returnTrue() { 4622 return true; 4623 } 4624 4625 function returnFalse() { 4626 return false; 4627 } 4628 4629 // Support: IE9 4630 // See #13393 for more info 4631 function safeActiveElement() { 4632 try { 4633 return document.activeElement; 4634 } catch (err) {} 4635 } 4636 4637 function on(elem, types, selector, data, fn, one) { 4638 var origFn, type; 4639 4640 // Types can be a map of types/handlers 4641 if (typeof types === "object") { 4642 4643 // ( types-Object, selector, data ) 4644 if (typeof selector !== "string") { 4645 4646 // ( types-Object, data ) 4647 data = data || selector; 4648 selector = undefined; 4649 } 4650 for (type in types) { 4651 on(elem, type, selector, data, types[type], one); 4652 } 4653 return elem; 4654 } 4655 4656 if (data == null && fn == null) { 4657 4658 // ( types, fn ) 4659 fn = selector; 4660 data = selector = undefined; 4661 } else if (fn == null) { 4662 if (typeof selector === "string") { 4663 4664 // ( types, selector, fn ) 4665 fn = data; 4666 data = undefined; 4667 } else { 4668 4669 // ( types, data, fn ) 4670 fn = data; 4671 data = selector; 4672 selector = undefined; 4673 } 4674 } 4675 if (fn === false) { 4676 fn = returnFalse; 4677 } else if (!fn) { 4678 return elem; 4679 } 4680 4681 if (one === 1) { 4682 origFn = fn; 4683 fn = function (event) { 4684 4685 // Can use an empty set, since event contains the info 4686 jQuery().off(event); 4687 return origFn.apply(this, arguments); 4688 }; 4689 4690 // Use same guid so caller can remove using origFn 4691 fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); 4692 } 4693 return elem.each(function () { 4694 jQuery.event.add(this, types, fn, data, selector); 4695 }); 4696 } 4697 4698 /* 4699 * Helper functions for managing events -- not part of the public interface. 4700 * Props to Dean Edwards' addEvent library for many of the ideas. 4701 */ 4702 jQuery.event = { 4703 4704 global: {}, 4705 4706 add: function (elem, types, handler, data, selector) { 4707 var tmp, 4708 events, 4709 t, 4710 handleObjIn, 4711 special, 4712 eventHandle, 4713 handleObj, 4714 handlers, 4715 type, 4716 namespaces, 4717 origType, 4718 elemData = jQuery._data(elem); 4719 4720 // Don't attach events to noData or text/comment nodes (but allow plain objects) 4721 if (!elemData) { 4722 return; 4723 } 4724 4725 // Caller can pass in an object of custom data in lieu of the handler 4726 if (handler.handler) { 4727 handleObjIn = handler; 4728 handler = handleObjIn.handler; 4729 selector = handleObjIn.selector; 4730 } 4731 4732 // Make sure that the handler has a unique ID, used to find/remove it later 4733 if (!handler.guid) { 4734 handler.guid = jQuery.guid++; 4735 } 4736 4737 // Init the element's event structure and main handler, if this is the first 4738 if (!(events = elemData.events)) { 4739 events = elemData.events = {}; 4740 } 4741 if (!(eventHandle = elemData.handle)) { 4742 eventHandle = elemData.handle = function (e) { 4743 4744 // Discard the second event of a jQuery.event.trigger() and 4745 // when an event is called after a page has unloaded 4746 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined; 4747 }; 4748 4749 // Add elem as a property of the handle fn to prevent a memory leak 4750 // with IE non-native events 4751 eventHandle.elem = elem; 4752 } 4753 4754 // Handle multiple events separated by a space 4755 types = (types || "").match(rnotwhite) || [""]; 4756 t = types.length; 4757 while (t--) { 4758 tmp = rtypenamespace.exec(types[t]) || []; 4759 type = origType = tmp[1]; 4760 namespaces = (tmp[2] || "").split(".").sort(); 4761 4762 // There *must* be a type, no attaching namespace-only handlers 4763 if (!type) { 4764 continue; 4765 } 4766 4767 // If event changes its type, use the special event handlers for the changed type 4768 special = jQuery.event.special[type] || {}; 4769 4770 // If selector defined, determine special event api type, otherwise given type 4771 type = (selector ? special.delegateType : special.bindType) || type; 4772 4773 // Update special based on newly reset type 4774 special = jQuery.event.special[type] || {}; 4775 4776 // handleObj is passed to all event handlers 4777 handleObj = jQuery.extend({ 4778 type: type, 4779 origType: origType, 4780 data: data, 4781 handler: handler, 4782 guid: handler.guid, 4783 selector: selector, 4784 needsContext: selector && jQuery.expr.match.needsContext.test(selector), 4785 namespace: namespaces.join(".") 4786 }, handleObjIn); 4787 4788 // Init the event handler queue if we're the first 4789 if (!(handlers = events[type])) { 4790 handlers = events[type] = []; 4791 handlers.delegateCount = 0; 4792 4793 // Only use addEventListener/attachEvent if the special events handler returns false 4794 if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { 4795 4796 // Bind the global event handler to the element 4797 if (elem.addEventListener) { 4798 elem.addEventListener(type, eventHandle, false); 4799 } else if (elem.attachEvent) { 4800 elem.attachEvent("on" + type, eventHandle); 4801 } 4802 } 4803 } 4804 4805 if (special.add) { 4806 special.add.call(elem, handleObj); 4807 4808 if (!handleObj.handler.guid) { 4809 handleObj.handler.guid = handler.guid; 4810 } 4811 } 4812 4813 // Add to the element's handler list, delegates in front 4814 if (selector) { 4815 handlers.splice(handlers.delegateCount++, 0, handleObj); 4816 } else { 4817 handlers.push(handleObj); 4818 } 4819 4820 // Keep track of which events have ever been used, for event optimization 4821 jQuery.event.global[type] = true; 4822 } 4823 4824 // Nullify elem to prevent memory leaks in IE 4825 elem = null; 4826 }, 4827 4828 // Detach an event or set of events from an element 4829 remove: function (elem, types, handler, selector, mappedTypes) { 4830 var j, 4831 handleObj, 4832 tmp, 4833 origCount, 4834 t, 4835 events, 4836 special, 4837 handlers, 4838 type, 4839 namespaces, 4840 origType, 4841 elemData = jQuery.hasData(elem) && jQuery._data(elem); 4842 4843 if (!elemData || !(events = elemData.events)) { 4844 return; 4845 } 4846 4847 // Once for each type.namespace in types; type may be omitted 4848 types = (types || "").match(rnotwhite) || [""]; 4849 t = types.length; 4850 while (t--) { 4851 tmp = rtypenamespace.exec(types[t]) || []; 4852 type = origType = tmp[1]; 4853 namespaces = (tmp[2] || "").split(".").sort(); 4854 4855 // Unbind all events (on this namespace, if provided) for the element 4856 if (!type) { 4857 for (type in events) { 4858 jQuery.event.remove(elem, type + types[t], handler, selector, true); 4859 } 4860 continue; 4861 } 4862 4863 special = jQuery.event.special[type] || {}; 4864 type = (selector ? special.delegateType : special.bindType) || type; 4865 handlers = events[type] || []; 4866 tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); 4867 4868 // Remove matching events 4869 origCount = j = handlers.length; 4870 while (j--) { 4871 handleObj = handlers[j]; 4872 4873 if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) { 4874 handlers.splice(j, 1); 4875 4876 if (handleObj.selector) { 4877 handlers.delegateCount--; 4878 } 4879 if (special.remove) { 4880 special.remove.call(elem, handleObj); 4881 } 4882 } 4883 } 4884 4885 // Remove generic event handler if we removed something and no more handlers exist 4886 // (avoids potential for endless recursion during removal of special event handlers) 4887 if (origCount && !handlers.length) { 4888 if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { 4889 4890 jQuery.removeEvent(elem, type, elemData.handle); 4891 } 4892 4893 delete events[type]; 4894 } 4895 } 4896 4897 // Remove the expando if it's no longer used 4898 if (jQuery.isEmptyObject(events)) { 4899 delete elemData.handle; 4900 4901 // removeData also checks for emptiness and clears the expando if empty 4902 // so use it instead of delete 4903 jQuery._removeData(elem, "events"); 4904 } 4905 }, 4906 4907 trigger: function (event, data, elem, onlyHandlers) { 4908 var handle, 4909 ontype, 4910 cur, 4911 bubbleType, 4912 special, 4913 tmp, 4914 i, 4915 eventPath = [elem || document], 4916 type = hasOwn.call(event, "type") ? event.type : event, 4917 namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; 4918 4919 cur = tmp = elem = elem || document; 4920 4921 // Don't do events on text and comment nodes 4922 if (elem.nodeType === 3 || elem.nodeType === 8) { 4923 return; 4924 } 4925 4926 // focus/blur morphs to focusin/out; ensure we're not firing them right now 4927 if (rfocusMorph.test(type + jQuery.event.triggered)) { 4928 return; 4929 } 4930 4931 if (type.indexOf(".") > -1) { 4932 4933 // Namespaced trigger; create a regexp to match event type in handle() 4934 namespaces = type.split("."); 4935 type = namespaces.shift(); 4936 namespaces.sort(); 4937 } 4938 ontype = type.indexOf(":") < 0 && "on" + type; 4939 4940 // Caller can pass in a jQuery.Event object, Object, or just an event type string 4941 event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event); 4942 4943 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 4944 event.isTrigger = onlyHandlers ? 2 : 3; 4945 event.namespace = namespaces.join("."); 4946 event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; 4947 4948 // Clean up the event in case it is being reused 4949 event.result = undefined; 4950 if (!event.target) { 4951 event.target = elem; 4952 } 4953 4954 // Clone any incoming data and prepend the event, creating the handler arg list 4955 data = data == null ? [event] : jQuery.makeArray(data, [event]); 4956 4957 // Allow special events to draw outside the lines 4958 special = jQuery.event.special[type] || {}; 4959 if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { 4960 return; 4961 } 4962 4963 // Determine event propagation path in advance, per W3C events spec (#9951) 4964 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 4965 if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) { 4966 4967 bubbleType = special.delegateType || type; 4968 if (!rfocusMorph.test(bubbleType + type)) { 4969 cur = cur.parentNode; 4970 } 4971 for (; cur; cur = cur.parentNode) { 4972 eventPath.push(cur); 4973 tmp = cur; 4974 } 4975 4976 // Only add window if we got to document (e.g., not plain obj or detached DOM) 4977 if (tmp === (elem.ownerDocument || document)) { 4978 eventPath.push(tmp.defaultView || tmp.parentWindow || window); 4979 } 4980 } 4981 4982 // Fire handlers on the event path 4983 i = 0; 4984 while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { 4985 4986 event.type = i > 1 ? bubbleType : special.bindType || type; 4987 4988 // jQuery handler 4989 handle = (jQuery._data(cur, "events") || {})[event.type] && jQuery._data(cur, "handle"); 4990 4991 if (handle) { 4992 handle.apply(cur, data); 4993 } 4994 4995 // Native handler 4996 handle = ontype && cur[ontype]; 4997 if (handle && handle.apply && acceptData(cur)) { 4998 event.result = handle.apply(cur, data); 4999 if (event.result === false) { 5000 event.preventDefault(); 5001 } 5002 } 5003 } 5004 event.type = type; 5005 5006 // If nobody prevented the default action, do it now 5007 if (!onlyHandlers && !event.isDefaultPrevented()) { 5008 5009 if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { 5010 5011 // Call a native DOM method on the target with the same name name as the event. 5012 // Can't use an .isFunction() check here because IE6/7 fails that test. 5013 // Don't do default actions on window, that's where global variables be (#6170) 5014 if (ontype && elem[type] && !jQuery.isWindow(elem)) { 5015 5016 // Don't re-trigger an onFOO event when we call its FOO() method 5017 tmp = elem[ontype]; 5018 5019 if (tmp) { 5020 elem[ontype] = null; 5021 } 5022 5023 // Prevent re-triggering of the same event, since we already bubbled it above 5024 jQuery.event.triggered = type; 5025 try { 5026 elem[type](); 5027 } catch (e) { 5028 5029 // IE<9 dies on focus/blur to hidden element (#1486,#12518) 5030 // only reproducible on winXP IE8 native, not IE9 in IE8 mode 5031 } 5032 jQuery.event.triggered = undefined; 5033 5034 if (tmp) { 5035 elem[ontype] = tmp; 5036 } 5037 } 5038 } 5039 } 5040 5041 return event.result; 5042 }, 5043 5044 dispatch: function (event) { 5045 5046 // Make a writable jQuery.Event from the native event object 5047 event = jQuery.event.fix(event); 5048 5049 var i, 5050 j, 5051 ret, 5052 matched, 5053 handleObj, 5054 handlerQueue = [], 5055 args = slice.call(arguments), 5056 handlers = (jQuery._data(this, "events") || {})[event.type] || [], 5057 special = jQuery.event.special[event.type] || {}; 5058 5059 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5060 args[0] = event; 5061 event.delegateTarget = this; 5062 5063 // Call the preDispatch hook for the mapped type, and let it bail if desired 5064 if (special.preDispatch && special.preDispatch.call(this, event) === false) { 5065 return; 5066 } 5067 5068 // Determine handlers 5069 handlerQueue = jQuery.event.handlers.call(this, event, handlers); 5070 5071 // Run delegates first; they may want to stop propagation beneath us 5072 i = 0; 5073 while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { 5074 event.currentTarget = matched.elem; 5075 5076 j = 0; 5077 while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { 5078 5079 // Triggered event must either 1) have no namespace, or 2) have namespace(s) 5080 // a subset or equal to those in the bound event (both can have no namespace). 5081 if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { 5082 5083 event.handleObj = handleObj; 5084 event.data = handleObj.data; 5085 5086 ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); 5087 5088 if (ret !== undefined) { 5089 if ((event.result = ret) === false) { 5090 event.preventDefault(); 5091 event.stopPropagation(); 5092 } 5093 } 5094 } 5095 } 5096 } 5097 5098 // Call the postDispatch hook for the mapped type 5099 if (special.postDispatch) { 5100 special.postDispatch.call(this, event); 5101 } 5102 5103 return event.result; 5104 }, 5105 5106 handlers: function (event, handlers) { 5107 var i, 5108 matches, 5109 sel, 5110 handleObj, 5111 handlerQueue = [], 5112 delegateCount = handlers.delegateCount, 5113 cur = event.target; 5114 5115 // Support (at least): Chrome, IE9 5116 // Find delegate handlers 5117 // Black-hole SVG <use> instance trees (#13180) 5118 // 5119 // Support: Firefox<=42+ 5120 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343) 5121 if (delegateCount && cur.nodeType && (event.type !== "click" || isNaN(event.button) || event.button < 1)) { 5122 5123 /* jshint eqeqeq: false */ 5124 for (; cur != this; cur = cur.parentNode || this) { 5125 /* jshint eqeqeq: true */ 5126 5127 // Don't check non-elements (#13208) 5128 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 5129 if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) { 5130 matches = []; 5131 for (i = 0; i < delegateCount; i++) { 5132 handleObj = handlers[i]; 5133 5134 // Don't conflict with Object.prototype properties (#13203) 5135 sel = handleObj.selector + " "; 5136 5137 if (matches[sel] === undefined) { 5138 matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; 5139 } 5140 if (matches[sel]) { 5141 matches.push(handleObj); 5142 } 5143 } 5144 if (matches.length) { 5145 handlerQueue.push({ elem: cur, handlers: matches }); 5146 } 5147 } 5148 } 5149 } 5150 5151 // Add the remaining (directly-bound) handlers 5152 if (delegateCount < handlers.length) { 5153 handlerQueue.push({ elem: this, handlers: handlers.slice(delegateCount) }); 5154 } 5155 5156 return handlerQueue; 5157 }, 5158 5159 fix: function (event) { 5160 if (event[jQuery.expando]) { 5161 return event; 5162 } 5163 5164 // Create a writable copy of the event object and normalize some properties 5165 var i, 5166 prop, 5167 copy, 5168 type = event.type, 5169 originalEvent = event, 5170 fixHook = this.fixHooks[type]; 5171 5172 if (!fixHook) { 5173 this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks : {}; 5174 } 5175 copy = fixHook.props ? this.props.concat(fixHook.props) : this.props; 5176 5177 event = new jQuery.Event(originalEvent); 5178 5179 i = copy.length; 5180 while (i--) { 5181 prop = copy[i]; 5182 event[prop] = originalEvent[prop]; 5183 } 5184 5185 // Support: IE<9 5186 // Fix target property (#1925) 5187 if (!event.target) { 5188 event.target = originalEvent.srcElement || document; 5189 } 5190 5191 // Support: Safari 6-8+ 5192 // Target should not be a text node (#504, #13143) 5193 if (event.target.nodeType === 3) { 5194 event.target = event.target.parentNode; 5195 } 5196 5197 // Support: IE<9 5198 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) 5199 event.metaKey = !!event.metaKey; 5200 5201 return fixHook.filter ? fixHook.filter(event, originalEvent) : event; 5202 }, 5203 5204 // Includes some event props shared by KeyEvent and MouseEvent 5205 props: ("altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + "metaKey relatedTarget shiftKey target timeStamp view which").split(" "), 5206 5207 fixHooks: {}, 5208 5209 keyHooks: { 5210 props: "char charCode key keyCode".split(" "), 5211 filter: function (event, original) { 5212 5213 // Add which for key events 5214 if (event.which == null) { 5215 event.which = original.charCode != null ? original.charCode : original.keyCode; 5216 } 5217 5218 return event; 5219 } 5220 }, 5221 5222 mouseHooks: { 5223 props: ("button buttons clientX clientY fromElement offsetX offsetY " + "pageX pageY screenX screenY toElement").split(" "), 5224 filter: function (event, original) { 5225 var body, 5226 eventDoc, 5227 doc, 5228 button = original.button, 5229 fromElement = original.fromElement; 5230 5231 // Calculate pageX/Y if missing and clientX/Y available 5232 if (event.pageX == null && original.clientX != null) { 5233 eventDoc = event.target.ownerDocument || document; 5234 doc = eventDoc.documentElement; 5235 body = eventDoc.body; 5236 5237 event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); 5238 event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); 5239 } 5240 5241 // Add relatedTarget, if necessary 5242 if (!event.relatedTarget && fromElement) { 5243 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; 5244 } 5245 5246 // Add which for click: 1 === left; 2 === middle; 3 === right 5247 // Note: button is not normalized, so don't use it 5248 if (!event.which && button !== undefined) { 5249 event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0; 5250 } 5251 5252 return event; 5253 } 5254 }, 5255 5256 special: { 5257 load: { 5258 5259 // Prevent triggered image.load events from bubbling to window.load 5260 noBubble: true 5261 }, 5262 focus: { 5263 5264 // Fire native event if possible so blur/focus sequence is correct 5265 trigger: function () { 5266 if (this !== safeActiveElement() && this.focus) { 5267 try { 5268 this.focus(); 5269 return false; 5270 } catch (e) { 5271 5272 // Support: IE<9 5273 // If we error on focus to hidden element (#1486, #12518), 5274 // let .trigger() run the handlers 5275 } 5276 } 5277 }, 5278 delegateType: "focusin" 5279 }, 5280 blur: { 5281 trigger: function () { 5282 if (this === safeActiveElement() && this.blur) { 5283 this.blur(); 5284 return false; 5285 } 5286 }, 5287 delegateType: "focusout" 5288 }, 5289 click: { 5290 5291 // For checkbox, fire native event so checked state will be right 5292 trigger: function () { 5293 if (jQuery.nodeName(this, "input") && this.type === "checkbox" && this.click) { 5294 this.click(); 5295 return false; 5296 } 5297 }, 5298 5299 // For cross-browser consistency, don't fire native .click() on links 5300 _default: function (event) { 5301 return jQuery.nodeName(event.target, "a"); 5302 } 5303 }, 5304 5305 beforeunload: { 5306 postDispatch: function (event) { 5307 5308 // Support: Firefox 20+ 5309 // Firefox doesn't alert if the returnValue field is not set. 5310 if (event.result !== undefined && event.originalEvent) { 5311 event.originalEvent.returnValue = event.result; 5312 } 5313 } 5314 } 5315 }, 5316 5317 // Piggyback on a donor event to simulate a different one 5318 simulate: function (type, elem, event) { 5319 var e = jQuery.extend(new jQuery.Event(), event, { 5320 type: type, 5321 isSimulated: true 5322 5323 // Previously, `originalEvent: {}` was set here, so stopPropagation call 5324 // would not be triggered on donor event, since in our own 5325 // jQuery.event.stopPropagation function we had a check for existence of 5326 // originalEvent.stopPropagation method, so, consequently it would be a noop. 5327 // 5328 // Guard for simulated events was moved to jQuery.event.stopPropagation function 5329 // since `originalEvent` should point to the original event for the 5330 // constancy with other events and for more focused logic 5331 }); 5332 5333 jQuery.event.trigger(e, null, elem); 5334 5335 if (e.isDefaultPrevented()) { 5336 event.preventDefault(); 5337 } 5338 } 5339 }; 5340 5341 jQuery.removeEvent = document.removeEventListener ? function (elem, type, handle) { 5342 5343 // This "if" is needed for plain objects 5344 if (elem.removeEventListener) { 5345 elem.removeEventListener(type, handle); 5346 } 5347 } : function (elem, type, handle) { 5348 var name = "on" + type; 5349 5350 if (elem.detachEvent) { 5351 5352 // #8545, #7054, preventing memory leaks for custom events in IE6-8 5353 // detachEvent needed property on element, by name of that event, 5354 // to properly expose it to GC 5355 if (typeof elem[name] === "undefined") { 5356 elem[name] = null; 5357 } 5358 5359 elem.detachEvent(name, handle); 5360 } 5361 }; 5362 5363 jQuery.Event = function (src, props) { 5364 5365 // Allow instantiation without the 'new' keyword 5366 if (!(this instanceof jQuery.Event)) { 5367 return new jQuery.Event(src, props); 5368 } 5369 5370 // Event object 5371 if (src && src.type) { 5372 this.originalEvent = src; 5373 this.type = src.type; 5374 5375 // Events bubbling up the document may have been marked as prevented 5376 // by a handler lower down the tree; reflect the correct value. 5377 this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && 5378 5379 // Support: IE < 9, Android < 4.0 5380 src.returnValue === false ? returnTrue : returnFalse; 5381 5382 // Event type 5383 } else { 5384 this.type = src; 5385 } 5386 5387 // Put explicitly provided properties onto the event object 5388 if (props) { 5389 jQuery.extend(this, props); 5390 } 5391 5392 // Create a timestamp if incoming event doesn't have one 5393 this.timeStamp = src && src.timeStamp || jQuery.now(); 5394 5395 // Mark it as fixed 5396 this[jQuery.expando] = true; 5397 }; 5398 5399 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 5400 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 5401 jQuery.Event.prototype = { 5402 constructor: jQuery.Event, 5403 isDefaultPrevented: returnFalse, 5404 isPropagationStopped: returnFalse, 5405 isImmediatePropagationStopped: returnFalse, 5406 5407 preventDefault: function () { 5408 var e = this.originalEvent; 5409 5410 this.isDefaultPrevented = returnTrue; 5411 if (!e) { 5412 return; 5413 } 5414 5415 // If preventDefault exists, run it on the original event 5416 if (e.preventDefault) { 5417 e.preventDefault(); 5418 5419 // Support: IE 5420 // Otherwise set the returnValue property of the original event to false 5421 } else { 5422 e.returnValue = false; 5423 } 5424 }, 5425 stopPropagation: function () { 5426 var e = this.originalEvent; 5427 5428 this.isPropagationStopped = returnTrue; 5429 5430 if (!e || this.isSimulated) { 5431 return; 5432 } 5433 5434 // If stopPropagation exists, run it on the original event 5435 if (e.stopPropagation) { 5436 e.stopPropagation(); 5437 } 5438 5439 // Support: IE 5440 // Set the cancelBubble property of the original event to true 5441 e.cancelBubble = true; 5442 }, 5443 stopImmediatePropagation: function () { 5444 var e = this.originalEvent; 5445 5446 this.isImmediatePropagationStopped = returnTrue; 5447 5448 if (e && e.stopImmediatePropagation) { 5449 e.stopImmediatePropagation(); 5450 } 5451 5452 this.stopPropagation(); 5453 } 5454 }; 5455 5456 // Create mouseenter/leave events using mouseover/out and event-time checks 5457 // so that event delegation works in jQuery. 5458 // Do the same for pointerenter/pointerleave and pointerover/pointerout 5459 // 5460 // Support: Safari 7 only 5461 // Safari sends mouseenter too often; see: 5462 // https://code.google.com/p/chromium/issues/detail?id=470258 5463 // for the description of the bug (it existed in older Chrome versions as well). 5464 jQuery.each({ 5465 mouseenter: "mouseover", 5466 mouseleave: "mouseout", 5467 pointerenter: "pointerover", 5468 pointerleave: "pointerout" 5469 }, function (orig, fix) { 5470 jQuery.event.special[orig] = { 5471 delegateType: fix, 5472 bindType: fix, 5473 5474 handle: function (event) { 5475 var ret, 5476 target = this, 5477 related = event.relatedTarget, 5478 handleObj = event.handleObj; 5479 5480 // For mouseenter/leave call the handler if related is outside the target. 5481 // NB: No relatedTarget if the mouse left/entered the browser window 5482 if (!related || related !== target && !jQuery.contains(target, related)) { 5483 event.type = handleObj.origType; 5484 ret = handleObj.handler.apply(this, arguments); 5485 event.type = fix; 5486 } 5487 return ret; 5488 } 5489 }; 5490 }); 5491 5492 // IE submit delegation 5493 if (!support.submit) { 5494 5495 jQuery.event.special.submit = { 5496 setup: function () { 5497 5498 // Only need this for delegated form submit events 5499 if (jQuery.nodeName(this, "form")) { 5500 return false; 5501 } 5502 5503 // Lazy-add a submit handler when a descendant form may potentially be submitted 5504 jQuery.event.add(this, "click._submit keypress._submit", function (e) { 5505 5506 // Node name check avoids a VML-related crash in IE (#9807) 5507 var elem = e.target, 5508 form = jQuery.nodeName(elem, "input") || jQuery.nodeName(elem, "button") ? 5509 5510 // Support: IE <=8 5511 // We use jQuery.prop instead of elem.form 5512 // to allow fixing the IE8 delegated submit issue (gh-2332) 5513 // by 3rd party polyfills/workarounds. 5514 jQuery.prop(elem, "form") : undefined; 5515 5516 if (form && !jQuery._data(form, "submit")) { 5517 jQuery.event.add(form, "submit._submit", function (event) { 5518 event._submitBubble = true; 5519 }); 5520 jQuery._data(form, "submit", true); 5521 } 5522 }); 5523 5524 // return undefined since we don't need an event listener 5525 }, 5526 5527 postDispatch: function (event) { 5528 5529 // If form was submitted by the user, bubble the event up the tree 5530 if (event._submitBubble) { 5531 delete event._submitBubble; 5532 if (this.parentNode && !event.isTrigger) { 5533 jQuery.event.simulate("submit", this.parentNode, event); 5534 } 5535 } 5536 }, 5537 5538 teardown: function () { 5539 5540 // Only need this for delegated form submit events 5541 if (jQuery.nodeName(this, "form")) { 5542 return false; 5543 } 5544 5545 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above 5546 jQuery.event.remove(this, "._submit"); 5547 } 5548 }; 5549 } 5550 5551 // IE change delegation and checkbox/radio fix 5552 if (!support.change) { 5553 5554 jQuery.event.special.change = { 5555 5556 setup: function () { 5557 5558 if (rformElems.test(this.nodeName)) { 5559 5560 // IE doesn't fire change on a check/radio until blur; trigger it on click 5561 // after a propertychange. Eat the blur-change in special.change.handle. 5562 // This still fires onchange a second time for check/radio after blur. 5563 if (this.type === "checkbox" || this.type === "radio") { 5564 jQuery.event.add(this, "propertychange._change", function (event) { 5565 if (event.originalEvent.propertyName === "checked") { 5566 this._justChanged = true; 5567 } 5568 }); 5569 jQuery.event.add(this, "click._change", function (event) { 5570 if (this._justChanged && !event.isTrigger) { 5571 this._justChanged = false;
5572 } 5573 5574 // Allow triggered, simulated change events (#11500) 5575 jQuery.event.simulate("change", this, event); 5576 }); 5577 } 5578 return false; 5579 } 5580 5581 // Delegated event; lazy-add a change handler on descendant inputs 5582 jQuery.event.add(this, "beforeactivate._change", function (e) { 5583 var elem = e.target; 5584 5585 if (rformElems.test(elem.nodeName) && !jQuery._data(elem, "change")) { 5586 jQuery.event.add(elem, "change._change", function (event) { 5587 if (this.parentNode && !event.isSimulated && !event.isTrigger) { 5588 jQuery.event.simulate("change", this.parentNode, event); 5589 } 5590 }); 5591 jQuery._data(elem, "change", true); 5592 } 5593 }); 5594 }, 5595 5596 handle: function (event) { 5597 var elem = event.target; 5598 5599 // Swallow native change events from checkbox/radio, we already triggered them above 5600 if (this !== elem || event.isSimulated || event.isTrigger || elem.type !== "radio" && elem.type !== "checkbox") { 5601 5602 return event.handleObj.handler.apply(this, arguments); 5603 } 5604 }, 5605 5606 teardown: function () { 5607 jQuery.event.remove(this, "._change"); 5608 5609 return !rformElems.test(this.nodeName); 5610 } 5611 }; 5612 } 5613 5614 // Support: Firefox 5615 // Firefox doesn't have focus(in | out) events
vendor: 1,180 bytes, lines 5616-5647
5616 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 5617 // 5618 // Support: Chrome, Safari 5619 // focus(in | out) events fire after focus & blur events, 5620 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 5621 // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857 5622 if (!support.focusin) { 5623 jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) { 5624 5625 // Attach a single capturing handler on the document while someone wants focusin/focusout 5626 var handler = function (event) { 5627 jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); 5628 }; 5629 5630 jQuery.event.special[fix] = { 5631 setup: function () { 5632 var doc = this.ownerDocument || this, 5633 attaches = jQuery._data(doc, fix); 5634 5635 if (!attaches) { 5636 doc.addEventListener(orig, handler, true); 5637 } 5638 jQuery._data(doc, fix, (attaches || 0) + 1); 5639 }, 5640 teardown: function () { 5641 var doc = this.ownerDocument || this, 5642 attaches = jQuery._data(doc, fix) - 1; 5643 5644 if (!attaches) { 5645 doc.removeEventListener(orig, handler, true); 5646 jQuery._removeData(doc, fix); 5647 } else {
vendor: 11,646 bytes, lines 5648-6057
5648 jQuery._data(doc, fix, attaches); 5649 } 5650 } 5651 }; 5652 }); 5653 } 5654 5655 jQuery.fn.extend({ 5656 5657 on: function (types, selector, data, fn) { 5658 return on(this, types, selector, data, fn); 5659 }, 5660 one: function (types, selector, data, fn) { 5661 return on(this, types, selector, data, fn, 1); 5662 }, 5663 off: function (types, selector, fn) { 5664 var handleObj, type; 5665 if (types && types.preventDefault && types.handleObj) { 5666 5667 // ( event ) dispatched jQuery.Event 5668 handleObj = types.handleObj; 5669 jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); 5670 return this; 5671 } 5672 if (typeof types === "object") { 5673 5674 // ( types-object [, selector] ) 5675 for (type in types) { 5676 this.off(type, selector, types[type]); 5677 } 5678 return this; 5679 } 5680 if (selector === false || typeof selector === "function") { 5681 5682 // ( types [, fn] ) 5683 fn = selector; 5684 selector = undefined; 5685 } 5686 if (fn === false) { 5687 fn = returnFalse; 5688 } 5689 return this.each(function () { 5690 jQuery.event.remove(this, types, fn, selector); 5691 }); 5692 }, 5693 5694 trigger: function (type, data) { 5695 return this.each(function () { 5696 jQuery.event.trigger(type, data, this); 5697 }); 5698 }, 5699 triggerHandler: function (type, data) { 5700 var elem = this[0]; 5701 if (elem) { 5702 return jQuery.event.trigger(type, data, elem, true); 5703 } 5704 } 5705 }); 5706 5707 var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, 5708 rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), 5709 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi, 5710 5711 5712 // Support: IE 10-11, Edge 10240+ 5713 // In IE/Edge using regex groups here causes severe slowdowns. 5714 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 5715 rnoInnerhtml = /<script|<style|<link/i, 5716 5717 5718 // checked="checked" or checked 5719 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 5720 rscriptTypeMasked = /^true\/(.*)/, 5721 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, 5722 safeFragment = createSafeFragment(document), 5723 fragmentDiv = safeFragment.appendChild(document.createElement("div")); 5724 5725 // Support: IE<8 5726 // Manipulating tables requires a tbody 5727 function manipulationTarget(elem, content) { 5728 return jQuery.nodeName(elem, "table") && jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr") ? elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody")) : elem; 5729 } 5730 5731 // Replace/restore the type attribute of script elements for safe DOM manipulation 5732 function disableScript(elem) { 5733 elem.type = (jQuery.find.attr(elem, "type") !== null) + "/" + elem.type; 5734 return elem; 5735 } 5736 function restoreScript(elem) { 5737 var match = rscriptTypeMasked.exec(elem.type); 5738 if (match) { 5739 elem.type = match[1]; 5740 } else { 5741 elem.removeAttribute("type"); 5742 } 5743 return elem; 5744 } 5745 5746 function cloneCopyEvent(src, dest) { 5747 if (dest.nodeType !== 1 || !jQuery.hasData(src)) { 5748 return; 5749 } 5750 5751 var type, 5752 i, 5753 l, 5754 oldData = jQuery._data(src), 5755 curData = jQuery._data(dest, oldData), 5756 events = oldData.events; 5757 5758 if (events) { 5759 delete curData.handle; 5760 curData.events = {}; 5761 5762 for (type in events) { 5763 for (i = 0, l = events[type].length; i < l; i++) { 5764 jQuery.event.add(dest, type, events[type][i]); 5765 } 5766 } 5767 } 5768 5769 // make the cloned public data object a copy from the original 5770 if (curData.data) { 5771 curData.data = jQuery.extend({}, curData.data); 5772 } 5773 } 5774 5775 function fixCloneNodeIssues(src, dest) { 5776 var nodeName, e, data; 5777 5778 // We do not need to do anything for non-Elements 5779 if (dest.nodeType !== 1) { 5780 return; 5781 } 5782 5783 nodeName = dest.nodeName.toLowerCase(); 5784 5785 // IE6-8 copies events bound via attachEvent when using cloneNode. 5786 if (!support.noCloneEvent && dest[jQuery.expando]) { 5787 data = jQuery._data(dest); 5788 5789 for (e in data.events) { 5790 jQuery.removeEvent(dest, e, data.handle); 5791 } 5792 5793 // Event data gets referenced instead of copied if the expando gets copied too 5794 dest.removeAttribute(jQuery.expando); 5795 } 5796 5797 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text 5798 if (nodeName === "script" && dest.text !== src.text) { 5799 disableScript(dest).text = src.text; 5800 restoreScript(dest); 5801 5802 // IE6-10 improperly clones children of object elements using classid. 5803 // IE10 throws NoModificationAllowedError if parent is null, #12132. 5804 } else if (nodeName === "object") { 5805 if (dest.parentNode) { 5806 dest.outerHTML = src.outerHTML; 5807 } 5808 5809 // This path appears unavoidable for IE9. When cloning an object 5810 // element in IE9, the outerHTML strategy above is not sufficient. 5811 // If the src has innerHTML and the destination does not, 5812 // copy the src.innerHTML into the dest.innerHTML. #10324 5813 if (support.html5Clone && src.innerHTML && !jQuery.trim(dest.innerHTML)) { 5814 dest.innerHTML = src.innerHTML; 5815 } 5816 } else if (nodeName === "input" && rcheckableType.test(src.type)) { 5817 5818 // IE6-8 fails to persist the checked state of a cloned checkbox 5819 // or radio button. Worse, IE6-7 fail to give the cloned element 5820 // a checked appearance if the defaultChecked value isn't also set 5821 5822 dest.defaultChecked = dest.checked = src.checked; 5823 5824 // IE6-7 get confused and end up setting the value of a cloned 5825 // checkbox/radio button to an empty string instead of "on" 5826 if (dest.value !== src.value) { 5827 dest.value = src.value; 5828 } 5829 5830 // IE6-8 fails to return the selected option to the default selected 5831 // state when cloning options 5832 } else if (nodeName === "option") { 5833 dest.defaultSelected = dest.selected = src.defaultSelected; 5834 5835 // IE6-8 fails to set the defaultValue to the correct value when 5836 // cloning other types of input fields 5837 } else if (nodeName === "input" || nodeName === "textarea") { 5838 dest.defaultValue = src.defaultValue; 5839 } 5840 } 5841 5842 function domManip(collection, args, callback, ignored) { 5843 5844 // Flatten any nested arrays 5845 args = concat.apply([], args); 5846 5847 var first, 5848 node, 5849 hasScripts, 5850 scripts, 5851 doc, 5852 fragment, 5853 i = 0, 5854 l = collection.length, 5855 iNoClone = l - 1, 5856 value = args[0], 5857 isFunction = jQuery.isFunction(value); 5858 5859 // We can't cloneNode fragments that contain checked, in WebKit 5860 if (isFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) { 5861 return collection.each(function (index) { 5862 var self = collection.eq(index); 5863 if (isFunction) { 5864 args[0] = value.call(this, index, self.html()); 5865 } 5866 domManip(self, args, callback, ignored); 5867 }); 5868 } 5869 5870 if (l) { 5871 fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); 5872 first = fragment.firstChild; 5873 5874 if (fragment.childNodes.length === 1) { 5875 fragment = first; 5876 } 5877 5878 // Require either new content or an interest in ignored elements to invoke the callback 5879 if (first || ignored) { 5880 scripts = jQuery.map(getAll(fragment, "script"), disableScript); 5881 hasScripts = scripts.length; 5882 5883 // Use the original fragment for the last item 5884 // instead of the first because it can end up 5885 // being emptied incorrectly in certain situations (#8070). 5886 for (; i < l; i++) { 5887 node = fragment; 5888 5889 if (i !== iNoClone) { 5890 node = jQuery.clone(node, true, true); 5891 5892 // Keep references to cloned scripts for later restoration 5893 if (hasScripts) { 5894 5895 // Support: Android<4.1, PhantomJS<2 5896 // push.apply(_, arraylike) throws on ancient WebKit 5897 jQuery.merge(scripts, getAll(node, "script")); 5898 } 5899 } 5900 5901 callback.call(collection[i], node, i); 5902 } 5903 5904 if (hasScripts) { 5905 doc = scripts[scripts.length - 1].ownerDocument; 5906 5907 // Reenable scripts 5908 jQuery.map(scripts, restoreScript); 5909 5910 // Evaluate executable scripts on first document insertion 5911 for (i = 0; i < hasScripts; i++) { 5912 node = scripts[i]; 5913 if (rscriptType.test(node.type || "") && !jQuery._data(node, "globalEval") && jQuery.contains(doc, node)) { 5914 5915 if (node.src) { 5916 5917 // Optional AJAX dependency, but won't run scripts if not present 5918 if (jQuery._evalUrl) { 5919 jQuery._evalUrl(node.src); 5920 } 5921 } else { 5922 jQuery.globalEval((node.text || node.textContent || node.innerHTML || "").replace(rcleanScript, "")); 5923 } 5924 } 5925 } 5926 } 5927 5928 // Fix #11809: Avoid leaking memory 5929 fragment = first = null; 5930 } 5931 } 5932 5933 return collection; 5934 } 5935 5936 function remove(elem, selector, keepData) { 5937 var node, 5938 elems = selector ? jQuery.filter(selector, elem) : elem, 5939 i = 0; 5940 5941 for (; (node = elems[i]) != null; i++) { 5942 5943 if (!keepData && node.nodeType === 1) { 5944 jQuery.cleanData(getAll(node)); 5945 } 5946 5947 if (node.parentNode) { 5948 if (keepData && jQuery.contains(node.ownerDocument, node)) { 5949 setGlobalEval(getAll(node, "script")); 5950 } 5951 node.parentNode.removeChild(node); 5952 } 5953 } 5954 5955 return elem; 5956 } 5957 5958 jQuery.extend({ 5959 htmlPrefilter: function (html) { 5960 return html.replace(rxhtmlTag, "<$1></$2>"); 5961 }, 5962 5963 clone: function (elem, dataAndEvents, deepDataAndEvents) { 5964 var destElements, 5965 node, 5966 clone, 5967 i, 5968 srcElements, 5969 inPage = jQuery.contains(elem.ownerDocument, elem); 5970 5971 if (support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test("<" + elem.nodeName + ">")) { 5972 5973 clone = elem.cloneNode(true); 5974 5975 // IE<=8 does not properly clone detached, unknown element nodes 5976 } else { 5977 fragmentDiv.innerHTML = elem.outerHTML; 5978 fragmentDiv.removeChild(clone = fragmentDiv.firstChild); 5979 } 5980 5981 if ((!support.noCloneEvent || !support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { 5982 5983 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 5984 destElements = getAll(clone); 5985 srcElements = getAll(elem); 5986 5987 // Fix all IE cloning issues 5988 for (i = 0; (node = srcElements[i]) != null; ++i) { 5989 5990 // Ensure that the destination node is not null; Fixes #9587 5991 if (destElements[i]) { 5992 fixCloneNodeIssues(node, destElements[i]); 5993 } 5994 } 5995 } 5996 5997 // Copy the events from the original to the clone 5998 if (dataAndEvents) { 5999 if (deepDataAndEvents) { 6000 srcElements = srcElements || getAll(elem); 6001 destElements = destElements || getAll(clone); 6002 6003 for (i = 0; (node = srcElements[i]) != null; i++) { 6004 cloneCopyEvent(node, destElements[i]); 6005 } 6006 } else { 6007 cloneCopyEvent(elem, clone); 6008 } 6009 } 6010 6011 // Preserve script evaluation history 6012 destElements = getAll(clone, "script"); 6013 if (destElements.length > 0) { 6014 setGlobalEval(destElements, !inPage && getAll(elem, "script")); 6015 } 6016 6017 destElements = srcElements = node = null; 6018 6019 // Return the cloned set 6020 return clone; 6021 }, 6022 6023 cleanData: function (elems, /* internal */forceAcceptData) { 6024 var elem, 6025 type, 6026 id, 6027 data, 6028 i = 0, 6029 internalKey = jQuery.expando, 6030 cache = jQuery.cache, 6031 attributes = support.attributes, 6032 special = jQuery.event.special; 6033 6034 for (; (elem = elems[i]) != null; i++) { 6035 if (forceAcceptData || acceptData(elem)) { 6036 6037 id = elem[internalKey]; 6038 data = id && cache[id]; 6039 6040 if (data) { 6041 if (data.events) { 6042 for (type in data.events) { 6043 if (special[type]) { 6044 jQuery.event.remove(elem, type); 6045 6046 // This is a shortcut to avoid jQuery.event.remove's overhead 6047 } else { 6048 jQuery.removeEvent(elem, type, data.handle); 6049 } 6050 } 6051 } 6052 6053 // Remove cache only if it was not already removed by jQuery.event.remove 6054 if (cache[id]) { 6055 6056 delete cache[id]; 6057
6058 // Support: IE<9 6059 // IE does not allow us to delete expando properties from nodes 6060 // IE creates expando attributes along with the property 6061 // IE does not have a removeAttribute function on Document nodes 6062 if (!attributes && typeof elem.removeAttribute !== "undefined") { 6063 elem.removeAttribute(internalKey); 6064 6065 // Webkit & Blink performance suffers when deleting properties 6066 // from DOM nodes, so set to undefined instead 6067 // https://code.google.com/p/chromium/issues/detail?id=378607 6068 } else { 6069 elem[internalKey] = undefined; 6070 } 6071 6072 deletedIds.push(id); 6073 } 6074 } 6075 } 6076 } 6077 } 6078 }); 6079 6080 jQuery.fn.extend({ 6081 6082 // Keep domManip exposed until 3.0 (gh-2225) 6083 domManip: domManip, 6084 6085 detach: function (selector) { 6086 return remove(this, selector, true); 6087 }, 6088 6089 remove: function (selector) { 6090 return remove(this, selector); 6091 }, 6092 6093 text: function (value) { 6094 return access(this, function (value) { 6095 return value === undefined ? jQuery.text(this) : this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(value)); 6096 }, null, value, arguments.length); 6097 }, 6098 6099 append: function () { 6100 return domManip(this, arguments, function (elem) { 6101 if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 6102 var target = manipulationTarget(this, elem); 6103 target.appendChild(elem); 6104 } 6105 }); 6106 }, 6107 6108 prepend: function () { 6109 return domManip(this, arguments, function (elem) { 6110 if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { 6111 var target = manipulationTarget(this, elem); 6112 target.insertBefore(elem, target.firstChild); 6113 } 6114 }); 6115 }, 6116 6117 before: function () { 6118 return domManip(this, arguments, function (elem) { 6119 if (this.parentNode) { 6120 this.parentNode.insertBefore(elem, this); 6121 } 6122 }); 6123 }, 6124 6125 after: function () { 6126 return domManip(this, arguments, function (elem) { 6127 if (this.parentNode) { 6128 this.parentNode.insertBefore(elem, this.nextSibling); 6129 } 6130 }); 6131 }, 6132 6133 empty: function () { 6134 var elem, 6135 i = 0; 6136 6137 for (; (elem = this[i]) != null; i++) { 6138 6139 // Remove element nodes and prevent memory leaks 6140 if (elem.nodeType === 1) { 6141 jQuery.cleanData(getAll(elem, false)); 6142 } 6143 6144 // Remove any remaining nodes 6145 while (elem.firstChild) { 6146 elem.removeChild(elem.firstChild); 6147 } 6148 6149 // If this is a select, ensure that it displays empty (#12336) 6150 // Support: IE<9 6151 if (elem.options && jQuery.nodeName(elem, "select")) { 6152 elem.options.length = 0; 6153 } 6154 } 6155 6156 return this; 6157 }, 6158 6159 clone: function (dataAndEvents, deepDataAndEvents) { 6160 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 6161 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 6162 6163 return this.map(function () { 6164 return jQuery.clone(this, dataAndEvents, deepDataAndEvents); 6165 }); 6166 }, 6167 6168 html: function (value) { 6169 return access(this, function (value) { 6170 var elem = this[0] || {}, 6171 i = 0, 6172 l = this.length; 6173 6174 if (value === undefined) { 6175 return elem.nodeType === 1 ? elem.innerHTML.replace(rinlinejQuery, "") : undefined; 6176 } 6177 6178 // See if we can take a shortcut and just use innerHTML 6179 if (typeof value === "string" && !rnoInnerhtml.test(value) && (support.htmlSerialize || !rnoshimcache.test(value)) && (support.leadingWhitespace || !rleadingWhitespace.test(value)) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { 6180 6181 value = jQuery.htmlPrefilter(value); 6182 6183 try { 6184 for (; i < l; i++) { 6185 6186 // Remove element nodes and prevent memory leaks 6187 elem = this[i] || {}; 6188 if (elem.nodeType === 1) { 6189 jQuery.cleanData(getAll(elem, false)); 6190 elem.innerHTML = value; 6191 } 6192 } 6193 6194 elem = 0; 6195 6196 // If using innerHTML throws an exception, use the fallback method 6197 } catch (e) {} 6198 } 6199 6200 if (elem) { 6201 this.empty().append(value); 6202 } 6203 }, null, value, arguments.length); 6204 }, 6205 6206 replaceWith: function () { 6207 var ignored = []; 6208 6209 // Make the changes, replacing each non-ignored context element with the new content 6210 return domManip(this, arguments, function (elem) { 6211 var parent = this.parentNode; 6212 6213 if (jQuery.inArray(this, ignored) < 0) { 6214 jQuery.cleanData(getAll(this)); 6215 if (parent) { 6216 parent.replaceChild(elem, this); 6217 } 6218 } 6219 6220 // Force callback invocation 6221 }, ignored); 6222 } 6223 }); 6224 6225 jQuery.each({ 6226 appendTo: "append",
vendor: 1,203 bytes, lines 6227-6274
6227 prependTo: "prepend", 6228 insertBefore: "before", 6229 insertAfter: "after", 6230 replaceAll: "replaceWith" 6231 }, function (name, original) { 6232 jQuery.fn[name] = function (selector) { 6233 var elems, 6234 i = 0, 6235 ret = [], 6236 insert = jQuery(selector), 6237 last = insert.length - 1; 6238 6239 for (; i <= last; i++) { 6240 elems = i === last ? this : this.clone(true); 6241 jQuery(insert[i])[original](elems); 6242 6243 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() 6244 push.apply(ret, elems.get()); 6245 } 6246 6247 return this.pushStack(ret); 6248 }; 6249 }); 6250 6251 var iframe, 6252 elemdisplay = { 6253 6254 // Support: Firefox 6255 // We have to pre-define these values for FF (#10227) 6256 HTML: "block", 6257 BODY: "block" 6258 }; 6259 6260 /** 6261 * Retrieve the actual display of a element 6262 * @param {String} name nodeName of the element 6263 * @param {Object} doc Document object 6264 */ 6265 6266 // Called only from within defaultDisplay 6267 function actualDisplay(name, doc) { 6268 var elem = jQuery(doc.createElement(name)).appendTo(doc.body), 6269 display = jQuery.css(elem[0], "display"); 6270 6271 // We don't have any data stored on the element, 6272 // so use "detach" method as fast way to get rid of the element 6273 elem.detach(); 6274
6275 return display; 6276 } 6277 6278 /** 6279 * Try to determine the default display value of an element 6280 * @param {String} nodeName 6281 */ 6282 function defaultDisplay(nodeName) { 6283 var doc = document, 6284 display = elemdisplay[nodeName]; 6285 6286 if (!display) { 6287 display = actualDisplay(nodeName, doc); 6288 6289 // If the simple way fails, read from inside an iframe 6290 if (display === "none" || !display) { 6291 6292 // Use the already-created iframe if possible 6293 iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")).appendTo(doc.documentElement); 6294 6295 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse 6296 doc = (iframe[0].contentWindow || iframe[0].contentDocument).document; 6297 6298 // Support: IE 6299 doc.write(); 6300 doc.close(); 6301 6302 display = actualDisplay(nodeName, doc); 6303 iframe.detach(); 6304 } 6305 6306 // Store the correct default display 6307 elemdisplay[nodeName] = display; 6308 } 6309 6310 return display; 6311 } 6312 var rmargin = /^margin/; 6313 6314 var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); 6315 6316 var swap = function (elem, options, callback, args) { 6317 var ret, 6318 name, 6319 old = {}; 6320 6321 // Remember the old values, and insert the new ones 6322 for (name in options) { 6323 old[name] = elem.style[name]; 6324 elem.style[name] = options[name]; 6325 } 6326 6327 ret = callback.apply(elem, args || []); 6328 6329 // Revert the old values 6330 for (name in options) { 6331 elem.style[name] = old[name]; 6332 } 6333 6334 return ret; 6335 }; 6336 6337 var documentElement = document.documentElement; 6338 6339 (function () { 6340 var pixelPositionVal, 6341 pixelMarginRightVal, 6342 boxSizingReliableVal, 6343 reliableHiddenOffsetsVal, 6344 reliableMarginRightVal, 6345 reliableMarginLeftVal, 6346 container = document.createElement("div"), 6347 div = document.createElement("div"); 6348 6349 // Finish early in limited (non-browser) environments 6350 if (!div.style) { 6351 return; 6352 } 6353 6354 div.style.cssText = "float:left;opacity:.5"; 6355 6356 // Support: IE<9 6357 // Make sure that element opacity exists (as opposed to filter) 6358 support.opacity = div.style.opacity === "0.5"; 6359 6360 // Verify style float existence 6361 // (IE uses styleFloat instead of cssFloat) 6362 support.cssFloat = !!div.style.cssFloat; 6363 6364 div.style.backgroundClip = "content-box"; 6365 div.cloneNode(true).style.backgroundClip = ""; 6366 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 6367 6368 container = document.createElement("div"); 6369 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + "padding:0;margin-top:1px;position:absolute"; 6370 div.innerHTML = ""; 6371 container.appendChild(div); 6372 6373 // Support: Firefox<29, Android 2.3 6374 // Vendor-prefix box-sizing 6375 support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" || div.style.WebkitBoxSizing === ""; 6376 6377 jQuery.extend(support, { 6378 reliableHiddenOffsets: function () { 6379 if (pixelPositionVal == null) { 6380 computeStyleTests(); 6381 } 6382 return reliableHiddenOffsetsVal; 6383 }, 6384 6385 boxSizingReliable: function () { 6386 6387 // We're checking for pixelPositionVal here instead of boxSizingReliableVal 6388 // since that compresses better and they're computed together anyway. 6389 if (pixelPositionVal == null) { 6390 computeStyleTests(); 6391 } 6392 return boxSizingReliableVal; 6393 }, 6394 6395 pixelMarginRight: function () { 6396 6397 // Support: Android 4.0-4.3 6398 if (pixelPositionVal == null) { 6399 computeStyleTests(); 6400 } 6401 return pixelMarginRightVal; 6402 }, 6403 6404 pixelPosition: function () { 6405 if (pixelPositionVal == null) { 6406 computeStyleTests(); 6407 } 6408 return pixelPositionVal; 6409 }, 6410 6411 reliableMarginRight: function () { 6412 6413 // Support: Android 2.3 6414 if (pixelPositionVal == null) { 6415 computeStyleTests(); 6416 } 6417 return reliableMarginRightVal; 6418 }, 6419 6420 reliableMarginLeft: function () { 6421 6422 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37 6423 if (pixelPositionVal == null) { 6424 computeStyleTests(); 6425 } 6426 return reliableMarginLeftVal; 6427 } 6428 }); 6429 6430 function computeStyleTests() { 6431 var contents, 6432 divStyle, 6433 documentElement = document.documentElement; 6434 6435 // Setup 6436 documentElement.appendChild(container); 6437 6438 div.style.cssText = 6439
6440 // Support: Android 2.3 6441 // Vendor-prefix box-sizing 6442 "-webkit-box-sizing:border-box;box-sizing:border-box;" + "position:relative;display:block;" + "margin:auto;border:1px;padding:1px;" + "top:1%;width:50%"; 6443 6444 // Support: IE<9 6445 // Assume reasonable values in the absence of getComputedStyle 6446 pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false; 6447 pixelMarginRightVal = reliableMarginRightVal = true; 6448 6449 // Check for getComputedStyle so that this code is not run in IE<9. 6450 if (window.getComputedStyle) { 6451 divStyle = window.getComputedStyle(div); 6452 pixelPositionVal = (divStyle || {}).top !== "1%"; 6453 reliableMarginLeftVal = (divStyle || {}).marginLeft === "2px"; 6454 boxSizingReliableVal = (divStyle || { width: "4px" }).width === "4px"; 6455 6456 // Support: Android 4.0 - 4.3 only 6457 // Some styles come back with percentage values, even though they shouldn't 6458 div.style.marginRight = "50%"; 6459 pixelMarginRightVal = (divStyle || { marginRight: "4px" }).marginRight === "4px"; 6460 6461 // Support: Android 2.3 only 6462 // Div with explicit width and no margin-right incorrectly 6463 // gets computed margin-right based on width of container (#3333) 6464 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right 6465 contents = div.appendChild(document.createElement("div")); 6466 6467 // Reset CSS: box-sizing; display; margin; border; padding 6468 contents.style.cssText = div.style.cssText = 6469 6470 // Support: Android 2.3 6471 // Vendor-prefix box-sizing 6472 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; 6473 contents.style.marginRight = contents.style.width = "0"; 6474 div.style.width = "1px"; 6475 6476 reliableMarginRightVal = !parseFloat((window.getComputedStyle(contents) || {}).marginRight); 6477 6478 div.removeChild(contents); 6479 } 6480 6481 // Support: IE6-8 6482 // First check that getClientRects works as expected 6483 // Check if table cells still have offsetWidth/Height when they are set 6484 // to display:none and there are still other visible table cells in a 6485 // table row; if so, offsetWidth/Height are not reliable for use when 6486 // determining if an element has been hidden directly using 6487 // display:none (it is still safe to use offsets if a parent element is 6488 // hidden; don safety goggles and see bug #4512 for more information). 6489 div.style.display = "none"; 6490 reliableHiddenOffsetsVal = div.getClientRects().length === 0; 6491 if (reliableHiddenOffsetsVal) { 6492 div.style.display = ""; 6493 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; 6494 div.childNodes[0].style.borderCollapse = "separate"; 6495 contents = div.getElementsByTagName("td"); 6496 contents[0].style.cssText = "margin:0;border:0;padding:0;display:none"; 6497 reliableHiddenOffsetsVal = contents[0].offsetHeight === 0; 6498 if (reliableHiddenOffsetsVal) { 6499 contents[0].style.display = ""; 6500 contents[1].style.display = "none"; 6501 reliableHiddenOffsetsVal = contents[0].offsetHeight === 0; 6502 } 6503 } 6504 6505 // Teardown 6506 documentElement.removeChild(container); 6507 } 6508 })(); 6509 6510 var getStyles, 6511 curCSS, 6512 rposition = /^(top|right|bottom|left)$/; 6513 6514 if (window.getComputedStyle) { 6515 getStyles = function (elem) { 6516 6517 // Support: IE<=11+, Firefox<=30+ (#15098, #14150) 6518 // IE throws on elements created in popups 6519 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 6520 var view = elem.ownerDocument.defaultView; 6521 6522 if (!view || !view.opener) { 6523 view = window; 6524 } 6525 6526 return view.getComputedStyle(elem); 6527 }; 6528 6529 curCSS = function (elem, name, computed) { 6530 var width, 6531 minWidth, 6532 maxWidth, 6533 ret, 6534 style = elem.style; 6535 6536 computed = computed || getStyles(elem); 6537 6538 // getPropertyValue is only needed for .css('filter') in IE9, see #12537 6539 ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined; 6540 6541 // Support: Opera 12.1x only 6542 // Fall back to style even without computed 6543 // computed is undefined for elems on document fragments 6544 if ((ret === "" || ret === undefined) && !jQuery.contains(elem.ownerDocument, elem)) { 6545 ret = jQuery.style(elem, name); 6546 } 6547 6548 if (computed) { 6549 6550 // A tribute to the "awesome hack by Dean Edwards" 6551 // Chrome < 17 and Safari 5.0 uses "computed value" 6552 // instead of "used value" for margin-right 6553 // Safari 5.1.7 (at least) returns percentage for a larger set of values, 6554 // but width seems to be reliably pixels 6555 // this is against the CSSOM draft spec: 6556 // http://dev.w3.org/csswg/cssom/#resolved-values 6557 if (!support.pixelMarginRight() && rnumnonpx.test(ret) && rmargin.test(name)) { 6558 6559 // Remember the original values 6560 width = style.width; 6561 minWidth = style.minWidth; 6562 maxWidth = style.maxWidth; 6563 6564 // Put in the new values to get a computed value out 6565 style.minWidth = style.maxWidth = style.width = ret; 6566 ret = computed.width; 6567 6568 // Revert the changed values 6569 style.width = width; 6570 style.minWidth = minWidth; 6571 style.maxWidth = maxWidth; 6572 } 6573 } 6574
vendor: 4,252 bytes, lines 6575-6727
6575 // Support: IE 6576 // IE returns zIndex value as an integer. 6577 return ret === undefined ? ret : ret + ""; 6578 }; 6579 } else if (documentElement.currentStyle) { 6580 getStyles = function (elem) { 6581 return elem.currentStyle; 6582 }; 6583 6584 curCSS = function (elem, name, computed) { 6585 var left, 6586 rs, 6587 rsLeft, 6588 ret, 6589 style = elem.style; 6590 6591 computed = computed || getStyles(elem); 6592 ret = computed ? computed[name] : undefined; 6593 6594 // Avoid setting ret to empty string here 6595 // so we don't default to auto 6596 if (ret == null && style && style[name]) { 6597 ret = style[name]; 6598 } 6599 6600 // From the awesome hack by Dean Edwards 6601 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 6602 6603 // If we're not dealing with a regular pixel number 6604 // but a number that has a weird ending, we need to convert it to pixels 6605 // but not position css attributes, as those are 6606 // proportional to the parent element instead 6607 // and we can't measure the parent instead because it 6608 // might trigger a "stacking dolls" problem 6609 if (rnumnonpx.test(ret) && !rposition.test(name)) { 6610 6611 // Remember the original values 6612 left = style.left; 6613 rs = elem.runtimeStyle; 6614 rsLeft = rs && rs.left; 6615 6616 // Put in the new values to get a computed value out 6617 if (rsLeft) { 6618 rs.left = elem.currentStyle.left; 6619 } 6620 style.left = name === "fontSize" ? "1em" : ret; 6621 ret = style.pixelLeft + "px"; 6622 6623 // Revert the changed values 6624 style.left = left; 6625 if (rsLeft) { 6626 rs.left = rsLeft; 6627 } 6628 } 6629 6630 // Support: IE 6631 // IE returns zIndex value as an integer. 6632 return ret === undefined ? ret : ret + "" || "auto"; 6633 }; 6634 } 6635 6636 function addGetHookIf(conditionFn, hookFn) { 6637 6638 // Define the hook, we'll check on the first run if it's really needed. 6639 return { 6640 get: function () { 6641 if (conditionFn()) { 6642 6643 // Hook not needed (or it's not possible to use it due 6644 // to missing dependency), remove it. 6645 delete this.get; 6646 return; 6647 } 6648 6649 // Hook needed; redefine it so that the support test is not executed again. 6650 return (this.get = hookFn).apply(this, arguments); 6651 } 6652 }; 6653 } 6654 6655 var ralpha = /alpha\([^)]*\)/i, 6656 ropacity = /opacity\s*=\s*([^)]*)/i, 6657 6658 6659 // swappable if display is none or starts with table except 6660 // "table", "table-cell", or "table-caption" 6661 // see here for display values: 6662 // https://developer.mozilla.org/en-US/docs/CSS/display 6663 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 6664 rnumsplit = new RegExp("^(" + pnum + ")(.*)$", "i"), 6665 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 6666 cssNormalTransform = { 6667 letterSpacing: "0", 6668 fontWeight: "400" 6669 }, 6670 cssPrefixes = ["Webkit", "O", "Moz", "ms"], 6671 emptyStyle = document.createElement("div").style; 6672 6673 // return a css property mapped to a potentially vendor prefixed property 6674 function vendorPropName(name) { 6675 6676 // shortcut for names that are not vendor prefixed 6677 if (name in emptyStyle) { 6678 return name; 6679 } 6680 6681 // check for vendor prefixed names 6682 var capName = name.charAt(0).toUpperCase() + name.slice(1), 6683 i = cssPrefixes.length; 6684 6685 while (i--) { 6686 name = cssPrefixes[i] + capName; 6687 if (name in emptyStyle) { 6688 return name; 6689 } 6690 } 6691 } 6692 6693 function showHide(elements, show) { 6694 var display, 6695 elem, 6696 hidden, 6697 values = [], 6698 index = 0, 6699 length = elements.length; 6700 6701 for (; index < length; index++) { 6702 elem = elements[index]; 6703 if (!elem.style) { 6704 continue; 6705 } 6706 6707 values[index] = jQuery._data(elem, "olddisplay"); 6708 display = elem.style.display; 6709 if (show) { 6710 6711 // Reset the inline display of this element to learn if it is 6712 // being hidden by cascaded rules or not 6713 if (!values[index] && display === "none") { 6714 elem.style.display = ""; 6715 } 6716 6717 // Set elements which have been overridden with display: none 6718 // in a stylesheet to whatever the default browser style is 6719 // for such an element 6720 if (elem.style.display === "" && isHidden(elem)) { 6721 values[index] = jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); 6722 } 6723 } else { 6724 hidden = isHidden(elem); 6725 6726 if (display && display !== "none" || !hidden) { 6727 jQuery._data(elem, "olddisplay", hidden ? display : jQuery.css(elem, "dis
vendor: 6,095 bytes, lines 6727-6928
6727play")); 6728 } 6729 } 6730 } 6731 6732 // Set the display of most of the elements in a second loop 6733 // to avoid the constant reflow 6734 for (index = 0; index < length; index++) { 6735 elem = elements[index]; 6736 if (!elem.style) { 6737 continue; 6738 } 6739 if (!show || elem.style.display === "none" || elem.style.display === "") { 6740 elem.style.display = show ? values[index] || "" : "none"; 6741 } 6742 } 6743 6744 return elements; 6745 } 6746 6747 function setPositiveNumber(elem, value, subtract) { 6748 var matches = rnumsplit.exec(value); 6749 return matches ? 6750 6751 // Guard against undefined "subtract", e.g., when used as in cssHooks 6752 Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") : value; 6753 } 6754 6755 function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) { 6756 var i = extra === (isBorderBox ? "border" : "content") ? 6757 6758 // If we already have the right measurement, avoid augmentation 6759 4 : 6760 6761 // Otherwise initialize for horizontal or vertical properties 6762 name === "width" ? 1 : 0, 6763 val = 0; 6764 6765 for (; i < 4; i += 2) { 6766 6767 // both box models exclude margin, so add it if we want it 6768 if (extra === "margin") { 6769 val += jQuery.css(elem, extra + cssExpand[i], true, styles); 6770 } 6771 6772 if (isBorderBox) { 6773 6774 // border-box includes padding, so remove it if we want content 6775 if (extra === "content") { 6776 val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); 6777 } 6778 6779 // at this point, extra isn't border nor margin, so remove border 6780 if (extra !== "margin") { 6781 val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); 6782 } 6783 } else { 6784 6785 // at this point, extra isn't content, so add padding 6786 val += jQuery.css(elem, "padding" + cssExpand[i], true, styles); 6787 6788 // at this point, extra isn't content nor padding, so add border 6789 if (extra !== "padding") { 6790 val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); 6791 } 6792 } 6793 } 6794 6795 return val; 6796 } 6797 6798 function getWidthOrHeight(elem, name, extra) { 6799 6800 // Start with offset property, which is equivalent to the border-box value 6801 var valueIsBorderBox = true, 6802 val = name === "width" ? elem.offsetWidth : elem.offsetHeight, 6803 styles = getStyles(elem), 6804 isBorderBox = support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box"; 6805 6806 // some non-html elements return undefined for offsetWidth, so check for null/undefined 6807 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 6808 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 6809 if (val <= 0 || val == null) { 6810 6811 // Fall back to computed then uncomputed css if necessary 6812 val = curCSS(elem, name, styles); 6813 if (val < 0 || val == null) { 6814 val = elem.style[name]; 6815 } 6816 6817 // Computed unit is not pixels. Stop here and return. 6818 if (rnumnonpx.test(val)) { 6819 return val; 6820 } 6821 6822 // we need the check for style in case a browser which returns unreliable values 6823 // for getComputedStyle silently falls back to the reliable elem.style 6824 valueIsBorderBox = isBorderBox && (support.boxSizingReliable() || val === elem.style[name]); 6825 6826 // Normalize "", auto, and prepare for extra 6827 val = parseFloat(val) || 0; 6828 } 6829 6830 // use the active box-sizing model to add/subtract irrelevant styles 6831 return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles) + "px"; 6832 } 6833 6834 jQuery.extend({ 6835 6836 // Add in style property hooks for overriding the default 6837 // behavior of getting and setting a style property 6838 cssHooks: { 6839 opacity: { 6840 get: function (elem, computed) { 6841 if (computed) { 6842 6843 // We should always get a number back from opacity 6844 var ret = curCSS(elem, "opacity"); 6845 return ret === "" ? "1" : ret; 6846 } 6847 } 6848 } 6849 }, 6850 6851 // Don't automatically add "px" to these possibly-unitless properties 6852 cssNumber: { 6853 "animationIterationCount": true, 6854 "columnCount": true, 6855 "fillOpacity": true, 6856 "flexGrow": true, 6857 "flexShrink": true, 6858 "fontWeight": true, 6859 "lineHeight": true, 6860 "opacity": true, 6861 "order": true, 6862 "orphans": true, 6863 "widows": true, 6864 "zIndex": true, 6865 "zoom": true 6866 }, 6867 6868 // Add in properties whose names you wish to fix before 6869 // setting or getting the value 6870 cssProps: { 6871 6872 // normalize float css property 6873 "float": support.cssFloat ? "cssFloat" : "styleFloat" 6874 }, 6875 6876 // Get and set the style property on a DOM Node 6877 style: function (elem, name, value, extra) { 6878 6879 // Don't set styles on text and comment nodes 6880 if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { 6881 return; 6882 } 6883 6884 // Make sure that we're working with the right name 6885 var ret, 6886 type, 6887 hooks, 6888 origName = jQuery.camelCase(name), 6889 style = elem.style; 6890 6891 name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName); 6892 6893 // gets hook for the prefixed version 6894 // followed by the unprefixed version 6895 hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; 6896 6897 // Check if we're setting a value 6898 if (value !== undefined) { 6899 type = typeof value; 6900 6901 // Convert "+=" or "-=" to relative numbers (#7345) 6902 if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { 6903 value = adjustCSS(elem, name, ret); 6904 6905 // Fixes bug #9237 6906 type = "number"; 6907 } 6908 6909 // Make sure that null and NaN values aren't set. See: #7116 6910 if (value == null || value !== value) { 6911 return; 6912 } 6913 6914 // If a number was passed in, add the unit (except for certain CSS properties) 6915 if (type === "number") { 6916 value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); 6917 } 6918 6919 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, 6920 // but it would mean to define eight 6921 // (for every problematic property) identical functions 6922 if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { 6923 style[name] = "inherit"; 6924 } 6925 6926 // If a hook was provided, use that value, otherwise just set the specified value 6927 if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { 6928
vendor: 4,360 bytes, lines 6929-7055
6929 // Support: IE 6930 // Swallow errors from 'invalid' CSS values (#5509) 6931 try { 6932 style[name] = value; 6933 } catch (e) {} 6934 } 6935 } else { 6936 6937 // If a hook was provided get the non-computed value from there 6938 if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { 6939 6940 return ret; 6941 } 6942 6943 // Otherwise just get the value from the style object 6944 return style[name]; 6945 } 6946 }, 6947 6948 css: function (elem, name, extra, styles) { 6949 var num, 6950 val, 6951 hooks, 6952 origName = jQuery.camelCase(name); 6953 6954 // Make sure that we're working with the right name 6955 name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName); 6956 6957 // gets hook for the prefixed version 6958 // followed by the unprefixed version 6959 hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; 6960 6961 // If a hook was provided get the computed value from there 6962 if (hooks && "get" in hooks) { 6963 val = hooks.get(elem, true, extra); 6964 } 6965 6966 // Otherwise, if a way to get the computed value exists, use that 6967 if (val === undefined) { 6968 val = curCSS(elem, name, styles); 6969 } 6970 6971 //convert "normal" to computed value 6972 if (val === "normal" && name in cssNormalTransform) { 6973 val = cssNormalTransform[name]; 6974 } 6975 6976 // Return, converting to number if forced or a qualifier was provided and val looks numeric 6977 if (extra === "" || extra) { 6978 num = parseFloat(val); 6979 return extra === true || isFinite(num) ? num || 0 : val; 6980 } 6981 return val; 6982 } 6983 }); 6984 6985 jQuery.each(["height", "width"], function (i, name) { 6986 jQuery.cssHooks[name] = { 6987 get: function (elem, computed, extra) { 6988 if (computed) { 6989 6990 // certain elements can have dimension info if we invisibly show them 6991 // however, it must have a current display style that would benefit from this 6992 return rdisplayswap.test(jQuery.css(elem, "display")) && elem.offsetWidth === 0 ? swap(elem, cssShow, function () { 6993 return getWidthOrHeight(elem, name, extra); 6994 }) : getWidthOrHeight(elem, name, extra); 6995 } 6996 }, 6997 6998 set: function (elem, value, extra) { 6999 var styles = extra && getStyles(elem); 7000 return setPositiveNumber(elem, value, extra ? augmentWidthOrHeight(elem, name, extra, support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box", styles) : 0); 7001 } 7002 }; 7003 }); 7004 7005 if (!support.opacity) { 7006 jQuery.cssHooks.opacity = { 7007 get: function (elem, computed) { 7008 7009 // IE uses filters for opacity 7010 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? 0.01 * parseFloat(RegExp.$1) + "" : computed ? "1" : ""; 7011 }, 7012 7013 set: function (elem, value) { 7014 var style = elem.style, 7015 currentStyle = elem.currentStyle, 7016 opacity = jQuery.isNumeric(value) ? "alpha(opacity=" + value * 100 + ")" : "", 7017 filter = currentStyle && currentStyle.filter || style.filter || ""; 7018 7019 // IE has trouble with opacity if it does not have layout 7020 // Force it by setting the zoom level 7021 style.zoom = 1; 7022 7023 // if setting opacity to 1, and no other filters exist - 7024 // attempt to remove filter attribute #6652 7025 // if value === "", then remove inline opacity #12685 7026 if ((value >= 1 || value === "") && jQuery.trim(filter.replace(ralpha, "")) === "" && style.removeAttribute) { 7027 7028 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText 7029 // if "filter:" is present at all, clearType is disabled, we want to avoid this 7030 // style.removeAttribute is IE Only, but so apparently is this code path... 7031 style.removeAttribute("filter"); 7032 7033 // if there is no filter style applied in a css rule 7034 // or unset inline opacity, we are done 7035 if (value === "" || currentStyle && !currentStyle.filter) { 7036 return; 7037 } 7038 } 7039 7040 // otherwise, set new filter values 7041 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : filter + " " + opacity; 7042 } 7043 }; 7044 } 7045 7046 jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight, function (elem, computed) { 7047 if (computed) { 7048 return swap(elem, { "display": "inline-block" }, curCSS, [elem, "marginRight"]); 7049 } 7050 }); 7051 7052 jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { 7053 if (computed) { 7054 return (parseFloat(curCSS(elem, "marginLeft")) || ( 7055
vendor: 4,554 bytes, lines 7056-7219
7056 // Support: IE<=11+ 7057 // Running getBoundingClientRect on a disconnected node in IE throws an error 7058 // Support: IE8 only 7059 // getClientRects() errors on disconnected elems 7060 jQuery.contains(elem.ownerDocument, elem) ? elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { 7061 return elem.getBoundingClientRect().left; 7062 }) : 0)) + "px"; 7063 } 7064 }); 7065 7066 // These hooks are used by animate to expand properties 7067 jQuery.each({ 7068 margin: "", 7069 padding: "", 7070 border: "Width" 7071 }, function (prefix, suffix) { 7072 jQuery.cssHooks[prefix + suffix] = { 7073 expand: function (value) { 7074 var i = 0, 7075 expanded = {}, 7076 7077 7078 // assumes a single number if not a string 7079 parts = typeof value === "string" ? value.split(" ") : [value]; 7080 7081 for (; i < 4; i++) { 7082 expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; 7083 } 7084 7085 return expanded; 7086 } 7087 }; 7088 7089 if (!rmargin.test(prefix)) { 7090 jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; 7091 } 7092 }); 7093 7094 jQuery.fn.extend({ 7095 css: function (name, value) { 7096 return access(this, function (elem, name, value) { 7097 var styles, 7098 len, 7099 map = {}, 7100 i = 0; 7101 7102 if (jQuery.isArray(name)) { 7103 styles = getStyles(elem); 7104 len = name.length; 7105 7106 for (; i < len; i++) { 7107 map[name[i]] = jQuery.css(elem, name[i], false, styles); 7108 } 7109 7110 return map; 7111 } 7112 7113 return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); 7114 }, name, value, arguments.length > 1); 7115 }, 7116 show: function () { 7117 return showHide(this, true); 7118 }, 7119 hide: function () { 7120 return showHide(this); 7121 }, 7122 toggle: function (state) { 7123 if (typeof state === "boolean") { 7124 return state ? this.show() : this.hide(); 7125 } 7126 7127 return this.each(function () { 7128 if (isHidden(this)) { 7129 jQuery(this).show(); 7130 } else { 7131 jQuery(this).hide(); 7132 } 7133 }); 7134 } 7135 }); 7136 7137 function Tween(elem, options, prop, end, easing) { 7138 return new Tween.prototype.init(elem, options, prop, end, easing); 7139 } 7140 jQuery.Tween = Tween; 7141 7142 Tween.prototype = { 7143 constructor: Tween, 7144 init: function (elem, options, prop, end, easing, unit) { 7145 this.elem = elem; 7146 this.prop = prop; 7147 this.easing = easing || jQuery.easing._default; 7148 this.options = options; 7149 this.start = this.now = this.cur(); 7150 this.end = end; 7151 this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); 7152 }, 7153 cur: function () { 7154 var hooks = Tween.propHooks[this.prop]; 7155 7156 return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); 7157 }, 7158 run: function (percent) { 7159 var eased, 7160 hooks = Tween.propHooks[this.prop]; 7161 7162 if (this.options.duration) { 7163 this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); 7164 } else { 7165 this.pos = eased = percent; 7166 } 7167 this.now = (this.end - this.start) * eased + this.start; 7168 7169 if (this.options.step) { 7170 this.options.step.call(this.elem, this.now, this); 7171 } 7172 7173 if (hooks && hooks.set) { 7174 hooks.set(this); 7175 } else { 7176 Tween.propHooks._default.set(this); 7177 } 7178 return this; 7179 } 7180 }; 7181 7182 Tween.prototype.init.prototype = Tween.prototype; 7183 7184 Tween.propHooks = { 7185 _default: { 7186 get: function (tween) { 7187 var result; 7188 7189 // Use a property on the element directly when it is not a DOM element, 7190 // or when there is no matching style property that exists. 7191 if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { 7192 return tween.elem[tween.prop]; 7193 } 7194 7195 // passing an empty string as a 3rd parameter to .css will automatically 7196 // attempt a parseFloat and fallback to a string if the parse fails 7197 // so, simple values such as "10px" are parsed to Float. 7198 // complex values such as "rotate(1rad)" are returned as is. 7199 result = jQuery.css(tween.elem, tween.prop, ""); 7200 7201 // Empty strings, null, undefined and "auto" are converted to 0. 7202 return !result || result === "auto" ? 0 : result; 7203 }, 7204 set: function (tween) { 7205 7206 // use step hook for back compat - use cssHook if its there - use .style if its 7207 // available and use plain properties where available 7208 if (jQuery.fx.step[tween.prop]) { 7209 jQuery.fx.step[tween.prop](tween); 7210 } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { 7211 jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); 7212 } else { 7213 tween.elem[tween.prop] = tween.now; 7214 } 7215 } 7216 } 7217 }; 7218 7219 // Support: IE <=9
vendor: 5,745 bytes, lines 7220-7439
7220 // Panic based approach to setting things on disconnected nodes 7221 7222 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 7223 set: function (tween) { 7224 if (tween.elem.nodeType && tween.elem.parentNode) { 7225 tween.elem[tween.prop] = tween.now; 7226 } 7227 } 7228 }; 7229 7230 jQuery.easing = { 7231 linear: function (p) { 7232 return p; 7233 }, 7234 swing: function (p) { 7235 return 0.5 - Math.cos(p * Math.PI) / 2; 7236 }, 7237 _default: "swing" 7238 }; 7239 7240 jQuery.fx = Tween.prototype.init; 7241 7242 // Back Compat <1.8 extension point 7243 jQuery.fx.step = {}; 7244 7245 var fxNow, 7246 timerId, 7247 rfxtypes = /^(?:toggle|show|hide)$/, 7248 rrun = /queueHooks$/; 7249 7250 // Animations created synchronously will run synchronously 7251 function createFxNow() { 7252 window.setTimeout(function () { 7253 fxNow = undefined; 7254 }); 7255 return fxNow = jQuery.now(); 7256 } 7257 7258 // Generate parameters to create a standard animation 7259 function genFx(type, includeWidth) { 7260 var which, 7261 attrs = { height: type }, 7262 i = 0; 7263 7264 // if we include width, step value is 1 to do all cssExpand values, 7265 // if we don't include width, step value is 2 to skip over Left and Right 7266 includeWidth = includeWidth ? 1 : 0; 7267 for (; i < 4; i += 2 - includeWidth) { 7268 which = cssExpand[i]; 7269 attrs["margin" + which] = attrs["padding" + which] = type; 7270 } 7271 7272 if (includeWidth) { 7273 attrs.opacity = attrs.width = type; 7274 } 7275 7276 return attrs; 7277 } 7278 7279 function createTween(value, prop, animation) { 7280 var tween, 7281 collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]), 7282 index = 0, 7283 length = collection.length; 7284 for (; index < length; index++) { 7285 if (tween = collection[index].call(animation, prop, value)) { 7286 7287 // we're done with this property 7288 return tween; 7289 } 7290 } 7291 } 7292 7293 function defaultPrefilter(elem, props, opts) { 7294 /* jshint validthis: true */ 7295 var prop, 7296 value, 7297 toggle, 7298 tween, 7299 hooks, 7300 oldfire, 7301 display, 7302 checkDisplay, 7303 anim = this, 7304 orig = {}, 7305 style = elem.style, 7306 hidden = elem.nodeType && isHidden(elem), 7307 dataShow = jQuery._data(elem, "fxshow"); 7308 7309 // handle queue: false promises 7310 if (!opts.queue) { 7311 hooks = jQuery._queueHooks(elem, "fx"); 7312 if (hooks.unqueued == null) { 7313 hooks.unqueued = 0; 7314 oldfire = hooks.empty.fire; 7315 hooks.empty.fire = function () { 7316 if (!hooks.unqueued) { 7317 oldfire(); 7318 } 7319 }; 7320 } 7321 hooks.unqueued++; 7322 7323 anim.always(function () { 7324 7325 // doing this makes sure that the complete handler will be called 7326 // before this completes 7327 anim.always(function () { 7328 hooks.unqueued--; 7329 if (!jQuery.queue(elem, "fx").length) { 7330 hooks.empty.fire(); 7331 } 7332 }); 7333 }); 7334 } 7335 7336 // height/width overflow pass 7337 if (elem.nodeType === 1 && ("height" in props || "width" in props)) { 7338 7339 // Make sure that nothing sneaks out 7340 // Record all 3 overflow attributes because IE does not 7341 // change the overflow attribute when overflowX and 7342 // overflowY are set to the same value 7343 opts.overflow = [style.overflow, style.overflowX, style.overflowY]; 7344 7345 // Set display property to inline-block for height/width 7346 // animations on inline elements that are having width/height animated 7347 display = jQuery.css(elem, "display"); 7348 7349 // Test default display if display is currently "none" 7350 checkDisplay = display === "none" ? jQuery._data(elem, "olddisplay") || defaultDisplay(elem.nodeName) : display; 7351 7352 if (checkDisplay === "inline" && jQuery.css(elem, "float") === "none") { 7353 7354 // inline-level elements accept inline-block; 7355 // block-level elements need to be inline with layout 7356 if (!support.inlineBlockNeedsLayout || defaultDisplay(elem.nodeName) === "inline") { 7357 style.display = "inline-block"; 7358 } else { 7359 style.zoom = 1; 7360 } 7361 } 7362 } 7363 7364 if (opts.overflow) { 7365 style.overflow = "hidden"; 7366 if (!support.shrinkWrapBlocks()) { 7367 anim.always(function () { 7368 style.overflow = opts.overflow[0]; 7369 style.overflowX = opts.overflow[1]; 7370 style.overflowY = opts.overflow[2]; 7371 }); 7372 } 7373 } 7374 7375 // show/hide pass 7376 for (prop in props) { 7377 value = props[prop]; 7378 if (rfxtypes.exec(value)) { 7379 delete props[prop]; 7380 toggle = toggle || value === "toggle"; 7381 if (value === (hidden ? "hide" : "show")) { 7382 7383 // If there is dataShow left over from a stopped hide or show 7384 // and we are going to proceed with show, we should pretend to be hidden 7385 if (value === "show" && dataShow && dataShow[prop] !== undefined) { 7386 hidden = true; 7387 } else { 7388 continue; 7389 } 7390 } 7391 orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); 7392 7393 // Any non-fx value stops us from restoring the original display value 7394 } else { 7395 display = undefined; 7396 } 7397 } 7398 7399 if (!jQuery.isEmptyObject(orig)) { 7400 if (dataShow) { 7401 if ("hidden" in dataShow) { 7402 hidden = dataShow.hidden; 7403 } 7404 } else { 7405 dataShow = jQuery._data(elem, "fxshow", {}); 7406 } 7407 7408 // store state if its toggle - enables .stop().toggle() to "reverse" 7409 if (toggle) { 7410 dataShow.hidden = !hidden; 7411 } 7412 if (hidden) { 7413 jQuery(elem).show(); 7414 } else { 7415 anim.done(function () { 7416 jQuery(elem).hide(); 7417 }); 7418 } 7419 anim.done(function () { 7420 var prop; 7421 jQuery._removeData(elem, "fxshow"); 7422 for (prop in orig) { 7423 jQuery.style(elem, prop, orig[prop]); 7424 } 7425 }); 7426 for (prop in orig) { 7427 tween = createTween(hidden ? dataShow[prop] : 0, prop, anim); 7428 7429 if (!(prop in dataShow)) { 7430 dataShow[prop] = tween.start; 7431 if (hidden) { 7432 tween.end = tween.start; 7433 tween.start = prop === "width" || prop === "height" ? 1 : 0; 7434 } 7435 } 7436 } 7437 7438 // If this is a noop like .hide().hide(), restore an overwritten display value 7439 } else if ((display === "none" ? defaultDisplay(elem.nodeName) : dis
vendor: 5,869 bytes, lines 7439-7665
7439play) === "inline") { 7440 style.display = display; 7441 } 7442 } 7443 7444 function propFilter(props, specialEasing) { 7445 var index, name, easing, value, hooks; 7446 7447 // camelCase, specialEasing and expand cssHook pass 7448 for (index in props) { 7449 name = jQuery.camelCase(index); 7450 easing = specialEasing[name]; 7451 value = props[index]; 7452 if (jQuery.isArray(value)) { 7453 easing = value[1]; 7454 value = props[index] = value[0]; 7455 } 7456 7457 if (index !== name) { 7458 props[name] = value; 7459 delete props[index]; 7460 } 7461 7462 hooks = jQuery.cssHooks[name]; 7463 if (hooks && "expand" in hooks) { 7464 value = hooks.expand(value); 7465 delete props[name]; 7466 7467 // not quite $.extend, this wont overwrite keys already present. 7468 // also - reusing 'index' from above because we have the correct "name" 7469 for (index in value) { 7470 if (!(index in props)) { 7471 props[index] = value[index]; 7472 specialEasing[index] = easing; 7473 } 7474 } 7475 } else { 7476 specialEasing[name] = easing; 7477 } 7478 } 7479 } 7480 7481 function Animation(elem, properties, options) { 7482 var result, 7483 stopped, 7484 index = 0, 7485 length = Animation.prefilters.length, 7486 deferred = jQuery.Deferred().always(function () { 7487 7488 // don't match elem in the :animated selector 7489 delete tick.elem; 7490 }), 7491 tick = function () { 7492 if (stopped) { 7493 return false; 7494 } 7495 var currentTime = fxNow || createFxNow(), 7496 remaining = Math.max(0, animation.startTime + animation.duration - currentTime), 7497 7498 7499 // Support: Android 2.3 7500 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 7501 temp = remaining / animation.duration || 0, 7502 percent = 1 - temp, 7503 index = 0, 7504 length = animation.tweens.length; 7505 7506 for (; index < length; index++) { 7507 animation.tweens[index].run(percent); 7508 } 7509 7510 deferred.notifyWith(elem, [animation, percent, remaining]); 7511 7512 if (percent < 1 && length) { 7513 return remaining; 7514 } else { 7515 deferred.resolveWith(elem, [animation]); 7516 return false; 7517 } 7518 }, 7519 animation = deferred.promise({ 7520 elem: elem, 7521 props: jQuery.extend({}, properties), 7522 opts: jQuery.extend(true, { 7523 specialEasing: {}, 7524 easing: jQuery.easing._default 7525 }, options), 7526 originalProperties: properties, 7527 originalOptions: options, 7528 startTime: fxNow || createFxNow(), 7529 duration: options.duration, 7530 tweens: [], 7531 createTween: function (prop, end) { 7532 var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); 7533 animation.tweens.push(tween); 7534 return tween; 7535 }, 7536 stop: function (gotoEnd) { 7537 var index = 0, 7538 7539 7540 // if we are going to the end, we want to run all the tweens 7541 // otherwise we skip this part 7542 length = gotoEnd ? animation.tweens.length : 0; 7543 if (stopped) { 7544 return this; 7545 } 7546 stopped = true; 7547 for (; index < length; index++) { 7548 animation.tweens[index].run(1); 7549 } 7550 7551 // resolve when we played the last frame 7552 // otherwise, reject 7553 if (gotoEnd) { 7554 deferred.notifyWith(elem, [animation, 1, 0]); 7555 deferred.resolveWith(elem, [animation, gotoEnd]); 7556 } else { 7557 deferred.rejectWith(elem, [animation, gotoEnd]); 7558 } 7559 return this; 7560 } 7561 }), 7562 props = animation.props; 7563 7564 propFilter(props, animation.opts.specialEasing); 7565 7566 for (; index < length; index++) { 7567 result = Animation.prefilters[index].call(animation, elem, props, animation.opts); 7568 if (result) { 7569 if (jQuery.isFunction(result.stop)) { 7570 jQuery._queueHooks(animation.elem, animation.opts.queue).stop = jQuery.proxy(result.stop, result); 7571 } 7572 return result; 7573 } 7574 } 7575 7576 jQuery.map(props, createTween, animation); 7577 7578 if (jQuery.isFunction(animation.opts.start)) { 7579 animation.opts.start.call(elem, animation); 7580 } 7581 7582 jQuery.fx.timer(jQuery.extend(tick, { 7583 elem: elem, 7584 anim: animation, 7585 queue: animation.opts.queue 7586 })); 7587 7588 // attach callbacks from options 7589 return animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); 7590 } 7591 7592 jQuery.Animation = jQuery.extend(Animation, { 7593 7594 tweeners: { 7595 "*": [function (prop, value) { 7596 var tween = this.createTween(prop, value); 7597 adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); 7598 return tween; 7599 }] 7600 }, 7601 7602 tweener: function (props, callback) { 7603 if (jQuery.isFunction(props)) { 7604 callback = props; 7605 props = ["*"]; 7606 } else { 7607 props = props.match(rnotwhite); 7608 } 7609 7610 var prop, 7611 index = 0, 7612 length = props.length; 7613 7614 for (; index < length; index++) { 7615 prop = props[index]; 7616 Animation.tweeners[prop] = Animation.tweeners[prop] || []; 7617 Animation.tweeners[prop].unshift(callback); 7618 } 7619 }, 7620 7621 prefilters: [defaultPrefilter], 7622 7623 prefilter: function (callback, prepend) { 7624 if (prepend) { 7625 Animation.prefilters.unshift(callback); 7626 } else { 7627 Animation.prefilters.push(callback); 7628 } 7629 } 7630 }); 7631 7632 jQuery.speed = function (speed, easing, fn) { 7633 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { 7634 complete: fn || !fn && easing || jQuery.isFunction(speed) && speed, 7635 duration: speed, 7636 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing 7637 }; 7638 7639 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; 7640 7641 // normalize opt.queue - true/undefined/null -> "fx" 7642 if (opt.queue == null || opt.queue === true) { 7643 opt.queue = "fx"; 7644 } 7645 7646 // Queueing 7647 opt.old = opt.complete; 7648 7649 opt.complete = function () { 7650 if (jQuery.isFunction(opt.old)) { 7651 opt.old.call(this); 7652 } 7653 7654 if (opt.queue) { 7655 jQuery.dequeue(this, opt.queue); 7656 } 7657 }; 7658 7659 return opt; 7660 }; 7661 7662 jQuery.fn.extend({ 7663 fadeTo: function (speed, to, easing, callback) { 7664 7665 // show any hidden elements after setting opacity to 0
vendor: 8,995 bytes, lines 7666-8006
7666 return this.filter(isHidden).css("opacity", 0).show() 7667 7668 // animate to the value specified 7669 .end().animate({ opacity: to }, speed, easing, callback); 7670 }, 7671 animate: function (prop, speed, easing, callback) { 7672 var empty = jQuery.isEmptyObject(prop), 7673 optall = jQuery.speed(speed, easing, callback), 7674 doAnimation = function () { 7675 7676 // Operate on a copy of prop so per-property easing won't be lost 7677 var anim = Animation(this, jQuery.extend({}, prop), optall); 7678 7679 // Empty animations, or finishing resolves immediately 7680 if (empty || jQuery._data(this, "finish")) { 7681 anim.stop(true); 7682 } 7683 }; 7684 doAnimation.finish = doAnimation; 7685 7686 return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); 7687 }, 7688 stop: function (type, clearQueue, gotoEnd) { 7689 var stopQueue = function (hooks) { 7690 var stop = hooks.stop; 7691 delete hooks.stop; 7692 stop(gotoEnd); 7693 }; 7694 7695 if (typeof type !== "string") { 7696 gotoEnd = clearQueue; 7697 clearQueue = type; 7698 type = undefined; 7699 } 7700 if (clearQueue && type !== false) { 7701 this.queue(type || "fx", []); 7702 } 7703 7704 return this.each(function () { 7705 var dequeue = true, 7706 index = type != null && type + "queueHooks", 7707 timers = jQuery.timers, 7708 data = jQuery._data(this); 7709 7710 if (index) { 7711 if (data[index] && data[index].stop) { 7712 stopQueue(data[index]); 7713 } 7714 } else { 7715 for (index in data) { 7716 if (data[index] && data[index].stop && rrun.test(index)) { 7717 stopQueue(data[index]); 7718 } 7719 } 7720 } 7721 7722 for (index = timers.length; index--;) { 7723 if (timers[index].elem === this && (type == null || timers[index].queue === type)) { 7724 7725 timers[index].anim.stop(gotoEnd); 7726 dequeue = false; 7727 timers.splice(index, 1); 7728 } 7729 } 7730 7731 // start the next in the queue if the last step wasn't forced 7732 // timers currently will call their complete callbacks, which will dequeue 7733 // but only if they were gotoEnd 7734 if (dequeue || !gotoEnd) { 7735 jQuery.dequeue(this, type); 7736 } 7737 }); 7738 }, 7739 finish: function (type) { 7740 if (type !== false) { 7741 type = type || "fx"; 7742 } 7743 return this.each(function () { 7744 var index, 7745 data = jQuery._data(this), 7746 queue = data[type + "queue"], 7747 hooks = data[type + "queueHooks"], 7748 timers = jQuery.timers, 7749 length = queue ? queue.length : 0; 7750 7751 // enable finishing flag on private data 7752 data.finish = true; 7753 7754 // empty the queue first 7755 jQuery.queue(this, type, []); 7756 7757 if (hooks && hooks.stop) { 7758 hooks.stop.call(this, true); 7759 } 7760 7761 // look for any active animations, and finish them 7762 for (index = timers.length; index--;) { 7763 if (timers[index].elem === this && timers[index].queue === type) { 7764 timers[index].anim.stop(true); 7765 timers.splice(index, 1); 7766 } 7767 } 7768 7769 // look for any animations in the old queue and finish them 7770 for (index = 0; index < length; index++) { 7771 if (queue[index] && queue[index].finish) { 7772 queue[index].finish.call(this); 7773 } 7774 } 7775 7776 // turn off finishing flag 7777 delete data.finish; 7778 }); 7779 } 7780 }); 7781 7782 jQuery.each(["toggle", "show", "hide"], function (i, name) { 7783 var cssFn = jQuery.fn[name]; 7784 jQuery.fn[name] = function (speed, easing, callback) { 7785 return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); 7786 }; 7787 }); 7788 7789 // Generate shortcuts for custom animations 7790 jQuery.each({ 7791 slideDown: genFx("show"), 7792 slideUp: genFx("hide"), 7793 slideToggle: genFx("toggle"), 7794 fadeIn: { opacity: "show" }, 7795 fadeOut: { opacity: "hide" }, 7796 fadeToggle: { opacity: "toggle" } 7797 }, function (name, props) { 7798 jQuery.fn[name] = function (speed, easing, callback) { 7799 return this.animate(props, speed, easing, callback); 7800 }; 7801 }); 7802 7803 jQuery.timers = []; 7804 jQuery.fx.tick = function () { 7805 var timer, 7806 timers = jQuery.timers, 7807 i = 0; 7808 7809 fxNow = jQuery.now(); 7810 7811 for (; i < timers.length; i++) { 7812 timer = timers[i]; 7813 7814 // Checks the timer has not already been removed 7815 if (!timer() && timers[i] === timer) { 7816 timers.splice(i--, 1); 7817 } 7818 } 7819 7820 if (!timers.length) { 7821 jQuery.fx.stop(); 7822 } 7823 fxNow = undefined; 7824 }; 7825 7826 jQuery.fx.timer = function (timer) { 7827 jQuery.timers.push(timer); 7828 if (timer()) { 7829 jQuery.fx.start(); 7830 } else { 7831 jQuery.timers.pop(); 7832 } 7833 }; 7834 7835 jQuery.fx.interval = 13; 7836 7837 jQuery.fx.start = function () { 7838 if (!timerId) { 7839 timerId = window.setInterval(jQuery.fx.tick, jQuery.fx.interval); 7840 } 7841 }; 7842 7843 jQuery.fx.stop = function () { 7844 window.clearInterval(timerId); 7845 timerId = null; 7846 }; 7847 7848 jQuery.fx.speeds = { 7849 slow: 600, 7850 fast: 200, 7851 7852 // Default speed 7853 _default: 400 7854 }; 7855 7856 // Based off of the plugin by Clint Helfers, with permission. 7857 // http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 7858 jQuery.fn.delay = function (time, type) { 7859 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; 7860 type = type || "fx"; 7861 7862 return this.queue(type, function (next, hooks) { 7863 var timeout = window.setTimeout(next, time); 7864 hooks.stop = function () { 7865 window.clearTimeout(timeout); 7866 }; 7867 }); 7868 }; 7869 7870 (function () { 7871 var a, 7872 input = document.createElement("input"), 7873 div = document.createElement("div"), 7874 select = document.createElement("select"), 7875 opt = select.appendChild(document.createElement("option")); 7876 7877 // Setup 7878 div = document.createElement("div"); 7879 div.setAttribute("className", "t"); 7880 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; 7881 a = div.getElementsByTagName("a")[0]; 7882 7883 // Support: Windows Web Apps (WWA) 7884 // `type` must use .setAttribute for WWA (#14901) 7885 input.setAttribute("type", "checkbox"); 7886 div.appendChild(input); 7887 7888 a = div.getElementsByTagName("a")[0]; 7889 7890 // First batch of tests. 7891 a.style.cssText = "top:1px"; 7892 7893 // Test setAttribute on camelCase class. 7894 // If it works, we need attrFixes when doing get/setAttribute (ie6/7) 7895 support.getSetAttribute = div.className !== "t"; 7896 7897 // Get the style information from getAttribute 7898 // (IE uses .cssText instead) 7899 support.style = /top/.test(a.getAttribute("style")); 7900 7901 // Make sure that URLs aren't manipulated 7902 // (IE normalizes it by default) 7903 support.hrefNormalized = a.getAttribute("href") === "/a"; 7904 7905 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) 7906 support.checkOn = !!input.value; 7907 7908 // Make sure that a selected-by-default option has a working selected property. 7909 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) 7910 support.optSelected = opt.selected; 7911 7912 // Tests for enctype support on a form (#6743) 7913 support.enctype = !!document.createElement("form").enctype; 7914 7915 // Make sure that the options inside disabled selects aren't marked as disabled 7916 // (WebKit marks them as disabled) 7917 select.disabled = true; 7918 support.optDisabled = !opt.disabled; 7919 7920 // Support: IE8 only 7921 // Check if we can trust getAttribute("value") 7922 input = document.createElement("input"); 7923 input.setAttribute("value", ""); 7924 support.input = input.getAttribute("value") === ""; 7925 7926 // Check if an input maintains its value after becoming a radio 7927 input.value = "t"; 7928 input.setAttribute("type", "radio"); 7929 support.radioValue = input.value === "t"; 7930 })(); 7931 7932 var rreturn = /\r/g, 7933 rspaces = /[\x20\t\r\n\f]+/g; 7934 7935 jQuery.fn.extend({ 7936 val: function (value) { 7937 var hooks, 7938 ret, 7939 isFunction, 7940 elem = this[0]; 7941 7942 if (!arguments.length) { 7943 if (elem) { 7944 hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; 7945 7946 if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) { 7947 return ret; 7948 } 7949 7950 ret = elem.value; 7951 7952 return typeof ret === "string" ? 7953 7954 // handle most common string cases 7955 ret.replace(rreturn, "") : 7956 7957 // handle cases where value is null/undef or number 7958 ret == null ? "" : ret; 7959 } 7960 7961 return; 7962 } 7963 7964 isFunction = jQuery.isFunction(value); 7965 7966 return this.each(function (i) { 7967 var val; 7968 7969 if (this.nodeType !== 1) { 7970 return; 7971 } 7972 7973 if (isFunction) { 7974 val = value.call(this, i, jQuery(this).val()); 7975 } else { 7976 val = value; 7977 } 7978 7979 // Treat null/undefined as ""; convert numbers to string 7980 if (val == null) { 7981 val = ""; 7982 } else if (typeof val === "number") { 7983 val += ""; 7984 } else if (jQuery.isArray(val)) { 7985 val = jQuery.map(val, function (value) { 7986 return value == null ? "" : value + ""; 7987 }); 7988 } 7989 7990 hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; 7991 7992 // If set returns undefined, fall back to normal setting 7993 if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { 7994 this.value = val; 7995 } 7996 }); 7997 } 7998 }); 7999 8000 jQuery.extend({ 8001 valHooks: { 8002 option: { 8003 get: function (elem) { 8004 var val = jQuery.find.attr(elem, "value"); 8005 return val != null ? val : 8006
vendor: 4,966 bytes, lines 8007-8195
8007 // Support: IE10-11+ 8008 // option.text throws exceptions (#14686, #14858) 8009 // Strip and collapse whitespace 8010 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 8011 jQuery.trim(jQuery.text(elem)).replace(rspaces, " "); 8012 } 8013 }, 8014 select: { 8015 get: function (elem) { 8016 var value, 8017 option, 8018 options = elem.options, 8019 index = elem.selectedIndex, 8020 one = elem.type === "select-one" || index < 0, 8021 values = one ? null : [], 8022 max = one ? index + 1 : options.length, 8023 i = index < 0 ? max : one ? index : 0; 8024 8025 // Loop through all the selected options 8026 for (; i < max; i++) { 8027 option = options[i]; 8028 8029 // oldIE doesn't update selected after form reset (#2551) 8030 if ((option.selected || i === index) && ( 8031 8032 // Don't return options that are disabled or in a disabled optgroup 8033 support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) { 8034 8035 // Get the specific value for the option 8036 value = jQuery(option).val(); 8037 8038 // We don't need an array for one selects 8039 if (one) { 8040 return value; 8041 } 8042 8043 // Multi-Selects return an array 8044 values.push(value); 8045 } 8046 } 8047 8048 return values; 8049 }, 8050 8051 set: function (elem, value) { 8052 var optionSet, 8053 option, 8054 options = elem.options, 8055 values = jQuery.makeArray(value), 8056 i = options.length; 8057 8058 while (i--) { 8059 option = options[i]; 8060 8061 if (jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { 8062 8063 // Support: IE6 8064 // When new option element is added to select box we need to 8065 // force reflow of newly added node in order to workaround delay 8066 // of initialization properties 8067 try { 8068 option.selected = optionSet = true; 8069 } catch (_) { 8070 8071 // Will be executed only in IE6 8072 option.scrollHeight; 8073 } 8074 } else { 8075 option.selected = false; 8076 } 8077 } 8078 8079 // Force browsers to behave consistently when non-matching value is set 8080 if (!optionSet) { 8081 elem.selectedIndex = -1; 8082 } 8083 8084 return options; 8085 } 8086 } 8087 } 8088 }); 8089 8090 // Radios and checkboxes getter/setter 8091 jQuery.each(["radio", "checkbox"], function () { 8092 jQuery.valHooks[this] = { 8093 set: function (elem, value) { 8094 if (jQuery.isArray(value)) { 8095 return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; 8096 } 8097 } 8098 }; 8099 if (!support.checkOn) { 8100 jQuery.valHooks[this].get = function (elem) { 8101 return elem.getAttribute("value") === null ? "on" : elem.value; 8102 }; 8103 } 8104 }); 8105 8106 var nodeHook, 8107 boolHook, 8108 attrHandle = jQuery.expr.attrHandle, 8109 ruseDefault = /^(?:checked|selected)$/i, 8110 getSetAttribute = support.getSetAttribute, 8111 getSetInput = support.input; 8112 8113 jQuery.fn.extend({ 8114 attr: function (name, value) { 8115 return access(this, jQuery.attr, name, value, arguments.length > 1); 8116 }, 8117 8118 removeAttr: function (name) { 8119 return this.each(function () { 8120 jQuery.removeAttr(this, name); 8121 }); 8122 } 8123 }); 8124 8125 jQuery.extend({ 8126 attr: function (elem, name, value) { 8127 var ret, 8128 hooks, 8129 nType = elem.nodeType; 8130 8131 // Don't get/set attributes on text, comment and attribute nodes 8132 if (nType === 3 || nType === 8 || nType === 2) { 8133 return; 8134 } 8135 8136 // Fallback to prop when attributes are not supported 8137 if (typeof elem.getAttribute === "undefined") { 8138 return jQuery.prop(elem, name, value); 8139 } 8140 8141 // All attributes are lowercase 8142 // Grab necessary hook if one is defined 8143 if (nType !== 1 || !jQuery.isXMLDoc(elem)) { 8144 name = name.toLowerCase(); 8145 hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook); 8146 } 8147 8148 if (value !== undefined) { 8149 if (value === null) { 8150 jQuery.removeAttr(elem, name); 8151 return; 8152 } 8153 8154 if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { 8155 return ret; 8156 } 8157 8158 elem.setAttribute(name, value + ""); 8159 return value; 8160 } 8161 8162 if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { 8163 return ret; 8164 } 8165 8166 ret = jQuery.find.attr(elem, name); 8167 8168 // Non-existent attributes return null, we normalize to undefined 8169 return ret == null ? undefined : ret; 8170 }, 8171 8172 attrHooks: { 8173 type: { 8174 set: function (elem, value) { 8175 if (!support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) { 8176 8177 // Setting the type on a radio button after the value resets the value in IE8-9 8178 // Reset value to default in case type is set after value during creation 8179 var val = elem.value; 8180 elem.setAttribute("type", value); 8181 if (val) { 8182 elem.value = val; 8183 } 8184 return value; 8185 } 8186 } 8187 } 8188 }, 8189 8190 removeAttr: function (elem, value) { 8191 var name, 8192 propName, 8193 i = 0, 8194 attrNames = value && value.match(rnotwhite); 8195
vendor: 4,714 bytes, lines 8196-8359
8196 if (attrNames && elem.nodeType === 1) { 8197 while (name = attrNames[i++]) { 8198 propName = jQuery.propFix[name] || name; 8199 8200 // Boolean attributes get special treatment (#10870) 8201 if (jQuery.expr.match.bool.test(name)) { 8202 8203 // Set corresponding property to false 8204 if (getSetInput && getSetAttribute || !ruseDefault.test(name)) { 8205 elem[propName] = false; 8206 8207 // Support: IE<9 8208 // Also clear defaultChecked/defaultSelected (if appropriate) 8209 } else { 8210 elem[jQuery.camelCase("default-" + name)] = elem[propName] = false; 8211 } 8212 8213 // See #9699 for explanation of this approach (setting first, then removal) 8214 } else { 8215 jQuery.attr(elem, name, ""); 8216 } 8217 8218 elem.removeAttribute(getSetAttribute ? name : propName); 8219 } 8220 } 8221 } 8222 }); 8223 8224 // Hooks for boolean attributes 8225 boolHook = { 8226 set: function (elem, value, name) { 8227 if (value === false) { 8228 8229 // Remove boolean attributes when set to false 8230 jQuery.removeAttr(elem, name); 8231 } else if (getSetInput && getSetAttribute || !ruseDefault.test(name)) { 8232 8233 // IE<8 needs the *property* name 8234 elem.setAttribute(!getSetAttribute && jQuery.propFix[name] || name, name); 8235 } else { 8236 8237 // Support: IE<9 8238 // Use defaultChecked and defaultSelected for oldIE 8239 elem[jQuery.camelCase("default-" + name)] = elem[name] = true; 8240 } 8241 return name; 8242 } 8243 }; 8244 8245 jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { 8246 var getter = attrHandle[name] || jQuery.find.attr; 8247 8248 if (getSetInput && getSetAttribute || !ruseDefault.test(name)) { 8249 attrHandle[name] = function (elem, name, isXML) { 8250 var ret, handle; 8251 if (!isXML) { 8252 8253 // Avoid an infinite loop by temporarily removing this function from the getter 8254 handle = attrHandle[name]; 8255 attrHandle[name] = ret; 8256 ret = getter(elem, name, isXML) != null ? name.toLowerCase() : null; 8257 attrHandle[name] = handle; 8258 } 8259 return ret; 8260 }; 8261 } else { 8262 attrHandle[name] = function (elem, name, isXML) { 8263 if (!isXML) { 8264 return elem[jQuery.camelCase("default-" + name)] ? name.toLowerCase() : null; 8265 } 8266 }; 8267 } 8268 }); 8269 8270 // fix oldIE attroperties 8271 if (!getSetInput || !getSetAttribute) { 8272 jQuery.attrHooks.value = { 8273 set: function (elem, value, name) { 8274 if (jQuery.nodeName(elem, "input")) { 8275 8276 // Does not return so that setAttribute is also used 8277 elem.defaultValue = value; 8278 } else { 8279 8280 // Use nodeHook if defined (#1954); otherwise setAttribute is fine 8281 return nodeHook && nodeHook.set(elem, value, name); 8282 } 8283 } 8284 }; 8285 } 8286 8287 // IE6/7 do not support getting/setting some attributes with get/setAttribute 8288 if (!getSetAttribute) { 8289 8290 // Use this for any attribute in IE6/7 8291 // This fixes almost every IE6/7 issue 8292 nodeHook = { 8293 set: function (elem, value, name) { 8294 8295 // Set the existing or create a new attribute node 8296 var ret = elem.getAttributeNode(name); 8297 if (!ret) { 8298 elem.setAttributeNode(ret = elem.ownerDocument.createAttribute(name)); 8299 } 8300 8301 ret.value = value += ""; 8302 8303 // Break association with cloned elements by also using setAttribute (#9646) 8304 if (name === "value" || value === elem.getAttribute(name)) { 8305 return value; 8306 } 8307 } 8308 }; 8309 8310 // Some attributes are constructed with empty-string values when not defined 8311 attrHandle.id = attrHandle.name = attrHandle.coords = function (elem, name, isXML) { 8312 var ret; 8313 if (!isXML) { 8314 return (ret = elem.getAttributeNode(name)) && ret.value !== "" ? ret.value : null; 8315 } 8316 }; 8317 8318 // Fixing value retrieval on a button requires this module 8319 jQuery.valHooks.button = { 8320 get: function (elem, name) { 8321 var ret = elem.getAttributeNode(name); 8322 if (ret && ret.specified) { 8323 return ret.value; 8324 } 8325 }, 8326 set: nodeHook.set 8327 }; 8328 8329 // Set contenteditable to false on removals(#10429) 8330 // Setting to empty string throws an error as an invalid value 8331 jQuery.attrHooks.contenteditable = { 8332 set: function (elem, value, name) { 8333 nodeHook.set(elem, value === "" ? false : value, name); 8334 } 8335 }; 8336 8337 // Set width and height to auto instead of 0 on empty string( Bug #8150 ) 8338 // This is for removals 8339 jQuery.each(["width", "height"], function (i, name) { 8340 jQuery.attrHooks[name] = { 8341 set: function (elem, value) { 8342 if (value === "") { 8343 elem.setAttribute(name, "auto"); 8344 return value; 8345 } 8346 } 8347 }; 8348 }); 8349 } 8350 8351 if (!support.style) { 8352 jQuery.attrHooks.style = { 8353 get: function (elem) { 8354 8355 // Return undefined in the case of empty string 8356 // Note: IE uppercases css property names, but if we were to .toLowerCase() 8357 // .cssText, that would destroy case sensitivity in URL's, like in "background" 8358 return elem.style.cssText || undefined; 8359 },
8360 set: function (elem, value) { 8361 return elem.style.cssText = value + ""; 8362 } 8363 }; 8364 } 8365 8366 var rfocusable = /^(?:input|select|textarea|button|object)$/i, 8367 rclickable = /^(?:a|area)$/i; 8368 8369 jQuery.fn.extend({ 8370 prop: function (name, value) { 8371 return access(this, jQuery.prop, name, value, arguments.length > 1); 8372 }, 8373 8374 removeProp: function (name) { 8375 name = jQuery.propFix[name] || name; 8376 return this.each(function () { 8377 8378 // try/catch handles cases where IE balks (such as removing a property on window) 8379 try { 8380 this[name] = undefined; 8381 delete this[name]; 8382 } catch (e) {} 8383 }); 8384 } 8385 }); 8386 8387 jQuery.extend({ 8388 prop: function (elem, name, value) { 8389 var ret, 8390 hooks, 8391 nType = elem.nodeType; 8392 8393 // Don't get/set properties on text, comment and attribute nodes 8394 if (nType === 3 || nType === 8 || nType === 2) { 8395 return; 8396 } 8397 8398 if (nType !== 1 || !jQuery.isXMLDoc(elem)) { 8399 8400 // Fix name and attach hooks 8401 name = jQuery.propFix[name] || name; 8402 hooks = jQuery.propHooks[name]; 8403 } 8404 8405 if (value !== undefined) { 8406 if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { 8407 return ret; 8408 } 8409 8410 return elem[name] = value; 8411 } 8412 8413 if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { 8414 return ret; 8415 } 8416 8417 return elem[name]; 8418 }, 8419 8420 propHooks: { 8421 tabIndex: { 8422 get: function (elem) { 8423 8424 // elem.tabIndex doesn't always return the 8425 // correct value when it hasn't been explicitly set 8426 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 8427 // Use proper attribute retrieval(#12072) 8428 var tabindex = jQuery.find.attr(elem, "tabindex"); 8429 8430 return tabindex ? parseInt(tabindex, 10) : rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href ? 0 : -1; 8431 } 8432 } 8433 }, 8434 8435 propFix: { 8436 "for": "htmlFor", 8437 "class": "className" 8438 } 8439 }); 8440 8441 // Some attributes require a special call on IE 8442 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 8443 if (!support.hrefNormalized) { 8444 8445 // href/src property should get the full normalized URL (#10299/#12915) 8446 jQuery.each(["href", "src"], function (i, name) { 8447 jQuery.propHooks[name] = { 8448 get: function (elem) { 8449 return elem.getAttribute(name, 4); 8450 } 8451 }; 8452 }); 8453 } 8454 8455 // Support: Safari, IE9+ 8456 // Accessing the selectedIndex property 8457 // forces the browser to respect setting selected 8458 // on the option 8459 // The getter ensures a default option is selected 8460 // when in an optgroup 8461 if (!support.optSelected) { 8462 jQuery.propHooks.selected = { 8463 get: function (elem) { 8464 var parent = elem.parentNode; 8465 8466 if (parent) { 8467 parent.selectedIndex; 8468 8469 // Make sure that it also works with optgroups, see #5701 8470 if (parent.parentNode) { 8471 parent.parentNode.selectedIndex; 8472 } 8473 } 8474 return null; 8475 }, 8476 set: function (elem) { 8477 var parent = elem.parentNode; 8478 if (parent) { 8479 parent.selectedIndex; 8480 8481 if (parent.parentNode) { 8482 parent.parentNode.selectedIndex; 8483 } 8484 } 8485 } 8486 }; 8487 } 8488 8489 jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { 8490 jQuery.propFix[this.toLowerCase()] = this; 8491 }); 8492 8493 // IE6/7 call enctype encoding 8494 if (!support.enctype) { 8495 jQuery.propFix.enctype = "encoding"; 8496 } 8497 8498 var rclass = /[\t\r\n\f]/g; 8499 8500 function getClass(elem) { 8501 return jQuery.attr(elem, "class") || ""; 8502 } 8503 8504 jQuery.fn.extend({ 8505 addClass: function (value) { 8506 var classes, 8507 elem, 8508 cur, 8509 curValue, 8510 clazz, 8511 j, 8512 finalValue, 8513 i = 0; 8514 8515 if (jQuery.isFunction(value)) { 8516 return this.each(function (j) { 8517 jQuery(this).addClass(value.call(this, j, getClass(this))); 8518 }); 8519 } 8520 8521 if (typeof value === "string" && value) { 8522 classes = value.match(rnotwhite) || []; 8523 8524 while (elem = this[i++]) { 8525 curValue = getClass(elem); 8526 cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " "); 8527 8528 if (cur) { 8529 j = 0; 8530 while (clazz = classes[j++]) { 8531 if (cur.indexOf(" " + clazz + " ") < 0) { 8532 cur += clazz + " "; 8533 } 8534 } 8535 8536 // only assign if different to avoid unneeded rendering. 8537 finalValue = jQuery.trim(cur); 8538 if (curValue !== finalValue) { 8539 jQuery.attr(elem, "class", finalValue); 8540 } 8541 } 8542 } 8543 } 8544 8545 return this; 8546 }, 8547 8548 removeClass: function (value) { 8549 var classes, 8550 elem, 8551 cur, 8552 curValue, 8553 clazz, 8554 j, 8555 finalValue, 8556 i = 0; 8557 8558 if (jQuery.isFunction(value)) { 8559 return this.each(function (j) { 8560 jQuery(this).removeClass(value.call(this, j, getClass(this))); 8561 }); 8562 } 8563 8564 if (!arguments.length) { 8565 return this.attr("class", ""); 8566 } 8567 8568 if (typeof value === "string" && value) { 8569 classes = value.match(rnotwhite) || []; 8570 8571 while (elem = this[i++]) { 8572 curValue = getClass(elem); 8573 8574 // This expression is here for better compressibility (see addClass) 8575 cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " "); 8576 8577 if (cur) { 8578 j = 0; 8579 while (clazz = classes[j++]) { 8580
8581 // Remove *all* instances 8582 while (cur.indexOf(" " + clazz + " ") > -1) { 8583 cur = cur.replace(" " + clazz + " ", " "); 8584 } 8585 } 8586 8587 // Only assign if different to avoid unneeded rendering. 8588 finalValue = jQuery.trim(cur); 8589 if (curValue !== finalValue) { 8590 jQuery.attr(elem, "class", finalValue); 8591 } 8592 } 8593 } 8594 } 8595 8596 return this; 8597 }, 8598 8599 toggleClass: function (value, stateVal) { 8600 var type = typeof value; 8601 8602 if (typeof stateVal === "boolean" && type === "string") { 8603 return stateVal ? this.addClass(value) : this.removeClass(value); 8604 } 8605 8606 if (jQuery.isFunction(value)) { 8607 return this.each(function (i) { 8608 jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); 8609 }); 8610 } 8611 8612 return this.each(function () { 8613 var className, i, self, classNames; 8614 8615 if (type === "string") { 8616 8617 // Toggle individual class names 8618 i = 0; 8619 self = jQuery(this); 8620 classNames = value.match(rnotwhite) || []; 8621 8622 while (className = classNames[i++]) { 8623 8624 // Check each className given, space separated list 8625 if (self.hasClass(className)) { 8626 self.removeClass(className); 8627 } else { 8628 self.addClass(className); 8629 } 8630 } 8631 8632 // Toggle whole class name 8633 } else if (value === undefined || type === "boolean") { 8634 className = getClass(this); 8635 if (className) { 8636 8637 // store className if set 8638 jQuery._data(this, "__className__", className); 8639 } 8640 8641 // If the element has a class name or if we're passed "false", 8642 // then remove the whole classname (if there was one, the above saved it). 8643 // Otherwise bring back whatever was previously saved (if anything), 8644 // falling back to the empty string if nothing was stored. 8645 jQuery.attr(this, "class", className || value === false ? "" : jQuery._data(this, "__className__") || ""); 8646 } 8647 }); 8648 }, 8649 8650 hasClass: function (selector) { 8651 var className, 8652 elem, 8653 i = 0; 8654 8655 className = " " + selector + " "; 8656 while (elem = this[i++]) { 8657 if (elem.nodeType === 1 && (" " + getClass(elem) + " ").replace(rclass, " ").indexOf(className) > -1) { 8658 return true; 8659 } 8660 } 8661 8662 return false; 8663 } 8664 }); 8665 8666 // Return jQuery for attributes-only inclusion 8667 8668 8669 jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function (i, name) { 8670 8671 // Handle event binding 8672 jQuery.fn[name] = function (data, fn) { 8673 return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name); 8674 }; 8675 }); 8676 8677 jQuery.fn.extend({ 8678 hover: function (fnOver, fnOut) { 8679 return this.mouseenter(fnOver).mouseleave(fnOut || fnOver); 8680 } 8681 }); 8682 8683 var location = window.location; 8684 8685 var nonce = jQuery.now(); 8686 8687 var rquery = /\?/; 8688 8689 var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; 8690 8691 jQuery.parseJSON = function (data) { 8692 8693 // Attempt to parse using the native JSON parser first 8694 if (window.JSON && window.JSON.parse) { 8695 8696 // Support: Android 2.3 8697 // Workaround failure to string-cast null input 8698 return window.JSON.parse(data + ""); 8699 } 8700 8701 var requireNonComma, 8702 depth = null, 8703 str = jQuery.trim(data + ""); 8704 8705 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains 8706 // after removing valid tokens 8707 return str && !jQuery.trim(str.replace(rvalidtokens, function (token, comma, open, close) { 8708 8709 // Force termination if we see a misplaced comma 8710 if (requireNonComma && comma) { 8711 depth = 0; 8712 } 8713 8714 // Perform no more replacements after returning to outermost depth 8715 if (depth === 0) { 8716 return token; 8717 } 8718 8719 // Commas must not follow "[", "{", or "," 8720 requireNonComma = open || comma; 8721 8722 // Determine new depth 8723 // array/object open ("[" or "{"): depth += true - false (increment) 8724 // array/object close ("]" or "}"): depth += false - true (decrement) 8725 // other cases ("," or primitive): depth += true - true (numeric cast) 8726 depth += !close - !open; 8727 8728 // Remove this token 8729 return ""; 8730 })) ? Function("return " + str)() : jQuery.error("Invalid JSON: " + data); 8731 }; 8732 8733 // Cross-browser xml parsing 8734 jQuery.parseXML = function (data) { 8735 var xml, tmp; 8736 if (!data || typeof data !== "string") { 8737 return null; 8738 } 8739 try { 8740 if (window.DOMParser) { 8741 // Standard 8742 tmp = new window.DOMParser(); 8743 xml = tmp.parseFromString(data, "text/xml"); 8744 } else { 8745 // IE 8746 xml = new window.ActiveXObject("Microsoft.XMLDOM"); 8747 xml.async = "false"; 8748 xml.loadXML(data); 8749 } 8750 } catch (e) { 8751 xml = undefined; 8752 } 8753 if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) { 8754 jQuery.error("Invalid XML: " + data); 8755 } 8756 return xml; 8757 }; 8758 8759 var rhash = /#.*$/, 8760 rts = /([?&])_=[^&]*/, 8761 8762 8763 // IE leaves an \r character at EOL 8764 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, 8765 8766
vendor: 13,733 bytes, lines 8767-9311
8767 // #7653, #8125, #8152: local protocol detection 8768 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 8769 rnoContent = /^(?:GET|HEAD)$/, 8770 rprotocol = /^\/\//, 8771 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, 8772 8773 8774 /* Prefilters 8775 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 8776 * 2) These are called: 8777 * - BEFORE asking for a transport 8778 * - AFTER param serialization (s.data is a string if s.processData is true) 8779 * 3) key is the dataType 8780 * 4) the catchall symbol "*" can be used 8781 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 8782 */ 8783 prefilters = {}, 8784 8785 8786 /* Transports bindings 8787 * 1) key is the dataType 8788 * 2) the catchall symbol "*" can be used 8789 * 3) selection will start with transport dataType and THEN go to "*" if needed 8790 */ 8791 transports = {}, 8792 8793 8794 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 8795 allTypes = "*/".concat("*"), 8796 8797 8798 // Document location 8799 ajaxLocation = location.href, 8800 8801 8802 // Segment location into parts 8803 ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || []; 8804 8805 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 8806 function addToPrefiltersOrTransports(structure) { 8807 8808 // dataTypeExpression is optional and defaults to "*" 8809 return function (dataTypeExpression, func) { 8810 8811 if (typeof dataTypeExpression !== "string") { 8812 func = dataTypeExpression; 8813 dataTypeExpression = "*"; 8814 } 8815 8816 var dataType, 8817 i = 0, 8818 dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || []; 8819 8820 if (jQuery.isFunction(func)) { 8821 8822 // For each dataType in the dataTypeExpression 8823 while (dataType = dataTypes[i++]) { 8824 8825 // Prepend if requested 8826 if (dataType.charAt(0) === "+") { 8827 dataType = dataType.slice(1) || "*"; 8828 (structure[dataType] = structure[dataType] || []).unshift(func); 8829 8830 // Otherwise append 8831 } else { 8832 (structure[dataType] = structure[dataType] || []).push(func); 8833 } 8834 } 8835 } 8836 }; 8837 } 8838 8839 // Base inspection function for prefilters and transports 8840 function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { 8841 8842 var inspected = {}, 8843 seekingTransport = structure === transports; 8844 8845 function inspect(dataType) { 8846 var selected; 8847 inspected[dataType] = true; 8848 jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { 8849 var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); 8850 if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) { 8851 8852 options.dataTypes.unshift(dataTypeOrTransport); 8853 inspect(dataTypeOrTransport); 8854 return false; 8855 } else if (seekingTransport) { 8856 return !(selected = dataTypeOrTransport); 8857 } 8858 }); 8859 return selected; 8860 } 8861 8862 return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*"); 8863 } 8864 8865 // A special extend for ajax options 8866 // that takes "flat" options (not to be deep extended) 8867 // Fixes #9887 8868 function ajaxExtend(target, src) { 8869 var deep, 8870 key, 8871 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 8872 8873 for (key in src) { 8874 if (src[key] !== undefined) { 8875 (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; 8876 } 8877 } 8878 if (deep) { 8879 jQuery.extend(true, target, deep); 8880 } 8881 8882 return target; 8883 } 8884 8885 /* Handles responses to an ajax request: 8886 * - finds the right dataType (mediates between content-type and expected dataType) 8887 * - returns the corresponding response 8888 */ 8889 function ajaxHandleResponses(s, jqXHR, responses) { 8890 var firstDataType, 8891 ct, 8892 finalDataType, 8893 type, 8894 contents = s.contents, 8895 dataTypes = s.dataTypes; 8896 8897 // Remove auto dataType and get content-type in the process 8898 while (dataTypes[0] === "*") { 8899 dataTypes.shift(); 8900 if (ct === undefined) { 8901 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); 8902 } 8903 } 8904 8905 // Check if we're dealing with a known content-type 8906 if (ct) { 8907 for (type in contents) { 8908 if (contents[type] && contents[type].test(ct)) { 8909 dataTypes.unshift(type); 8910 break; 8911 } 8912 } 8913 } 8914 8915 // Check to see if we have a response for the expected dataType 8916 if (dataTypes[0] in responses) { 8917 finalDataType = dataTypes[0]; 8918 } else { 8919 8920 // Try convertible dataTypes 8921 for (type in responses) { 8922 if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) { 8923 finalDataType = type; 8924 break; 8925 } 8926 if (!firstDataType) { 8927 firstDataType = type; 8928 } 8929 } 8930 8931 // Or just use first one 8932 finalDataType = finalDataType || firstDataType; 8933 } 8934 8935 // If we found a dataType 8936 // We add the dataType to the list if needed 8937 // and return the corresponding response 8938 if (finalDataType) { 8939 if (finalDataType !== dataTypes[0]) { 8940 dataTypes.unshift(finalDataType); 8941 } 8942 return responses[finalDataType]; 8943 } 8944 } 8945 8946 /* Chain conversions given the request and the original response 8947 * Also sets the responseXXX fields on the jqXHR instance 8948 */ 8949 function ajaxConvert(s, response, jqXHR, isSuccess) { 8950 var conv2, 8951 current, 8952 conv, 8953 tmp, 8954 prev, 8955 converters = {}, 8956 8957 8958 // Work with a copy of dataTypes in case we need to modify it for conversion 8959 dataTypes = s.dataTypes.slice(); 8960 8961 // Create converters map with lowercased keys 8962 if (dataTypes[1]) { 8963 for (conv in s.converters) { 8964 converters[conv.toLowerCase()] = s.converters[conv]; 8965 } 8966 } 8967 8968 current = dataTypes.shift(); 8969 8970 // Convert to each sequential dataType 8971 while (current) { 8972 8973 if (s.responseFields[current]) { 8974 jqXHR[s.responseFields[current]] = response; 8975 } 8976 8977 // Apply the dataFilter if provided 8978 if (!prev && isSuccess && s.dataFilter) { 8979 response = s.dataFilter(response, s.dataType); 8980 } 8981 8982 prev = current; 8983 current = dataTypes.shift(); 8984 8985 if (current) { 8986 8987 // There's only work to do if current dataType is non-auto 8988 if (current === "*") { 8989 8990 current = prev; 8991 8992 // Convert response if prev dataType is non-auto and differs from current 8993 } else if (prev !== "*" && prev !== current) { 8994 8995 // Seek a direct converter 8996 conv = converters[prev + " " + current] || converters["* " + current]; 8997 8998 // If none found, seek a pair 8999 if (!conv) { 9000 for (conv2 in converters) { 9001 9002 // If conv2 outputs current 9003 tmp = conv2.split(" "); 9004 if (tmp[1] === current) { 9005 9006 // If prev can be converted to accepted input 9007 conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]]; 9008 if (conv) { 9009 9010 // Condense equivalence converters 9011 if (conv === true) { 9012 conv = converters[conv2]; 9013 9014 // Otherwise, insert the intermediate dataType 9015 } else if (converters[conv2] !== true) { 9016 current = tmp[0]; 9017 dataTypes.unshift(tmp[1]); 9018 } 9019 break; 9020 } 9021 } 9022 } 9023 } 9024 9025 // Apply converter (if not an equivalence) 9026 if (conv !== true) { 9027 9028 // Unless errors are allowed to bubble, catch and return them 9029 if (conv && s["throws"]) { 9030 // jscs:ignore requireDotNotation 9031 response = conv(response); 9032 } else { 9033 try { 9034 response = conv(response); 9035 } catch (e) { 9036 return { 9037 state: "parsererror", 9038 error: conv ? e : "No conversion from " + prev + " to " + current 9039 }; 9040 } 9041 } 9042 } 9043 } 9044 } 9045 } 9046 9047 return { state: "success", data: response }; 9048 } 9049 9050 jQuery.extend({ 9051 9052 // Counter for holding the number of active queries 9053 active: 0, 9054 9055 // Last-Modified header cache for next request 9056 lastModified: {}, 9057 etag: {}, 9058 9059 ajaxSettings: { 9060 url: ajaxLocation, 9061 type: "GET", 9062 isLocal: rlocalProtocol.test(ajaxLocParts[1]), 9063 global: true, 9064 processData: true, 9065 async: true, 9066 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 9067 /* 9068 timeout: 0, 9069 data: null, 9070 dataType: null, 9071 username: null, 9072 password: null, 9073 cache: null, 9074 throws: false, 9075 traditional: false, 9076 headers: {}, 9077 */ 9078 9079 accepts: { 9080 "*": allTypes, 9081 text: "text/plain", 9082 html: "text/html", 9083 xml: "application/xml, text/xml", 9084 json: "application/json, text/javascript" 9085 }, 9086 9087 contents: { 9088 xml: /\bxml\b/, 9089 html: /\bhtml/, 9090 json: /\bjson\b/ 9091 }, 9092 9093 responseFields: { 9094 xml: "responseXML", 9095 text: "responseText", 9096 json: "responseJSON" 9097 }, 9098 9099 // Data converters 9100 // Keys separate source (or catchall "*") and destination types with a single space 9101 converters: { 9102 9103 // Convert anything to text 9104 "* text": String, 9105 9106 // Text to html (true = no transformation) 9107 "text html": true, 9108 9109 // Evaluate text as a json expression 9110 "text json": jQuery.parseJSON, 9111 9112 // Parse text as xml 9113 "text xml": jQuery.parseXML 9114 }, 9115 9116 // For options that shouldn't be deep extended: 9117 // you can add your own custom options here if 9118 // and when you create one that shouldn't be 9119 // deep extended (see ajaxExtend) 9120 flatOptions: { 9121 url: true, 9122 context: true 9123 } 9124 }, 9125 9126 // Creates a full fledged settings object into target 9127 // with both ajaxSettings and settings fields. 9128 // If target is omitted, writes into ajaxSettings. 9129 ajaxSetup: function (target, settings) { 9130 return settings ? 9131 9132 // Building a settings object 9133 ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : 9134 9135 // Extending ajaxSettings 9136 ajaxExtend(jQuery.ajaxSettings, target); 9137 }, 9138 9139 ajaxPrefilter: addToPrefiltersOrTransports(prefilters), 9140 ajaxTransport: addToPrefiltersOrTransports(transports), 9141 9142 // Main method 9143 ajax: function (url, options) { 9144 9145 // If url is an object, simulate pre-1.5 signature 9146 if (typeof url === "object") { 9147 options = url; 9148 url = undefined; 9149 } 9150 9151 // Force options to be an object 9152 options = options || {}; 9153 9154 var 9155 9156 // Cross-domain detection vars 9157 parts, 9158 9159 9160 // Loop variable 9161 i, 9162 9163 9164 // URL without anti-cache param 9165 cacheURL, 9166 9167 9168 // Response headers as string 9169 responseHeadersString, 9170 9171 9172 // timeout handle 9173 timeoutTimer, 9174 9175 9176 // To know if global events are to be dispatched 9177 fireGlobals, 9178 transport, 9179 9180 9181 // Response headers 9182 responseHeaders, 9183 9184 9185 // Create the final options object 9186 s = jQuery.ajaxSetup({}, options), 9187 9188 9189 // Callbacks context 9190 callbackContext = s.context || s, 9191 9192 9193 // Context for global events is callbackContext if it is a DOM node or jQuery collection 9194 globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, 9195 9196 9197 // Deferreds 9198 deferred = jQuery.Deferred(), 9199 completeDeferred = jQuery.Callbacks("once memory"), 9200 9201 9202 // Status-dependent callbacks 9203 statusCode = s.statusCode || {}, 9204 9205 9206 // Headers (they are sent all at once) 9207 requestHeaders = {}, 9208 requestHeadersNames = {}, 9209 9210 9211 // The jqXHR state 9212 state = 0, 9213 9214 9215 // Default abort message 9216 strAbort = "canceled", 9217 9218 9219 // Fake xhr 9220 jqXHR = { 9221 readyState: 0, 9222 9223 // Builds headers hashtable if needed 9224 getResponseHeader: function (key) { 9225 var match; 9226 if (state === 2) { 9227 if (!responseHeaders) { 9228 responseHeaders = {}; 9229 while (match = rheaders.exec(responseHeadersString)) { 9230 responseHeaders[match[1].toLowerCase()] = match[2]; 9231 } 9232 } 9233 match = responseHeaders[key.toLowerCase()]; 9234 } 9235 return match == null ? null : match; 9236 }, 9237 9238 // Raw string 9239 getAllResponseHeaders: function () { 9240 return state === 2 ? responseHeadersString : null; 9241 }, 9242 9243 // Caches the header 9244 setRequestHeader: function (name, value) { 9245 var lname = name.toLowerCase(); 9246 if (!state) { 9247 name = requestHeadersNames[lname] = requestHeadersNames[lname] || name; 9248 requestHeaders[name] = value; 9249 } 9250 return this; 9251 }, 9252 9253 // Overrides response content-type header 9254 overrideMimeType: function (type) { 9255 if (!state) { 9256 s.mimeType = type; 9257 } 9258 return this; 9259 }, 9260 9261 // Status-dependent callbacks 9262 statusCode: function (map) { 9263 var code; 9264 if (map) { 9265 if (state < 2) { 9266 for (code in map) { 9267 9268 // Lazy-add the new callback in a way that preserves old ones 9269 statusCode[code] = [statusCode[code], map[code]]; 9270 } 9271 } else { 9272 9273 // Execute the appropriate callbacks 9274 jqXHR.always(map[jqXHR.status]); 9275 } 9276 } 9277 return this; 9278 }, 9279 9280 // Cancel the request 9281 abort: function (statusText) { 9282 var finalText = statusText || strAbort; 9283 if (transport) { 9284 transport.abort(finalText); 9285 } 9286 done(0, finalText); 9287 return this; 9288 } 9289 }; 9290 9291 // Attach deferreds 9292 deferred.promise(jqXHR).complete = completeDeferred.add; 9293 jqXHR.success = jqXHR.done; 9294 jqXHR.error = jqXHR.fail; 9295 9296 // Remove hash character (#7531: and string promotion) 9297 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) 9298 // Handle falsy url in the settings object (#10093: consistency with old signature) 9299 // We also use the url parameter if available 9300 s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "").replace(rprotocol, ajaxLocParts[1] + "//"); 9301 9302 // Alias method option to type as per ticket #12004 9303 s.type = options.method || options.type || s.method || s.type; 9304 9305 // Extract dataTypes list 9306 s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""]; 9307 9308 // A cross-domain request is in order when we have a protocol:host:port mismatch 9309 if (s.crossDomain == null) { 9310 parts = rurl.exec(s.url.toLowerCase()); 9311 s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80" : "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443")))
vendor: 9,321 bytes, lines 9311-9682
9311); 9312 } 9313 9314 // Convert data if not already a string 9315 if (s.data && s.processData && typeof s.data !== "string") { 9316 s.data = jQuery.param(s.data, s.traditional); 9317 } 9318 9319 // Apply prefilters 9320 inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); 9321 9322 // If request was aborted inside a prefilter, stop there 9323 if (state === 2) { 9324 return jqXHR; 9325 } 9326 9327 // We can fire global events as of now if asked to 9328 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 9329 fireGlobals = jQuery.event && s.global; 9330 9331 // Watch for a new set of requests 9332 if (fireGlobals && jQuery.active++ === 0) { 9333 jQuery.event.trigger("ajaxStart"); 9334 } 9335 9336 // Uppercase the type 9337 s.type = s.type.toUpperCase(); 9338 9339 // Determine if request has content 9340 s.hasContent = !rnoContent.test(s.type); 9341 9342 // Save the URL in case we're toying with the If-Modified-Since 9343 // and/or If-None-Match header later on 9344 cacheURL = s.url; 9345 9346 // More options handling for requests with no content 9347 if (!s.hasContent) { 9348 9349 // If data is available, append data to url 9350 if (s.data) { 9351 cacheURL = s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data; 9352 9353 // #9682: remove data so that it's not used in an eventual retry 9354 delete s.data; 9355 } 9356 9357 // Add anti-cache in url if needed 9358 if (s.cache === false) { 9359 s.url = rts.test(cacheURL) ? 9360 9361 // If there is already a '_' parameter, set its value 9362 cacheURL.replace(rts, "$1_=" + nonce++) : 9363 9364 // Otherwise add one to the end 9365 cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++; 9366 } 9367 } 9368 9369 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9370 if (s.ifModified) { 9371 if (jQuery.lastModified[cacheURL]) { 9372 jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]); 9373 } 9374 if (jQuery.etag[cacheURL]) { 9375 jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]); 9376 } 9377 } 9378 9379 // Set the correct header, if data is being sent 9380 if (s.data && s.hasContent && s.contentType !== false || options.contentType) { 9381 jqXHR.setRequestHeader("Content-Type", s.contentType); 9382 } 9383 9384 // Set the Accepts header for the server, depending on the dataType 9385 jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]); 9386 9387 // Check for headers option 9388 for (i in s.headers) { 9389 jqXHR.setRequestHeader(i, s.headers[i]); 9390 } 9391 9392 // Allow custom headers/mimetypes and early abort 9393 if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) { 9394 9395 // Abort if not done already and return 9396 return jqXHR.abort(); 9397 } 9398 9399 // aborting is no longer a cancellation 9400 strAbort = "abort"; 9401 9402 // Install callbacks on deferreds 9403 for (i in { success: 1, error: 1, complete: 1 }) { 9404 jqXHR[i](s[i]); 9405 } 9406 9407 // Get transport 9408 transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); 9409 9410 // If no transport, we auto-abort 9411 if (!transport) { 9412 done(-1, "No Transport"); 9413 } else { 9414 jqXHR.readyState = 1; 9415 9416 // Send global event 9417 if (fireGlobals) { 9418 globalEventContext.trigger("ajaxSend", [jqXHR, s]); 9419 } 9420 9421 // If request was aborted inside ajaxSend, stop there 9422 if (state === 2) { 9423 return jqXHR; 9424 } 9425 9426 // Timeout 9427 if (s.async && s.timeout > 0) { 9428 timeoutTimer = window.setTimeout(function () { 9429 jqXHR.abort("timeout"); 9430 }, s.timeout); 9431 } 9432 9433 try { 9434 state = 1; 9435 transport.send(requestHeaders, done); 9436 } catch (e) { 9437 9438 // Propagate exception as error if not done 9439 if (state < 2) { 9440 done(-1, e); 9441 9442 // Simply rethrow otherwise 9443 } else { 9444 throw e; 9445 } 9446 } 9447 } 9448 9449 // Callback for when everything is done 9450 function done(status, nativeStatusText, responses, headers) { 9451 var isSuccess, 9452 success, 9453 error, 9454 response, 9455 modified, 9456 statusText = nativeStatusText; 9457 9458 // Called once 9459 if (state === 2) { 9460 return; 9461 } 9462 9463 // State is "done" now 9464 state = 2; 9465 9466 // Clear timeout if it exists 9467 if (timeoutTimer) { 9468 window.clearTimeout(timeoutTimer); 9469 } 9470 9471 // Dereference transport for early garbage collection 9472 // (no matter how long the jqXHR object will be used) 9473 transport = undefined; 9474 9475 // Cache response headers 9476 responseHeadersString = headers || ""; 9477 9478 // Set readyState 9479 jqXHR.readyState = status > 0 ? 4 : 0; 9480 9481 // Determine if successful 9482 isSuccess = status >= 200 && status < 300 || status === 304; 9483 9484 // Get response data 9485 if (responses) { 9486 response = ajaxHandleResponses(s, jqXHR, responses); 9487 } 9488 9489 // Convert no matter what (that way responseXXX fields are always set) 9490 response = ajaxConvert(s, response, jqXHR, isSuccess); 9491 9492 // If successful, handle type chaining 9493 if (isSuccess) { 9494 9495 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 9496 if (s.ifModified) { 9497 modified = jqXHR.getResponseHeader("Last-Modified"); 9498 if (modified) { 9499 jQuery.lastModified[cacheURL] = modified; 9500 } 9501 modified = jqXHR.getResponseHeader("etag"); 9502 if (modified) { 9503 jQuery.etag[cacheURL] = modified; 9504 } 9505 } 9506 9507 // if no content 9508 if (status === 204 || s.type === "HEAD") { 9509 statusText = "nocontent"; 9510 9511 // if not modified 9512 } else if (status === 304) { 9513 statusText = "notmodified"; 9514 9515 // If we have data, let's convert it 9516 } else { 9517 statusText = response.state; 9518 success = response.data; 9519 error = response.error; 9520 isSuccess = !error; 9521 } 9522 } else { 9523 9524 // We extract error from statusText 9525 // then normalize statusText and status for non-aborts 9526 error = statusText; 9527 if (status || !statusText) { 9528 statusText = "error"; 9529 if (status < 0) { 9530 status = 0; 9531 } 9532 } 9533 } 9534 9535 // Set data for the fake xhr object 9536 jqXHR.status = status; 9537 jqXHR.statusText = (nativeStatusText || statusText) + ""; 9538 9539 // Success/Error 9540 if (isSuccess) { 9541 deferred.resolveWith(callbackContext, [success, statusText, jqXHR]); 9542 } else { 9543 deferred.rejectWith(callbackContext, [jqXHR, statusText, error]); 9544 } 9545 9546 // Status-dependent callbacks 9547 jqXHR.statusCode(statusCode); 9548 statusCode = undefined; 9549 9550 if (fireGlobals) { 9551 globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]); 9552 } 9553 9554 // Complete 9555 completeDeferred.fireWith(callbackContext, [jqXHR, statusText]); 9556 9557 if (fireGlobals) { 9558 globalEventContext.trigger("ajaxComplete", [jqXHR, s]); 9559 9560 // Handle the global AJAX counter 9561 if (! --jQuery.active) { 9562 jQuery.event.trigger("ajaxStop"); 9563 } 9564 } 9565 } 9566 9567 return jqXHR; 9568 }, 9569 9570 getJSON: function (url, data, callback) { 9571 return jQuery.get(url, data, callback, "json"); 9572 }, 9573 9574 getScript: function (url, callback) { 9575 return jQuery.get(url, undefined, callback, "script"); 9576 } 9577 }); 9578 9579 jQuery.each(["get", "post"], function (i, method) { 9580 jQuery[method] = function (url, data, callback, type) { 9581 9582 // shift arguments if data argument was omitted 9583 if (jQuery.isFunction(data)) { 9584 type = type || callback; 9585 callback = data; 9586 data = undefined; 9587 } 9588 9589 // The url can be an options object (which then must have .url) 9590 return jQuery.ajax(jQuery.extend({ 9591 url: url, 9592 type: method, 9593 dataType: type, 9594 data: data, 9595 success: callback 9596 }, jQuery.isPlainObject(url) && url)); 9597 }; 9598 }); 9599 9600 jQuery._evalUrl = function (url) { 9601 return jQuery.ajax({ 9602 url: url, 9603 9604 // Make this explicit, since user can override this through ajaxSetup (#11264) 9605 type: "GET", 9606 dataType: "script", 9607 cache: true, 9608 async: false, 9609 global: false, 9610 "throws": true 9611 }); 9612 }; 9613 9614 jQuery.fn.extend({ 9615 wrapAll: function (html) { 9616 if (jQuery.isFunction(html)) { 9617 return this.each(function (i) { 9618 jQuery(this).wrapAll(html.call(this, i)); 9619 }); 9620 } 9621 9622 if (this[0]) { 9623 9624 // The elements to wrap the target around 9625 var wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); 9626 9627 if (this[0].parentNode) { 9628 wrap.insertBefore(this[0]); 9629 } 9630 9631 wrap.map(function () { 9632 var elem = this; 9633 9634 while (elem.firstChild && elem.firstChild.nodeType === 1) { 9635 elem = elem.firstChild; 9636 } 9637 9638 return elem; 9639 }).append(this); 9640 } 9641 9642 return this; 9643 }, 9644 9645 wrapInner: function (html) { 9646 if (jQuery.isFunction(html)) { 9647 return this.each(function (i) { 9648 jQuery(this).wrapInner(html.call(this, i)); 9649 }); 9650 } 9651 9652 return this.each(function () { 9653 var self = jQuery(this), 9654 contents = self.contents(); 9655 9656 if (contents.length) { 9657 contents.wrapAll(html); 9658 } else { 9659 self.append(html); 9660 } 9661 }); 9662 }, 9663 9664 wrap: function (html) { 9665 var isFunction = jQuery.isFunction(html); 9666 9667 return this.each(function (i) { 9668 jQuery(this).wrapAll(isFunction ? html.call(this, i) : html); 9669 }); 9670 }, 9671 9672 unwrap: function () { 9673 return this.parent().each(function () { 9674 if (!jQuery.nodeName(this, "body")) { 9675 jQuery(this).replaceWith(this.childNodes); 9676 } 9677 }).end(); 9678 } 9679 }); 9680 9681 function getDisplay(elem) { 9682 return elem.style && elem.style.display || jQuery.css(elem, "dis
9682play"); 9683 } 9684 9685 function filterHidden(elem) { 9686 9687 // Disconnected elements are considered hidden 9688 if (!jQuery.contains(elem.ownerDocument || document, elem)) { 9689 return true; 9690 } 9691 while (elem && elem.nodeType === 1) { 9692 if (getDisplay(elem) === "none" || elem.type === "hidden") { 9693 return true; 9694 } 9695 elem = elem.parentNode; 9696 } 9697 return false; 9698 } 9699 9700 jQuery.expr.filters.hidden = function (elem) { 9701 9702 // Support: Opera <= 12.12 9703 // Opera reports offsetWidths and offsetHeights less than zero on some elements 9704 return support.reliableHiddenOffsets() ? elem.offsetWidth <= 0 && elem.offsetHeight <= 0 && !elem.getClientRects().length : filterHidden(elem); 9705 }; 9706 9707 jQuery.expr.filters.visible = function (elem) { 9708 return !jQuery.expr.filters.hidden(elem); 9709 }; 9710 9711 var r20 = /%20/g, 9712 rbracket = /\[\]$/, 9713 rCRLF = /\r?\n/g, 9714 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 9715 rsubmittable = /^(?:input|select|textarea|keygen)/i; 9716 9717 function buildParams(prefix, obj, traditional, add) { 9718 var name; 9719 9720 if (jQuery.isArray(obj)) { 9721 9722 // Serialize array item. 9723 jQuery.each(obj, function (i, v) { 9724 if (traditional || rbracket.test(prefix)) { 9725 9726 // Treat each array item as a scalar. 9727 add(prefix, v); 9728 } else { 9729 9730 // Item is non-scalar (array or object), encode its numeric index. 9731 buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add); 9732 } 9733 }); 9734 } else if (!traditional && jQuery.type(obj) === "object") { 9735 9736 // Serialize object item. 9737 for (name in obj) { 9738 buildParams(prefix + "[" + name + "]", obj[name], traditional, add); 9739 } 9740 } else { 9741 9742 // Serialize scalar item. 9743 add(prefix, obj); 9744 } 9745 } 9746 9747 // Serialize an array of form elements or a set of 9748 // key/values into a query string 9749 jQuery.param = function (a, traditional) { 9750 var prefix, 9751 s = [], 9752 add = function (key, value) { 9753 9754 // If value is a function, invoke it and return its value 9755 value = jQuery.isFunction(value) ? value() : value == null ? "" : value; 9756 s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value); 9757 }; 9758 9759 // Set traditional to true for jQuery <= 1.3.2 behavior. 9760 if (traditional === undefined) { 9761 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; 9762 } 9763 9764 // If an array was passed in, assume that it is an array of form elements. 9765 if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { 9766 9767 // Serialize the form elements 9768 jQuery.each(a, function () { 9769 add(this.name, this.value); 9770 }); 9771 } else { 9772 9773 // If traditional, encode the "old" way (the way 1.3.2 or older 9774 // did it), otherwise encode params recursively. 9775 for (prefix in a) { 9776 buildParams(prefix, a[prefix], traditional, add); 9777 } 9778 } 9779 9780 // Return the resulting serialization 9781 return s.join("&").replace(r20, "+"); 9782 }; 9783 9784 jQuery.fn.extend({ 9785 serialize: function () { 9786 return jQuery.param(this.serializeArray()); 9787 }, 9788 serializeArray: function () { 9789 return this.map(function () { 9790 9791 // Can add propHook for "elements" to filter or add form elements 9792 var elements = jQuery.prop(this, "elements"); 9793 return elements ? jQuery.makeArray(elements) : this; 9794 }).filter(function () { 9795 var type = this.type; 9796 9797 // Use .is(":disabled") so that fieldset[disabled] works 9798 return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); 9799 }).map(function (i, elem) { 9800 var val = jQuery(this).val(); 9801 9802 return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val) { 9803 return { name: elem.name, value: val.replace(rCRLF, "\r\n") }; 9804 }) : { name: elem.name, value: val.replace(rCRLF, "\r\n") }; 9805 }).get(); 9806 } 9807 }); 9808 9809 // Create the request object 9810 // (This is still attached to ajaxSettings for backward compatibility) 9811 jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ? 9812 9813 // Support: IE6-IE8 9814 function () { 9815 9816 // XHR cannot access local files, always use ActiveX for that case 9817 if (this.isLocal) { 9818 return createActiveXHR(); 9819 } 9820
9821 // Support: IE 9-11 9822 // IE seems to error on cross-domain PATCH requests when ActiveX XHR 9823 // is used. In IE 9+ always use the native XHR. 9824 // Note: this condition won't catch Edge as it doesn't define 9825 // document.documentMode but it also doesn't support ActiveX so it won't 9826 // reach this code. 9827 if (document.documentMode > 8) { 9828 return createStandardXHR(); 9829 } 9830 9831 // Support: IE<9 9832 // oldIE XHR does not support non-RFC2616 methods (#13240) 9833 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx 9834 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 9835 // Although this check for six methods instead of eight 9836 // since IE also does not support "trace" and "connect" 9837 return (/^(get|post|head|put|delete|options)$/i.test(this.type) && createStandardXHR() || createActiveXHR() 9838 ); 9839 } : 9840 9841 // For all other browsers, use the standard XMLHttpRequest object 9842 createStandardXHR; 9843 9844 var xhrId = 0, 9845 xhrCallbacks = {}, 9846 xhrSupported = jQuery.ajaxSettings.xhr(); 9847 9848 // Support: IE<10 9849 // Open requests must be manually aborted on unload (#5280) 9850 // See https://support.microsoft.com/kb/2856746 for more info 9851 if (window.attachEvent) { 9852 window.attachEvent("onunload", function () { 9853 for (var key in xhrCallbacks) { 9854 xhrCallbacks[key](undefined, true); 9855 } 9856 }); 9857 } 9858 9859 // Determine support properties 9860 support.cors = !!xhrSupported && "withCredentials" in xhrSupported; 9861 xhrSupported = support.ajax = !!xhrSupported; 9862 9863 // Create transport if the browser can provide an xhr 9864 if (xhrSupported) { 9865 9866 jQuery.ajaxTransport(function (options) { 9867 9868 // Cross domain only allowed if supported through XMLHttpRequest 9869 if (!options.crossDomain || support.cors) { 9870 9871 var callback; 9872 9873 return { 9874 send: function (headers, complete) { 9875 var i, 9876 xhr = options.xhr(), 9877 id = ++xhrId; 9878 9879 // Open the socket 9880 xhr.open(options.type, options.url, options.async, options.username, options.password); 9881 9882 // Apply custom fields if provided 9883 if (options.xhrFields) { 9884 for (i in options.xhrFields) { 9885 xhr[i] = options.xhrFields[i]; 9886 } 9887 } 9888 9889 // Override mime type if needed 9890 if (options.mimeType && xhr.overrideMimeType) { 9891 xhr.overrideMimeType(options.mimeType); 9892 } 9893 9894 // X-Requested-With header 9895 // For cross-domain requests, seeing as conditions for a preflight are 9896 // akin to a jigsaw puzzle, we simply never set it to be sure. 9897 // (it can always be set on a per-request basis or even using ajaxSetup)
vendor: 8,552 bytes, lines 9898-10207
9898 // For same-domain requests, won't change header if already provided. 9899 if (!options.crossDomain && !headers["X-Requested-With"]) { 9900 headers["X-Requested-With"] = "XMLHttpRequest"; 9901 } 9902 9903 // Set headers 9904 for (i in headers) { 9905 9906 // Support: IE<9 9907 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting 9908 // request header to a null-value. 9909 // 9910 // To keep consistent with other XHR implementations, cast the value 9911 // to string and ignore `undefined`. 9912 if (headers[i] !== undefined) { 9913 xhr.setRequestHeader(i, headers[i] + ""); 9914 } 9915 } 9916 9917 // Do send the request 9918 // This may raise an exception which is actually 9919 // handled in jQuery.ajax (so no try/catch here) 9920 xhr.send(options.hasContent && options.data || null); 9921 9922 // Listener 9923 callback = function (_, isAbort) { 9924 var status, statusText, responses; 9925 9926 // Was never called and is aborted or complete 9927 if (callback && (isAbort || xhr.readyState === 4)) { 9928 9929 // Clean up 9930 delete xhrCallbacks[id]; 9931 callback = undefined; 9932 xhr.onreadystatechange = jQuery.noop; 9933 9934 // Abort manually if needed 9935 if (isAbort) { 9936 if (xhr.readyState !== 4) { 9937 xhr.abort(); 9938 } 9939 } else { 9940 responses = {}; 9941 status = xhr.status; 9942 9943 // Support: IE<10 9944 // Accessing binary-data responseText throws an exception 9945 // (#11426) 9946 if (typeof xhr.responseText === "string") { 9947 responses.text = xhr.responseText; 9948 } 9949 9950 // Firefox throws an exception when accessing 9951 // statusText for faulty cross-domain requests 9952 try { 9953 statusText = xhr.statusText; 9954 } catch (e) { 9955 9956 // We normalize with Webkit giving an empty statusText 9957 statusText = ""; 9958 } 9959 9960 // Filter status for non standard behaviors 9961 9962 // If the request is local and we have data: assume a success 9963 // (success with no data won't get notified, that's the best we 9964 // can do given current implementations) 9965 if (!status && options.isLocal && !options.crossDomain) { 9966 status = responses.text ? 200 : 404; 9967 9968 // IE - #1450: sometimes returns 1223 when it should be 204 9969 } else if (status === 1223) { 9970 status = 204; 9971 } 9972 } 9973 } 9974 9975 // Call complete if needed 9976 if (responses) { 9977 complete(status, statusText, responses, xhr.getAllResponseHeaders()); 9978 } 9979 }; 9980 9981 // Do send the request 9982 // `xhr.send` may raise an exception, but it will be 9983 // handled in jQuery.ajax (so no try/catch here) 9984 if (!options.async) { 9985 9986 // If we're in sync mode we fire the callback 9987 callback(); 9988 } else if (xhr.readyState === 4) { 9989 9990 // (IE6 & IE7) if it's in cache and has been 9991 // retrieved directly we need to fire the callback 9992 window.setTimeout(callback); 9993 } else { 9994 9995 // Register the callback, but delay it in case `xhr.send` throws 9996 // Add to the list of active xhr callbacks 9997 xhr.onreadystatechange = xhrCallbacks[id] = callback; 9998 } 9999 }, 10000 10001 abort: function () { 10002 if (callback) { 10003 callback(undefined, true); 10004 } 10005 } 10006 }; 10007 } 10008 }); 10009 } 10010 10011 // Functions to create xhrs 10012 function createStandardXHR() { 10013 try { 10014 return new window.XMLHttpRequest(); 10015 } catch (e) {} 10016 } 10017 10018 function createActiveXHR() { 10019 try { 10020 return new window.ActiveXObject("Microsoft.XMLHTTP"); 10021 } catch (e) {} 10022 } 10023 10024 // Install script dataType 10025 jQuery.ajaxSetup({ 10026 accepts: { 10027 script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" 10028 }, 10029 contents: { 10030 script: /\b(?:java|ecma)script\b/ 10031 }, 10032 converters: { 10033 "text script": function (text) { 10034 jQuery.globalEval(text); 10035 return text; 10036 } 10037 } 10038 }); 10039 10040 // Handle cache's special case and global 10041 jQuery.ajaxPrefilter("script", function (s) { 10042 if (s.cache === undefined) { 10043 s.cache = false; 10044 } 10045 if (s.crossDomain) { 10046 s.type = "GET"; 10047 s.global = false; 10048 } 10049 }); 10050 10051 // Bind script tag hack transport 10052 jQuery.ajaxTransport("script", function (s) { 10053 10054 // This transport only deals with cross domain requests 10055 if (s.crossDomain) { 10056 10057 var script, 10058 head = document.head || jQuery("head")[0] || document.documentElement; 10059 10060 return { 10061 10062 send: function (_, callback) { 10063 10064 script = document.createElement("script"); 10065 10066 script.async = true; 10067 10068 if (s.scriptCharset) { 10069 script.charset = s.scriptCharset; 10070 } 10071 10072 script.src = s.url; 10073 10074 // Attach handlers for all browsers 10075 script.onload = script.onreadystatechange = function (_, isAbort) { 10076 10077 if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) { 10078 10079 // Handle memory leak in IE 10080 script.onload = script.onreadystatechange = null; 10081 10082 // Remove the script 10083 if (script.parentNode) { 10084 script.parentNode.removeChild(script); 10085 } 10086 10087 // Dereference the script 10088 script = null; 10089 10090 // Callback if not abort 10091 if (!isAbort) { 10092 callback(200, "success"); 10093 } 10094 } 10095 }; 10096 10097 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending 10098 // Use native DOM manipulation to avoid our domManip AJAX trickery 10099 head.insertBefore(script, head.firstChild); 10100 }, 10101 10102 abort: function () { 10103 if (script) { 10104 script.onload(undefined, true); 10105 } 10106 } 10107 }; 10108 } 10109 }); 10110 10111 var oldCallbacks = [], 10112 rjsonp = /(=)\?(?=&|$)|\?\?/; 10113 10114 // Default jsonp settings 10115 jQuery.ajaxSetup({ 10116 jsonp: "callback", 10117 jsonpCallback: function () { 10118 var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce++; 10119 this[callback] = true; 10120 return callback; 10121 } 10122 }); 10123 10124 // Detect, normalize options and install callbacks for jsonp requests 10125 jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) { 10126 10127 var callbackName, 10128 overwritten, 10129 responseContainer, 10130 jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0 && rjsonp.test(s.data) && "data"); 10131 10132 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10133 if (jsonProp || s.dataTypes[0] === "jsonp") { 10134 10135 // Get callback name, remembering preexisting value associated with it 10136 callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback; 10137 10138 // Insert callback into url or form data 10139 if (jsonProp) { 10140 s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName); 10141 } else if (s.jsonp !== false) { 10142 s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName; 10143 } 10144 10145 // Use data converter to retrieve json after script execution 10146 s.converters["script json"] = function () { 10147 if (!responseContainer) { 10148 jQuery.error(callbackName + " was not called"); 10149 } 10150 return responseContainer[0]; 10151 }; 10152 10153 // force json dataType 10154 s.dataTypes[0] = "json"; 10155 10156 // Install callback 10157 overwritten = window[callbackName]; 10158 window[callbackName] = function () { 10159 responseContainer = arguments; 10160 }; 10161 10162 // Clean-up function (fires after converters) 10163 jqXHR.always(function () { 10164 10165 // If previous value didn't exist - remove it 10166 if (overwritten === undefined) { 10167 jQuery(window).removeProp(callbackName); 10168 10169 // Otherwise restore preexisting value 10170 } else { 10171 window[callbackName] = overwritten; 10172 } 10173 10174 // Save back as free 10175 if (s[callbackName]) { 10176 10177 // make sure that re-using the options doesn't screw things around 10178 s.jsonpCallback = originalSettings.jsonpCallback; 10179 10180 // save the callback name for future use 10181 oldCallbacks.push(callbackName); 10182 } 10183 10184 // Call if it was a function and we have a response 10185 if (responseContainer && jQuery.isFunction(overwritten)) { 10186 overwritten(responseContainer[0]); 10187 } 10188 10189 responseContainer = overwritten = undefined; 10190 }); 10191 10192 // Delegate to script 10193 return "script"; 10194 } 10195 }); 10196 10197 // data: string of html 10198 // context (optional): If specified, the fragment will be created in this context, 10199 // defaults to document 10200 // keepScripts (optional): If true, will include scripts passed in the html string 10201 jQuery.parseHTML = function (data, context, keepScripts) { 10202 if (!data || typeof data !== "string") { 10203 return null; 10204 } 10205 if (typeof context === "boolean") { 10206 keepScripts = context; 10207 context = false;
10208 } 10209 context = context || document; 10210 10211 var parsed = rsingleTag.exec(data), 10212 scripts = !keepScripts && []; 10213 10214 // Single tag 10215 if (parsed) { 10216 return [context.createElement(parsed[1])]; 10217 } 10218 10219 parsed = buildFragment([data], context, scripts); 10220 10221 if (scripts && scripts.length) { 10222 jQuery(scripts).remove(); 10223 } 10224 10225 return jQuery.merge([], parsed.childNodes); 10226 }; 10227 10228 // Keep a copy of the old load method 10229 var _load = jQuery.fn.load; 10230 10231 /** 10232 * Load a url into a page 10233 */ 10234 jQuery.fn.load = function (url, params, callback) { 10235 if (typeof url !== "string" && _load) { 10236 return _load.apply(this, arguments); 10237 } 10238 10239 var selector, 10240 type, 10241 response, 10242 self = this, 10243 off = url.indexOf(" "); 10244 10245 if (off > -1) { 10246 selector = jQuery.trim(url.slice(off, url.length)); 10247 url = url.slice(0, off); 10248 } 10249 10250 // If it's a function 10251 if (jQuery.isFunction(params)) { 10252 10253 // We assume that it's the callback 10254 callback = params; 10255 params = undefined; 10256 10257 // Otherwise, build a param string 10258 } else if (params && typeof params === "object") { 10259 type = "POST"; 10260 } 10261 10262 // If we have elements to modify, make the request 10263 if (self.length > 0) { 10264 jQuery.ajax({ 10265 url: url, 10266 10267 // If "type" variable is undefined, then "GET" method will be used. 10268 // Make value of this field explicit since 10269 // user can override it through ajaxSetup method 10270 type: type || "GET", 10271 dataType: "html", 10272 data: params 10273 }).done(function (responseText) { 10274 10275 // Save response for use in complete callback 10276 response = arguments; 10277 10278 self.html(selector ? 10279 10280 // If a selector was specified, locate the right elements in a dummy div 10281 // Exclude scripts to avoid IE 'Permission Denied' errors 10282 jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : 10283 10284 // Otherwise use the full result 10285 responseText); 10286 10287 // If the request succeeds, this function gets "data", "status", "jqXHR" 10288 // but they are ignored because response was set above. 10289 // If it fails, this function gets "jqXHR", "status", "error" 10290 }).always(callback && function (jqXHR, status) { 10291 self.each(function () { 10292 callback.apply(this, response || [jqXHR.responseText, status, jqXHR]); 10293 }); 10294 }); 10295 } 10296 10297 return this; 10298 }; 10299 10300 // Attach a bunch of functions for handling common AJAX events 10301 jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) { 10302 jQuery.fn[type] = function (fn) { 10303 return this.on(type, fn); 10304 }; 10305 }); 10306 10307 jQuery.expr.filters.animated = function (elem) { 10308 return jQuery.grep(jQuery.timers, function (fn) { 10309 return elem === fn.elem; 10310 }).length; 10311 }; 10312 10313 /** 10314 * Gets a window from an element 10315 */ 10316 function getWindow(elem) { 10317 return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false; 10318 } 10319 10320 jQuery.offset = { 10321 setOffset: function (elem, options, i) { 10322 var curPosition, 10323 curLeft, 10324 curCSSTop, 10325 curTop, 10326 curOffset, 10327 curCSSLeft, 10328 calculatePosition, 10329 position = jQuery.css(elem, "position"), 10330 curElem = jQuery(elem), 10331 props = {}; 10332 10333 // set position first, in-case top/left are set even on static elem 10334 if (position === "static") { 10335 elem.style.position = "relative"; 10336 } 10337 10338 curOffset = curElem.offset(); 10339 curCSSTop = jQuery.css(elem, "top"); 10340 curCSSLeft = jQuery.css(elem, "left"); 10341 calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1; 10342 10343 // need to be able to calculate position if either top or left 10344 // is auto and position is either absolute or fixed 10345 if (calculatePosition) { 10346 curPosition = curElem.position(); 10347 curTop = curPosition.top; 10348 curLeft = curPosition.left; 10349 } else { 10350 curTop = parseFloat(curCSSTop) || 0; 10351 curLeft = parseFloat(curCSSLeft) || 0; 10352 } 10353 10354 if (jQuery.isFunction(options)) { 10355 10356 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 10357 options = options.call(elem, i, jQuery.extend({}, curOffset)); 10358 } 10359 10360 if (options.top != null) { 10361 props.top = options.top - curOffset.top + curTop; 10362 } 10363 if (options.left != null) { 10364 props.left = options.left - curOffset.left + curLeft; 10365 } 10366 10367 if ("using" in options) { 10368 options.using.call(elem, props); 10369 } else { 10370 curElem.css(props); 10371 } 10372 } 10373 }; 10374 10375 jQuery.fn.extend({ 10376 offset: function (options) { 10377 if (arguments.length) {
vendor: 8,365 bytes, lines 10378-10632
10378 return options === undefined ? this : this.each(function (i) { 10379 jQuery.offset.setOffset(this, options, i); 10380 }); 10381 } 10382 10383 var docElem, 10384 win, 10385 box = { top: 0, left: 0 }, 10386 elem = this[0], 10387 doc = elem && elem.ownerDocument; 10388 10389 if (!doc) { 10390 return; 10391 } 10392 10393 docElem = doc.documentElement; 10394 10395 // Make sure it's not a disconnected DOM node 10396 if (!jQuery.contains(docElem, elem)) { 10397 return box; 10398 } 10399 10400 // If we don't have gBCR, just use 0,0 rather than error 10401 // BlackBerry 5, iOS 3 (original iPhone) 10402 if (typeof elem.getBoundingClientRect !== "undefined") { 10403 box = elem.getBoundingClientRect(); 10404 } 10405 win = getWindow(doc); 10406 return { 10407 top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0), 10408 left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0) 10409 }; 10410 }, 10411 10412 position: function () { 10413 if (!this[0]) { 10414 return; 10415 } 10416 10417 var offsetParent, 10418 offset, 10419 parentOffset = { top: 0, left: 0 }, 10420 elem = this[0]; 10421 10422 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, 10423 // because it is its only offset parent 10424 if (jQuery.css(elem, "position") === "fixed") { 10425 10426 // we assume that getBoundingClientRect is available when computed position is fixed 10427 offset = elem.getBoundingClientRect(); 10428 } else { 10429 10430 // Get *real* offsetParent 10431 offsetParent = this.offsetParent(); 10432 10433 // Get correct offsets 10434 offset = this.offset(); 10435 if (!jQuery.nodeName(offsetParent[0], "html")) { 10436 parentOffset = offsetParent.offset(); 10437 } 10438 10439 // Add offsetParent borders 10440 parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true); 10441 parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true); 10442 } 10443 10444 // Subtract parent offsets and element margins 10445 // note: when an element has margin: auto the offsetLeft and marginLeft 10446 // are the same in Safari causing offset.left to incorrectly be 0 10447 return { 10448 top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true), 10449 left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true) 10450 }; 10451 }, 10452 10453 offsetParent: function () { 10454 return this.map(function () { 10455 var offsetParent = this.offsetParent; 10456 10457 while (offsetParent && !jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static") { 10458 offsetParent = offsetParent.offsetParent; 10459 } 10460 return offsetParent || documentElement; 10461 }); 10462 } 10463 }); 10464 10465 // Create scrollLeft and scrollTop methods 10466 jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (method, prop) { 10467 var top = /Y/.test(prop); 10468 10469 jQuery.fn[method] = function (val) { 10470 return access(this, function (elem, method, val) { 10471 var win = getWindow(elem); 10472 10473 if (val === undefined) { 10474 return win ? prop in win ? win[prop] : win.document.documentElement[method] : elem[method]; 10475 } 10476 10477 if (win) { 10478 win.scrollTo(!top ? val : jQuery(win).scrollLeft(), top ? val : jQuery(win).scrollTop()); 10479 } else { 10480 elem[method] = val; 10481 } 10482 }, method, val, arguments.length, null); 10483 }; 10484 }); 10485 10486 // Support: Safari<7-8+, Chrome<37-44+ 10487 // Add the top/left cssHooks using jQuery.fn.position 10488 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 10489 // getComputedStyle returns percent when specified for top/left/bottom/right 10490 // rather than make the css module depend on the offset module, we just check for it here 10491 jQuery.each(["top", "left"], function (i, prop) { 10492 jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) { 10493 if (computed) { 10494 computed = curCSS(elem, prop); 10495 10496 // if curCSS returns percentage, fallback to offset 10497 return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed; 10498 } 10499 }); 10500 }); 10501 10502 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 10503 jQuery.each({ Height: "height", Width: "width" }, function (name, type) { 10504 jQuery.each({ padding: "inner" + name, content: type, "": "outer" + name }, function (defaultExtra, funcName) { 10505 10506 // margin is only for outerHeight, outerWidth 10507 jQuery.fn[funcName] = function (margin, value) { 10508 var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"), 10509 extra = defaultExtra || (margin === true || value === true ? "margin" : "border"); 10510 10511 return access(this, function (elem, type, value) { 10512 var doc; 10513 10514 if (jQuery.isWindow(elem)) { 10515 10516 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there 10517 // isn't a whole lot we can do. See pull request at this URL for discussion: 10518 // https://github.com/jquery/jquery/pull/764 10519 return elem.document.documentElement["client" + name]; 10520 } 10521 10522 // Get document width or height 10523 if (elem.nodeType === 9) { 10524 doc = elem.documentElement; 10525 10526 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 10527 // whichever is greatest 10528 // unfortunately, this causes bug #3838 in IE6/8 only, 10529 // but there is currently no good, small way to fix it. 10530 return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]); 10531 } 10532 10533 return value === undefined ? 10534 10535 // Get width or height on the element, requesting but not forcing parseFloat 10536 jQuery.css(elem, type, extra) : 10537 10538 // Set width or height on the element 10539 jQuery.style(elem, type, value, extra); 10540 }, type, chainable ? margin : undefined, chainable, null); 10541 }; 10542 }); 10543 }); 10544 10545 jQuery.fn.extend({ 10546 10547 bind: function (types, data, fn) { 10548 return this.on(types, null, data, fn); 10549 }, 10550 unbind: function (types, fn) { 10551 return this.off(types, null, fn); 10552 }, 10553 10554 delegate: function (selector, types, data, fn) { 10555 return this.on(types, selector, data, fn); 10556 }, 10557 undelegate: function (selector, types, fn) { 10558 10559 // ( namespace ) or ( selector, types [, fn] ) 10560 return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn); 10561 } 10562 }); 10563 10564 // The number of elements contained in the matched element set 10565 jQuery.fn.size = function () { 10566 return this.length; 10567 }; 10568 10569 jQuery.fn.andSelf = jQuery.fn.addBack; 10570 10571 // Register as a named AMD module, since jQuery can be concatenated with other 10572 // files that may use define, but not via a proper concatenation script that 10573 // understands anonymous AMD modules. A named AMD is safest and most robust 10574 // way to register. Lowercase jquery is used because AMD module names are 10575 // derived from file names, and jQuery is normally delivered in a lowercase 10576 // file name. Do this after creating the global so that if an AMD module wants 10577 // to call noConflict to hide this version of jQuery, it will work. 10578 10579 // Note that for maximum portability, libraries that are not jQuery should 10580 // declare themselves as anonymous modules, and avoid setting a global if an 10581 // AMD loader is present. jQuery is a special case. For more information, see 10582 // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 10583 10584 if (true) { 10585 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { 10586 return jQuery; 10587 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 10588 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 10589 } 10590 10591 var 10592 10593 // Map over jQuery in case of overwrite 10594 _jQuery = window.jQuery, 10595 10596 10597 // Map over the $ in case of overwrite 10598 _$ = window.$; 10599 10600 jQuery.noConflict = function (deep) { 10601 if (window.$ === jQuery) { 10602 window.$ = _$; 10603 } 10604 10605 if (deep && window.jQuery === jQuery) { 10606 window.jQuery = _jQuery; 10607 } 10608 10609 return jQuery; 10610 }; 10611 10612 // Expose jQuery and $ identifiers, even in 10613 // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 10614 // and CommonJS for browser emulators (#13566) 10615 if (!noGlobal) { 10616 window.jQuery = window.$ = jQuery; 10617 } 10618 10619 return jQuery; 10620}); 10621 10622/***/ }), 10623/* 1 */ 10624/***/ (function(module, exports, __webpack_require__) { 10625 10626/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 10627 * VERSION: 1.20.3 10628 * DATE: 2017-10-02 10629 * UPDATES AND DOCS AT: http://greensock.com 10630 * 10631 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved. 10632 * This work is subject to the terms at http://greensock.com/standard-license or for
10633 * Club GreenSock members, the software agreement that was issued with your membership. 10634 * 10635 * @author: Jack Doyle, [email protected] 10636 */ 10637(function (window, moduleName) { 10638 10639 "use strict"; 10640 10641 var _exports = {}, 10642 _doc = window.document, 10643 _globals = window.GreenSockGlobals = window.GreenSockGlobals || window; 10644 if (_globals.TweenLite) { 10645 return; //in case the core set of classes is already loaded, don't instantiate twice. 10646 } 10647 var _namespace = function (ns) { 10648 var a = ns.split("."), 10649 p = _globals, 10650 i; 10651 for (i = 0; i < a.length; i++) { 10652 p[a[i]] = p = p[a[i]] || {}; 10653 } 10654 return p; 10655 }, 10656 gs = _namespace("com.greensock"), 10657 _tinyNum = 0.0000000001, 10658 _slice = function (a) { 10659 //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 10660 var b = [], 10661 l = a.length, 10662 i; 10663 for (i = 0; i !== l; b.push(a[i++])) {} 10664 return b; 10665 }, 10666 _emptyFunc = function () {}, 10667 _isArray = function () { 10668 //works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower) 10669 var toString = Object.prototype.toString, 10670 array = toString.call([]); 10671 return function (obj) { 10672 return obj != null && (obj instanceof Array || typeof obj === "object" && !!obj.push && toString.call(obj) === array); 10673 }; 10674 }(), 10675 a, 10676 i, 10677 p, 10678 _ticker, 10679 _tickerActive, 10680 _defLookup = {}, 10681 10682 10683 /** 10684 * @constructor 10685 * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition. 10686 * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is 10687 * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin 10688 * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally. 10689 * 10690 * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found, 10691 * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere, 10692 * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so 10693 * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything 10694 * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock 10695 * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could 10696 * sandbox the banner one like: 10697 * 10698 * <script> 10699 * var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever. 10700 * </script> 10701 * <script src="js/greensock/v1.7/TweenMax.js"></script> 10702 * <script> 10703 * window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...) 10704 * </script> 10705 * <script src="js/greensock/v1.6/TweenMax.js"></script> 10706 * <script> 10707 * gs.TweenLite.to(...); //would use v1.7 10708 * TweenLite.to(...); //would use v1.6 10709 * </script> 10710 * 10711 * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back". 10712 * @param {!Array.<string>}
10712 dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"] 10713 * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition. 10714 * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object) 10715 */ 10716 Definition = function (ns, dependencies, func, global) { 10717 this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses 10718 _defLookup[ns] = this; 10719 this.gsClass = null; 10720 this.func = func; 10721 var _classes = []; 10722 this.check = function (init) { 10723 var i = dependencies.length, 10724 missing = i, 10725 cur, 10726 a, 10727 n, 10728 cl; 10729 while (--i > -1) { 10730 if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) { 10731 _classes[i] = cur.gsClass; 10732 missing--; 10733 } else if (init) { 10734 cur.sc.push(this); 10735 } 10736 } 10737 if (missing === 0 && func) { 10738 a = ("com.greensock." + ns).split("."); 10739 n = a.pop(); 10740 cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes); 10741 10742 //exports to multiple environments 10743 if (global) { 10744 _globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.) 10745 if (typeof module !== "undefined" && module.exports) { 10746 //node 10747 if (ns === moduleName) { 10748 module.exports = _exports[moduleName] = cl; 10749 for (i in _exports) { 10750 cl[i] = _exports[i]; 10751 } 10752 } else if (_exports[moduleName]) { 10753 _exports[moduleName][n] = cl; 10754 } 10755 } else if (true) { 10756 //AMD 10757 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { 10758 return cl; 10759 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 10760 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 10761 } 10762 } 10763 for (i = 0; i < this.sc.length; i++) { 10764 this.sc[i].check(); 10765 } 10766 } 10767 }; 10768 this.check(true); 10769 }, 10770 10771 10772 //used to create Definition instances (which basically registers a class that has dependencies). 10773 _gsDefine = window._gsDefine = function (ns, dependencies, func, global) { 10774 return new Definition(ns, dependencies, func, global); 10775 }, 10776 10777 10778 //a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class). 10779 _class = gs._class = function (ns, func, global) { 10780 func = func || function () {}; 10781 _gsDefine(ns, [], function () { 10782 return func; 10783 }, global); 10784 return func; 10785 }; 10786 10787 _gsDefine.globals = _globals; 10788 10789 /* 10790 * ---------------------------------------------------------------- 10791 * Ease 10792 * ---------------------------------------------------------------- 10793 */ 10794 var _baseParams = [0, 0, 1, 1], 10795 Ease = _class("easing.Ease", function (func, extraParams, type, power) { 10796 this._func = func; 10797 this._type = type || 0; 10798 this._power = power || 0; 10799 this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams; 10800 }, true), 10801 _easeMap = Ease.map = {}, 10802 _easeReg = Ease.register = function (ease, names, types, create) { 10803 var na = names.split(","), 10804 i = na.length, 10805 ta = (types || "easeIn,easeOut,easeInOut").split(","), 10806 e, 10807 name, 10808 j, 10809 type; 10810 while (--i > -1) { 10811 name = na[i]; 10812 e = create ? _class("easing." + name, null, true) : gs.easing[name] || {}; 10813 j = ta.length; 10814 while (--j > -1) { 10815 type = ta[j]; 10816 _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease(); 10817 } 10818 } 10819 }; 10820 10821 p = Ease.prototype; 10822 p._calcEnd = false;
10823 p.getRatio = function (p) { 10824 if (this._func) { 10825 this._params[0] = p; 10826 return this._func.apply(null, this._params); 10827 } 10828 var t = this._type, 10829 pw = this._power, 10830 r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2; 10831 if (pw === 1) { 10832 r *= r; 10833 } else if (pw === 2) { 10834 r *= r * r; 10835 } else if (pw === 3) { 10836 r *= r * r * r; 10837 } else if (pw === 4) { 10838 r *= r * r * r * r; 10839 } 10840 return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2; 10841 }; 10842 10843 //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut) 10844 a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"]; 10845 i = a.length; 10846 while (--i > -1) { 10847 p = a[i] + ",Power" + i; 10848 _easeReg(new Ease(null, null, 1, i), p, "easeOut", true); 10849 _easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : "")); 10850 _easeReg(new Ease(null, null, 3, i), p, "easeInOut"); 10851 } 10852 _easeMap.linear = gs.easing.Linear.easeIn; 10853 _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks 10854 10855 10856 /* 10857 * ---------------------------------------------------------------- 10858 * EventDispatcher 10859 * ---------------------------------------------------------------- 10860 */ 10861 var EventDispatcher = _class("events.EventDispatcher", function (target) { 10862 this._listeners = {}; 10863 this._eventTarget = target || this; 10864 }); 10865 p = EventDispatcher.prototype; 10866 10867 p.addEventListener = function (type, callback, scope, useParam, priority) { 10868 priority = priority || 0; 10869 var list = this._listeners[type], 10870 index = 0, 10871 listener, 10872 i; 10873 if (this === _ticker && !_tickerActive) { 10874 _ticker.wake(); 10875 } 10876 if (list == null) { 10877 this._listeners[type] = list = []; 10878 } 10879 i = list.length; 10880 while (--i > -1) { 10881 listener = list[i]; 10882 if (listener.c === callback && listener.s === scope) { 10883 list.splice(i, 1); 10884 } else if (index === 0 && listener.pr < priority) { 10885 index = i + 1; 10886 } 10887 } 10888 list.splice(index, 0, { c: callback, s: scope, up: useParam, pr: priority }); 10889 }; 10890 10891 p.removeEventListener = function (type, callback) { 10892 var list = this._listeners[type], 10893 i; 10894 if (list) { 10895 i = list.length; 10896 while (--i > -1) { 10897 if (list[i].c === callback) { 10898 list.splice(i, 1); 10899 return; 10900 } 10901 } 10902 } 10903 }; 10904 10905 p.dispatchEvent = function (type) { 10906 var list = this._listeners[type], 10907 i, 10908 t, 10909 listener; 10910 if (list) { 10911 i = list.length; 10912 if (i > 1) { 10913 list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip) 10914 } 10915 t = this._eventTarget; 10916 while (--i > -1) { 10917 listener = list[i]; 10918 if (listener) { 10919 if (listener.up) { 10920 listener.c.call(listener.s || t, { type: type, target: t }); 10921 } else { 10922 listener.c.call(listener.s || t); 10923 } 10924 } 10925 } 10926 } 10927 }; 10928 10929 /* 10930 * ---------------------------------------------------------------- 10931 * Ticker 10932 * ---------------------------------------------------------------- 10933 */ 10934 var _reqAnimFrame = window.requestAnimationFrame, 10935 _cancelAnimFrame = window.cancelAnimationFrame, 10936 _getTime = Date.now || function () { 10937 return new Date().getTime(); 10938 }, 10939 _lastUpdate = _getTime(); 10940 10941 //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill. 10942 a = ["ms", "moz", "webkit", "o"]; 10943 i = a.length; 10944 while (--i > -1 && !_reqAnimFrame) { 10945 _reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; 10946 _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; 10947 } 10948 10949 _class("Ticker", function (fps, useRAF) { 10950 var _self = this, 10951 _startTime = _getTime(), 10952 _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false, 10953 _lagThreshold = 500, 10954 _adjustedLag = 33, 10955 _tickWord = "tick", 10956 //helps reduce gc burden 10957 _fps, 10958 _req, 10959 _id, 10960 _gap, 10961 _nextTime, 10962 _tick = function (manual) { 10963 var elapsed = _getTime() - _lastUpdate, 10964 overlap, 10965 dispatch; 10966 if (elapsed > _lagThreshold) { 10967 _startTime += elapsed - _adjustedLag; 10968 } 10969 _lastUpdate += elapsed; 10970 _self.time = (_lastUpdate - _startTime) / 1000; 10971 overlap = _self.time - _nextTime; 10972 if (!_fps || overlap > 0 || manual === true) { 10973 _self.frame++; 10974 _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap); 10975 dispatch = true; 10976 } 10977 if (manual !== true) { 10978 //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. 10979 _id = _req(_tick); 10980 }
10981 if (dispatch) { 10982 _self.dispatchEvent(_tickWord); 10983 } 10984 }; 10985 10986 EventDispatcher.call(_self); 10987 _self.time = _self.frame = 0; 10988 _self.tick = function () { 10989 _tick(true); 10990 }; 10991 10992 _self.lagSmoothing = function (threshold, adjustedLag) { 10993 if (!arguments.length) { 10994 //if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use. 10995 return _lagThreshold < 1 / _tinyNum; 10996 } 10997 _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited 10998 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 10999 }; 11000 11001 _self.sleep = function () { 11002 if (_id == null) { 11003 return; 11004 } 11005 if (!_useRAF || !_cancelAnimFrame) { 11006 clearTimeout(_id); 11007 } else { 11008 _cancelAnimFrame(_id); 11009 } 11010 _req = _emptyFunc; 11011 _id = null; 11012 if (_self === _ticker) { 11013 _tickerActive = false; 11014 } 11015 }; 11016 11017 _self.wake = function (seamless) { 11018 if (_id !== null) { 11019 _self.sleep(); 11020 } else if (seamless) { 11021 _startTime += -_lastUpdate + (_lastUpdate = _getTime()); 11022 } else if (_self.frame > 10) { 11023 //don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout(). 11024 _lastUpdate = _getTime() - _lagThreshold + 5; 11025 } 11026 _req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) { 11027 return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0); 11028 } : _reqAnimFrame; 11029 if (_self === _ticker) { 11030 _tickerActive = true; 11031 } 11032 _tick(2); 11033 }; 11034 11035 _self.fps = function (value) { 11036 if (!arguments.length) { 11037 return _fps; 11038 } 11039 _fps = value; 11040 _gap = 1 / (_fps || 60); 11041 _nextTime = this.time + _gap; 11042 _self.wake(); 11043 }; 11044 11045 _self.useRAF = function (value) { 11046 if (!arguments.length) { 11047 return _useRAF; 11048 } 11049 _self.sleep(); 11050 _useRAF = value; 11051 _self.fps(_fps); 11052 }; 11053 _self.fps(fps); 11054 11055 //a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition. 11056 setTimeout(function () { 11057 if (_useRAF === "auto" && _self.frame < 5 && _doc.visibilityState !== "hidden") { 11058 _self.useRAF(false); 11059 } 11060 }, 1500); 11061 }); 11062 11063 p = gs.Ticker.prototype = new gs.events.EventDispatcher(); 11064 p.constructor = gs.Ticker; 11065 11066 /* 11067 * ---------------------------------------------------------------- 11068 * Animation 11069 * ---------------------------------------------------------------- 11070 */ 11071 var Animation = _class("core.Animation", function (duration, vars) { 11072 this.vars = vars = vars || {}; 11073 this._duration = this._totalDuration = duration || 0; 11074 this._delay = Number(vars.delay) || 0; 11075 this._timeScale = 1; 11076 this._active = vars.immediateRender === true; 11077 this.data = vars.data; 11078 this._reversed = vars.reversed === true; 11079 11080 if (!_rootTimeline) { 11081 return; 11082 } 11083 if (!_tickerActive) { 11084 //some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly. 11085 _ticker.wake(); 11086 } 11087 11088 var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline; 11089 tl.add(this, tl._time); 11090 11091 if (this.vars.paused) { 11092 this.paused(true); 11093 } 11094 }); 11095 11096 _ticker = Animation.ticker = new gs.Ticker(); 11097 p = Animation.prototype; 11098 p._dirty = p._gc = p._initted = p._paused = false; 11099 p._totalTime = p._time = 0; 11100 p._rawPrevTime = -1; 11101 p._next = p._last = p._onUpdate = p._timeline = p.timeline = null; 11102 p._paused = false; 11103 11104 //some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker. 11105 var _checkTimeout = function () { 11106 if (_tickerActive && _getTime() - _lastUpdate > 2000 && (_doc.visibilityState !== "hidden" || !_ticker.lagSmoothing())) { 11107 //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled. 11108 _ticker.wake(); 11109 } 11110 var t = setTimeout(_checkTimeout, 2000); 11111 if (t.unref) { 11112 // allows a node process to exit even if the timeoutâs callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds. 11113 t.unref(); 11114 } 11115 }; 11116 _checkTimeout(); 11117 11118 p.play = function (from, suppressEvents) { 11119 if (from != null) { 11120 this.seek(from, suppressEvents); 11121 } 11122 return this.reversed(false).paused(false); 11123 }; 11124 11125 p.pause = function (atTime, suppressEvents) { 11126 if (atTime != null) { 11127 this.seek(atTime, suppressEvents); 11128 } 11129 return this.paused(true); 11130 }; 11131 11132 p.resume = function (from, suppressEvents) { 11133 if (from != null) { 11134 this.seek(from, suppressEvents); 11135 } 11136 return this.paused(false); 11137 }; 11138 11139 p.seek = function (time, suppressEvents) { 11140 return this.totalTime(Number(time), suppressEvents !== false); 11141 }; 11142 11143 p.restart = function (includeDelay, suppressEvents) { 11144 return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true); 11145 }; 11146 11147 p.reverse = function (from, suppressEvents) { 11148 if (from != null) { 11149 this.seek(from || this.totalDuration(), suppressEvents); 11150 } 11151 return this.reversed(true).paused(false); 11152 }; 11153 11154 p.render = function (time, suppressEvents, force) { 11155 //stub - we override this method in subclasses. 11156 }; 11157 11158 p.invalidate = function () { 11159 this._time = this._totalTime = 0; 11160 this._initted = this._gc = false;
11161 this._rawPrevTime = -1; 11162 if (this._gc || !this.timeline) { 11163 this._enabled(true); 11164 } 11165 return this; 11166 }; 11167 11168 p.isActive = function () { 11169 var tl = this._timeline, 11170 //the 2 root timelines won't have a _timeline; they're always active. 11171 startTime = this._startTime, 11172 rawTime; 11173 return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001; 11174 }; 11175 11176 p._enabled = function (enabled, ignoreTimeline) { 11177 if (!_tickerActive) { 11178 _ticker.wake(); 11179 } 11180 this._gc = !enabled; 11181 this._active = this.isActive(); 11182 if (ignoreTimeline !== true) { 11183 if (enabled && !this.timeline) { 11184 this._timeline.add(this, this._startTime - this._delay); 11185 } else if (!enabled && this.timeline) { 11186 this._timeline._remove(this, true); 11187 } 11188 } 11189 return false; 11190 }; 11191 11192 p._kill = function (vars, target) { 11193 return this._enabled(false, false); 11194 }; 11195 11196 p.kill = function (vars, target) { 11197 this._kill(vars, target); 11198 return this; 11199 }; 11200 11201 p._uncache = function (includeSelf) { 11202 var tween = includeSelf ? this : this.timeline; 11203 while (tween) { 11204 tween._dirty = true; 11205 tween = tween.timeline; 11206 } 11207 return this; 11208 }; 11209 11210 p._swapSelfInParams = function (params) { 11211 var i = params.length, 11212 copy = params.concat(); 11213 while (--i > -1) { 11214 if (params[i] === "{self}") { 11215 copy[i] = this; 11216 } 11217 } 11218 return copy; 11219 }; 11220 11221 p._callback = function (type) { 11222 var v = this.vars, 11223 callback = v[type], 11224 params = v[type + "Params"], 11225 scope = v[type + "Scope"] || v.callbackScope || this, 11226 l = params ? params.length : 0; 11227 switch (l) {//speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray); 11228 case 0: 11229 callback.call(scope);break; 11230 case 1: 11231 callback.call(scope, params[0]);break; 11232 case 2: 11233 callback.call(scope, params[0], params[1]);break; 11234 default: 11235 callback.apply(scope, params); 11236 } 11237 }; 11238 11239 //----Animation getters/setters -------------------------------------------------------- 11240 11241 p.eventCallback = function (type, callback, params, scope) { 11242 if ((type || "").substr(0, 2) === "on") { 11243 var v = this.vars; 11244 if (arguments.length === 1) { 11245 return v[type]; 11246 } 11247 if (callback == null) { 11248 delete v[type]; 11249 } else { 11250 v[type] = callback; 11251 v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params; 11252 v[type + "Scope"] = scope; 11253 } 11254 if (type === "onUpdate") { 11255 this._onUpdate = callback; 11256 } 11257 } 11258 return this; 11259 }; 11260 11261 p.delay = function (value) { 11262 if (!arguments.length) { 11263 return this._delay; 11264 } 11265 if (this._timeline.smoothChildTiming) { 11266 this.startTime(this._startTime + value - this._delay); 11267 } 11268 this._delay = value; 11269 return this; 11270 }; 11271 11272 p.duration = function (value) { 11273 if (!arguments.length) { 11274 this._dirty = false; 11275 return this._duration; 11276 } 11277 this._duration = this._totalDuration = value; 11278 this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration. 11279 if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) { 11280 this.totalTime(this._totalTime * (value / this._duration), true); 11281 } 11282 return this; 11283 }; 11284 11285 p.totalDuration = function (value) { 11286 this._dirty = false; 11287 return !arguments.length ? this._totalDuration : this.duration(value); 11288 }; 11289 11290 p.time = function (value, suppressEvents) { 11291 if (!arguments.length) { 11292 return this._time; 11293 } 11294 if (this._dirty) { 11295 this.totalDuration(); 11296 } 11297 return this.totalTime(value > this._duration ? this._duration : value, suppressEvents); 11298 }; 11299 11300 p.totalTime = function (time, suppressEvents, uncapped) { 11301 if (!_tickerActive) { 11302 _ticker.wake(); 11303 } 11304 if (!arguments.length) { 11305 return this._totalTime; 11306 } 11307 if (this._timeline) { 11308 if (time < 0 && !uncapped) { 11309 time += this.totalDuration(); 11310 } 11311 if (this._timeline.smoothChildTiming) { 11312 if (this._dirty) { 11313 this.totalDuration(); 11314 } 11315 var totalDuration = this._totalDuration, 11316 tl = this._timeline; 11317 if (time > totalDuration && !uncapped) { 11318 time = totalDuration; 11319 } 11320 this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale; 11321 if (!tl._dirty) { 11322 //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. 11323 this._uncache(false); 11324 } 11325 //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
11325ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. 11326 if (tl._timeline) { 11327 while (tl._timeline) { 11328 if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { 11329 tl.totalTime(tl._totalTime, true); 11330 } 11331 tl = tl._timeline; 11332 } 11333 } 11334 } 11335 if (this._gc) { 11336 this._enabled(true, false); 11337 } 11338 if (this._totalTime !== time || this._duration === 0) { 11339 if (_lazyTweens.length) { 11340 _lazyRender(); 11341 } 11342 this.render(time, suppressEvents, false); 11343 if (_lazyTweens.length) { 11344 //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. 11345 _lazyRender(); 11346 } 11347 } 11348 } 11349 return this; 11350 }; 11351 11352 p.progress = p.totalProgress = function (value, suppressEvents) { 11353 var duration = this.duration(); 11354 return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents); 11355 }; 11356 11357 p.startTime = function (value) { 11358 if (!arguments.length) { 11359 return this._startTime; 11360 } 11361 if (value !== this._startTime) { 11362 this._startTime = value; 11363 if (this.timeline) if (this.timeline._sortChildren) { 11364 this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. 11365 } 11366 } 11367 return this; 11368 }; 11369 11370 p.endTime = function (includeRepeats) { 11371 return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale; 11372 }; 11373 11374 p.timeScale = function (value) { 11375 if (!arguments.length) { 11376 return this._timeScale; 11377 } 11378 var pauseTime, t; 11379 value = value || _tinyNum; //can't allow zero because it'll throw the math off 11380 if (this._timeline && this._timeline.smoothChildTiming) { 11381 pauseTime = this._pauseTime; 11382 t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime(); 11383 this._startTime = t - (t - this._startTime) * this._timeScale / value; 11384 } 11385 this._timeScale = value; 11386 t = this.timeline; 11387 while (t && t.timeline) { 11388 //must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though. 11389 t._dirty = true; 11390 t.totalDuration(); 11391 t = t.timeline; 11392 } 11393 return this; 11394 }; 11395 11396 p.reversed = function (value) { 11397 if (!arguments.length) { 11398 return this._reversed; 11399 } 11400 if (value != this._reversed) { 11401 this._reversed = value; 11402 this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true); 11403 } 11404 return this; 11405 }; 11406 11407 p.paused = function (value) { 11408 if (!arguments.length) { 11409 return this._paused; 11410 } 11411 var tl = this._timeline, 11412 raw, 11413 elapsed; 11414 if (value != this._paused) if (tl) { 11415 if (!_tickerActive && !value) { 11416 _ticker.wake(); 11417 } 11418 raw = tl.rawTime();
11419 elapsed = raw - this._pauseTime; 11420 if (!value && tl.smoothChildTiming) { 11421 this._startTime += elapsed; 11422 this._uncache(false); 11423 } 11424 this._pauseTime = value ? raw : null; 11425 this._paused = value; 11426 this._active = this.isActive(); 11427 if (!value && elapsed !== 0 && this._initted && this.duration()) { 11428 raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale; 11429 this.render(raw, raw === this._totalTime, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. 11430 } 11431 } 11432 if (this._gc && !value) { 11433 this._enabled(true, false); 11434 } 11435 return this; 11436 }; 11437 11438 /* 11439 * ---------------------------------------------------------------- 11440 * SimpleTimeline 11441 * ---------------------------------------------------------------- 11442 */ 11443 var SimpleTimeline = _class("core.SimpleTimeline", function (vars) { 11444 Animation.call(this, 0, vars); 11445 this.autoRemoveChildren = this.smoothChildTiming = true; 11446 }); 11447 11448 p = SimpleTimeline.prototype = new Animation(); 11449 p.constructor = SimpleTimeline; 11450 p.kill()._gc = false; 11451 p._first = p._last = p._recent = null; 11452 p._sortChildren = false; 11453 11454 p.add = p.insert = function (child, position, align, stagger) { 11455 var prevTween, st; 11456 child._startTime = Number(position || 0) + child._delay; 11457 if (child._paused) if (this !== child._timeline) { 11458 //we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order). 11459 child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale; 11460 } 11461 if (child.timeline) { 11462 child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one. 11463 } 11464 child.timeline = child._timeline = this; 11465 if (child._gc) { 11466 child._enabled(true, true); 11467 } 11468 prevTween = this._last; 11469 if (this._sortChildren) { 11470 st = child._startTime; 11471 while (prevTween && prevTween._startTime > st) { 11472 prevTween = prevTween._prev; 11473 } 11474 } 11475 if (prevTween) { 11476 child._next = prevTween._next; 11477 prevTween._next = child; 11478 } else { 11479 child._next = this._first; 11480 this._first = child; 11481 } 11482 if (child._next) { 11483 child._next._prev = child; 11484 } else { 11485 this._last = child; 11486 } 11487 child._prev = prevTween; 11488 this._recent = child; 11489 if (this._timeline) { 11490 this._uncache(true); 11491 } 11492 return this; 11493 }; 11494 11495 p._remove = function (tween, skipDisable) { 11496 if (tween.timeline === this) { 11497 if (!skipDisable) { 11498 tween._enabled(false, true); 11499 } 11500 11501 if (tween._prev) { 11502 tween._prev._next = tween._next; 11503 } else if (this._first === tween) { 11504 this._first = tween._next; 11505 } 11506 if (tween._next) { 11507 tween._next._prev = tween._prev; 11508 } else if (this._last === tween) { 11509 this._last = tween._prev; 11510 } 11511 tween._next = tween._prev = tween.timeline = null; 11512 if (tween === this._recent) { 11513 this._recent = this._last; 11514 } 11515 11516 if (this._timeline) { 11517 this._uncache(true); 11518 } 11519 } 11520 return this; 11521 }; 11522 11523 p.render = function (time, suppressEvents, force) { 11524 var tween = this._first, 11525 next; 11526 this._totalTime = this._time = this._rawPrevTime = time; 11527 while (tween) { 11528 next = tween._next; //record it here because the value could change after rendering... 11529 if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) { 11530 if (!tween._reversed) { 11531 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 11532 } else { 11533 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 11534 } 11535 } 11536 tween = next; 11537 } 11538 }; 11539 11540 p.rawTime = function () { 11541 if (!_tickerActive) { 11542 _ticker.wake(); 11543 } 11544 return this._totalTime; 11545 }; 11546 11547 /* 11548 * ---------------------------------------------------------------- 11549 * TweenLite 11550 * ---------------------------------------------------------------- 11551 */ 11552 var TweenLite = _class("TweenLite", function (target, duration, vars) { 11553 Animation.call(this, duration, vars); 11554 this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) 11555 11556 if (target == null) { 11557 throw "Cannot tween a null target."; 11558 } 11559 11560 this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target; 11561 11562 var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
11563 overwrite = this.vars.overwrite, 11564 i, 11565 targ, 11566 targets; 11567 11568 this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite]; 11569 11570 if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") { 11571 this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 11572 this._propLookup = []; 11573 this._siblings = []; 11574 for (i = 0; i < targets.length; i++) { 11575 targ = targets[i]; 11576 if (!targ) { 11577 targets.splice(i--, 1); 11578 continue; 11579 } else if (typeof targ === "string") { 11580 targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings 11581 if (typeof targ === "string") { 11582 targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) 11583 } 11584 continue; 11585 } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) { 11586 //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself. 11587 targets.splice(i--, 1); 11588 this._targets = targets = targets.concat(_slice(targ)); 11589 continue; 11590 } 11591 this._siblings[i] = _register(targ, this, false); 11592 if (overwrite === 1) if (this._siblings[i].length > 1) { 11593 _applyOverwrite(targ, this, null, 1, this._siblings[i]); 11594 } 11595 } 11596 } else { 11597 this._propLookup = {}; 11598 this._siblings = _register(target, this, false); 11599 if (overwrite === 1) if (this._siblings.length > 1) { 11600 _applyOverwrite(target, this, null, 1, this._siblings); 11601 } 11602 } 11603 if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) { 11604 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 11605 this.render(Math.min(0, -this._delay)); //in case delay is negative 11606 } 11607 }, true), 11608 _isSelector = function (v) { 11609 return v && v.length && v !== window && v[0] && (v[0] === window || v[0].nodeType && v[0].style && !v.nodeType); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox. 11610 }, 11611 _autoCSS = function (vars, target) { 11612 var css = {}, 11613 p; 11614 for (p in vars) { 11615 if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || _plugins[p] && _plugins[p]._autoCSS)) { 11616 //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. 11617 css[p] = vars[p]; 11618 delete vars[p]; 11619 } 11620 } 11621 vars.css = css; 11622 }; 11623 11624 p = TweenLite.prototype = new Animation(); 11625 p.constructor = TweenLite; 11626 p.kill()._gc = false; 11627 11628 //----TweenLite defaults, overwrite management, and root updates ---------------------------------------------------- 11629 11630 p.ratio = 0; 11631 p._firstPT = p._targets = p._overwrittenProps = p._startAt = null; 11632 p._notifyPluginsOfEnabled = p._lazy = false; 11633 11634 TweenLite.version = "1.20.3"; 11635 TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1); 11636 TweenLite.defaultOverwrite = "auto"; 11637 TweenLite.ticker = _ticker; 11638 TweenLite.autoSleep = 120; 11639 TweenLite.lagSmoothing = function (threshold, adjustedLag) { 11640 _ticker.lagSmoothing(threshold, adjustedLag); 11641 }; 11642 11643 TweenLite.selector = window.$ || window.jQuery || function (e) { 11644 var selector = window.$ || window.jQuery; 11645 if (selector) { 11646 TweenLite.selector = selector; 11647 return selector(e); 11648 } 11649 return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e); 11650 }; 11651 11652 var _lazyTweens = [], 11653 _lazyLookup = {}, 11654 _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 11655 _relExp = /[\+-]=-?[\.\d]/, 11656 11657 //_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig, 11658 _setRatio = function (v) { 11659 var pt = this._firstPT, 11660 min = 0.000001, 11661 val; 11662 while (pt) { 11663 val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start; 11664 if (pt.m) { 11665 val = pt.m(val, this._target || pt.t); 11666 } else if (val < min) if (val > -min && !pt.blob) {
11667 //prevents issues with converting very small numbers to strings in the browser 11668 val = 0; 11669 } 11670 if (!pt.f) { 11671 pt.t[pt.p] = val; 11672 } else if (pt.fp) { 11673 pt.t[pt.p](pt.fp, val); 11674 } else { 11675 pt.t[pt.p](val); 11676 } 11677 pt = pt._next; 11678 } 11679 }, 11680 11681 //compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")). 11682 _blobDif = function (start, end, filter, pt) { 11683 var a = [], 11684 charIndex = 0, 11685 s = "", 11686 color = 0, 11687 startNums, 11688 endNums, 11689 num, 11690 i, 11691 l, 11692 nonNumbers, 11693 currentNum; 11694 a.start = start; 11695 a.end = end; 11696 start = a[0] = start + ""; //ensure values are strings 11697 end = a[1] = end + ""; 11698 if (filter) { 11699 filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 11700 start = a[0]; 11701 end = a[1]; 11702 } 11703 a.length = 0; 11704 startNums = start.match(_numbersExp) || []; 11705 endNums = end.match(_numbersExp) || []; 11706 if (pt) { 11707 pt._next = null; 11708 pt.blob = 1; 11709 a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first) 11710 } 11711 l = endNums.length; 11712 for (i = 0; i < l; i++) { 11713 currentNum = endNums[i]; 11714 nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex); 11715 s += nonNumbers || !i ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 11716 charIndex += nonNumbers.length; 11717 if (color) { 11718 //sense rgba() values and round them. 11719 color = (color + 1) % 5; 11720 } else if (nonNumbers.substr(-5) === "rgba(") { 11721 color = 1; 11722 } 11723 if (currentNum === startNums[i] || startNums.length <= i) { 11724 s += currentNum; 11725 } else { 11726 if (s) { 11727 a.push(s); 11728 s = ""; 11729 } 11730 num = parseFloat(startNums[i]); 11731 a.push(num); 11732 a._firstPT = { _next: a._firstPT, t: a, p: a.length - 1, s: num, c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0, f: 0, m: color && color < 4 ? Math.round : 0 }; 11733 //note: we don't set _prev because we'll never need to remove individual PropTweens from this list. 11734 } 11735 charIndex += currentNum.length; 11736 } 11737 s += end.substr(charIndex); 11738 if (s) { 11739 a.push(s); 11740 } 11741 a.setRatio = _setRatio; 11742 if (_relExp.test(end)) { 11743 //if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 11744 a.end = null; 11745 } 11746 return a; 11747 }, 11748 11749 //note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example. 11750 _addPropTween = function (target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) { 11751 if (typeof end === "function") { 11752 end = end(index || 0, target); 11753 } 11754 var type = typeof target[prop], 11755 getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3), 11756 s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](), 11757 isRelative = typeof end === "string" && end.charAt(1) === "=", 11758 pt = { t: target, p: prop, s: s, f: type === "function", pg: 0, n: overwriteProp || prop, m: !mod ? 0 : typeof mod === "function" ? mod : Math.round, pr: 0, c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0 }, 11759 blob; 11760 11761 if (typeof s !== "number" || typeof end !== "number" && !isRelative) { 11762 if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") { 11763 //a blob (string that has multiple numbers in it) 11764 pt.fp = funcParam; 11765 blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c : end, stringFilter || TweenLite.defaultStringFilter, pt); 11766 pt = { t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0 }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example. 11767 } else { 11768 pt.s = parseFloat(s); 11769 if (!isRelative) { 11770 pt.c = parseFloat(end) - pt.s || 0; 11771 } 11772 } 11773 } 11774 if (pt.c) { 11775 //only add it to the linked list if there's a change. 11776 if (pt._next = this._firstPT) { 11777 pt._next._prev = pt; 11778 } 11779 this._firstPT = pt; 11780 return pt; 11781 } 11782 }, 11783 _internals = TweenLite._internals = { isArray: _isArray, isSelector: _isSelector, lazyTweens: _lazyTweens, blobDif: _blobDif }, 11784 //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object. 11785 _plugins = TweenLite._plugins = {}, 11786 _tweenLookup = _internals.tweenLookup = {}, 11787 _tweenLookupNum = 0, 11788 _reservedProps = _internals.reservedProps = { ease: 1, delay: 1, overwrite: 1, onComplete: 1, onCompleteParams: 1, onCompleteScope: 1, useFrames: 1, runBackwards: 1, startAt: 1, onUpdate: 1, onUpdateParams: 1, onUpdateScope: 1, onStart: 1, onStartParams: 1, onStartScope: 1, onReverseComplete: 1, onReverseCompleteParams: 1, onReverseCompleteScope: 1, onRepeat: 1, onRepeatParams: 1, onRepeatScope: 1, easeParams: 1, yoyo: 1, immediateRender: 1, repeat: 1, repeatDelay: 1, data: 1, paused: 1, reversed: 1, autoCSS: 1, lazy: 1, onOverwrite: 1, callbackScope: 1, str
11788ingFilter: 1, id: 1, yoyoEase: 1 }, 11789 _overwriteLookup = { none: 0, all: 1, auto: 2, concurrent: 3, allOnStart: 4, preexisting: 5, "true": 1, "false": 0 }, 11790 _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(), 11791 _rootTimeline = Animation._rootTimeline = new SimpleTimeline(), 11792 _nextGCFrame = 30, 11793 _lazyRender = _internals.lazyRender = function () { 11794 var i = _lazyTweens.length, 11795 tween; 11796 _lazyLookup = {}; 11797 while (--i > -1) { 11798 tween = _lazyTweens[i]; 11799 if (tween && tween._lazy !== false) { 11800 tween.render(tween._lazy[0], tween._lazy[1], true); 11801 tween._lazy = false; 11802 } 11803 } 11804 _lazyTweens.length = 0; 11805 }; 11806 11807 _rootTimeline._startTime = _ticker.time; 11808 _rootFramesTimeline._startTime = _ticker.frame; 11809 _rootTimeline._active = _rootFramesTimeline._active = true; 11810 setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick". 11811 11812 Animation._updateRoot = TweenLite.render = function () { 11813 var i, a, p; 11814 if (_lazyTweens.length) { 11815 //if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again. 11816 _lazyRender(); 11817 } 11818 _rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false); 11819 _rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); 11820 if (_lazyTweens.length) { 11821 _lazyRender(); 11822 } 11823 if (_ticker.frame >= _nextGCFrame) { 11824 //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to 11825 _nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120); 11826 for (p in _tweenLookup) { 11827 a = _tweenLookup[p].tweens; 11828 i = a.length; 11829 while (--i > -1) { 11830 if (a[i]._gc) { 11831 a.splice(i, 1); 11832 } 11833 } 11834 if (a.length === 0) { 11835 delete _tweenLookup[p]; 11836 } 11837 } 11838 //if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly 11839 p = _rootTimeline._first; 11840 if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) { 11841 while (p && p._paused) { 11842 p = p._next; 11843 } 11844 if (!p) { 11845 _ticker.sleep(); 11846 } 11847 } 11848 } 11849 }; 11850 11851 _ticker.addEventListener("tick", Animation._updateRoot); 11852 11853 var _register = function (target, tween, scrub) { 11854 var id = target._gsTweenID, 11855 a, 11856 i; 11857 if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) { 11858 _tweenLookup[id] = { target: target, tweens: [] }; 11859 } 11860 if (tween) { 11861 a = _tweenLookup[id].tweens; 11862 a[i = a.length] = tween; 11863 if (scrub) { 11864 while (--i > -1) { 11865 if (a[i] === tween) { 11866 a.splice(i, 1); 11867 } 11868 } 11869 } 11870 } 11871 return _tweenLookup[id].tweens; 11872 }, 11873 _onOverwrite = function (overwrittenTween, overwritingTween, target, killedProps) { 11874 var func = overwrittenTween.vars.onOverwrite, 11875 r1, 11876 r2; 11877 if (func) { 11878 r1 = func(overwrittenTween, overwritingTween, target, killedProps); 11879 } 11880 func = TweenLite.onOverwrite; 11881 if (func) { 11882 r2 = func(overwrittenTween, overwritingTween, target, killedProps); 11883 } 11884 return r1 !== false && r2 !== false; 11885 }, 11886 _applyOverwrite = function (target, tween, props, mode, siblings) { 11887 var i, changed, curTween, l; 11888 if (mode === 1 || mode >= 4) { 11889 l = siblings.length; 11890 for (i = 0; i < l; i++) { 11891 if ((curTween = siblings[i]) !== tween) { 11892 if (!curTween._gc) { 11893 if (curTween._kill(null, target, tween)) { 11894 changed = true; 11895 } 11896 } 11897 } else if (mode === 5) { 11898 break; 11899 } 11900 } 11901 return changed; 11902 } 11903 //NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example) 11904 var startTime = tween._startTime + _tinyNum, 11905 overlaps = [], 11906 oCount = 0, 11907 zeroDur = tween._duration === 0, 11908 globalStart; 11909 i = siblings.length; 11910 while (--i > -1) { 11911 if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) { 11912 //ignore 11913 } else if (curTween._timeline !== tween._timeline) { 11914 globalStart = globalStart || _checkOverlap(tween, 0, zeroDur); 11915 if (_checkOverlap(curTween, globalStart, zeroDur) === 0) { 11916 overlaps[oCount++] = curTween; 11917 } 11918 } else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) { 11919 overlaps[oCount++] = curTween; 11920 } 11921 } 11922 11923 i = oCount; 11924 while (--i > -1) { 11925 curTween = overlaps[i]; 11926 if (mode === 2) if (curTween._kill(props, target, tween)) { 11927 changed = true; 11928 } 11929 if (mode !== 2 || !curTween._firstPT && curTween._initted) { 11930 if (mode !== 2 && !_onOverwrite(curTween, tween)) { 11931 continue; 11932 } 11933 if (curTween._enabled(false, false)) { 11934 //if all property tweens have been overwritten, kill the tween. 11935 changed = true; 11936 } 11937 } 11938 } 11939 return changed; 11940 }, 11941 _checkOverlap = function (tween, reference, zeroDur) { 11942 var tl = tween._timeline, 11943 ts = tl._timeScale, 11944 t = tween._startTime; 11945 while (tl._timeline) { 11946 t += tl._startTime; 11947 ts *= tl._timeScale; 11948 if (tl._paused) { 11949 return -100; 11950 } 11951 tl = tl._timeline; 11952 } 11953 t /= ts; 11954 return t > reference ? t - reference : zeroDur && t === reference || !tween._initted && t - reference < 2 * _tinyNum ? _tinyNum : (t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum ? 0 : t - reference - _tinyNum; 11955 }; 11956 11957 //---- TweenLite instance methods ----------------------------------------------------------------------------- 11958 11959 p._init = function () { 11960 var v = this.vars, 11961 op = this._overwrittenProps, 11962 dur = this._duration, 11963 immediate = !!v.immediateRender, 11964 ease = v.ease, 11965 i, 11966 initPlugins, 11967 pt, 11968 p, 11969 startVars, 11970 l; 11971 if (v.startAt) { 11972 if (this._startAt) { 11973 this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change. 11974 this._startAt.kill(); 11975 } 11976 startVars = {}; 11977 for (p in v.startAt) { 11978 //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from); 11979 startVars[p] = v.startAt[p]; 11980 } 11981 startVars.data = "isStart"; 11982 startVars.overwrite = false;
11983 startVars.immediateRender = true; 11984 startVars.lazy = immediate && v.lazy !== false; 11985 startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop). 11986 startVars.onUpdate = v.onUpdate; 11987 startVars.onUpdateParams = v.onUpdateParams; 11988 startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this; 11989 this._startAt = TweenLite.to(this.target, 0, startVars); 11990 if (immediate) { 11991 if (this._time > 0) { 11992 this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()). 11993 } else if (dur !== 0) { 11994 return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting. 11995 } 11996 } 11997 } else if (v.runBackwards && dur !== 0) { 11998 //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards) 11999 if (this._startAt) { 12000 this._startAt.render(-1, true); 12001 this._startAt.kill(); 12002 this._startAt = null; 12003 } else { 12004 if (this._time !== 0) { 12005 //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0 12006 immediate = false; 12007 } 12008 pt = {}; 12009 for (p in v) { 12010 //copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through. 12011 if (!_reservedProps[p] || p === "autoCSS") { 12012 pt[p] = v[p]; 12013 } 12014 } 12015 pt.overwrite = 0; 12016 pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in. 12017 pt.lazy = immediate && v.lazy !== false; 12018 pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after) 12019 this._startAt = TweenLite.to(this.target, 0, pt); 12020 if (!immediate) { 12021 this._startAt._init(); //ensures that the initial values are recorded 12022 this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween. 12023 if (this.vars.immediateRender) { 12024 this._startAt = null; 12025 } 12026 } else if (this._time === 0) { 12027 return; 12028 } 12029 } 12030 } 12031 this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase; 12032 if (v.easeParams instanceof Array && ease.config) { 12033 this._ease = ease.config.apply(ease, v.easeParams); 12034 } 12035 this._easeType = this._ease._type; 12036 this._easePower = this._ease._power; 12037 this._firstPT = null; 12038 12039 if (this._targets) { 12040 l = this._targets.length; 12041 for (i = 0; i < l; i++) { 12042 if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) { 12043 initPlugins = true; 12044 } 12045 } 12046 } else { 12047 initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0); 12048 } 12049 12050 if (initPlugins) { 12051 TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite 12052 } 12053 if (op) if (!this._firstPT) if (typeof this.target !== "function") { 12054 //if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live. 12055 this._enabled(false, false); 12056 } 12057 if (v.runBackwards) { 12058 pt = this._firstPT; 12059 while (pt) { 12060 pt.s += pt.c; 12061 pt.c = -pt.c; 12062 pt = pt._next; 12063 } 12064 } 12065 this._onUpdate = v.onUpdate; 12066 this._initted = true; 12067 }; 12068 12069 p._initProps = function (target, propLookup, siblings, overwrittenProps, index) { 12070 var p, i, initPlugins, plugin, pt, v; 12071 if (target == null) { 12072 return false;
12073 } 12074 12075 if (_lazyLookup[target._gsTweenID]) { 12076 _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end) 12077 } 12078 12079 if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { 12080 //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe. 12081 _autoCSS(this.vars, target); 12082 } 12083 for (p in this.vars) { 12084 v = this.vars[p]; 12085 if (_reservedProps[p]) { 12086 if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) { 12087 this.vars[p] = v = this._swapSelfInParams(v, this); 12088 } 12089 } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) { 12090 12091 //t - target [object] 12092 //p - property [string] 12093 //s - start [number] 12094 //c - change [number] 12095 //f - isFunction [boolean] 12096 //n - name [string] 12097 //pg - isPlugin [boolean] 12098 //pr - priority [number] 12099 //m - mod [function | 0] 12100 this._firstPT = pt = { _next: this._firstPT, t: plugin, p: "setRatio", s: 0, c: 1, f: 1, n: p, pg: 1, pr: plugin._priority, m: 0 }; 12101 i = plugin._overwriteProps.length; 12102 while (--i > -1) { 12103 propLookup[plugin._overwriteProps[i]] = this._firstPT; 12104 } 12105 if (plugin._priority || plugin._onInitAllProps) { 12106 initPlugins = true; 12107 } 12108 if (plugin._onDisable || plugin._onEnable) { 12109 this._notifyPluginsOfEnabled = true; 12110 } 12111 if (pt._next) { 12112 pt._next._prev = pt; 12113 } 12114 } else { 12115 propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index); 12116 } 12117 } 12118 12119 if (overwrittenProps) if (this._kill(overwrittenProps, target)) { 12120 //another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first) 12121 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 12122 } 12123 if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) { 12124 this._kill(propLookup, target); 12125 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 12126 } 12127 if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) { 12128 //zero duration tweens don't lazy render by default; everything else does. 12129 _lazyLookup[target._gsTweenID] = true; 12130 } 12131 return initPlugins; 12132 }; 12133 12134 p.render = function (time, suppressEvents, force) { 12135 var prevTime = this._time, 12136 duration = this._duration, 12137 prevRawPrevTime = this._rawPrevTime, 12138 isComplete, 12139 callback, 12140 pt, 12141 rawPrevTime; 12142 if (time >= duration - 0.0000001 && time >= 0) { 12143 //to work around occasional floating point math artifacts. 12144 this._totalTime = this._time = duration; 12145 this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1; 12146 if (!this._reversed) { 12147 isComplete = true; 12148 callback = "onComplete"; 12149 force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 12150 } 12151 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 12152 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 12153 if (this._startTime === this._timeline._duration) { 12154 //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
12154ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate. 12155 time = 0; 12156 } 12157 if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) { 12158 //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause. 12159 force = true; 12160 if (prevRawPrevTime > _tinyNum) { 12161 callback = "onReverseComplete"; 12162 } 12163 } 12164 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 12165 } 12166 } else if (time < 0.0000001) { 12167 //to work around occasional floating point math artifacts, round super small values to 0. 12168 this._totalTime = this._time = 0; 12169 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 12170 if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) { 12171 callback = "onReverseComplete"; 12172 isComplete = this._reversed; 12173 } 12174 if (time < 0) { 12175 this._active = false; 12176 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 12177 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 12178 if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) { 12179 force = true; 12180 } 12181 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 12182 } 12183 } 12184 if (!this._initted || this._startAt && this._startAt.progress()) { 12185 //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values. 12186 force = true; 12187 } 12188 } else { 12189 this._totalTime = this._time = time; 12190 12191 if (this._easeType) { 12192 var r = time / duration, 12193 type = this._easeType, 12194 pow = this._easePower; 12195 if (type === 1 || type === 3 && r >= 0.5) { 12196 r = 1 - r; 12197 } 12198 if (type === 3) { 12199 r *= 2; 12200 } 12201 if (pow === 1) { 12202 r *= r; 12203 } else if (pow === 2) { 12204 r *= r * r; 12205 } else if (pow === 3) { 12206 r *= r * r * r; 12207 } else if (pow === 4) { 12208 r *= r * r * r * r; 12209 } 12210 12211 if (type === 1) { 12212 this.ratio = 1 - r; 12213 } else if (type === 2) { 12214 this.ratio = r; 12215 } else if (time / duration < 0.5) { 12216 this.ratio = r / 2; 12217 } else { 12218 this.ratio = 1 - r / 2; 12219 } 12220 } else { 12221 this.ratio = this._ease.getRatio(time / duration); 12222 } 12223 } 12224 12225 if (this._time === prevTime && !force) { 12226 return; 12227 } else if (!this._initted) { 12228 this._init(); 12229 if (!this._initted || this._gc) { 12230 //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
12230writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example. 12231 return; 12232 } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) { 12233 this._time = this._totalTime = prevTime; 12234 this._rawPrevTime = prevRawPrevTime; 12235 _lazyTweens.push(this); 12236 this._lazy = [time, suppressEvents]; 12237 return; 12238 } 12239 //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. 12240 if (this._time && !isComplete) { 12241 this.ratio = this._ease.getRatio(this._time / duration); 12242 } else if (isComplete && this._ease._calcEnd) { 12243 this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1); 12244 } 12245 } 12246 if (this._lazy !== false) { 12247 //in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time. 12248 this._lazy = false; 12249 } 12250 if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { 12251 this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. 12252 } 12253 if (prevTime === 0) { 12254 if (this._startAt) { 12255 if (time >= 0) { 12256 this._startAt.render(time, true, force); 12257 } else if (!callback) { 12258 callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area. 12259 } 12260 } 12261 if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) { 12262 this._callback("onStart"); 12263 } 12264 } 12265 pt = this._firstPT; 12266 while (pt) { 12267 if (pt.f) { 12268 pt.t[pt.p](pt.c * this.ratio + pt.s); 12269 } else { 12270 pt.t[pt.p] = pt.c * this.ratio + pt.s; 12271 } 12272 pt = pt._next; 12273 } 12274 12275 if (this._onUpdate) { 12276 if (time < 0) if (this._startAt && time !== -0.0001) { 12277 //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 12278 this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 12279 } 12280 if (!suppressEvents) if (this._time !== prevTime || isComplete || force) { 12281 this._callback("onUpdate"); 12282 } 12283 } 12284 if (callback) if (!this._gc || force) { 12285 //check _gc because there's a chance that kill() could be called in an onUpdate 12286 if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) { 12287 //-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values. 12288 this._startAt.render(time, true, force); 12289 } 12290 if (isComplete) { 12291 if (this._timeline.autoRemoveChildren) { 12292 this._enabled(false, false); 12293 } 12294 this._active = false; 12295 } 12296 if (!suppressEvents && this.vars[callback]) { 12297 this._callback(callback); 12298 } 12299 if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { 12300 //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
12300nario, but possible nonetheless. 12301 this._rawPrevTime = 0; 12302 } 12303 } 12304 }; 12305 12306 p._kill = function (vars, target, overwritingTween) { 12307 if (vars === "all") { 12308 vars = null; 12309 } 12310 if (vars == null) if (target == null || target === this.target) { 12311 this._lazy = false; 12312 return this._enabled(false, false); 12313 } 12314 target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target; 12315 var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline, 12316 i, 12317 overwrittenProps, 12318 p, 12319 pt, 12320 propLookup, 12321 changed, 12322 killProps, 12323 record, 12324 killed; 12325 if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") { 12326 i = target.length; 12327 while (--i > -1) { 12328 if (this._kill(vars, target[i], overwritingTween)) { 12329 changed = true; 12330 } 12331 } 12332 } else { 12333 if (this._targets) { 12334 i = this._targets.length; 12335 while (--i > -1) { 12336 if (target === this._targets[i]) { 12337 propLookup = this._propLookup[i] || {}; 12338 this._overwrittenProps = this._overwrittenProps || []; 12339 overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all"; 12340 break; 12341 } 12342 } 12343 } else if (target !== this.target) { 12344 return false; 12345 } else { 12346 propLookup = this._propLookup; 12347 overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all"; 12348 } 12349 12350 if (propLookup) { 12351 killProps = vars || propLookup; 12352 record = vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof vars !== "object" || !vars._tempKill); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin) 12353 if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) { 12354 for (p in killProps) { 12355 if (propLookup[p]) { 12356 if (!killed) { 12357 killed = []; 12358 } 12359 killed.push(p); 12360 } 12361 } 12362 if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) { 12363 //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it). 12364 return false; 12365 } 12366 } 12367 12368 for (p in killProps) { 12369 if (pt = propLookup[p]) { 12370 if (simultaneousOverwrite) { 12371 //if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween. 12372 if (pt.f) { 12373 pt.t[pt.p](pt.s); 12374 } else { 12375 pt.t[pt.p] = pt.s; 12376 } 12377 changed = true; 12378 } 12379 if (pt.pg && pt.t._kill(killProps)) { 12380 changed = true; //some plugins need to be notified so they can perform cleanup tasks first 12381 } 12382 if (!pt.pg || pt.t._overwriteProps.length === 0) { 12383 if (pt._prev) { 12384 pt._prev._next = pt._next; 12385 } else if (pt === this._firstPT) { 12386 this._firstPT = pt._next; 12387 } 12388 if (pt._next) { 12389 pt._next._prev = pt._prev; 12390 } 12391 pt._next = pt._prev = null; 12392 } 12393 delete propLookup[p]; 12394 } 12395 if (record) { 12396 overwrittenProps[p] = 1; 12397 } 12398 } 12399 if (!this._firstPT && this._initted) { 12400 //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening. 12401 this._enabled(false, false); 12402 } 12403 } 12404 } 12405 return changed; 12406 }; 12407 12408 p.invalidate = function () { 12409 if (this._notifyPluginsOfEnabled) { 12410 TweenLite._onPluginEvent("_onDisable", this); 12411 } 12412 this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null; 12413 this._notifyPluginsOfEnabled = this._active = this._lazy = false;
12414 this._propLookup = this._targets ? {} : []; 12415 Animation.prototype.invalidate.call(this); 12416 if (this.vars.immediateRender) { 12417 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 12418 this.render(Math.min(0, -this._delay)); //in case delay is negative. 12419 } 12420 return this; 12421 }; 12422 12423 p._enabled = function (enabled, ignoreTimeline) { 12424 if (!_tickerActive) { 12425 _ticker.wake(); 12426 } 12427 if (enabled && this._gc) { 12428 var targets = this._targets, 12429 i; 12430 if (targets) { 12431 i = targets.length; 12432 while (--i > -1) { 12433 this._siblings[i] = _register(targets[i], this, true); 12434 } 12435 } else { 12436 this._siblings = _register(this.target, this, true); 12437 } 12438 } 12439 Animation.prototype._enabled.call(this, enabled, ignoreTimeline); 12440 if (this._notifyPluginsOfEnabled) if (this._firstPT) { 12441 return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this); 12442 } 12443 return false; 12444 }; 12445 12446 //----TweenLite static methods ----------------------------------------------------- 12447 12448 TweenLite.to = function (target, duration, vars) { 12449 return new TweenLite(target, duration, vars); 12450 }; 12451 12452 TweenLite.from = function (target, duration, vars) { 12453 vars.runBackwards = true; 12454 vars.immediateRender = vars.immediateRender != false; 12455 return new TweenLite(target, duration, vars); 12456 }; 12457 12458 TweenLite.fromTo = function (target, duration, fromVars, toVars) { 12459 toVars.startAt = fromVars; 12460 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 12461 return new TweenLite(target, duration, toVars); 12462 }; 12463 12464 TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) { 12465 return new TweenLite(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, lazy: false, useFrames: useFrames, overwrite: 0 }); 12466 }; 12467 12468 TweenLite.set = function (target, vars) { 12469 return new TweenLite(target, 0, vars); 12470 }; 12471 12472 TweenLite.getTweensOf = function (target, onlyActive) { 12473 if (target == null) { 12474 return []; 12475 } 12476 target = typeof target !== "string" ? target : TweenLite.selector(target) || target; 12477 var i, a, j, t; 12478 if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") { 12479 i = target.length; 12480 a = []; 12481 while (--i > -1) { 12482 a = a.concat(TweenLite.getTweensOf(target[i], onlyActive)); 12483 } 12484 i = a.length; 12485 //now get rid of any duplicates (tweens of arrays of objects could cause duplicates) 12486 while (--i > -1) { 12487 t = a[i]; 12488 j = i; 12489 while (--j > -1) { 12490 if (t === a[j]) { 12491 a.splice(i, 1); 12492 } 12493 } 12494 } 12495 } else if (target._gsTweenID) { 12496 a = _register(target).concat(); 12497 i = a.length; 12498 while (--i > -1) { 12499 if (a[i]._gc || onlyActive && !a[i].isActive()) { 12500 a.splice(i, 1); 12501 } 12502 } 12503 } 12504 return a || []; 12505 }; 12506 12507 TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) { 12508 if (typeof onlyActive === "object") { 12509 vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted) 12510 onlyActive = false; 12511 } 12512 var a = TweenLite.getTweensOf(target, onlyActive), 12513 i = a.length; 12514 while (--i > -1) { 12515 a[i]._kill(vars, target); 12516 } 12517 }; 12518 12519 /* 12520 * ---------------------------------------------------------------- 12521 * TweenPlugin (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget) 12522 * ---------------------------------------------------------------- 12523 */ 12524 var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) { 12525 this._overwriteProps = (props || "").split(","); 12526 this._propName = this._overwriteProps[0]; 12527 this._priority = priority || 0; 12528 this._super = TweenPlugin.prototype; 12529 }, true); 12530 12531 p = TweenPlugin.prototype; 12532 TweenPlugin.version = "1.19.0"; 12533 TweenPlugin.API = 2; 12534 p._firstPT = null; 12535 p._addTween = _addPropTween; 12536 p.setRatio = _setRatio; 12537 12538 p._kill = function (lookup) { 12539 var a = this._overwriteProps, 12540 pt = this._firstPT, 12541 i; 12542 if (lookup[this._propName] != null) { 12543 this._overwriteProps = []; 12544 } else { 12545 i = a.length; 12546 while (--i > -1) { 12547 if (lookup[a[i]] != null) { 12548 a.splice(i, 1); 12549 } 12550 } 12551 } 12552 while (pt) { 12553 if (lookup[pt.n] != null) { 12554 if (pt._next) { 12555 pt._next._prev = pt._prev; 12556 } 12557 if (pt._prev) { 12558 pt._prev._next = pt._next; 12559 pt._prev = null; 12560 } else if (this._firstPT === pt) { 12561 this._firstPT = pt._next; 12562 } 12563 } 12564 pt = pt._next; 12565 } 12566 return false;
12567 }; 12568 12569 p._mod = p._roundProps = function (lookup) { 12570 var pt = this._firstPT, 12571 val; 12572 while (pt) { 12573 val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")]; 12574 if (val && typeof val === "function") { 12575 //some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here. 12576 if (pt.f === 2) { 12577 pt.t._applyPT.m = val; 12578 } else { 12579 pt.m = val; 12580 } 12581 } 12582 pt = pt._next; 12583 } 12584 }; 12585 12586 TweenLite._onPluginEvent = function (type, tween) { 12587 var pt = tween._firstPT, 12588 changed, 12589 pt2, 12590 first, 12591 last, 12592 next; 12593 if (type === "_onInitAllProps") { 12594 //sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame. 12595 while (pt) { 12596 next = pt._next; 12597 pt2 = first; 12598 while (pt2 && pt2.pr > pt.pr) { 12599 pt2 = pt2._next; 12600 } 12601 if (pt._prev = pt2 ? pt2._prev : last) { 12602 pt._prev._next = pt; 12603 } else { 12604 first = pt; 12605 } 12606 if (pt._next = pt2) { 12607 pt2._prev = pt; 12608 } else { 12609 last = pt; 12610 } 12611 pt = next; 12612 } 12613 pt = tween._firstPT = first; 12614 } 12615 while (pt) { 12616 if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) { 12617 changed = true; 12618 } 12619 pt = pt._next; 12620 } 12621 return changed; 12622 }; 12623 12624 TweenPlugin.activate = function (plugins) { 12625 var i = plugins.length; 12626 while (--i > -1) { 12627 if (plugins[i].API === TweenPlugin.API) { 12628 _plugins[new plugins[i]()._propName] = plugins[i]; 12629 } 12630 } 12631 return true; 12632 }; 12633 12634 //provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations. 12635 _gsDefine.plugin = function (config) { 12636 if (!config || !config.propName || !config.init || !config.API) { 12637 throw "illegal plugin definition."; 12638 } 12639 var propName = config.propName, 12640 priority = config.priority || 0, 12641 overwriteProps = config.overwriteProps, 12642 map = { init: "_onInitTween", set: "setRatio", kill: "_kill", round: "_mod", mod: "_mod", initAll: "_onInitAllProps" }, 12643 Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () { 12644 TweenPlugin.call(this, propName, priority); 12645 this._overwriteProps = overwriteProps || []; 12646 }, config.global === true), 12647 p = Plugin.prototype = new TweenPlugin(propName), 12648 prop; 12649 p.constructor = Plugin; 12650 Plugin.API = config.API; 12651 for (prop in map) { 12652 if (typeof config[prop] === "function") { 12653 p[map[prop]] = config[prop]; 12654 } 12655 } 12656 Plugin.version = config.version; 12657 TweenPlugin.activate([Plugin]); 12658 return Plugin; 12659 }; 12660 12661 //now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you. 12662 a = window._gsQueue; 12663 if (a) { 12664 for (i = 0; i < a.length; i++) { 12665 a[i](); 12666 } 12667 for (p in _defLookup) { 12668 if (!_defLookup[p].func) { 12669 window.console.log("GSAP encountered missing dependency: " + p); 12670 } 12671 } 12672 } 12673 12674 _tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated 12675})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window, "TweenLite"); 12676/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) 12677 12678/***/ }), 12679/* 2 */ 12680/***/ (function(module, exports, __webpack_require__) { 12681 12682var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 12683 * ScrollMagic v2.0.5 (2015-04-29) 12684 * The javascript library for magical scroll interactions. 12685 * (c) 2015 Jan Paepke (@janpaepke) 12686 * Project Website: http://scrollmagic.io 12687 * 12688 * @version 2.0.5 12689 * @license Dual licensed under MIT license and GPL. 12690 * @author Jan Paepke - [email protected] 12691 * 12692 * @file ScrollMagic main library. 12693 */ 12694/** 12695 * @namespace ScrollMagic 12696 */ 12697(function (root, factory) { 12698 if (true) { 12699 // AMD. Register as an anonymous module. 12700 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 12701 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 12702 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 12703 __WEBPACK_AMD_DEFINE_FACTORY__),
12704 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 12705 } else if (typeof exports === 'object') { 12706 // CommonJS 12707 module.exports = factory(); 12708 } else { 12709 // Browser global 12710 root.ScrollMagic = factory(); 12711 } 12712})(this, function () { 12713 "use strict"; 12714 12715 var ScrollMagic = function () { 12716 _util.log(2, '(COMPATIBILITY NOTICE) -> As of ScrollMagic 2.0.0 you need to use \'new ScrollMagic.Controller()\' to create a new controller instance. Use \'new ScrollMagic.Scene()\' to instance a scene.'); 12717 }; 12718 12719 ScrollMagic.version = "2.0.5"; 12720 12721 // TODO: temporary workaround for chrome's scroll jitter bug 12722 window.addEventListener("mousewheel", function () {}); 12723 12724 // global const 12725 var PIN_SPACER_ATTRIBUTE = "data-scrollmagic-pin-spacer"; 12726 12727 /** 12728 * The main class that is needed once per scroll container. 12729 * 12730 * @class 12731 * 12732 * @example 12733 * // basic initialization 12734 * var controller = new ScrollMagic.Controller(); 12735 * 12736 * // passing options 12737 * var controller = new ScrollMagic.Controller({container: "#myContainer", loglevel: 3}); 12738 * 12739 * @param {object} [options] - An object containing one or more options for the controller. 12740 * @param {(string|object)} [options.container=window] - A selector, DOM object that references the main container for scrolling. 12741 * @param {boolean} [options.vertical=true] - Sets the scroll mode to vertical (`true`) or horizontal (`false`) scrolling. 12742 * @param {object} [options.globalSceneOptions={}] - These options will be passed to every Scene that is added to the controller using the addScene method. For more information on Scene options see {@link ScrollMagic.Scene}. 12743 * @param {number} [options.loglevel=2] Loglevel for debugging. Note that logging is disabled in the minified version of ScrollMagic. 12744 ** `0` => silent 12745 ** `1` => errors 12746 ** `2` => errors, warnings 12747 ** `3` => errors, warnings, debuginfo 12748 * @param {boolean} [options.refreshInterval=100] - Some changes don't call events by default, like changing the container size or moving a scene trigger element. 12749 This interval polls these parameters to fire the necessary events. 12750 If you don't use custom containers, trigger elements or have static layouts, where the positions of the trigger elements don't change, you can set this to 0 disable interval checking and improve performance. 12751 * 12752 */ 12753 ScrollMagic.Controller = function (options) { 12754 /* 12755 * ---------------------------------------------------------------- 12756 * settings 12757 * ---------------------------------------------------------------- 12758 */ 12759 var NAMESPACE = 'ScrollMagic.Controller', 12760 SCROLL_DIRECTION_FORWARD = 'FORWARD', 12761 SCROLL_DIRECTION_REVERSE = 'REVERSE', 12762 SCROLL_DIRECTION_PAUSED = 'PAUSED', 12763 DEFAULT_OPTIONS = CONTROLLER_OPTIONS.defaults; 12764 12765 /* 12766 * ---------------------------------------------------------------- 12767 * private vars 12768 * ---------------------------------------------------------------- 12769 */ 12770 var Controller = this, 12771 _options = _util.extend({}, DEFAULT_OPTIONS, options), 12772 _sceneObjects = [], 12773 _updateScenesOnNextCycle = false, 12774 12775 // can be boolean (true => all scenes) or an array of scenes to be updated 12776 _scrollPos = 0, 12777 _scrollDirection = SCROLL_DIRECTION_PAUSED, 12778 _isDocument = true, 12779 _viewPortSize = 0, 12780 _enabled = true, 12781 _updateTimeout, 12782 _refreshTimeout; 12783 12784 /* 12785 * ---------------------------------------------------------------- 12786 * private functions 12787 * ---------------------------------------------------------------- 12788 */ 12789 12790 /** 12791 * Internal constructor function of the ScrollMagic Controller 12792 * @private 12793 */ 12794 var construct = function () { 12795 for (var key in _options) { 12796 if (!DEFAULT_OPTIONS.hasOwnProperty(key)) { 12797 log(2, "WARNING: Unknown option \"" + key + "\""); 12798 delete _options[key]; 12799 } 12800 } 12801 _options.container = _util.get.elements(_options.container)[0];
12802 // check ScrollContainer 12803 if (!_options.container) { 12804 log(1, "ERROR creating object " + NAMESPACE + ": No valid scroll container supplied"); 12805 throw NAMESPACE + " init failed."; // cancel 12806 } 12807 _isDocument = _options.container === window || _options.container === document.body || !document.body.contains(_options.container); 12808 // normalize to window 12809 if (_isDocument) { 12810 _options.container = window; 12811 } 12812 // update container size immediately 12813 _viewPortSize = getViewportSize(); 12814 // set event handlers 12815 _options.container.addEventListener("resize", onChange); 12816 _options.container.addEventListener("scroll", onChange); 12817 12818 _options.refreshInterval = parseInt(_options.refreshInterval) || DEFAULT_OPTIONS.refreshInterval; 12819 scheduleRefresh(); 12820 12821 log(3, "added new " + NAMESPACE + " controller (v" + ScrollMagic.version + ")"); 12822 }; 12823 12824 /** 12825 * Schedule the next execution of the refresh function 12826 * @private 12827 */ 12828 var scheduleRefresh = function () { 12829 if (_options.refreshInterval > 0) { 12830 _refreshTimeout = window.setTimeout(refresh, _options.refreshInterval); 12831 } 12832 }; 12833 12834 /** 12835 * Default function to get scroll pos - overwriteable using `Controller.scrollPos(newFunction)` 12836 * @private 12837 */ 12838 var getScrollPos = function () { 12839 return _options.vertical ? _util.get.scrollTop(_options.container) : _util.get.scrollLeft(_options.container); 12840 }; 12841 12842 /** 12843 * Returns the current viewport Size (width vor horizontal, height for vertical) 12844 * @private 12845 */ 12846 var getViewportSize = function () { 12847 return _options.vertical ? _util.get.height(_options.container) : _util.get.width(_options.container); 12848 }; 12849 12850 /** 12851 * Default function to set scroll pos - overwriteable using `Controller.scrollTo(newFunction)` 12852 * Make available publicly for pinned mousewheel workaround. 12853 * @private 12854 */ 12855 var setScrollPos = this._setScrollPos = function (pos) { 12856 if (_options.vertical) { 12857 if (_isDocument) { 12858 window.scrollTo(_util.get.scrollLeft(), pos); 12859 } else { 12860 _options.container.scrollTop = pos; 12861 } 12862 } else { 12863 if (_isDocument) { 12864 window.scrollTo(pos, _util.get.scrollTop()); 12865 } else { 12866 _options.container.scrollLeft = pos; 12867 } 12868 } 12869 }; 12870 12871 /** 12872 * Handle updates in cycles instead of on scroll (performance) 12873 * @private 12874 */ 12875 var updateScenes = function () { 12876 if (_enabled && _updateScenesOnNextCycle) { 12877 // determine scenes to update 12878 var scenesToUpdate = _util.type.Array(_updateScenesOnNextCycle) ? _updateScenesOnNextCycle : _sceneObjects.slice(0); 12879 // reset scenes 12880 _updateScenesOnNextCycle = false; 12881 var oldScrollPos = _scrollPos; 12882 // update scroll pos now instead of onChange, as it might have changed since scheduling (i.e. in-browser smooth scroll) 12883 _scrollPos = Controller.scrollPos(); 12884 var deltaScroll = _scrollPos - oldScrollPos; 12885 if (deltaScroll !== 0) { 12886 // scroll position changed? 12887 _scrollDirection = deltaScroll > 0 ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_REVERSE; 12888 } 12889 // reverse order of scenes if scrolling reverse 12890 if (_scrollDirection === SCROLL_DIRECTION_REVERSE) { 12891 scenesToUpdate.reverse(); 12892 } 12893 // update scenes 12894 scenesToUpdate.forEach(function (scene, index) { 12895 log(3, "updating Scene " + (index + 1) + "/" + scenesToUpdate.length + " (" + _sceneObjects.length + " total)"); 12896 scene.update(true); 12897 }); 12898 if (scenesToUpdate.length === 0 && _options.loglevel >= 3) { 12899 log(3, "updating 0 Scenes (nothing added to controller)"); 12900 } 12901 } 12902 }; 12903 12904 /** 12905 * Initializes rAF callback 12906 * @private 12907 */ 12908 var debounceUpdate = function () { 12909 _updateTimeout = _util.rAF(updateScenes); 12910 }; 12911 12912 /** 12913 * Handles Container changes 12914 * @private 12915 */ 12916 var onChange = function (e) { 12917 log(3, "event fired causing an update:", e.type); 12918 if (e.type == "resize") { 12919 // resize 12920 _viewPortSize = getViewportSize(); 12921 _scrollDirection = SCROLL_DIRECTION_PAUSED; 12922 } 12923 // schedule update 12924 if (_updateScenesOnNextCycle !== true) { 12925 _updateScenesOnNextCycle = true; 12926 debounceUpdate(); 12927 } 12928 }; 12929 12930 var refresh = function () { 12931 if (!_isDocument) { 12932 // simulate resize event. Only works for viewport relevant param (performance) 12933 if (_viewPortSize != getViewportSize()) { 12934 var resizeEvent; 12935 try { 12936 resizeEvent = new Event('resize', { 12937 bubbles: false, 12938 cancelable: false 12939 }); 12940 } catch (e) { 12941 // stupid IE 12942 resizeEvent = document.createEvent("Event"); 12943 resizeEvent.initEvent("resize", false, false); 12944 }
12945 _options.container.dispatchEvent(resizeEvent); 12946 } 12947 } 12948 _sceneObjects.forEach(function (scene, index) { 12949 // refresh all scenes 12950 scene.refresh(); 12951 }); 12952 scheduleRefresh(); 12953 }; 12954 12955 /** 12956 * Send a debug message to the console. 12957 * provided publicly with _log for plugins 12958 * @private 12959 * 12960 * @param {number} loglevel - The loglevel required to initiate output for the message. 12961 * @param {...mixed} output - One or more variables that should be passed to the console. 12962 */ 12963 var log = this._log = function (loglevel, output) { 12964 if (_options.loglevel >= loglevel) { 12965 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ") ->"); 12966 _util.log.apply(window, arguments); 12967 } 12968 }; 12969 // for scenes we have getters for each option, but for the controller we don't, so we need to make it available externally for plugins 12970 this._options = _options; 12971 12972 /** 12973 * Sort scenes in ascending order of their start offset. 12974 * @private 12975 * 12976 * @param {array} ScenesArray - an array of ScrollMagic Scenes that should be sorted 12977 * @return {array} The sorted array of Scenes. 12978 */ 12979 var sortScenes = function (ScenesArray) { 12980 if (ScenesArray.length <= 1) { 12981 return ScenesArray; 12982 } else { 12983 var scenes = ScenesArray.slice(0); 12984 scenes.sort(function (a, b) { 12985 return a.scrollOffset() > b.scrollOffset() ? 1 : -1; 12986 }); 12987 return scenes; 12988 } 12989 }; 12990 12991 /** 12992 * ---------------------------------------------------------------- 12993 * public functions 12994 * ---------------------------------------------------------------- 12995 */ 12996 12997 /** 12998 * Add one ore more scene(s) to the controller. 12999 * This is the equivalent to `Scene.addTo(controller)`. 13000 * @public 13001 * @example 13002 * // with a previously defined scene 13003 * controller.addScene(scene); 13004 * 13005 * // with a newly created scene. 13006 * controller.addScene(new ScrollMagic.Scene({duration : 0})); 13007 * 13008 * // adding multiple scenes 13009 * controller.addScene([scene, scene2, new ScrollMagic.Scene({duration : 0})]); 13010 * 13011 * @param {(ScrollMagic.Scene|array)} newScene - ScrollMagic Scene or Array of Scenes to be added to the controller. 13012 * @return {Controller} Parent object for chaining. 13013 */ 13014 this.addScene = function (newScene) { 13015 if (_util.type.Array(newScene)) { 13016 newScene.forEach(function (scene, index) { 13017 Controller.addScene(scene); 13018 }); 13019 } else if (newScene instanceof ScrollMagic.Scene) { 13020 if (newScene.controller() !== Controller) { 13021 newScene.addTo(Controller); 13022 } else if (_sceneObjects.indexOf(newScene) < 0) { 13023 // new scene 13024 _sceneObjects.push(newScene); // add to array 13025 _sceneObjects = sortScenes(_sceneObjects); // sort 13026 newScene.on("shift.controller_sort", function () { 13027 // resort whenever scene moves 13028 _sceneObjects = sortScenes(_sceneObjects); 13029 }); 13030 // insert Global defaults. 13031 for (var key in _options.globalSceneOptions) { 13032 if (newScene[key]) { 13033 newScene[key].call(newScene, _options.globalSceneOptions[key]); 13034 } 13035 } 13036 log(3, "adding Scene (now " + _sceneObjects.length + " total)"); 13037 } 13038 } else { 13039 log(1, "ERROR: invalid argument supplied for '.addScene()'"); 13040 } 13041 return Controller; 13042 }; 13043 13044 /** 13045 * Remove one ore more scene(s) from the controller. 13046 * This is the equivalent to `Scene.remove()`. 13047 * @public 13048 * @example 13049 * // remove a scene from the controller 13050 * controller.removeScene(scene); 13051 * 13052 * // remove multiple scenes from the controller 13053 * controller.removeScene([scene, scene2, scene3]); 13054 * 13055 * @param {(ScrollMagic.Scene|array)} Scene - ScrollMagic Scene or Array of Scenes to be removed from the controller. 13056 * @returns {Controller} Parent object for chaining. 13057 */ 13058 this.removeScene = function (Scene) { 13059 if (_util.type.Array(Scene)) { 13060 Scene.forEach(function (scene, index) { 13061 Controller.removeScene(scene); 13062 }); 13063 } else { 13064 var index = _sceneObjects.indexOf(Scene); 13065 if (index > -1) { 13066 Scene.off("shift.controller_sort"); 13067 _sceneObjects.splice(index, 1); 13068 log(3, "removing Scene (now " + _sceneObjects.length + " left)"); 13069 Scene.remove(); 13070 } 13071 } 13072 return Controller; 13073 }; 13074 13075 /** 13076 * Update one ore more scene(s) according to the scroll position of the container.
13077 * This is the equivalent to `Scene.update()`. 13078 * The update method calculates the scene's start and end position (based on the trigger element, trigger hook, duration and offset) and checks it against the current scroll position of the container. 13079 * It then updates the current scene state accordingly (or does nothing, if the state is already correct) â Pins will be set to their correct position and tweens will be updated to their correct progress. 13080 * _**Note:** This method gets called constantly whenever Controller detects a change. The only application for you is if you change something outside of the realm of ScrollMagic, like moving the trigger or changing tween parameters._ 13081 * @public 13082 * @example 13083 * // update a specific scene on next cycle 13084 * controller.updateScene(scene); 13085 * 13086 * // update a specific scene immediately 13087 * controller.updateScene(scene, true); 13088 * 13089 * // update multiple scenes scene on next cycle 13090 * controller.updateScene([scene1, scene2, scene3]); 13091 * 13092 * @param {ScrollMagic.Scene} Scene - ScrollMagic Scene or Array of Scenes that is/are supposed to be updated. 13093 * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle. 13094 This is useful when changing multiple properties of the scene - this way it will only be updated once all new properties are set (updateScenes). 13095 * @return {Controller} Parent object for chaining. 13096 */ 13097 this.updateScene = function (Scene, immediately) { 13098 if (_util.type.Array(Scene)) { 13099 Scene.forEach(function (scene, index) { 13100 Controller.updateScene(scene, immediately); 13101 }); 13102 } else { 13103 if (immediately) { 13104 Scene.update(true); 13105 } else if (_updateScenesOnNextCycle !== true && Scene instanceof ScrollMagic.Scene) { 13106 // if _updateScenesOnNextCycle is true, all connected scenes are already scheduled for update 13107 // prep array for next update cycle 13108 _updateScenesOnNextCycle = _updateScenesOnNextCycle || []; 13109 if (_updateScenesOnNextCycle.indexOf(Scene) == -1) { 13110 _updateScenesOnNextCycle.push(Scene); 13111 } 13112 _updateScenesOnNextCycle = sortScenes(_updateScenesOnNextCycle); // sort 13113 debounceUpdate(); 13114 } 13115 } 13116 return Controller; 13117 }; 13118 13119 /** 13120 * Updates the controller params and calls updateScene on every scene, that is attached to the controller. 13121 * See `Controller.updateScene()` for more information about what this means. 13122 * In most cases you will not need this function, as it is called constantly, whenever ScrollMagic detects a state change event, like resize or scroll. 13123 * The only application for this method is when ScrollMagic fails to detect these events. 13124 * One application is with some external scroll libraries (like iScroll) that move an internal container to a negative offset instead of actually scrolling. In this case the update on the controller needs to be called whenever the child container's position changes. 13125 * For this case there will also be the need to provide a custom function to calculate the correct scroll position. See `Controller.scrollPos()` for details. 13126 * @public 13127 * @example 13128 * // update the controller on next cycle (saves performance due to elimination of redundant updates) 13129 * controller.update(); 13130 * 13131 * // update the controller immediately 13132 * controller.update(true); 13133 * 13134 * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle (better performance) 13135 * @return {Controller} Parent object for chaining. 13136 */ 13137 this.update = function (immediately) { 13138 onChange({ 13139 type: "resize" 13140 }); // will update size and set _updateScenesOnNextCycle to true 13141 if (immediately) { 13142 updateScenes(); 13143 } 13144 return Controller; 13145 }; 13146 13147 /** 13148 * Scroll to a numeric scroll offset, a DOM element, the start of a scene or provide an alternate method for scrolling. 13149 * For vertical controllers it will change the top scroll offset and for horizontal applications it will change the left offset. 13150 * @public 13151 * 13152 * @since 1.1.0 13153 * @example 13154 * // scroll to an offset of 100 13155 * controller.scrollTo(100); 13156 * 13157 * // scroll to a DOM element 13158 * controller.scrollTo("#anchor"); 13159 * 13160 * // scroll to the beginning of a scene 13161 * var scene = new ScrollMagic.Scene({offset: 200}); 13162 * controller.scrollTo(scene); 13163 * 13164 * // define a new scroll position modification function (jQuery animate instead of jump) 13165 * controller.scrollTo(function (newScrollPos) { 13166 * $("html, body").animate({scrollTop: newScrollPos}); 13167 * }); 13168 * controller.scrollTo(100); // call as usual, but the new function will be used instead 13169 * 13170 * // define a new scroll function with an additional parameter 13171 * controller.scrollTo(function (newScrollPos, message) { 13172 * console.log(message); 13173 * $(this).animate({scrollTop: newScrollPos}); 13174 * }); 13175 * // call as usual, but supply an extra parameter to the defined custom function 13176 * controller.scrollTo(100, "my message"); 13177 * 13178 * // define a new scroll function with an additional parameter containing multiple variables 13179 * controller.scrollTo(function (newScrollPos, options) { 13180 * someGlobalVar = options.a + options.b; 13181 * $(this).animate({scrollTop: newScrollPos}); 13182 * }); 13183 * // call as usual, but supply an extra parameter containing multiple options 13184 * controller.scrollTo(100, {a: 1, b: 2}); 13185 * 13186 * // define a new scroll function with a callback supplied as an additional parameter 13187 * controller.scrollTo(function (newScrollPos, callback) { 13188 * $(this).animate({scrollTop: newScrollPos}, 400, "swing", callback); 13189 * }); 13190 * // call as usual, but supply an extra parameter, which is used as a callback in the previously defined custom scroll function 13191 * controller.scrollTo(100, function() { 13192 * console.log("scroll has finished."); 13193 * }); 13194 * 13195 * @param {mixed} scrollTarget - The supplied argument can be one of these types: 13196 * 1. `number` -> The container will scroll to this new scroll offset. 13197 * 2. `string` or `object` -> Can be a selector or a DOM object. 13198 * The container will scroll to the position of this element. 13199 * 3. `ScrollMagic Scene` -> The container will scroll to the start of this scene. 13200 * 4. `function` -> This function will be used for future scroll position modifications. 13201 * This provides a way for you to change the behaviour of scrolling and adding new behaviour like animation. The function receives the new scroll position as a parameter and a reference to the container element using `this`.
13202 * It may also optionally receive an optional additional parameter (see below) 13203 * _**NOTE:** 13204 * All other options will still work as expected, using the new function to scroll._ 13205 * @param {mixed} [additionalParameter] - If a custom scroll function was defined (see above 4.), you may want to supply additional parameters to it, when calling it. You can do this using this parameter â see examples for details. Please note, that this parameter will have no effect, if you use the default scrolling function. 13206 * @returns {Controller} Parent object for chaining. 13207 */ 13208 this.scrollTo = function (scrollTarget, additionalParameter) { 13209 if (_util.type.Number(scrollTarget)) { 13210 // excecute 13211 setScrollPos.call(_options.container, scrollTarget, additionalParameter); 13212 } else if (scrollTarget instanceof ScrollMagic.Scene) { 13213 // scroll to scene 13214 if (scrollTarget.controller() === Controller) { 13215 // check if the controller is associated with this scene 13216 Controller.scrollTo(scrollTarget.scrollOffset(), additionalParameter); 13217 } else { 13218 log(2, "scrollTo(): The supplied scene does not belong to this controller. Scroll cancelled.", scrollTarget); 13219 } 13220 } else if (_util.type.Function(scrollTarget)) { 13221 // assign new scroll function 13222 setScrollPos = scrollTarget; 13223 } else { 13224 // scroll to element 13225 var elem = _util.get.elements(scrollTarget)[0]; 13226 if (elem) { 13227 // if parent is pin spacer, use spacer position instead so correct start position is returned for pinned elements. 13228 while (elem.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) { 13229 elem = elem.parentNode; 13230 } 13231 13232 var param = _options.vertical ? "top" : "left", 13233 13234 // which param is of interest ? 13235 containerOffset = _util.get.offset(_options.container), 13236 13237 // container position is needed because element offset is returned in relation to document, not in relation to container. 13238 elementOffset = _util.get.offset(elem); 13239 13240 if (!_isDocument) { 13241 // container is not the document root, so substract scroll Position to get correct trigger element position relative to scrollcontent 13242 containerOffset[param] -= Controller.scrollPos(); 13243 } 13244 13245 Controller.scrollTo(elementOffset[param] - containerOffset[param], additionalParameter); 13246 } else { 13247 log(2, "scrollTo(): The supplied argument is invalid. Scroll cancelled.", scrollTarget); 13248 } 13249 } 13250 return Controller; 13251 }; 13252 13253 /** 13254 * **Get** the current scrollPosition or **Set** a new method to calculate it. 13255 * -> **GET**: 13256 * When used as a getter this function will return the current scroll position. 13257 * To get a cached value use Controller.info("scrollPos"), which will be updated in the update cycle. 13258 * For vertical controllers it will return the top scroll offset and for horizontal applications it will return the left offset. 13259 * 13260 * -> **SET**: 13261 * When used as a setter this method prodes a way to permanently overwrite the controller's scroll position calculation. 13262 * A typical usecase is when the scroll position is not reflected by the containers scrollTop or scrollLeft values, but for example by the inner offset of a child container. 13263 * Moving a child container inside a parent is a commonly used method for several scrolling frameworks, including iScroll. 13264 * By providing an alternate calculation function you can make sure ScrollMagic receives the correct scroll position. 13265 * Please also bear in mind that your function should return y values for vertical scrolls an x for horizontals. 13266 * 13267 * To change the current scroll position please use `Controller.scrollTo()`. 13268 * @public 13269 * 13270 * @example 13271 * // get the current scroll Position 13272 * var scrollPos = controller.scrollPos(); 13273 * 13274 * // set a new scroll position calculation method 13275 * controller.scrollPos(function () { 13276 * return this.info("vertical") ? -mychildcontainer.y : -mychildcontainer.x 13277 * }); 13278 * 13279 * @param {function} [scrollPosMethod] - The function to be used for the scroll position calculation of the container. 13280 * @returns {(number|Controller)} Current scroll position or parent object for chaining. 13281 */ 13282 this.scrollPos = function (scrollPosMethod) { 13283 if (!arguments.length) { 13284 // get 13285 return getScrollPos.call(Controller); 13286 } else { 13287 // set 13288 if (_util.type.Function(scrollPosMethod)) { 13289 getScrollPos = scrollPosMethod; 13290 } else { 13291 log(2, "Provided value for method 'scrollPos' is not a function. To change the current scroll position use 'scrollTo()'."); 13292 } 13293 } 13294 return Controller; 13295 }; 13296 13297 /** 13298 * **Get** all infos or one in particular about the controller. 13299 * @public 13300 * @example 13301 * // returns the current scroll position (number) 13302 * var scrollPos = controller.info("scrollPos"); 13303 * 13304 * // returns all infos as an object 13305 * var infos = controller.info(); 13306 * 13307 * @param {string} [about] - If passed only this info will be returned instead of an object c
13307ontaining all. 13308 Valid options are: 13309 ** `"size"` => the current viewport size of the container 13310 ** `"vertical"` => true if vertical scrolling, otherwise false 13311 ** `"scrollPos"` => the current scroll position 13312 ** `"scrollDirection"` => the last known direction of the scroll 13313 ** `"container"` => the container element 13314 ** `"isDocument"` => true if container element is the document. 13315 * @returns {(mixed|object)} The requested info(s). 13316 */ 13317 this.info = function (about) { 13318 var values = { 13319 size: _viewPortSize, 13320 // contains height or width (in regard to orientation); 13321 vertical: _options.vertical, 13322 scrollPos: _scrollPos, 13323 scrollDirection: _scrollDirection, 13324 container: _options.container, 13325 isDocument: _isDocument 13326 }; 13327 if (!arguments.length) { 13328 // get all as an object 13329 return values; 13330 } else if (values[about] !== undefined) { 13331 return values[about]; 13332 } else { 13333 log(1, "ERROR: option \"" + about + "\" is not available"); 13334 return; 13335 } 13336 }; 13337 13338 /** 13339 * **Get** or **Set** the current loglevel option value. 13340 * @public 13341 * 13342 * @example 13343 * // get the current value 13344 * var loglevel = controller.loglevel(); 13345 * 13346 * // set a new value 13347 * controller.loglevel(3); 13348 * 13349 * @param {number} [newLoglevel] - The new loglevel setting of the Controller. `[0-3]` 13350 * @returns {(number|Controller)} Current loglevel or parent object for chaining. 13351 */ 13352 this.loglevel = function (newLoglevel) { 13353 if (!arguments.length) { 13354 // get 13355 return _options.loglevel; 13356 } else if (_options.loglevel != newLoglevel) { 13357 // set 13358 _options.loglevel = newLoglevel; 13359 } 13360 return Controller; 13361 }; 13362 13363 /** 13364 * **Get** or **Set** the current enabled state of the controller. 13365 * This can be used to disable all Scenes connected to the controller without destroying or removing them. 13366 * @public 13367 * 13368 * @example 13369 * // get the current value 13370 * var enabled = controller.enabled(); 13371 * 13372 * // disable the controller 13373 * controller.enabled(false); 13374 * 13375 * @param {boolean} [newState] - The new enabled state of the controller `true` or `false`. 13376 * @returns {(boolean|Controller)} Current enabled state or parent object for chaining. 13377 */ 13378 this.enabled = function (newState) { 13379 if (!arguments.length) { 13380 // get 13381 return _enabled; 13382 } else if (_enabled != newState) { 13383 // set 13384 _enabled = !!newState; 13385 Controller.updateScene(_sceneObjects, true); 13386 } 13387 return Controller; 13388 }; 13389 13390 /** 13391 * Destroy the Controller, all Scenes and everything. 13392 * @public 13393 * 13394 * @example 13395 * // without resetting the scenes 13396 * controller = controller.destroy(); 13397 * 13398 * // with scene reset 13399 * controller = controller.destroy(true); 13400 * 13401 * @param {boolean} [resetScenes=false] - If `true` the pins and tweens (if existent) of all scenes will be reset. 13402 * @returns {null} Null to unset handler variables. 13403 */ 13404 this.destroy = function (resetScenes) { 13405 window.clearTimeout(_refreshTimeout); 13406 var i = _sceneObjects.length; 13407 while (i--) { 13408 _sceneObjects[i].destroy(resetScenes); 13409 } 13410 _options.container.removeEventListener("resize", onChange); 13411 _options.container.removeEventListener("scroll", onChange); 13412 _util.cAF(_updateTimeout); 13413 log(3, "destroyed " + NAMESPACE + " (reset: " + (resetScenes ? "true" : "false") + ")"); 13414 return null; 13415 }; 13416 13417 // INIT 13418 construct(); 13419 return Controller; 13420 }; 13421 13422 // store pagewide controller options 13423 var CONTROLLER_OPTIONS = { 13424 defaults: { 13425 container: window, 13426 vertical: true, 13427 globalSceneOptions: {}, 13428 loglevel: 2, 13429 refreshInterval: 100 13430 } 13431 }; 13432 /* 13433 * method used to add an option to ScrollMagic Scenes. 13434 */ 13435 ScrollMagic.Controller.addOption = function (name, defaultValue) { 13436 CONTROLLER_OPTIONS.defaults[name] = defaultValue; 13437 }; 13438 // instance extension function for plugins 13439 ScrollMagic.Controller.extend = function (extension) { 13440 var oldClass = this; 13441 ScrollMagic.Controller = function () { 13442 oldClass.apply(this, arguments); 13443 this.$super = _util.extend({}, this); // copy parent state 13444 return extension.apply(this, arguments) || this; 13445 }; 13446 _util.extend(ScrollMagic.Controller, oldClass); // copy properties 13447 ScrollMagic.Controller.prototype = oldClass.prototype; // copy prototype 13448 ScrollMagic.Controller.prototype.constructor = ScrollMagic.Controller; // restore constructor 13449 }; 13450 13451 /** 13452 * A Scene defines where the controller should react and how. 13453 * 13454 * @class 13455 * 13456 * @example 13457 * // create a standard scene and add it to a controller 13458 * new ScrollMagic.Scene() 13459 * .addTo(controller); 13460 * 13461 * // create a scene with custom options and assign a handler to it. 13462 * var scene = new ScrollMagic.Scene({ 13463 * duration: 100, 13464 * offset: 200, 13465 * triggerHook: "onEnter", 13466 * reverse: false 13467 * }); 13468 * 13469 * @param {object} [options] - Options for the Scene. The options can be updated at any time. 13470 Instead of setting the options for each scene individually you can also set them globally in the controller as the controllers `globalSceneOptions` option. The object accepts the same properties as the ones below. 13471 When a scene is added to the controller the options defined using the Scene constructor will be overwritten by those set in `globalSceneOptions`. 13472 * @param {(number|function)} [options.duration=0] - The duration of the scene. 13473 If `0` tweens will auto-play when reaching the scene start point, pins will be pinned indefinetly starting at the start position. 13474 A function retuning the duration value is also supported. Please see `Scene.duration()` for details. 13475 * @param {number} [options.offset=0] - Offset Value for the Trigger Position. If no triggerElement is defined this will be the scroll distance from the start of the page, after which the scene will start. 13476 * @param {(string|object)} [options.triggerElement=null] - Selector or DOM object that defines the start of the scene. If undefined the scene will start right at the start of the page (unless an offset is set). 13477 * @param {(number|string)} [options.triggerHook="onCenter"] - Can be a number between 0 and 1 defining the position of the trigger Hook in relation to the viewport. 13478 Can also be defined using a string: 13479 ** `"onEnter"` => `1` 13480 ** `"onCenter"` => `0.5` 13481 ** `"onLeave"` => `0` 13482 * @param {boolean} [options.reverse=true] - Should the scene reverse, when scrolling up? 13483 * @param {number} [options.loglevel=2] - Loglevel for debugging. Note that logging is disabled in the minified version of ScrollMagic. 13484 ** `0` => silent 13485 ** `1` => errors 13486 ** `2` => errors, warnings 13487 ** `3` => errors, warnings, debuginfo 13488 * 13489 */ 13490 ScrollMagic.Scene = function (options) { 13491 13492 /* 13493 * ---------------------------------------------------------------- 13494 * settings 13495 * ---------------------------------------------------------------- 13496 */ 13497 13498 var NAMESPACE = 'ScrollMagic.Scene', 13499 SCENE_STATE_BEFORE = 'BEFORE', 13500 SCENE_STATE_DURING = 'DURING', 13501 SCENE_STATE_AFTER = 'AFTER', 13502 DEFAULT_OPTIONS = SCENE_OPTIONS.defaults; 13503 13504 /* 13505 * ---------------------------------------------------------------- 13506 * private vars 13507 * ---------------------------------------------------------------- 13508 */ 13509 13510 var Scene = this, 13511 _options = _util.extend({}, DEFAULT_OPTIONS, options), 13512 _state = SCENE_STATE_BEFORE, 13513 _progress = 0, 13514 _scrollOffset = { 13515 start: 0, 13516 end: 0 13517 }, 13518 13519 // reflects the controllers's scroll position for the start and end of the scene respectively 13520 _triggerPos = 0, 13521 _enabled = true, 13522 _durationUpdateMethod, 13523 _controller; 13524 13525 /**
13526 * Internal constructor function of the ScrollMagic Scene 13527 * @private 13528 */ 13529 var construct = function () { 13530 for (var key in _options) { 13531 // check supplied options 13532 if (!DEFAULT_OPTIONS.hasOwnProperty(key)) { 13533 log(2, "WARNING: Unknown option \"" + key + "\""); 13534 delete _options[key]; 13535 } 13536 } 13537 // add getters/setters for all possible options 13538 for (var optionName in DEFAULT_OPTIONS) { 13539 addSceneOption(optionName); 13540 } 13541 // validate all options 13542 validateOption(); 13543 }; 13544 13545 /* 13546 * ---------------------------------------------------------------- 13547 * Event Management 13548 * ---------------------------------------------------------------- 13549 */ 13550 13551 var _listeners = {}; 13552 /** 13553 * Scene start event. 13554 * Fires whenever the scroll position its the starting point of the scene. 13555 * It will also fire when scrolling back up going over the start position of the scene. If you want something to happen only when scrolling down/right, use the scrollDirection parameter passed to the callback. 13556 * 13557 * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method. 13558 * 13559 * @event ScrollMagic.Scene#start 13560 * 13561 * @example 13562 * scene.on("start", function (event) { 13563 * console.log("Hit start point of scene."); 13564 * }); 13565 * 13566 * @property {object} event - The event Object passed to each callback 13567 * @property {string} event.type - The name of the event 13568 * @property {Scene} event.target - The Scene object that triggered this event 13569 * @property {number} event.progress - Reflects the current progress of the scene 13570 * @property {string} event.state - The current state of the scene `"BEFORE"` or `"DURING"` 13571 * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"` 13572 */ 13573 /** 13574 * Scene end event. 13575 * Fires whenever the scroll position its the ending point of the scene. 13576 * It will also fire when scrolling back up from after the scene and going over its end position. If you want something to happen only when scrolling down/right, use the scrollDirection parameter passed to the callback. 13577 * 13578 * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method. 13579 * 13580 * @event ScrollMagic.Scene#end 13581 * 13582 * @example 13583 * scene.on("end", function (event) { 13584 * console.log("Hit end point of scene."); 13585 * }); 13586 * 13587 * @property {object} event - The event Object passed to each callback 13588 * @property {string} event.type - The name of the event 13589 * @property {Scene} event.target - The Scene object that triggered this event 13590 * @property {number} event.progress - Reflects the current progress of the scene 13591 * @property {string} event.state - The current state of the scene `"DURING"` or `"AFTER"` 13592 * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"` 13593 */ 13594 /** 13595 * Scene enter event. 13596 * Fires whenever the scene enters the "DURING" state. 13597 * Keep in mind that it doesn't matter if the scene plays forward or backward: This event always fires when the scene enters its active scroll timeframe, regardless of the scroll-direction. 13598 * 13599 * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method. 13600 * 13601 * @event ScrollMagic.Scene#enter 13602 * 13603 * @example 13604 * scene.on("enter", function (event) { 13605 * console.log("Scene entered."); 13606 * }); 13607 * 13608 * @property {object} event - The event Object passed to each callback 13609 * @property {string} event.type - The name of the event 13610 * @property {Scene} event.target - The Scene object that triggered this event 13611 * @property {number} event.progress - Reflects the current progress of the scene 13612 * @property {string} event.state - The current state of the scene - always `"DURING"` 13613 * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"` 13614 */ 13615 /** 13616 * Scene leave event. 13617 * Fires whenever the scene's state goes from "DURING" to either "BEFORE" or "AFTER". 13618 * Keep in mind that it doesn't matter if the scene plays forward or backward: This event al
13618ways fires when the scene leaves its active scroll timeframe, regardless of the scroll-direction. 13619 * 13620 * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method. 13621 * 13622 * @event ScrollMagic.Scene#leave 13623 * 13624 * @example 13625 * scene.on("leave", function (event) { 13626 * console.log("Scene left."); 13627 * }); 13628 * 13629 * @property {object} event - The event Object passed to each callback 13630 * @property {string} event.type - The name of the event 13631 * @property {Scene} event.target - The Scene object that triggered this event 13632 * @property {number} event.progress - Reflects the current progress of the scene 13633 * @property {string} event.state - The current state of the scene `"BEFORE"` or `"AFTER"` 13634 * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"` 13635 */ 13636 /** 13637 * Scene update event. 13638 * Fires whenever the scene is updated (but not necessarily changes the progress). 13639 * 13640 * @event ScrollMagic.Scene#update 13641 * 13642 * @example 13643 * scene.on("update", function (event) { 13644 * console.log("Scene updated."); 13645 * }); 13646 * 13647 * @property {object} event - The event Object passed to each callback 13648 * @property {string} event.type - The name of the event 13649 * @property {Scene} event.target - The Scene object that triggered this event 13650 * @property {number} event.startPos - The starting position of the scene (in relation to the conainer) 13651 * @property {number} event.endPos - The ending position of the scene (in relation to the conainer) 13652 * @property {number} event.scrollPos - The current scroll position of the container 13653 */ 13654 /** 13655 * Scene progress event. 13656 * Fires whenever the progress of the scene changes. 13657 * 13658 * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method. 13659 * 13660 * @event ScrollMagic.Scene#progress 13661 * 13662 * @example 13663 * scene.on("progress", function (event) { 13664 * console.log("Scene progress changed to " + event.progress); 13665 * }); 13666 * 13667 * @property {object} event - The event Object passed to each callback 13668 * @property {string} event.type - The name of the event 13669 * @property {Scene} event.target - The Scene object that triggered this event 13670 * @property {number} event.progress - Reflects the current progress of the scene 13671 * @property {string} event.state - The current state of the scene `"BEFORE"`, `"DURING"` or `"AFTER"` 13672 * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"` 13673 */ 13674 /** 13675 * Scene change event. 13676 * Fires whenvever a property of the scene is changed. 13677 * 13678 * @event ScrollMagic.Scene#change 13679 * 13680 * @example 13681 * scene.on("change", function (event) { 13682 * console.log("Scene Property \"" + event.what + "\" changed to " + event.newval); 13683 * }); 13684 * 13685 * @property {object} event - The event Object passed to each callback 13686 * @property {string} event.type - The name of the event 13687 * @property {Scene} event.target - The Scene object that triggered this event 13688 * @property {string} event.what - Indicates what value has been changed 13689 * @property {mixed} event.newval - The new value of the changed property 13690 */ 13691 /** 13692 * Scene shift event. 13693 * Fires whenvever the start or end **scroll offset** of the scene change. 13694 * This happens explicitely, when one of these values change: `offset`, `duration` or `triggerHook`. 13695 * It will fire implicitly when the `triggerElement` changes, if the new element has a different position (most cases). 13696 * It will also fire implicitly when the size of the container changes and the triggerHook is anything other than `onLeave`. 13697 * 13698 * @event ScrollMagic.Scene#shift 13699 * @since 1.1.0 13700 * 13701 * @example 13702 * scene.on("shift", function (event) { 13703 * console.log("Scene moved, because the " + event.reason + " has changed.)"); 13704 * }); 13705 * 13706 * @property {object} event - The event Object passed to each callback 13707 * @property {string} event.type - The name of the event 13708 * @property {Scene} event.target - The Scene object that triggered this event 13709 * @property {string} event.reason - Indicates why the scene has shifted 13710 */ 13711 /** 13712 * Scene destroy event. 13713 * Fires whenvever the scene is destroyed. 13714 * This can be used to tidy up custom behaviour used in events. 13715 * 13716 * @event ScrollMagic.Scene#destroy 13717 * @since 1.1.0 13718 * 13719 * @example 13720 * scene.on("enter", function (event) { 13721 * // add custom action 13722 * $("#my-elem").left("200"); 13723 * }) 13724 * .on("destroy", function (event) { 13725 * // reset my element to start position 13726 * if (event.reset) { 13727 * $("#my-elem").left("0"); 13728 * } 13729 * }); 13730 * 13731 * @property {object} event - The event Object passed to each callback 13732 * @property {string} event.type - The name of the event 13733 * @property {Scene} event.target - The Scene object that triggered this event 13734 * @property {boolean} event.reset - Indicates if the destroy method was called with reset `true` or `false`. 13735 */ 13736 /** 13737 * Scene add event. 13738 * Fires when the scene is added to a controller. 13739 * This is mostly used by plugins to know that change might be due. 13740 * 13741 * @event ScrollMagic.Scene#add 13742 * @since 2.0.0 13743 * 13744 * @example 13745 * scene.on("add", function (event) { 13746 * console.log('Scene was added to a new controller.'); 13747 * }); 13748 * 13749 * @property {object} event - The event Object passed to each callback 13750 * @property {string} event.type - The name of the event 13751 * @property {Scene} event.target - The Scene object that triggered this event 13752 * @property {boolean} event.controller - The controller object the scene was added to. 13753 */ 13754 /** 13755 * Scene remove event. 13756 * Fires when the scene is removed from a controller. 13757 * This is mostly used by plugins to know that change might be due. 13758 * 13759 * @event ScrollMagic.Scene#remove 13760 * @since 2.0.0 13761 * 13762 * @example 13763 * scene.on("remove", function (event) { 13764 * console.log('Scene was removed from its controller.'); 13765 * }); 13766 * 13767 * @property {object} event - The event Object passed to each callback 13768 * @property {string} event.type - The name of the event 13769 * @property {Scene} event.target - The Scene object that triggered this event 13770 */ 13771 13772 /** 13773 * Add one ore more event listener. 13774 * The callback function will be fired at the respective event, and an object c
13774ontaining relevant data will be passed to the callback. 13775 * @method ScrollMagic.Scene#on 13776 * 13777 * @example 13778 * function callback (event) { 13779 * console.log("Event fired! (" + event.type + ")"); 13780 * } 13781 * // add listeners 13782 * scene.on("change update progress start end enter leave", callback); 13783 * 13784 * @param {string} names - The name or names of the event the callback should be attached to. 13785 * @param {function} callback - A function that should be executed, when the event is dispatched. An event object will be passed to the callback. 13786 * @returns {Scene} Parent object for chaining. 13787 */ 13788 this.on = function (names, callback) { 13789 if (_util.type.Function(callback)) { 13790 names = names.trim().split(' '); 13791 names.forEach(function (fullname) { 13792 var nameparts = fullname.split('.'), 13793 eventname = nameparts[0], 13794 namespace = nameparts[1]; 13795 if (eventname != "*") { 13796 // disallow wildcards 13797 if (!_listeners[eventname]) { 13798 _listeners[eventname] = []; 13799 } 13800 _listeners[eventname].push({ 13801 namespace: namespace || '', 13802 callback: callback 13803 }); 13804 } 13805 }); 13806 } else { 13807 log(1, "ERROR when calling '.on()': Supplied callback for '" + names + "' is not a valid function!"); 13808 } 13809 return Scene; 13810 }; 13811 13812 /** 13813 * Remove one or more event listener. 13814 * @method ScrollMagic.Scene#off 13815 * 13816 * @example 13817 * function callback (event) { 13818 * console.log("Event fired! (" + event.type + ")"); 13819 * } 13820 * // add listeners 13821 * scene.on("change update", callback); 13822 * // remove listeners 13823 * scene.off("change update", callback); 13824 * 13825 * @param {string} names - The name or names of the event that should be removed. 13826 * @param {function} [callback] - A specific callback function that should be removed. If none is passed all callbacks to the event listener will be removed. 13827 * @returns {Scene} Parent object for chaining. 13828 */ 13829 this.off = function (names, callback) { 13830 if (!names) { 13831 log(1, "ERROR: Invalid event name supplied."); 13832 return Scene; 13833 } 13834 names = names.trim().split(' '); 13835 names.forEach(function (fullname, key) { 13836 var nameparts = fullname.split('.'), 13837 eventname = nameparts[0], 13838 namespace = nameparts[1] || '', 13839 removeList = eventname === '*' ? Object.keys(_listeners) : [eventname]; 13840 removeList.forEach(function (remove) { 13841 var list = _listeners[remove] || [], 13842 i = list.length; 13843 while (i--) { 13844 var listener = list[i]; 13845 if (listener && (namespace === listener.namespace || namespace === '*') && (!callback || callback == listener.callback)) { 13846 list.splice(i, 1); 13847 } 13848 } 13849 if (!list.length) { 13850 delete _listeners[remove]; 13851 } 13852 }); 13853 }); 13854 return Scene; 13855 }; 13856 13857 /** 13858 * Trigger an event. 13859 * @method ScrollMagic.Scene#trigger 13860 * 13861 * @example 13862 * this.trigger("change"); 13863 * 13864 * @param {string} name - The name of the event that should be triggered. 13865 * @param {object} [vars] - An object containing info that should be passed to the callback. 13866 * @returns {Scene} Parent object for chaining. 13867 */ 13868 this.trigger = function (name, vars) { 13869 if (name) { 13870 var nameparts = name.trim().split('.'), 13871 eventname = nameparts[0], 13872 namespace = nameparts[1], 13873 listeners = _listeners[eventname]; 13874 log(3, 'event fired:', eventname, vars ? "->" : '', vars || ''); 13875 if (listeners) { 13876 listeners.forEach(function (listener, key) { 13877 if (!namespace || namespace === listener.namespace) { 13878 listener.callback.call(Scene, new ScrollMagic.Event(eventname, listener.namespace, Scene, vars)); 13879 } 13880 }); 13881 } 13882 } else { 13883 log(1, "ERROR: Invalid event name supplied."); 13884 } 13885 return Scene; 13886 }; 13887 13888 // set event listeners 13889 Scene.on("change.internal", function (e) { 13890 if (e.what !== "loglevel" && e.what !== "tweenChanges") { 13891 // no need for a scene update scene with these options... 13892 if (e.what === "triggerElement") { 13893 updateTriggerElementPosition(); 13894 } else if (e.what === "reverse") { 13895 // the only property left that may have an impact on the current scene state. Everything else is handled by the shift event.
13896 Scene.update(); 13897 } 13898 } 13899 }).on("shift.internal", function (e) { 13900 updateScrollOffset(); 13901 Scene.update(); // update scene to reflect new position 13902 }); 13903 13904 /** 13905 * Send a debug message to the console. 13906 * @private 13907 * but provided publicly with _log for plugins 13908 * 13909 * @param {number} loglevel - The loglevel required to initiate output for the message. 13910 * @param {...mixed} output - One or more variables that should be passed to the console. 13911 */ 13912 var log = this._log = function (loglevel, output) { 13913 if (_options.loglevel >= loglevel) { 13914 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ") ->"); 13915 _util.log.apply(window, arguments); 13916 } 13917 }; 13918 13919 /** 13920 * Add the scene to a controller. 13921 * This is the equivalent to `Controller.addScene(scene)`. 13922 * @method ScrollMagic.Scene#addTo 13923 * 13924 * @example 13925 * // add a scene to a ScrollMagic Controller 13926 * scene.addTo(controller); 13927 * 13928 * @param {ScrollMagic.Controller} controller - The controller to which the scene should be added. 13929 * @returns {Scene} Parent object for chaining. 13930 */ 13931 this.addTo = function (controller) { 13932 if (!(controller instanceof ScrollMagic.Controller)) { 13933 log(1, "ERROR: supplied argument of 'addTo()' is not a valid ScrollMagic Controller"); 13934 } else if (_controller != controller) { 13935 // new controller 13936 if (_controller) { 13937 // was associated to a different controller before, so remove it... 13938 _controller.removeScene(Scene); 13939 } 13940 _controller = controller; 13941 validateOption(); 13942 updateDuration(true); 13943 updateTriggerElementPosition(true); 13944 updateScrollOffset(); 13945 _controller.info("container").addEventListener('resize', onContainerResize); 13946 controller.addScene(Scene); 13947 Scene.trigger("add", { 13948 controller: _controller 13949 }); 13950 log(3, "added " + NAMESPACE + " to controller"); 13951 Scene.update(); 13952 } 13953 return Scene; 13954 }; 13955 13956 /** 13957 * **Get** or **Set** the current enabled state of the scene. 13958 * This can be used to disable this scene without removing or destroying it. 13959 * @method ScrollMagic.Scene#enabled 13960 * 13961 * @example 13962 * // get the current value 13963 * var enabled = scene.enabled(); 13964 * 13965 * // disable the scene 13966 * scene.enabled(false); 13967 * 13968 * @param {boolean} [newState] - The new enabled state of the scene `true` or `false`. 13969 * @returns {(boolean|Scene)} Current enabled state or parent object for chaining. 13970 */ 13971 this.enabled = function (newState) { 13972 if (!arguments.length) { 13973 // get 13974 return _enabled; 13975 } else if (_enabled != newState) { 13976 // set 13977 _enabled = !!newState; 13978 Scene.update(true); 13979 } 13980 return Scene; 13981 }; 13982 13983 /** 13984 * Remove the scene from the controller. 13985 * This is the equivalent to `Controller.removeScene(scene)`. 13986 * The scene will not be updated anymore until you readd it to a controller. 13987 * To remove the pin or the tween you need to call removeTween() or removePin() respectively. 13988 * @method ScrollMagic.Scene#remove 13989 * @example 13990 * // remove the scene from its controller 13991 * scene.remove(); 13992 * 13993 * @returns {Scene} Parent object for chaining. 13994 */ 13995 this.remove = function () { 13996 if (_controller) { 13997 _controller.info("container").removeEventListener('resize', onContainerResize); 13998 var tmpParent = _controller; 13999 _controller = undefined; 14000 tmpParent.removeScene(Scene); 14001 Scene.trigger("remove"); 14002 log(3, "removed " + NAMESPACE + " from controller"); 14003 } 14004 return Scene; 14005 }; 14006 14007 /** 14008 * Destroy the scene and everything. 14009 * @method ScrollMagic.Scene#destroy 14010 * @example 14011 * // destroy the scene without resetting the pin and tween to their initial positions 14012 * scene = scene.destroy(); 14013 * 14014 * // destroy the scene and reset the pin and tween 14015 * scene = scene.destroy(true); 14016 * 14017 * @param {boolean} [reset=false] - If `true` the pin and tween (if existent) will be reset. 14018 * @returns {null} Null to unset handler variables. 14019 */ 14020 this.destroy = function (reset) { 14021 Scene.trigger("destroy", { 14022 reset: reset 14023 }); 14024 Scene.remove(); 14025 Scene.off("*.*"); 14026 log(3, "destroyed " + NAMESPACE + " (reset: " + (reset ? "true" : "false") + ")"); 14027 return null; 14028 }; 14029 14030 /** 14031 * Updates the Scene to reflect the current state. 14032 * This is the equivalent to `Controller.updateScene(scene, immediately)`. 14033 * The update method calculates the scene's start and end position (based on the trigger element, trigger hook, duration and offset) and checks it against the current scroll position of the container. 14034 * It then updates the current scene state accordingly (or does nothing, if the state is already correct) â Pins will be set to their correct position and tweens will be updated to their correct progress. 14035 * This means an update doesn't necessarily result in a progress change. The `progress` event will be fired if the progress has indeed changed between this update and the last. 14036 * _**NOTE:** This method gets called constantly whenever ScrollMagic detects a change. The only application for you is
14036if you change something outside of the realm of ScrollMagic, like moving the trigger or changing tween parameters._ 14037 * @method ScrollMagic.Scene#update 14038 * @example 14039 * // update the scene on next tick 14040 * scene.update(); 14041 * 14042 * // update the scene immediately 14043 * scene.update(true); 14044 * 14045 * @fires Scene.update 14046 * 14047 * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle (better performance). 14048 * @returns {Scene} Parent object for chaining. 14049 */ 14050 this.update = function (immediately) { 14051 if (_controller) { 14052 if (immediately) { 14053 if (_controller.enabled() && _enabled) { 14054 var scrollPos = _controller.info("scrollPos"), 14055 newProgress; 14056 14057 if (_options.duration > 0) { 14058 newProgress = (scrollPos - _scrollOffset.start) / (_scrollOffset.end - _scrollOffset.start); 14059 } else { 14060 newProgress = scrollPos >= _scrollOffset.start ? 1 : 0; 14061 } 14062 14063 Scene.trigger("update", { 14064 startPos: _scrollOffset.start, 14065 endPos: _scrollOffset.end, 14066 scrollPos: scrollPos 14067 }); 14068 14069 Scene.progress(newProgress); 14070 } else if (_pin && _state === SCENE_STATE_DURING) { 14071 updatePinState(true); // unpin in position 14072 } 14073 } else { 14074 _controller.updateScene(Scene, false); 14075 } 14076 } 14077 return Scene; 14078 }; 14079 14080 /** 14081 * Updates dynamic scene variables like the trigger element position or the duration. 14082 * This method is automatically called in regular intervals from the controller. See {@link ScrollMagic.Controller} option `refreshInterval`. 14083 * 14084 * You can call it to minimize lag, for example when you intentionally change the position of the triggerElement. 14085 * If you don't it will simply be updated in the next refresh interval of the container, which is usually sufficient. 14086 * 14087 * @method ScrollMagic.Scene#refresh 14088 * @since 1.1.0 14089 * @example 14090 * scene = new ScrollMagic.Scene({triggerElement: "#trigger"}); 14091 * 14092 * // change the position of the trigger 14093 * $("#trigger").css("top", 500); 14094 * // immediately let the scene know of this change 14095 * scene.refresh(); 14096 * 14097 * @fires {@link Scene.shift}, if the trigger element position or the duration changed 14098 * @fires {@link Scene.change}, if the duration changed 14099 * 14100 * @returns {Scene} Parent object for chaining. 14101 */ 14102 this.refresh = function () { 14103 updateDuration(); 14104 updateTriggerElementPosition(); 14105 // update trigger element position 14106 return Scene; 14107 }; 14108 14109 /** 14110 * **Get** or **Set** the scene's progress. 14111 * Usually it shouldn't be necessary to use this as a setter, as it is set automatically by scene.update(). 14112 * The order in which the events are fired depends on the duration of the scene: 14113 * 1. Scenes with `duration == 0`: 14114 * Scenes that have no duration by definition have no ending. Thus the `end` event will never be fired. 14115 * When the trigger position of the scene is passed the events are always fired in this order: 14116 * `enter`, `start`, `progress` when scrolling forward 14117 * and 14118 * `progress`, `start`, `leave` when scrolling in reverse 14119 * 2. Scenes with `duration > 0`: 14120 * Scenes with a set duration have a defined start and end point. 14121 * When scrolling past the start position of the scene it will fire these events in this order: 14122 * `enter`, `start`, `progress` 14123 * When continuing to scroll and passing the end point it will fire these events: 14124 * `progress`, `end`, `leave` 14125 * When reversing through the end point these events are fired: 14126 * `enter`, `end`, `progress` 14127 * And when continuing to scroll past the start position in reverse it will fire: 14128 * `progress`, `start`, `leave` 14129 * In between start and end the `progress` event will be called constantly, whenever the progress changes. 14130 * 14131 * In short: 14132 * `enter` events will always trigger **before** the progress update and `leave` envents will trigger **after** the progress update. 14133 * `start` and `end` will always trigger at their respective position. 14134 * 14135 * Please review the event descriptions for details on the events and the event object that is passed to the callback. 14136 * 14137 * @method ScrollMagic.Scene#progress 14138 * @example 14139 * // get the current scene progress 14140 * var progress = scene.progress(); 14141 * 14142 * // set new scene progress 14143 * scene.progress(0.3); 14144 * 14145 * @fires {@link Scene.enter}, when used as setter 14146 * @fires {@link Scene.start}, when used as setter 14147 * @fires {@link Scene.progress}, when used as setter 14148 * @fires {@link Scene.end}, when used as setter 14149 * @fires {@link Scene.leave}, when used as setter 14150 * 14151 * @param {number} [progress] - The new progress value of the scene `[0-1]`. 14152 * @returns {number} `get` - Current scene progress. 14153 * @returns {Scene} `set` - Parent object for chaining. 14154 */ 14155 this.progress = function (progress) { 14156 if (!arguments.length) { 14157 // get 14158 return _progress; 14159 } else { 14160 // set 14161 var doUpdate = false, 14162 oldState = _state, 14163 scrollDirection = _controller ? _controller.info("scrollDirection") : 'PAUSED', 14164 reverseOrForward = _options.reverse || progress >= _progress; 14165 if (_options.duration === 0) { 14166 // zero duration scenes 14167 doUpdate = _progress != progress; 14168 _progress = progress < 1 && reverseOrForward ? 0 : 1; 14169 _state = _progress === 0 ? SCENE_STATE_BEFORE : SCENE_STATE_DURING; 14170 } else { 14171 // scenes with start and end 14172 if (progress < 0 && _state !== SCENE_STATE_BEFORE && reverseOrForward) { 14173 // go back to initial state 14174 _progress = 0; 14175 _state = SCENE_STATE_BEFORE; 14176 doUpdate = true; 14177 } else if (progress >= 0 && progress < 1 && reverseOrForward) { 14178 _progress = progress; 14179 _state = SCENE_STATE_DURING; 14180 doUpdate = true; 14181 } else if (progress >= 1 && _state !== SCENE_STATE_AFTER) { 14182 _progress = 1; 14183 _state = SCENE_STATE_AFTER; 14184 doUpdate = true; 14185 } else if (_state === SCENE_STATE_DURING && !reverseOrForward) { 14186 updatePinState(); // in case we scrolled backwards mid-scene and reverse is disabled => update the pin position, so it doesn't move back as well. 14187 } 14188 } 14189 if (doUpdate) { 14190 // fire events 14191 var eventVars = { 14192 progress: _progress, 14193 state: _state, 14194 scrollDirection: scrollDirection 14195 }, 14196 stateChanged = _state != oldState; 14197 14198 var trigger = function (eventName) { 14199 // tmp helper to simplify code 14200 Scene.trigger(eventName, eventVars); 14201 }; 14202 14203 if (stateChanged) { 14204 // enter events 14205 if (oldState !== SCENE_STATE_DURING) { 14206 trigger("enter"); 14207 trigger(oldState === SCENE_STATE_BEFORE ? "start" : "end"); 14208 } 14209 } 14210 trigger("progress"); 14211 if (stateChanged) { 14212 // leave events 14213 if (_state !== SCENE_STATE_DURING) { 14214 trigger(_state === SCENE_STATE_BEFORE ? "start" : "end"); 14215 trigger("leave"); 14216 } 14217 } 14218 } 14219 14220 return Scene; 14221 } 14222 }; 14223 14224 /** 14225 * Update the start and end scrollOffset of the container. 14226 * The positions reflect what the controller's scroll position will be at the start and end respectively. 14227 * Is called, when: 14228 * - Scene event "change" is called with: offset, triggerHook, duration 14229 * - scroll container event "resize" is called 14230 * - the position of the triggerElement changes 14231 * - the controller changes -> addTo() 14232 * @private 14233 */ 14234 var updateScrollOffset = function () { 14235 _scrollOffset = { 14236 start: _triggerPos + _options.offset 14237 }; 14238 if (_controller && _options.triggerElement) { 14239 // take away triggerHook portion to get relative to top 14240 _scrollOffset.start -= _controller.info("size") * _options.triggerHook; 14241 } 14242 _scrollOffset.end = _scrollOffset.start + _options.duration; 14243 }; 14244 14245 /** 14246 * Updates the duration if set to a dynamic function. 14247 * This method is called when the scene is added to a controller and in regular intervals from the controller through scene.refresh(). 14248 * 14249 * @fires {@link Scene.change}, if the duration changed 14250 * @fires {@link Scene.shift}, if the duration changed 14251 * 14252 * @param {boolean} [suppressEvents=false] - If true the shift event will be suppressed. 14253 * @private 14254 */ 14255 var updateDuration = function (suppressEvents) { 14256 // update duration 14257 if (_durationUpdateMethod) { 14258 var varname = "duration"; 14259 if (changeOption(varname, _durationUpdateMethod.call(Scene)) && !suppressEvents) { 14260 // set 14261 Scene.trigger("change", { 14262 what: varname, 14263 newval: _options[varname] 14264 }); 14265 Scene.trigger("shift", { 14266 reason: varname 14267 }); 14268 } 14269 } 14270 }; 14271 14272 /** 14273 * Updates the position of the triggerElement, if present. 14274 * This method is called ... 14275 * - ... when the triggerElement is changed 14276 * - ... when the scene is added to a (new) controller 14277 * - ... in regular intervals from the controller through scene.refresh(). 14278 * 14279 * @fires {@link Scene.shift}, if the position changed 14280 * 14281 * @param {boolean} [suppressEvents=false] - If true the shift event will be suppressed. 14282 * @private 14283 */ 14284 var updateTriggerElementPosition = function (suppressEvents) { 14285 var elementPos = 0, 14286 telem = _options.triggerElement; 14287 if (_controller && telem) { 14288 var controllerInfo = _controller.info(), 14289 containerOffset = _util.get.offset(controllerInfo.container), 14290 14291 // container position is needed because element offset is returned in relation to document, not in relation to container. 14292 param = controllerInfo.vertical ? "top" : "left"; // which param is of interest ? 14293 // if parent is spacer, use spacer position instead so correct start position is returned for pinned elements. 14294 while (telem.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) { 14295 telem = telem.parentNode; 14296 } 14297 14298 var elementOffset = _util.get.offset(telem); 14299 14300 if (!controllerInfo.isDocument) { 14301 // container is not the document root, so substract scroll Position to get correct trigger element position relative to scrollcontent 14302 containerOffset[param] -= _controller.scrollPos(); 14303 } 14304 14305 elementPos = elementOffset[param] - containerOffset[param]; 14306 } 14307 var changed = elementPos != _triggerPos; 14308 _triggerPos = elementPos; 14309 if (changed && !suppressEvents) { 14310 Scene.trigger("shift", { 14311 reason: "triggerElementPosition" 14312 }); 14313 } 14314 }; 14315 14316 /** 14317 * Trigger a shift event, when the container is resized and the triggerHook is > 1. 14318 * @private 14319 */ 14320 var onContainerResize = function (e) { 14321 if (_options.triggerHook > 0) { 14322 Scene.trigger("shift", { 14323 reason: "containerResize" 14324 }); 14325 } 14326 }; 14327 14328 var _validate = _util.extend(SCENE_OPTIONS.validate, { 14329 // validation for duration handled internally for reference to private var _durationMethod 14330 duration: function (val) { 14331 if (_util.type.String(val) && val.match(/^(\.|\d)*\d+%$/)) { 14332 // percentage value 14333 var perc = parseFloat(val) / 100; 14334 val = function () { 14335 return _controller ? _controller.info("size") * perc : 0; 14336 }; 14337 } 14338 if (_util.type.Function(val)) { 14339 // function 14340 _durationUpdateMethod = val; 14341 try { 14342 val = parseFloat(_durationUpdateMethod()); 14343 } catch (e) { 14344 val = -1; // will cause error below 14345 } 14346 } 14347 // val has to be float 14348 val = parseFloat(val); 14349 if (!_util.type.Number(val) || val < 0) { 14350 if (_durationUpdateMethod) { 14351 _durationUpdateMethod = undefined; 14352 throw ["Invalid return value of supplied function for option \"duration\":", val]; 14353 } else { 14354 throw ["Invalid value for option \"duration\":", val]; 14355 } 14356 } 14357 return val; 14358 } 14359 }); 14360 14361 /** 14362 * Checks the validity of a specific or all options and reset to default if neccessary. 14363 * @private 14364 */
14365 var validateOption = function (check) { 14366 check = arguments.length ? [check] : Object.keys(_validate); 14367 check.forEach(function (optionName, key) { 14368 var value; 14369 if (_validate[optionName]) { 14370 // there is a validation method for this option 14371 try { 14372 // validate value 14373 value = _validate[optionName](_options[optionName]); 14374 } catch (e) { 14375 // validation failed -> reset to default 14376 value = DEFAULT_OPTIONS[optionName]; 14377 var logMSG = _util.type.String(e) ? [e] : e; 14378 if (_util.type.Array(logMSG)) { 14379 logMSG[0] = "ERROR: " + logMSG[0]; 14380 logMSG.unshift(1); // loglevel 1 for error msg 14381 log.apply(this, logMSG); 14382 } else { 14383 log(1, "ERROR: Problem executing validation callback for option '" + optionName + "':", e.message); 14384 } 14385 } finally { 14386 _options[optionName] = value; 14387 } 14388 } 14389 }); 14390 }; 14391 14392 /** 14393 * Helper used by the setter/getters for scene options 14394 * @private 14395 */ 14396 var changeOption = function (varname, newval) { 14397 var changed = false, 14398 oldval = _options[varname]; 14399 if (_options[varname] != newval) { 14400 _options[varname] = newval; 14401 validateOption(varname); // resets to default if necessary 14402 changed = oldval != _options[varname]; 14403 } 14404 return changed; 14405 }; 14406 14407 // generate getters/setters for all options 14408 var addSceneOption = function (optionName) { 14409 if (!Scene[optionName]) { 14410 Scene[optionName] = function (newVal) { 14411 if (!arguments.length) { 14412 // get 14413 return _options[optionName]; 14414 } else { 14415 if (optionName === "duration") { 14416 // new duration is set, so any previously set function must be unset 14417 _durationUpdateMethod = undefined; 14418 } 14419 if (changeOption(optionName, newVal)) { 14420 // set 14421 Scene.trigger("change", { 14422 what: optionName, 14423 newval: _options[optionName] 14424 }); 14425 if (SCENE_OPTIONS.shifts.indexOf(optionName) > -1) { 14426 Scene.trigger("shift", { 14427 reason: optionName 14428 }); 14429 } 14430 } 14431 } 14432 return Scene; 14433 }; 14434 } 14435 }; 14436 14437 /** 14438 * **Get** or **Set** the duration option value. 14439 * As a setter it also accepts a function returning a numeric value. 14440 * This is particularly useful for responsive setups. 14441 * 14442 * The duration is updated using the supplied function every time `Scene.refresh()` is called, which happens periodically from the controller (see ScrollMagic.Controller option `refreshInterval`). 14443 * _**NOTE:** Be aware that it's an easy way to kill performance, if you supply a function that has high CPU demand. 14444 * Even for size and position calculations it is recommended to use a variable to cache the value. (see example) 14445 * This counts double if you use the same function for multiple scenes._ 14446 * 14447 * @method ScrollMagic.Scene#duration 14448 * @example 14449 * // get the current duration value 14450 * var duration = scene.duration(); 14451 * 14452 * // set a new duration 14453 * scene.duration(300); 14454 * 14455 * // use a function to automatically adjust the duration to the window height. 14456 * var durationValueCache; 14457 * function getDuration () { 14458 * return durationValueCache; 14459 * } 14460 * function updateDuration (e) { 14461 * durationValueCache = window.innerHeight; 14462 * } 14463 * $(window).on("resize", updateDuration); // update the duration when the window size changes 14464 * $(window).triggerHandler("resize"); // set to initial value 14465 * scene.duration(getDuration); // supply duration method 14466 * 14467 * @fires {@link Scene.change}, when used as setter 14468 * @fires {@link Scene.shift}, when used as setter 14469 * @param {(number|function)} [newDuration] - The new duration of the scene. 14470 * @returns {number} `get` - Current scene duration. 14471 * @returns {Scene} `set` - Parent object for chaining. 14472 */ 14473 14474 /** 14475 * **Get** or **Set** the offset option value. 14476 * @method ScrollMagic.Scene#offset 14477 * @example 14478 * // get the current offset 14479 * var offset = scene.offset(); 14480 * 14481 * // set a new offset 14482 * scene.offset(100); 14483 * 14484 * @fires {@link Scene.change}, when used as setter 14485 * @fires {@link Scene.shift}, when used as setter 14486 * @param {number} [newOffset] - The new offset of the scene. 14487 * @returns {number} `get` - Current scene offset. 14488 * @returns {Scene} `set` - Parent object for chaining. 14489 */ 14490 14491 /** 14492 * **Get** or **Set** the triggerElement option value. 14493 * Does **not** fire `Scene.shift`, because changing the trigger Element doesn't necessarily mean the start position changes. This will be determined in `Scene.refresh()`, which is automatically triggered. 14494 * @method ScrollMagic.Scene#triggerElement 14495 * @example 14496 * // get the current triggerElement 14497 * var triggerElement = scene.triggerElement(); 14498 * 14499 * // set a new triggerElement using a selector 14500 * scene.triggerElement("#trigger"); 14501 * // set a new triggerElement using a DOM object 14502 * scene.triggerElement(document.getElementById("trigger")); 14503 * 14504 * @fires {@link Scene.change}, when used as setter 14505 * @param {(string|object)} [newTriggerElement] - The new trigger element for the scene. 14506 * @returns {(string|object)} `get` - Current triggerElement. 14507 * @returns {Scene} `set` - Parent object for chaining. 14508 */ 14509 14510 /** 14511 * **Get** or **Set** the triggerHook option value. 14512 * @method ScrollMagic.Scene#triggerHook 14513 * @example 14514 * // get the current triggerHook value 14515 * var triggerHook = scene.triggerHook(); 14516 * 14517 * // set a new triggerHook using a string 14518 * scene.triggerHook("onLeave"); 14519 * // set a new triggerHook using a number 14520 * scene.triggerHook(0.7); 14521 * 14522 * @fires {@link Scene.change}, when used as setter 14523 * @fires {@link Scene.shift}, when used as setter 14524 * @param {(number|string)} [newTriggerHook] - The new triggerHook of the scene. See {@link Scene} parameter description for value options. 14525 * @returns {number} `get` - Current triggerHook (ALWAYS numerical). 14526 * @returns {Scene} `set` - Parent object for chaining. 14527 */ 14528 14529 /** 14530 * **Get** or **Set** the reverse option value. 14531 * @method ScrollMagic.Scene#reverse 14532 * @example 14533 * // get the current reverse option 14534 * var reverse = scene.reverse(); 14535 * 14536 * // set new reverse option 14537 * scene.reverse(false); 14538 * 14539 * @fires {@link Scene.change}, when used as setter 14540 * @param {boolean} [newReverse] - The new reverse setting of the scene. 14541 * @returns {boolean} `get` - Current reverse option value. 14542 * @returns {Scene} `set` - Parent object for chaining. 14543 */ 14544 14545 /** 14546 * **Get** or **Set** the loglevel option value. 14547 * @method ScrollMagic.Scene#loglevel 14548 * @example 14549 * // get the current loglevel 14550 * var loglevel = scene.loglevel(); 14551 * 14552 * // set new loglevel 14553 * scene.loglevel(3); 14554 * 14555 * @fires {@link Scene.change}, when used as setter 14556 * @param {number} [newLoglevel] - The new loglevel setting of the scene. `[0-3]` 14557 * @returns {number} `get` - Current loglevel. 14558 * @returns {Scene} `set` - Parent object for chaining. 14559 */ 14560 14561 /** 14562 * **Get** the associated controller. 14563 * @method ScrollMagic.Scene#controller 14564 * @example 14565 * // get the controller of a scene 14566 * var controller = scene.controller(); 14567 * 14568 * @returns {ScrollMagic.Controller} Parent controller or `undefined` 14569 */ 14570 this.controller = function () { 14571 return _controller; 14572 }; 14573 14574 /** 14575 * **Get** the current state. 14576 * @method ScrollMagic.Scene#state 14577 * @example 14578 * // get the current state 14579 * var state = scene.state(); 14580 * 14581 * @returns {string} `"BEFORE"`, `"DURING"` or `"AFTER"` 14582 */ 14583 this.state = function () { 14584 return _state; 14585 }; 14586 14587 /** 14588 * **Get** the current scroll offset for the start of the scene. 14589 * Mind, that the scrollOffset is related to the size of the container, if `triggerHook` is bigger than `0` (or `"onLeave"`). 14590 * This means, that resizing the container or changing the `triggerHook` will influence the scene's start offset. 14591 * @method ScrollMagic.Scene#scrollOffset 14592 * @example 14593 * // get the current scroll offset for the start and end of the scene. 14594 * var start = scene.scrollOffset(); 14595 * var end = scene.scrollOffset() + scene.duration(); 14596 * console.log("the scene starts at", start, "and ends at", end); 14597 * 14598 * @returns {number} The scroll offset (of the container) at which the scene will trigger. Y value for vertical and X value for horizontal scrolls. 14599 */ 14600 this.scrollOffset = function () { 14601 return _scrollOffset.start; 14602 }; 14603 14604 /** 14605 * **Get** the trigger position of the scene (including the value of the `offset` option). 14606 * @method ScrollMagic.Scene#triggerPosition 14607 * @example 14608 * // get the scene's trigger position 14609 * var triggerPosition = scene.triggerPosition(); 14610 * 14611 * @returns {number} Start position of the scene. Top position value for vertical and left position value for horizontal scrolls. 14612 */ 14613 this.triggerPosition = function () { 14614 var pos = _options.offset; // the offset is the basis 14615 if (_controller) { 14616 // get the trigger position 14617 if (_options.triggerElement) { 14618 // Element as trigger 14619 pos += _triggerPos; 14620 } else { 14621 // return the height of the triggerHook to start at the beginning 14622 pos += _controller.info("size") * Scene.triggerHook(); 14623 } 14624 } 14625 return pos; 14626 }; 14627 14628 var _pin, _pinOptions; 14629 14630 Scene.on("shift.internal", function (e) { 14631 var durationChanged = e.reason === "duration"; 14632 if (_state === SCENE_STATE_AFTER && durationChanged || _state === SCENE_STATE_DURING && _options.duration === 0) { 14633 // if [duration changed after a scene (inside scene progress updates pin position)] or [duration is 0, we are in pin phase and some other value changed]. 14634 updatePinState(); 14635 } 14636 if (durationChanged) { 14637 updatePinDimensions(); 14638 } 14639 }).on("progress.internal", function (e) { 14640 updatePinState(); 14641 }).on("add.internal", function (e) { 14642 updatePinDimensions(); 14643 }).on("destroy.internal", function (e) { 14644 Scene.removePin(e.reset); 14645 }); 14646 /** 14647 * Update the pin state. 14648 * @private 14649 */ 14650 var updatePinState = function (forceUnpin) { 14651 if (_pin && _controller) { 14652 var containerInfo = _controller.info(), 14653 pinTarget = _pinOptions.spacer.firstChild; // may be pin element or another spacer, if cascading pins 14654 if (!forceUnpin && _state === SCENE_STATE_DURING) { 14655 // during scene or if duration is 0 and we are past the trigger 14656 // pinned state 14657 if (_util.css(pinTarget, "position") != "fixed") { 14658 // change state before updating pin spacer (position changes due to fixed collapsing might occur.) 14659 _util.css(pinTarget, { 14660 "position": "fixed" 14661 }); 14662 // update pin spacer 14663 updatePinDimensions(); 14664 } 14665 14666 var fixedPos = _util.get.offset(_pinOptions.spacer, true), 14667 14668 // get viewport position of spacer 14669 scrollDistance = _options.reverse || _options.duration === 0 ? containerInfo.scrollPos - _scrollOffset.start // quicker 14670 : Math.round(_progress * _options.duration * 10) / 10; // if no reverse and during pin the position needs to be recalculated using the progress 14671 // add scrollDistance 14672 fixedPos[containerInfo.vertical ? "top" : "left"] += scrollDistance; 14673 14674 // set new values 14675 _util.css(_pinOptions.spacer.firstChild, { 14676 top: fixedPos.top, 14677 left: fixedPos.left 14678 }); 14679 } else { 14680 // unpinned state 14681 var newCSS = { 14682 position: _pinOptions.inFlow ? "relative" : "absolute", 14683 top: 0, 14684 left: 0 14685 }, 14686 change = _util.css(pinTarget, "position") != newCSS.position; 14687 14688 if (!_pinOptions.pushFollowers) { 14689 newCSS[containerInfo.vertical ? "top" : "left"] = _options.duration * _progress; 14690 } else if (_options.duration > 0) { 14691 // only concerns scenes with duration 14692 if (_state === SCENE_STATE_AFTER && parseFloat(_util.css(_pinOptions.spacer, "padding-top")) === 0) { 14693 change = true; // if in after state but havent updated spacer yet (jumped past pin) 14694 } else if (_state === SCENE_STATE_BEFORE && parseFloat(_util.css(_pinOptions.spacer, "padding-bottom")) === 0) { 14695 // before 14696 change = true; // jumped past fixed state upward direction 14697 } 14698 } 14699 // set new values 14700 _util.css(pinTarget, newCSS); 14701 if (change) { 14702 // update pin spacer if state changed 14703 updatePinDimensions(); 14704 } 14705 } 14706 } 14707 }; 14708 14709 /** 14710 * Update the pin spacer and/or element size. 14711 * The size of the spacer needs to be updated whenever the duration of the scene changes, if it is to push down following elements. 14712 * @private 14713 */ 14714 var updatePinDimensions = function () { 14715 if (_pin && _controller && _pinOptions.inFlow) { 14716 // no spacerresize, if original position is absolute 14717 var after = _state === SCENE_STATE_AFTER, 14718 before = _state === SCENE_STATE_BEFORE, 14719 during = _state === SCENE_STATE_DURING, 14720 vertical = _controller.info("vertical"), 14721 pinTarget = _pinOptions.spacer.firstChild, 14722 14723 // usually the pined element but can also be another spacer (cascaded pins) 14724 marginCollapse = _util.isMarginCollapseType(_util.css(_pinOptions.spacer, "display")), 14725 css = {}; 14726 14727 // set new size 14728 // if relsize: spacer -> pin | else: pin -> spacer 14729 if (_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) { 14730 if (during) { 14731 _util.css(_pin, { 14732 "width": _util.get.width(_pinOptions.spacer) 14733 }); 14734 } else { 14735 _util.css(_pin, { 14736 "width": "100%" 14737 }); 14738 } 14739 } else { 14740 // minwidth is needed for cascaded pins. 14741 css["min-width"] = _util.get.width(vertical ? _pin : pinTarget, true, true); 14742 css.width = during ? css["min-width"] : "auto"; 14743 } 14744 if (_pinOptions.relSize.height) { 14745 if (during) { 14746 // the only padding the spacer should ever include is the duration (if pushFollowers = true), so we need to substract that. 14747 _util.css(_pin, { 14748 "height": _util.get.height(_pinOptions.spacer) - (_pinOptions.pushFollowers ? _options.duration : 0) 14749 }); 14750 } else { 14751 _util.css(_pin, { 14752 "height": "100%" 14753 }); 14754 } 14755 } else { 14756 // margin is only included if it's a cascaded pin to resolve an IE9 bug 14757 css["min-height"] = _util.get.height(vertical ? pinTarget : _pin, true, !marginCollapse); // needed for cascading pins 14758 css.height = during ? css["min-height"] : "auto"; 14759 } 14760 14761 // add space for duration if pushFollowers is true 14762 if (_pinOptions.pushFollowers) { 14763 css["padding" + (vertical ? "Top" : "Left")] = _options.duration * _progress; 14764 css["padding" + (vertical ? "Bottom" : "Right")] = _options.duration * (1 - _progress); 14765 } 14766 _util.css(_pinOptions.spacer, css); 14767 } 14768 }; 14769 14770 /** 14771 * Updates the Pin state (in certain scenarios) 14772 * If the controller container is not the document and we are mid-pin-phase scrolling or resizing the main document can result to wrong pin positions. 14773 * So this function is called on resize and scroll of the document. 14774 * @private 14775 */ 14776 var updatePinInContainer = function () { 14777 if (_controller && _pin && _state === SCENE_STATE_DURING && !_controller.info("isDocument")) { 14778 updatePinState(); 14779 } 14780 }; 14781 14782 /** 14783 * Updates the Pin spacer size state (in certain scenarios) 14784 * If container is resized during pin and relatively sized the size of the pin might need to be updated... 14785 * So this function is called on resize of the container. 14786 * @private 14787 */ 14788 var updateRelativePinSpacer = function () { 14789 if (_controller && _pin && // well, duh 14790 _state === SCENE_STATE_DURING && ( // element in pinned state? 14791 // is width or height relatively sized, but not in relation to body? then we need to recalc. 14792 (_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) && _util.get.width(window) != _util.get.width(_pinOptions.spacer.parentNode) || _pinOptions.relSize.height && _util.get.height(window) != _util.get.height(_pinOptions.spacer.parentNode))) { 14793 updatePinDimensions(); 14794 } 14795 }; 14796 14797 /** 14798 * Is called, when the mousewhel is used while over a pinned element inside a div container. 14799 * If the scene is in fixed state scroll events would be counted towards the body. This forwards the event to the scroll container. 14800 * @private 14801 */ 14802 var onMousewheelOverPin = function (e) { 14803 if (_controller && _pin && _state === SCENE_STATE_DURING && !_controller.info("isDocument")) {
14804 // in pin state 14805 e.preventDefault(); 14806 _controller._setScrollPos(_controller.info("scrollPos") - ((e.wheelDelta || e[_controller.info("vertical") ? "wheelDeltaY" : "wheelDeltaX"]) / 3 || -e.detail * 30)); 14807 } 14808 }; 14809 14810 /** 14811 * Pin an element for the duration of the tween. 14812 * If the scene duration is 0 the element will only be unpinned, if the user scrolls back past the start position. 14813 * Make sure only one pin is applied to an element at the same time. 14814 * An element can be pinned multiple times, but only successively. 14815 * _**NOTE:** The option `pushFollowers` has no effect, when the scene duration is 0._ 14816 * @method ScrollMagic.Scene#setPin 14817 * @example 14818 * // pin element and push all following elements down by the amount of the pin duration. 14819 * scene.setPin("#pin"); 14820 * 14821 * // pin element and keeping all following elements in their place. The pinned element will move past them. 14822 * scene.setPin("#pin", {pushFollowers: false}); 14823 * 14824 * @param {(string|object)} element - A Selector targeting an element or a DOM object that is supposed to be pinned. 14825 * @param {object} [settings] - settings for the pin 14826 * @param {boolean} [settings.pushFollowers=true] - If `true` following elements will be "pushed" down for the duration of the pin, if `false` the pinned element will just scroll past them. 14827 Ignored, when duration is `0`. 14828 * @param {string} [settings.spacerClass="scrollmagic-pin-spacer"] - Classname of the pin spacer element, which is used to replace the element. 14829 * 14830 * @returns {Scene} Parent object for chaining. 14831 */ 14832 this.setPin = function (element, settings) { 14833 var defaultSettings = { 14834 pushFollowers: true, 14835 spacerClass: "scrollmagic-pin-spacer" 14836 }; 14837 settings = _util.extend({}, defaultSettings, settings); 14838 14839 // validate Element 14840 element = _util.get.elements(element)[0]; 14841 if (!element) { 14842 log(1, "ERROR calling method 'setPin()': Invalid pin element supplied."); 14843 return Scene; // cancel 14844 } else if (_util.css(element, "position") === "fixed") { 14845 log(1, "ERROR calling method 'setPin()': Pin does not work with elements that are positioned 'fixed'."); 14846 return Scene; // cancel 14847 } 14848 14849 if (_pin) { 14850 // preexisting pin? 14851 if (_pin === element) { 14852 // same pin we already have -> do nothing 14853 return Scene; // cancel 14854 } else { 14855 // kill old pin 14856 Scene.removePin(); 14857 } 14858 } 14859 _pin = element; 14860 14861 var parentDisplay = _pin.parentNode.style.display, 14862 boundsParams = ["top", "left", "bottom", "right", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom"]; 14863 14864 _pin.parentNode.style.display = 'none'; // hack start to force css to return stylesheet values instead of calculated px values. 14865 var inFlow = _util.css(_pin, "position") != "absolute", 14866 pinCSS = _util.css(_pin, boundsParams.concat(["display"])), 14867 sizeCSS = _util.css(_pin, ["width", "height"]); 14868 _pin.parentNode.style.display = parentDisplay; // hack end. 14869 if (!inFlow && settings.pushFollowers) { 14870 log(2, "WARNING: If the pinned element is positioned absolutely pushFollowers will be disabled."); 14871 settings.pushFollowers = false; 14872 } 14873 window.setTimeout(function () { 14874 // wait until all finished, because with responsive duration it will only be set after scene is added to controller 14875 if (_pin && _options.duration === 0 && settings.pushFollowers) { 14876 log(2, "WARNING: pushFollowers =", true, "has no effect, when scene duration is 0."); 14877 } 14878 }, 0); 14879 14880 // create spacer and insert 14881 var spacer = _pin.parentNode.insertBefore(document.createElement('div'), _pin), 14882 spacerCSS = _util.extend(pinCSS, { 14883 position: inFlow ? "relative" : "absolute", 14884 boxSizing: "content-box", 14885 mozBoxSizing: "content-box", 14886 webkitBoxSizing: "content-box" 14887 }); 14888 14889 if (!inFlow) { 14890 // copy size if positioned absolutely, to work for bottom/right positioned elements. 14891 _util.extend(spacerCSS, _util.css(_pin, ["width", "height"])); 14892 } 14893 14894 _util.css(spacer, spacerCSS); 14895 spacer.setAttribute(PIN_SPACER_ATTRIBUTE, ""); 14896 _util.addClass(spacer, settings.spacerClass); 14897 14898 // set the pin Options 14899 _pinOptions = { 14900 spacer: spacer, 14901 relSize: { // save if size is defined using % values. if so, handle spacer resize differently... 14902 width: sizeCSS.width.slice(-1) === "%", 14903 height: sizeCSS.height.slice(-1) === "%",
14904 autoFullWidth: sizeCSS.width === "auto" && inFlow && _util.isMarginCollapseType(pinCSS.display) 14905 }, 14906 pushFollowers: settings.pushFollowers, 14907 inFlow: inFlow 14908 // stores if the element takes up space in the document flow 14909 }; 14910 14911 if (!_pin.___origStyle) { 14912 _pin.___origStyle = {}; 14913 var pinInlineCSS = _pin.style, 14914 copyStyles = boundsParams.concat(["width", "height", "position", "boxSizing", "mozBoxSizing", "webkitBoxSizing"]); 14915 copyStyles.forEach(function (val) { 14916 _pin.___origStyle[val] = pinInlineCSS[val] || ""; 14917 }); 14918 } 14919 14920 // if relative size, transfer it to spacer and make pin calculate it... 14921 if (_pinOptions.relSize.width) { 14922 _util.css(spacer, { 14923 width: sizeCSS.width 14924 }); 14925 } 14926 if (_pinOptions.relSize.height) { 14927 _util.css(spacer, { 14928 height: sizeCSS.height 14929 }); 14930 } 14931 14932 // now place the pin element inside the spacer 14933 spacer.appendChild(_pin); 14934 // and set new css 14935 _util.css(_pin, { 14936 position: inFlow ? "relative" : "absolute", 14937 margin: "auto", 14938 top: "auto", 14939 left: "auto", 14940 bottom: "auto", 14941 right: "auto" 14942 }); 14943 14944 if (_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) { 14945 _util.css(_pin, { 14946 boxSizing: "border-box", 14947 mozBoxSizing: "border-box", 14948 webkitBoxSizing: "border-box" 14949 }); 14950 } 14951 14952 // add listener to document to update pin position in case controller is not the document. 14953 window.addEventListener('scroll', updatePinInContainer); 14954 window.addEventListener('resize', updatePinInContainer); 14955 window.addEventListener('resize', updateRelativePinSpacer); 14956 // add mousewheel listener to catch scrolls over fixed elements 14957 _pin.addEventListener("mousewheel", onMousewheelOverPin); 14958 _pin.addEventListener("DOMMouseScroll", onMousewheelOverPin); 14959 14960 log(3, "added pin"); 14961 14962 // finally update the pin to init 14963 updatePinState(); 14964 14965 return Scene; 14966 }; 14967 14968 /** 14969 * Remove the pin from the scene. 14970 * @method ScrollMagic.Scene#removePin 14971 * @example 14972 * // remove the pin from the scene without resetting it (the spacer is not removed) 14973 * scene.removePin(); 14974 * 14975 * // remove the pin from the scene and reset the pin element to its initial position (spacer is removed) 14976 * scene.removePin(true); 14977 * 14978 * @param {boolean} [reset=false] - If `false` the spacer will not be removed and the element's position will not be reset. 14979 * @returns {Scene} Parent object for chaining. 14980 */ 14981 this.removePin = function (reset) { 14982 if (_pin) { 14983 if (_state === SCENE_STATE_DURING) { 14984 updatePinState(true); // force unpin at position 14985 } 14986 if (reset || !_controller) { 14987 // if there's no controller no progress was made anyway... 14988 var pinTarget = _pinOptions.spacer.firstChild; // usually the pin element, but may be another spacer (cascaded pins)... 14989 if (pinTarget.hasAttribute(PIN_SPACER_ATTRIBUTE)) { 14990 // copy margins to child spacer 14991 var style = _pinOptions.spacer.style, 14992 values = ["margin", "marginLeft", "marginRight", "marginTop", "marginBottom"]; 14993 margins = {}; 14994 values.forEach(function (val) { 14995 margins[val] = style[val] || ""; 14996 }); 14997 _util.css(pinTarget, margins); 14998 } 14999 _pinOptions.spacer.parentNode.insertBefore(pinTarget, _pinOptions.spacer); 15000 _pinOptions.spacer.parentNode.removeChild(_pinOptions.spacer); 15001 if (!_pin.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) { 15002 // if it's the last pin for this element -> restore inline styles 15003 // TODO: only correctly set for first pin (when cascading) - how to fix? 15004 _util.css(_pin, _pin.___origStyle); 15005 delete _pin.___origStyle; 15006 } 15007 } 15008 window.removeEventListener('scroll', updatePinInContainer); 15009 window.removeEventListener('resize', updatePinInContainer); 15010 window.removeEventListener('resize', updateRelativePinSpacer); 15011 _pin.removeEventListener("mousewheel", onMousewheelOverPin); 15012 _pin.removeEventListener("DOMMouseScroll", onMousewheelOverPin); 15013 _pin = undefined; 15014 log(3, "removed pin (reset: " + (reset ? "true" : "false") + ")"); 15015 } 15016 return Scene; 15017 }; 15018
15019 var _cssClasses, 15020 _cssClassElems = []; 15021 15022 Scene.on("destroy.internal", function (e) { 15023 Scene.removeClassToggle(e.reset); 15024 }); 15025 /** 15026 * Define a css class modification while the scene is active. 15027 * When the scene triggers the classes will be added to the supplied element and removed, when the scene is over. 15028 * If the scene duration is 0 the classes will only be removed if the user scrolls back past the start position. 15029 * @method ScrollMagic.Scene#setClassToggle 15030 * @example 15031 * // add the class 'myclass' to the element with the id 'my-elem' for the duration of the scene 15032 * scene.setClassToggle("#my-elem", "myclass"); 15033 * 15034 * // add multiple classes to multiple elements defined by the selector '.classChange' 15035 * scene.setClassToggle(".classChange", "class1 class2 class3"); 15036 * 15037 * @param {(string|object)} element - A Selector targeting one or more elements or a DOM object that is supposed to be modified. 15038 * @param {string} classes - One or more Classnames (separated by space) that should be added to the element during the scene. 15039 * 15040 * @returns {Scene} Parent object for chaining. 15041 */ 15042 this.setClassToggle = function (element, classes) { 15043 var elems = _util.get.elements(element); 15044 if (elems.length === 0 || !_util.type.String(classes)) { 15045 log(1, "ERROR calling method 'setClassToggle()': Invalid " + (elems.length === 0 ? "element" : "classes") + " supplied."); 15046 return Scene; 15047 } 15048 if (_cssClassElems.length > 0) { 15049 // remove old ones 15050 Scene.removeClassToggle(); 15051 } 15052 _cssClasses = classes; 15053 _cssClassElems = elems; 15054 Scene.on("enter.internal_class leave.internal_class", function (e) { 15055 var toggle = e.type === "enter" ? _util.addClass : _util.removeClass; 15056 _cssClassElems.forEach(function (elem, key) {
15057 toggle(elem, _cssClasses); 15058 }); 15059 }); 15060 return Scene; 15061 }; 15062 15063 /** 15064 * Remove the class binding from the scene. 15065 * @method ScrollMagic.Scene#removeClassToggle 15066 * @example 15067 * // remove class binding from the scene without reset 15068 * scene.removeClassToggle(); 15069 * 15070 * // remove class binding and remove the changes it caused 15071 * scene.removeClassToggle(true); 15072 * 15073 * @param {boolean} [reset=false] - If `false` and the classes are currently active, they will remain on the element. If `true` they will be removed. 15074 * @returns {Scene} Parent object for chaining. 15075 */ 15076 this.removeClassToggle = function (reset) { 15077 if (reset) { 15078 _cssClassElems.forEach(function (elem, key) { 15079 _util.removeClass(elem, _cssClasses); 15080 }); 15081 } 15082 Scene.off("start.internal_class end.internal_class"); 15083 _cssClasses = undefined; 15084 _cssClassElems = []; 15085 return Scene; 15086 }; 15087 15088 // INIT 15089 construct(); 15090 return Scene; 15091 }; 15092 15093 // store pagewide scene options 15094 var SCENE_OPTIONS = { 15095 defaults: { 15096 duration: 0, 15097 offset: 0, 15098 triggerElement: undefined, 15099 triggerHook: 0.5, 15100 reverse: true, 15101 loglevel: 2 15102 }, 15103 validate: { 15104 offset: function (val) { 15105 val = parseFloat(val); 15106 if (!_util.type.Number(val)) { 15107 throw ["Invalid value for option \"offset\":", val]; 15108 } 15109 return val; 15110 }, 15111 triggerElement: function (val) { 15112 val = val || undefined; 15113 if (val) { 15114 var elem = _util.get.elements(val)[0]; 15115 if (elem) { 15116 val = elem; 15117 } else { 15118 throw ["Element defined in option \"triggerElement\" was not found:", val]; 15119 } 15120 } 15121 return val; 15122 }, 15123 triggerHook: function (val) { 15124 var translate = { 15125 "onCenter": 0.5, 15126 "onEnter": 1, 15127 "onLeave": 0 15128 }; 15129 if (_util.type.Number(val)) { 15130 val = Math.max(0, Math.min(parseFloat(val), 1)); // make sure its betweeen 0 and 1 15131 } else if (val in translate) { 15132 val = translate[val]; 15133 } else { 15134 throw ["Invalid value for option \"triggerHook\": ", val]; 15135 } 15136 return val; 15137 }, 15138 reverse: function (val) { 15139 return !!val; // force boolean 15140 }, 15141 loglevel: function (val) { 15142 val = parseInt(val); 15143 if (!_util.type.Number(val) || val < 0 || val > 3) { 15144 throw ["Invalid value for option \"loglevel\":", val]; 15145 } 15146 return val; 15147 } 15148 }, 15149 // holder for validation methods. duration validation is handled in 'getters-setters.js' 15150 shifts: ["duration", "offset", "triggerHook"] 15151 // list of options that trigger a `shift` event 15152 }; 15153 /* 15154 * method used to add an option to ScrollMagic Scenes. 15155 * TODO: DOC (private for dev) 15156 */ 15157 ScrollMagic.Scene.addOption = function (name, defaultValue, validationCallback, shifts) { 15158 if (!(name in SCENE_OPTIONS.defaults)) { 15159 SCENE_OPTIONS.defaults[name] = defaultValue; 15160 SCENE_OPTIONS.validate[name] = validationCallback; 15161 if (shifts) { 15162 SCENE_OPTIONS.shifts.push(name); 15163 } 15164 } else { 15165 ScrollMagic._util.log(1, "[static] ScrollMagic.Scene -> Cannot add Scene option '" + name + "', because it already exists."); 15166 } 15167 }; 15168 // instance extension function for plugins 15169 // TODO: DOC (private for dev) 15170 ScrollMagic.Scene.extend = function (extension) { 15171 var oldClass = this; 15172 ScrollMagic.Scene = function () { 15173 oldClass.apply(this, arguments); 15174 this.$super = _util.extend({}, this); // copy parent state 15175 return extension.apply(this, arguments) || this; 15176 }; 15177 _util.extend(ScrollMagic.Scene, oldClass); // copy properties 15178 ScrollMagic.Scene.prototype = oldClass.prototype; // copy prototype 15179 ScrollMagic.Scene.prototype.constructor = ScrollMagic.Scene; // restore constructor 15180 }; 15181 15182 /** 15183 * TODO: DOCS (private for dev) 15184 * @class 15185 * @private 15186 */ 15187 15188 ScrollMagic.Event = function (type, namespace, target, vars) { 15189 vars = vars || {}; 15190 for (var key in vars) { 15191 this[key] = vars[key]; 15192 } 15193 this.type = type; 15194 this.target = this.currentTarget = target; 15195 this.namespace = namespace || ''; 15196 this.timeStamp = this.timestamp = Date.now(); 15197 return this; 15198 }; 15199 15200 /* 15201 * TODO: DOCS (private for dev) 15202 */ 15203 15204 var _util = ScrollMagic._util = function (window) { 15205 var U = {}, 15206 i; 15207 15208 /** 15209 * ------------------------------ 15210 * internal helpers 15211 * ------------------------------ 15212 */ 15213 15214 // parse float and fall back to 0. 15215 var floatval = function (number) { 15216 return parseFloat(number) || 0; 15217 }; 15218 // get current style IE safe (otherwise IE would return calculated values for 'auto') 15219 var _getComputedStyle = function (elem) { 15220 return elem.currentStyle ? elem.currentStyle : window.getComputedStyle(elem); 15221 }; 15222 15223 // get element dimension (width or height) 15224 var _dimension = function (which, elem, outer, includeMargin) { 15225 elem = elem === document ? window : elem; 15226 if (elem === window) { 15227 includeMargin = false;
15228 } else if (!_type.DomElement(elem)) { 15229 return 0; 15230 } 15231 which = which.charAt(0).toUpperCase() + which.substr(1).toLowerCase(); 15232 var dimension = (outer ? elem['offset' + which] || elem['outer' + which] : elem['client' + which] || elem['inner' + which]) || 0; 15233 if (outer && includeMargin) { 15234 var style = _getComputedStyle(elem); 15235 dimension += which === 'Height' ? floatval(style.marginTop) + floatval(style.marginBottom) : floatval(style.marginLeft) + floatval(style.marginRight); 15236 } 15237 return dimension; 15238 }; 15239 // converts 'margin-top' into 'marginTop' 15240 var _camelCase = function (str) { 15241 return str.replace(/^[^a-z]+([a-z])/g, '$1').replace(/-([a-z])/g, function (g) { 15242 return g[1].toUpperCase(); 15243 }); 15244 }; 15245 15246 /** 15247 * ------------------------------ 15248 * external helpers 15249 * ------------------------------ 15250 */ 15251 15252 // extend obj â same as jQuery.extend({}, objA, objB) 15253 U.extend = function (obj) { 15254 obj = obj || {}; 15255 for (i = 1; i < arguments.length; i++) { 15256 if (!arguments[i]) { 15257 continue; 15258 } 15259 for (var key in arguments[i]) { 15260 if (arguments[i].hasOwnProperty(key)) { 15261 obj[key] = arguments[i][key]; 15262 } 15263 } 15264 } 15265 return obj; 15266 }; 15267 15268 // check if a css display type results in margin-collapse or not 15269 U.isMarginCollapseType = function (str) { 15270 return ["block", "flex", "list-item", "table", "-webkit-box"].indexOf(str) > -1; 15271 }; 15272 15273 // implementation of requestAnimationFrame 15274 // based on https://gist.github.com/paulirish/1579671 15275 var lastTime = 0, 15276 vendors = ['ms', 'moz', 'webkit', 'o']; 15277 var _requestAnimationFrame = window.requestAnimationFrame; 15278 var _cancelAnimationFrame = window.cancelAnimationFrame; 15279 // try vendor prefixes if the above doesn't work 15280 for (i = 0; !_requestAnimationFrame && i < vendors.length; ++i) { 15281 _requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame']; 15282 _cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame']; 15283 } 15284 15285 // fallbacks 15286 if (!_requestAnimationFrame) { 15287 _requestAnimationFrame = function (callback) { 15288 var currTime = new Date().getTime(), 15289 timeToCall = Math.max(0, 16 - (currTime - lastTime)), 15290 id = window.setTimeout(function () { 15291 callback(currTime + timeToCall); 15292 }, timeToCall); 15293 lastTime = currTime + timeToCall; 15294 return id; 15295 }; 15296 } 15297 if (!_cancelAnimationFrame) { 15298 _cancelAnimationFrame = function (id) { 15299 window.clearTimeout(id); 15300 }; 15301 } 15302 U.rAF = _requestAnimationFrame.bind(window); 15303 U.cAF = _cancelAnimationFrame.bind(window); 15304 15305 var loglevels = ["error", "warn", "log"], 15306 console = window.console || {}; 15307 15308 console.log = console.log || function () {}; // no console log, well - do nothing then... 15309 // make sure methods for all levels exist. 15310 for (i = 0; i < loglevels.length; i++) { 15311 var method = loglevels[i]; 15312 if (!console[method]) { 15313 console[method] = console.log; // prefer .log over nothing 15314 } 15315 } 15316 U.log = function (loglevel) { 15317 if (loglevel > loglevels.length || loglevel <= 0) loglevel = loglevels.length; 15318 var now = new Date(), 15319 time = ("0" + now.getHours()).slice(-2) + ":" + ("0" + now.getMinutes()).slice(-2) + ":" + ("0" + now.getSeconds()).slice(-2) + ":" + ("00" + now.getMilliseconds()).slice(-3), 15320 method = loglevels[loglevel - 1], 15321 args = Array.prototype.splice.call(arguments, 1), 15322 func = Function.prototype.bind.call(console[method], console); 15323 args.unshift(time); 15324 func.apply(console, args); 15325 }; 15326 15327 /** 15328 * ------------------------------ 15329 * type testing 15330 * ------------------------------ 15331 */ 15332 15333 var _type = U.type = function (v) { 15334 return Object.prototype.toString.call(v).replace(/^\[object (.+)\]$/, "$1").toLowerCase(); 15335 }; 15336 _type.String = function (v) { 15337 return _type(v) === 'string'; 15338 }; 15339 _type.Function = function (v) { 15340 return _type(v) === 'function'; 15341 }; 15342 _type.Array = function (v) { 15343 return Array.isArray(v); 15344 }; 15345 _type.Number = function (v) { 15346 return !_type.Array(v) && v - parseFloat(v) + 1 >= 0; 15347 }; 15348 _type.DomElement = function (o) { 15349 return typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2 15350 o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"; 15351 }; 15352 15353 /** 15354 * ------------------------------ 15355 * DOM Element info 15356 * ------------------------------ 15357 */ 15358 // always returns a list of matching DOM elements, from a selector, a DOM element or an list of elements or even an array of selectors 15359 var _get = U.get = {}; 15360 _get.elements = function (selector) { 15361 var arr = []; 15362 if (_type.String(selector)) { 15363 try { 15364 selector = document.querySelectorAll(selector); 15365 } catch (e) { 15366 // invalid selector 15367 return arr; 15368 } 15369 } 15370 if (_type(selector) === 'nodelist' || _type.Array(selector)) { 15371 for (var i = 0, ref = arr.length = selector.length; i < ref; i++) { 15372 // list of elements 15373 var elem = selector[i]; 15374 arr[i] = _type.DomElement(elem) ? elem : _get.elements(elem); // if not an element, try to resolve recursively 15375 } 15376 } else if (_type.DomElement(selector) || selector === document || selector === window) { 15377 arr = [selector]; // only the element 15378 } 15379 return arr; 15380 }; 15381 // get scroll top value 15382 _get.scrollTop = function (elem) { 15383 return elem && typeof elem.scrollTop === 'number' ? elem.scrollTop : window.pageYOffset || 0; 15384 }; 15385 // get scroll left value 15386 _get.scrollLeft = function (elem) { 15387 return elem && typeof elem.scrollLeft === 'number' ? elem.scrollLeft : window.pageXOffset || 0; 15388 }; 15389 // get element height 15390 _get.width = function (elem, outer, includeMargin) { 15391 return _dimension('width', elem, outer, includeMargin); 15392 }; 15393 // get element width 15394 _get.height = function (elem, outer, includeMargin) { 15395 return _dimension('height', elem, outer, includeMargin); 15396 }; 15397 15398 // get element position (optionally relative to viewport) 15399 _get.offset = function (elem, relativeToViewport) { 15400 var offset = { 15401 top: 0, 15402 left: 0 15403 }; 15404 if (elem && elem.getBoundingClientRect) { 15405 // check if available 15406 var rect = elem.getBoundingClientRect(); 15407 offset.top = rect.top; 15408 offset.left = rect.left; 15409 if (!relativeToViewport) { 15410 // clientRect is by default relative to viewport... 15411 offset.top += _get.scrollTop(); 15412 offset.left += _get.scrollLeft(); 15413 } 15414 } 15415 return offset; 15416 }; 15417 15418 /** 15419 * ------------------------------ 15420 * DOM Element manipulation 15421 * ------------------------------ 15422 */ 15423 15424 U.addClass = function (elem, classname) { 15425 if (classname) { 15426 if (elem.classList) elem.classList.add(classname);else elem.className += ' ' + classname; 15427 } 15428 }; 15429 U.removeClass = function (elem, classname) { 15430 if (classname) { 15431 if (elem.classList) elem.classList.remove(classname);else elem.className = elem.className.replace(new RegExp('(^|\\b)' + classname.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 15432 } 15433 }; 15434 // if options is string -> returns css value 15435 // if options is array -> returns object with css value pairs 15436 // if options is object -> set new css values 15437 U.css = function (elem, options) { 15438 if (_type.String(options)) { 15439 return _getComputedStyle(elem)[_camelCase(options)]; 15440 } else if (_type.Array(options)) { 15441 var obj = {}, 15442 style = _getComputedStyle(elem); 15443 options.forEach(function (option, key) { 15444 obj[option] = style[_camelCase(option)]; 15445 }); 15446 return obj; 15447 } else { 15448 for (var option in options) { 15449 var val = options[option]; 15450 if (val == parseFloat(val)) { 15451 // assume pixel for seemingly numerical values 15452 val += 'px'; 15453 } 15454 elem.style[_camelCase(option)] = val; 15455 } 15456 } 15457 }; 15458 15459 return U; 15460 }(window || {}); 15461 15462 ScrollMagic.Scene.prototype.addIndicators = function () { 15463 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling addIndicators() due to missing Plugin \'debug.addIndicators\'. Please make sure to include plugins/debug.addIndicators.js'); 15464 return this; 15465 }; 15466 ScrollMagic.Scene.prototype.removeIndicators = function () { 15467 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeIndicators() due to missing Plugin \'debug.addIndicators\'. Please make sure to include plugins/debug.addIndicators.js'); 15468 return this; 15469 }; 15470 ScrollMagic.Scene.prototype.setTween = function () { 15471 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling setTween() due to missing Plugin \'animation.gsap\'. Please make sure to include plugins/animation.gsap.js'); 15472 return this; 15473 }; 15474 ScrollMagic.Scene.prototype.removeTween = function () { 15475 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeTween() due to missing Plugin \'animation.gsap\'. Please make sure to include plugins/animation.gsap.js'); 15476 return this; 15477 }; 15478 ScrollMagic.Scene.prototype.setVelocity = function () { 15479 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling setVelocity() due to missing Plugin \'animation.velocity\'. Please make sure to include plugins/animation.velocity.js'); 15480 return this; 15481 }; 15482 ScrollMagic.Scene.prototype.removeVelocity = function () { 15483 ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeVelocity() due to missing Plugin \'animation.velocity\'. Please make sure to include plugins/animation.velocity.js'); 15484 return this; 15485 }; 15486 15487 return ScrollMagic; 15488}); 15489 15490/***/ }), 15491/* 3 */, 15492/* 4 */, 15493/* 5 */
15494/***/ (function(module, exports) { 15495 15496var g; 15497 15498// This works in non-strict mode 15499g = function () { 15500 return this; 15501}(); 15502 15503try { 15504 // This works if eval is allowed (see CSP) 15505 g = g || Function("return this")() || (1, eval)("this"); 15506} catch (e) { 15507 // This works if the window reference is available 15508 if (typeof window === "object") g = window; 15509} 15510 15511// g can still be undefined, but nothing to do about it... 15512// We return undefined, instead of nothing here, so it's 15513// easier to handle this case. if(!global) { ...} 15514 15515module.exports = g; 15516 15517/***/ }), 15518/* 6 */ 15519/***/ (function(module, __webpack_exports__, __webpack_require__) { 15520 15521"use strict"; 15522/* eslint consistent-return: "off" */ 15523/* eslint func-names: ["off"] */ 15524/* eslint max-len: ["off", { "code": 200 }] */ 15525/* eslint prefer-destructuring: ["off"] */ 15526/** 15527 * ------------------------------------------------------------------ 15528 * 夿æµè§å¨ç±»å 15529 * ------------------------------------------------------------------ 15530 */ 15531 15532const browserType = function () { 15533 const userAgent = navigator.userAgent; // å徿µè§å¨çuserAgentå符串 15534 const isOpera = userAgent.indexOf('Opera') > -1; // 夿æ¯å¦Operaæµè§å¨ 15535 // let isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //夿æ¯å¦IEæµè§å¨ 15536 const isIE = window.ActiveXObject || 'ActiveXObject' in window; 15537 // let isEdge = userAgent.indexOf("Windows NT 6.1; Trident/7.0;") > -1 && !isIE; //夿æ¯å¦IEçEdgeæµè§å¨ 15538 const isEdge = userAgent.indexOf('Edge') > -1; // 夿æ¯å¦IEçEdgeæµè§å¨ 15539 const isFF = userAgent.indexOf('Firefox') > -1; // 夿æ¯å¦Firefoxæµè§å¨ 15540 const isSafari = userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1; // 夿æ¯å¦Safariæµè§å¨ 15541 const isChrome = userAgent.indexOf('Chrome') > -1 && userAgent.indexOf('Safari') > -1 && !isEdge; // 夿Chromeæµè§å¨ 15542 15543 if (isIE) { 15544 const reIE = new RegExp('MSIE (\\d+\\.\\d+);'); 15545 reIE.test(userAgent); 15546 const fIEVersion = parseFloat(RegExp.$1); 15547 if (userAgent.indexOf('MSIE 6.0') !== -1) { 15548 return 'IE6'; 15549 } else if (fIEVersion === 7) { 15550 return 'IE7'; 15551 } else if (fIEVersion === 8) { 15552 return 'IE8'; 15553 } else if (fIEVersion === 9) { 15554 return 'IE9'; 15555 } else if (fIEVersion === 10) { 15556 return 'IE10'; 15557 } else if (userAgent.toLowerCase().match(/rv:([\d.]+)\) like gecko/)) { 15558 return 'IE11'; 15559 } 15560 return '0'; // IEçæ¬è¿ä½ 15561 } // isIE end 15562 15563 if (isFF) { 15564 return 'FF'; 15565 } 15566 if (isOpera) { 15567 return 'Opera'; 15568 } 15569 if (isSafari) { 15570 return 'Safari'; 15571 } 15572 if (isChrome) { 15573 return 'Chrome'; 15574 } 15575 if (isEdge) { 15576 return 'Edge'; 15577 } 15578}; 15579 15580/* harmony default export */ __webpack_exports__["a"] = (browserType); 15581 15582/***/ }), 15583/* 7 */ 15584/***/ (function(module, exports, __webpack_require__) { 15585 15586/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 15587 * VERSION: 1.20.3 15588 * DATE: 2017-10-02 15589 * UPDATES AND DOCS AT: http://greensock.com 15590 * 15591 * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin 15592 * 15593 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved. 15594 * This work is subject to the terms at http://greensock.com/standard-license or for 15595 * Club GreenSock members, the software agreement that was issued with your membership. 15596 * 15597 * @author: Jack Doyle, [email protected] 15598 **/ 15599var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node 15600(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () { 15601 15602 "use strict"; 15603 15604 _gsScope._gsDefine("TweenMax", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) { 15605 15606 var _slice = function (a) { 15607 //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 15608 var b = [], 15609 l = a.length, 15610 i; 15611 for (i = 0; i !== l; b.push(a[i++])); 15612 return b; 15613 }, 15614 _applyCycle = function (vars, targets, i) { 15615 var alt = vars.cycle, 15616 p, 15617 val; 15618 for (p in alt) { 15619 val = alt[p]; 15620 vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length]; 15621 } 15622 delete vars.cycle; 15623 }, 15624 TweenMax = function (target, duration, vars) { 15625 TweenLite.call(this, target, duration, vars); 15626 this._cycle = 0; 15627 this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase; 15628 this._repeat = this.vars.repeat || 0; 15629 this._repeatDelay = this.vars.repeatDelay || 0; 15630 if (this._repeat) { 15631 this._uncache(true); //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it. 15632 } 15633 this.render = TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) 15634 }, 15635 _tinyNum = 0.0000000001, 15636 TweenLiteInternals = TweenLite._internals, 15637 _isSelector = TweenLiteInternals.isSelector, 15638 _isArray = TweenLiteInternals.isArray, 15639 p = TweenMax.prototype = TweenLite.to({}, 0.1, {}), 15640 _blankArray = []; 15641 15642 TweenMax.version = "1.20.3"; 15643 p.constructor = TweenMax; 15644 p.kill()._gc = false;
15645 TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf; 15646 TweenMax.getTweensOf = TweenLite.getTweensOf; 15647 TweenMax.lagSmoothing = TweenLite.lagSmoothing; 15648 TweenMax.ticker = TweenLite.ticker; 15649 TweenMax.render = TweenLite.render; 15650 15651 p.invalidate = function () { 15652 this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase; 15653 this._repeat = this.vars.repeat || 0; 15654 this._repeatDelay = this.vars.repeatDelay || 0; 15655 this._yoyoEase = null; 15656 this._uncache(true); 15657 return TweenLite.prototype.invalidate.call(this); 15658 }; 15659 15660 p.updateTo = function (vars, resetDuration) { 15661 var curRatio = this.ratio, 15662 immediate = this.vars.immediateRender || vars.immediateRender, 15663 p; 15664 if (resetDuration && this._startTime < this._timeline._time) { 15665 this._startTime = this._timeline._time; 15666 this._uncache(false); 15667 if (this._gc) { 15668 this._enabled(true, false); 15669 } else { 15670 this._timeline.insert(this, this._startTime - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. 15671 } 15672 } 15673 for (p in vars) { 15674 this.vars[p] = vars[p]; 15675 } 15676 if (this._initted || immediate) { 15677 if (resetDuration) { 15678 this._initted = false; 15679 if (immediate) { 15680 this.render(0, true, true); 15681 } 15682 } else { 15683 if (this._gc) { 15684 this._enabled(true, false); 15685 } 15686 if (this._notifyPluginsOfEnabled && this._firstPT) { 15687 TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks 15688 } 15689 if (this._time / this._duration > 0.998) { 15690 //if the tween has finished (or come extremely close to finishing), we just need to rewind it to 0 and then render it again at the end which forces it to re-initialize (parsing the new vars). We allow tweens that are close to finishing (but haven't quite finished) to work this way too because otherwise, the values are so small when determining where to project the starting values that binary math issues creep in and can make the tween appear to render incorrectly when run backwards. 15691 var prevTime = this._totalTime; 15692 this.render(0, true, false); 15693 this._initted = false; 15694 this.render(prevTime, true, false); 15695 } else { 15696 this._initted = false; 15697 this._init(); 15698 if (this._time > 0 || immediate) { 15699 var inv = 1 / (1 - curRatio), 15700 pt = this._firstPT, 15701 endValue; 15702 while (pt) { 15703 endValue = pt.s + pt.c; 15704 pt.c *= inv; 15705 pt.s = endValue - pt.c; 15706 pt = pt._next; 15707 } 15708 } 15709 } 15710 } 15711 } 15712 return this; 15713 }; 15714 15715 p.render = function (time, suppressEvents, force) { 15716 if (!this._initted) if (this._duration === 0 && this.vars.repeat) { 15717 //zero duration tweens that render immediately have render() called from TweenLite's constructor, before TweenMax's constructor has finished setting _repeat, _repeatDelay, and _yoyo which are critical in determining totalDuration() so we need to call invalidate() which is a low-kb way to get those set properly. 15718 this.invalidate(); 15719 } 15720 var totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 15721 prevTime = this._time, 15722 prevTotalTime = this._totalTime, 15723 prevCycle = this._cycle, 15724 duration = this._duration, 15725 prevRawPrevTime = this._rawPrevTime, 15726 isComplete, 15727 callback, 15728 pt, 15729 cycleDuration, 15730 r, 15731 type, 15732 pow, 15733 rawPrevTime, 15734 yoyoEase; 15735 if (time >= totalDur - 0.0000001 && time >= 0) { 15736 //to work around occasional floating point math artifacts. 15737 this._totalTime = totalDur; 15738 this._cycle = this._repeat; 15739 if (this._yoyo && (this._cycle & 1) !== 0) { 15740 this._time = 0; 15741 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 15742 } else { 15743 this._time = duration; 15744 this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1; 15745 } 15746 if (!this._reversed) { 15747 isComplete = true; 15748 callback = "onComplete"; 15749 force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 15750 } 15751 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 15752 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 15753 if (this._startTime === this._timeline._duration) { 15754 //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
15754ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate. 15755 time = 0; 15756 } 15757 if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) { 15758 //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause. 15759 force = true; 15760 if (prevRawPrevTime > _tinyNum) { 15761 callback = "onReverseComplete"; 15762 } 15763 } 15764 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 15765 } 15766 } else if (time < 0.0000001) { 15767 //to work around occasional floating point math artifacts, round super small values to 0. 15768 this._totalTime = this._time = this._cycle = 0; 15769 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 15770 if (prevTotalTime !== 0 || duration === 0 && prevRawPrevTime > 0) { 15771 callback = "onReverseComplete"; 15772 isComplete = this._reversed; 15773 } 15774 if (time < 0) { 15775 this._active = false; 15776 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 15777 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 15778 if (prevRawPrevTime >= 0) { 15779 force = true; 15780 } 15781 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 15782 } 15783 } 15784 if (!this._initted) { 15785 //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. 15786 force = true; 15787 } 15788 } else { 15789 this._totalTime = this._time = time; 15790 if (this._repeat !== 0) { 15791 cycleDuration = duration + this._repeatDelay; 15792 this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 15793 if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) { 15794 this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) 15795 } 15796 this._time = this._totalTime - this._cycle * cycleDuration; 15797 if (this._yoyo) if ((this._cycle & 1) !== 0) { 15798 this._time = duration - this._time; 15799 yoyoEase = this._yoyoEase || this.vars.yoyoEase; //note: we don't set this._yoyoEase in _init() like we do other properties because it's TweenMax-specific and doing it here allows us to optimize performance (most tweens don't have a yoyoEase). Note that we also must skip the this.ratio calculation further down right after we _init() in this function, because we're doing it here. 15800 if (yoyoEase) { 15801 if (!this._yoyoEase) { 15802 if (yoyoEase === true && !this._initted) { 15803 //if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here. 15804 yoyoEase = this.vars.ease; 15805 this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : yoyoEase instanceof Ease ? yoyoEase : typeof yoyoEase === "function" ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase; 15806 } else { 15807 this._yoyoEase = yoyoEase = yoyoEase === true ? this._ease : yoyoEase instanceof Ease ? yoyoEase : Ease.map[yoyoEase]; 15808 } 15809 } 15810 this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0; 15811 } 15812 } 15813 if (this._time > duration) { 15814 this._time = duration; 15815 } else if (this._time < 0) { 15816 this._time = 0; 15817 } 15818 } 15819 15820 if (this._easeType && !yoyoEase) { 15821 r = this._time / duration; 15822 type = this._easeType; 15823 pow = this._easePower; 15824 if (type === 1 || type === 3 && r >= 0.5) { 15825 r = 1 - r; 15826 } 15827 if (type === 3) { 15828 r *= 2; 15829 } 15830 if (pow === 1) { 15831 r *= r; 15832 } else if (pow === 2) { 15833 r *= r * r; 15834 } else if (pow === 3) { 15835 r *= r * r * r; 15836 } else if (pow === 4) { 15837 r *= r * r * r * r; 15838 } 15839 15840 if (type === 1) { 15841 this.ratio = 1 - r; 15842 } else if (type === 2) { 15843 this.ratio = r; 15844 } else if (this._time / duration < 0.5) { 15845 this.ratio = r / 2; 15846 } else { 15847 this.ratio = 1 - r / 2; 15848 } 15849 } else if (!yoyoEase) { 15850 this.ratio = this._ease.getRatio(this._time / duration); 15851 } 15852 } 15853 15854 if (prevTime === this._time && !force && prevCycle === this._cycle) { 15855 if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
15856 //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate. 15857 this._callback("onUpdate"); 15858 } 15859 return; 15860 } else if (!this._initted) { 15861 this._init(); 15862 if (!this._initted || this._gc) { 15863 //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that overwriting occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example. 15864 return; 15865 } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) { 15866 //we stick it in the queue for rendering at the very end of the tick - this is a performance optimization because browsers invalidate styles and force a recalculation if you read, write, and then read style data (so it's better to read/read/read/write/write/write than read/write/read/write/read/write). The down side, of course, is that usually you WANT things to render immediately because you may have code running right after that which depends on the change. Like imagine running TweenLite.set(...) and then immediately after that, creating a nother tween that animates the same property to another value; the starting values of that 2nd tween wouldn't be accurate if lazy is true. 15867 this._time = prevTime; 15868 this._totalTime = prevTotalTime; 15869 this._rawPrevTime = prevRawPrevTime; 15870 this._cycle = prevCycle; 15871 TweenLiteInternals.lazyTweens.push(this); 15872 this._lazy = [time, suppressEvents]; 15873 return; 15874 } 15875 //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. 15876 if (this._time && !isComplete && !yoyoEase) { 15877 this.ratio = this._ease.getRatio(this._time / duration); 15878 } else if (isComplete && this._ease._calcEnd && !yoyoEase) { 15879 this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1); 15880 } 15881 } 15882 if (this._lazy !== false) { 15883 this._lazy = false; 15884 } 15885 15886 if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { 15887 this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. 15888 } 15889 if (prevTotalTime === 0) { 15890 if (this._initted === 2 && time > 0) { 15891 //this.invalidate(); 15892 this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true 15893 } 15894 if (this._startAt) { 15895 if (time >= 0) { 15896 this._startAt.render(time, true, force); 15897 } else if (!callback) { 15898 callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area. 15899 } 15900 } 15901 if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) { 15902 this._callback("onStart"); 15903 } 15904 } 15905 15906 pt = this._firstPT; 15907 while (pt) { 15908 if (pt.f) { 15909 pt.t[pt.p](pt.c * this.ratio + pt.s); 15910 } else { 15911 pt.t[pt.p] = pt.c * this.ratio + pt.s; 15912 } 15913 pt = pt._next; 15914 } 15915 15916 if (this._onUpdate) { 15917 if (time < 0) if (this._startAt && this._startTime) { 15918 //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 15919 this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 15920 } 15921 if (!suppressEvents) if (this._totalTime !== prevTotalTime || callback) {
15922 this._callback("onUpdate"); 15923 } 15924 } 15925 if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) { 15926 this._callback("onRepeat"); 15927 } 15928 if (callback) if (!this._gc || force) { 15929 //check gc because there's a chance that kill() could be called in an onUpdate 15930 if (time < 0 && this._startAt && !this._onUpdate && this._startTime) { 15931 //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 15932 this._startAt.render(time, true, force); 15933 } 15934 if (isComplete) { 15935 if (this._timeline.autoRemoveChildren) { 15936 this._enabled(false, false); 15937 } 15938 this._active = false; 15939 } 15940 if (!suppressEvents && this.vars[callback]) { 15941 this._callback(callback); 15942 } 15943 if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { 15944 //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
15944nario, but possible nonetheless. 15945 this._rawPrevTime = 0; 15946 } 15947 } 15948 }; 15949 15950 //---- STATIC FUNCTIONS ----------------------------------------------------------------------------------------------------------- 15951 15952 TweenMax.to = function (target, duration, vars) { 15953 return new TweenMax(target, duration, vars); 15954 }; 15955 15956 TweenMax.from = function (target, duration, vars) { 15957 vars.runBackwards = true; 15958 vars.immediateRender = vars.immediateRender != false; 15959 return new TweenMax(target, duration, vars); 15960 }; 15961 15962 TweenMax.fromTo = function (target, duration, fromVars, toVars) { 15963 toVars.startAt = fromVars; 15964 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 15965 return new TweenMax(target, duration, toVars); 15966 }; 15967 15968 TweenMax.staggerTo = TweenMax.allTo = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 15969 stagger = stagger || 0; 15970 var delay = 0, 15971 a = [], 15972 finalComplete = function () { 15973 if (vars.onComplete) { 15974 vars.onComplete.apply(vars.onCompleteScope || this, arguments); 15975 } 15976 onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray); 15977 }, 15978 cycle = vars.cycle, 15979 fromCycle = vars.startAt && vars.startAt.cycle, 15980 l, 15981 copy, 15982 i, 15983 p; 15984 if (!_isArray(targets)) { 15985 if (typeof targets === "string") { 15986 targets = TweenLite.selector(targets) || targets; 15987 } 15988 if (_isSelector(targets)) { 15989 targets = _slice(targets); 15990 } 15991 } 15992 targets = targets || []; 15993 if (stagger < 0) { 15994 targets = _slice(targets); 15995 targets.reverse(); 15996 stagger *= -1; 15997 } 15998 l = targets.length - 1; 15999 for (i = 0; i <= l; i++) { 16000 copy = {}; 16001 for (p in vars) { 16002 copy[p] = vars[p]; 16003 } 16004 if (cycle) { 16005 _applyCycle(copy, targets, i); 16006 if (copy.duration != null) { 16007 duration = copy.duration; 16008 delete copy.duration; 16009 } 16010 } 16011 if (fromCycle) { 16012 fromCycle = copy.startAt = {}; 16013 for (p in vars.startAt) { 16014 fromCycle[p] = vars.startAt[p]; 16015 } 16016 _applyCycle(copy.startAt, targets, i); 16017 } 16018 copy.delay = delay + (copy.delay || 0); 16019 if (i === l && onCompleteAll) { 16020 copy.onComplete = finalComplete; 16021 } 16022 a[i] = new TweenMax(targets[i], duration, copy); 16023 delay += stagger; 16024 } 16025 return a; 16026 }; 16027 16028 TweenMax.staggerFrom = TweenMax.allFrom = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 16029 vars.runBackwards = true; 16030 vars.immediateRender = vars.immediateRender != false; 16031 return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 16032 }; 16033 16034 TweenMax.staggerFromTo = TweenMax.allFromTo = function (targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 16035 toVars.startAt = fromVars; 16036 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 16037 return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 16038 }; 16039 16040 TweenMax.delayedCall = function (delay, callback, params, scope, useFrames) { 16041 return new TweenMax(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, useFrames: useFrames, overwrite: 0 }); 16042 }; 16043 16044 TweenMax.set = function (target, vars) { 16045 return new TweenMax(target, 0, vars); 16046 }; 16047 16048 TweenMax.isTweening = function (target) { 16049 return TweenLite.getTweensOf(target, true).length > 0; 16050 }; 16051 16052 var _getChildrenOf = function (timeline, includeTimelines) { 16053 var a = [], 16054 cnt = 0, 16055 tween = timeline._first; 16056 while (tween) { 16057 if (tween instanceof TweenLite) { 16058 a[cnt++] = tween; 16059 } else { 16060 if (includeTimelines) { 16061 a[cnt++] = tween; 16062 } 16063 a = a.concat(_getChildrenOf(tween, includeTimelines)); 16064 cnt = a.length; 16065 } 16066 tween = tween._next; 16067 } 16068 return a; 16069 }, 16070 getAllTweens = TweenMax.getAllTweens = function (includeTimelines) { 16071 return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat(_getChildrenOf(Animation._rootFramesTimeline, includeTimelines)); 16072 }; 16073 16074 TweenMax.killAll = function (complete, tweens, delayedCalls, timelines) { 16075 if (tweens == null) { 16076 tweens = true; 16077 } 16078 if (delayedCalls == null) { 16079 delayedCalls = true; 16080 } 16081 var a = getAllTweens(timelines != false), 16082 l = a.length, 16083 allTrue = tweens && delayedCalls && timelines, 16084 isDC, 16085 tween, 16086 i; 16087 for (i = 0; i < l; i++) { 16088 tween = a[i]; 16089 if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) { 16090 if (complete) { 16091 tween.totalTime(tween._reversed ? 0 : tween.totalDuration()); 16092 } else { 16093 tween._enabled(false, false); 16094 } 16095 } 16096 } 16097 }; 16098 16099 TweenMax.killChildTweensOf = function (parent, complete) { 16100 if (parent == null) { 16101 return; 16102 } 16103 var tl = TweenLiteInternals.tweenLookup, 16104 a, 16105 curParent, 16106 p, 16107 i, 16108 l; 16109 if (typeof parent === "string") { 16110 parent = TweenLite.selector(parent) || parent; 16111 } 16112 if (_isSelector(parent)) { 16113 parent = _slice(parent); 16114 } 16115 if (_isArray(parent)) { 16116 i = parent.length; 16117 while (--i > -1) { 16118 TweenMax.killChildTweensOf(parent[i], complete); 16119 } 16120 return; 16121 } 16122 a = []; 16123 for (p in tl) { 16124 curParent = tl[p].target.parentNode; 16125 while (curParent) { 16126 if (curParent === parent) { 16127 a = a.concat(tl[p].tweens); 16128 } 16129 curParent = curParent.parentNode; 16130 } 16131 } 16132 l = a.length; 16133 for (i = 0; i < l; i++) { 16134 if (complete) { 16135 a[i].totalTime(a[i].totalDuration()); 16136 } 16137 a[i]._enabled(false, false); 16138 } 16139 }; 16140 16141 var _changePause = function (pause, tweens, delayedCalls, timelines) { 16142 tweens = tweens !== false; 16143 delayedCalls = delayedCalls !== false; 16144 timelines = timelines !== false; 16145 var a = getAllTweens(timelines), 16146 allTrue = tweens && delayedCalls && timelines, 16147 i = a.length, 16148 isDC, 16149 tween; 16150 while (--i > -1) { 16151 tween = a[i]; 16152 if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) { 16153 tween.paused(pause); 16154 } 16155 } 16156 }; 16157 16158 TweenMax.pauseAll = function (tweens, delayedCalls, timelines) { 16159 _changePause(true, tweens, delayedCalls, timelines); 16160 }; 16161 16162 TweenMax.resumeAll = function (tweens, delayedCalls, timelines) { 16163 _changePause(false, tweens, delayedCalls, timelines); 16164 }; 16165 16166 TweenMax.globalTimeScale = function (value) { 16167 var tl = Animation._rootTimeline, 16168 t = TweenLite.ticker.time; 16169 if (!arguments.length) { 16170 return tl._timeScale; 16171 } 16172 value = value || _tinyNum; //can't allow zero because it'll throw the math off 16173 tl._startTime = t - (t - tl._startTime) * tl._timeScale / value; 16174 tl = Animation._rootFramesTimeline; 16175 t = TweenLite.ticker.frame; 16176 tl._startTime = t - (t - tl._startTime) * tl._timeScale / value; 16177 tl._timeScale = Animation._rootTimeline._timeScale = value; 16178 return value; 16179 }; 16180 16181 //---- GETTERS / SETTERS ---------------------------------------------------------------------------------------------------------- 16182 16183 p.progress = function (value, suppressEvents) { 16184 return !arguments.length ? this._time / this.duration() : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents); 16185 }; 16186 16187 p.totalProgress = function (value, suppressEvents) { 16188 return !arguments.length ? this._totalTime / this.totalDuration() : this.totalTime(this.totalDuration() * value, suppressEvents); 16189 }; 16190 16191 p.time = function (value, suppressEvents) { 16192 if (!arguments.length) { 16193 return this._time; 16194 } 16195 if (this._dirty) { 16196 this.totalDuration(); 16197 } 16198 if (value > this._duration) { 16199 value = this._duration; 16200 } 16201 if (this._yoyo && (this._cycle & 1) !== 0) { 16202 value = this._duration - value + this._cycle * (this._duration + this._repeatDelay); 16203 } else if (this._repeat !== 0) { 16204 value += this._cycle * (this._duration + this._repeatDelay); 16205 } 16206 return this.totalTime(value, suppressEvents); 16207 }; 16208 16209 p.duration = function (value) { 16210 if (!arguments.length) { 16211 return this._duration; //don't set _dirty = false because there could be repeats that haven't been factored
16211into the _totalDuration yet. Otherwise, if you create a repeated TweenMax and then immediately check its duration(), it would cache the value and the totalDuration would not be correct, thus repeats wouldn't take effect. 16212 } 16213 return Animation.prototype.duration.call(this, value); 16214 }; 16215 16216 p.totalDuration = function (value) { 16217 if (!arguments.length) { 16218 if (this._dirty) { 16219 //instead of Infinity, we use 999999999999 so that we can accommodate reverses 16220 this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat; 16221 this._dirty = false; 16222 } 16223 return this._totalDuration; 16224 } 16225 return this._repeat === -1 ? this : this.duration((value - this._repeat * this._repeatDelay) / (this._repeat + 1)); 16226 }; 16227 16228 p.repeat = function (value) { 16229 if (!arguments.length) { 16230 return this._repeat; 16231 } 16232 this._repeat = value; 16233 return this._uncache(true); 16234 }; 16235 16236 p.repeatDelay = function (value) { 16237 if (!arguments.length) { 16238 return this._repeatDelay; 16239 } 16240 this._repeatDelay = value; 16241 return this._uncache(true); 16242 }; 16243 16244 p.yoyo = function (value) { 16245 if (!arguments.length) { 16246 return this._yoyo; 16247 } 16248 this._yoyo = value; 16249 return this; 16250 }; 16251 16252 return TweenMax; 16253 }, true); 16254 16255 /* 16256 * ---------------------------------------------------------------- 16257 * TimelineLite 16258 * ---------------------------------------------------------------- 16259 */ 16260 _gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) { 16261 16262 var TimelineLite = function (vars) { 16263 SimpleTimeline.call(this, vars); 16264 this._labels = {}; 16265 this.autoRemoveChildren = this.vars.autoRemoveChildren === true; 16266 this.smoothChildTiming = this.vars.smoothChildTiming === true; 16267 this._sortChildren = true; 16268 this._onUpdate = this.vars.onUpdate; 16269 var v = this.vars, 16270 val, 16271 p; 16272 for (p in v) { 16273 val = v[p]; 16274 if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) { 16275 v[p] = this._swapSelfInParams(val); 16276 } 16277 } 16278 if (_isArray(v.tweens)) { 16279 this.add(v.tweens, 0, v.align, v.stagger); 16280 } 16281 }, 16282 _tinyNum = 0.0000000001, 16283 TweenLiteInternals = TweenLite._internals, 16284 _internals = TimelineLite._internals = {}, 16285 _isSelector = TweenLiteInternals.isSelector, 16286 _isArray = TweenLiteInternals.isArray, 16287 _lazyTweens = TweenLiteInternals.lazyTweens, 16288 _lazyRender = TweenLiteInternals.lazyRender, 16289 _globals = _gsScope._gsDefine.globals, 16290 _copy = function (vars) { 16291 var copy = {}, 16292 p; 16293 for (p in vars) { 16294 copy[p] = vars[p]; 16295 } 16296 return copy; 16297 }, 16298 _applyCycle = function (vars, targets, i) { 16299 var alt = vars.cycle, 16300 p, 16301 val; 16302 for (p in alt) { 16303 val = alt[p]; 16304 vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length]; 16305 } 16306 delete vars.cycle; 16307 }, 16308 _pauseCallback = _internals.pauseCallback = function () {}, 16309 _slice = function (a) { 16310 //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 16311 var b = [], 16312 l = a.length, 16313 i; 16314 for (i = 0; i !== l; b.push(a[i++])); 16315 return b; 16316 }, 16317 p = TimelineLite.prototype = new SimpleTimeline(); 16318 16319 TimelineLite.version = "1.20.3"; 16320 p.constructor = TimelineLite; 16321 p.kill()._gc = p._forcingPlayhead = p._hasPause = false; 16322 16323 /* might use later... 16324 //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales. 16325 function localToGlobal(time, animation) { 16326 while (animation) { 16327 time = (time / animation._timeScale) + animation._startTime; 16328 animation = animation.timeline; 16329 } 16330 return time; 16331 } 16332 //translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales 16333 function globalToLocal(time, animation) { 16334 var scale = 1; 16335 time -= localToGlobal(0, animation); 16336 while (animation) { 16337 scale *= animation._timeScale; 16338 animation = animation.timeline; 16339 } 16340 return time * scale; 16341 } 16342 */ 16343 16344 p.to = function (target, duration, vars, position) { 16345 var Engine = vars.repeat && _globals.TweenMax || TweenLite; 16346 return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position); 16347 }; 16348 16349 p.from = function (target, duration, vars, position) { 16350 return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position); 16351 }; 16352 16353 p.fromTo = function (target, duration, fromVars, toVars, position) { 16354 var Engine = toVars.repeat && _globals.TweenMax || TweenLite; 16355 return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position); 16356 }; 16357 16358 p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 16359 var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }), 16360 cycle = vars.cycle, 16361 copy, 16362 i; 16363 if (typeof targets === "string") { 16364 targets = TweenLite.selector(targets) || targets; 16365 } 16366 targets = targets || []; 16367 if (_isSelector(targets)) { 16368 //senses if the targets object is a selector. If it is, we should translate it into an array.
16369 targets = _slice(targets); 16370 } 16371 stagger = stagger || 0; 16372 if (stagger < 0) { 16373 targets = _slice(targets); 16374 targets.reverse(); 16375 stagger *= -1; 16376 } 16377 for (i = 0; i < targets.length; i++) { 16378 copy = _copy(vars); 16379 if (copy.startAt) { 16380 copy.startAt = _copy(copy.startAt); 16381 if (copy.startAt.cycle) { 16382 _applyCycle(copy.startAt, targets, i); 16383 } 16384 } 16385 if (cycle) { 16386 _applyCycle(copy, targets, i); 16387 if (copy.duration != null) { 16388 duration = copy.duration; 16389 delete copy.duration; 16390 } 16391 } 16392 tl.to(targets[i], duration, copy, i * stagger); 16393 } 16394 return this.add(tl, position); 16395 }; 16396 16397 p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 16398 vars.immediateRender = vars.immediateRender != false; 16399 vars.runBackwards = true; 16400 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 16401 }; 16402 16403 p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 16404 toVars.startAt = fromVars; 16405 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 16406 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 16407 }; 16408 16409 p.call = function (callback, params, scope, position) { 16410 return this.add(TweenLite.delayedCall(0, callback, params, scope), position); 16411 }; 16412 16413 p.set = function (target, vars, position) { 16414 position = this._parseTimeOrLabel(position, 0, true); 16415 if (vars.immediateRender == null) { 16416 vars.immediateRender = position === this._time && !this._paused; 16417 } 16418 return this.add(new TweenLite(target, 0, vars), position); 16419 }; 16420 16421 TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) { 16422 vars = vars || {}; 16423 if (vars.smoothChildTiming == null) { 16424 vars.smoothChildTiming = true; 16425 } 16426 var tl = new TimelineLite(vars), 16427 root = tl._timeline, 16428 hasNegativeStart, 16429 time, 16430 tween, 16431 next; 16432 if (ignoreDelayedCalls == null) { 16433 ignoreDelayedCalls = true; 16434 } 16435 root._remove(tl, true); 16436 tl._startTime = 0; 16437 tl._rawPrevTime = tl._time = tl._totalTime = root._time; 16438 tween = root._first; 16439 while (tween) { 16440 next = tween._next; 16441 if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) { 16442 time = tween._startTime - tween._delay; 16443 if (time < 0) { 16444 hasNegativeStart = 1; 16445 } 16446 tl.add(tween, time); 16447 } 16448 tween = next; 16449 } 16450 root.add(tl, 0); 16451 if (hasNegativeStart) { 16452 //calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero. 16453 tl.totalDuration(); 16454 } 16455 return tl; 16456 }; 16457 16458 p.add = function (value, position, align, stagger) { 16459 var curTime, l, i, child, tl, beforeRawTime; 16460 if (typeof position !== "number") { 16461 position = this._parseTimeOrLabel(position, 0, true, value); 16462 } 16463 if (!(value instanceof Animation)) { 16464 if (value instanceof Array || value && value.push && _isArray(value)) { 16465 align = align || "normal"; 16466 stagger = stagger || 0; 16467 curTime = position; 16468 l = value.length; 16469 for (i = 0; i < l; i++) { 16470 if (_isArray(child = value[i])) { 16471 child = new TimelineLite({ tweens: child }); 16472 } 16473 this.add(child, curTime); 16474 if (typeof child !== "string" && typeof child !== "function") { 16475 if (align === "sequence") { 16476 curTime = child._startTime + child.totalDuration() / child._timeScale; 16477 } else if (align === "start") { 16478 child._startTime -= child.delay(); 16479 } 16480 } 16481 curTime += stagger; 16482 } 16483 return this._uncache(true); 16484 } else if (typeof value === "string") { 16485 return this.addLabel(value, position); 16486 } else if (typeof value === "function") { 16487 value = TweenLite.delayedCall(0, value); 16488 } else { 16489 throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string."; 16490 } 16491 } 16492 16493 SimpleTimeline.prototype.add.call(this, value, position); 16494 16495 if (value._time) { 16496 //in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 16497 value.render((this.rawTime() - value._startTime) * value._timeScale, false, false); 16498 } 16499 16500 //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 16501 if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) { 16502 //in case any of the ancestors had completed but should now be enabled... 16503 tl = this; 16504 beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect. 16505 while (tl._timeline) { 16506 if (beforeRawTime && tl._timeline.smoothChildTiming) { 16507 tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it. 16508 } else if (tl._gc) { 16509 tl._enabled(true, false); 16510 } 16511 tl = tl._timeline; 16512 } 16513 } 16514 16515 return this; 16516 }; 16517 16518 p.remove = function (value) { 16519 if (value instanceof Animation) { 16520 this._remove(value, false); 16521 var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline. 16522 value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct. 16523 return this; 16524 } else if (value instanceof Array || value && value.push && _isArray(value)) { 16525 var i = value.length; 16526 while (--i > -1) { 16527 this.remove(value[i]); 16528 } 16529 return this; 16530 } else if (typeof value === "string") { 16531 return this.removeLabel(value); 16532 } 16533 return this.kill(null, value); 16534 }; 16535 16536 p._remove = function (tween, skipDisable) { 16537 SimpleTimeline.prototype._remove.call(this, tween, skipDisable); 16538 var last = this._last; 16539 if (!last) { 16540 this._time = this._totalTime = this._duration = this._totalDuration = 0; 16541 } else if (this._time > this.duration()) { 16542 this._time = this._duration; 16543 this._totalTime = this._totalDuration; 16544 } 16545 return this; 16546 }; 16547 16548 p.append = function (value, offsetOrLabel) { 16549 return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value)); 16550 }; 16551 16552 p.insert = p.insertMultiple = function (value, position, align, stagger) { 16553 return this.add(value, position || 0, align, stagger); 16554 }; 16555 16556 p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) { 16557 return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger); 16558 }; 16559 16560 p.addLabel = function (label, position) { 16561 this._labels[label] = this._parseTimeOrLabel(position); 16562 return this; 16563 }; 16564 16565 p.addPause = function (position, callback, params, scope) { 16566 var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this); 16567 t.vars.onComplete = t.vars.onReverseComplete = callback;
16568 t.data = "isPause"; 16569 this._hasPause = true; 16570 return this.add(t, position); 16571 }; 16572 16573 p.removeLabel = function (label) { 16574 delete this._labels[label]; 16575 return this; 16576 }; 16577 16578 p.getLabelTime = function (label) { 16579 return this._labels[label] != null ? this._labels[label] : -1; 16580 }; 16581 16582 p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) { 16583 var clippedDuration, i; 16584 //if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration(). 16585 if (ignore instanceof Animation && ignore.timeline === this) { 16586 this.remove(ignore); 16587 } else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) { 16588 i = ignore.length; 16589 while (--i > -1) { 16590 if (ignore[i] instanceof Animation && ignore[i].timeline === this) { 16591 this.remove(ignore[i]); 16592 } 16593 } 16594 } 16595 clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 16596 if (typeof offsetOrLabel === "string") { 16597 return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent); 16598 } 16599 offsetOrLabel = offsetOrLabel || 0; 16600 if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { 16601 //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 16602 i = timeOrLabel.indexOf("="); 16603 if (i === -1) { 16604 if (this._labels[timeOrLabel] == null) { 16605 return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel; 16606 } 16607 return this._labels[timeOrLabel] + offsetOrLabel; 16608 } 16609 offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1)); 16610 timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration; 16611 } else if (timeOrLabel == null) { 16612 timeOrLabel = clippedDuration; 16613 } 16614 return Number(timeOrLabel) + offsetOrLabel; 16615 }; 16616 16617 p.seek = function (position, suppressEvents) { 16618 return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false); 16619 }; 16620 16621 p.stop = function () { 16622 return this.paused(true); 16623 }; 16624 16625 p.gotoAndPlay = function (position, suppressEvents) { 16626 return this.play(position, suppressEvents); 16627 }; 16628 16629 p.gotoAndStop = function (position, suppressEvents) { 16630 return this.pause(position, suppressEvents); 16631 }; 16632 16633 p.render = function (time, suppressEvents, force) { 16634 if (this._gc) { 16635 this._enabled(true, false); 16636 } 16637 var prevTime = this._time, 16638 totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 16639 prevStart = this._startTime, 16640 prevTimeScale = this._timeScale, 16641 prevPaused = this._paused, 16642 tween, 16643 isComplete, 16644 next, 16645 callback, 16646 internalForce, 16647 pauseTween, 16648 curTime; 16649 if (prevTime !== this._time) { 16650 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 16651 time += this._time - prevTime; 16652 } 16653 if (time >= totalDur - 0.0000001 && time >= 0) { 16654 //to work around occasional floating point math artifacts. 16655 this._totalTime = this._time = totalDur; 16656 if (!this._reversed) if (!this._hasPausedChild()) { 16657 isComplete = true; 16658 callback = "onComplete"; 16659 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 16660 if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) { 16661 internalForce = true; 16662 if (this._rawPrevTime > _tinyNum) { 16663 callback = "onReverseComplete"; 16664 } 16665 } 16666 } 16667 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 16668 time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. 16669 } else if (time < 0.0000001) { 16670 //to work around occasional floating point math artifacts, round super small values to 0. 16671 this._totalTime = this._time = 0; 16672 if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) { 16673 callback = "onReverseComplete"; 16674 isComplete = this._reversed; 16675 } 16676 if (time < 0) { 16677 this._active = false;
16678 if (this._timeline.autoRemoveChildren && this._reversed) { 16679 //ensures proper GC if a timeline is resumed after it's finished reversing. 16680 internalForce = isComplete = true; 16681 callback = "onReverseComplete"; 16682 } else if (this._rawPrevTime >= 0 && this._first) { 16683 //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 16684 internalForce = true; 16685 } 16686 this._rawPrevTime = time; 16687 } else { 16688 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 16689 if (time === 0 && isComplete) { 16690 //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 16691 tween = this._first; 16692 while (tween && tween._startTime === 0) { 16693 if (!tween._duration) { 16694 isComplete = false; 16695 } 16696 tween = tween._next; 16697 } 16698 } 16699 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 16700 if (!this._initted) { 16701 internalForce = true; 16702 } 16703 } 16704 } else { 16705 16706 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 16707 if (time >= prevTime) { 16708 tween = this._first; 16709 while (tween && tween._startTime <= time && !pauseTween) { 16710 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 16711 pauseTween = tween; 16712 } 16713 tween = tween._next; 16714 } 16715 } else { 16716 tween = this._last; 16717 while (tween && tween._startTime >= time && !pauseTween) { 16718 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 16719 pauseTween = tween; 16720 } 16721 tween = tween._prev; 16722 } 16723 } 16724 if (pauseTween) { 16725 this._time = time = pauseTween._startTime; 16726 this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay); 16727 } 16728 } 16729 16730 this._totalTime = this._time = this._rawPrevTime = time; 16731 } 16732 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 16733 return; 16734 } else if (!this._initted) { 16735 this._initted = true; 16736 } 16737 16738 if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { 16739 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 16740 } 16741 16742 if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) { 16743 this._callback("onStart"); 16744 } 16745 16746 curTime = this._time; 16747 if (curTime >= prevTime) { 16748 tween = this._first; 16749 while (tween) { 16750 next = tween._next; //record it here because the value could change after rendering... 16751 if (curTime !== this._time || this._paused && !prevPaused) { 16752 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 16753 break; 16754 } else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) { 16755 if (pauseTween === tween) { 16756 this.pause(); 16757 } 16758 if (!tween._reversed) { 16759 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 16760 } else { 16761 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 16762 } 16763 } 16764 tween = next; 16765 } 16766 } else { 16767 tween = this._last; 16768 while (tween) { 16769 next = tween._prev; //record it here because the value could change after rendering... 16770 if (curTime !== this._time || this._paused && !prevPaused) { 16771 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 16772 break; 16773 } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) { 16774 if (pauseTween === tween) { 16775 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 16776 while (pauseTween && pauseTween.endTime() > this._time) { 16777 pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force); 16778 pauseTween = pauseTween._prev; 16779 } 16780 pauseTween = null; 16781 this.pause(); 16782 } 16783 if (!tween._reversed) { 16784 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 16785 } else { 16786 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 16787 } 16788 } 16789 tween = next; 16790 } 16791 } 16792 16793 if (this._onUpdate) if (!suppressEvents) { 16794 if (_lazyTweens.length) { 16795 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 16796 _lazyRender(); 16797 }
16798 this._callback("onUpdate"); 16799 } 16800 16801 if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { 16802 //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 16803 if (isComplete) { 16804 if (_lazyTweens.length) { 16805 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 16806 _lazyRender(); 16807 } 16808 if (this._timeline.autoRemoveChildren) { 16809 this._enabled(false, false); 16810 } 16811 this._active = false; 16812 } 16813 if (!suppressEvents && this.vars[callback]) { 16814 this._callback(callback); 16815 } 16816 } 16817 }; 16818 16819 p._hasPausedChild = function () { 16820 var tween = this._first; 16821 while (tween) { 16822 if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) { 16823 return true; 16824 } 16825 tween = tween._next; 16826 } 16827 return false; 16828 }; 16829 16830 p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) { 16831 ignoreBeforeTime = ignoreBeforeTime || -9999999999; 16832 var a = [], 16833 tween = this._first, 16834 cnt = 0; 16835 while (tween) { 16836 if (tween._startTime < ignoreBeforeTime) { 16837 //do nothing 16838 } else if (tween instanceof TweenLite) { 16839 if (tweens !== false) { 16840 a[cnt++] = tween; 16841 } 16842 } else { 16843 if (timelines !== false) { 16844 a[cnt++] = tween; 16845 } 16846 if (nested !== false) { 16847 a = a.concat(tween.getChildren(true, tweens, timelines)); 16848 cnt = a.length; 16849 } 16850 } 16851 tween = tween._next; 16852 } 16853 return a; 16854 }; 16855 16856 p.getTweensOf = function (target, nested) { 16857 var disabled = this._gc, 16858 a = [], 16859 cnt = 0, 16860 tweens, 16861 i; 16862 if (disabled) { 16863 this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here. 16864 } 16865 tweens = TweenLite.getTweensOf(target); 16866 i = tweens.length; 16867 while (--i > -1) { 16868 if (tweens[i].timeline === this || nested && this._contains(tweens[i])) { 16869 a[cnt++] = tweens[i]; 16870 } 16871 } 16872 if (disabled) { 16873 this._enabled(false, true); 16874 } 16875 return a; 16876 }; 16877 16878 p.recent = function () { 16879 return this._recent; 16880 }; 16881 16882 p._contains = function (tween) { 16883 var tl = tween.timeline; 16884 while (tl) { 16885 if (tl === this) { 16886 return true; 16887 } 16888 tl = tl.timeline; 16889 } 16890 return false; 16891 }; 16892 16893 p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) { 16894 ignoreBeforeTime = ignoreBeforeTime || 0; 16895 var tween = this._first, 16896 labels = this._labels, 16897 p; 16898 while (tween) { 16899 if (tween._startTime >= ignoreBeforeTime) { 16900 tween._startTime += amount; 16901 } 16902 tween = tween._next; 16903 }
16904 if (adjustLabels) { 16905 for (p in labels) { 16906 if (labels[p] >= ignoreBeforeTime) { 16907 labels[p] += amount; 16908 } 16909 } 16910 } 16911 return this._uncache(true); 16912 }; 16913 16914 p._kill = function (vars, target) { 16915 if (!vars && !target) { 16916 return this._enabled(false, false); 16917 } 16918 var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target), 16919 i = tweens.length, 16920 changed = false; 16921 while (--i > -1) { 16922 if (tweens[i]._kill(vars, target)) { 16923 changed = true; 16924 } 16925 } 16926 return changed; 16927 }; 16928 16929 p.clear = function (labels) { 16930 var tweens = this.getChildren(false, true, true), 16931 i = tweens.length; 16932 this._time = this._totalTime = 0; 16933 while (--i > -1) { 16934 tweens[i]._enabled(false, false); 16935 } 16936 if (labels !== false) { 16937 this._labels = {}; 16938 } 16939 return this._uncache(true); 16940 }; 16941 16942 p.invalidate = function () { 16943 var tween = this._first; 16944 while (tween) { 16945 tween.invalidate(); 16946 tween = tween._next; 16947 } 16948 return Animation.prototype.invalidate.call(this);; 16949 }; 16950 16951 p._enabled = function (enabled, ignoreTimeline) { 16952 if (enabled === this._gc) { 16953 var tween = this._first; 16954 while (tween) { 16955 tween._enabled(enabled, true); 16956 tween = tween._next; 16957 } 16958 } 16959 return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline); 16960 }; 16961 16962 p.totalTime = function (time, suppressEvents, uncapped) { 16963 this._forcingPlayhead = true; 16964 var val = Animation.prototype.totalTime.apply(this, arguments); 16965 this._forcingPlayhead = false; 16966 return val; 16967 }; 16968 16969 p.duration = function (value) { 16970 if (!arguments.length) { 16971 if (this._dirty) { 16972 this.totalDuration(); //just triggers recalculation 16973 } 16974 return this._duration; 16975 } 16976 if (this.duration() !== 0 && value !== 0) { 16977 this.timeScale(this._duration / value); 16978 } 16979 return this; 16980 }; 16981 16982 p.totalDuration = function (value) { 16983 if (!arguments.length) { 16984 if (this._dirty) { 16985 var max = 0, 16986 tween = this._last, 16987 prevStart = 999999999999, 16988 prev, 16989 end; 16990 while (tween) { 16991 prev = tween._prev; //record it here in case the tween changes position in the sequence... 16992 if (tween._dirty) { 16993 tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it. 16994 } 16995 if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) { 16996 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 16997 this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel(). 16998 this.add(tween, tween._startTime - tween._delay); 16999 this._calculatingDuration = 0; 17000 } else { 17001 prevStart = tween._startTime; 17002 } 17003 if (tween._startTime < 0 && !tween._paused) { 17004 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 17005 max -= tween._startTime; 17006 if (this._timeline.smoothChildTiming) { 17007 this._startTime += tween._startTime / this._timeScale; 17008 this._time -= tween._startTime; 17009 this._totalTime -= tween._startTime; 17010 this._rawPrevTime -= tween._startTime; 17011 } 17012 this.shiftChildren(-tween._startTime, false, -9999999999); 17013 prevStart = 0; 17014 } 17015 end = tween._startTime + tween._totalDuration / tween._timeScale; 17016 if (end > max) { 17017 max = end; 17018 } 17019 tween = prev; 17020 } 17021 this._duration = this._totalDuration = max; 17022 this._dirty = false; 17023 } 17024 return this._totalDuration; 17025 } 17026 return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this; 17027 }; 17028 17029 p.paused = function (value) { 17030 if (!value) { 17031 //if there's a pause directly at the spot from where we're unpausing, skip it. 17032 var tween = this._first, 17033 time = this._time; 17034 while (tween) { 17035 if (tween._startTime === time && tween.data === "isPause") { 17036 tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. 17037 } 17038 tween = tween._next; 17039 } 17040 } 17041 return Animation.prototype.paused.apply(this, arguments); 17042 }; 17043 17044 p.usesFrames = function () { 17045 var tl = this._timeline; 17046 while (tl._timeline) { 17047 tl = tl._timeline; 17048 } 17049 return tl === Animation._rootFramesTimeline; 17050 }; 17051 17052 p.rawTime = function (wrapRepeats) { 17053 return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale; 17054 }; 17055 17056 return TimelineLite; 17057 }, true); 17058 17059 /* 17060 * ---------------------------------------------------------------- 17061 * TimelineMax 17062 * ---------------------------------------------------------------- 17063 */ 17064 _gsScope._gsDefine("TimelineMax", ["TimelineLite", "TweenLite", "easing.Ease"], function (TimelineLite, TweenLite, Ease) { 17065 17066 var TimelineMax = function (vars) { 17067 TimelineLite.call(this, vars); 17068 this._repeat = this.vars.repeat || 0; 17069 this._repeatDelay = this.vars.repeatDelay || 0; 17070 this._cycle = 0; 17071 this._yoyo = this.vars.yoyo === true; 17072 this._dirty = true; 17073 }, 17074 _tinyNum = 0.0000000001, 17075 TweenLiteInternals = TweenLite._internals, 17076 _lazyTweens = TweenLiteInternals.lazyTweens, 17077 _lazyRender = TweenLiteInternals.lazyRender, 17078 _globals = _gsScope._gsDefine.globals,
17079 _easeNone = new Ease(null, null, 1, 0), 17080 p = TimelineMax.prototype = new TimelineLite(); 17081 17082 p.constructor = TimelineMax; 17083 p.kill()._gc = false; 17084 TimelineMax.version = "1.20.3"; 17085 17086 p.invalidate = function () { 17087 this._yoyo = this.vars.yoyo === true; 17088 this._repeat = this.vars.repeat || 0; 17089 this._repeatDelay = this.vars.repeatDelay || 0; 17090 this._uncache(true); 17091 return TimelineLite.prototype.invalidate.call(this); 17092 }; 17093 17094 p.addCallback = function (callback, position, params, scope) { 17095 return this.add(TweenLite.delayedCall(0, callback, params, scope), position); 17096 }; 17097 17098 p.removeCallback = function (callback, position) { 17099 if (callback) { 17100 if (position == null) { 17101 this._kill(null, callback); 17102 } else { 17103 var a = this.getTweensOf(callback, false), 17104 i = a.length, 17105 time = this._parseTimeOrLabel(position); 17106 while (--i > -1) { 17107 if (a[i]._startTime === time) { 17108 a[i]._enabled(false, false); 17109 } 17110 } 17111 } 17112 } 17113 return this; 17114 }; 17115 17116 p.removePause = function (position) { 17117 return this.removeCallback(TimelineLite._internals.pauseCallback, position); 17118 }; 17119 17120 p.tweenTo = function (position, vars) { 17121 vars = vars || {}; 17122 var copy = { ease: _easeNone, useFrames: this.usesFrames(), immediateRender: false }, 17123 Engine = vars.repeat && _globals.TweenMax || TweenLite, 17124 duration, 17125 p, 17126 t; 17127 for (p in vars) { 17128 copy[p] = vars[p]; 17129 } 17130 copy.time = this._parseTimeOrLabel(position); 17131 duration = Math.abs(Number(copy.time) - this._time) / this._timeScale || 0.001; 17132 t = new Engine(this, duration, copy); 17133 copy.onStart = function () { 17134 t.target.paused(true); 17135 if (t.vars.time !== t.target.time() && duration === t.duration()) { 17136 //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all. 17137 t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale); 17138 } 17139 if (vars.onStart) { 17140 //in case the user had an onStart in the vars - we don't want to overwrite it. 17141 vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error. 17142 } 17143 }; 17144 return t; 17145 }; 17146 17147 p.tweenFromTo = function (fromPosition, toPosition, vars) { 17148 vars = vars || {}; 17149 fromPosition = this._parseTimeOrLabel(fromPosition); 17150 vars.startAt = { onComplete: this.seek, onCompleteParams: [fromPosition], callbackScope: this }; 17151 vars.immediateRender = vars.immediateRender !== false; 17152 var t = this.tweenTo(toPosition, vars); 17153 return t.duration(Math.abs(t.vars.time - fromPosition) / this._timeScale || 0.001); 17154 }; 17155 17156 p.render = function (time, suppressEvents, force) { 17157 if (this._gc) { 17158 this._enabled(true, false); 17159 } 17160 var prevTime = this._time, 17161 totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 17162 dur = this._duration, 17163 prevTotalTime = this._totalTime, 17164 prevStart = this._startTime, 17165 prevTimeScale = this._timeScale, 17166 prevRawPrevTime = this._rawPrevTime, 17167 prevPaused = this._paused, 17168 prevCycle = this._cycle, 17169 tween, 17170 isComplete, 17171 next, 17172 callback, 17173 internalForce, 17174 cycleDuration, 17175 pauseTween, 17176 curTime; 17177 if (prevTime !== this._time) { 17178 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 17179 time += this._time - prevTime; 17180 } 17181 if (time >= totalDur - 0.0000001 && time >= 0) { 17182 //to work around occasional floating point math artifacts. 17183 if (!this._locked) { 17184 this._totalTime = totalDur; 17185 this._cycle = this._repeat; 17186 } 17187 if (!this._reversed) if (!this._hasPausedChild()) { 17188 isComplete = true; 17189 callback = "onComplete"; 17190 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 17191 if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) { 17192 internalForce = true; 17193 if (prevRawPrevTime > _tinyNum) { 17194 callback = "onReverseComplete"; 17195 } 17196 } 17197 } 17198 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 17199 if (this._yoyo && (this._cycle & 1) !== 0) { 17200 this._time = time = 0; 17201 } else { 17202 this._time = dur; 17203 time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in
17203which case adding 0.00000001, for example, causes it to act like nothing was added. 17204 } 17205 } else if (time < 0.0000001) { 17206 //to work around occasional floating point math artifacts, round super small values to 0. 17207 if (!this._locked) { 17208 this._totalTime = this._cycle = 0; 17209 } 17210 this._time = 0; 17211 if (prevTime !== 0 || dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || time < 0 && prevRawPrevTime >= 0) && !this._locked) { 17212 //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare) 17213 callback = "onReverseComplete"; 17214 isComplete = this._reversed; 17215 } 17216 if (time < 0) { 17217 this._active = false; 17218 if (this._timeline.autoRemoveChildren && this._reversed) { 17219 internalForce = isComplete = true; 17220 callback = "onReverseComplete"; 17221 } else if (prevRawPrevTime >= 0 && this._first) { 17222 //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 17223 internalForce = true; 17224 } 17225 this._rawPrevTime = time; 17226 } else { 17227 this._rawPrevTime = dur || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 17228 if (time === 0 && isComplete) { 17229 //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 17230 tween = this._first; 17231 while (tween && tween._startTime === 0) { 17232 if (!tween._duration) { 17233 isComplete = false; 17234 } 17235 tween = tween._next; 17236 } 17237 } 17238 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 17239 if (!this._initted) { 17240 internalForce = true; 17241 } 17242 } 17243 } else { 17244 if (dur === 0 && prevRawPrevTime < 0) { 17245 //without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through. 17246 internalForce = true; 17247 } 17248 this._time = this._rawPrevTime = time; 17249 if (!this._locked) { 17250 this._totalTime = time; 17251 if (this._repeat !== 0) { 17252 cycleDuration = dur + this._repeatDelay; 17253 this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!) 17254 if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) { 17255 this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) 17256 } 17257 this._time = this._totalTime - this._cycle * cycleDuration; 17258 if (this._yoyo) if ((this._cycle & 1) !== 0) { 17259 this._time = dur - this._time; 17260 } 17261 if (this._time > dur) { 17262 this._time = dur; 17263 time = dur + 0.0001; //to avoid occasional floating point rounding error 17264 } else if (this._time < 0) { 17265 this._time = time = 0; 17266 } else { 17267 time = this._time; 17268 } 17269 } 17270 } 17271 17272 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 17273 time = this._time; 17274 if (time >= prevTime || this._repeat && prevCycle !== this._cycle) { 17275 tween = this._first; 17276 while (tween && tween._startTime <= time && !pauseTween) { 17277 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 17278 pauseTween = tween; 17279 } 17280 tween = tween._next; 17281 } 17282 } else { 17283 tween = this._last; 17284 while (tween && tween._startTime >= time && !pauseTween) { 17285 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 17286 pauseTween = tween; 17287 } 17288 tween = tween._prev; 17289 } 17290 } 17291 if (pauseTween && pauseTween._startTime < dur) { 17292 this._time = time = pauseTween._startTime; 17293 this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay); 17294 } 17295 } 17296 } 17297 17298 if (this._cycle !== prevCycle) if (!this._locked) { 17299 /* 17300 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 17301 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
17302 would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 17303 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 17304 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 17305 ensure that zero-duration tweens at the very beginning or end of the TimelineMax work. 17306 */ 17307 var backwards = this._yoyo && (prevCycle & 1) !== 0, 17308 wrap = backwards === (this._yoyo && (this._cycle & 1) !== 0), 17309 recTotalTime = this._totalTime, 17310 recCycle = this._cycle, 17311 recRawPrevTime = this._rawPrevTime, 17312 recTime = this._time; 17313 17314 this._totalTime = prevCycle * dur; 17315 if (this._cycle < prevCycle) { 17316 backwards = !backwards; 17317 } else { 17318 this._totalTime += dur; 17319 } 17320 this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method. 17321 17322 this._rawPrevTime = dur === 0 ? prevRawPrevTime - 0.0001 : prevRawPrevTime; 17323 this._cycle = prevCycle; 17324 this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render() 17325 prevTime = backwards ? 0 : dur; 17326 this.render(prevTime, suppressEvents, dur === 0); 17327 if (!suppressEvents) if (!this._gc) { 17328 if (this.vars.onRepeat) { 17329 this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle. 17330 this._locked = false; 17331 this._callback("onRepeat"); 17332 } 17333 } 17334 if (prevTime !== this._time) { 17335 //in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort. 17336 return; 17337 } 17338 if (wrap) { 17339 this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too. 17340 this._locked = true; 17341 prevTime = backwards ? dur + 0.0001 : -0.0001; 17342 this.render(prevTime, true, false); 17343 } 17344 this._locked = false; 17345 if (this._paused && !prevPaused) { 17346 //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible) 17347 return; 17348 } 17349 this._time = recTime; 17350 this._totalTime = recTotalTime; 17351 this._cycle = recCycle; 17352 this._rawPrevTime = recRawPrevTime; 17353 } 17354 17355 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 17356 if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { 17357 //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate. 17358 this._callback("onUpdate"); 17359 } 17360 return; 17361 } else if (!this._initted) { 17362 this._initted = true; 17363 } 17364 17365 if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) { 17366 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 17367 } 17368 17369 if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) { 17370 this._callback("onStart"); 17371 } 17372 17373 curTime = this._time; 17374 if (curTime >= prevTime) { 17375 tween = this._first; 17376 while (tween) { 17377 next = tween._next; //record it here because the value could change after rendering... 17378 if (curTime !== this._time || this._paused && !prevPaused) { 17379 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 17380 break; 17381 } else if (tween._active || tween._startTime <= this._time && !tween._paused && !tween._gc) { 17382 if (pauseTween === tween) { 17383 this.pause(); 17384 } 17385 if (!tween._reversed) { 17386 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 17387 } else { 17388 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 17389 } 17390 } 17391 tween = next; 17392 } 17393 } else { 17394 tween = this._last; 17395 while (tween) { 17396 next = tween._prev; //record it here because the value could change after rendering... 17397 if (curTime !== this._time || this._paused && !prevPaused) { 17398 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 17399 break; 17400 } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) { 17401 if (pauseTween === tween) { 17402 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 17403 while (pauseTween && pauseTween.endTime() > this._time) { 17404 pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force); 17405 pauseTween = pauseTween._prev; 17406 } 17407 pauseTween = null; 17408 this.pause(); 17409 } 17410 if (!tween._reversed) { 17411 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 17412 } else { 17413 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 17414 } 17415 } 17416 tween = next; 17417 } 17418 } 17419 17420 if (this._onUpdate) if (!suppressEvents) { 17421 if (_lazyTweens.length) { 17422 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 17423 _lazyRender(); 17424 }
17425 this._callback("onUpdate"); 17426 } 17427 if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { 17428 //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 17429 if (isComplete) { 17430 if (_lazyTweens.length) { 17431 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 17432 _lazyRender(); 17433 } 17434 if (this._timeline.autoRemoveChildren) { 17435 this._enabled(false, false); 17436 } 17437 this._active = false; 17438 } 17439 if (!suppressEvents && this.vars[callback]) { 17440 this._callback(callback); 17441 } 17442 } 17443 }; 17444 17445 p.getActive = function (nested, tweens, timelines) { 17446 if (nested == null) { 17447 nested = true; 17448 } 17449 if (tweens == null) { 17450 tweens = true; 17451 } 17452 if (timelines == null) { 17453 timelines = false; 17454 } 17455 var a = [], 17456 all = this.getChildren(nested, tweens, timelines), 17457 cnt = 0, 17458 l = all.length, 17459 i, 17460 tween; 17461 for (i = 0; i < l; i++) { 17462 tween = all[i]; 17463 if (tween.isActive()) { 17464 a[cnt++] = tween; 17465 } 17466 } 17467 return a; 17468 }; 17469 17470 p.getLabelAfter = function (time) { 17471 if (!time) if (time !== 0) { 17472 //faster than isNan() 17473 time = this._time; 17474 } 17475 var labels = this.getLabelsArray(), 17476 l = labels.length, 17477 i; 17478 for (i = 0; i < l; i++) { 17479 if (labels[i].time > time) { 17480 return labels[i].name; 17481 } 17482 } 17483 return null; 17484 }; 17485 17486 p.getLabelBefore = function (time) { 17487 if (time == null) { 17488 time = this._time; 17489 } 17490 var labels = this.getLabelsArray(), 17491 i = labels.length; 17492 while (--i > -1) { 17493 if (labels[i].time < time) { 17494 return labels[i].name; 17495 } 17496 } 17497 return null; 17498 }; 17499 17500 p.getLabelsArray = function () { 17501 var a = [], 17502 cnt = 0, 17503 p; 17504 for (p in this._labels) { 17505 a[cnt++] = { time: this._labels[p], name: p }; 17506 } 17507 a.sort(function (a, b) { 17508 return a.time - b.time; 17509 }); 17510 return a; 17511 }; 17512 17513 p.invalidate = function () { 17514 this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat 17515 return TimelineLite.prototype.invalidate.call(this); 17516 }; 17517 17518 //---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------- 17519 17520 p.progress = function (value, suppressEvents) { 17521 return !arguments.length ? this._time / this.duration() || 0 : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents); 17522 }; 17523 17524 p.totalProgress = function (value, suppressEvents) { 17525 return !arguments.length ? this._totalTime / this.totalDuration() || 0 : this.totalTime(this.totalDuration() * value, suppressEvents); 17526 }; 17527 17528 p.totalDuration = function (value) { 17529 if (!arguments.length) { 17530 if (this._dirty) { 17531 TimelineLite.prototype.totalDuration.call(this); //just forces refresh 17532 //Instead of Infinity, we use 999999999999 so that we can accommodate reverses. 17533 this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat; 17534 } 17535 return this._totalDuration; 17536 } 17537 return this._repeat === -1 || !value ? this : this.timeScale(this.totalDuration() / value); 17538 }; 17539 17540 p.time = function (value, suppressEvents) { 17541 if (!arguments.length) { 17542 return this._time; 17543 } 17544 if (this._dirty) { 17545 this.totalDuration(); 17546 } 17547 if (value > this._duration) { 17548 value = this._duration; 17549 } 17550 if (this._yoyo && (this._cycle & 1) !== 0) { 17551 value = this._duration - value + this._cycle * (this._duration + this._repeatDelay); 17552 } else if (this._repeat !== 0) { 17553 value += this._cycle * (this._duration + this._repeatDelay); 17554 } 17555 return this.totalTime(value, suppressEvents); 17556 }; 17557 17558 p.repeat = function (value) { 17559 if (!arguments.length) { 17560 return this._repeat; 17561 } 17562 this._repeat = value; 17563 return this._uncache(true); 17564 }; 17565 17566 p.repeatDelay = function (value) { 17567 if (!arguments.length) { 17568 return this._repeatDelay; 17569 } 17570 this._repeatDelay = value; 17571 return this._uncache(true); 17572 }; 17573 17574 p.yoyo = function (value) { 17575 if (!arguments.length) { 17576 return this._yoyo; 17577 } 17578 this._yoyo = value; 17579 return this; 17580 }; 17581 17582 p.currentLabel = function (value) { 17583 if (!arguments.length) { 17584 return this.getLabelBefore(this._time + 0.00000001); 17585 } 17586 return this.seek(value, true); 17587 }; 17588 17589 return TimelineMax; 17590 }, true); 17591 17592 /* 17593 * ---------------------------------------------------------------- 17594 * BezierPlugin 17595 * ---------------------------------------------------------------- 17596 */ 17597 (function () { 17598 17599 var _RAD2DEG = 180 / Math.PI, 17600 _r1 = [], 17601 _r2 = [], 17602 _r3 = [], 17603 _corProps = {}, 17604 _globals = _gsScope._gsDefine.globals, 17605 Segment = function (a, b, c, d) { 17606 if (c === d) { 17607 //if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly. 17608 c = d - (d - b) / 1000000; 17609 }
17610 if (a === b) { 17611 //if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly. 17612 b = a + (c - a) / 1000000; 17613 } 17614 this.a = a; 17615 this.b = b; 17616 this.c = c; 17617 this.d = d; 17618 this.da = d - a; 17619 this.ca = c - a; 17620 this.ba = b - a; 17621 }, 17622 _correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,", 17623 cubicToQuadratic = function (a, b, c, d) { 17624 var q1 = { a: a }, 17625 q2 = {}, 17626 q3 = {}, 17627 q4 = { c: d }, 17628 mab = (a + b) / 2, 17629 mbc = (b + c) / 2, 17630 mcd = (c + d) / 2, 17631 mabc = (mab + mbc) / 2, 17632 mbcd = (mbc + mcd) / 2, 17633 m8 = (mbcd - mabc) / 8; 17634 q1.b = mab + (a - mab) / 4; 17635 q2.b = mabc + m8; 17636 q1.c = q2.a = (q1.b + q2.b) / 2; 17637 q2.c = q3.a = (mabc + mbcd) / 2; 17638 q3.b = mbcd - m8; 17639 q4.b = mcd + (d - mcd) / 4; 17640 q3.c = q4.a = (q3.b + q4.b) / 2; 17641 return [q1, q2, q3, q4]; 17642 }, 17643 _calculateControlPoints = function (a, curviness, quad, basic, correlate) { 17644 var l = a.length - 1, 17645 ii = 0, 17646 cp1 = a[0].a, 17647 i, 17648 p1, 17649 p2, 17650 p3, 17651 seg, 17652 m1, 17653 m2, 17654 mm, 17655 cp2, 17656 qb, 17657 r1, 17658 r2, 17659 tl; 17660 for (i = 0; i < l; i++) { 17661 seg = a[ii]; 17662 p1 = seg.a; 17663 p2 = seg.d; 17664 p3 = a[ii + 1].d; 17665 17666 if (correlate) { 17667 r1 = _r1[i]; 17668 r2 = _r2[i]; 17669 tl = (r2 + r1) * curviness * 0.25 / (basic ? 0.5 : _r3[i] || 0.5); 17670 m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : r1 !== 0 ? tl / r1 : 0); 17671 m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : r2 !== 0 ? tl / r2 : 0); 17672 mm = p2 - (m1 + ((m2 - m1) * (r1 * 3 / (r1 + r2) + 0.5) / 4 || 0)); 17673 } else { 17674 m1 = p2 - (p2 - p1) * curviness * 0.5; 17675 m2 = p2 + (p3 - p2) * curviness * 0.5; 17676 mm = p2 - (m1 + m2) / 2; 17677 } 17678 m1 += mm; 17679 m2 += mm; 17680 17681 seg.c = cp2 = m1; 17682 if (i !== 0) { 17683 seg.b = cp1; 17684 } else { 17685 seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6; //instead of placing b on a exactly, we move it inline with c so that if the user specifies an ease like Back.easeIn or Elastic.easeIn which goes BEYOND the beginning, it will do so smoothly. 17686 } 17687 17688 seg.da = p2 - p1; 17689 seg.ca = cp2 - p1; 17690 seg.ba = cp1 - p1; 17691 17692 if (quad) { 17693 qb = cubicToQuadratic(p1, cp1, cp2, p2); 17694 a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); 17695 ii += 4; 17696 } else { 17697 ii++; 17698 } 17699 17700 cp1 = m2; 17701 } 17702 seg = a[ii]; 17703 seg.b = cp1; 17704 seg.c = cp1 + (seg.d - cp1) * 0.4; //instead of placing c on d exactly, we move it inline with b so that if the user specifies an ease like Back.easeOut or Elastic.easeOut which goes BEYOND the end, it will do so smoothly. 17705 seg.da = seg.d - seg.a; 17706 seg.ca = seg.c - seg.a; 17707 seg.ba = cp1 - seg.a; 17708 if (quad) { 17709 qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d); 17710 a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); 17711 } 17712 }, 17713 _parseAnchors = function (values, p, correlate, prepend) { 17714 var a = [], 17715 l, 17716 i, 17717 p1, 17718 p2, 17719 p3, 17720 tmp; 17721 if (prepend) { 17722 values = [prepend].concat(values); 17723 i = values.length; 17724 while (--i > -1) { 17725 if (typeof (tmp = values[i][p]) === "string") if (tmp.charAt(1) === "=") { 17726 values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)); //accommodate relative values. Do it inline instead of breaking it out into a function for speed reasons 17727 } 17728 } 17729 } 17730 l = values.length - 2; 17731 if (l < 0) { 17732 a[0] = new Segment(values[0][p], 0, 0, values[0][p]); 17733 return a; 17734 } 17735 for (i = 0; i < l; i++) { 17736 p1 = values[i][p]; 17737 p2 = values[i + 1][p]; 17738 a[i] = new Segment(p1, 0, 0, p2); 17739 if (correlate) { 17740 p3 = values[i + 2][p]; 17741 _r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1); 17742 _r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2); 17743 } 17744 } 17745 a[i] = new Segment(values[i][p], 0, 0, values[i + 1][p]); 17746 return a; 17747 }, 17748 bezierThrough = function (values, curviness, quadratic, basic, correlate, prepend) { 17749 var obj = {}, 17750 props = [], 17751 first = prepend || values[0], 17752 i, 17753 p, 17754 a, 17755 j, 17756 r, 17757 l, 17758 seamless, 17759 last; 17760 correlate = typeof correlate === "string" ? "," + correlate + "," : _correlate; 17761 if (curviness == null) { 17762 curviness = 1; 17763 } 17764 for (p in values[0]) { 17765 props.push(p); 17766 } 17767 //check to see if the last and first values are identical (well, within 0.05). If so, make seamless by appending the second element to the very end of the values array and the 2nd-to-last element to the very beginning (we'll remove those segments later) 17768 if (values.length > 1) { 17769 last = values[values.length - 1]; 17770 seamless = true; 17771 i = props.length; 17772 while (--i > -1) { 17773 p = props[i]; 17774 if (Math.abs(first[p] - last[p]) > 0.05) { 17775 //build in a tolerance of +/-0.05 to accommodate rounding errors. 17776 seamless = false;
17777 break; 17778 } 17779 } 17780 if (seamless) { 17781 values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens 17782 if (prepend) { 17783 values.unshift(prepend); 17784 } 17785 values.push(values[1]); 17786 prepend = values[values.length - 3]; 17787 } 17788 } 17789 _r1.length = _r2.length = _r3.length = 0; 17790 i = props.length; 17791 while (--i > -1) { 17792 p = props[i]; 17793 _corProps[p] = correlate.indexOf("," + p + ",") !== -1; 17794 obj[p] = _parseAnchors(values, p, _corProps[p], prepend); 17795 } 17796 i = _r1.length; 17797 while (--i > -1) { 17798 _r1[i] = Math.sqrt(_r1[i]); 17799 _r2[i] = Math.sqrt(_r2[i]); 17800 } 17801 if (!basic) { 17802 i = props.length; 17803 while (--i > -1) { 17804 if (_corProps[p]) { 17805 a = obj[props[i]]; 17806 l = a.length - 1; 17807 for (j = 0; j < l; j++) { 17808 r = a[j + 1].da / _r2[j] + a[j].da / _r1[j] || 0; 17809 _r3[j] = (_r3[j] || 0) + r * r; 17810 } 17811 } 17812 } 17813 i = _r3.length; 17814 while (--i > -1) { 17815 _r3[i] = Math.sqrt(_r3[i]); 17816 } 17817 } 17818 i = props.length; 17819 j = quadratic ? 4 : 1; 17820 while (--i > -1) { 17821 p = props[i]; 17822 a = obj[p]; 17823 _calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]); //this method requires that _parseAnchors() and _setSegmentRatios() ran first so that _r1, _r2, and _r3 values are populated for all properties 17824 if (seamless) { 17825 a.splice(0, j); 17826 a.splice(a.length - j, j); 17827 } 17828 } 17829 return obj; 17830 }, 17831 _parseBezierData = function (values, type, prepend) { 17832 type = type || "soft"; 17833 var obj = {}, 17834 inc = type === "cubic" ? 3 : 2, 17835 soft = type === "soft", 17836 props = [], 17837 a, 17838 b, 17839 c, 17840 d, 17841 cur, 17842 i, 17843 j, 17844 l, 17845 p, 17846 cnt, 17847 tmp; 17848 if (soft && prepend) { 17849 values = [prepend].concat(values); 17850 } 17851 if (values == null || values.length < inc + 1) { 17852 throw "invalid Bezier data"; 17853 } 17854 for (p in values[0]) { 17855 props.push(p); 17856 } 17857 i = props.length; 17858 while (--i > -1) { 17859 p = props[i]; 17860 obj[p] = cur = []; 17861 cnt = 0; 17862 l = values.length; 17863 for (j = 0; j < l; j++) { 17864 a = prepend == null ? values[j][p] : typeof (tmp = values[j][p]) === "string" && tmp.charAt(1) === "=" ? prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp); 17865 if (soft) if (j > 1) if (j < l - 1) { 17866 cur[cnt++] = (a + cur[cnt - 2]) / 2; 17867 } 17868 cur[cnt++] = a; 17869 } 17870 l = cnt - inc + 1; 17871 cnt = 0; 17872 for (j = 0; j < l; j += inc) { 17873 a = cur[j]; 17874 b = cur[j + 1]; 17875 c = cur[j + 2]; 17876 d = inc === 2 ? 0 : cur[j + 3]; 17877 cur[cnt++] = tmp = inc === 3 ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); 17878 } 17879 cur.length = cnt; 17880 } 17881 return obj; 17882 }, 17883 _addCubicLengths = function (a, steps, resolution) { 17884 var inc = 1 / resolution, 17885 j = a.length, 17886 d, 17887 d1, 17888 s, 17889 da, 17890 ca, 17891 ba, 17892 p, 17893 i, 17894 inv, 17895 bez, 17896 index; 17897 while (--j > -1) { 17898 bez = a[j]; 17899 s = bez.a; 17900 da = bez.d - s; 17901 ca = bez.c - s; 17902 ba = bez.b - s; 17903 d = d1 = 0; 17904 for (i = 1; i <= resolution; i++) { 17905 p = inc * i; 17906 inv = 1 - p; 17907 d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p); 17908 index = j * resolution + i - 1; 17909 steps[index] = (steps[index] || 0) + d * d; 17910 } 17911 } 17912 }, 17913 _parseLengthData = function (obj, resolution) { 17914 resolution = resolution >> 0 || 6; 17915 var a = [], 17916 lengths = [], 17917 d = 0, 17918 total = 0, 17919 threshold = resolution - 1, 17920 segments = [], 17921 curLS = [], 17922 //current length segments array 17923 p, 17924 i, 17925 l, 17926 index; 17927 for (p in obj) { 17928 _addCubicLengths(obj[p], a, resolution); 17929 } 17930 l = a.length; 17931 for (i = 0; i < l; i++) { 17932 d += Math.sqrt(a[i]); 17933 index = i % resolution; 17934 curLS[index] = d; 17935 if (index === threshold) { 17936 total += d; 17937 index = i / resolution >> 0; 17938 segments[index] = curLS; 17939 lengths[index] = total; 17940 d = 0; 17941 curLS = []; 17942 } 17943 } 17944 return { length: total, lengths: lengths, segments: segments }; 17945 }, 17946 BezierPlugin = _gsScope._gsDefine.plugin({ 17947 propName: "bezier", 17948 priority: -1, 17949 version: "1.3.8", 17950 API: 2, 17951 global: true, 17952 17953 //gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 17954 init: function (target, vars, tween) { 17955 this._target = target; 17956 if (vars instanceof Array) { 17957 vars = { values: vars }; 17958 } 17959 this._func = {}; 17960 this._mod = {}; 17961 this._props = []; 17962 this._timeRes = vars.timeResolution == null ? 6 : parseInt(vars.timeResolution, 10); 17963 var values = vars.values || [], 17964 first = {}, 17965 second = values[0], 17966 autoRotate = vars.autoRotate || tween.vars.orientToBezier, 17967 p, 17968 isFunc, 17969 i, 17970 j, 17971 prepend; 17972 17973 this._autoRotate = autoRotate ? autoRotate instanceof Array ? autoRotate : [["x", "y", "rotation", autoRotate === true ? 0 : Number(autoRotate) || 0]] : null; 17974 for (p in second) { 17975 this._props.push(p); 17976 } 17977 17978 i = this._props.length; 17979 while (--i > -1) { 17980 p = this._props[i]; 17981 17982 this._overwriteProps.push(p); 17983 isFunc = this._func[p] = typeof target[p] === "function"; 17984 first[p] = !isFunc ? parseFloat(target[p]) : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)](); 17985 if (!prepend) if (first[p] !== values[0][p]) { 17986 prepend = first; 17987 } 17988 } 17989 this._beziers = vars.type !== "cubic" && vars.type !== "quadratic" && vars.type !== "soft" ? bezierThrough(values, isNaN(vars.curviness) ? 1 : vars.curviness, false, vars.type === "thruBasic", vars.c
17989orrelate, prepend) : _parseBezierData(values, vars.type, first); 17990 this._segCount = this._beziers[p].length; 17991 17992 if (this._timeRes) { 17993 var ld = _parseLengthData(this._beziers, this._timeRes); 17994 this._length = ld.length; 17995 this._lengths = ld.lengths; 17996 this._segments = ld.segments; 17997 this._l1 = this._li = this._s1 = this._si = 0; 17998 this._l2 = this._lengths[0]; 17999 this._curSeg = this._segments[0]; 18000 this._s2 = this._curSeg[0]; 18001 this._prec = 1 / this._curSeg.length; 18002 } 18003 18004 if (autoRotate = this._autoRotate) { 18005 this._initialRotations = []; 18006 if (!(autoRotate[0] instanceof Array)) { 18007 this._autoRotate = autoRotate = [autoRotate]; 18008 } 18009 i = autoRotate.length; 18010 while (--i > -1) { 18011 for (j = 0; j < 3; j++) { 18012 p = autoRotate[i][j]; 18013 this._func[p] = typeof target[p] === "function" ? target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)] : false; 18014 } 18015 p = autoRotate[i][2]; 18016 this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0; 18017 this._overwriteProps.push(p); 18018 } 18019 } 18020 this._startRatio = tween.vars.runBackwards ? 1 : 0; //we determine the starting ratio when the tween inits which is always 0 unless the tween has runBackwards:true (indicating it's a from() tween) in which case it's 1. 18021 return true; 18022 }, 18023 18024 //called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.) 18025 set: function (v) { 18026 var segments = this._segCount, 18027 func = this._func, 18028 target = this._target, 18029 notStart = v !== this._startRatio, 18030 curIndex, 18031 inv, 18032 i, 18033 p, 18034 b, 18035 t, 18036 val, 18037 l, 18038 lengths, 18039 curSeg; 18040 if (!this._timeRes) { 18041 curIndex = v < 0 ? 0 : v >= 1 ? segments - 1 : segments * v >> 0; 18042 t = (v - curIndex * (1 / segments)) * segments; 18043 } else { 18044 lengths = this._lengths; 18045 curSeg = this._curSeg; 18046 v *= this._length; 18047 i = this._li; 18048 //find the appropriate segment (if the currently cached one isn't correct) 18049 if (v > this._l2 && i < segments - 1) { 18050 l = segments - 1; 18051 while (i < l && (this._l2 = lengths[++i]) <= v) {} 18052 this._l1 = lengths[i - 1]; 18053 this._li = i; 18054 this._curSeg = curSeg = this._segments[i]; 18055 this._s2 = curSeg[this._s1 = this._si = 0]; 18056 } else if (v < this._l1 && i > 0) { 18057 while (i > 0 && (this._l1 = lengths[--i]) >= v) {} 18058 if (i === 0 && v < this._l1) { 18059 this._l1 = 0; 18060 } else { 18061 i++; 18062 } 18063 this._l2 = lengths[i]; 18064 this._li = i; 18065 this._curSeg = curSeg = this._segments[i]; 18066 this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0; 18067 this._s2 = curSeg[this._si]; 18068 } 18069 curIndex = i; 18070 //now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one) 18071 v -= this._l1; 18072 i = this._si; 18073 if (v > this._s2 && i < curSeg.length - 1) { 18074 l = curSeg.length - 1; 18075 while (i < l && (this._s2 = curSeg[++i]) <= v) {} 18076 this._s1 = curSeg[i - 1]; 18077 this._si = i; 18078 } else if (v < this._s1 && i > 0) { 18079 while (i > 0 && (this._s1 = curSeg[--i]) >= v) {} 18080 if (i === 0 && v < this._s1) { 18081 this._s1 = 0; 18082 } else { 18083 i++; 18084 } 18085 this._s2 = curSeg[i]; 18086 this._si = i; 18087 } 18088 t = (i + (v - this._s1) / (this._s2 - this._s1)) * this._prec || 0; 18089 } 18090 inv = 1 - t; 18091 18092 i = this._props.length; 18093 while (--i > -1) { 18094 p = this._props[i]; 18095 b = this._beziers[p][curIndex]; 18096 val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a; 18097 if (this._mod[p]) { 18098 val = this._mod[p](val, target); 18099 } 18100 if (func[p]) { 18101 target[p](val); 18102 } else { 18103 target[p] = val; 18104 } 18105 } 18106 18107 if (this._autoRotate) { 18108 var ar = this._autoRotate, 18109 b2, 18110 x1, 18111 y1, 18112 x2, 18113 y2, 18114 add, 18115 conv; 18116 i = ar.length; 18117 while (--i > -1) { 18118 p = ar[i][2]; 18119 add = ar[i][3] || 0; 18120 conv = ar[i][4] === true ? 1 : _RAD2DEG; 18121 b = this._beziers[ar[i][0]]; 18122 b2 = this._beziers[ar[i][1]]; 18123 18124 if (b && b2) { 18125 //in case one of the properties got overwritten. 18126 b = b[curIndex]; 18127 b2 = b2[curIndex]; 18128 18129 x1 = b.a + (b.b - b.a) * t; 18130 x2 = b.b + (b.c - b.b) * t; 18131 x1 += (x2 - x1) * t;
18132 x2 += (b.c + (b.d - b.c) * t - x2) * t; 18133 18134 y1 = b2.a + (b2.b - b2.a) * t; 18135 y2 = b2.b + (b2.c - b2.b) * t; 18136 y1 += (y2 - y1) * t; 18137 y2 += (b2.c + (b2.d - b2.c) * t - y2) * t; 18138 18139 val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i]; 18140 18141 if (this._mod[p]) { 18142 val = this._mod[p](val, target); //for modProps 18143 } 18144 18145 if (func[p]) { 18146 target[p](val); 18147 } else { 18148 target[p] = val; 18149 } 18150 } 18151 } 18152 } 18153 } 18154 }), 18155 p = BezierPlugin.prototype; 18156 18157 BezierPlugin.bezierThrough = bezierThrough; 18158 BezierPlugin.cubicToQuadratic = cubicToQuadratic; 18159 BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite 18160 BezierPlugin.quadraticToCubic = function (a, b, c) { 18161 return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); 18162 }; 18163 18164 BezierPlugin._cssRegister = function () { 18165 var CSSPlugin = _globals.CSSPlugin; 18166 if (!CSSPlugin) { 18167 return; 18168 } 18169 var _internals = CSSPlugin._internals, 18170 _parseToProxy = _internals._parseToProxy, 18171 _setPluginRatio = _internals._setPluginRatio, 18172 CSSPropTween = _internals.CSSPropTween; 18173 _internals._registerComplexSpecialProp("bezier", { parser: function (t, e, prop, cssp, pt, plugin) { 18174 if (e instanceof Array) { 18175 e = { values: e }; 18176 } 18177 plugin = new BezierPlugin(); 18178 var values = e.values, 18179 l = values.length - 1, 18180 pluginValues = [], 18181 v = {}, 18182 i, 18183 p, 18184 data; 18185 if (l < 0) { 18186 return pt; 18187 } 18188 for (i = 0; i <= l; i++) { 18189 data = _parseToProxy(t, values[i], cssp, pt, plugin, l !== i); 18190 pluginValues[i] = data.end; 18191 } 18192 for (p in e) { 18193 v[p] = e[p]; //duplicate the vars object because we need to alter some things which would cause problems if the user plans to reuse the same vars object for another tween. 18194 } 18195 v.values = pluginValues; 18196 pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2); 18197 pt.data = data; 18198 pt.plugin = plugin; 18199 pt.setRatio = _setPluginRatio; 18200 if (v.autoRotate === 0) { 18201 v.autoRotate = true; 18202 } 18203 if (v.autoRotate && !(v.autoRotate instanceof Array)) { 18204 i = v.autoRotate === true ? 0 : Number(v.autoRotate); 18205 v.autoRotate = data.end.left != null ? [["left", "top", "rotation", i, false]] : data.end.x != null ? [["x", "y", "rotation", i, false]] : false; 18206 } 18207 if (v.autoRotate) { 18208 if (!cssp._transform) { 18209 cssp._enableTransforms(false); 18210 } 18211 data.autoRotate = cssp._target._gsTransform; 18212 data.proxy.rotation = data.autoRotate.rotation || 0; 18213 cssp._overwriteProps.push("rotation"); 18214 } 18215 plugin._onInitTween(data.proxy, v, cssp._tween); 18216 return pt; 18217 } }); 18218 }; 18219 18220 p._mod = function (lookup) { 18221 var op = this._overwriteProps, 18222 i = op.length, 18223 val; 18224 while (--i > -1) { 18225 val = lookup[op[i]]; 18226 if (val && typeof val === "function") { 18227 this._mod[op[i]] = val; 18228 } 18229 } 18230 }; 18231 18232 p._kill = function (lookup) { 18233 var a = this._props, 18234 p, 18235 i; 18236 for (p in this._beziers) { 18237 if (p in lookup) { 18238 delete this._beziers[p]; 18239 delete this._func[p]; 18240 i = a.length; 18241 while (--i > -1) { 18242 if (a[i] === p) { 18243 a.splice(i, 1); 18244 } 18245 } 18246 } 18247 } 18248 a = this._autoRotate; 18249 if (a) { 18250 i = a.length; 18251 while (--i > -1) { 18252 if (lookup[a[i][2]]) { 18253 a.splice(i, 1); 18254 } 18255 } 18256 } 18257 return this._super._kill.call(this, lookup); 18258 }; 18259 })(); 18260 18261 /* 18262 * ---------------------------------------------------------------- 18263 * CSSPlugin 18264 * ---------------------------------------------------------------- 18265 */ 18266 _gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin", "TweenLite"], function (TweenPlugin, TweenLite) { 18267 18268 /** @constructor **/ 18269 var CSSPlugin = function () { 18270 TweenPlugin.call(this, "css"); 18271 this._overwriteProps.length = 0; 18272 this.setRatio = CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method) 18273 }, 18274 _globals = _gsScope._gsDefine.globals, 18275 _hasPriority, 18276 //turns true whenever a CSSPropTween instance is created that has a priority other than 0. This helps us discern whether or not we should spend the time organizing the linked list or not after a CSSPlugin's _onInitTween() method is called. 18277 _suffixMap, 18278 //we set this in _onInitTween() each time as a way to have a persistent variable we can use in other methods like _parse() without having to pass it around as a parameter and we keep _parse() decoupled from a particular CSSPlugin instance 18279 _cs, 18280 //computed style (we store this in a shared variable to conserve memory and make minification tighter 18281 _overwriteProps, 18282 //alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification. 18283 _specialProps = {}, 18284 p = CSSPlugin.prototype = new TweenPlugin("css"); 18285 18286 p.constructor = CSSPlugin; 18287 CSSPlugin.version = "1.20.3"; 18288 CSSPlugin.API = 2; 18289 CSSPlugin.defaultTransformPerspective = 0; 18290 CSSPlugin.defaultSkewType = "compensated"; 18291 CSSPlugin.defaultSmoothOrigin = true; 18292 p = "px"; //we'll reuse the "p" variable to keep file size down
18293 CSSPlugin.suffixMap = { top: p, right: p, bottom: p, left: p, width: p, height: p, fontSize: p, padding: p, margin: p, perspective: p, lineHeight: "" }; 18294 18295 var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g, 18296 _relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g, 18297 _valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi, 18298 //finds all the values that begin with numbers or += or -= and then a number. Includes suffixes. We use this to split complex values apart like "1px 5px 20px rgb(255,102,51)" 18299 _NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g, 18300 //also allows scientific notation and doesn't kill the leading -/+ in -= and += 18301 _suffixExp = /(?:\d|\-|\+|=|#|\.)*/g, 18302 _opacityExp = /opacity *= *([^)]*)/i, 18303 _opacityValExp = /opacity:([^;]*)/i, 18304 _alphaFilterExp = /alpha\(opacity *=.+?\)/i, 18305 _rgbhslExp = /^(rgb|hsl)/, 18306 _capsExp = /([A-Z])/g, 18307 _camelExp = /-([a-z])/gi, 18308 _urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi, 18309 //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage) 18310 _camelFunc = function (s, g) { 18311 return g.toUpperCase(); 18312 }, 18313 _horizExp = /(?:Left|Right|Width)/i, 18314 _ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi, 18315 _ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i, 18316 _commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi, 18317 //finds any commas that are not within parenthesis 18318 _complexExp = /[\s,\(]/i, 18319 //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value) 18320 _DEG2RAD = Math.PI / 180, 18321 _RAD2DEG = 180 / Math.PI, 18322 _forcePT = {}, 18323 _dummyElement = { style: {} }, 18324 _doc = _gsScope.document || { createElement: function () { 18325 return _dummyElement; 18326 } }, 18327 _createElement = function (type, ns) { 18328 return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type); 18329 }, 18330 _tempDiv = _createElement("div"), 18331 _tempImg = _createElement("img"), 18332 _internals = CSSPlugin._internals = { _specialProps: _specialProps }, 18333 //provides a hook to a few internal methods that we need to access from inside other plugins 18334 _agent = (_gsScope.navigator || {}).userAgent || "", 18335 _autoRound, 18336 _reqSafariFix, 18337 //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance). 18338 18339 _isSafari, 18340 _isFirefox, 18341 //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element. 18342 _isSafariLT6, 18343 //Safari (and Android 4 which uses a flavor of Safari) has a bug that prevents changes to "top" and "left" properties from rendering properly if changed on the same frame as a transform UNLESS we set the element's WebkitBackfaceVisibility to hidden (weird, I know). Doing this for Android 3 and earlier seems to actually cause other problems, though (fun!) 18344 _ieVers, 18345 _supportsOpacity = function () { 18346 //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version. 18347 var i = _agent.indexOf("Android"), 18348 a = _createElement("a"); 18349 _isSafari = _agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i + 8, 2)) > 3); 18350 _isSafariLT6 = _isSafari && parseFloat(_agent.substr(_agent.indexOf("Version/") + 8, 2)) < 6; 18351 _isFirefox = _agent.indexOf("Firefox") !== -1; 18352 if (/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(_agent) || /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(_agent)) { 18353 _ieVers = parseFloat(RegExp.$1); 18354 } 18355 if (!a) { 18356 return false; 18357 } 18358 a.style.cssText = "top:1px;opacity:.55;"; 18359 return (/^0.55/.test(a.style.opacity) 18360 ); 18361 }(), 18362 _getIEOpacity = function (v) { 18363 return _opacityExp.test(typeof v === "string" ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ? parseFloat(RegExp.$1) / 100 : 1; 18364 }, 18365 _log = function (s) { 18366 //for logging messages, but in a way that won't throw errors in old versions of IE. 18367 if (_gsScope.console) { 18368 console.log(s); 18369 } 18370 }, 18371 _target, 18372 //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params 18373 _index, 18374 //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params 18375 18376 _prefixCSS = "", 18377 //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-" 18378 _prefix = "", 18379 //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz". 18380 18381 // @private feed in a camelCase property name like "transform" and it will check to see if it is valid as-is or if it needs a vendor prefix. It returns the corrected camelCase property name (i.e. "WebkitTransform" or "MozTransform" or "transform" or null if no such property is found, like if the browser is IE8 or before, "transform" won't be found at all) 18382 _checkPropPrefix = function (p, e) { 18383 e = e || _tempDiv; 18384 var s = e.style, 18385 a, 18386 i; 18387 if (s[p] !== undefined) { 18388 return p; 18389 } 18390 p = p.charAt(0).toUpperCase() + p.substr(1); 18391 a = ["O", "Moz", "ms", "Ms", "Webkit"]; 18392 i = 5; 18393 while (--i > -1 && s[a[i] + p] === undefined) {} 18394 if (i >= 0) { 18395 _prefix = i === 3 ? "ms" : a[i]; 18396 _prefixCSS = "-" + _prefix.toLowerCase() + "-"; 18397 return _prefix + p; 18398 } 18399 return null; 18400 }, 18401 _getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function () {}, 18402 18403 18404 /** 18405 * @private Returns the css style for a particular property of an element. For example, to get whatever the current "left" css value for an element with an ID of "myElement", you could do: 18406 * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left"); 18407 * 18408 * @param {!Object} t Target element whose style property you want to query 18409 * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.) 18410 * @param {Object=} cs Computed style object. This just provides a way to speed processing if you're going to get several properties on the same element in quick succession - you can reuse the result of the getComputedStyle() call. 18411 * @param {boolean=} calc If true, the value will not be read directly from the element's "style" property (if it exists there), but instead the getComputedStyle() result will be used. This can be useful when you want to ensure that the browser itself is interpreting the value. 18412 * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto". 18413 * @return {?string} The current property value 18414 */ 18415 _getStyle = CSSPlugin.getStyle = function (t, p, cs, calc, dflt) { 18416 var rv; 18417 if (!_supportsOpacity) if (p === "opacity") { 18418 //several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here. 18419 return _getIEOpacity(t); 18420 } 18421 if (!calc && t.style[p]) { 18422 rv = t.style[p]; 18423 } else if (cs = cs || _getComputedStyle(t)) { 18424 rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase()); 18425 } else if (t.currentStyle) { 18426 rv = t.currentStyle[p]; 18427 } 18428 return dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto") ? dflt : rv; 18429 }, 18430 18431 18432 /** 18433 * @private Pass the target element, the property name, the numeric value, and the suffix (like "%", "em", "px", etc.) and it will spit back the equivalent pixel number. 18434 * @param {!Object} t Target element 18435 * @param {!string} p Property name (like "left", "top", "marginLeft", etc.) 18436 * @param {!number} v Value 18437 * @param {string=} sfx Suffix (like "px" or "%" or "em") 18438 * @param {boolean=} recurse If true, the call is a recursive one. In some browsers (like IE7/8), occasionally the value isn't accurately reported initially, but if we run the function again it will take effect. 18439 * @return {number} value in pixels 18440 */ 18441 _convertToPixels = _internals.convertToPixels = function (t, p, v, sfx, recurse) { 18442 if (sfx === "px" || !sfx && p !== "lineHeight") { 18443 return v; 18444 } 18445 if (sfx === "auto" || !v) { 18446 return 0; 18447 } 18448 var horiz = _horizExp.test(p), 18449 node = t, 18450 style = _tempDiv.style, 18451 neg = v < 0, 18452 precise = v === 1, 18453 pix, 18454 cache, 18455 time; 18456 if (neg) { 18457 v = -v; 18458 } 18459 if (precise) { 18460 v *= 100; 18461 } 18462 if (p === "lineHeight" && !sfx) { 18463 //special case of when a simple lineHeight (without a unit) is used. Set it to the value, read back the computed value, and then revert. 18464 cache = _getComputedStyle(t).lineHeight; 18465 t.style.lineHeight = v; 18466 pix = parseFloat(_getComputedStyle(t).lineHeight); 18467 t.style.lineHeight = cache; 18468 } else if (sfx === "%" && p.indexOf("border") !== -1) { 18469 pix = v / 100 * (horiz ? t.clientWidth : t.clientHeight); 18470 } else { 18471 style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;"; 18472 if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") { 18473 node = t.parentNode || _doc.body; 18474 if (_getStyle(node, "display").indexOf("flex") !== -1) { 18475 //Edge and IE11 have a bug that causes offsetWidth to report as 0 if the container has display:flex and the child is position:relative. Switching to position: absolute solves it. 18476 style.position = "absolute"; 18477 } 18478 cache = node._gsCache; 18479 time = TweenLite.ticker.frame; 18480 if (cache && horiz && cache.time === time) { 18481 //performance optimization: we record the width of elements along with the ticker frame so that we can quickly get it again on the same tick (seems relatively safe to assume it wouldn't change on the same tick) 18482 return cache.width * v / 100; 18483 } 18484 style[horiz ? "width" : "height"] = v + sfx; 18485 } else { 18486 style[horiz ? "borderLeftWidth" : "borderTopWidth"] = v + sfx; 18487 } 18488 node.appendChild(_tempDiv); 18489 pix = parseFloat(_tempDiv[horiz ? "offsetWidth" : "offsetHeight"]); 18490 node.removeChild(_tempDiv); 18491 if (horiz && sfx === "%" && CSSPlugin.cacheWidths !== false) { 18492 cache = node._gsCache = node._gsCache || {}; 18493 cache.time = time; 18494 cache.width = pix / v * 100; 18495 } 18496 if (pix === 0 && !recurse) { 18497 pix = _convertToPixels(t, p, v, sfx, true); 18498 } 18499 } 18500 if (precise) { 18501 pix /= 100; 18502 } 18503 return neg ? -pix : pix; 18504 }, 18505 _calculateOffset = _internals.calculateOffset = function (t, p, cs) { 18506 //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop 18507 if (_getStyle(t, "position", cs) !== "absolute") { 18508 return 0; 18509 } 18510 var dim = p === "left" ? "Left" : "Top",
18511 v = _getStyle(t, "margin" + dim, cs); 18512 return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0); 18513 }, 18514 18515 18516 // @private returns at object containing ALL of the style properties in camelCase and their associated values. 18517 _getAllStyles = function (t, cs) { 18518 var s = {}, 18519 i, 18520 tr, 18521 p; 18522 if (cs = cs || _getComputedStyle(t, null)) { 18523 if (i = cs.length) { 18524 while (--i > -1) { 18525 p = cs[i]; 18526 if (p.indexOf("-transform") === -1 || _transformPropCSS === p) { 18527 //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here. 18528 s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p); 18529 } 18530 } 18531 } else { 18532 //some browsers behave differently - cs.length is always 0, so we must do a for...in loop. 18533 for (i in cs) { 18534 if (i.indexOf("Transform") === -1 || _transformProp === i) { 18535 //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here. 18536 s[i] = cs[i]; 18537 } 18538 } 18539 } 18540 } else if (cs = t.currentStyle || t.style) { 18541 for (i in cs) { 18542 if (typeof i === "string" && s[i] === undefined) { 18543 s[i.replace(_camelExp, _camelFunc)] = cs[i]; 18544 } 18545 } 18546 } 18547 if (!_supportsOpacity) { 18548 s.opacity = _getIEOpacity(t); 18549 } 18550 tr = _getTransform(t, cs, false); 18551 s.rotation = tr.rotation; 18552 s.skewX = tr.skewX; 18553 s.scaleX = tr.scaleX; 18554 s.scaleY = tr.scaleY; 18555 s.x = tr.x; 18556 s.y = tr.y; 18557 if (_supports3D) { 18558 s.z = tr.z; 18559 s.rotationX = tr.rotationX; 18560 s.rotationY = tr.rotationY; 18561 s.scaleZ = tr.scaleZ; 18562 } 18563 if (s.filters) { 18564 delete s.filters; 18565 } 18566 return s; 18567 }, 18568 18569 18570 // @private analyzes two style objects (as returned by _getAllStyles()) and only looks for differences between them that contain tweenable values (like a number or color). It returns an object with a "difs" property which refers to an object c
18570ontaining only those isolated properties and values for tweening, and a "firstMPT" property which refers to the first MiniPropTween instance in a linked list that recorded all the starting values of the different properties so that we can revert to them at the end or beginning of the tween - we don't want the cascading to get messed up. The forceLookup parameter is an optional generic object with properties that should be forced into the results - this is necessary for className tweens that are overwriting others because imagine a scenario where a rollover/rollout adds/removes a class and the user swipes the mouse over the target SUPER fast, thus nothing actually changed yet and the subsequent comparison of the properties would indicate they match (especially when px rounding is taken into consideration), thus no tweening is necessary even though it SHOULD tween and remove those properties after the tween (otherwise the inline styles will contaminate things). See the className SpecialProp code for details. 18571 _cssDif = function (t, s1, s2, vars, forceLookup) { 18572 var difs = {}, 18573 style = t.style, 18574 val, 18575 p, 18576 mpt; 18577 for (p in s2) { 18578 if (p !== "cssText") if (p !== "length") if (isNaN(p)) if (s1[p] !== (val = s2[p]) || forceLookup && forceLookup[p]) if (p.indexOf("Origin") === -1) if (typeof val === "number" || typeof val === "string") { 18579 difs[p] = val === "auto" && (p === "left" || p === "top") ? _calculateOffset(t, p) : (val === "" || val === "auto" || val === "none") && typeof s1[p] === "string" && s1[p].replace(_NaNExp, "") !== "" ? 0 : val; //if the ending value is defaulting ("" or "auto"), we check the starting value and if it can be parsed into a number (a string which could have a suffix too, like 700px), then we swap in 0 for "" or "auto" so that things actually tween. 18580 if (style[p] !== undefined) { 18581 //for className tweens, we must remember which properties already existed inline - the ones that didn't should be removed when the tween isn't in progress because they were only introduced to facilitate the transition between classes. 18582 mpt = new MiniPropTween(style, p, style[p], mpt); 18583 } 18584 } 18585 } 18586 if (vars) { 18587 for (p in vars) { 18588 //copy properties (except className) 18589 if (p !== "className") { 18590 difs[p] = vars[p]; 18591 } 18592 } 18593 } 18594 return { difs: difs, firstMPT: mpt }; 18595 }, 18596 _dimensions = { width: ["Left", "Right"], height: ["Top", "Bottom"] }, 18597 _margins = ["marginLeft", "marginRight", "marginTop", "marginBottom"], 18598 18599 18600 /** 18601 * @private Gets the width or height of an element 18602 * @param {!Object} t Target element 18603 * @param {!string} p Property name ("width" or "height") 18604 * @param {Object=} cs Computed style object (if one exists). Just a speed optimization. 18605 * @return {number} Dimension (in pixels) 18606 */ 18607 _getDimension = function (t, p, cs) { 18608 if ((t.nodeName + "").toLowerCase() === "svg") { 18609 //Chrome no longer supports offsetWidth/offsetHeight on SVG elements. 18610 return (cs || _getComputedStyle(t))[p] || 0; 18611 } else if (t.getCTM && _isSVG(t)) { 18612 return t.getBBox()[p] || 0; 18613 } 18614 var v = parseFloat(p === "width" ? t.offsetWidth : t.offsetHeight), 18615 a = _dimensions[p], 18616 i = a.length; 18617 cs = cs || _getComputedStyle(t, null); 18618 while (--i > -1) { 18619 v -= parseFloat(_getStyle(t, "padding" + a[i], cs, true)) || 0; 18620 v -= parseFloat(_getStyle(t, "border" + a[i] + "Width", cs, true)) || 0; 18621 } 18622 return v; 18623 }, 18624 18625 18626 // @private Parses position-related complex strings like "top left" or "50px 10px" or "70% 20%", etc. which are used for things like transformOrigin or backgroundPosition. Optionally decorates a supplied object (recObj) with the following properties: "ox" (offsetX), "oy" (offsetY), "oxp" (if true, "ox" is a percentage not a pixel value), and "oxy" (if true, "oy" is a percentage not a pixel value) 18627 _parsePosition = function (v, recObj) { 18628 if (v === "contain" || v === "auto" || v === "auto auto") { 18629 //note: Firefox uses "auto auto" as default whereas Chrome uses "auto". 18630 return v + " "; 18631 } 18632 if (v == null || v === "") { 18633 v = "0 0"; 18634 } 18635 var a = v.split(" "), 18636 x = v.indexOf("left") !== -1 ? "0%" : v.indexOf("right") !== -1 ? "100%" : a[0], 18637 y = v.indexOf("top") !== -1 ? "0%" : v.indexOf("bottom") !== -1 ? "100%" : a[1], 18638 i; 18639 if (a.length > 3 && !recObj) { 18640 //multiple positions 18641 a = v.split(", ").join(",").split(","); 18642 v = []; 18643 for (i = 0; i < a.length; i++) { 18644 v.push(_parsePosition(a[i])); 18645 } 18646 return v.join(","); 18647 } 18648 if (y == null) { 18649 y = x === "center" ? "50%" : "0"; 18650 } else if (y === "center") { 18651 y = "50%"; 18652 } 18653 if (x === "center" || isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1) { 18654 //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
18654ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative. 18655 x = "50%"; 18656 } 18657 v = x + " " + y + (a.length > 2 ? " " + a[2] : ""); 18658 if (recObj) { 18659 recObj.oxp = x.indexOf("%") !== -1; 18660 recObj.oyp = y.indexOf("%") !== -1; 18661 recObj.oxr = x.charAt(1) === "="; 18662 recObj.oyr = y.charAt(1) === "="; 18663 recObj.ox = parseFloat(x.replace(_NaNExp, "")); 18664 recObj.oy = parseFloat(y.replace(_NaNExp, "")); 18665 recObj.v = v; 18666 } 18667 return recObj || v; 18668 }, 18669 18670 18671 /** 18672 * @private Takes an ending value (typically a string, but can be a number) and a starting value and returns the change between the two, looking for relative value indicators like += and -= and it also ignores suffixes (but make sure the ending value starts with a number or +=/-= and that the starting value is a NUMBER!) 18673 * @param {(number|string)} e End value which is typically a string, but could be a number 18674 * @param {(number|string)} b Beginning value which is typically a string but could be a number 18675 * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized) 18676 */ 18677 _parseChange = function (e, b) { 18678 if (typeof e === "function") { 18679 e = e(_index, _target); 18680 } 18681 return typeof e === "string" && e.charAt(1) === "=" ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : parseFloat(e) - parseFloat(b) || 0; 18682 }, 18683 18684 18685 /** 18686 * @private Takes a value and a default number, checks if the value is relative, null, or numeric and spits back a normalized number accordingly. Primarily used in the _parseTransform() function. 18687 * @param {Object} v Value to be parsed 18688 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter) 18689 * @return {number} Parsed value 18690 */ 18691 _parseVal = function (v, d) { 18692 if (typeof v === "function") { 18693 v = v(_index, _target); 18694 } 18695 return v == null ? d : typeof v === "string" && v.charAt(1) === "=" ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0; 18696 }, 18697 18698 18699 /** 18700 * @private Translates strings like "40deg" or "40" or 40rad" or "+=40deg" or "270_short" or "-90_cw" or "+=45_ccw" to a numeric radian angle. Of course a starting/default value must be fed in too so that relative values can be calculated properly. 18701 * @param {Object} v Value to be parsed 18702 * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter) 18703 * @param {string=} p property name for directionalEnd (optional - only used when the parsed value is directional ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation). Property name would be "rotation", "rotationX", or "rotationY" 18704 * @param {Object=} directionalEnd An object that will store the raw end values for directional angles ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation. 18705 * @return {number} parsed angle in radians 18706 */ 18707 _parseAngle = function (v, d, p, directionalEnd) { 18708 var min = 0.000001, 18709 cap, 18710 split, 18711 dif, 18712 result, 18713 isRelative; 18714 if (typeof v === "function") { 18715 v = v(_index, _target); 18716 } 18717 if (v == null) { 18718 result = d; 18719 } else if (typeof v === "number") { 18720 result = v; 18721 } else { 18722 cap = 360; 18723 split = v.split("_"); 18724 isRelative = v.charAt(1) === "="; 18725 dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])) * (v.indexOf("rad") === -1 ? 1 : _RAD2DEG) - (isRelative ? 0 : d); 18726 if (split.length) { 18727 if (directionalEnd) { 18728 directionalEnd[p] = d + dif; 18729 } 18730 if (v.indexOf("short") !== -1) { 18731 dif = dif % cap; 18732 if (dif !== dif % (cap / 2)) { 18733 dif = dif < 0 ? dif + cap : dif - cap; 18734 } 18735 } 18736 if (v.indexOf("_cw") !== -1 && dif < 0) { 18737 dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap; 18738 } else if (v.indexOf("ccw") !== -1 && dif > 0) { 18739 dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap; 18740 } 18741 } 18742 result = d + dif; 18743 } 18744 if (result < min && result > -min) { 18745 result = 0; 18746 } 18747 return result; 18748 }, 18749 _colorLookup = { aqua: [0, 255, 255], 18750 lime: [0, 255, 0], 18751 silver: [192, 192, 192], 18752 black: [0, 0, 0], 18753 maroon: [128, 0, 0], 18754 teal: [0, 128, 128], 18755 blue: [0, 0, 255], 18756 navy: [0, 0, 128], 18757 white: [255, 255, 255], 18758 fuchsia: [255, 0, 255], 18759 olive: [128, 128, 0], 18760 yellow: [255, 255, 0], 18761 orange: [255, 165, 0], 18762 gray: [128, 128, 128], 18763 purple: [128, 0, 128], 18764 green: [0, 128, 0], 18765 red: [255, 0, 0], 18766 pink: [255, 192, 203], 18767 cyan: [0, 255, 255],
18768 transparent: [255, 255, 255, 0] }, 18769 _hue = function (h, m1, m2) { 18770 h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; 18771 return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < 0.5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * 255 + 0.5 | 0; 18772 }, 18773 18774 18775 /** 18776 * @private Parses a color (like #9F0, #FF9900, rgb(255,51,153) or hsl(108, 50%, 10%)) into an array with 3 elements for red, green, and blue or if toHSL parameter is true, it will populate the array with hue, saturation, and lightness values. If a relative value is found in an hsl() or hsla() string, it will preserve those relative prefixes and all the values in the array will be strings instead of numbers (in all other cases it will be populated with numbers). 18777 * @param {(string|number)} v The value the should be parsed which could be a string like #9F0 or rgb(255,102,51) or rgba(255,0,0,0.5) or it could be a number like 0xFF00CC or even a named color like red, blue, purple, etc. 18778 * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba() 18779 * @return {Array.<number>} An array containing red, green, and blue (and optionally alpha) in that order, or if the toHSL parameter was true, the array will contain hue, saturation and lightness (and optionally alpha) in that order. Always numbers unless there's a relative prefix found in an hsl() or hsla() string and toHSL is true. 18780 */ 18781 _parseColor = CSSPlugin.parseColor = function (v, toHSL) { 18782 var a, r, g, b, h, s, l, max, min, d, wasHSL; 18783 if (!v) { 18784 a = _colorLookup.black; 18785 } else if (typeof v === "number") { 18786 a = [v >> 16, v >> 8 & 255, v & 255]; 18787 } else { 18788 if (v.charAt(v.length - 1) === ",") { 18789 //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value. 18790 v = v.substr(0, v.length - 1); 18791 } 18792 if (_colorLookup[v]) { 18793 a = _colorLookup[v]; 18794 } else if (v.charAt(0) === "#") { 18795 if (v.length === 4) { 18796 //for shorthand like #9F0 18797 r = v.charAt(1); 18798 g = v.charAt(2); 18799 b = v.charAt(3); 18800 v = "#" + r + r + g + g + b + b; 18801 } 18802 v = parseInt(v.substr(1), 16); 18803 a = [v >> 16, v >> 8 & 255, v & 255]; 18804 } else if (v.substr(0, 3) === "hsl") { 18805 a = wasHSL = v.match(_numExp); 18806 if (!toHSL) { 18807 h = Number(a[0]) % 360 / 360; 18808 s = Number(a[1]) / 100; 18809 l = Number(a[2]) / 100; 18810 g = l <= 0.5 ? l * (s + 1) : l + s - l * s; 18811 r = l * 2 - g; 18812 if (a.length > 3) { 18813 a[3] = Number(a[3]); 18814 } 18815 a[0] = _hue(h + 1 / 3, r, g); 18816 a[1] = _hue(h, r, g); 18817 a[2] = _hue(h - 1 / 3, r, g); 18818 } else if (v.indexOf("=") !== -1) { 18819 //if relative values are found, just return the raw strings with the relative prefixes in place. 18820 return v.match(_relNumExp); 18821 } 18822 } else { 18823 a = v.match(_numExp) || _colorLookup.transparent; 18824 } 18825 a[0] = Number(a[0]); 18826 a[1] = Number(a[1]); 18827 a[2] = Number(a[2]); 18828 if (a.length > 3) { 18829 a[3] = Number(a[3]); 18830 } 18831 } 18832 if (toHSL && !wasHSL) { 18833 r = a[0] / 255; 18834 g = a[1] / 255; 18835 b = a[2] / 255; 18836 max = Math.max(r, g, b); 18837 min = Math.min(r, g, b); 18838 l = (max + min) / 2; 18839 if (max === min) { 18840 h = s = 0; 18841 } else { 18842 d = max - min; 18843 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 18844 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 18845 h *= 60; 18846 } 18847 a[0] = h + 0.5 | 0; 18848 a[1] = s * 100 + 0.5 | 0; 18849 a[2] = l * 100 + 0.5 | 0; 18850 } 18851 return a; 18852 }, 18853 _formatColors = function (s, toHSL) { 18854 var colors = s.match(_colorExp) || [], 18855 charIndex = 0, 18856 parsed = "", 18857 i, 18858 color, 18859 temp; 18860 if (!colors.length) { 18861 return s; 18862 } 18863 for (i = 0; i < colors.length; i++) { 18864 color = colors[i]; 18865 temp = s.substr(charIndex, s.indexOf(color, charIndex) - charIndex); 18866 charIndex += temp.length + color.length; 18867 color = _parseColor(color, toHSL); 18868 if (color.length === 3) { 18869 color.push(1); 18870 } 18871 parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.
18871join(",")) + ")"; 18872 } 18873 return parsed + s.substr(charIndex); 18874 }, 18875 _colorExp = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3}){1,2}\\b"; //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc. 18876 18877 for (p in _colorLookup) { 18878 _colorExp += "|" + p + "\\b"; 18879 } 18880 _colorExp = new RegExp(_colorExp + ")", "gi"); 18881 18882 CSSPlugin.colorStringFilter = function (a) { 18883 var combined = a[0] + " " + a[1], 18884 toHSL; 18885 if (_colorExp.test(combined)) { 18886 toHSL = combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1; 18887 a[0] = _formatColors(a[0], toHSL); 18888 a[1] = _formatColors(a[1], toHSL); 18889 } 18890 _colorExp.lastIndex = 0; 18891 }; 18892 18893 if (!TweenLite.defaultStringFilter) { 18894 TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter; 18895 } 18896 18897 /** 18898 * @private Returns a formatter function that handles taking a string (or number in some cases) and returning a consistently formatted one in terms of delimiters, quantity of values, etc. For example, we may get boxShadow values defined as "0px red" or "0px 0px 10px rgb(255,0,0)" or "0px 0px 20px 20px #F00" and we need to ensure that what we get back is described with 4 numbers and a color. This allows us to feed it into the _parseComplex() method and split the values up appropriately. The neat thing about this _getFormatter() function is that the dflt defines a pattern as well as a default, so for example, _getFormatter("0px 0px 0px 0px #777", true) not only sets the default as 0px for all distances and #777 for the color, but also sets the pattern such that 4 numbers and a color will always get returned. 18899 * @param {!string} dflt The default value and pattern to follow. So "0px 0px 0px 0px #777" will ensure that 4 numbers and a color will always get returned. 18900 * @param {boolean=} clr If true, the values should be searched for color-related data. For example, boxShadow values typically contain a color whereas borderRadius don't. 18901 * @param {boolean=} collapsible If true, the value is a top/left/right/bottom style one that acts like margin or padding, where if only one value is received, it's used for all 4; if 2 are received, the first is duplicated for 3rd (bottom) and the 2nd is duplicated for the 4th spot (left), etc. 18902 * @return {Function} formatter function 18903 */ 18904 var _getFormatter = function (dflt, clr, collapsible, multi) { 18905 if (dflt == null) { 18906 return function (v) { 18907 return v; 18908 }; 18909 } 18910 var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "", 18911 dVals = dflt.split(dColor).join("").match(_valuesExp) || [], 18912 pfx = dflt.substr(0, dflt.indexOf(dVals[0])), 18913 sfx = dflt.charAt(dflt.length - 1) === ")" ? ")" : "", 18914 delim = dflt.indexOf(" ") !== -1 ? " " : ",", 18915 numVals = dVals.length, 18916 dSfx = numVals > 0 ? dVals[0].replace(_numExp, "") : "", 18917 formatter; 18918 if (!numVals) { 18919 return function (v) { 18920 return v; 18921 }; 18922 } 18923 if (clr) { 18924 formatter = function (v) { 18925 var color, vals, i, a; 18926 if (typeof v === "number") { 18927 v += dSfx; 18928 } else if (multi && _commasOutsideParenExp.test(v)) { 18929 a = v.replace(_commasOutsideParenExp, "|").split("|"); 18930 for (i = 0; i < a.length; i++) { 18931 a[i] = formatter(a[i]); 18932 } 18933 return a.join(","); 18934 } 18935 color = (v.match(_colorExp) || [dColor])[0]; 18936 vals = v.split(color).join("").match(_valuesExp) || []; 18937 i = vals.length; 18938 if (numVals > i--) { 18939 while (++i < numVals) { 18940 vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i]; 18941 } 18942 } 18943 return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : ""); 18944 }; 18945 return formatter; 18946 } 18947 formatter = function (v) { 18948 var vals, a, i; 18949 if (typeof v === "number") { 18950 v += dSfx; 18951 } else if (multi && _commasOutsideParenExp.test(v)) { 18952 a = v.replace(_commasOutsideParenExp, "|").split("|"); 18953 for (i = 0; i < a.length; i++) { 18954 a[i] = formatter(a[i]); 18955 } 18956 return a.join(","); 18957 } 18958 vals = v.match(_valuesExp) || []; 18959 i = vals.length; 18960 if (numVals > i--) { 18961 while (++i < numVals) { 18962 vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i]; 18963 } 18964 } 18965 return pfx + vals.join(delim) + sfx; 18966 }; 18967 return formatter; 18968 }, 18969 18970 18971 /** 18972 * @private returns a formatter function that's used for edge-related values like marginTop, marginLeft, paddingBottom, paddingRight, etc. Just pass a comma-delimited list of property names related to the edges. 18973 * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft" 18974 * @return {Function} a formatter function 18975 */ 18976 _getEdgeParser = function (props) { 18977 props = props.split(","); 18978 return function (t, e, p, cssp, pt, plugin, vars) { 18979 var a = (e + "").split(" "), 18980 i; 18981 vars = {}; 18982 for (i = 0; i < 4; i++) { 18983 vars[props[i]] = a[i] = a[i] || a[(i - 1) / 2 >> 0]; 18984 } 18985 return cssp.parse(t, vars, pt, plugin); 18986 }; 18987 }, 18988 18989 18990 // @private used when other plugins must tween values first, like BezierPlugin or ThrowPropsPlugin, etc. That plugin's setRatio() gets called first so that the values are updated, and then we loop through the MiniPropTweens which handle copying the values into their appropriate slots so that they can then be applied correctly in the main CSSPlugin setRatio() method. Remember, we typically create a proxy object that has a bunch of uniquely-named properties that we feed to the sub-plugin and it does its magic normally, and then we must interpret those values and apply them to the css because often numbers must get combined/concatenated, suffixes added, etc. to work with css, like boxShadow could have 4 values plus a color. 18991 _setPluginRatio = _internals._setPluginRatio = function (v) { 18992 this.plugin.setRatio(v); 18993 var d = this.data, 18994 proxy = d.proxy, 18995 mpt = d.firstMPT, 18996 min = 0.000001, 18997 val, 18998 pt, 18999 i, 19000 str, 19001 p; 19002 while (mpt) { 19003 val = proxy[mpt.v]; 19004 if (mpt.r) { 19005 val = Math.round(val); 19006 } else if (val < min && val > -min) { 19007 val = 0; 19008 } 19009 mpt.t[mpt.p] = val; 19010 mpt = mpt._next; 19011 } 19012 if (d.autoRotate) { 19013 d.autoRotate.rotation = d.mod ? d.mod(proxy.rotation, this.t) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier 19014 } 19015 //at the end, we must set the CSSPropTween's "e" (end) value dynamically here because that's what is used in the final setRatio() method. Same for "b" at the beginning. 19016 if (v === 1 || v === 0) { 19017 mpt = d.firstMPT; 19018 p = v === 1 ? "e" : "b"; 19019 while (mpt) { 19020 pt = mpt.t; 19021 if (!pt.type) { 19022 pt[p] = pt.s + pt.xs0; 19023 } else if (pt.type === 1) { 19024 str = pt.xs0 + pt.s + pt.xs1; 19025 for (i = 1; i < pt.l; i++) { 19026 str += pt["xn" + i] + pt["xs" + (i + 1)]; 19027 } 19028 pt[p] = str; 19029 } 19030 mpt = mpt._next; 19031 } 19032 } 19033 }, 19034 19035 19036 /** 19037 * @private @constructor Used by a few SpecialProps to hold important values for proxies. For example, _parseToProxy() creates a MiniPropTween instance for each property that must get tweened on the proxy, and we record the original property name as well as the unique one we create for the proxy, plus whether or not the value needs to be roun
19037ded plus the original value. 19038 * @param {!Object} t target object whose property we're tweening (often a CSSPropTween) 19039 * @param {!string} p property name 19040 * @param {(number|string|object)} v value 19041 * @param {MiniPropTween=} next next MiniPropTween in the linked list 19042 * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer 19043 */ 19044 MiniPropTween = function (t, p, v, next, r) { 19045 this.t = t; 19046 this.p = p; 19047 this.v = v; 19048 this.r = r; 19049 if (next) { 19050 next._prev = this; 19051 this._next = next; 19052 } 19053 }, 19054 19055 19056 /** 19057 * @private Most other plugins (like BezierPlugin and ThrowPropsPlugin and others) can only tween numeric values, but CSSPlugin must accommodate special values that have a bunch of extra data (like a suffix or strings between numeric values, etc.). For example, boxShadow has values like "10px 10px 20px 30px rgb(255,0,0)" which would utterly confuse other plugins. This method allows us to split that data apart and grab only the numeric data and attach it to uniquely-named properties of a generic proxy object ({}) so that we can feed that to virtually any plugin to have the numbers tweened. However, we must also keep track of which properties from the proxy go with which CSSPropTween values and instances. So we create a linked list of MiniPropTweens. Each one records a target (the original CSSPropTween), property (like "s" or "xn1" or "xn2") that we're tweening and the unique property name that was used for the proxy (like "boxShadow_xn1" and "boxShadow_xn2") and whether or not they need to be rounded. That way, in the _setPluginRatio() method we can simply copy the values over from the proxy to the CSSPropTween instance(s). Then, when the main CSSPlugin setRatio() method runs and applies the CSSPropTween values accordingly, they're updated nicely. So the external plugin tweens the numbers, _setPluginRatio() copies them over, and setRatio() acts normally, applying css-specific values to the element. 19058 * This method returns an object that has the following properties:
19059 * - proxy: a generic object containing the starting values for all the properties that will be tweened by the external plugin. This is what we feed to the external _onInitTween() as the target 19060 * - end: a generic object containing the ending values for all the properties that will be tweened by the external plugin. This is what we feed to the external plugin's _onInitTween() as the destination values 19061 * - firstMPT: the first MiniPropTween in the linked list 19062 * - pt: the first CSSPropTween in the linked list that was created when parsing. If shallow is true, this linked list will NOT attach to the one passed into the _parseToProxy() as the "pt" (4th) parameter. 19063 * @param {!Object} t target object to be tweened 19064 * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed 19065 * @param {!CSSPlugin} cssp The CSSPlugin instance 19066 * @param {CSSPropTween=} pt the next CSSPropTween in the linked list 19067 * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values 19068 * @param {boolean=} shallow if true, the resulting linked list from the parse will NOT be attached to the CSSPropTween that was passed in as the "pt" (4th) parameter. 19069 * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions) 19070 */ 19071 _parseToProxy = _internals._parseToProxy = function (t, vars, cssp, pt, plugin, shallow) { 19072 var bpt = pt, 19073 start = {}, 19074 end = {}, 19075 transform = cssp._transform, 19076 oldForce = _forcePT, 19077 i, 19078 p, 19079 xp, 19080 mpt, 19081 firstPT; 19082 cssp._transform = null; 19083 _forcePT = vars; 19084 pt = firstPT = cssp.parse(t, vars, pt, plugin); 19085 _forcePT = oldForce; 19086 //break off from the linked list so the new ones are isolated. 19087 if (shallow) { 19088 cssp._transform = transform; 19089 if (bpt) { 19090 bpt._prev = null; 19091 if (bpt._prev) { 19092 bpt._prev._next = null; 19093 } 19094 } 19095 } 19096 while (pt && pt !== bpt) { 19097 if (pt.type <= 1) { 19098 p = pt.p; 19099 end[p] = pt.s + pt.c; 19100 start[p] = pt.s; 19101 if (!shallow) { 19102 mpt = new MiniPropTween(pt, "s", p, mpt, pt.r); 19103 pt.c = 0; 19104 } 19105 if (pt.type === 1) { 19106 i = pt.l; 19107 while (--i > 0) { 19108 xp = "xn" + i; 19109 p = pt.p + "_" + xp; 19110 end[p] = pt.data[xp]; 19111 start[p] = pt[xp]; 19112 if (!shallow) { 19113 mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]); 19114 } 19115 } 19116 } 19117 } 19118 pt = pt._next; 19119 } 19120 return { proxy: start, end: end, firstMPT: mpt, pt: firstPT }; 19121 }, 19122 19123 19124 /** 19125 * @constructor Each property that is tweened has at least one CSSPropTween associated with it. These instances store important information like the target, property, starting value, amount of change, etc. They can also optionally have a number of "extra" strings and numeric values named xs1, xn1, xs2, xn2, xs3, xn3, etc. where "s" indicates string and "n" indicates number. These can be pieced together in a complex-value tween (type:1) that has alternating types of data like a string, number, string, number, etc. For example, boxShadow could be "5px 5px 8px rgb(102, 102, 51)". In that value, there are 6 numbers that may need to tween and then pieced back together into a string again with spaces, suffixes, etc. xs0 is special in that it stores the suffix for standard (type:0) tweens, -OR- the first string (prefix) in a complex-value (type:1) CSSPropTween -OR- it can be the non-tweening value in a type:-1 CSSPropTween. We do this to conserve memory. 19126 * CSSPropTweens have the following optional properties as well (not defined through the constructor): 19127 * - l: Length in terms of the number of extra properties that the CSSPropTween has (default: 0). For example, for a boxShadow we may need to tween 5 numbers in which case l would be 5; Keep in mind that the start/end values for the first number that's tweened are always stored in the s and c properties to conserve memory. All additional values thereafter are stored in xn1, xn2, etc. 19128 * - xfirst: The first instance of any sub-CSSPropTweens that are tweening properties of this instance. For example, we may split up a boxShadow tween so that there's a main CSSPropTween of type:1 that has various xs* and xn* values associated with the h-shadow, v-shadow, blur, color, etc. Then we spawn a CSSPropTween for each of those that has a higher priority and runs BEFORE the main CSSPropTween so that the values are all set by the time it needs to re-assemble them. The xfirst gives us an easy way to identify the first one in that chain which typically ends at the main one (because they're all prepende to the linked list) 19129 * - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
19129weens (like xfirst refers to) to tween the values - we might want ThrowPropsPlugin or BezierPlugin some other plugin to do the actual tweening, so we create a plugin instance and store a reference here. We need this reference so that if we get a request to round values or disable a tween, we can pass along that request. 19130 * - data: Arbitrary data that needs to be stored with the CSSPropTween. Typically if we're going to have a plugin handle the tweening of a complex-value tween, we create a generic object that stores the END values that we're tweening to and the CSSPropTween's xs1, xs2, etc. have the starting values. We store that object as data. That way, we can simply pass that object to the plugin and use the CSSPropTween as the target. 19131 * - setRatio: Only used for type:2 tweens that require custom functionality. In this case, we call the CSSPropTween's setRatio() method and pass the ratio each time the tween updates. This isn't quite as efficient as doing things directly in the CSSPlugin's setRatio() method, but it's very convenient and flexible. 19132 * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything. 19133 * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width". 19134 * @param {number} s Starting numeric value 19135 * @param {number} c Change in numeric value over the course of the entire tween. For example, if element.width starts at 5 and should end at 100, c would be 95. 19136 * @param {CSSPropTween=} next The next CSSPropTween in the linked list. If one is defined, we will define its _prev as the new instance, and the new instance's _next will be pointed at it. 19137 * @param {number=} type The type of CSSPropTween where -1 = a non-tweening value, 0 = a standard simple tween, 1 = a complex value (like one that has multiple numbers in a comma- or space-delimited string like border:"1px solid red"), and 2 = one that uses a custom setRatio function that does all of the work of applying the values on each update. 19138 * @param {string=} n Name of the property that should be used for overwriting purposes which is typically the same as p but not always. For example, we may need to create a subtween for the 2nd part of a "clip:rect(...)" tween in which case "p" might be xs1 but "n" is still "clip" 19139 * @param {boolean=} r If true, the value(s) should be rounded 19140 * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0. 19141 * @param {string=} b Beginning value. We store this to ensure that it is EXACTLY what it was when the tween began without any risk of interpretation issues. 19142 * @param {string=} e Ending value. We store this to ensure that it is EXACTLY what the user defined at the end of the tween without any risk of interpretation issues. 19143 */ 19144 CSSPropTween = _internals.CSSPropTween = function (t, p, s, c, next, type, n, r, pr, b, e) { 19145 this.t = t; //target 19146 this.p = p; //property 19147 this.s = s; //starting value 19148 this.c = c; //change value 19149 this.n = n || p; //name that this CSSPropTween should be associated to (usually the same as p, but not always - n is what overwriting looks at) 19150 if (!(t instanceof CSSPropTween)) { 19151 _overwriteProps.push(this.n); 19152 } 19153 this.r = r; //round (boolean) 19154 this.type = type || 0; //0 = normal tween, -1 = non-tweening (in which case xs0 will be applied to the target's property, like tp.t[tp.p] = tp.xs0), 1 = complex-value SpecialProp, 2 = custom setRatio() that does all the work 19155 if (pr) { 19156 this.pr = pr; 19157 _hasPriority = true; 19158 } 19159 this.b = b === undefined ? s : b; 19160 this.e = e === undefined ? s + c : e; 19161 if (next) { 19162 this._next = next; 19163 next._prev = this; 19164 } 19165 }, 19166 _addNonTweeningNumericPT = function (target, prop, start, end, next, overwriteProp) { 19167 //cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween 19168 var pt = new CSSPropTween(target, prop, start, end - start, next, -1, over
19168writeProp); 19169 pt.b = start; 19170 pt.e = pt.xs0 = end; 19171 return pt; 19172 }, 19173 19174 19175 /** 19176 * Takes a target, the beginning value and ending value (as strings) and parses them into a CSSPropTween (possibly with child CSSPropTweens) that accommodates multiple numbers, colors, comma-delimited values, etc. For example: 19177 * sp.parseComplex(element, "boxShadow", "5px 10px 20px rgb(255,102,51)", "0px 0px 0px red", true, "0px 0px 0px rgb(0,0,0,0)", pt); 19178 * It will walk through the beginning and ending values (which should be in the same format with the same number and type of values) and figure out which parts are numbers, what strings separate the numeric/tweenable values, and then create the CSSPropTweens accordingly. If a plugin is defined, no child CSSPropTweens will be created. Instead, the ending values will be stored in the "data" property of the returned CSSPropTween like: {s:-5, xn1:-10, xn2:-20, xn3:255, xn4:0, xn5:0} so that it can be fed to any other plugin and it'll be plain numeric tweens but the recomposition of the complex value will be handled inside CSSPlugin's setRatio(). 19179 * If a setRatio is defined, the type of the CSSPropTween will be set to 2 and recomposition of the values will be the responsibility of that method. 19180 * 19181 * @param {!Object} t Target whose property will be tweened 19182 * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow") 19183 * @param {string} b Beginning value 19184 * @param {string} e Ending value 19185 * @param {boolean} clrs If true, the value could contain a color value like "rgb(255,0,0)" or "#F00" or "red". The default is false, so no colors will be recognized (a performance optimization) 19186 * @param {(string|number|Object)} dflt The default beginning value that should be used if no valid beginning value is defined or if the number of values inside the complex beginning and ending values don't match 19187 * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this). 19188 * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0. 19189 * @param {TweenPlugin=} plugin If a plugin should handle the tweening of extra properties, pass the plugin instance here. If one is defined, then NO subtweens will be created for any extra properties (the properties will be created - just not additional CSSPropTween instances to tween them) because the plugin is expected to do so. However, the end values WILL be populated in the "data" property, like {s:100, xn1:50, xn2:300} 19190 * @param {function(number)=} setRatio If values should be set in a custom function instead of being pieced together in a type:1 (complex-value) CSSPropTween, define that custom function here. 19191 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call. 19192 */ 19193 _parseComplex = CSSPlugin.parseComplex = function (t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) { 19194 //DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e); 19195 b = b || dflt || ""; 19196 if (typeof e === "function") { 19197 e = e(_index, _target); 19198 } 19199 pt = new CSSPropTween(t, p, 0, 0, pt, setRatio ? 2 : 1, null, false, pr, b, e); 19200 e += ""; //ensures it's a string 19201 if (clrs && _colorExp.test(e + b)) { 19202 //if colors are found, normalize the formatting to rgba() or hsla(). 19203 e = [b, e]; 19204 CSSPlugin.colorStringFilter(e); 19205 b = e[0]; 19206 e = e[1]; 19207 } 19208 var ba = b.split(", ").join(",").split(" "), 19209 //beginning array 19210 ea = e.split(", ").join(",").split(" "), 19211 //ending array 19212 l = ba.length, 19213 autoRound = _autoRound !== false, 19214 i, 19215 xi, 19216 ni, 19217 bv, 19218 ev, 19219 bnums, 19220 enums, 19221 bn, 19222 hasAlpha, 19223 temp, 19224 cv, 19225 str, 19226 useHSL; 19227 if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) { 19228 if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) { 19229 //keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces) 19230 ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" "); 19231 ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" "); 19232 } else { 19233 ba = ba.join(" ").split(",").join(", ").split(" "); 19234 ea = ea.join(" ").split(",").join(", ").split(" "); 19235 } 19236 l = ba.length; 19237 } 19238 if (l !== ea.length) { 19239 //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")"); 19240 ba = (dflt || "").split(" "); 19241 l = ba.length; 19242 } 19243 pt.plugin = plugin; 19244 pt.setRatio = setRatio; 19245 _colorExp.lastIndex = 0; 19246 for (i = 0; i < l; i++) { 19247 bv = ba[i]; 19248 ev = ea[i]; 19249 bn = parseFloat(bv); 19250 //if the value begins with a number (most common). It's fine if it has a suffix like px 19251 if (bn || bn === 0) { 19252 pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), autoRound && ev.indexOf("px") !== -1, true); 19253 19254 //if the value is a color 19255 } else if (clrs && _colorExp.test(bv)) { 19256 str = ev.indexOf(")") + 1; 19257 str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it. 19258 useHSL = ev.indexOf("hsl") !== -1 && _supportsOpacity; 19259 temp = ev; //original string value so we can look for any prefix later. 19260 bv = _parseColor(bv, useHSL); 19261 ev = _parseColor(ev, useHSL); 19262 hasAlpha = bv.length + ev.length > 6; 19263 if (hasAlpha && !_supportsOpacity && ev[3] === 0) { 19264 //older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color 19265 pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
19266 pt.e = pt.e.split(ea[i]).join("transparent"); 19267 } else { 19268 if (!_supportsOpacity) { 19269 //old versions of IE don't support rgba(). 19270 hasAlpha = false; 19271 } 19272 if (useHSL) { 19273 pt.appendXtra(temp.substr(0, temp.indexOf("hsl")) + (hasAlpha ? "hsla(" : "hsl("), bv[0], _parseChange(ev[0], bv[0]), ",", false, true).appendXtra("", bv[1], _parseChange(ev[1], bv[1]), "%,", false).appendXtra("", bv[2], _parseChange(ev[2], bv[2]), hasAlpha ? "%," : "%" + str, false); 19274 } else { 19275 pt.appendXtra(temp.substr(0, temp.indexOf("rgb")) + (hasAlpha ? "rgba(" : "rgb("), bv[0], ev[0] - bv[0], ",", true, true).appendXtra("", bv[1], ev[1] - bv[1], ",", true).appendXtra("", bv[2], ev[2] - bv[2], hasAlpha ? "," : str, true); 19276 } 19277 19278 if (hasAlpha) { 19279 bv = bv.length < 4 ? 1 : bv[3]; 19280 pt.appendXtra("", bv, (ev.length < 4 ? 1 : ev[3]) - bv, str, false); 19281 } 19282 } 19283 _colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results. 19284 } else { 19285 bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array 19286 19287 //if no number is found, treat it as a non-tweening value and just append the string to the current xs. 19288 if (!bnums) { 19289 pt["xs" + pt.l] += pt.l || pt["xs" + pt.l] ? " " + ev : ev; 19290 19291 //loop through all the numbers that are found and construct the extra values on the pt. 19292 } else { 19293 enums = ev.match(_relNumExp); //get each group of numbers in the end value string and drop them into an array. We allow relative values too, like +=50 or -=.5 19294 if (!enums || enums.length !== bnums.length) { 19295 //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")"); 19296 return pt; 19297 } 19298 ni = 0; 19299 for (xi = 0; xi < bnums.length; xi++) { 19300 cv = bnums[xi]; 19301 temp = bv.indexOf(cv, ni); 19302 pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", autoRound && bv.substr(temp + cv.length, 2) === "px", xi === 0); 19303 ni = temp + cv.length; 19304 } 19305 pt["xs" + pt.l] += bv.substr(ni); 19306 } 19307 } 19308 } 19309 //if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly. 19310 if (e.indexOf("=") !== -1) if (pt.data) { 19311 str = pt.xs0 + pt.data.s; 19312 for (i = 1; i < pt.l; i++) { 19313 str += pt["xs" + i] + pt.data["xn" + i]; 19314 } 19315 pt.e = str + pt["xs" + i]; 19316 } 19317 if (!pt.l) { 19318 pt.type = -1; 19319 pt.xs0 = pt.e; 19320 } 19321 return pt.xfirst || pt; 19322 }, 19323 i = 9; 19324 19325 p = CSSPropTween.prototype; 19326 p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc. 19327 while (--i > 0) { 19328 p["xn" + i] = 0; 19329 p["xs" + i] = ""; 19330 } 19331 p.xs0 = ""; 19332 p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null; 19333 19334 /** 19335 * Appends and extra tweening value to a CSSPropTween and automatically manages any prefix and suffix strings. The first extra value is stored in the s and c of the main CSSPropTween instance, but thereafter any extras are stored in the xn1, xn2, xn3, etc. The prefixes and suffixes are stored in the xs0, xs1, xs2, etc. properties. For example, if I walk through a clip value like "rect(10px, 5px, 0px, 20px)", the values would be stored like this: 19336 * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)" 19337 * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method). 19338 * @param {string=} pfx Prefix (if any) 19339 * @param {!number} s Starting value 19340 * @param {!number} c Change in numeric value over the course of the entire tween. For example, if the start is 5 and the end is 100, the change would be 95. 19341 * @param {string=} sfx Suffix (if any) 19342 * @param {boolean=} r Round (if true). 19343 * @param {boolean=} pad If true, this extra value should be separated by the previous one by a space. If there is no previous extra and pad is true, it will automatically drop the space. 19344 * @return {CSSPropTween} returns itself so that multiple methods can be chained together. 19345 */ 19346 p.appendXtra = function (pfx, s, c, sfx, r, pad) { 19347 var pt = this, 19348 l = pt.l; 19349 pt["xs" + l] += pad && (l || pt["xs" + l]) ? " " + pfx : pfx || ""; 19350 if (!c) if (l !== 0 && !pt.plugin) { 19351 //typically we'll combine non-changing values right into the xs to optimize performance, but we don't combine them when there's a plugin that will be tweening the values because it may depend on the values being split apart, like for a bezier, if a value doesn't change between the first and second iteration but then it does on the 3rd, we'll run into trouble because there's no xn slot for that value! 19352 pt["xs" + l] += s + (sfx || ""); 19353 return pt; 19354 } 19355 pt.l++; 19356 pt.type = pt.setRatio ? 2 : 1; 19357 pt["xs" + pt.l] = sfx || ""; 19358 if (l > 0) { 19359 pt.data["xn" + l] = s + c; 19360 pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method) 19361 pt["xn" + l] = s; 19362 if (!pt.plugin) { 19363 pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr); 19364 pt.xfirst.xs0 = 0; //just to ensure that the property stays numeric which helps modern browsers speed up processing. Remember, in the setRatio() method, we do pt.t[pt.p] = val + pt.xs0 so if pt.xs0 is "" (the default), it'll cast the end value as a string. When a property is a number sometimes and a string sometimes, it prevents the compiler from locking in the data type, slowing things down slightly. 19365 } 19366 return pt; 19367 } 19368 pt.data = { s: s + c }; 19369 pt.rxp = {}; 19370 pt.s = s; 19371 pt.c = c; 19372 pt.r = r; 19373 return pt; 19374 }; 19375 19376 /** 19377 * @constructor A SpecialProp is basically a css property that needs to be treated in a non-standard way, like if it may contain a complex value like boxShadow:"5px 10px 15px rgb(255, 102, 51)" or if it is associated with another plugin like ThrowPropsPlugin or BezierPlugin. Every SpecialProp is associated with a particular property name like "boxShadow" or "throwProps" or "bezier" and it will intercept those values in the vars object that's passed to the CSSPlugin and handle them accordingly. 19378 * @param {!string} p Property name (like "boxShadow" or "throwProps") 19379 * @param {Object=}
19379 options An object containing any of the following configuration options: 19380 * - defaultValue: the default value 19381 * - parser: A function that should be called when the associated property name is found in the vars. This function should return a CSSPropTween instance and it should ensure that it is properly inserted into the linked list. It will receive 4 paramters: 1) The target, 2) The value defined in the vars, 3) The CSSPlugin instance (whose _firstPT should be used for the linked list), and 4) A computed style object if one was calculated (this is a speed optimization that allows retrieval of starting values quicker) 19382 * - formatter: a function that formats any value received for this special property (for example, boxShadow could take "5px 5px red" and format it to "5px 5px 0px 0px red" so that both the beginning and ending values have a common order and quantity of values.) 19383 * - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O) 19384 * - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc. 19385 * - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0. 19386 * - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out. 19387 * - collapsible: if true, the formatter should treat the value like it's a top/right/bottom/left value that could be collapsed, like "5px" would apply to all, "5px, 10px" would use 5px for top/bottom and 10px for right/left, etc. 19388 * - keyword: a special keyword that can [optionally] be found inside the value (like "inset" for boxShadow). This allows us to validate beginning/ending values to make sure they match (if the keyword is found in one, it'll be added to the other for consistency by default). 19389 */ 19390 var SpecialProp = function (p, options) { 19391 options = options || {}; 19392 this.p = options.prefix ? _checkPropPrefix(p) || p : p; 19393 _specialProps[p] = _specialProps[this.p] = this; 19394 this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi); 19395 if (options.parser) { 19396 this.parse = options.parser; 19397 } 19398 this.clrs = options.color; 19399 this.multi = options.multi; 19400 this.keyword = options.keyword; 19401 this.dflt = options.defaultValue; 19402 this.pr = options.priority || 0; 19403 }, 19404 19405 19406 //shortcut for creating a new SpecialProp that can accept multiple properties as a comma-delimited list (helps minification). dflt can be an array for multiple values (we don't do a comma-delimited list because the default value may contain commas, like rect(0px,0px,0px,0px)). We attach this method to the SpecialProp class/object instead of using a private _createSpecialProp() method so that we can tap into it externally if necessary, like from another plugin. 19407 _registerComplexSpecialProp = _internals._registerComplexSpecialProp = function (p, options, defaults) { 19408 if (typeof options !== "object") { 19409 options = { parser: defaults }; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin 19410 } 19411 var a = p.split(","), 19412 d = options.defaultValue, 19413 i, 19414 temp; 19415 defaults = defaults || [d]; 19416 for (i = 0; i < a.length; i++) { 19417 options.prefix = i === 0 && options.prefix; 19418 options.defaultValue = defaults[i] || d; 19419 temp = new SpecialProp(a[i], options); 19420 } 19421 }, 19422 19423 19424 //creates a placeholder special prop for a plugin so that the property gets caught the first time a tween of it is attempted, and at that time it makes the plugin register itself, thus taking over for all future tweens of that property. This allows us to not mandate that things load in a particular order and it also allows us to log() an error that informs the user when they attempt to tween an external plugin-related property without loading its .js file. 19425 _registerPluginProp = _internals._registerPluginProp = function (p) { 19426 if (!_specialProps[p]) { 19427 var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin"; 19428 _registerComplexSpecialProp(p, { parser: function (t, e, p, cssp, pt, plugin, vars) { 19429 var pluginClass = _globals.com.greensock.plugins[pluginName]; 19430 if (!pluginClass) { 19431 _log("Error: " + pluginName + " js file not loaded."); 19432 return pt; 19433 } 19434 pluginClass._cssRegister(); 19435 return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars); 19436 } }); 19437 } 19438 }; 19439 19440 p = SpecialProp.prototype; 19441 19442 /** 19443 * Alias for _parseComplex() that automatically plugs in certain values for this SpecialProp, like its property name, whether or not colors should be sensed, the default value, and priority. It also looks for any keyword that the SpecialProp defines (like "inset" for boxSh
19443adow) and ensures that the beginning and ending values have the same number of values for SpecialProps where multi is true (like boxShadow and textShadow can have a comma-delimited list) 19444 * @param {!Object} t target element 19445 * @param {(string|number|object)} b beginning value 19446 * @param {(string|number|object)} e ending (destination) value 19447 * @param {CSSPropTween=} pt next CSSPropTween in the linked list 19448 * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here. 19449 * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here. 19450 * @return {CSSPropTween=} First CSSPropTween in the linked list 19451 */ 19452 p.parseComplex = function (t, b, e, pt, plugin, setRatio) { 19453 var kwd = this.keyword, 19454 i, 19455 ba, 19456 ea, 19457 l, 19458 bi, 19459 ei; 19460 //if this SpecialProp's value can contain a comma-delimited list of values (like boxShadow or textShadow), we must parse them in a special way, and look for a keyword (like "inset" for boxShadow) and ensure that the beginning and ending BOTH have it if the end defines it as such. We also must ensure that there are an equal number of values specified (we can't tween 1 boxShadow to 3 for example) 19461 if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) { 19462 ba = b.replace(_commasOutsideParenExp, "|").split("|"); 19463 ea = e.replace(_commasOutsideParenExp, "|").split("|"); 19464 } else if (kwd) { 19465 ba = [b]; 19466 ea = [e]; 19467 } 19468 if (ea) { 19469 l = ea.length > ba.length ? ea.length : ba.length; 19470 for (i = 0; i < l; i++) { 19471 b = ba[i] = ba[i] || this.dflt; 19472 e = ea[i] = ea[i] || this.dflt; 19473 if (kwd) { 19474 bi = b.indexOf(kwd); 19475 ei = e.indexOf(kwd); 19476 if (bi !== ei) { 19477 if (ei === -1) { 19478 //if the keyword isn't in the end value, remove it from the beginning one. 19479 ba[i] = ba[i].split(kwd).join(""); 19480 } else if (bi === -1) { 19481 //if the keyword isn't in the beginning, add it. 19482 ba[i] += " " + kwd; 19483 } 19484 } 19485 } 19486 } 19487 b = ba.join(", "); 19488 e = ea.join(", "); 19489 } 19490 return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio); 19491 }; 19492 19493 /** 19494 * Accepts a target and end value and spits back a CSSPropTween that has been inserted into the CSSPlugin's linked list and conforms with all the conventions we use internally, like type:-1, 0, 1, or 2, setting up any extra property tweens, priority, etc. For example, if we have a boxShadow SpecialProp and call: 19495 * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this); 19496 * It should figure out the starting value of the element's boxShadow, compare it to the provided end value and create all the necessary CSSPropTweens of the appropriate types to tween the boxShadow. The CSSPropTween that gets spit back should already be inserted into the linked list (the 4th parameter is the current head, so prepend to that). 19497 * @param {!Object} t Target object whose property is being tweened 19498 * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object). 19499 * @param {!string} p Property name 19500 * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween. 19501 * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it) 19502 * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance. 19503 * @param {Object=} vars Original vars object that contains the data for parsing. 19504 * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call. 19505 */ 19506 p.parse = function (t, e, p, cssp, pt, plugin, vars) { 19507 return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin); 19508 }; 19509 19510 /** 19511 * Registers a special property that should be intercepted from any "css" objects defined in tweens. This allows you to handle them however you want without CSSPlugin doing it for you. The 2nd parameter should be a function that accepts 3 parameters: 19512 * 1) Target object whose property should be tweened (typically a DOM element) 19513 * 2) The end/destination value (could be a string, number, object, or whatever you want) 19514 * 3) The tween instance (you probably don't need to worry about this, but it can be useful for looking up information like the duration) 19515 * 19516 * Then, your function should return a function which will be called each time the tween gets rendered, passing a numeric "ratio" parameter to your function that indicates the change factor (usually between 0 and 1). For example: 19517 * 19518 * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) { 19519 * var start = target.style.width;
19520 * return function(ratio) { 19521 * target.style.width = (start + value * ratio) + "px"; 19522 * console.log("set width to " + target.style.width); 19523 * } 19524 * }, 0); 19525 * 19526 * Then, when I do this tween, it will trigger my special property: 19527 * 19528 * TweenLite.to(element, 1, {css:{myCustomProp:100}}); 19529 * 19530 * In the example, of course, we're just changing the width, but you can do anything you want. 19531 * 19532 * @param {!string} name Property name (or comma-delimited list of property names) that should be intercepted and handled by your function. For example, if I define "myCustomProp", then it would handle that portion of the following tween: TweenLite.to(element, 1, {css:{myCustomProp:100}}) 19533 * @param {!function(Object, Object, Object, string):function(number)} onInitTween The function that will be called when a tween of this special property is performed. The function will receive 4 parameters: 1) Target object that should be tweened, 2) Value that was passed to the tween, 3) The tween instance itself (rarely used), and 4) The property name that's being tweened. Your function should return a function that should be called on every update of the tween. That function will receive a single parameter that is a "change factor" value (typically between 0 and 1) indicating the amount of change as a ratio. You can use this to determine how to set the values appropriately in your function. 19534 * @param {number=} priority Priority that helps the engine determine the order in which to set the properties (default: 0). Higher priority properties will be updated before lower priority ones. 19535 */ 19536 CSSPlugin.registerSpecialProp = function (name, onInitTween, priority) { 19537 _registerComplexSpecialProp(name, { parser: function (t, e, p, cssp, pt, plugin, vars) { 19538 var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority); 19539 rv.plugin = plugin; 19540 rv.setRatio = onInitTween(t, e, cssp._tween, p); 19541 return rv; 19542 }, priority: priority }); 19543 }; 19544 19545 //transform-related methods and properties 19546 CSSPlugin.useSVGTransformAttr = true; //Safari and Firefox both have some rendering bugs when applying CSS transforms to SVG elements, so default to using the "transform" attribute instead (users can override this). 19547 var _transformProps = "scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent".split(","), 19548 _transformProp = _checkPropPrefix("transform"), 19549 //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform. 19550 _transformPropCSS = _prefixCSS + "transform", 19551 _transformOriginProp = _checkPropPrefix("transformOrigin"), 19552 _supports3D = _checkPropPrefix("perspective") !== null, 19553 Transform = _internals.Transform = function () { 19554 this.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0; 19555 this.force3D = CSSPlugin.defaultForce3D === false || !_supports3D ? false : CSSPlugin.defaultForce3D || "auto"; 19556 }, 19557 _SVGElement = _gsScope.SVGElement, 19558 _useSVGTransformAttr, 19559 19560 //Some browsers (like Firefox and IE) don't honor transform-origin properly in SVG elements, so we need to manually adjust the matrix accordingly. We feature detect here rather than always doing the conversion for certain browsers because they may fix the problem at some point in the future. 19561 19562 _createSVG = function (type, container, attributes) { 19563 var element = _doc.createElementNS("http://www.w3.org/2000/svg", type), 19564 reg = /([a-z])([A-Z])/g, 19565 p; 19566 for (p in attributes) { 19567 element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]); 19568 } 19569 container.appendChild(element); 19570 return element; 19571 }, 19572 _docElement = _doc.documentElement || {}, 19573 _forceSVGTransformAttr = function () { 19574 //IE and Android stock don't support CSS transforms on SVG elements, so we must write them to the "transform" attribute. We populate this variable in the _parseTransform() method, and only if/when we come across an SVG element 19575 var force = _ieVers || /Android/i.test(_agent) && !_gsScope.chrome, 19576 svg, 19577 rect, 19578 width; 19579 if (_doc.createElementNS && !force) { 19580 //IE8 and earlier doesn't support SVG anyway 19581 svg = _createSVG("svg", _docElement); 19582 rect = _createSVG("rect", svg, { width: 100, height: 50, x: 100 }); 19583 width = rect.getBoundingClientRect().width; 19584 rect.style[_transformOriginProp] = "50% 50%"; 19585 rect.style[_transformProp] = "scaleX(0.5)"; 19586 force = width === rect.getBoundingClientRect().width && !(_is
19586Firefox && _supports3D); //note: Firefox fails the test even though it does support CSS transforms in 3D. Since we can't push 3D stuff into the transform attribute, we force Firefox to pass the test here (as long as it does truly support 3D). 19587 _docElement.removeChild(svg); 19588 } 19589 return force; 19590 }(), 19591 _parseSVGOrigin = function (e, local, decoratee, absolute, smoothOrigin, skipRecord) { 19592 var tm = e._gsTransform, 19593 m = _getMatrix(e, true), 19594 v, 19595 x, 19596 y, 19597 xOrigin, 19598 yOrigin, 19599 a, 19600 b, 19601 c, 19602 d, 19603 tx, 19604 ty, 19605 determinant, 19606 xOriginOld, 19607 yOriginOld; 19608 if (tm) { 19609 xOriginOld = tm.xOrigin; //record the original values before we alter them. 19610 yOriginOld = tm.yOrigin; 19611 } 19612 if (!absolute || (v = absolute.split(" ")).length < 2) { 19613 b = e.getBBox(); 19614 if (b.x === 0 && b.y === 0 && b.width + b.height === 0) { 19615 //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case. 19616 b = { x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0, y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0, width: 0, height: 0 }; 19617 } 19618 local = _parsePosition(local).split(" "); 19619 v = [(local[0].indexOf("%") !== -1 ? parseFloat(local[0]) / 100 * b.width : parseFloat(local[0])) + b.x, (local[1].indexOf("%") !== -1 ? parseFloat(local[1]) / 100 * b.height : parseFloat(local[1])) + b.y]; 19620 } 19621 decoratee.xOrigin = xOrigin = parseFloat(v[0]); 19622 decoratee.yOrigin = yOrigin = parseFloat(v[1]); 19623 if (absolute && m !== _identity2DMatrix) { 19624 //if svgOrigin is being set, we must invert the matrix and determine where the absolute point is, factoring in the current transforms. Otherwise, the svgOrigin would be based on the element's non-transformed position on the canvas. 19625 a = m[0]; 19626 b = m[1]; 19627 c = m[2]; 19628 d = m[3]; 19629 tx = m[4]; 19630 ty = m[5]; 19631 determinant = a * d - b * c; 19632 if (determinant) { 19633 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero. 19634 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 19635 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 19636 xOrigin = decoratee.xOrigin = v[0] = x; 19637 yOrigin = decoratee.yOrigin = v[1] = y; 19638 } 19639 } 19640 if (tm) { 19641 //avoid jump when transformOrigin is changed - adjust the x/y values accordingly 19642 if (skipRecord) { 19643 decoratee.xOffset = tm.xOffset; 19644 decoratee.yOffset = tm.yOffset; 19645 tm = decoratee; 19646 } 19647 if (smoothOrigin || smoothOrigin !== false && CSSPlugin.defaultSmoothOrigin !== false) { 19648 x = xOrigin - xOriginOld; 19649 y = yOrigin - yOriginOld; 19650 //originally, we simply adjusted the x and y values, but that would cause problems if, for example, you created a rotational tween part-way through an x/y tween. Managing the offset in a separate variable gives us ultimate flexibility. 19651 //tm.x -= x - (x * m[0] + y * m[2]); 19652 //tm.y -= y - (x * m[1] + y * m[3]); 19653 tm.xOffset += x * m[0] + y * m[2] - x; 19654 tm.yOffset += x * m[1] + y * m[3] - y; 19655 } else { 19656 tm.xOffset = tm.yOffset = 0; 19657 } 19658 } 19659 if (!skipRecord) { 19660 e.setAttribute("data-svg-origin", v.join(" ")); 19661 } 19662 }, 19663 _getBBoxHack = function (swapIfPossible) { 19664 //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it). 19665 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 19666 oldParent = this.parentNode, 19667 oldSibling = this.nextSibling, 19668 oldCSS = this.style.cssText, 19669 bbox; 19670 _docElement.appendChild(svg); 19671 svg.appendChild(this); 19672 this.style.display = "block"; 19673 if (swapIfPossible) { 19674 try { 19675 bbox = this.getBBox(); 19676 this._originalGetBBox = this.getBBox; 19677 this.getBBox = _getBBoxHack; 19678 } catch (e) {} 19679 } else if (this._originalGetBBox) { 19680 bbox = this._originalGetBBox(); 19681 } 19682 if (oldSibling) { 19683 oldParent.insertBefore(this, oldSibling); 19684 } else { 19685 oldParent.appendChild(this); 19686 } 19687 _docElement.removeChild(svg); 19688 this.style.cssText = oldCSS; 19689 return bbox; 19690 }, 19691 _getBBox = function (e) { 19692 try { 19693 return e.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118 19694 } catch (error) { 19695 return _getBBoxHack.call(e, true); 19696 } 19697 }, 19698 _isSVG = function (e) { 19699 //reports if the element is an SVG on which getBBox() actually works 19700 return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 19701 }, 19702 _identity2DMatrix = [1, 0, 0, 1, 0, 0], 19703 _getMatrix = function (e, force2D) { 19704 var tm = e._gsTransform || new Transform(), 19705 rnd = 100000, 19706 style = e.style, 19707 isDefault, 19708 s, 19709 m, 19710 n, 19711 dec, 19712 none; 19713 if (_transformProp) { 19714 s = _getStyle(e, _transformPropCSS, null, true); 19715 } else if (e.currentStyle) { 19716 //for older versions of IE, we need to interpret the filter portion that is in the format: progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17, sizingMethod='auto expand') Notice that we need to swap b and c compared to a normal matrix. 19717 s = e.currentStyle.filter.match(_ieGetMatrixExp); 19718 s = s && s.length === 4 ? [s[0].substr(4), Number(s[2].substr(4)), Number(s[1].substr(4)), s[3].substr(4), tm.x || 0, tm.y || 0].join(",") : ""; 19719 }
19720 isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)"; 19721 if (_transformProp && ((none = !_getComputedStyle(e) || _getComputedStyle(e).display === "none") || !e.parentNode)) { 19722 //note: Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397 19723 if (none) { 19724 //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px). 19725 n = style.display; 19726 style.display = "block"; 19727 } 19728 if (!e.parentNode) { 19729 dec = 1; //flag 19730 _docElement.appendChild(e); 19731 } 19732 s = _getStyle(e, _transformPropCSS, null, true); 19733 isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)"; 19734 if (n) { 19735 style.display = n; 19736 } else if (none) { 19737 _removeProp(style, "display"); 19738 } 19739 if (dec) { 19740 _docElement.removeChild(e); 19741 } 19742 } 19743 if (tm.svg || e.getCTM && _isSVG(e)) { 19744 if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) { 19745 //some browsers (like Chrome 40) don't correctly report transforms that are applied inline on an SVG element (they don't get included in the computed style), so we double-check here and accept matrix values 19746 s = style[_transformProp]; 19747 isDefault = 0; 19748 } 19749 m = e.getAttribute("transform"); 19750 if (isDefault && m) { 19751 if (m.indexOf("matrix") !== -1) { 19752 //just in case there's a "transform" value specified as an attribute instead of CSS style. Accept either a matrix() or simple translate() value though. 19753 s = m; 19754 isDefault = 0; 19755 } else if (m.indexOf("translate") !== -1) { 19756 s = "matrix(1,0,0,1," + m.match(/(?:\-|\b)[\d\-\.e]+\b/gi).join(",") + ")"; 19757 isDefault = 0; 19758 } 19759 } 19760 } 19761 if (isDefault) { 19762 return _identity2DMatrix; 19763 } 19764 //split the matrix values out into an array (m for matrix) 19765 m = (s || "").match(_numExp) || []; 19766 i = m.length; 19767 while (--i > -1) { 19768 n = Number(m[i]); 19769 m[i] = (dec = n - (n |= 0)) ? (dec * rnd + (dec < 0 ? -0.5 : 0.5) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example). 19770 } 19771 return force2D && m.length > 6 ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m; 19772 }, 19773 19774 19775 /** 19776 * Parses the transform values for an element, returning an object with x, y, z, scaleX, scaleY, scaleZ, rotation, rotationX, rotationY, skewX, and skewY properties. Note: by default (for performance reasons), all skewing is combined into skewX and rotation but skewY still has a place in the transform object so that we can record how much of the skew is attributed to skewX vs skewY. Remember, a skewY of 10 looks the same as a rotation of 10 and skewX of -10. 19777 * @param {!Object} t target element 19778 * @param {Object=} cs computed style object (optional) 19779 * @param {boolean=} rec if true, the transform values will be recorded to the target element's _gsTransform object, like target._gsTransform = {x:0, y:0, z:0, scaleX:1...} 19780 * @param {boolean=} parse if true, we'll ignore any _gsTransform values that already exist on the element, and force a reparsing of the css (calculated style) 19781 * @return {object}
19781 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...} 19782 */ 19783 _getTransform = _internals.getTransform = function (t, cs, rec, parse) { 19784 if (t._gsTransform && rec && !parse) { 19785 return t._gsTransform; //if the element already has a _gsTransform, use that. Note: some browsers don't accurately return the calculated style for the transform (particularly for SVG), so it's almost always safest to just use the values we've already applied rather than re-parsing things. 19786 } 19787 var tm = rec ? t._gsTransform || new Transform() : new Transform(), 19788 invX = tm.scaleX < 0, 19789 //in order to interpret things properly, we need to know if the user applied a negative scaleX previously so that we can adjust the rotation and skewX accordingly. Otherwise, if we always interpret a flipped matrix as affecting scaleY and the user only wants to tween the scaleX on multiple sequential tweens, it would keep the negative scaleY without that being the user's intent. 19790 min = 0.00002, 19791 rnd = 100000, 19792 zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin || 0 : 0, 19793 defaultTransformPerspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0, 19794 m, 19795 i, 19796 scaleX, 19797 scaleY, 19798 rotation, 19799 skewX; 19800 19801 tm.svg = !!(t.getCTM && _isSVG(t)); 19802 if (tm.svg) { 19803 _parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin")); 19804 _useSVGTransformAttr = CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr; 19805 } 19806 m = _getMatrix(t); 19807 if (m !== _identity2DMatrix) { 19808 19809 if (m.length === 16) { 19810 //we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values) 19811 var a11 = m[0], 19812 a21 = m[1], 19813 a31 = m[2], 19814 a41 = m[3], 19815 a12 = m[4], 19816 a22 = m[5], 19817 a32 = m[6], 19818 a42 = m[7], 19819 a13 = m[8], 19820 a23 = m[9], 19821 a33 = m[10], 19822 a14 = m[12], 19823 a24 = m[13], 19824 a34 = m[14], 19825 a43 = m[11], 19826 angle = Math.atan2(a32, a33), 19827 t1, 19828 t2, 19829 t3, 19830 t4, 19831 cos, 19832 sin; 19833 //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari 19834 if (tm.zOrigin) { 19835 a34 = -tm.zOrigin; 19836 a14 = a13 * a34 - m[12]; 19837 a24 = a23 * a34 - m[13]; 19838 a34 = a33 * a34 + tm.zOrigin - m[14]; 19839 } 19840 //note for possible future consolidation: rotationX: Math.atan2(a32, a33), rotationY: Math.atan2(-a31, Math.sqrt(a33 * a33 + a32 * a32)), rotation: Math.atan2(a21, a11), skew: Math.atan2(a12, a22). However, it doesn't seem to be quite as reliable as the full-on backwards rotation procedure. 19841 tm.rotationX = angle * _RAD2DEG; 19842 //rotationX 19843 if (angle) { 19844 cos = Math.cos(-angle); 19845 sin = Math.sin(-angle); 19846 t1 = a12 * cos + a13 * sin; 19847 t2 = a22 * cos + a23 * sin; 19848 t3 = a32 * cos + a33 * sin; 19849 a13 = a12 * -sin + a13 * cos; 19850 a23 = a22 * -sin + a23 * cos; 19851 a33 = a32 * -sin + a33 * cos; 19852 a43 = a42 * -sin + a43 * cos; 19853 a12 = t1; 19854 a22 = t2; 19855 a32 = t3; 19856 } 19857 //rotationY 19858 angle = Math.atan2(-a31, a33); 19859 tm.rotationY = angle * _RAD2DEG; 19860 if (angle) { 19861 cos = Math.cos(-angle); 19862 sin = Math.sin(-angle); 19863 t1 = a11 * cos - a13 * sin; 19864 t2 = a21 * cos - a23 * sin; 19865 t3 = a31 * cos - a33 * sin; 19866 a23 = a21 * sin + a23 * cos; 19867 a33 = a31 * sin + a33 * cos; 19868 a43 = a41 * sin + a43 * cos; 19869 a11 = t1; 19870 a21 = t2; 19871 a31 = t3; 19872 } 19873 //rotationZ 19874 angle = Math.atan2(a21, a11); 19875 tm.rotation = angle * _RAD2DEG; 19876 if (angle) { 19877 cos = Math.cos(angle); 19878 sin = Math.sin(angle); 19879 t1 = a11 * cos + a21 * sin; 19880 t2 = a12 * cos + a22 * sin; 19881 t3 = a13 * cos + a23 * sin; 19882 a21 = a21 * cos - a11 * sin; 19883 a22 = a22 * cos - a12 * sin; 19884 a23 = a23 * cos - a13 * sin; 19885 a11 = t1; 19886 a12 = t2; 19887 a13 = t3; 19888 } 19889 19890 if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) { 19891 //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here. 19892 tm.rotationX = tm.rotation = 0; 19893 tm.rotationY = 180 - tm.rotationY; 19894 } 19895 19896 //skewX 19897 angle = Math.atan2(a12, a22); 19898 19899 //scales 19900 tm.scaleX = (Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5 | 0) / rnd; 19901 tm.scaleY = (Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5 | 0) / rnd; 19902 tm.scaleZ = (Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5 | 0) / rnd; 19903 a11 /= tm.scaleX; 19904 a12 /= tm.scaleY; 19905 a21 /= tm.scaleX; 19906 a22 /= tm.scaleY; 19907 if (Math.abs(angle) > min) { 19908 tm.skewX = angle * _RAD2DEG; 19909 a12 = 0;
19909 //unskews 19910 if (tm.skewType !== "simple") { 19911 tm.scaleY *= 1 / Math.cos(angle); //by default, we compensate the scale based on the skew so that the element maintains a similar proportion when skewed, so we have to alter the scaleY here accordingly to match the default (non-adjusted) skewing that CSS does (stretching more and more as it skews). 19912 } 19913 } else { 19914 tm.skewX = 0; 19915 } 19916 19917 /* //for testing purposes 19918 var transform = "matrix3d(", 19919 comma = ",", 19920 zero = "0"; 19921 a13 /= tm.scaleZ; 19922 a23 /= tm.scaleZ; 19923 a31 /= tm.scaleX; 19924 a32 /= tm.scaleY; 19925 a33 /= tm.scaleZ; 19926 transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31); 19927 transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22); 19928 transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13); 19929 transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma; 19930 transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")"; 19931 console.log(transform); 19932 document.querySelector(".test").style[_transformProp] = transform; 19933 */ 19934 19935 tm.perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 19936 tm.x = a14; 19937 tm.y = a24; 19938 tm.z = a34; 19939 if (tm.svg) { 19940 tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12); 19941 tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22); 19942 } 19943 } else if (!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || !tm.rotationX && !tm.rotationY) { 19944 //sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those. 19945 var k = m.length >= 6, 19946 a = k ? m[0] : 1, 19947 b = m[1] || 0, 19948 c = m[2] || 0, 19949 d = k ? m[3] : 1; 19950 tm.x = m[4] || 0; 19951 tm.y = m[5] || 0; 19952 scaleX = Math.sqrt(a * a + b * b); 19953 scaleY = Math.sqrt(d * d + c * c); 19954 rotation = a || b ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist). 19955 skewX = c || d ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0; 19956 tm.scaleX = scaleX; 19957 tm.scaleY = scaleY; 19958 tm.rotation = rotation; 19959 tm.skewX = skewX; 19960 if (_supports3D) { 19961 tm.rotationX = tm.rotationY = tm.z = 0; 19962 tm.perspective = defaultTransformPerspective; 19963 tm.scaleZ = 1; 19964 } 19965 if (tm.svg) { 19966 tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c); 19967 tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d); 19968 } 19969 } 19970 if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) { 19971 if (invX) { 19972 tm.scaleX *= -1; 19973 tm.skewX += tm.rotation <= 0 ? 180 : -180; 19974 tm.rotation += tm.rotation <= 0 ? 180 : -180; 19975 } else { 19976 tm.scaleY *= -1; 19977 tm.skewX += tm.skewX <= 0 ? 180 : -180; 19978 } 19979 } 19980 tm.zOrigin = zOrigin;
19981 //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate. 19982 for (i in tm) { 19983 if (tm[i] < min) if (tm[i] > -min) { 19984 tm[i] = 0; 19985 } 19986 } 19987 } 19988 //DEBUG: _log("parsed rotation of " + t.getAttribute("id")+": "+(tm.rotationX)+", "+(tm.rotationY)+", "+(tm.rotation)+", scale: "+tm.scaleX+", "+tm.scaleY+", "+tm.scaleZ+", position: "+tm.x+", "+tm.y+", "+tm.z+", perspective: "+tm.perspective+ ", origin: "+ tm.xOrigin+ ","+ tm.yOrigin); 19989 if (rec) { 19990 t._gsTransform = tm; //record to the object's _gsTransform which we use so that tweens can control individual properties independently (we need all the properties to accurately recompose the matrix in the setRatio() method) 19991 if (tm.svg) { 19992 //if we're supposed to apply transforms to the SVG element's "transform" attribute, make sure there aren't any CSS transforms applied or they'll override the attribute ones. Also clear the transform attribute if we're using CSS, just to be clean. 19993 if (_useSVGTransformAttr && t.style[_transformProp]) { 19994 TweenLite.delayedCall(0.001, function () { 19995 //if we apply this right away (before anything has rendered), we risk there being no transforms for a brief moment and it also interferes with adjusting the transformOrigin in a tween with immediateRender:true (it'd try reading the matrix and it wouldn't have the appropriate data in place because we just removed it). 19996 _removeProp(t.style, _transformProp); 19997 }); 19998 } else if (!_useSVGTransformAttr && t.getAttribute("transform")) { 19999 TweenLite.delayedCall(0.001, function () { 20000 t.removeAttribute("transform"); 20001 }); 20002 } 20003 } 20004 } 20005 return tm; 20006 }, 20007 20008 20009 //for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms) 20010 _setIETransformRatio = function (v) { 20011 var t = this.data, 20012 //refers to the element's _gsTransform object 20013 ang = -t.rotation * _DEG2RAD, 20014 skew = ang + t.skewX * _DEG2RAD, 20015 rnd = 100000, 20016 a = (Math.cos(ang) * t.scaleX * rnd | 0) / rnd, 20017 b = (Math.sin(ang) * t.scaleX * rnd | 0) / rnd, 20018 c = (Math.sin(skew) * -t.scaleY * rnd | 0) / rnd, 20019 d = (Math.cos(skew) * t.scaleY * rnd | 0) / rnd, 20020 style = this.t.style, 20021 cs = this.t.currentStyle, 20022 filters, 20023 val; 20024 if (!cs) { 20025 return; 20026 } 20027 val = b; //just for swapping the variables an inverting them (reused "val" to avoid creating another variable in memory). IE's filter matrix uses a non-standard matrix configuration (angle goes the opposite way, and b and c are reversed and inverted) 20028 b = -c; 20029 c = -val; 20030 filters = cs.filter; 20031 style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight 20032 var w = this.t.offsetWidth, 20033 h = this.t.offsetHeight, 20034 clip = cs.position !== "absolute", 20035 m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d, 20036 ox = t.x + w * t.xPercent / 100, 20037 oy = t.y + h * t.yPercent / 100, 20038 dx, 20039 dy; 20040 20041 //if transformOrigin is being used, adjust the offset x and y 20042 if (t.ox != null) { 20043 dx = (t.oxp ? w * t.ox * 0.01 : t.ox) - w / 2; 20044 dy = (t.oyp ? h * t.oy * 0.01 : t.oy) - h / 2; 20045 ox += dx - (dx * a + dy * b); 20046 oy += dy - (dx * c + dy * d); 20047 } 20048 20049 if (!clip) { 20050 m += ", sizingMethod='auto expand')"; 20051 } else { 20052 dx = w / 2; 20053 dy = h / 2; 20054 //translate to ensure that transformations occur around the correct origin (default is center). 20055 m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")"; 20056 } 20057 if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) { 20058 style.filter = filters.replace(_ieSetMatrixExp, m); 20059 } else { 20060 style.filter = m + " " + filters;
20060 //we must always put the transform/matrix FIRST (before alpha(opacity=xx)) to avoid an IE bug that slices part of the object when rotation is applied with alpha. 20061 } 20062 20063 //at the end or beginning of the tween, if the matrix is normal (1, 0, 0, 1) and opacity is 100 (or doesn't exist), remove the filter to improve browser performance. 20064 if (v === 0 || v === 1) if (a === 1) if (b === 0) if (c === 0) if (d === 1) if (!clip || m.indexOf("Dx=0, Dy=0") !== -1) if (!_opacityExp.test(filters) || parseFloat(RegExp.$1) === 100) if (filters.indexOf("gradient(" && filters.indexOf("Alpha")) === -1) { 20065 style.removeAttribute("filter"); 20066 } 20067 20068 //we must set the margins AFTER applying the filter in order to avoid some bugs in IE8 that could (in rare scenarios) cause them to be ignored intermittently (vibration). 20069 if (!clip) { 20070 var mult = _ieVers < 8 ? 1 : -1, 20071 //in Internet Explorer 7 and before, the box model is broken, causing the browser to treat the width/height of the actual rotated filtered image as the width/height of the box itself, but Microsoft corrected that in IE8. We must use a negative offset in IE8 on the right/bottom 20072 marg, 20073 prop, 20074 dif; 20075 dx = t.ieOffsetX || 0; 20076 dy = t.ieOffsetY || 0; 20077 t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox); 20078 t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy); 20079 for (i = 0; i < 4; i++) { 20080 prop = _margins[i]; 20081 marg = cs[prop]; 20082 //we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes) 20083 val = marg.indexOf("px") !== -1 ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0; 20084 if (val !== t[prop]) { 20085 dif = i < 2 ? -t.ieOffsetX : -t.ieOffsetY; //if another tween is controlling a margin, we cannot only apply the difference in the ieOffsets, so we essentially zero-out the dx and dy here in that case. We record the margin(s) later so that we can keep comparing them, making this code very flexible. 20086 } else { 20087 dif = i < 2 ? dx - t.ieOffsetX : dy - t.ieOffsetY; 20088 } 20089 style[prop] = (t[prop] = Math.round(val - dif * (i === 0 || i === 2 ? 1 : mult))) + "px"; 20090 } 20091 } 20092 }, 20093 20094 20095 /* translates a super small decimal to a string WITHOUT scientific notation 20096 _safeDecimal = function(n) { 20097 var s = (n < 0 ? -n : n) + "", 20098 a = s.split("e-"); 20099 return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join(""); 20100 }, 20101 */ 20102 20103 _setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function (v) { 20104 var t = this.data, 20105 //refers to the element's _gsTransform object 20106 style = this.t.style, 20107 angle = t.rotation, 20108 rotationX = t.rotationX, 20109 rotationY = t.rotationY, 20110 sx = t.scaleX, 20111 sy = t.scaleY, 20112 sz = t.scaleZ, 20113 x = t.x, 20114 y = t.y, 20115 z = t.z, 20116 isSVG = t.svg, 20117 perspective = t.perspective, 20118 force3D = t.force3D, 20119 skewY = t.skewY, 20120 skewX = t.skewX, 20121 t1, 20122 a11, 20123 a12, 20124 a13, 20125 a21, 20126 a22, 20127 a23, 20128 a31, 20129 a32, 20130 a33, 20131 a41, 20132 a42, 20133 a43, 20134 zOrigin, 20135 min, 20136 cos, 20137 sin, 20138 t2, 20139 transform, 20140 comma, 20141 zero, 20142 skew, 20143 rnd; 20144 if (skewY) { 20145 //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees. 20146 skewX += skewY; 20147 angle += skewY; 20148 } 20149 20150 //check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true) 20151 if (((v === 1 || v === 0) && force3D === "auto" && (this.tween._totalTime === this.tween._totalDuration || !this.tween._totalTime) || !force3D) && !z && !perspective && !rotationY && !rotationX && sz === 1 || _useSVGTransformAttr && isSVG || !_supports3D) { 20152 //on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices. Check the tween's totalTime/totalDuration too in order to make sure it doesn't happen between repeats if it's a repeating tween. 20153 20154 //2D 20155 if (angle || skewX || isSVG) { 20156 angle *= _DEG2RAD; 20157 skew = skewX * _DEG2RAD; 20158 rnd = 100000; 20159 a11 = Math.cos(angle) * sx; 20160 a21 = Math.sin(angle) * sx; 20161 a12 = Math.sin(angle - skew) * -sy;
20162 a22 = Math.cos(angle - skew) * sy; 20163 if (skew && t.skewType === "simple") { 20164 //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does 20165 t1 = Math.tan(skew - skewY * _DEG2RAD); 20166 t1 = Math.sqrt(1 + t1 * t1); 20167 a12 *= t1; 20168 a22 *= t1; 20169 if (skewY) { 20170 t1 = Math.tan(skewY * _DEG2RAD); 20171 t1 = Math.sqrt(1 + t1 * t1); 20172 a11 *= t1; 20173 a21 *= t1; 20174 } 20175 } 20176 if (isSVG) { 20177 x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset; 20178 y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset; 20179 if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) { 20180 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it. 20181 min = this.t.getBBox(); 20182 x += t.xPercent * 0.01 * min.width; 20183 y += t.yPercent * 0.01 * min.height; 20184 } 20185 min = 0.000001; 20186 if (x < min) if (x > -min) { 20187 x = 0; 20188 } 20189 if (y < min) if (y > -min) { 20190 y = 0; 20191 } 20192 } 20193 transform = (a11 * rnd | 0) / rnd + "," + (a21 * rnd | 0) / rnd + "," + (a12 * rnd | 0) / rnd + "," + (a22 * rnd | 0) / rnd + "," + x + "," + y + ")"; 20194 if (isSVG && _useSVGTransformAttr) {
20195 this.t.setAttribute("transform", "matrix(" + transform); 20196 } else { 20197 //some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 5 decimal places. 20198 style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform; 20199 } 20200 } else { 20201 style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")"; 20202 } 20203 return; 20204 } 20205 if (_isFirefox) { 20206 //Firefox has a bug (at least in v25) that causes it to render the transparent part of 32-bit PNG images as black when displayed inside an iframe and the 3D scale is very small and doesn't change sufficiently enough between renders (like if you use a Power4.easeInOut to scale from 0 to 1 where the beginning values only change a tiny amount to begin the tween before accelerating). In this case, we force the scale to be 0.00002 instead which is visually the same but works around the Firefox issue. 20207 min = 0.0001; 20208 if (sx < min && sx > -min) { 20209 sx = sz = 0.00002; 20210 } 20211 if (sy < min && sy > -min) { 20212 sy = sz = 0.00002; 20213 } 20214 if (perspective && !t.z && !t.rotationX && !t.rotationY) { 20215 //Firefox has a bug that causes elements to have an odd super-thin, broken/dotted black border on elements that have a perspective set but aren't utilizing 3D space (no rotationX, rotationY, or z). 20216 perspective = 0; 20217 } 20218 }
20219 if (angle || skewX) { 20220 angle *= _DEG2RAD; 20221 cos = a11 = Math.cos(angle); 20222 sin = a21 = Math.sin(angle); 20223 if (skewX) { 20224 angle -= skewX * _DEG2RAD; 20225 cos = Math.cos(angle); 20226 sin = Math.sin(angle); 20227 if (t.skewType === "simple") { 20228 //by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does 20229 t1 = Math.tan((skewX - skewY) * _DEG2RAD); 20230 t1 = Math.sqrt(1 + t1 * t1); 20231 cos *= t1; 20232 sin *= t1; 20233 if (t.skewY) { 20234 t1 = Math.tan(skewY * _DEG2RAD); 20235 t1 = Math.sqrt(1 + t1 * t1); 20236 a11 *= t1; 20237 a21 *= t1; 20238 } 20239 } 20240 } 20241 a12 = -sin; 20242 a22 = cos; 20243 } else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) { 20244 //if we're only translating and/or 2D scaling, this is faster... 20245 style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) translate3d(" : "translate3d(") + x + "px," + y + "px," + z + "px)" + (sx !== 1 || sy !== 1 ? " scale(" + sx + "," + sy + ")" : ""); 20246 return; 20247 } else { 20248 a11 = a22 = 1; 20249 a12 = a21 = 0; 20250 } 20251 // KEY INDEX AFFECTS a[row][column] 20252 // a11 0 rotation, rotationY, scaleX 20253 // a21 1 rotation, rotationY, scaleX 20254 // a31 2 rotationY, scaleX 20255 // a41 3 rotationY, scaleX 20256 // a12 4 rotation, skewX, rotationX, scaleY 20257 // a22 5 rotation, skewX, rotationX, scaleY 20258 // a32 6 rotationX, scaleY 20259 // a42 7 rotationX, scaleY 20260 // a13 8 rotationY, rotationX, scaleZ 20261 // a23 9 rotationY, rotationX, scaleZ 20262 // a33 10 rotationY, rotationX, scaleZ 20263 // a43 11 rotationY, rotationX, perspective, scaleZ 20264 // a14 12 x, zOrigin, svgOrigin 20265 // a24 13 y, zOrigin, svgOrigin 20266 // a34 14 z, zOrigin 20267 // a44 15 20268 // rotation: Math.atan2(a21, a11) 20269 // rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11)) 20270 // rotationX: Math.atan2(a32, a33) 20271 a33 = 1; 20272 a13 = a23 = a31 = a32 = a41 = a42 = 0; 20273 a43 = perspective ? -1 / perspective : 0; 20274 zOrigin = t.zOrigin; 20275 min = 0.000001; //threshold below which browsers use scientific notation which won't work. 20276 comma = ","; 20277 zero = "0"; 20278 angle = rotationY * _DEG2RAD; 20279 if (angle) { 20280 cos = Math.cos(angle); 20281 sin = Math.sin(angle); 20282 a31 = -sin; 20283 a41 = a43 * -sin; 20284 a13 = a11 * sin; 20285 a23 = a21 * sin; 20286 a33 = cos; 20287 a43 *= cos; 20288 a11 *= cos; 20289 a21 *= cos; 20290 } 20291 angle = rotationX * _DEG2RAD; 20292 if (angle) { 20293 cos = Math.cos(angle); 20294 sin = Math.sin(angle); 20295 t1 = a12 * cos + a13 * sin; 20296 t2 = a22 * cos + a23 * sin; 20297 a32 = a33 * sin; 20298 a42 = a43 * sin; 20299 a13 = a12 * -sin + a13 * cos; 20300 a23 = a22 * -sin + a23 * cos; 20301 a33 = a33 * cos; 20302 a43 = a43 * cos; 20303 a12 = t1; 20304 a22 = t2; 20305 } 20306 if (sz !== 1) { 20307 a13 *= sz; 20308 a23 *= sz; 20309 a33 *= sz; 20310 a43 *= sz; 20311 } 20312 if (sy !== 1) { 20313 a12 *= sy; 20314 a22 *= sy; 20315 a32 *= sy; 20316 a42 *= sy; 20317 } 20318 if (sx !== 1) { 20319 a11 *= sx; 20320 a21 *= sx; 20321 a31 *= sx; 20322 a41 *= sx; 20323 } 20324 20325 if (zOrigin || isSVG) { 20326 if (zOrigin) { 20327 x += a13 * -zOrigin; 20328 y += a23 * -zOrigin; 20329 z += a33 * -zOrigin + zOrigin; 20330 } 20331 if (isSVG) { 20332 //due to bugs in some browsers, we need to manage the transform-origin of SVG manually 20333 x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset; 20334 y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset; 20335 } 20336 if (x < min && x > -min) { 20337 x = zero; 20338 } 20339 if (y < min && y > -min) { 20340 y = zero; 20341 } 20342 if (z < min && z > -min) { 20343 z = 0; //don't use string because we calculate perspective later and need the number. 20344 } 20345 } 20346 20347 //optimized way of concatenating all the values into a string. If we do it all in one shot, it's slower because of the way browsers have to create temp strings and the way it affects memory. If we do it piece-by-piece with +=, it's a bit slower too. We found that doing it in these sized chunks works best overall: 20348 transform = t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d("; 20349 transform += (a11 < min && a11 > -min ? zero : a11) + comma + (a21 < min && a21 > -min ? zero : a21) + comma + (a31 < min && a31 > -min ? zero : a31); 20350 transform += comma + (a41 < min && a41 > -min ? zero : a41) + comma + (a12 < min && a12 > -min ? zero : a12) + comma + (a22 < min && a22 > -min ? zero : a22); 20351 if (rotationX || rotationY || sz !== 1) { 20352 //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations) 20353 transform += comma + (a32 < min && a32 > -min ? zero : a32) + comma + (a42 < min && a42 > -min ? zero : a42) + comma + (a13 < min && a13 > -min ? zero : a13); 20354 transform += comma + (a23 < min && a23 > -min ? zero : a23) + comma + (a33 < min && a33 > -min ? zero : a33) + comma + (a43 < min && a43 > -min ? zero : a43) + comma; 20355 } else { 20356 transform += ",0,0,0,0,1,0,"; 20357 } 20358 transform += x + comma + y + comma + z + comma + (perspective ? 1 + -z / perspective : 1) + ")"; 20359 20360 style[_transformProp] = transform; 20361 }; 20362 20363 p = Transform.prototype; 20364 p.x = p.y = p.z = p.skewX = p.skewY = p.rotation = p.rotationX = p.rotationY = p.zOrigin = p.xPercent = p.yPercent = p.xOffset = p.yOffset = 0; 20365 p.scaleX = p.scaleY = p.scaleZ = 1; 20366 20367 _registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,svgOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent,smoothOrigin", { parser: function (t, e, parsingProp, cssp, pt, plugin, vars) { 20368 if (cssp._lastParsedTransform === vars) { 20369 return pt; 20370 } //only need to parse the transform once, and only if the browser supports it. 20371 cssp._lastParsedTransform = vars; 20372 var scaleFunc = vars.scale && typeof vars.scale === "function" ? vars.scale : 0, 20373 //if there's a function-based "scale" value, swap in the resulting numeric value temporarily. Otherwise, if it's called for both scaleX and scaleY independently, they may not match (like if the function uses Math.random()). 20374 swapFunc; 20375 if (typeof vars[parsingProp] === "function") { 20376 //whatever property triggers the initial parsing might be a function-based value in which case it already got called in parse(), thus we don't want to call it again in here. The most efficient way to avoid this is to temporarily swap the value directly into the vars object, and then after we do all our parsing in this function, we'll swap it back again. 20377 swapFunc = vars[parsingProp]; 20378 vars[parsingProp] = e; 20379 } 20380 if (scaleFunc) { 20381 vars.scale = scaleFunc(_index, t); 20382 } 20383 var originalGSTransform = t._gsTransform, 20384 style = t.style, 20385 min = 0.000001, 20386 i = _transformProps.length, 20387 v = vars, 20388 endRotations = {}, 20389 transformOriginString = "transformOrigin", 20390 m1 = _getTransform(t, _cs, true, v.parseTransform), 20391 orig = v.transform && (typeof v.transform === "function" ? v.transform(_index, _target) : v.transform), 20392 m2, 20393 copy, 20394 has3D, 20395 hasChange, 20396 dr, 20397 x, 20398 y, 20399 matrix, 20400 p; 20401 m1.skewType = v.skewType || m1.skewType || CSSPlugin.defaultSkewType; 20402 cssp._transform = m1; 20403 if (orig && typeof orig === "string" && _transformProp) { 20404 //for values like transform:"rotate(60deg) scale(0.5, 0.8)" 20405 copy = _tempDiv.style; //don't use the original target because it might be SVG in which case some browsers don't report computed style correctly. 20406 copy[_transformProp] = orig; 20407 copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly. 20408 copy.position = "absolute"; 20409 _doc.body.appendChild(_tempDiv); 20410 m2 = _getTransform(_tempDiv, null, false); 20411 if (m1.skewType === "simple") { 20412 //the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple". 20413 m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD); 20414 } 20415 if (m1.svg) { 20416 //if it's an SVG element, x/y part of the matrix will be affected by whatever we use as the origin and the offsets, so compensate here... 20417 x = m1.xOrigin; 20418 y = m1.yOrigin; 20419 m2.x -= m1.xOffset; 20420 m2.y -= m1.yOffset; 20421 if (v.transformOrigin || v.svgOrigin) { 20422 //if this tween is altering the origin, we must factor that in here. The actual work of recording the transformOrigin values and setting up the PropTween is done later (still inside this function) so we cannot leave the changes intact here - we only want to update the x/y accordingly. 20423 orig = {}; 20424 _parseSVGOrigin(t, _parsePosition(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true); 20425 x = orig.xOrigin; 20426 y = orig.yOrigin; 20427 m2.x -= orig.xOffset - m1.xOffset; 20428 m2.y -= orig.yOffset - m1.yOffset; 20429 } 20430 if (x || y) { 20431 matrix = _getMatrix(_tempDiv, true); 20432 m2.x -= x - (x * matrix[0] + y * matrix[2]); 20433 m2.y -= y - (x * matrix[1] + y * matrix[3]); 20434 } 20435 } 20436 _doc.body.removeChild(_tempDiv); 20437 if (!m2.perspective) { 20438 m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case. 20439 } 20440 if (v.xPercent != null) { 20441 m2.xPercent = _parseVal(v.xPercent, m1.xPercent); 20442 } 20443 if (v.yPercent != null) { 20444 m2.yPercent = _parseVal(v.yPercent, m1.yPercent); 20445 } 20446 } else if (typeof v === "object") { 20447 //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object) 20448 m2 = { scaleX: _parseVal(v.scaleX != null ? v.scaleX : v.scale, m1.scaleX), 20449 scaleY: _parseVal(v.scaleY != null ? v.scaleY : v.scale, m1.scaleY), 20450 scaleZ: _parseVal(v.scaleZ, m1.scaleZ), 20451 x: _parseVal(v.x, m1.x), 20452 y: _parseVal(v.y, m1.y), 20453 z: _parseVal(v.z, m1.z), 20454 xPercent: _parseVal(v.xPercent, m1.xPercent), 20455 yPercent: _parseVal(v.yPercent, m1.yPercent), 20456 perspective: _parseVal(v.transformPerspective, m1.perspective) }; 20457 dr = v.directionalRotation; 20458 if (dr != null) { 20459 if (typeof dr === "object") { 20460 for (copy in dr) { 20461 v[copy] = dr[copy]; 20462 } 20463 } else { 20464 v.rotation = dr; 20465 } 20466 } 20467 if (typeof v.x === "string" && v.x.indexOf("%") !== -1) { 20468 m2.x = 0; 20469 m2.xPercent = _parseVal(v.x, m1.xPercent); 20470 } 20471 if (typeof v.y === "string" && v.y.indexOf("%") !== -1) { 20472 m2.y = 0; 20473 m2.yPercent = _parseVal(v.y, m1.yPercent); 20474 } 20475 20476 m2.rotation = _parseAngle("rotation" in v ? v.rotation : "shortRotation" in v ? v.shortRotation + "_short" : "rotationZ" in v ? v.rotationZ : m1.rotation, m1.rotation, "rotation", endRotations); 20477 if (_supports3D) { 20478 m2.rotationX = _parseAngle("rotationX" in v ? v.rotationX : "shortRotationX" in v ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations); 20479 m2.rotationY = _parseAngle("rotationY" in v ? v.rotationY : "shortRotationY" in v ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations); 20480 }
20481 m2.skewX = _parseAngle(v.skewX, m1.skewX); 20482 m2.skewY = _parseAngle(v.skewY, m1.skewY); 20483 } 20484 if (_supports3D && v.force3D != null) { 20485 m1.force3D = v.force3D; 20486 hasChange = true; 20487 } 20488 20489 has3D = m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective; 20490 if (!has3D && v.scale != null) { 20491 m2.scaleZ = 1; //no need to tween scaleZ. 20492 } 20493 20494 while (--i > -1) { 20495 p = _transformProps[i]; 20496 orig = m2[p] - m1[p]; 20497 if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) { 20498 hasChange = true; 20499 pt = new CSSPropTween(m1, p, m1[p], orig, pt); 20500 if (p in endRotations) { 20501 pt.e = endRotations[p]; //directional rotations typically have compensated values during the tween, but we need to make sure they end at exactly what the user requested 20502 } 20503 pt.xs0 = 0; //ensures the value stays numeric in setRatio() 20504 pt.plugin = plugin; 20505 cssp._overwriteProps.push(pt.n); 20506 } 20507 } 20508 20509 orig = v.transformOrigin; 20510 if (m1.svg && (orig || v.svgOrigin)) { 20511 x = m1.xOffset; //when we change the origin, in order to prevent things from jumping we adjust the x/y so we must record those here so that we can create PropTweens for them and flip them at the same time as the origin 20512 y = m1.yOffset; 20513 _parseSVGOrigin(t, _parsePosition(orig), m2, v.svgOrigin, v.smoothOrigin); 20514 pt = _addNonTweeningNumericPT(m1, "xOrigin", (originalGSTransform ? m1 : m2).xOrigin, m2.xOrigin, pt, transformOriginString); //note: if there wasn't a transformOrigin defined yet, just start with the destination one; it's wasteful otherwise, and it causes problems with fromTo() tweens. For example, TweenLite.to("#wheel", 3, {rotation:180, transformOrigin:"50% 50%", delay:1}); TweenLite.fromTo("#wheel", 3, {scale:0.5, transformOrigin:"50% 50%"}, {scale:1, delay:2}); would cause a jump when the from values revert at the beginning of the 2nd tween. 20515 pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString); 20516 if (x !== m1.xOffset || y !== m1.yOffset) { 20517 pt = _addNonTweeningNumericPT(m1, "xOffset", originalGSTransform ? x : m1.xOffset, m1.xOffset, pt, transformOriginString); 20518 pt = _addNonTweeningNumericPT(m1, "yOffset", originalGSTransform ? y : m1.yOffset, m1.yOffset, pt, transformOriginString); 20519 } 20520 orig = "0px 0px"; //certain browsers (like firefox) completely botch transform-origin, so we must remove it to prevent it from contaminating transforms. We manage it ourselves with xOrigin and yOrigin 20521 } 20522 if (orig || _supports3D && has3D && m1.zOrigin) { 20523 //if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly). 20524 if (_transformProp) { 20525 hasChange = true; 20526 p = _transformOriginProp; 20527 orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors 20528 pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString); 20529 pt.b = style[p]; 20530 pt.plugin = plugin; 20531 if (_supports3D) { 20532 copy = m1.zOrigin; 20533 orig = orig.split(" "); 20534 m1.zOrigin = (orig.length > 2 && !(copy !== 0 && orig[2] === "0px") ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method. 20535 pt.xs0 = pt.e = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)! 20536 pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here) 20537 pt.b = copy; 20538 pt.xs0 = pt.e = m1.zOrigin; 20539 } else { 20540 pt.xs0 = pt.e = orig; 20541 } 20542 20543 //for older versions of IE (6-8), we need to manually calculate things inside the setRatio() function. We record origin x and y (ox and oy) and whether or not the values are percentages (oxp and oyp). 20544 } else { 20545 _parsePosition(orig + "", m1); 20546 } 20547 } 20548 if (hasChange) { 20549 cssp._transformType = !(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3) ? 3 : 2; //quicker than calling cssp._enableTransforms(); 20550 } 20551 if (swapFunc) { 20552 vars[parsingProp] = swapFunc; 20553 } 20554 if (scaleFunc) { 20555 vars.scale = scaleFunc; 20556 } 20557 return pt; 20558 }, prefix: true }); 20559 20560 _registerComplexSpecialProp("boxShadow", { defaultValue: "0px 0px 0px 0px #999", prefix: true, color: true, multi: true, keyword: "inset" }); 20561 20562 _registerComplexSpecialProp("borderRadius", { defaultValue: "0px", parser: function (t, e, p, cssp, pt, plugin) { 20563 e = this.format(e); 20564 var props = ["borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"], 20565 style = t.style, 20566 ea1, 20567 i, 20568 es2, 20569 bs2, 20570 bs, 20571 es, 20572 bn, 20573 en, 20574 w, 20575 h, 20576 esfx, 20577 bsfx, 20578 rel, 20579 hn, 20580 vn, 20581 em; 20582 w = parseFloat(t.offsetWidth); 20583 h = parseFloat(t.offsetHeight); 20584 ea1 = e.split(" "); 20585 for (i = 0; i < props.length; i++) { 20586 //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis! 20587 if (this.p.indexOf("border")) { 20588 //older browsers used a prefix 20589 props[i] = _checkPropPrefix(props[i]); 20590 }
20591 bs = bs2 = _getStyle(t, props[i], _cs, false, "0px"); 20592 if (bs.indexOf(" ") !== -1) { 20593 bs2 = bs.split(" "); 20594 bs = bs2[0]; 20595 bs2 = bs2[1]; 20596 } 20597 es = es2 = ea1[i]; 20598 bn = parseFloat(bs); 20599 bsfx = bs.substr((bn + "").length); 20600 rel = es.charAt(1) === "="; 20601 if (rel) { 20602 en = parseInt(es.charAt(0) + "1", 10); 20603 es = es.substr(2); 20604 en *= parseFloat(es); 20605 esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || ""; 20606 } else { 20607 en = parseFloat(es); 20608 esfx = es.substr((en + "").length); 20609 } 20610 if (esfx === "") { 20611 esfx = _suffixMap[p] || bsfx; 20612 } 20613 if (esfx !== bsfx) { 20614 hn = _convertToPixels(t, "borderLeft", bn, bsfx); //horizontal number (we use a bogus "borderLeft" property just because the _convertToPixels() method searches for the keywords "Left", "Right", "Top", and "Bottom" to determine of it's a horizontal or vertical property, and we need "border" in the name so that it knows it should measure relative to the element itself, not its parent. 20615 vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number 20616 if (esfx === "%") { 20617 bs = hn / w * 100 + "%"; 20618 bs2 = vn / h * 100 + "%"; 20619 } else if (esfx === "em") { 20620 em = _convertToPixels(t, "borderLeft", 1, "em"); 20621 bs = hn / em + "em"; 20622 bs2 = vn / em + "em"; 20623 } else { 20624 bs = hn + "px"; 20625 bs2 = vn + "px"; 20626 } 20627 if (rel) { 20628 es = parseFloat(bs) + en + esfx; 20629 es2 = parseFloat(bs2) + en + esfx; 20630 } 20631 } 20632 pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt); 20633 } 20634 return pt; 20635 }, prefix: true, formatter: _getFormatter("0px 0px 0px 0px", false, true) }); 20636 _registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", { defaultValue: "0px", parser: function (t, e, p, cssp, pt, plugin) { 20637 return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt); 20638 }, prefix: true, formatter: _getFormatter("0px 0px", false, true) }); 20639 _registerComplexSpecialProp("backgroundPosition", { defaultValue: "0 0", parser: function (t, e, p, cssp, pt, plugin) { 20640 var bp = "background-position", 20641 cs = _cs || _getComputedStyle(t, null), 20642 bs = this.format((cs ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"), 20643 //Internet Explorer doesn't report background-position correctly - we must query background-position-x and background-position-y and combine them (even in IE10). Before IE9, we must do the same with the currentStyle object and use camelCase 20644 es = this.format(e), 20645 ba, 20646 ea, 20647 i, 20648 pct, 20649 overlap, 20650 src; 20651 if (bs.indexOf("%") !== -1 !== (es.indexOf("%") !== -1) && es.split(",").length < 2) { 20652 src = _getStyle(t, "backgroundImage").replace(_urlExp, ""); 20653 if (src && src !== "none") { 20654 ba = bs.split(" "); 20655 ea = es.split(" "); 20656 _tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height 20657 i = 2; 20658 while (--i > -1) { 20659 bs = ba[i]; 20660 pct = bs.indexOf("%") !== -1; 20661 if (pct !== (ea[i].indexOf("%") !== -1)) { 20662 overlap = i === 0 ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height; 20663 ba[i] = pct ? parseFloat(bs) / 100 * overlap + "px" : parseFloat(bs) / overlap * 100 + "%"; 20664 } 20665 } 20666 bs = ba.join(" "); 20667 } 20668 } 20669 return this.parseComplex(t.style, bs, es, pt, plugin); 20670 }, formatter: _parsePosition }); 20671 _registerComplexSpecialProp("backgroundSize", { defaultValue: "0 0", formatter: function (v) { 20672 v += ""; //ensure it's a string 20673 return _parsePosition(v.indexOf(" ") === -1 ? v + " " + v : v); //if set to something like "100% 100%", Safari typically reports the computed style as just "100%" (no 2nd value), but we should ensure that there are two values, so copy the first one. Otherwise, it'd be interpreted as "100% 0" (wrong). 20674 } }); 20675 _registerComplexSpecialProp("perspective", { defaultValue: "0px", prefix: true }); 20676 _registerComplexSpecialProp("perspectiveOrigin", { defaultValue: "50% 50%", prefix: true }); 20677 _registerComplexSpecialProp("transformStyle", { prefix: true }); 20678 _registerComplexSpecialProp("backfaceVisibility", { prefix: true }); 20679 _registerComplexSpecialProp("userSelect", { prefix: true }); 20680 _registerComplexSpecialProp("margin", { parser: _getEdgeParser("marginTop,marginRight,marginBottom,marginLeft") }); 20681 _registerComplexSpecialProp("padding", { parser: _getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft") }); 20682 _registerComplexSpecialProp("clip", { defaultValue: "rect(0px,0px,0px,0px)", parser: function (t, e, p, cssp, pt, plugin) { 20683 var b, cs, delim; 20684 if (_ieVers < 9) { 20685 //IE8 and earlier don't report a "clip" value in the currentStyle - instead, the values are split apart into clipTop, clipRight, clipBottom, and clipLeft. Also, in IE7 and earlier, the values inside rect() are space-delimited, not comma-delimited. 20686 cs = t.currentStyle; 20687 delim = _ieVers < 8 ? " " : ","; 20688 b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")"; 20689 e = this.format(e).split(",").join(delim); 20690 } else { 20691 b = this.format(_getStyle(t, this.p, _cs, false, this.dflt)); 20692 e = this.format(e); 20693 } 20694 return this.parseComplex(t.style, b, e, pt, plugin); 20695 } }); 20696 _registerComplexSpecialProp("textShadow", { defaultValue: "0px 0px 0px #999", color: true, multi: true }); 20697 _registerComplexSpecialProp("autoRound,strictUnits", { parser: function (t, e, p, cssp, pt) { 20698 return pt; 20699 } }); //just so that we can ignore these properties (not tween them) 20700 _registerComplexSpecialProp("border", { defaultValue: "0px solid #000", parser: function (t, e, p, cssp, pt, plugin) { 20701 var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"), 20702 end = this.format(e).split(" "), 20703 esfx = end[0].replace(_suffixExp, ""); 20704 if (esfx !== "px") { 20705 //if we're animating to a non-px value, we need to convert the beginning width to that unit. 20706 bw = parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx) + esfx; 20707 } 20708 return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin); 20709 }, color: true, formatter: function (v) { 20710 var a = v.split(" "); 20711 return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0]; 20712 } }); 20713 _registerComplexSpecialProp("borderWidth", { parser: _getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth") }); //Firefox doesn't pick up on borderWidth set in style sheets (only inline). 20714 _registerComplexSpecialProp("float,cssFloat,styleFloat", { parser: function (t, e, p, cssp, pt, plugin) { 20715 var s = t.style, 20716 prop = "cssFloat" in s ? "cssFloat" : "styleFloat"; 20717 return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e); 20718 } }); 20719 20720 //opacity-related 20721 var _setIEOpacityRatio = function (v) { 20722 var t = this.t, 20723 //refers to the element's style property 20724 filters = t.filter || _getStyle(this.data, "filter") || "", 20725 val = this.s + this.c * v | 0, 20726 skip; 20727 if (val === 100) { 20728 //for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters. 20729 if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) { 20730 t.removeAttribute("filter"); 20731 skip = !_getStyle(this.data, "filter"); //if a class is applied that has an alpha filter, it will take effect (we don't want that), so re-apply our alpha filter in that case. We must first remove it and then check. 20732 } else {
20733 t.filter = filters.replace(_alphaFilterExp, ""); 20734 skip = true; 20735 } 20736 } 20737 if (!skip) { 20738 if (this.xn1) { 20739 t.filter = filters = filters || "alpha(opacity=" + val + ")"; //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame. 20740 } 20741 if (filters.indexOf("pacity") === -1) { 20742 //only used if browser doesn't support the standard opacity style property (IE 7 and 8). We omit the "O" to avoid case-sensitivity issues 20743 if (val !== 0 || !this.xn1) { 20744 //bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween) 20745 t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly. 20746 } 20747 } else { 20748 t.filter = filters.replace(_opacityExp, "opacity=" + val); 20749 } 20750 } 20751 }; 20752 _registerComplexSpecialProp("opacity,alpha,autoAlpha", { defaultValue: "1", parser: function (t, e, p, cssp, pt, plugin) { 20753 var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")), 20754 style = t.style, 20755 isAutoAlpha = p === "autoAlpha"; 20756 if (typeof e === "string" && e.charAt(1) === "=") { 20757 e = (e.charAt(0) === "-" ? -1 : 1) * parseFloat(e.substr(2)) + b; 20758 } 20759 if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) { 20760 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) 20761 b = 0; 20762 } 20763 if (_supportsOpacity) { 20764 pt = new CSSPropTween(style, "opacity", b, e - b, pt); 20765 } else { 20766 pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt); 20767 pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug. 20768 style.zoom = 1; //helps correct an IE issue. 20769 pt.type = 2; 20770 pt.b = "alpha(opacity=" + pt.s + ")"; 20771 pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")"; 20772 pt.data = t; 20773 pt.plugin = plugin; 20774 pt.setRatio = _setIEOpacityRatio; 20775 } 20776 if (isAutoAlpha) { 20777 //we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier 20778 pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, b !== 0 ? "inherit" : "hidden", e === 0 ? "hidden" : "inherit"); 20779 pt.xs0 = "inherit"; 20780 cssp._overwriteProps.push(pt.n); 20781 cssp._overwriteProps.push(p); 20782 } 20783 return pt; 20784 } }); 20785 20786 var _removeProp = function (s, p) { 20787 if (p) { 20788 if (s.removeProperty) { 20789 if (p.substr(0, 2) === "ms" || p.substr(0, 6) === "webkit") { 20790 //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example) 20791 p = "-" + p; 20792 } 20793 s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 20794 } else { 20795 //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" 20796 s.removeAttribute(p); 20797 } 20798 } 20799 }, 20800 _setClassNameRatio = function (v) { 20801 this.t._gsClassPT = this; 20802 if (v === 1 || v === 0) { 20803 this.t.setAttribute("class", v === 0 ? this.b : this.e); 20804 var mpt = this.data, 20805 //first MiniPropTween 20806 s = this.t.style; 20807 while (mpt) { 20808 if (!mpt.v) { 20809 _removeProp(s, mpt.p); 20810 } else { 20811 s[mpt.p] = mpt.v; 20812 } 20813 mpt = mpt._next; 20814 } 20815 if (v === 1 && this.t._gsClassPT === this) { 20816 this.t._gsClassPT = null; 20817 } 20818 } else if (this.t.getAttribute("class") !== this.e) { 20819 this.t.setAttribute("class", this.e); 20820 } 20821 }; 20822 _registerComplexSpecialProp("className", { parser: function (t, e, p, cssp, pt, plugin, vars) { 20823 var b = t.getAttribute("class") || "", 20824 //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable. 20825 cssText = t.style.cssText, 20826 difData, 20827 bs, 20828 cnpt, 20829 cnptLookup, 20830 mpt; 20831 pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2); 20832 pt.setRatio = _setClassNameRatio; 20833 pt.pr = -11; 20834 _hasPriority = true; 20835 pt.b = b; 20836 bs = _getAllStyles(t, _cs); 20837 //if there's a className tween already operating on the target, force it to its end so that the necessary inline styles are removed and the class name is applied before we determine the end state (we don't want inline styles interfer
20837ing that were there just for class-specific values) 20838 cnpt = t._gsClassPT; 20839 if (cnpt) { 20840 cnptLookup = {}; 20841 mpt = cnpt.data; //first MiniPropTween which stores the inline styles - we need to force these so that the inline styles don't contaminate things. Otherwise, there's a small chance that a tween could start and the inline values match the destination values and they never get cleaned. 20842 while (mpt) { 20843 cnptLookup[mpt.p] = 1; 20844 mpt = mpt._next; 20845 } 20846 cnpt.setRatio(1); 20847 } 20848 t._gsClassPT = pt; 20849 pt.e = e.charAt(1) !== "=" ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + (e.charAt(0) === "+" ? " " + e.substr(2) : ""); 20850 t.setAttribute("class", pt.e); 20851 difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup); 20852 t.setAttribute("class", b); 20853 pt.data = difData.firstMPT; 20854 t.style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity). 20855 pt = pt.xfirst = cssp.parse(t, difData.difs, pt, plugin); //we record the CSSPropTween as the xfirst so that we can handle overwriting propertly (if "className" gets overwritten, we must kill all the properties associated with the className part of the tween, so we can loop through from xfirst to the pt itself) 20856 return pt; 20857 } }); 20858 20859 var _setClearPropsRatio = function (v) { 20860 if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") { 20861 //this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that and if the tween is the zero-duration one that's created internally to render the starting values in a from() tween, ignore that because otherwise, for example, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in). 20862 var s = this.t.style, 20863 transformParse = _specialProps.transform.parse, 20864 a, 20865 p, 20866 i, 20867 clearTransform, 20868 transform; 20869 if (this.e === "all") { 20870 s.cssText = ""; 20871 clearTransform = true; 20872 } else { 20873 a = this.e.split(" ").join("").split(","); 20874 i = a.length; 20875 while (--i > -1) { 20876 p = a[i]; 20877 if (_specialProps[p]) { 20878 if (_specialProps[p].parse === transformParse) { 20879 clearTransform = true; 20880 } else { 20881 p = p === "transformOrigin" ? _transformOriginProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow" 20882 } 20883 } 20884 _removeProp(s, p); 20885 } 20886 } 20887 if (clearTransform) { 20888 _removeProp(s, _transformProp); 20889 transform = this.t._gsTransform; 20890 if (transform) { 20891 if (transform.svg) { 20892 this.t.removeAttribute("data-svg-origin"); 20893 this.t.removeAttribute("transform"); 20894 } 20895 delete this.t._gsTransform; 20896 } 20897 } 20898 } 20899 }; 20900 _registerComplexSpecialProp("clearProps", { parser: function (t, e, p, cssp, pt) { 20901 pt = new CSSPropTween(t, p, 0, 0, pt, 2); 20902 pt.setRatio = _setClearPropsRatio; 20903 pt.e = e; 20904 pt.pr = -10; 20905 pt.data = cssp._tween; 20906 _hasPriority = true; 20907 return pt; 20908 } }); 20909 20910 p = "bezier,throwProps,physicsProps,physics2D".split(","); 20911 i = p.length; 20912 while (i--) { 20913 _registerPluginProp(p[i]); 20914 } 20915 20916 p = CSSPlugin.prototype; 20917 p._firstPT = p._lastParsedTransform = p._transform = null; 20918 20919 //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc. 20920 p._onInitTween = function (target, vars, tween, index) { 20921 if (!target.nodeType) { 20922 //css is only for dom elements 20923 return false; 20924 } 20925 this._target = _target = target; 20926 this._tween = tween; 20927 this._vars = vars; 20928 _index = index; 20929 _autoRound = vars.autoRound; 20930 _hasPriority = false;
20931 _suffixMap = vars.suffixMap || CSSPlugin.suffixMap; 20932 _cs = _getComputedStyle(target, ""); 20933 _overwriteProps = this._overwriteProps; 20934 var style = target.style, 20935 v, 20936 pt, 20937 pt2, 20938 first, 20939 last, 20940 next, 20941 zIndex, 20942 tpt, 20943 threeD; 20944 if (_reqSafariFix) if (style.zIndex === "") { 20945 v = _getStyle(target, "zIndex", _cs); 20946 if (v === "auto" || v === "") { 20947 //corrects a bug in [non-Android] Safari that prevents it from repainting elements in their new positions if they don't have a zIndex set. We also can't just apply this inside _parseTransform() because anything that's moved in any way (like using "left" or "top" instead of transforms like "x" and "y") can be affected, so it is best to ensure that anything that's tweening has a z-index. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. Plus zIndex is less memory-intensive. 20948 this._addLazySet(style, "zIndex", 0); 20949 } 20950 } 20951 20952 if (typeof vars === "string") { 20953 first = style.cssText; 20954 v = _getAllStyles(target, _cs); 20955 style.cssText = first + ";" + vars; 20956 v = _cssDif(target, v, _getAllStyles(target)).difs; 20957 if (!_supportsOpacity && _opacityValExp.test(vars)) { 20958 v.opacity = parseFloat(RegExp.$1); 20959 } 20960 vars = v; 20961 style.cssText = first; 20962 } 20963 20964 if (vars.className) { 20965 //className tweens will combine any differences they find in the css with the vars that are passed in, so {className:"myClass", scale:0.5, left:20} would work. 20966 this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars); 20967 } else { 20968 this._firstPT = pt = this.parse(target, vars, null); 20969 } 20970 20971 if (this._transformType) { 20972 threeD = this._transformType === 3; 20973 if (!_transformProp) { 20974 style.zoom = 1; //helps correct an IE issue. 20975 } else if (_isSafari) { 20976 _reqSafariFix = true; 20977 //if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random). 20978 if (style.zIndex === "") { 20979 zIndex = _getStyle(target, "zIndex", _cs); 20980 if (zIndex === "auto" || zIndex === "") { 20981 this._addLazySet(style, "zIndex", 0); 20982 } 20983 } 20984 //Setting WebkitBackfaceVisibility corrects 3 bugs: 20985 // 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update. 20986 // 2) iOS Safari sometimes neglects to repaint elements in their new positions. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. 20987 // 3) Safari sometimes displayed odd artifacts when tweening the transform (or WebkitTransform) property, like ghosts of the edges of the element remained. Definitely a browser bug. 20988 //Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween. 20989 if (_isSafariLT6) { 20990 this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden")); 20991 } 20992 } 20993 pt2 = pt; 20994 while (pt2 && pt2._next) { 20995 pt2 = pt2._next; 20996 } 20997 tpt = new CSSPropTween(target, "transform", 0, 0, null, 2); 20998 this._linkCSSP(tpt, null, pt2); 20999 tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio; 21000 tpt.data = this._transform || _getTransform(target, _cs, true); 21001 tpt.tween = tween; 21002 tpt.pr = -1; //ensures that the transforms get applied after the components are updated. 21003 _overwriteProps.pop(); //we don't want to force the overwrite of all "transform" tweens of the target - we only care about individual transform properties like scaleX, rotation, etc. The CSSPropTween constructor automatically adds the property to _overwriteProps which is why we need to pop() here. 21004 } 21005 21006 if (_hasPriority) { 21007 //reorders the linked list in order of pr (priority) 21008 while (pt) { 21009 next = pt._next; 21010 pt2 = first; 21011 while (pt2 && pt2.pr > pt.pr) { 21012 pt2 = pt2._next; 21013 } 21014 if (pt._prev = pt2 ? pt2._prev : last) { 21015 pt._prev._next = pt; 21016 } else { 21017 first = pt; 21018 } 21019 if (pt._next = pt2) { 21020 pt2._prev = pt; 21021 } else { 21022 last = pt; 21023 } 21024 pt = next; 21025 } 21026 this._firstPT = first; 21027 } 21028 return true; 21029 }; 21030 21031 p.parse = function (target, vars, pt, plugin) { 21032 var style = target.style, 21033 p, 21034 sp, 21035 bn, 21036 en, 21037 bs, 21038 es, 21039 bsfx, 21040 esfx, 21041 isStr, 21042 rel; 21043 for (p in vars) { 21044 es = vars[p]; //ending value string 21045 if (typeof es === "function") { 21046 es = es(_index, _target); 21047 } 21048 sp = _specialProps[p]; //SpecialProp lookup. 21049 if (sp) { 21050 pt = sp.parse(target, es, p, this, pt, plugin, vars); 21051 } else if (p.substr(0, 2) === "--") { 21052 //for tweening CSS variables (which always start with "--"). To maximize performance and simplicity, we bypass CSSPlugin altogether and just add a normal property tween to the tween instance itself. 21053 this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p); 21054 continue; 21055 } else { 21056 bs = _getStyle(target, p, _cs) + ""; 21057 isStr = typeof es === "string"; 21058 if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || isStr && _rgbhslExp.test(es)) { 21059 //Opera uses background: to define color sometimes in addition to backgroundColor: 21060 if (!isStr) { 21061 es = _parseColor(es); 21062 es = (es.length > 3 ? "rgba(" : "rgb(") + es.join(",") + ")"; 21063 } 21064 pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin); 21065 } else if (isStr && _complexExp.test(es)) { 21066 pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin); 21067 } else { 21068 bn = parseFloat(bs); 21069 bsfx = bn || bn === 0 ? bs.substr((bn + "").length) : ""; //remember, bs could be non-numeric like "normal" for fontWeight, so we should default to a blank suffix in that case. 21070 21071 if (bs === "" || bs === "auto") { 21072 if (p === "width" || p === "height") { 21073 bn = _getDimension(target, p, _cs); 21074 bsfx = "px"; 21075 } else if (p === "left" || p === "top") {
21076 bn = _calculateOffset(target, p, _cs); 21077 bsfx = "px"; 21078 } else { 21079 bn = p !== "opacity" ? 0 : 1; 21080 bsfx = ""; 21081 } 21082 } 21083 21084 rel = isStr && es.charAt(1) === "="; 21085 if (rel) { 21086 en = parseInt(es.charAt(0) + "1", 10); 21087 es = es.substr(2); 21088 en *= parseFloat(es); 21089 esfx = es.replace(_suffixExp, ""); 21090 } else { 21091 en = parseFloat(es); 21092 esfx = isStr ? es.replace(_suffixExp, "") : ""; 21093 } 21094 21095 if (esfx === "") { 21096 esfx = p in _suffixMap ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix. 21097 } 21098 21099 es = en || en === 0 ? (rel ? en + bn : en) + esfx : vars[p]; //ensures that any += or -= prefixes are taken care of. Record the end value before normalizing the suffix because we always want to end the tween on exactly what they intended even if it doesn't match the beginning value's suffix. 21100 //if the beginning/ending suffixes don't match, normalize them... 21101 if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) { 21102 //note: if the beginning value (bn) is 0, we don't need to convert units! 21103 bn = _convertToPixels(target, p, bn, bsfx); 21104 if (esfx === "%") { 21105 bn /= _convertToPixels(target, p, 100, "%") / 100; 21106 if (vars.strictUnits !== true) { 21107 //some browsers report only "px" values instead of allowing "%" with getComputedStyle(), so we assume that if we're tweening to a %, we should start there too unless strictUnits:true is defined. This approach is particularly useful for responsive designs that use from() tweens. 21108 bs = bn + "%"; 21109 } 21110 } else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") { 21111 bn /= _convertToPixels(target, p, 1, esfx); 21112 21113 //otherwise convert to pixels. 21114 } else if (esfx !== "px") { 21115 en = _convertToPixels(target, p, en, esfx); 21116 esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too. 21117 } 21118 if (rel) if (en || en === 0) { 21119 es = en + bn + esfx; //the changes we made affect relative calculations, so adjust the end value here. 21120 } 21121 } 21122 21123 if (rel) { 21124 en += bn; 21125 } 21126 21127 if ((bn || bn === 0) && (en || en === 0)) { 21128 //faster than isNaN(). Also, previously we required en !== bn but that doesn't really gain much performance and it prevents _parseToProxy() from working properly if beginning and ending values match but need to get tweened by an external plugin anyway. For example, a bezier tween where the target starts at left:0 and has these points: [{left:50},{left:0}] wouldn't work properly because when parsing the last point, it'd match the first (current) one and a non-tweening CSSPropTween would be recorded when we actually need a normal tween (type:0) so that things get updated during the tween properly. 21129 pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, _autoRound !== false && (esfx === "px" || p === "zIndex"), 0, bs, es); 21130 pt.xs0 = esfx; 21131 //DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0); 21132 } else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) { 21133 _log("invalid " + p + " tween value: " + vars[p]); 21134 } else { 21135 pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es); 21136 pt.xs0 = es === "none" && (p === "display" || p.indexOf("Style") !== -1) ? bs : es; //intermediate value should typically be set immediately (end value) except for "display" or things like borderTopStyle, borderBottomStyle, etc. which should use the beginning value during the tween. 21137 //DEBUG: _log("non-tweening value "+p+": "+pt.xs0); 21138 } 21139 } 21140 } 21141 if (plugin) if (pt && !pt.plugin) { 21142 pt.plugin = plugin; 21143 } 21144 } 21145 return pt; 21146 }; 21147 21148 //gets called every time the tween updates, passing the new ratio (typically a value between 0 and 1, but not always (for example, if an Elastic.easeOut is used, the value can jump above 1 mid-tween). It will always start and 0 and end at 1. 21149 p.setRatio = function (v) { 21150 var pt = this._firstPT, 21151 min = 0.000001, 21152 val, 21153 str, 21154 i; 21155 //at the end of the tween, we set the values to exactly what we received in order to make sure non-tweening values (like "position" or "float" or whatever) are set and so that if the beginning/ending suffixes (units) didn't match and we normalized to px, the value that the user passed in is used here. We check to see if the tween is at its beginning in case it's a from() tween in which case the ratio will actually go from 1 to 0 over the course of the tween (backwards). 21156 if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) { 21157 while (pt) { 21158 if (pt.type !== 2) { 21159 if (pt.r && pt.type !== -1) { 21160 val = Math.round(pt.s + pt.c); 21161 if (!pt.type) { 21162 pt.t[pt.p] = val + pt.xs0; 21163 } else if (pt.type === 1) { 21164 //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)" 21165 i = pt.l; 21166 str = pt.xs0 + val + pt.xs1; 21167 for (i = 1; i < pt.l; i++) { 21168 str += pt["xn" + i] + pt["xs" + (i + 1)]; 21169 } 21170 pt.t[pt.p] = str; 21171 } 21172 } else { 21173 pt.t[pt.p] = pt.e; 21174 } 21175 } else { 21176 pt.setRatio(v); 21177 } 21178 pt = pt._next; 21179 } 21180 } else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) { 21181 while (pt) { 21182 val = pt.c * v + pt.s; 21183 if (pt.r) { 21184 val = Math.round(val); 21185 } else if (val < min) if (val > -min) { 21186 val = 0; 21187 } 21188 if (!pt.type) { 21189 pt.t[pt.p] = val + pt.xs0; 21190 } else if (pt.type === 1) { 21191 //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)" 21192 i = pt.l; 21193 if (i === 2) { 21194 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2; 21195 } else if (i === 3) { 21196 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3; 21197 } else if (i === 4) { 21198 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4; 21199 } else if (i === 5) { 21200 pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4 + pt.xn4 + pt.xs5; 21201 } else { 21202 str = pt.xs0 + val + pt.xs1; 21203 for (i = 1; i < pt.l; i++) { 21204 str += pt["xn" + i] + pt["xs" + (i + 1)]; 21205 } 21206 pt.t[pt.p] = str; 21207 } 21208 } else if (pt.type === -1) { 21209 //non-tweening value 21210 pt.t[pt.p] = pt.xs0; 21211 }
21211 else if (pt.setRatio) { 21212 //custom setRatio() for things like SpecialProps, external plugins, etc. 21213 pt.setRatio(v); 21214 } 21215 pt = pt._next; 21216 } 21217 21218 //if the tween is reversed all the way back to the beginning, we need to restore the original values which may have different units (like % instead of px or em or whatever). 21219 } else { 21220 while (pt) { 21221 if (pt.type !== 2) { 21222 pt.t[pt.p] = pt.b; 21223 } else { 21224 pt.setRatio(v); 21225 } 21226 pt = pt._next; 21227 } 21228 } 21229 }; 21230 21231 /** 21232 * @private 21233 * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called. 21234 * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked 21235 * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call 21236 * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin 21237 * doesn't have any transform-related properties of its own. You can call this method as many times as you 21238 * want and it won't create duplicate CSSPropTweens. 21239 * 21240 * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster) 21241 */ 21242 p._enableTransforms = function (threeD) { 21243 this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values. 21244 this._transformType = !(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3) ? 3 : 2; 21245 }; 21246 21247 var lazySet = function (v) { 21248 this.t[this.p] = this.e; 21249 this.data._linkCSSP(this, this._next, null, true); //we purposefully keep this._next even though it'd make sense to null it, but this is a performance optimization, as this happens during the while (pt) {} loop in setRatio() at the bottom of which it sets pt = pt._next, so if we null it, the linked list will be broken in that loop. 21250 }; 21251 /** @private Gives us a way to set a value on the first render (and only the first render). **/ 21252 p._addLazySet = function (t, p, v) { 21253 var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2); 21254 pt.e = v; 21255 pt.setRatio = lazySet; 21256 pt.data = this; 21257 }; 21258 21259 /** @private **/ 21260 p._linkCSSP = function (pt, next, prev, remove) { 21261 if (pt) { 21262 if (next) { 21263 next._prev = pt; 21264 } 21265 if (pt._next) { 21266 pt._next._prev = pt._prev; 21267 } 21268 if (pt._prev) { 21269 pt._prev._next = pt._next; 21270 } else if (this._firstPT === pt) { 21271 this._firstPT = pt._next; 21272 remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed) 21273 } 21274 if (prev) { 21275 prev._next = pt; 21276 } else if (!remove && this._firstPT === null) { 21277 this._firstPT = pt; 21278 } 21279 pt._next = next; 21280 pt._prev = prev; 21281 } 21282 return pt; 21283 }; 21284 21285 p._mod = function (lookup) { 21286 var pt = this._firstPT; 21287 while (pt) { 21288 if (typeof lookup[pt.p] === "function" && lookup[pt.p] === Math.round) { 21289 //only gets called by RoundPropsPlugin (ModifyPlugin manages all the rendering internally for CSSPlugin properties that need modification). Remember, we handle rounding a bit differently in this plugin for performance reasons, leveraging "r" as an indicator that the value should be rounded internally.. 21290 pt.r = 1; 21291 } 21292 pt = pt._next; 21293 } 21294 }; 21295 21296 //we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property. 21297 p._kill = function (lookup) { 21298 var copy = lookup, 21299 pt, 21300 p, 21301 xfirst; 21302 if (lookup.autoAlpha || lookup.alpha) { 21303 copy = {}; 21304 for (p in lookup) { 21305 //copy the lookup so that we're not changing the original which may be passed elsewhere. 21306 copy[p] = lookup[p]; 21307 } 21308 copy.opacity = 1; 21309 if (copy.autoAlpha) { 21310 copy.visibility = 1; 21311 } 21312 } 21313 if (lookup.className && (pt = this._classNamePT)) { 21314 //for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst". 21315 xfirst = pt.xfirst; 21316 if (xfirst && xfirst._prev) { 21317 this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev 21318 } else if (xfirst === this._firstPT) { 21319 this._firstPT = pt._next; 21320 } 21321 if (pt._next) { 21322 this._linkCSSP(pt._next, pt._next._next, xfirst._prev); 21323 } 21324 this._classNamePT = null; 21325 } 21326 pt = this._firstPT; 21327 while (pt) { 21328 if (pt.plugin && pt.plugin !== p && pt.plugin._kill) { 21329 //for plugins that are registered with CSSPlugin, we should notify them of the kill. 21330 pt.plugin._kill(lookup); 21331 p = pt.plugin; 21332 } 21333 pt = pt._next; 21334 } 21335 return TweenPlugin.prototype._kill.call(this, copy); 21336 }; 21337 21338 //used by cascadeTo() for gathering all the style properties of each child element into an array for c
21338omparison. 21339 var _getChildStyles = function (e, props, targets) { 21340 var children, i, child, type; 21341 if (e.slice) { 21342 i = e.length; 21343 while (--i > -1) { 21344 _getChildStyles(e[i], props, targets); 21345 } 21346 return; 21347 } 21348 children = e.childNodes; 21349 i = children.length; 21350 while (--i > -1) { 21351 child = children[i]; 21352 type = child.type; 21353 if (child.style) { 21354 props.push(_getAllStyles(child)); 21355 if (targets) { 21356 targets.push(child); 21357 } 21358 } 21359 if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) { 21360 _getChildStyles(child, props, targets); 21361 } 21362 } 21363 }; 21364 21365 /** 21366 * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite 21367 * and then compares the style properties of all the target's child elements at the tween's start and end, and 21368 * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting 21369 * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is 21370 * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens 21371 * is because it creates entirely new tweens that may have completely different targets than the original tween, 21372 * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API 21373 * and it would create other problems. For example: 21374 * - If I create a tween of elementA, that tween instance may suddenly change its target to include 50 other elements (unintuitive if I specifically defined the target I wanted) 21375 * - We can't just create new independent tweens because otherwise, what happens if the original/parent tween is reversed or pause or dropped into a TimelineLite for tight control? You'd expect that tween's behavior to affect all the others. 21376 * - Analyzing every style property of every child before and after the tween is an expensive operation when there are many children, so this behavior shouldn't be imposed on all className tweens by default, especially since it's probably rare that this extra functionality is needed. 21377 * 21378 * @param {Object} target object to be tweened 21379 * @param {number} Duration in seconds (or frames for frames-based tweens) 21380 * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone} 21381 * @return {Array} An array of TweenLite instances 21382 */ 21383 CSSPlugin.cascadeTo = function (target, duration, vars) { 21384 var tween = TweenLite.to(target, duration, vars), 21385 results = [tween], 21386 b = [], 21387 e = [], 21388 targets = [], 21389 _reservedProps = TweenLite._internals.reservedProps, 21390 i, 21391 difs, 21392 p, 21393 from; 21394 target = tween._targets || tween.target; 21395 _getChildStyles(target, b, targets); 21396 tween.render(duration, true, true); 21397 _getChildStyles(target, e); 21398 tween.render(0, true, true); 21399 tween._enabled(true); 21400 i = targets.length; 21401 while (--i > -1) { 21402 difs = _cssDif(targets[i], b[i], e[i]); 21403 if (difs.firstMPT) { 21404 difs = difs.difs; 21405 for (p in vars) { 21406 if (_reservedProps[p]) { 21407 difs[p] = vars[p]; 21408 } 21409 } 21410 from = {}; 21411 for (p in difs) { 21412 from[p] = b[i][p]; 21413 } 21414 results.push(TweenLite.fromTo(targets[i], duration, from, difs)); 21415 } 21416 } 21417 return results; 21418 }; 21419 21420 TweenPlugin.activate([CSSPlugin]); 21421 return CSSPlugin; 21422 }, true); 21423 21424 /* 21425 * ---------------------------------------------------------------- 21426 * RoundPropsPlugin 21427 * ---------------------------------------------------------------- 21428 */ 21429 (function () { 21430 21431 var RoundPropsPlugin = _gsScope._gsDefine.plugin({ 21432 propName: "roundProps", 21433 version: "1.6.0", 21434 priority: -1, 21435 API: 2, 21436 21437 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 21438 init: function (target, value, tween) { 21439 this._tween = tween; 21440 return true; 21441 } 21442 21443 }), 21444 _roundLinkedList = function (node) { 21445 while (node) { 21446 if (!node.f && !node.blob) { 21447 node.m = Math.round; 21448 } 21449 node = node._next; 21450 } 21451 }, 21452 p = RoundPropsPlugin.prototype; 21453 21454 p._onInitAllProps = function () { 21455 var tween = this._tween,
21456 rp = tween.vars.roundProps.join ? tween.vars.roundProps : tween.vars.roundProps.split(","), 21457 i = rp.length, 21458 lookup = {}, 21459 rpt = tween._propLookup.roundProps, 21460 prop, 21461 pt, 21462 next; 21463 while (--i > -1) { 21464 lookup[rp[i]] = Math.round; 21465 } 21466 i = rp.length; 21467 while (--i > -1) { 21468 prop = rp[i]; 21469 pt = tween._firstPT; 21470 while (pt) { 21471 next = pt._next; //record here, because it may get removed 21472 if (pt.pg) { 21473 pt.t._mod(lookup); 21474 } else if (pt.n === prop) { 21475 if (pt.f === 2 && pt.t) { 21476 //a blob (text containing multiple numeric values) 21477 _roundLinkedList(pt.t._firstPT); 21478 } else { 21479 this._add(pt.t, prop, pt.s, pt.c); 21480 //remove from linked list 21481 if (next) { 21482 next._prev = pt._prev; 21483 } 21484 if (pt._prev) { 21485 pt._prev._next = next; 21486 } else if (tween._firstPT === pt) { 21487 tween._firstPT = next; 21488 } 21489 pt._next = pt._prev = null; 21490 tween._propLookup[prop] = rpt; 21491 } 21492 } 21493 pt = next; 21494 } 21495 } 21496 return false; 21497 }; 21498 21499 p._add = function (target, p, s, c) { 21500 this._addTween(target, p, s, s + c, p, Math.round); 21501 this._overwriteProps.push(p); 21502 }; 21503 })(); 21504 21505 /* 21506 * ---------------------------------------------------------------- 21507 * AttrPlugin 21508 * ---------------------------------------------------------------- 21509 */ 21510 21511 (function () { 21512 21513 _gsScope._gsDefine.plugin({ 21514 propName: "attr", 21515 API: 2, 21516 version: "0.6.1", 21517 21518 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 21519 init: function (target, value, tween, index) { 21520 var p, end; 21521 if (typeof target.setAttribute !== "function") { 21522 return false; 21523 } 21524 for (p in value) { 21525 end = value[p]; 21526 if (typeof end === "function") { 21527 end = end(index, target); 21528 } 21529 this._addTween(target, "setAttribute", target.getAttribute(p) + "", end + "", p, false, p); 21530 this._overwriteProps.push(p); 21531 } 21532 return true; 21533 } 21534 21535 }); 21536 })(); 21537 21538 /* 21539 * ---------------------------------------------------------------- 21540 * DirectionalRotationPlugin 21541 * ---------------------------------------------------------------- 21542 */ 21543 _gsScope._gsDefine.plugin({ 21544 propName: "directionalRotation", 21545 version: "0.3.1", 21546 API: 2, 21547 21548 //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run. 21549 init: function (target, value, tween, index) { 21550 if (typeof value !== "object") { 21551 value = { rotation: value }; 21552 } 21553 this.finals = {}; 21554 var cap = value.useRadians === true ? Math.PI * 2 : 360, 21555 min = 0.000001, 21556 p, 21557 v, 21558 start, 21559 end, 21560 dif, 21561 split; 21562 for (p in value) { 21563 if (p !== "useRadians") { 21564 end = value[p]; 21565 if (typeof end === "function") { 21566 end = end(index, target); 21567 } 21568 split = (end + "").split("_"); 21569 v = split[0]; 21570 start = parseFloat(typeof target[p] !== "function" ? target[p] : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)]()); 21571 end = this.finals[p] = typeof v === "string" && v.charAt(1) === "=" ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0; 21572 dif = end - start; 21573 if (split.length) { 21574 v = split.join("_"); 21575 if (v.indexOf("short") !== -1) { 21576 dif = dif % cap; 21577 if (dif !== dif % (cap / 2)) { 21578 dif = dif < 0 ? dif + cap : dif - cap; 21579 } 21580 } 21581 if (v.indexOf("_cw") !== -1 && dif < 0) { 21582 dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap; 21583 } else if (v.indexOf("ccw") !== -1 && dif > 0) { 21584 dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap; 21585 } 21586 } 21587 if (dif > min || dif < -min) { 21588 this._addTween(target, p, start, start + dif, p); 21589 this._overwriteProps.push(p); 21590 } 21591 } 21592 } 21593 return true; 21594 }, 21595 21596 //called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.) 21597 set: function (ratio) { 21598 var pt; 21599 if (ratio !== 1) { 21600 this._super.setRatio.call(this, ratio); 21601 } else { 21602 pt = this._firstPT; 21603 while (pt) { 21604 if (pt.f) { 21605 pt.t[pt.p](this.finals[pt.p]); 21606 } else { 21607 pt.t[pt.p] = this.finals[pt.p]; 21608 } 21609 pt = pt._next; 21610 } 21611 } 21612 } 21613 21614 })._autoCSS = true; 21615 21616 /* 21617 * ---------------------------------------------------------------- 21618 * EasePack 21619 * ---------------------------------------------------------------- 21620 */ 21621 _gsScope._gsDefine("easing.Back", ["easing.Ease"], function (Ease) { 21622 21623 var w = _gsScope.GreenSockGlobals || _gsScope, 21624 gs = w.com.greensock, 21625 _2PI = Math.PI * 2, 21626 _HALF_PI = Math.PI / 2, 21627 _class = gs._class, 21628 _create = function (n, f) { 21629 var C = _class("easing." + n, function () {}, true), 21630 p = C.prototype = new Ease(); 21631 p.constructor = C; 21632 p.getRatio = f; 21633 return C; 21634 }, 21635 _easeReg = Ease.register || function () {}, 21636 //put an empty function in place just as a safety measure in case someone loads an OLD version of TweenLite.js where Ease.register doesn't exist. 21637 _wrap = function (name, EaseOut, EaseIn, EaseInOut, aliases) { 21638 var C = _class("easing." + name, { 21639 easeOut: new EaseOut(),
21640 easeIn: new EaseIn(), 21641 easeInOut: new EaseInOut() 21642 }, true); 21643 _easeReg(C, name); 21644 return C; 21645 }, 21646 EasePoint = function (time, value, next) { 21647 this.t = time; 21648 this.v = value; 21649 if (next) { 21650 this.next = next; 21651 next.prev = this; 21652 this.c = next.v - value; 21653 this.gap = next.t - time; 21654 } 21655 }, 21656 21657 21658 //Back 21659 _createBack = function (n, f) { 21660 var C = _class("easing." + n, function (overshoot) { 21661 this._p1 = overshoot || overshoot === 0 ? overshoot : 1.70158; 21662 this._p2 = this._p1 * 1.525; 21663 }, true), 21664 p = C.prototype = new Ease(); 21665 p.constructor = C; 21666 p.getRatio = f; 21667 p.config = function (overshoot) { 21668 return new C(overshoot); 21669 }; 21670 return C; 21671 }, 21672 Back = _wrap("Back", _createBack("BackOut", function (p) { 21673 return (p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1; 21674 }), _createBack("BackIn", function (p) { 21675 return p * p * ((this._p1 + 1) * p - this._p1); 21676 }), _createBack("BackInOut", function (p) { 21677 return (p *= 2) < 1 ? 0.5 * p * p * ((this._p2 + 1) * p - this._p2) : 0.5 * ((p -= 2) * p * ((this._p2 + 1) * p + this._p2) + 2); 21678 })), 21679 21680 21681 //SlowMo 21682 SlowMo = _class("easing.SlowMo", function (linearRatio, power, yoyoMode) { 21683 power = power || power === 0 ? power : 0.7; 21684 if (linearRatio == null) { 21685 linearRatio = 0.7; 21686 } else if (linearRatio > 1) { 21687 linearRatio = 1; 21688 } 21689 this._p = linearRatio !== 1 ? power : 0; 21690 this._p1 = (1 - linearRatio) / 2; 21691 this._p2 = linearRatio; 21692 this._p3 = this._p1 + this._p2; 21693 this._calcEnd = yoyoMode === true; 21694 }, true), 21695 p = SlowMo.prototype = new Ease(), 21696 SteppedEase, 21697 RoughEase, 21698 _createElastic; 21699 21700 p.constructor = SlowMo; 21701 p.getRatio = function (p) { 21702 var r = p + (0.5 - p) * this._p; 21703 if (p < this._p1) { 21704 return this._calcEnd ? 1 - (p = 1 - p / this._p1) * p : r - (p = 1 - p / this._p1) * p * p * p * r; 21705 } else if (p > this._p3) { 21706 return this._calcEnd ? p === 1 ? 0 : 1 - (p = (p - this._p3) / this._p1) * p : r + (p - r) * (p = (p - this._p3) / this._p1) * p * p * p; //added p === 1 ? 0 to avoid floating point rounding errors from affecting the final value, like 1 - 0.7 = 0.30000000000000004 instead of 0.3 21707 } 21708 return this._calcEnd ? 1 : r; 21709 }; 21710 SlowMo.ease = new SlowMo(0.7, 0.7); 21711 21712 p.config = SlowMo.config = function (linearRatio, power, yoyoMode) { 21713 return new SlowMo(linearRatio, power, yoyoMode); 21714 }; 21715 21716 //SteppedEase 21717 SteppedEase = _class("easing.SteppedEase", function (steps, immediateStart) { 21718 steps = steps || 1; 21719 this._p1 = 1 / steps; 21720 this._p2 = steps + (immediateStart ? 0 : 1); 21721 this._p3 = immediateStart ? 1 : 0; 21722 }, true); 21723 p = SteppedEase.prototype = new Ease(); 21724 p.constructor = SteppedEase; 21725 p.getRatio = function (p) { 21726 if (p < 0) { 21727 p = 0; 21728 } else if (p >= 1) { 21729 p = 0.999999999; 21730 } 21731 return ((this._p2 * p | 0) + this._p3) * this._p1; 21732 }; 21733 p.config = SteppedEase.config = function (steps, immediateStart) { 21734 return new SteppedEase(steps, immediateStart); 21735 }; 21736 21737 //RoughEase 21738 RoughEase = _class("easing.RoughEase", function (vars) { 21739 vars = vars || {}; 21740 var taper = vars.taper || "none", 21741 a = [], 21742 cnt = 0, 21743 points = (vars.points || 20) | 0, 21744 i = points, 21745 randomize = vars.randomize !== false, 21746 clamp = vars.clamp === true, 21747 template = vars.template instanceof Ease ? vars.template : null, 21748 strength = typeof vars.strength === "number" ? vars.strength * 0.4 : 0.4, 21749 x, 21750 y, 21751 bump, 21752 invX, 21753 obj, 21754 pnt; 21755 while (--i > -1) { 21756 x = randomize ? Math.random() : 1 / points * i; 21757 y = template ? template.getRatio(x) : x; 21758 if (taper === "none") { 21759 bump = strength; 21760 } else if (taper === "out") { 21761 invX = 1 - x; 21762 bump = invX * invX * strength; 21763 } else if (taper === "in") { 21764 bump = x * x * strength; 21765 } else if (x < 0.5) { 21766 //"both" (start) 21767 invX = x * 2; 21768 bump = invX * invX * 0.5 * strength; 21769 } else { 21770 //"both" (end) 21771 invX = (1 - x) * 2; 21772 bump = invX * invX * 0.5 * strength; 21773 } 21774 if (randomize) { 21775 y += Math.random() * bump - bump * 0.5; 21776 } else if (i % 2) { 21777 y += bump * 0.5; 21778 } else { 21779 y -= bump * 0.5; 21780 } 21781 if (clamp) { 21782 if (y > 1) { 21783 y = 1; 21784 } else if (y < 0) { 21785 y = 0; 21786 } 21787 } 21788 a[cnt++] = { x: x, y: y }; 21789 } 21790 a.sort(function (a, b) { 21791 return a.x - b.x; 21792 }); 21793 21794 pnt = new EasePoint(1, 1, null); 21795 i = points; 21796 while (--i > -1) { 21797 obj = a[i]; 21798 pnt = new EasePoint(obj.x, obj.y, pnt); 21799 } 21800 21801 this._prev = new EasePoint(0, 0, pnt.t !== 0 ? pnt : pnt.next); 21802 }, true); 21803 p = RoughEase.prototype = new Ease(); 21804 p.constructor = RoughEase; 21805 p.getRatio = function (p) { 21806 var pnt = this._prev; 21807 if (p > pnt.t) { 21808 while (pnt.next && p >= pnt.t) { 21809 pnt = pnt.next; 21810 } 21811 pnt = pnt.prev; 21812 } else { 21813 while (pnt.prev && p <= pnt.t) { 21814 pnt = pnt.prev; 21815 } 21816 } 21817 this._prev = pnt; 21818 return pnt.v + (p - pnt.t) / pnt.gap * pnt.c; 21819 }; 21820 p.config = function (vars) { 21821 return new RoughEase(vars); 21822 }; 21823 RoughEase.ease = new RoughEase(); 21824 21825 //Bounce 21826 _wrap("Bounce", _create("BounceOut", function (p) { 21827 if (p < 1 / 2.75) { 21828 return 7.5625 * p * p; 21829 } else if (p < 2 / 2.75) { 21830 return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75; 21831 } else if (p < 2.5 / 2.75) { 21832 return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375; 21833 } 21834 return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375; 21835 }), _create("BounceIn", function (p) { 21836 if ((p = 1 - p) < 1 / 2.75) { 21837 return 1 - 7.5625 * p * p; 21838 } else if (p < 2 / 2.75) { 21839 return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75); 21840 } else if (p < 2.5 / 2.75) { 21841 return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375); 21842 } 21843 return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375); 21844 }), _create("BounceInOut", function (p) { 21845 var invert = p < 0.5; 21846 if (invert) { 21847 p = 1 - p * 2; 21848 } else { 21849 p = p * 2 - 1; 21850 } 21851 if (p < 1 / 2.75) { 21852 p = 7.5625 * p * p; 21853 } else if (p < 2 / 2.75) { 21854 p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75; 21855 } else if (p < 2.5 / 2.75) { 21856 p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375; 21857 } else { 21858 p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375; 21859 } 21860 return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5; 21861 })); 21862 21863 //CIRC 21864 _wrap("Circ", _create("CircOut", function (p) { 21865 return Math.sqrt(1 - (p = p - 1) * p); 21866 }), _create("CircIn", function (p) { 21867 return -(Math.sqrt(1 - p * p) - 1); 21868 }), _create("CircInOut", function (p) { 21869 return (p *= 2) < 1 ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1); 21870 })); 21871 21872 //Elastic 21873 _createElastic = function (n, f, def) { 21874 var C = _class("easing." + n, function (amplitude, period) { 21875 this._p1 = amplitude >= 1 ? amplitude : 1;
21875 //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1. 21876 this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1); 21877 this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0); 21878 this._p2 = _2PI / this._p2; //precalculate to optimize 21879 }, true), 21880 p = C.prototype = new Ease(); 21881 p.constructor = C; 21882 p.getRatio = f; 21883 p.config = function (amplitude, period) { 21884 return new C(amplitude, period); 21885 }; 21886 return C; 21887 }; 21888 _wrap("Elastic", _createElastic("ElasticOut", function (p) { 21889 return this._p1 * Math.pow(2, -10 * p) * Math.sin((p - this._p3) * this._p2) + 1; 21890 }, 0.3), _createElastic("ElasticIn", function (p) { 21891 return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2)); 21892 }, 0.3), _createElastic("ElasticInOut", function (p) { 21893 return (p *= 2) < 1 ? -0.5 * (this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2)) : this._p1 * Math.pow(2, -10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2) * 0.5 + 1; 21894 }, 0.45)); 21895 21896 //Expo 21897 _wrap("Expo", _create("ExpoOut", function (p) { 21898 return 1 - Math.pow(2, -10 * p); 21899 }), _create("ExpoIn", function (p) { 21900 return Math.pow(2, 10 * (p - 1)) - 0.001; 21901 }), _create("ExpoInOut", function (p) { 21902 return (p *= 2) < 1 ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1))); 21903 })); 21904 21905 //Sine 21906 _wrap("Sine", _create("SineOut", function (p) { 21907 return Math.sin(p * _HALF_PI); 21908 }), _create("SineIn", function (p) { 21909 return -Math.cos(p * _HALF_PI) + 1; 21910 }), _create("SineInOut", function (p) { 21911 return -0.5 * (Math.cos(Math.PI * p) - 1); 21912 })); 21913 21914 _class("easing.EaseLookup", { 21915 find: function (s) { 21916 return Ease.map[s]; 21917 } 21918 }, true); 21919 21920 //register the non-standard eases 21921 _easeReg(w.SlowMo, "SlowMo", "ease,"); 21922 _easeReg(RoughEase, "RoughEase", "ease,"); 21923 _easeReg(SteppedEase, "SteppedEase", "ease,"); 21924 21925 return Back; 21926 }, true); 21927}); 21928 21929if (_gsScope._gsDefine) { 21930 _gsScope._gsQueue.pop()(); 21931} //necessary in case TweenLite was already loaded separately. 21932 21933 21934/* 21935 * ---------------------------------------------------------------- 21936 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc. 21937 * ---------------------------------------------------------------- 21938 */ 21939(function (window, moduleName) { 21940 21941 "use strict"; 21942 21943 var _exports = {}, 21944 _doc = window.document, 21945 _globals = window.GreenSockGlobals = window.GreenSockGlobals || window; 21946 if (_globals.TweenLite) { 21947 return; //in case the core set of classes is already loaded, don't instantiate twice. 21948 } 21949 var _namespace = function (ns) { 21950 var a = ns.split("."), 21951 p = _globals, 21952 i; 21953 for (i = 0; i < a.length; i++) { 21954 p[a[i]] = p = p[a[i]] || {}; 21955 } 21956 return p; 21957 }, 21958 gs = _namespace("com.greensock"), 21959 _tinyNum = 0.0000000001, 21960 _slice = function (a) { 21961 //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 21962 var b = [], 21963 l = a.length, 21964 i; 21965 for (i = 0; i !== l; b.push(a[i++])) {} 21966 return b; 21967 }, 21968 _emptyFunc = function () {}, 21969 _isArray = function () { 21970 //works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower) 21971 var toString = Object.prototype.toString, 21972 array = toString.call([]); 21973 return function (obj) { 21974 return obj != null && (obj instanceof Array || typeof obj === "object" && !!obj.push && toString.call(obj) === array); 21975 }; 21976 }(), 21977 a, 21978 i, 21979 p, 21980 _ticker, 21981 _tickerActive, 21982 _defLookup = {}, 21983 21984 21985 /** 21986 * @constructor 21987 * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition. 21988 * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is 21989 * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin 21990 * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally. 21991 * 21992 * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found, 21993 * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere, 21994 * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so 21995 * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything 21996 * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock 21997 * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could
21998 * sandbox the banner one like: 21999 * 22000 * <script> 22001 * var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever. 22002 * </script> 22003 * <script src="js/greensock/v1.7/TweenMax.js"></script> 22004 * <script> 22005 * window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...) 22006 * </script> 22007 * <script src="js/greensock/v1.6/TweenMax.js"></script> 22008 * <script> 22009 * gs.TweenLite.to(...); //would use v1.7 22010 * TweenLite.to(...); //would use v1.6 22011 * </script> 22012 * 22013 * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back". 22014 * @param {!Array.<string>} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"] 22015 * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition. 22016 * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object) 22017 */ 22018 Definition = function (ns, dependencies, func, global) { 22019 this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses 22020 _defLookup[ns] = this; 22021 this.gsClass = null; 22022 this.func = func; 22023 var _classes = []; 22024 this.check = function (init) { 22025 var i = dependencies.length, 22026 missing = i, 22027 cur, 22028 a, 22029 n, 22030 cl; 22031 while (--i > -1) { 22032 if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) { 22033 _classes[i] = cur.gsClass; 22034 missing--; 22035 } else if (init) { 22036 cur.sc.push(this); 22037 } 22038 } 22039 if (missing === 0 && func) { 22040 a = ("com.greensock." + ns).split("."); 22041 n = a.pop(); 22042 cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes); 22043 22044 //exports to multiple environments 22045 if (global) { 22046 _globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.) 22047 if (typeof module !== "undefined" && module.exports) { 22048 //node 22049 if (ns === moduleName) { 22050 module.exports = _exports[moduleName] = cl; 22051 for (i in _exports) { 22052 cl[i] = _exports[i]; 22053 } 22054 } else if (_exports[moduleName]) { 22055 _exports[moduleName][n] = cl; 22056 } 22057 } else if (true) { 22058 //AMD 22059 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () { 22060 return cl; 22061 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 22062 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 22063 } 22064 } 22065 for (i = 0; i < this.sc.length; i++) { 22066 this.sc[i].check(); 22067 } 22068 } 22069 }; 22070 this.check(true); 22071 }, 22072 22073 22074 //used to create Definition instances (which basically registers a class that has dependencies). 22075 _gsDefine = window._gsDefine = function (ns, dependencies, func, global) { 22076 return new Definition(ns, dependencies, func, global); 22077 }, 22078 22079 22080 //a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class). 22081 _class = gs._class = function (ns, func, global) { 22082 func = func || function () {}; 22083 _gsDefine(ns, [], function () { 22084 return func; 22085 }, global); 22086 return func; 22087 }; 22088 22089 _gsDefine.globals = _globals; 22090 22091 /* 22092 * ---------------------------------------------------------------- 22093 * Ease 22094 * ---------------------------------------------------------------- 22095 */ 22096 var _baseParams = [0, 0, 1, 1], 22097 Ease = _class("easing.Ease", function (func, extraParams, type, power) { 22098 this._func = func; 22099 this._type = type || 0; 22100 this._power = power || 0; 22101 this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams; 22102 }, true), 22103 _easeMap = Ease.map = {}, 22104 _easeReg = Ease.register = function (ease, names, types, create) { 22105 var na = names.split(","), 22106 i = na.length, 22107 ta = (types || "easeIn,easeOut,easeInOut").split(","), 22108 e, 22109 name, 22110 j, 22111 type; 22112 while (--i > -1) { 22113 name = na[i]; 22114 e = create ? _class("easing." + name, null, true) : gs.easing[name] || {}; 22115 j = ta.length; 22116 while (--j > -1) { 22117 type = ta[j]; 22118 _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease(); 22119 } 22120 } 22121 }; 22122 22123 p = Ease.prototype; 22124 p._calcEnd = false;
22125 p.getRatio = function (p) { 22126 if (this._func) { 22127 this._params[0] = p; 22128 return this._func.apply(null, this._params); 22129 } 22130 var t = this._type, 22131 pw = this._power, 22132 r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2; 22133 if (pw === 1) { 22134 r *= r; 22135 } else if (pw === 2) { 22136 r *= r * r; 22137 } else if (pw === 3) { 22138 r *= r * r * r; 22139 } else if (pw === 4) { 22140 r *= r * r * r * r; 22141 } 22142 return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2; 22143 }; 22144 22145 //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut) 22146 a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"]; 22147 i = a.length; 22148 while (--i > -1) { 22149 p = a[i] + ",Power" + i; 22150 _easeReg(new Ease(null, null, 1, i), p, "easeOut", true); 22151 _easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : "")); 22152 _easeReg(new Ease(null, null, 3, i), p, "easeInOut"); 22153 } 22154 _easeMap.linear = gs.easing.Linear.easeIn; 22155 _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks 22156 22157 22158 /* 22159 * ---------------------------------------------------------------- 22160 * EventDispatcher 22161 * ---------------------------------------------------------------- 22162 */ 22163 var EventDispatcher = _class("events.EventDispatcher", function (target) { 22164 this._listeners = {}; 22165 this._eventTarget = target || this; 22166 }); 22167 p = EventDispatcher.prototype; 22168 22169 p.addEventListener = function (type, callback, scope, useParam, priority) { 22170 priority = priority || 0; 22171 var list = this._listeners[type], 22172 index = 0, 22173 listener, 22174 i; 22175 if (this === _ticker && !_tickerActive) { 22176 _ticker.wake(); 22177 } 22178 if (list == null) { 22179 this._listeners[type] = list = []; 22180 } 22181 i = list.length; 22182 while (--i > -1) { 22183 listener = list[i]; 22184 if (listener.c === callback && listener.s === scope) { 22185 list.splice(i, 1); 22186 } else if (index === 0 && listener.pr < priority) { 22187 index = i + 1; 22188 } 22189 } 22190 list.splice(index, 0, { c: callback, s: scope, up: useParam, pr: priority }); 22191 }; 22192 22193 p.removeEventListener = function (type, callback) { 22194 var list = this._listeners[type], 22195 i; 22196 if (list) { 22197 i = list.length; 22198 while (--i > -1) { 22199 if (list[i].c === callback) { 22200 list.splice(i, 1); 22201 return; 22202 } 22203 } 22204 } 22205 }; 22206 22207 p.dispatchEvent = function (type) { 22208 var list = this._listeners[type], 22209 i, 22210 t, 22211 listener; 22212 if (list) { 22213 i = list.length; 22214 if (i > 1) { 22215 list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip) 22216 } 22217 t = this._eventTarget; 22218 while (--i > -1) { 22219 listener = list[i]; 22220 if (listener) { 22221 if (listener.up) { 22222 listener.c.call(listener.s || t, { type: type, target: t }); 22223 } else { 22224 listener.c.call(listener.s || t); 22225 } 22226 } 22227 } 22228 } 22229 }; 22230 22231 /* 22232 * ---------------------------------------------------------------- 22233 * Ticker 22234 * ---------------------------------------------------------------- 22235 */ 22236 var _reqAnimFrame = window.requestAnimationFrame, 22237 _cancelAnimFrame = window.cancelAnimationFrame, 22238 _getTime = Date.now || function () { 22239 return new Date().getTime(); 22240 }, 22241 _lastUpdate = _getTime(); 22242 22243 //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill. 22244 a = ["ms", "moz", "webkit", "o"]; 22245 i = a.length; 22246 while (--i > -1 && !_reqAnimFrame) { 22247 _reqAnimFrame = window[a[i] + "RequestAnimationFrame"]; 22248 _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"]; 22249 } 22250 22251 _class("Ticker", function (fps, useRAF) { 22252 var _self = this, 22253 _startTime = _getTime(), 22254 _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false, 22255 _lagThreshold = 500, 22256 _adjustedLag = 33, 22257 _tickWord = "tick", 22258 //helps reduce gc burden 22259 _fps, 22260 _req, 22261 _id, 22262 _gap, 22263 _nextTime, 22264 _tick = function (manual) { 22265 var elapsed = _getTime() - _lastUpdate, 22266 overlap, 22267 dispatch; 22268 if (elapsed > _lagThreshold) { 22269 _startTime += elapsed - _adjustedLag; 22270 } 22271 _lastUpdate += elapsed; 22272 _self.time = (_lastUpdate - _startTime) / 1000; 22273 overlap = _self.time - _nextTime; 22274 if (!_fps || overlap > 0 || manual === true) { 22275 _self.frame++; 22276 _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap); 22277 dispatch = true; 22278 } 22279 if (manual !== true) { 22280 //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. 22281 _id = _req(_tick); 22282 }
22283 if (dispatch) { 22284 _self.dispatchEvent(_tickWord); 22285 } 22286 }; 22287 22288 EventDispatcher.call(_self); 22289 _self.time = _self.frame = 0; 22290 _self.tick = function () { 22291 _tick(true); 22292 }; 22293 22294 _self.lagSmoothing = function (threshold, adjustedLag) { 22295 if (!arguments.length) { 22296 //if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use. 22297 return _lagThreshold < 1 / _tinyNum; 22298 } 22299 _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited 22300 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 22301 }; 22302 22303 _self.sleep = function () { 22304 if (_id == null) { 22305 return; 22306 } 22307 if (!_useRAF || !_cancelAnimFrame) { 22308 clearTimeout(_id); 22309 } else { 22310 _cancelAnimFrame(_id); 22311 } 22312 _req = _emptyFunc; 22313 _id = null; 22314 if (_self === _ticker) { 22315 _tickerActive = false; 22316 } 22317 }; 22318 22319 _self.wake = function (seamless) { 22320 if (_id !== null) { 22321 _self.sleep(); 22322 } else if (seamless) { 22323 _startTime += -_lastUpdate + (_lastUpdate = _getTime()); 22324 } else if (_self.frame > 10) { 22325 //don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout(). 22326 _lastUpdate = _getTime() - _lagThreshold + 5; 22327 } 22328 _req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) { 22329 return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0); 22330 } : _reqAnimFrame; 22331 if (_self === _ticker) { 22332 _tickerActive = true; 22333 } 22334 _tick(2); 22335 }; 22336 22337 _self.fps = function (value) { 22338 if (!arguments.length) { 22339 return _fps; 22340 } 22341 _fps = value; 22342 _gap = 1 / (_fps || 60); 22343 _nextTime = this.time + _gap; 22344 _self.wake(); 22345 }; 22346 22347 _self.useRAF = function (value) { 22348 if (!arguments.length) { 22349 return _useRAF; 22350 } 22351 _self.sleep(); 22352 _useRAF = value; 22353 _self.fps(_fps); 22354 }; 22355 _self.fps(fps); 22356 22357 //a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition. 22358 setTimeout(function () { 22359 if (_useRAF === "auto" && _self.frame < 5 && _doc.visibilityState !== "hidden") { 22360 _self.useRAF(false); 22361 } 22362 }, 1500); 22363 }); 22364 22365 p = gs.Ticker.prototype = new gs.events.EventDispatcher(); 22366 p.constructor = gs.Ticker; 22367 22368 /* 22369 * ---------------------------------------------------------------- 22370 * Animation 22371 * ---------------------------------------------------------------- 22372 */ 22373 var Animation = _class("core.Animation", function (duration, vars) { 22374 this.vars = vars = vars || {}; 22375 this._duration = this._totalDuration = duration || 0; 22376 this._delay = Number(vars.delay) || 0; 22377 this._timeScale = 1; 22378 this._active = vars.immediateRender === true; 22379 this.data = vars.data; 22380 this._reversed = vars.reversed === true; 22381 22382 if (!_rootTimeline) { 22383 return; 22384 } 22385 if (!_tickerActive) { 22386 //some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly. 22387 _ticker.wake(); 22388 } 22389 22390 var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline; 22391 tl.add(this, tl._time); 22392 22393 if (this.vars.paused) { 22394 this.paused(true); 22395 } 22396 }); 22397 22398 _ticker = Animation.ticker = new gs.Ticker(); 22399 p = Animation.prototype; 22400 p._dirty = p._gc = p._initted = p._paused = false; 22401 p._totalTime = p._time = 0; 22402 p._rawPrevTime = -1; 22403 p._next = p._last = p._onUpdate = p._timeline = p.timeline = null; 22404 p._paused = false; 22405 22406 //some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker. 22407 var _checkTimeout = function () { 22408 if (_tickerActive && _getTime() - _lastUpdate > 2000 && (_doc.visibilityState !== "hidden" || !_ticker.lagSmoothing())) { 22409 //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled. 22410 _ticker.wake(); 22411 } 22412 var t = setTimeout(_checkTimeout, 2000); 22413 if (t.unref) { 22414 // allows a node process to exit even if the timeoutâs callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds. 22415 t.unref(); 22416 } 22417 }; 22418 _checkTimeout(); 22419 22420 p.play = function (from, suppressEvents) { 22421 if (from != null) { 22422 this.seek(from, suppressEvents); 22423 } 22424 return this.reversed(false).paused(false); 22425 }; 22426 22427 p.pause = function (atTime, suppressEvents) { 22428 if (atTime != null) { 22429 this.seek(atTime, suppressEvents); 22430 } 22431 return this.paused(true); 22432 }; 22433 22434 p.resume = function (from, suppressEvents) { 22435 if (from != null) { 22436 this.seek(from, suppressEvents); 22437 } 22438 return this.paused(false); 22439 }; 22440 22441 p.seek = function (time, suppressEvents) { 22442 return this.totalTime(Number(time), suppressEvents !== false); 22443 }; 22444 22445 p.restart = function (includeDelay, suppressEvents) { 22446 return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true); 22447 }; 22448 22449 p.reverse = function (from, suppressEvents) { 22450 if (from != null) { 22451 this.seek(from || this.totalDuration(), suppressEvents); 22452 } 22453 return this.reversed(true).paused(false); 22454 }; 22455 22456 p.render = function (time, suppressEvents, force) { 22457 //stub - we override this method in subclasses. 22458 }; 22459 22460 p.invalidate = function () { 22461 this._time = this._totalTime = 0; 22462 this._initted = this._gc = false;
22463 this._rawPrevTime = -1; 22464 if (this._gc || !this.timeline) { 22465 this._enabled(true); 22466 } 22467 return this; 22468 }; 22469 22470 p.isActive = function () { 22471 var tl = this._timeline, 22472 //the 2 root timelines won't have a _timeline; they're always active. 22473 startTime = this._startTime, 22474 rawTime; 22475 return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001; 22476 }; 22477 22478 p._enabled = function (enabled, ignoreTimeline) { 22479 if (!_tickerActive) { 22480 _ticker.wake(); 22481 } 22482 this._gc = !enabled; 22483 this._active = this.isActive(); 22484 if (ignoreTimeline !== true) { 22485 if (enabled && !this.timeline) { 22486 this._timeline.add(this, this._startTime - this._delay); 22487 } else if (!enabled && this.timeline) { 22488 this._timeline._remove(this, true); 22489 } 22490 } 22491 return false; 22492 }; 22493 22494 p._kill = function (vars, target) { 22495 return this._enabled(false, false); 22496 }; 22497 22498 p.kill = function (vars, target) { 22499 this._kill(vars, target); 22500 return this; 22501 }; 22502 22503 p._uncache = function (includeSelf) { 22504 var tween = includeSelf ? this : this.timeline; 22505 while (tween) { 22506 tween._dirty = true; 22507 tween = tween.timeline; 22508 } 22509 return this; 22510 }; 22511 22512 p._swapSelfInParams = function (params) { 22513 var i = params.length, 22514 copy = params.concat(); 22515 while (--i > -1) { 22516 if (params[i] === "{self}") { 22517 copy[i] = this; 22518 } 22519 } 22520 return copy; 22521 }; 22522 22523 p._callback = function (type) { 22524 var v = this.vars, 22525 callback = v[type], 22526 params = v[type + "Params"], 22527 scope = v[type + "Scope"] || v.callbackScope || this, 22528 l = params ? params.length : 0; 22529 switch (l) {//speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray); 22530 case 0: 22531 callback.call(scope);break; 22532 case 1: 22533 callback.call(scope, params[0]);break; 22534 case 2: 22535 callback.call(scope, params[0], params[1]);break; 22536 default: 22537 callback.apply(scope, params); 22538 } 22539 }; 22540 22541 //----Animation getters/setters -------------------------------------------------------- 22542 22543 p.eventCallback = function (type, callback, params, scope) { 22544 if ((type || "").substr(0, 2) === "on") { 22545 var v = this.vars; 22546 if (arguments.length === 1) { 22547 return v[type]; 22548 } 22549 if (callback == null) { 22550 delete v[type]; 22551 } else { 22552 v[type] = callback; 22553 v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params; 22554 v[type + "Scope"] = scope; 22555 } 22556 if (type === "onUpdate") { 22557 this._onUpdate = callback; 22558 } 22559 } 22560 return this; 22561 }; 22562 22563 p.delay = function (value) { 22564 if (!arguments.length) { 22565 return this._delay; 22566 } 22567 if (this._timeline.smoothChildTiming) { 22568 this.startTime(this._startTime + value - this._delay); 22569 } 22570 this._delay = value; 22571 return this; 22572 }; 22573 22574 p.duration = function (value) { 22575 if (!arguments.length) { 22576 this._dirty = false; 22577 return this._duration; 22578 } 22579 this._duration = this._totalDuration = value; 22580 this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration. 22581 if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) { 22582 this.totalTime(this._totalTime * (value / this._duration), true); 22583 } 22584 return this; 22585 }; 22586 22587 p.totalDuration = function (value) { 22588 this._dirty = false; 22589 return !arguments.length ? this._totalDuration : this.duration(value); 22590 }; 22591 22592 p.time = function (value, suppressEvents) { 22593 if (!arguments.length) { 22594 return this._time; 22595 } 22596 if (this._dirty) { 22597 this.totalDuration(); 22598 } 22599 return this.totalTime(value > this._duration ? this._duration : value, suppressEvents); 22600 }; 22601 22602 p.totalTime = function (time, suppressEvents, uncapped) { 22603 if (!_tickerActive) { 22604 _ticker.wake(); 22605 } 22606 if (!arguments.length) { 22607 return this._totalTime; 22608 } 22609 if (this._timeline) { 22610 if (time < 0 && !uncapped) { 22611 time += this.totalDuration(); 22612 } 22613 if (this._timeline.smoothChildTiming) { 22614 if (this._dirty) { 22615 this.totalDuration(); 22616 } 22617 var totalDuration = this._totalDuration, 22618 tl = this._timeline; 22619 if (time > totalDuration && !uncapped) { 22620 time = totalDuration; 22621 } 22622 this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale; 22623 if (!tl._dirty) { 22624 //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. 22625 this._uncache(false); 22626 } 22627 //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
22627ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed. 22628 if (tl._timeline) { 22629 while (tl._timeline) { 22630 if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) { 22631 tl.totalTime(tl._totalTime, true); 22632 } 22633 tl = tl._timeline; 22634 } 22635 } 22636 } 22637 if (this._gc) { 22638 this._enabled(true, false); 22639 } 22640 if (this._totalTime !== time || this._duration === 0) { 22641 if (_lazyTweens.length) { 22642 _lazyRender(); 22643 } 22644 this.render(time, suppressEvents, false); 22645 if (_lazyTweens.length) { 22646 //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. 22647 _lazyRender(); 22648 } 22649 } 22650 } 22651 return this; 22652 }; 22653 22654 p.progress = p.totalProgress = function (value, suppressEvents) { 22655 var duration = this.duration(); 22656 return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents); 22657 }; 22658 22659 p.startTime = function (value) { 22660 if (!arguments.length) { 22661 return this._startTime; 22662 } 22663 if (value !== this._startTime) { 22664 this._startTime = value; 22665 if (this.timeline) if (this.timeline._sortChildren) { 22666 this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct. 22667 } 22668 } 22669 return this; 22670 }; 22671 22672 p.endTime = function (includeRepeats) { 22673 return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale; 22674 }; 22675 22676 p.timeScale = function (value) { 22677 if (!arguments.length) { 22678 return this._timeScale; 22679 } 22680 var pauseTime, t; 22681 value = value || _tinyNum; //can't allow zero because it'll throw the math off 22682 if (this._timeline && this._timeline.smoothChildTiming) { 22683 pauseTime = this._pauseTime; 22684 t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime(); 22685 this._startTime = t - (t - this._startTime) * this._timeScale / value; 22686 } 22687 this._timeScale = value; 22688 t = this.timeline; 22689 while (t && t.timeline) { 22690 //must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though. 22691 t._dirty = true; 22692 t.totalDuration(); 22693 t = t.timeline; 22694 } 22695 return this; 22696 }; 22697 22698 p.reversed = function (value) { 22699 if (!arguments.length) { 22700 return this._reversed; 22701 } 22702 if (value != this._reversed) { 22703 this._reversed = value; 22704 this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true); 22705 } 22706 return this; 22707 }; 22708 22709 p.paused = function (value) { 22710 if (!arguments.length) { 22711 return this._paused; 22712 } 22713 var tl = this._timeline, 22714 raw, 22715 elapsed; 22716 if (value != this._paused) if (tl) { 22717 if (!_tickerActive && !value) { 22718 _ticker.wake(); 22719 } 22720 raw = tl.rawTime();
22721 elapsed = raw - this._pauseTime; 22722 if (!value && tl.smoothChildTiming) { 22723 this._startTime += elapsed; 22724 this._uncache(false); 22725 } 22726 this._pauseTime = value ? raw : null; 22727 this._paused = value; 22728 this._active = this.isActive(); 22729 if (!value && elapsed !== 0 && this._initted && this.duration()) { 22730 raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale; 22731 this.render(raw, raw === this._totalTime, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render. 22732 } 22733 } 22734 if (this._gc && !value) { 22735 this._enabled(true, false); 22736 } 22737 return this; 22738 }; 22739 22740 /* 22741 * ---------------------------------------------------------------- 22742 * SimpleTimeline 22743 * ---------------------------------------------------------------- 22744 */ 22745 var SimpleTimeline = _class("core.SimpleTimeline", function (vars) { 22746 Animation.call(this, 0, vars); 22747 this.autoRemoveChildren = this.smoothChildTiming = true; 22748 }); 22749 22750 p = SimpleTimeline.prototype = new Animation(); 22751 p.constructor = SimpleTimeline; 22752 p.kill()._gc = false; 22753 p._first = p._last = p._recent = null; 22754 p._sortChildren = false; 22755 22756 p.add = p.insert = function (child, position, align, stagger) { 22757 var prevTween, st; 22758 child._startTime = Number(position || 0) + child._delay; 22759 if (child._paused) if (this !== child._timeline) { 22760 //we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order). 22761 child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale; 22762 } 22763 if (child.timeline) { 22764 child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one. 22765 } 22766 child.timeline = child._timeline = this; 22767 if (child._gc) { 22768 child._enabled(true, true); 22769 } 22770 prevTween = this._last; 22771 if (this._sortChildren) { 22772 st = child._startTime; 22773 while (prevTween && prevTween._startTime > st) { 22774 prevTween = prevTween._prev; 22775 } 22776 } 22777 if (prevTween) { 22778 child._next = prevTween._next; 22779 prevTween._next = child; 22780 } else { 22781 child._next = this._first; 22782 this._first = child; 22783 } 22784 if (child._next) { 22785 child._next._prev = child; 22786 } else { 22787 this._last = child; 22788 } 22789 child._prev = prevTween; 22790 this._recent = child; 22791 if (this._timeline) { 22792 this._uncache(true); 22793 } 22794 return this; 22795 }; 22796 22797 p._remove = function (tween, skipDisable) { 22798 if (tween.timeline === this) { 22799 if (!skipDisable) { 22800 tween._enabled(false, true); 22801 } 22802 22803 if (tween._prev) { 22804 tween._prev._next = tween._next; 22805 } else if (this._first === tween) { 22806 this._first = tween._next; 22807 } 22808 if (tween._next) { 22809 tween._next._prev = tween._prev; 22810 } else if (this._last === tween) { 22811 this._last = tween._prev; 22812 } 22813 tween._next = tween._prev = tween.timeline = null; 22814 if (tween === this._recent) { 22815 this._recent = this._last; 22816 } 22817 22818 if (this._timeline) { 22819 this._uncache(true); 22820 } 22821 } 22822 return this; 22823 }; 22824 22825 p.render = function (time, suppressEvents, force) { 22826 var tween = this._first, 22827 next; 22828 this._totalTime = this._time = this._rawPrevTime = time; 22829 while (tween) { 22830 next = tween._next; //record it here because the value could change after rendering... 22831 if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) { 22832 if (!tween._reversed) { 22833 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 22834 } else { 22835 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 22836 } 22837 } 22838 tween = next; 22839 } 22840 }; 22841 22842 p.rawTime = function () { 22843 if (!_tickerActive) { 22844 _ticker.wake(); 22845 } 22846 return this._totalTime; 22847 }; 22848 22849 /* 22850 * ---------------------------------------------------------------- 22851 * TweenLite 22852 * ---------------------------------------------------------------- 22853 */ 22854 var TweenLite = _class("TweenLite", function (target, duration, vars) { 22855 Animation.call(this, duration, vars); 22856 this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method) 22857 22858 if (target == null) { 22859 throw "Cannot tween a null target."; 22860 } 22861 22862 this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target; 22863 22864 var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
22865 overwrite = this.vars.overwrite, 22866 i, 22867 targ, 22868 targets; 22869 22870 this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite]; 22871 22872 if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") { 22873 this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 22874 this._propLookup = []; 22875 this._siblings = []; 22876 for (i = 0; i < targets.length; i++) { 22877 targ = targets[i]; 22878 if (!targ) { 22879 targets.splice(i--, 1); 22880 continue; 22881 } else if (typeof targ === "string") { 22882 targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings 22883 if (typeof targ === "string") { 22884 targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case) 22885 } 22886 continue; 22887 } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) { 22888 //in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself. 22889 targets.splice(i--, 1); 22890 this._targets = targets = targets.concat(_slice(targ)); 22891 continue; 22892 } 22893 this._siblings[i] = _register(targ, this, false); 22894 if (overwrite === 1) if (this._siblings[i].length > 1) { 22895 _applyOverwrite(targ, this, null, 1, this._siblings[i]); 22896 } 22897 } 22898 } else { 22899 this._propLookup = {}; 22900 this._siblings = _register(target, this, false); 22901 if (overwrite === 1) if (this._siblings.length > 1) { 22902 _applyOverwrite(target, this, null, 1, this._siblings); 22903 } 22904 } 22905 if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) { 22906 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 22907 this.render(Math.min(0, -this._delay)); //in case delay is negative 22908 } 22909 }, true), 22910 _isSelector = function (v) { 22911 return v && v.length && v !== window && v[0] && (v[0] === window || v[0].nodeType && v[0].style && !v.nodeType); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox. 22912 }, 22913 _autoCSS = function (vars, target) { 22914 var css = {}, 22915 p; 22916 for (p in vars) { 22917 if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || _plugins[p] && _plugins[p]._autoCSS)) { 22918 //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties. 22919 css[p] = vars[p]; 22920 delete vars[p]; 22921 } 22922 } 22923 vars.css = css; 22924 }; 22925 22926 p = TweenLite.prototype = new Animation(); 22927 p.constructor = TweenLite; 22928 p.kill()._gc = false; 22929 22930 //----TweenLite defaults, overwrite management, and root updates ---------------------------------------------------- 22931 22932 p.ratio = 0; 22933 p._firstPT = p._targets = p._overwrittenProps = p._startAt = null; 22934 p._notifyPluginsOfEnabled = p._lazy = false; 22935 22936 TweenLite.version = "1.20.3"; 22937 TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1); 22938 TweenLite.defaultOverwrite = "auto"; 22939 TweenLite.ticker = _ticker; 22940 TweenLite.autoSleep = 120; 22941 TweenLite.lagSmoothing = function (threshold, adjustedLag) { 22942 _ticker.lagSmoothing(threshold, adjustedLag); 22943 }; 22944 22945 TweenLite.selector = window.$ || window.jQuery || function (e) { 22946 var selector = window.$ || window.jQuery; 22947 if (selector) { 22948 TweenLite.selector = selector; 22949 return selector(e); 22950 } 22951 return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e); 22952 }; 22953 22954 var _lazyTweens = [], 22955 _lazyLookup = {}, 22956 _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 22957 _relExp = /[\+-]=-?[\.\d]/, 22958 22959 //_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig, 22960 _setRatio = function (v) { 22961 var pt = this._firstPT, 22962 min = 0.000001, 22963 val; 22964 while (pt) { 22965 val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start; 22966 if (pt.m) { 22967 val = pt.m(val, this._target || pt.t); 22968 } else if (val < min) if (val > -min && !pt.blob) {
22969 //prevents issues with converting very small numbers to strings in the browser 22970 val = 0; 22971 } 22972 if (!pt.f) { 22973 pt.t[pt.p] = val; 22974 } else if (pt.fp) { 22975 pt.t[pt.p](pt.fp, val); 22976 } else { 22977 pt.t[pt.p](val); 22978 } 22979 pt = pt._next; 22980 } 22981 }, 22982 22983 //compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")). 22984 _blobDif = function (start, end, filter, pt) { 22985 var a = [], 22986 charIndex = 0, 22987 s = "", 22988 color = 0, 22989 startNums, 22990 endNums, 22991 num, 22992 i, 22993 l, 22994 nonNumbers, 22995 currentNum; 22996 a.start = start; 22997 a.end = end; 22998 start = a[0] = start + ""; //ensure values are strings 22999 end = a[1] = end + ""; 23000 if (filter) { 23001 filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 23002 start = a[0]; 23003 end = a[1]; 23004 } 23005 a.length = 0; 23006 startNums = start.match(_numbersExp) || []; 23007 endNums = end.match(_numbersExp) || []; 23008 if (pt) { 23009 pt._next = null; 23010 pt.blob = 1; 23011 a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first) 23012 } 23013 l = endNums.length; 23014 for (i = 0; i < l; i++) { 23015 currentNum = endNums[i]; 23016 nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex); 23017 s += nonNumbers || !i ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 23018 charIndex += nonNumbers.length; 23019 if (color) { 23020 //sense rgba() values and round them. 23021 color = (color + 1) % 5; 23022 } else if (nonNumbers.substr(-5) === "rgba(") { 23023 color = 1; 23024 } 23025 if (currentNum === startNums[i] || startNums.length <= i) { 23026 s += currentNum; 23027 } else { 23028 if (s) { 23029 a.push(s); 23030 s = ""; 23031 } 23032 num = parseFloat(startNums[i]); 23033 a.push(num); 23034 a._firstPT = { _next: a._firstPT, t: a, p: a.length - 1, s: num, c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0, f: 0, m: color && color < 4 ? Math.round : 0 }; 23035 //note: we don't set _prev because we'll never need to remove individual PropTweens from this list. 23036 } 23037 charIndex += currentNum.length; 23038 } 23039 s += end.substr(charIndex); 23040 if (s) { 23041 a.push(s); 23042 } 23043 a.setRatio = _setRatio; 23044 if (_relExp.test(end)) { 23045 //if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 23046 a.end = null; 23047 } 23048 return a; 23049 }, 23050 23051 //note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example. 23052 _addPropTween = function (target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) { 23053 if (typeof end === "function") { 23054 end = end(index || 0, target); 23055 } 23056 var type = typeof target[prop], 23057 getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3), 23058 s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](), 23059 isRelative = typeof end === "string" && end.charAt(1) === "=", 23060 pt = { t: target, p: prop, s: s, f: type === "function", pg: 0, n: overwriteProp || prop, m: !mod ? 0 : typeof mod === "function" ? mod : Math.round, pr: 0, c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0 }, 23061 blob; 23062 23063 if (typeof s !== "number" || typeof end !== "number" && !isRelative) { 23064 if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") { 23065 //a blob (string that has multiple numbers in it) 23066 pt.fp = funcParam; 23067 blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c : end, stringFilter || TweenLite.defaultStringFilter, pt); 23068 pt = { t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0 }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example. 23069 } else { 23070 pt.s = parseFloat(s); 23071 if (!isRelative) { 23072 pt.c = parseFloat(end) - pt.s || 0; 23073 } 23074 } 23075 } 23076 if (pt.c) { 23077 //only add it to the linked list if there's a change. 23078 if (pt._next = this._firstPT) { 23079 pt._next._prev = pt; 23080 } 23081 this._firstPT = pt; 23082 return pt; 23083 } 23084 }, 23085 _internals = TweenLite._internals = { isArray: _isArray, isSelector: _isSelector, lazyTweens: _lazyTweens, blobDif: _blobDif }, 23086 //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object. 23087 _plugins = TweenLite._plugins = {}, 23088 _tweenLookup = _internals.tweenLookup = {}, 23089 _tweenLookupNum = 0, 23090 _reservedProps = _internals.reservedProps = { ease: 1, delay: 1, overwrite: 1, onComplete: 1, onCompleteParams: 1, onCompleteScope: 1, useFrames: 1, runBackwards: 1, startAt: 1, onUpdate: 1, onUpdateParams: 1, onUpdateScope: 1, onStart: 1, onStartParams: 1, onStartScope: 1, onReverseComplete: 1, onReverseCompleteParams: 1, onReverseCompleteScope: 1, onRepeat: 1, onRepeatParams: 1, onRepeatScope: 1, easeParams: 1, yoyo: 1, immediateRender: 1, repeat: 1, repeatDelay: 1, data: 1, paused: 1, reversed: 1, autoCSS: 1, lazy: 1, onOverwrite: 1, callbackScope: 1, str
23090ingFilter: 1, id: 1, yoyoEase: 1 }, 23091 _overwriteLookup = { none: 0, all: 1, auto: 2, concurrent: 3, allOnStart: 4, preexisting: 5, "true": 1, "false": 0 }, 23092 _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(), 23093 _rootTimeline = Animation._rootTimeline = new SimpleTimeline(), 23094 _nextGCFrame = 30, 23095 _lazyRender = _internals.lazyRender = function () { 23096 var i = _lazyTweens.length, 23097 tween; 23098 _lazyLookup = {}; 23099 while (--i > -1) { 23100 tween = _lazyTweens[i]; 23101 if (tween && tween._lazy !== false) { 23102 tween.render(tween._lazy[0], tween._lazy[1], true); 23103 tween._lazy = false; 23104 } 23105 } 23106 _lazyTweens.length = 0; 23107 }; 23108 23109 _rootTimeline._startTime = _ticker.time; 23110 _rootFramesTimeline._startTime = _ticker.frame; 23111 _rootTimeline._active = _rootFramesTimeline._active = true; 23112 setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick". 23113 23114 Animation._updateRoot = TweenLite.render = function () { 23115 var i, a, p; 23116 if (_lazyTweens.length) { 23117 //if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again. 23118 _lazyRender(); 23119 } 23120 _rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false); 23121 _rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false); 23122 if (_lazyTweens.length) { 23123 _lazyRender(); 23124 } 23125 if (_ticker.frame >= _nextGCFrame) { 23126 //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to 23127 _nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120); 23128 for (p in _tweenLookup) { 23129 a = _tweenLookup[p].tweens; 23130 i = a.length; 23131 while (--i > -1) { 23132 if (a[i]._gc) { 23133 a.splice(i, 1); 23134 } 23135 } 23136 if (a.length === 0) { 23137 delete _tweenLookup[p]; 23138 } 23139 } 23140 //if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly 23141 p = _rootTimeline._first; 23142 if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) { 23143 while (p && p._paused) { 23144 p = p._next; 23145 } 23146 if (!p) { 23147 _ticker.sleep(); 23148 } 23149 } 23150 } 23151 }; 23152 23153 _ticker.addEventListener("tick", Animation._updateRoot); 23154 23155 var _register = function (target, tween, scrub) { 23156 var id = target._gsTweenID, 23157 a, 23158 i; 23159 if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) { 23160 _tweenLookup[id] = { target: target, tweens: [] }; 23161 } 23162 if (tween) { 23163 a = _tweenLookup[id].tweens; 23164 a[i = a.length] = tween; 23165 if (scrub) { 23166 while (--i > -1) { 23167 if (a[i] === tween) { 23168 a.splice(i, 1); 23169 } 23170 } 23171 } 23172 } 23173 return _tweenLookup[id].tweens; 23174 }, 23175 _onOverwrite = function (overwrittenTween, overwritingTween, target, killedProps) { 23176 var func = overwrittenTween.vars.onOverwrite, 23177 r1, 23178 r2; 23179 if (func) { 23180 r1 = func(overwrittenTween, overwritingTween, target, killedProps); 23181 } 23182 func = TweenLite.onOverwrite; 23183 if (func) { 23184 r2 = func(overwrittenTween, overwritingTween, target, killedProps); 23185 } 23186 return r1 !== false && r2 !== false; 23187 }, 23188 _applyOverwrite = function (target, tween, props, mode, siblings) { 23189 var i, changed, curTween, l; 23190 if (mode === 1 || mode >= 4) { 23191 l = siblings.length; 23192 for (i = 0; i < l; i++) { 23193 if ((curTween = siblings[i]) !== tween) { 23194 if (!curTween._gc) { 23195 if (curTween._kill(null, target, tween)) { 23196 changed = true; 23197 } 23198 } 23199 } else if (mode === 5) { 23200 break; 23201 } 23202 } 23203 return changed; 23204 } 23205 //NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example) 23206 var startTime = tween._startTime + _tinyNum, 23207 overlaps = [], 23208 oCount = 0, 23209 zeroDur = tween._duration === 0, 23210 globalStart; 23211 i = siblings.length; 23212 while (--i > -1) { 23213 if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) { 23214 //ignore 23215 } else if (curTween._timeline !== tween._timeline) { 23216 globalStart = globalStart || _checkOverlap(tween, 0, zeroDur); 23217 if (_checkOverlap(curTween, globalStart, zeroDur) === 0) { 23218 overlaps[oCount++] = curTween; 23219 } 23220 } else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) { 23221 overlaps[oCount++] = curTween; 23222 } 23223 } 23224 23225 i = oCount; 23226 while (--i > -1) { 23227 curTween = overlaps[i]; 23228 if (mode === 2) if (curTween._kill(props, target, tween)) { 23229 changed = true; 23230 } 23231 if (mode !== 2 || !curTween._firstPT && curTween._initted) { 23232 if (mode !== 2 && !_onOverwrite(curTween, tween)) { 23233 continue; 23234 } 23235 if (curTween._enabled(false, false)) { 23236 //if all property tweens have been overwritten, kill the tween. 23237 changed = true; 23238 } 23239 } 23240 } 23241 return changed; 23242 }, 23243 _checkOverlap = function (tween, reference, zeroDur) { 23244 var tl = tween._timeline, 23245 ts = tl._timeScale, 23246 t = tween._startTime; 23247 while (tl._timeline) { 23248 t += tl._startTime; 23249 ts *= tl._timeScale; 23250 if (tl._paused) { 23251 return -100; 23252 } 23253 tl = tl._timeline; 23254 } 23255 t /= ts; 23256 return t > reference ? t - reference : zeroDur && t === reference || !tween._initted && t - reference < 2 * _tinyNum ? _tinyNum : (t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum ? 0 : t - reference - _tinyNum; 23257 }; 23258 23259 //---- TweenLite instance methods ----------------------------------------------------------------------------- 23260 23261 p._init = function () { 23262 var v = this.vars, 23263 op = this._overwrittenProps, 23264 dur = this._duration, 23265 immediate = !!v.immediateRender, 23266 ease = v.ease, 23267 i, 23268 initPlugins, 23269 pt, 23270 p, 23271 startVars, 23272 l; 23273 if (v.startAt) { 23274 if (this._startAt) { 23275 this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change. 23276 this._startAt.kill(); 23277 } 23278 startVars = {}; 23279 for (p in v.startAt) { 23280 //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from); 23281 startVars[p] = v.startAt[p]; 23282 } 23283 startVars.data = "isStart"; 23284 startVars.overwrite = false;
23285 startVars.immediateRender = true; 23286 startVars.lazy = immediate && v.lazy !== false; 23287 startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop). 23288 startVars.onUpdate = v.onUpdate; 23289 startVars.onUpdateParams = v.onUpdateParams; 23290 startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this; 23291 this._startAt = TweenLite.to(this.target, 0, startVars); 23292 if (immediate) { 23293 if (this._time > 0) { 23294 this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()). 23295 } else if (dur !== 0) { 23296 return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting. 23297 } 23298 } 23299 } else if (v.runBackwards && dur !== 0) { 23300 //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards) 23301 if (this._startAt) { 23302 this._startAt.render(-1, true); 23303 this._startAt.kill(); 23304 this._startAt = null; 23305 } else { 23306 if (this._time !== 0) { 23307 //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0 23308 immediate = false; 23309 } 23310 pt = {}; 23311 for (p in v) { 23312 //copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through. 23313 if (!_reservedProps[p] || p === "autoCSS") { 23314 pt[p] = v[p]; 23315 } 23316 } 23317 pt.overwrite = 0; 23318 pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in. 23319 pt.lazy = immediate && v.lazy !== false; 23320 pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after) 23321 this._startAt = TweenLite.to(this.target, 0, pt); 23322 if (!immediate) { 23323 this._startAt._init(); //ensures that the initial values are recorded 23324 this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween. 23325 if (this.vars.immediateRender) { 23326 this._startAt = null; 23327 } 23328 } else if (this._time === 0) { 23329 return; 23330 } 23331 } 23332 } 23333 this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase; 23334 if (v.easeParams instanceof Array && ease.config) { 23335 this._ease = ease.config.apply(ease, v.easeParams); 23336 } 23337 this._easeType = this._ease._type; 23338 this._easePower = this._ease._power; 23339 this._firstPT = null; 23340 23341 if (this._targets) { 23342 l = this._targets.length; 23343 for (i = 0; i < l; i++) { 23344 if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) { 23345 initPlugins = true; 23346 } 23347 } 23348 } else { 23349 initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0); 23350 } 23351 23352 if (initPlugins) { 23353 TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite 23354 } 23355 if (op) if (!this._firstPT) if (typeof this.target !== "function") { 23356 //if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live. 23357 this._enabled(false, false); 23358 } 23359 if (v.runBackwards) { 23360 pt = this._firstPT; 23361 while (pt) { 23362 pt.s += pt.c; 23363 pt.c = -pt.c; 23364 pt = pt._next; 23365 } 23366 } 23367 this._onUpdate = v.onUpdate; 23368 this._initted = true; 23369 }; 23370 23371 p._initProps = function (target, propLookup, siblings, overwrittenProps, index) { 23372 var p, i, initPlugins, plugin, pt, v; 23373 if (target == null) { 23374 return false;
23375 } 23376 23377 if (_lazyLookup[target._gsTweenID]) { 23378 _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end) 23379 } 23380 23381 if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) { 23382 //it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe. 23383 _autoCSS(this.vars, target); 23384 } 23385 for (p in this.vars) { 23386 v = this.vars[p]; 23387 if (_reservedProps[p]) { 23388 if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) { 23389 this.vars[p] = v = this._swapSelfInParams(v, this); 23390 } 23391 } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) { 23392 23393 //t - target [object] 23394 //p - property [string] 23395 //s - start [number] 23396 //c - change [number] 23397 //f - isFunction [boolean] 23398 //n - name [string] 23399 //pg - isPlugin [boolean] 23400 //pr - priority [number] 23401 //m - mod [function | 0] 23402 this._firstPT = pt = { _next: this._firstPT, t: plugin, p: "setRatio", s: 0, c: 1, f: 1, n: p, pg: 1, pr: plugin._priority, m: 0 }; 23403 i = plugin._overwriteProps.length; 23404 while (--i > -1) { 23405 propLookup[plugin._overwriteProps[i]] = this._firstPT; 23406 } 23407 if (plugin._priority || plugin._onInitAllProps) { 23408 initPlugins = true; 23409 } 23410 if (plugin._onDisable || plugin._onEnable) { 23411 this._notifyPluginsOfEnabled = true; 23412 } 23413 if (pt._next) { 23414 pt._next._prev = pt; 23415 } 23416 } else { 23417 propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index); 23418 } 23419 } 23420 23421 if (overwrittenProps) if (this._kill(overwrittenProps, target)) { 23422 //another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first) 23423 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 23424 } 23425 if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) { 23426 this._kill(propLookup, target); 23427 return this._initProps(target, propLookup, siblings, overwrittenProps, index); 23428 } 23429 if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) { 23430 //zero duration tweens don't lazy render by default; everything else does. 23431 _lazyLookup[target._gsTweenID] = true; 23432 } 23433 return initPlugins; 23434 }; 23435 23436 p.render = function (time, suppressEvents, force) { 23437 var prevTime = this._time, 23438 duration = this._duration, 23439 prevRawPrevTime = this._rawPrevTime, 23440 isComplete, 23441 callback, 23442 pt, 23443 rawPrevTime; 23444 if (time >= duration - 0.0000001 && time >= 0) { 23445 //to work around occasional floating point math artifacts. 23446 this._totalTime = this._time = duration; 23447 this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1; 23448 if (!this._reversed) { 23449 isComplete = true; 23450 callback = "onComplete"; 23451 force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 23452 } 23453 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 23454 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 23455 if (this._startTime === this._timeline._duration) { 23456 //if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
23456ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate. 23457 time = 0; 23458 } 23459 if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) { 23460 //note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause. 23461 force = true; 23462 if (prevRawPrevTime > _tinyNum) { 23463 callback = "onReverseComplete"; 23464 } 23465 } 23466 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 23467 } 23468 } else if (time < 0.0000001) { 23469 //to work around occasional floating point math artifacts, round super small values to 0. 23470 this._totalTime = this._time = 0; 23471 this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0; 23472 if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) { 23473 callback = "onReverseComplete"; 23474 isComplete = this._reversed; 23475 } 23476 if (time < 0) { 23477 this._active = false; 23478 if (duration === 0) if (this._initted || !this.vars.lazy || force) { 23479 //zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered. 23480 if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) { 23481 force = true; 23482 } 23483 this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 23484 } 23485 } 23486 if (!this._initted || this._startAt && this._startAt.progress()) { 23487 //if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values. 23488 force = true; 23489 } 23490 } else { 23491 this._totalTime = this._time = time; 23492 23493 if (this._easeType) { 23494 var r = time / duration, 23495 type = this._easeType, 23496 pow = this._easePower; 23497 if (type === 1 || type === 3 && r >= 0.5) { 23498 r = 1 - r; 23499 } 23500 if (type === 3) { 23501 r *= 2; 23502 } 23503 if (pow === 1) { 23504 r *= r; 23505 } else if (pow === 2) { 23506 r *= r * r; 23507 } else if (pow === 3) { 23508 r *= r * r * r; 23509 } else if (pow === 4) { 23510 r *= r * r * r * r; 23511 } 23512 23513 if (type === 1) { 23514 this.ratio = 1 - r; 23515 } else if (type === 2) { 23516 this.ratio = r; 23517 } else if (time / duration < 0.5) { 23518 this.ratio = r / 2; 23519 } else { 23520 this.ratio = 1 - r / 2; 23521 } 23522 } else { 23523 this.ratio = this._ease.getRatio(time / duration); 23524 } 23525 } 23526 23527 if (this._time === prevTime && !force) { 23528 return; 23529 } else if (!this._initted) { 23530 this._init(); 23531 if (!this._initted || this._gc) { 23532 //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
23532writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example. 23533 return; 23534 } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) { 23535 this._time = this._totalTime = prevTime; 23536 this._rawPrevTime = prevRawPrevTime; 23537 _lazyTweens.push(this); 23538 this._lazy = [time, suppressEvents]; 23539 return; 23540 } 23541 //_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently. 23542 if (this._time && !isComplete) { 23543 this.ratio = this._ease.getRatio(this._time / duration); 23544 } else if (isComplete && this._ease._calcEnd) { 23545 this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1); 23546 } 23547 } 23548 if (this._lazy !== false) { 23549 //in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time. 23550 this._lazy = false; 23551 } 23552 if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) { 23553 this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done. 23554 } 23555 if (prevTime === 0) { 23556 if (this._startAt) { 23557 if (time >= 0) { 23558 this._startAt.render(time, true, force); 23559 } else if (!callback) { 23560 callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area. 23561 } 23562 } 23563 if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) { 23564 this._callback("onStart"); 23565 } 23566 } 23567 pt = this._firstPT; 23568 while (pt) { 23569 if (pt.f) { 23570 pt.t[pt.p](pt.c * this.ratio + pt.s); 23571 } else { 23572 pt.t[pt.p] = pt.c * this.ratio + pt.s; 23573 } 23574 pt = pt._next; 23575 } 23576 23577 if (this._onUpdate) { 23578 if (time < 0) if (this._startAt && time !== -0.0001) { 23579 //if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values. 23580 this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 23581 } 23582 if (!suppressEvents) if (this._time !== prevTime || isComplete || force) { 23583 this._callback("onUpdate"); 23584 } 23585 } 23586 if (callback) if (!this._gc || force) { 23587 //check _gc because there's a chance that kill() could be called in an onUpdate 23588 if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) { 23589 //-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values. 23590 this._startAt.render(time, true, force); 23591 } 23592 if (isComplete) { 23593 if (this._timeline.autoRemoveChildren) { 23594 this._enabled(false, false); 23595 } 23596 this._active = false; 23597 } 23598 if (!suppressEvents && this.vars[callback]) { 23599 this._callback(callback); 23600 } 23601 if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) { 23602 //the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
23602nario, but possible nonetheless. 23603 this._rawPrevTime = 0; 23604 } 23605 } 23606 }; 23607 23608 p._kill = function (vars, target, overwritingTween) { 23609 if (vars === "all") { 23610 vars = null; 23611 } 23612 if (vars == null) if (target == null || target === this.target) { 23613 this._lazy = false; 23614 return this._enabled(false, false); 23615 } 23616 target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target; 23617 var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline, 23618 i, 23619 overwrittenProps, 23620 p, 23621 pt, 23622 propLookup, 23623 changed, 23624 killProps, 23625 record, 23626 killed; 23627 if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") { 23628 i = target.length; 23629 while (--i > -1) { 23630 if (this._kill(vars, target[i], overwritingTween)) { 23631 changed = true; 23632 } 23633 } 23634 } else { 23635 if (this._targets) { 23636 i = this._targets.length; 23637 while (--i > -1) { 23638 if (target === this._targets[i]) { 23639 propLookup = this._propLookup[i] || {}; 23640 this._overwrittenProps = this._overwrittenProps || []; 23641 overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all"; 23642 break; 23643 } 23644 } 23645 } else if (target !== this.target) { 23646 return false; 23647 } else { 23648 propLookup = this._propLookup; 23649 overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all"; 23650 } 23651 23652 if (propLookup) { 23653 killProps = vars || propLookup; 23654 record = vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof vars !== "object" || !vars._tempKill); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin) 23655 if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) { 23656 for (p in killProps) { 23657 if (propLookup[p]) { 23658 if (!killed) { 23659 killed = []; 23660 } 23661 killed.push(p); 23662 } 23663 } 23664 if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) { 23665 //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it). 23666 return false; 23667 } 23668 } 23669 23670 for (p in killProps) { 23671 if (pt = propLookup[p]) { 23672 if (simultaneousOverwrite) { 23673 //if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween. 23674 if (pt.f) { 23675 pt.t[pt.p](pt.s); 23676 } else { 23677 pt.t[pt.p] = pt.s; 23678 } 23679 changed = true; 23680 } 23681 if (pt.pg && pt.t._kill(killProps)) { 23682 changed = true; //some plugins need to be notified so they can perform cleanup tasks first 23683 } 23684 if (!pt.pg || pt.t._overwriteProps.length === 0) { 23685 if (pt._prev) { 23686 pt._prev._next = pt._next; 23687 } else if (pt === this._firstPT) { 23688 this._firstPT = pt._next; 23689 } 23690 if (pt._next) { 23691 pt._next._prev = pt._prev; 23692 } 23693 pt._next = pt._prev = null; 23694 } 23695 delete propLookup[p]; 23696 } 23697 if (record) { 23698 overwrittenProps[p] = 1; 23699 } 23700 } 23701 if (!this._firstPT && this._initted) { 23702 //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening. 23703 this._enabled(false, false); 23704 } 23705 } 23706 } 23707 return changed; 23708 }; 23709 23710 p.invalidate = function () { 23711 if (this._notifyPluginsOfEnabled) { 23712 TweenLite._onPluginEvent("_onDisable", this); 23713 } 23714 this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null; 23715 this._notifyPluginsOfEnabled = this._active = this._lazy = false;
23716 this._propLookup = this._targets ? {} : []; 23717 Animation.prototype.invalidate.call(this); 23718 if (this.vars.immediateRender) { 23719 this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 23720 this.render(Math.min(0, -this._delay)); //in case delay is negative. 23721 } 23722 return this; 23723 }; 23724 23725 p._enabled = function (enabled, ignoreTimeline) { 23726 if (!_tickerActive) { 23727 _ticker.wake(); 23728 } 23729 if (enabled && this._gc) { 23730 var targets = this._targets, 23731 i; 23732 if (targets) { 23733 i = targets.length; 23734 while (--i > -1) { 23735 this._siblings[i] = _register(targets[i], this, true); 23736 } 23737 } else { 23738 this._siblings = _register(this.target, this, true); 23739 } 23740 } 23741 Animation.prototype._enabled.call(this, enabled, ignoreTimeline); 23742 if (this._notifyPluginsOfEnabled) if (this._firstPT) { 23743 return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this); 23744 } 23745 return false; 23746 }; 23747 23748 //----TweenLite static methods ----------------------------------------------------- 23749 23750 TweenLite.to = function (target, duration, vars) { 23751 return new TweenLite(target, duration, vars); 23752 }; 23753 23754 TweenLite.from = function (target, duration, vars) { 23755 vars.runBackwards = true; 23756 vars.immediateRender = vars.immediateRender != false; 23757 return new TweenLite(target, duration, vars); 23758 }; 23759 23760 TweenLite.fromTo = function (target, duration, fromVars, toVars) { 23761 toVars.startAt = fromVars; 23762 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 23763 return new TweenLite(target, duration, toVars); 23764 }; 23765 23766 TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) { 23767 return new TweenLite(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, lazy: false, useFrames: useFrames, overwrite: 0 }); 23768 }; 23769 23770 TweenLite.set = function (target, vars) { 23771 return new TweenLite(target, 0, vars); 23772 }; 23773 23774 TweenLite.getTweensOf = function (target, onlyActive) { 23775 if (target == null) { 23776 return []; 23777 } 23778 target = typeof target !== "string" ? target : TweenLite.selector(target) || target; 23779 var i, a, j, t; 23780 if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") { 23781 i = target.length; 23782 a = []; 23783 while (--i > -1) { 23784 a = a.concat(TweenLite.getTweensOf(target[i], onlyActive)); 23785 } 23786 i = a.length; 23787 //now get rid of any duplicates (tweens of arrays of objects could cause duplicates) 23788 while (--i > -1) { 23789 t = a[i]; 23790 j = i; 23791 while (--j > -1) { 23792 if (t === a[j]) { 23793 a.splice(i, 1); 23794 } 23795 } 23796 } 23797 } else if (target._gsTweenID) { 23798 a = _register(target).concat(); 23799 i = a.length; 23800 while (--i > -1) { 23801 if (a[i]._gc || onlyActive && !a[i].isActive()) { 23802 a.splice(i, 1); 23803 } 23804 } 23805 } 23806 return a || []; 23807 }; 23808 23809 TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) { 23810 if (typeof onlyActive === "object") { 23811 vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted) 23812 onlyActive = false; 23813 } 23814 var a = TweenLite.getTweensOf(target, onlyActive), 23815 i = a.length; 23816 while (--i > -1) { 23817 a[i]._kill(vars, target); 23818 } 23819 }; 23820 23821 /* 23822 * ---------------------------------------------------------------- 23823 * TweenPlugin (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget) 23824 * ---------------------------------------------------------------- 23825 */ 23826 var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) { 23827 this._overwriteProps = (props || "").split(","); 23828 this._propName = this._overwriteProps[0]; 23829 this._priority = priority || 0; 23830 this._super = TweenPlugin.prototype; 23831 }, true); 23832 23833 p = TweenPlugin.prototype; 23834 TweenPlugin.version = "1.19.0"; 23835 TweenPlugin.API = 2; 23836 p._firstPT = null; 23837 p._addTween = _addPropTween; 23838 p.setRatio = _setRatio; 23839 23840 p._kill = function (lookup) { 23841 var a = this._overwriteProps, 23842 pt = this._firstPT, 23843 i; 23844 if (lookup[this._propName] != null) { 23845 this._overwriteProps = []; 23846 } else { 23847 i = a.length; 23848 while (--i > -1) { 23849 if (lookup[a[i]] != null) { 23850 a.splice(i, 1); 23851 } 23852 } 23853 } 23854 while (pt) { 23855 if (lookup[pt.n] != null) { 23856 if (pt._next) { 23857 pt._next._prev = pt._prev; 23858 } 23859 if (pt._prev) { 23860 pt._prev._next = pt._next; 23861 pt._prev = null; 23862 } else if (this._firstPT === pt) { 23863 this._firstPT = pt._next; 23864 } 23865 } 23866 pt = pt._next; 23867 } 23868 return false;
23869 }; 23870 23871 p._mod = p._roundProps = function (lookup) { 23872 var pt = this._firstPT, 23873 val; 23874 while (pt) { 23875 val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")]; 23876 if (val && typeof val === "function") { 23877 //some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here. 23878 if (pt.f === 2) { 23879 pt.t._applyPT.m = val; 23880 } else { 23881 pt.m = val; 23882 } 23883 } 23884 pt = pt._next; 23885 } 23886 }; 23887 23888 TweenLite._onPluginEvent = function (type, tween) { 23889 var pt = tween._firstPT, 23890 changed, 23891 pt2, 23892 first, 23893 last, 23894 next; 23895 if (type === "_onInitAllProps") { 23896 //sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame. 23897 while (pt) { 23898 next = pt._next; 23899 pt2 = first; 23900 while (pt2 && pt2.pr > pt.pr) { 23901 pt2 = pt2._next; 23902 } 23903 if (pt._prev = pt2 ? pt2._prev : last) { 23904 pt._prev._next = pt; 23905 } else { 23906 first = pt; 23907 } 23908 if (pt._next = pt2) { 23909 pt2._prev = pt; 23910 } else { 23911 last = pt; 23912 } 23913 pt = next; 23914 } 23915 pt = tween._firstPT = first; 23916 } 23917 while (pt) { 23918 if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) { 23919 changed = true; 23920 } 23921 pt = pt._next; 23922 } 23923 return changed; 23924 }; 23925 23926 TweenPlugin.activate = function (plugins) { 23927 var i = plugins.length; 23928 while (--i > -1) { 23929 if (plugins[i].API === TweenPlugin.API) { 23930 _plugins[new plugins[i]()._propName] = plugins[i]; 23931 } 23932 } 23933 return true; 23934 }; 23935 23936 //provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations. 23937 _gsDefine.plugin = function (config) { 23938 if (!config || !config.propName || !config.init || !config.API) { 23939 throw "illegal plugin definition."; 23940 } 23941 var propName = config.propName, 23942 priority = config.priority || 0, 23943 overwriteProps = config.overwriteProps, 23944 map = { init: "_onInitTween", set: "setRatio", kill: "_kill", round: "_mod", mod: "_mod", initAll: "_onInitAllProps" }, 23945 Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () { 23946 TweenPlugin.call(this, propName, priority); 23947 this._overwriteProps = overwriteProps || []; 23948 }, config.global === true), 23949 p = Plugin.prototype = new TweenPlugin(propName), 23950 prop; 23951 p.constructor = Plugin; 23952 Plugin.API = config.API; 23953 for (prop in map) { 23954 if (typeof config[prop] === "function") { 23955 p[map[prop]] = config[prop]; 23956 } 23957 } 23958 Plugin.version = config.version; 23959 TweenPlugin.activate([Plugin]); 23960 return Plugin; 23961 }; 23962 23963 //now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you. 23964 a = window._gsQueue; 23965 if (a) { 23966 for (i = 0; i < a.length; i++) { 23967 a[i](); 23968 } 23969 for (p in _defLookup) { 23970 if (!_defLookup[p].func) { 23971 window.console.log("GSAP encountered missing dependency: " + p); 23972 } 23973 } 23974 } 23975 23976 _tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated 23977})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window, "TweenMax"); 23978/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) 23979 23980/***/ }), 23981/* 8 */ 23982/***/ (function(module, exports, __webpack_require__) { 23983 23984/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 23985 * VERSION: 1.20.3 23986 * DATE: 2017-10-02 23987 * UPDATES AND DOCS AT: http://greensock.com 23988 * 23989 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved. 23990 * This work is subject to the terms at http://greensock.com/standard-license or for
23991 * Club GreenSock members, the software agreement that was issued with your membership. 23992 * 23993 * @author: Jack Doyle, [email protected] 23994 */ 23995var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node 23996(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () { 23997 23998 "use strict"; 23999 24000 _gsScope._gsDefine("TimelineMax", ["TimelineLite", "TweenLite", "easing.Ease"], function (TimelineLite, TweenLite, Ease) { 24001 24002 var TimelineMax = function (vars) { 24003 TimelineLite.call(this, vars); 24004 this._repeat = this.vars.repeat || 0; 24005 this._repeatDelay = this.vars.repeatDelay || 0; 24006 this._cycle = 0; 24007 this._yoyo = this.vars.yoyo === true; 24008 this._dirty = true; 24009 }, 24010 _tinyNum = 0.0000000001, 24011 TweenLiteInternals = TweenLite._internals, 24012 _lazyTweens = TweenLiteInternals.lazyTweens, 24013 _lazyRender = TweenLiteInternals.lazyRender, 24014 _globals = _gsScope._gsDefine.globals, 24015 _easeNone = new Ease(null, null, 1, 0), 24016 p = TimelineMax.prototype = new TimelineLite(); 24017 24018 p.constructor = TimelineMax; 24019 p.kill()._gc = false; 24020 TimelineMax.version = "1.20.3"; 24021 24022 p.invalidate = function () { 24023 this._yoyo = this.vars.yoyo === true; 24024 this._repeat = this.vars.repeat || 0; 24025 this._repeatDelay = this.vars.repeatDelay || 0; 24026 this._uncache(true); 24027 return TimelineLite.prototype.invalidate.call(this); 24028 }; 24029 24030 p.addCallback = function (callback, position, params, scope) { 24031 return this.add(TweenLite.delayedCall(0, callback, params, scope), position); 24032 }; 24033 24034 p.removeCallback = function (callback, position) { 24035 if (callback) { 24036 if (position == null) { 24037 this._kill(null, callback); 24038 } else { 24039 var a = this.getTweensOf(callback, false), 24040 i = a.length, 24041 time = this._parseTimeOrLabel(position); 24042 while (--i > -1) { 24043 if (a[i]._startTime === time) { 24044 a[i]._enabled(false, false); 24045 } 24046 } 24047 } 24048 } 24049 return this; 24050 }; 24051 24052 p.removePause = function (position) { 24053 return this.removeCallback(TimelineLite._internals.pauseCallback, position); 24054 }; 24055 24056 p.tweenTo = function (position, vars) { 24057 vars = vars || {}; 24058 var copy = { ease: _easeNone, useFrames: this.usesFrames(), immediateRender: false }, 24059 Engine = vars.repeat && _globals.TweenMax || TweenLite, 24060 duration, 24061 p, 24062 t; 24063 for (p in vars) { 24064 copy[p] = vars[p]; 24065 } 24066 copy.time = this._parseTimeOrLabel(position); 24067 duration = Math.abs(Number(copy.time) - this._time) / this._timeScale || 0.001; 24068 t = new Engine(this, duration, copy); 24069 copy.onStart = function () { 24070 t.target.paused(true); 24071 if (t.vars.time !== t.target.time() && duration === t.duration()) { 24072 //don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all. 24073 t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale); 24074 } 24075 if (vars.onStart) { 24076 //in case the user had an onStart in the vars - we don't want to overwrite it. 24077 vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error. 24078 } 24079 }; 24080 return t; 24081 }; 24082 24083 p.tweenFromTo = function (fromPosition, toPosition, vars) { 24084 vars = vars || {}; 24085 fromPosition = this._parseTimeOrLabel(fromPosition); 24086 vars.startAt = { onComplete: this.seek, onCompleteParams: [fromPosition], callbackScope: this }; 24087 vars.immediateRender = vars.immediateRender !== false; 24088 var t = this.tweenTo(toPosition, vars); 24089 return t.duration(Math.abs(t.vars.time - fromPosition) / this._timeScale || 0.001); 24090 }; 24091 24092 p.render = function (time, suppressEvents, force) { 24093 if (this._gc) { 24094 this._enabled(true, false); 24095 } 24096 var prevTime = this._time, 24097 totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 24098 dur = this._duration, 24099 prevTotalTime = this._totalTime, 24100 prevStart = this._startTime, 24101 prevTimeScale = this._timeScale, 24102 prevRawPrevTime = this._rawPrevTime, 24103 prevPaused = this._paused, 24104 prevCycle = this._cycle, 24105 tween, 24106 isComplete, 24107 next, 24108 callback, 24109 internalForce, 24110 cycleDuration, 24111 pauseTween, 24112 curTime; 24113 if (prevTime !== this._time) { 24114 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 24115 time += this._time - prevTime; 24116 } 24117 if (time >= totalDur - 0.0000001 && time >= 0) { 24118 //to work around occasional floating point math artifacts. 24119 if (!this._locked) { 24120 this._totalTime = totalDur; 24121 this._cycle = this._repeat; 24122 } 24123 if (!this._reversed) if (!this._hasPausedChild()) { 24124 isComplete = true; 24125 callback = "onComplete"; 24126 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 24127 if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) { 24128 internalForce = true; 24129 if (prevRawPrevTime > _tinyNum) { 24130 callback = "onReverseComplete"; 24131 } 24132 } 24133 } 24134 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 24135 if (this._yoyo && (this._cycle & 1) !== 0) { 24136 this._time = time = 0; 24137 } else { 24138 this._time = dur; 24139 time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in
24139which case adding 0.00000001, for example, causes it to act like nothing was added. 24140 } 24141 } else if (time < 0.0000001) { 24142 //to work around occasional floating point math artifacts, round super small values to 0. 24143 if (!this._locked) { 24144 this._totalTime = this._cycle = 0; 24145 } 24146 this._time = 0; 24147 if (prevTime !== 0 || dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || time < 0 && prevRawPrevTime >= 0) && !this._locked) { 24148 //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare) 24149 callback = "onReverseComplete"; 24150 isComplete = this._reversed; 24151 } 24152 if (time < 0) { 24153 this._active = false; 24154 if (this._timeline.autoRemoveChildren && this._reversed) { 24155 internalForce = isComplete = true; 24156 callback = "onReverseComplete"; 24157 } else if (prevRawPrevTime >= 0 && this._first) { 24158 //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 24159 internalForce = true; 24160 } 24161 this._rawPrevTime = time; 24162 } else { 24163 this._rawPrevTime = dur || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 24164 if (time === 0 && isComplete) { 24165 //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 24166 tween = this._first; 24167 while (tween && tween._startTime === 0) { 24168 if (!tween._duration) { 24169 isComplete = false; 24170 } 24171 tween = tween._next; 24172 } 24173 } 24174 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 24175 if (!this._initted) { 24176 internalForce = true; 24177 } 24178 } 24179 } else { 24180 if (dur === 0 && prevRawPrevTime < 0) { 24181 //without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through. 24182 internalForce = true; 24183 } 24184 this._time = this._rawPrevTime = time; 24185 if (!this._locked) { 24186 this._totalTime = time; 24187 if (this._repeat !== 0) { 24188 cycleDuration = dur + this._repeatDelay; 24189 this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!) 24190 if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) { 24191 this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning) 24192 } 24193 this._time = this._totalTime - this._cycle * cycleDuration; 24194 if (this._yoyo) if ((this._cycle & 1) !== 0) { 24195 this._time = dur - this._time; 24196 } 24197 if (this._time > dur) { 24198 this._time = dur; 24199 time = dur + 0.0001; //to avoid occasional floating point rounding error 24200 } else if (this._time < 0) { 24201 this._time = time = 0; 24202 } else { 24203 time = this._time; 24204 } 24205 } 24206 } 24207 24208 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 24209 time = this._time; 24210 if (time >= prevTime || this._repeat && prevCycle !== this._cycle) { 24211 tween = this._first; 24212 while (tween && tween._startTime <= time && !pauseTween) { 24213 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 24214 pauseTween = tween; 24215 } 24216 tween = tween._next; 24217 } 24218 } else { 24219 tween = this._last; 24220 while (tween && tween._startTime >= time && !pauseTween) { 24221 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 24222 pauseTween = tween; 24223 } 24224 tween = tween._prev; 24225 } 24226 } 24227 if (pauseTween && pauseTween._startTime < dur) { 24228 this._time = time = pauseTween._startTime; 24229 this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay); 24230 } 24231 } 24232 } 24233 24234 if (this._cycle !== prevCycle) if (!this._locked) { 24235 /* 24236 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 24237 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
24238 would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 24239 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 24240 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 24241 ensure that zero-duration tweens at the very beginning or end of the TimelineMax work. 24242 */ 24243 var backwards = this._yoyo && (prevCycle & 1) !== 0, 24244 wrap = backwards === (this._yoyo && (this._cycle & 1) !== 0), 24245 recTotalTime = this._totalTime, 24246 recCycle = this._cycle, 24247 recRawPrevTime = this._rawPrevTime, 24248 recTime = this._time; 24249 24250 this._totalTime = prevCycle * dur; 24251 if (this._cycle < prevCycle) { 24252 backwards = !backwards; 24253 } else { 24254 this._totalTime += dur; 24255 } 24256 this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method. 24257 24258 this._rawPrevTime = dur === 0 ? prevRawPrevTime - 0.0001 : prevRawPrevTime; 24259 this._cycle = prevCycle; 24260 this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render() 24261 prevTime = backwards ? 0 : dur; 24262 this.render(prevTime, suppressEvents, dur === 0); 24263 if (!suppressEvents) if (!this._gc) { 24264 if (this.vars.onRepeat) { 24265 this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle. 24266 this._locked = false; 24267 this._callback("onRepeat"); 24268 } 24269 } 24270 if (prevTime !== this._time) { 24271 //in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort. 24272 return; 24273 } 24274 if (wrap) { 24275 this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too. 24276 this._locked = true; 24277 prevTime = backwards ? dur + 0.0001 : -0.0001; 24278 this.render(prevTime, true, false); 24279 } 24280 this._locked = false; 24281 if (this._paused && !prevPaused) { 24282 //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible) 24283 return; 24284 } 24285 this._time = recTime; 24286 this._totalTime = recTotalTime; 24287 this._cycle = recCycle; 24288 this._rawPrevTime = recRawPrevTime; 24289 } 24290 24291 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 24292 if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) { 24293 //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate. 24294 this._callback("onUpdate"); 24295 } 24296 return; 24297 } else if (!this._initted) { 24298 this._initted = true; 24299 } 24300 24301 if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) { 24302 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 24303 } 24304 24305 if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) { 24306 this._callback("onStart"); 24307 } 24308 24309 curTime = this._time; 24310 if (curTime >= prevTime) { 24311 tween = this._first; 24312 while (tween) { 24313 next = tween._next; //record it here because the value could change after rendering... 24314 if (curTime !== this._time || this._paused && !prevPaused) { 24315 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 24316 break; 24317 } else if (tween._active || tween._startTime <= this._time && !tween._paused && !tween._gc) { 24318 if (pauseTween === tween) { 24319 this.pause(); 24320 } 24321 if (!tween._reversed) { 24322 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 24323 } else { 24324 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 24325 } 24326 } 24327 tween = next; 24328 } 24329 } else { 24330 tween = this._last; 24331 while (tween) { 24332 next = tween._prev; //record it here because the value could change after rendering... 24333 if (curTime !== this._time || this._paused && !prevPaused) { 24334 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 24335 break; 24336 } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) { 24337 if (pauseTween === tween) { 24338 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 24339 while (pauseTween && pauseTween.endTime() > this._time) { 24340 pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force); 24341 pauseTween = pauseTween._prev; 24342 } 24343 pauseTween = null; 24344 this.pause(); 24345 } 24346 if (!tween._reversed) { 24347 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 24348 } else { 24349 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 24350 } 24351 } 24352 tween = next; 24353 } 24354 } 24355 24356 if (this._onUpdate) if (!suppressEvents) { 24357 if (_lazyTweens.length) { 24358 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 24359 _lazyRender(); 24360 }
24361 this._callback("onUpdate"); 24362 } 24363 if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { 24364 //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 24365 if (isComplete) { 24366 if (_lazyTweens.length) { 24367 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 24368 _lazyRender(); 24369 } 24370 if (this._timeline.autoRemoveChildren) { 24371 this._enabled(false, false); 24372 } 24373 this._active = false; 24374 } 24375 if (!suppressEvents && this.vars[callback]) { 24376 this._callback(callback); 24377 } 24378 } 24379 }; 24380 24381 p.getActive = function (nested, tweens, timelines) { 24382 if (nested == null) { 24383 nested = true; 24384 } 24385 if (tweens == null) { 24386 tweens = true; 24387 } 24388 if (timelines == null) { 24389 timelines = false; 24390 } 24391 var a = [], 24392 all = this.getChildren(nested, tweens, timelines), 24393 cnt = 0, 24394 l = all.length, 24395 i, 24396 tween; 24397 for (i = 0; i < l; i++) { 24398 tween = all[i]; 24399 if (tween.isActive()) { 24400 a[cnt++] = tween; 24401 } 24402 } 24403 return a; 24404 }; 24405 24406 p.getLabelAfter = function (time) { 24407 if (!time) if (time !== 0) { 24408 //faster than isNan() 24409 time = this._time; 24410 } 24411 var labels = this.getLabelsArray(), 24412 l = labels.length, 24413 i; 24414 for (i = 0; i < l; i++) { 24415 if (labels[i].time > time) { 24416 return labels[i].name; 24417 } 24418 } 24419 return null; 24420 }; 24421 24422 p.getLabelBefore = function (time) { 24423 if (time == null) { 24424 time = this._time; 24425 } 24426 var labels = this.getLabelsArray(), 24427 i = labels.length; 24428 while (--i > -1) { 24429 if (labels[i].time < time) { 24430 return labels[i].name; 24431 } 24432 } 24433 return null; 24434 }; 24435 24436 p.getLabelsArray = function () { 24437 var a = [], 24438 cnt = 0, 24439 p; 24440 for (p in this._labels) { 24441 a[cnt++] = { time: this._labels[p], name: p }; 24442 } 24443 a.sort(function (a, b) { 24444 return a.time - b.time; 24445 }); 24446 return a; 24447 }; 24448 24449 p.invalidate = function () { 24450 this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat 24451 return TimelineLite.prototype.invalidate.call(this); 24452 }; 24453 24454 //---- GETTERS / SETTERS ------------------------------------------------------------------------------------------------------- 24455 24456 p.progress = function (value, suppressEvents) { 24457 return !arguments.length ? this._time / this.duration() || 0 : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents); 24458 }; 24459 24460 p.totalProgress = function (value, suppressEvents) { 24461 return !arguments.length ? this._totalTime / this.totalDuration() || 0 : this.totalTime(this.totalDuration() * value, suppressEvents); 24462 }; 24463 24464 p.totalDuration = function (value) { 24465 if (!arguments.length) { 24466 if (this._dirty) { 24467 TimelineLite.prototype.totalDuration.call(this); //just forces refresh 24468 //Instead of Infinity, we use 999999999999 so that we can accommodate reverses. 24469 this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat; 24470 } 24471 return this._totalDuration; 24472 } 24473 return this._repeat === -1 || !value ? this : this.timeScale(this.totalDuration() / value); 24474 }; 24475 24476 p.time = function (value, suppressEvents) { 24477 if (!arguments.length) { 24478 return this._time; 24479 } 24480 if (this._dirty) { 24481 this.totalDuration(); 24482 } 24483 if (value > this._duration) { 24484 value = this._duration; 24485 } 24486 if (this._yoyo && (this._cycle & 1) !== 0) { 24487 value = this._duration - value + this._cycle * (this._duration + this._repeatDelay); 24488 } else if (this._repeat !== 0) { 24489 value += this._cycle * (this._duration + this._repeatDelay); 24490 } 24491 return this.totalTime(value, suppressEvents); 24492 }; 24493 24494 p.repeat = function (value) { 24495 if (!arguments.length) { 24496 return this._repeat; 24497 } 24498 this._repeat = value; 24499 return this._uncache(true); 24500 }; 24501 24502 p.repeatDelay = function (value) { 24503 if (!arguments.length) { 24504 return this._repeatDelay; 24505 } 24506 this._repeatDelay = value; 24507 return this._uncache(true); 24508 }; 24509 24510 p.yoyo = function (value) { 24511 if (!arguments.length) { 24512 return this._yoyo; 24513 } 24514 this._yoyo = value; 24515 return this; 24516 }; 24517 24518 p.currentLabel = function (value) { 24519 if (!arguments.length) { 24520 return this.getLabelBefore(this._time + 0.00000001); 24521 } 24522 return this.seek(value, true); 24523 }; 24524 24525 return TimelineMax; 24526 }, true); 24527 24528 /* 24529 * ---------------------------------------------------------------- 24530 * TimelineLite 24531 * ---------------------------------------------------------------- 24532 */ 24533 24534 _gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) { 24535 24536 var TimelineLite = function (vars) { 24537 SimpleTimeline.call(this, vars); 24538 this._labels = {}; 24539 this.autoRemoveChildren = this.vars.autoRemoveChildren === true; 24540 this.smoothChildTiming = this.vars.smoothChildTiming === true; 24541 this._sortChildren = true;
24542 this._onUpdate = this.vars.onUpdate; 24543 var v = this.vars, 24544 val, 24545 p; 24546 for (p in v) { 24547 val = v[p]; 24548 if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) { 24549 v[p] = this._swapSelfInParams(val); 24550 } 24551 } 24552 if (_isArray(v.tweens)) { 24553 this.add(v.tweens, 0, v.align, v.stagger); 24554 } 24555 }, 24556 _tinyNum = 0.0000000001, 24557 TweenLiteInternals = TweenLite._internals, 24558 _internals = TimelineLite._internals = {}, 24559 _isSelector = TweenLiteInternals.isSelector, 24560 _isArray = TweenLiteInternals.isArray, 24561 _lazyTweens = TweenLiteInternals.lazyTweens, 24562 _lazyRender = TweenLiteInternals.lazyRender, 24563 _globals = _gsScope._gsDefine.globals, 24564 _copy = function (vars) { 24565 var copy = {}, 24566 p; 24567 for (p in vars) { 24568 copy[p] = vars[p]; 24569 } 24570 return copy; 24571 }, 24572 _applyCycle = function (vars, targets, i) { 24573 var alt = vars.cycle, 24574 p, 24575 val; 24576 for (p in alt) { 24577 val = alt[p]; 24578 vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length]; 24579 } 24580 delete vars.cycle; 24581 }, 24582 _pauseCallback = _internals.pauseCallback = function () {}, 24583 _slice = function (a) { 24584 //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 24585 var b = [], 24586 l = a.length, 24587 i; 24588 for (i = 0; i !== l; b.push(a[i++])); 24589 return b; 24590 }, 24591 p = TimelineLite.prototype = new SimpleTimeline(); 24592 24593 TimelineLite.version = "1.20.3"; 24594 p.constructor = TimelineLite; 24595 p.kill()._gc = p._forcingPlayhead = p._hasPause = false; 24596 24597 /* might use later... 24598 //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales. 24599 function localToGlobal(time, animation) { 24600 while (animation) { 24601 time = (time / animation._timeScale) + animation._startTime; 24602 animation = animation.timeline; 24603 } 24604 return time; 24605 } 24606 //translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales 24607 function globalToLocal(time, animation) { 24608 var scale = 1; 24609 time -= localToGlobal(0, animation); 24610 while (animation) { 24611 scale *= animation._timeScale; 24612 animation = animation.timeline; 24613 } 24614 return time * scale; 24615 } 24616 */ 24617 24618 p.to = function (target, duration, vars, position) { 24619 var Engine = vars.repeat && _globals.TweenMax || TweenLite; 24620 return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position); 24621 }; 24622 24623 p.from = function (target, duration, vars, position) { 24624 return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position); 24625 }; 24626 24627 p.fromTo = function (target, duration, fromVars, toVars, position) { 24628 var Engine = toVars.repeat && _globals.TweenMax || TweenLite; 24629 return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position); 24630 }; 24631 24632 p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 24633 var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }), 24634 cycle = vars.cycle, 24635 copy, 24636 i; 24637 if (typeof targets === "string") { 24638 targets = TweenLite.selector(targets) || targets; 24639 } 24640 targets = targets || []; 24641 if (_isSelector(targets)) { 24642 //senses if the targets object is a selector. If it is, we should translate it into an array. 24643 targets = _slice(targets); 24644 } 24645 stagger = stagger || 0; 24646 if (stagger < 0) { 24647 targets = _slice(targets); 24648 targets.reverse(); 24649 stagger *= -1; 24650 } 24651 for (i = 0; i < targets.length; i++) { 24652 copy = _copy(vars); 24653 if (copy.startAt) { 24654 copy.startAt = _copy(copy.startAt); 24655 if (copy.startAt.cycle) { 24656 _applyCycle(copy.startAt, targets, i); 24657 } 24658 } 24659 if (cycle) { 24660 _applyCycle(copy, targets, i); 24661 if (copy.duration != null) { 24662 duration = copy.duration; 24663 delete copy.duration; 24664 } 24665 } 24666 tl.to(targets[i], duration, copy, i * stagger); 24667 } 24668 return this.add(tl, position); 24669 }; 24670 24671 p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 24672 vars.immediateRender = vars.immediateRender != false; 24673 vars.runBackwards = true; 24674 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 24675 }; 24676 24677 p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 24678 toVars.startAt = fromVars; 24679 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 24680 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 24681 }; 24682 24683 p.call = function (callback, params, scope, position) { 24684 return this.add(TweenLite.delayedCall(0, callback, params, scope), position); 24685 }; 24686 24687 p.set = function (target, vars, position) { 24688 position = this._parseTimeOrLabel(position, 0, true); 24689 if (vars.immediateRender == null) { 24690 vars.immediateRender = position === this._time && !this._paused; 24691 } 24692 return this.add(new TweenLite(target, 0, vars), position); 24693 }; 24694 24695 TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) { 24696 vars = vars || {}; 24697 if (vars.smoothChildTiming == null) { 24698 vars.smoothChildTiming = true; 24699 } 24700 var tl = new TimelineLite(vars), 24701 root = tl._timeline, 24702 hasNegativeStart, 24703 time, 24704 tween, 24705 next; 24706 if (ignoreDelayedCalls == null) { 24707 ignoreDelayedCalls = true; 24708 } 24709 root._remove(tl, true); 24710 tl._startTime = 0; 24711 tl._rawPrevTime = tl._time = tl._totalTime = root._time; 24712 tween = root._first; 24713 while (tween) { 24714 next = tween._next; 24715 if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) { 24716 time = tween._startTime - tween._delay; 24717 if (time < 0) { 24718 hasNegativeStart = 1; 24719 } 24720 tl.add(tween, time); 24721 } 24722 tween = next; 24723 } 24724 root.add(tl, 0); 24725 if (hasNegativeStart) { 24726 //calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero. 24727 tl.totalDuration(); 24728 } 24729 return tl; 24730 }; 24731 24732 p.add = function (value, position, align, stagger) { 24733 var curTime, l, i, child, tl, beforeRawTime; 24734 if (typeof position !== "number") { 24735 position = this._parseTimeOrLabel(position, 0, true, value); 24736 } 24737 if (!(value instanceof Animation)) { 24738 if (value instanceof Array || value && value.push && _isArray(value)) {
24739 align = align || "normal"; 24740 stagger = stagger || 0; 24741 curTime = position; 24742 l = value.length; 24743 for (i = 0; i < l; i++) { 24744 if (_isArray(child = value[i])) { 24745 child = new TimelineLite({ tweens: child }); 24746 } 24747 this.add(child, curTime); 24748 if (typeof child !== "string" && typeof child !== "function") { 24749 if (align === "sequence") { 24750 curTime = child._startTime + child.totalDuration() / child._timeScale; 24751 } else if (align === "start") { 24752 child._startTime -= child.delay(); 24753 } 24754 } 24755 curTime += stagger; 24756 } 24757 return this._uncache(true); 24758 } else if (typeof value === "string") { 24759 return this.addLabel(value, position); 24760 } else if (typeof value === "function") { 24761 value = TweenLite.delayedCall(0, value); 24762 } else { 24763 throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string."; 24764 } 24765 } 24766 24767 SimpleTimeline.prototype.add.call(this, value, position); 24768 24769 if (value._time) { 24770 //in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 24771 value.render((this.rawTime() - value._startTime) * value._timeScale, false, false); 24772 } 24773 24774 //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 24775 if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) { 24776 //in case any of the ancestors had completed but should now be enabled... 24777 tl = this; 24778 beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect. 24779 while (tl._timeline) { 24780 if (beforeRawTime && tl._timeline.smoothChildTiming) { 24781 tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it. 24782 } else if (tl._gc) { 24783 tl._enabled(true, false); 24784 } 24785 tl = tl._timeline; 24786 } 24787 } 24788 24789 return this; 24790 }; 24791 24792 p.remove = function (value) { 24793 if (value instanceof Animation) { 24794 this._remove(value, false); 24795 var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline. 24796 value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct. 24797 return this; 24798 } else if (value instanceof Array || value && value.push && _isArray(value)) { 24799 var i = value.length; 24800 while (--i > -1) { 24801 this.remove(value[i]); 24802 } 24803 return this; 24804 } else if (typeof value === "string") { 24805 return this.removeLabel(value); 24806 } 24807 return this.kill(null, value); 24808 }; 24809 24810 p._remove = function (tween, skipDisable) { 24811 SimpleTimeline.prototype._remove.call(this, tween, skipDisable); 24812 var last = this._last; 24813 if (!last) { 24814 this._time = this._totalTime = this._duration = this._totalDuration = 0; 24815 } else if (this._time > this.duration()) { 24816 this._time = this._duration; 24817 this._totalTime = this._totalDuration; 24818 } 24819 return this; 24820 }; 24821 24822 p.append = function (value, offsetOrLabel) { 24823 return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value)); 24824 }; 24825 24826 p.insert = p.insertMultiple = function (value, position, align, stagger) { 24827 return this.add(value, position || 0, align, stagger); 24828 }; 24829 24830 p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) { 24831 return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger); 24832 }; 24833 24834 p.addLabel = function (label, position) { 24835 this._labels[label] = this._parseTimeOrLabel(position); 24836 return this; 24837 }; 24838 24839 p.addPause = function (position, callback, params, scope) { 24840 var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this); 24841 t.vars.onComplete = t.vars.onReverseComplete = callback;
24842 t.data = "isPause"; 24843 this._hasPause = true; 24844 return this.add(t, position); 24845 }; 24846 24847 p.removeLabel = function (label) { 24848 delete this._labels[label]; 24849 return this; 24850 }; 24851 24852 p.getLabelTime = function (label) { 24853 return this._labels[label] != null ? this._labels[label] : -1; 24854 }; 24855 24856 p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) { 24857 var clippedDuration, i; 24858 //if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration(). 24859 if (ignore instanceof Animation && ignore.timeline === this) { 24860 this.remove(ignore); 24861 } else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) { 24862 i = ignore.length; 24863 while (--i > -1) { 24864 if (ignore[i] instanceof Animation && ignore[i].timeline === this) { 24865 this.remove(ignore[i]); 24866 } 24867 } 24868 } 24869 clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 24870 if (typeof offsetOrLabel === "string") { 24871 return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent); 24872 } 24873 offsetOrLabel = offsetOrLabel || 0; 24874 if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { 24875 //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 24876 i = timeOrLabel.indexOf("="); 24877 if (i === -1) { 24878 if (this._labels[timeOrLabel] == null) { 24879 return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel; 24880 } 24881 return this._labels[timeOrLabel] + offsetOrLabel; 24882 } 24883 offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1)); 24884 timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration; 24885 } else if (timeOrLabel == null) { 24886 timeOrLabel = clippedDuration; 24887 } 24888 return Number(timeOrLabel) + offsetOrLabel; 24889 }; 24890 24891 p.seek = function (position, suppressEvents) { 24892 return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false); 24893 }; 24894 24895 p.stop = function () { 24896 return this.paused(true); 24897 }; 24898 24899 p.gotoAndPlay = function (position, suppressEvents) { 24900 return this.play(position, suppressEvents); 24901 }; 24902 24903 p.gotoAndStop = function (position, suppressEvents) { 24904 return this.pause(position, suppressEvents); 24905 }; 24906 24907 p.render = function (time, suppressEvents, force) { 24908 if (this._gc) { 24909 this._enabled(true, false); 24910 } 24911 var totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 24912 prevTime = this._time, 24913 prevStart = this._startTime, 24914 prevTimeScale = this._timeScale, 24915 prevPaused = this._paused, 24916 tween, 24917 isComplete, 24918 next, 24919 callback, 24920 internalForce, 24921 pauseTween, 24922 curTime; 24923 if (time >= totalDur - 0.0000001 && time >= 0) { 24924 //to work around occasional floating point math artifacts. 24925 this._totalTime = this._time = totalDur; 24926 if (!this._reversed) if (!this._hasPausedChild()) { 24927 isComplete = true; 24928 callback = "onComplete"; 24929 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 24930 if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) { 24931 internalForce = true; 24932 if (this._rawPrevTime > _tinyNum) { 24933 callback = "onReverseComplete"; 24934 } 24935 } 24936 } 24937 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 24938 time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. 24939 } else if (time < 0.0000001) { 24940 //to work around occasional floating point math artifacts, round super small values to 0. 24941 this._totalTime = this._time = 0; 24942 if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) { 24943 callback = "onReverseComplete"; 24944 isComplete = this._reversed; 24945 } 24946 if (time < 0) { 24947 this._active = false;
24948 if (this._timeline.autoRemoveChildren && this._reversed) { 24949 //ensures proper GC if a timeline is resumed after it's finished reversing. 24950 internalForce = isComplete = true; 24951 callback = "onReverseComplete"; 24952 } else if (this._rawPrevTime >= 0 && this._first) { 24953 //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 24954 internalForce = true; 24955 } 24956 this._rawPrevTime = time; 24957 } else { 24958 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 24959 if (time === 0 && isComplete) { 24960 //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 24961 tween = this._first; 24962 while (tween && tween._startTime === 0) { 24963 if (!tween._duration) { 24964 isComplete = false; 24965 } 24966 tween = tween._next; 24967 } 24968 } 24969 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 24970 if (!this._initted) { 24971 internalForce = true; 24972 } 24973 } 24974 } else { 24975 24976 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 24977 if (time >= prevTime) { 24978 tween = this._first; 24979 while (tween && tween._startTime <= time && !pauseTween) { 24980 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 24981 pauseTween = tween; 24982 } 24983 tween = tween._next; 24984 } 24985 } else { 24986 tween = this._last; 24987 while (tween && tween._startTime >= time && !pauseTween) { 24988 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 24989 pauseTween = tween; 24990 } 24991 tween = tween._prev; 24992 } 24993 } 24994 if (pauseTween) { 24995 this._time = time = pauseTween._startTime; 24996 this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay); 24997 } 24998 } 24999 25000 this._totalTime = this._time = this._rawPrevTime = time; 25001 } 25002 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 25003 return; 25004 } else if (!this._initted) { 25005 this._initted = true; 25006 } 25007 25008 if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { 25009 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 25010 } 25011 25012 if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) { 25013 this._callback("onStart"); 25014 } 25015 25016 curTime = this._time; 25017 if (curTime >= prevTime) { 25018 tween = this._first; 25019 while (tween) { 25020 next = tween._next; //record it here because the value could change after rendering... 25021 if (curTime !== this._time || this._paused && !prevPaused) { 25022 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 25023 break; 25024 } else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) { 25025 if (pauseTween === tween) { 25026 this.pause(); 25027 } 25028 if (!tween._reversed) { 25029 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 25030 } else { 25031 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 25032 } 25033 } 25034 tween = next; 25035 } 25036 } else { 25037 tween = this._last; 25038 while (tween) { 25039 next = tween._prev; //record it here because the value could change after rendering... 25040 if (curTime !== this._time || this._paused && !prevPaused) { 25041 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 25042 break; 25043 } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) { 25044 if (pauseTween === tween) { 25045 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 25046 while (pauseTween && pauseTween.endTime() > this._time) { 25047 pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force); 25048 pauseTween = pauseTween._prev; 25049 } 25050 pauseTween = null; 25051 this.pause(); 25052 } 25053 if (!tween._reversed) { 25054 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 25055 } else { 25056 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 25057 } 25058 } 25059 tween = next; 25060 } 25061 } 25062 25063 if (this._onUpdate) if (!suppressEvents) { 25064 if (_lazyTweens.length) { 25065 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 25066 _lazyRender(); 25067 }
25068 this._callback("onUpdate"); 25069 } 25070 25071 if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { 25072 //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 25073 if (isComplete) { 25074 if (_lazyTweens.length) { 25075 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 25076 _lazyRender(); 25077 } 25078 if (this._timeline.autoRemoveChildren) { 25079 this._enabled(false, false); 25080 } 25081 this._active = false; 25082 } 25083 if (!suppressEvents && this.vars[callback]) { 25084 this._callback(callback); 25085 } 25086 } 25087 }; 25088 25089 p._hasPausedChild = function () { 25090 var tween = this._first; 25091 while (tween) { 25092 if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) { 25093 return true; 25094 } 25095 tween = tween._next; 25096 } 25097 return false; 25098 }; 25099 25100 p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) { 25101 ignoreBeforeTime = ignoreBeforeTime || -9999999999; 25102 var a = [], 25103 tween = this._first, 25104 cnt = 0; 25105 while (tween) { 25106 if (tween._startTime < ignoreBeforeTime) { 25107 //do nothing 25108 } else if (tween instanceof TweenLite) { 25109 if (tweens !== false) { 25110 a[cnt++] = tween; 25111 } 25112 } else { 25113 if (timelines !== false) { 25114 a[cnt++] = tween; 25115 } 25116 if (nested !== false) { 25117 a = a.concat(tween.getChildren(true, tweens, timelines)); 25118 cnt = a.length; 25119 } 25120 } 25121 tween = tween._next; 25122 } 25123 return a; 25124 }; 25125 25126 p.getTweensOf = function (target, nested) { 25127 var disabled = this._gc, 25128 a = [], 25129 cnt = 0, 25130 tweens, 25131 i; 25132 if (disabled) { 25133 this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here. 25134 } 25135 tweens = TweenLite.getTweensOf(target); 25136 i = tweens.length; 25137 while (--i > -1) { 25138 if (tweens[i].timeline === this || nested && this._contains(tweens[i])) { 25139 a[cnt++] = tweens[i]; 25140 } 25141 } 25142 if (disabled) { 25143 this._enabled(false, true); 25144 } 25145 return a; 25146 }; 25147 25148 p.recent = function () { 25149 return this._recent; 25150 }; 25151 25152 p._contains = function (tween) { 25153 var tl = tween.timeline; 25154 while (tl) { 25155 if (tl === this) { 25156 return true; 25157 } 25158 tl = tl.timeline; 25159 } 25160 return false; 25161 }; 25162 25163 p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) { 25164 ignoreBeforeTime = ignoreBeforeTime || 0; 25165 var tween = this._first, 25166 labels = this._labels, 25167 p; 25168 while (tween) { 25169 if (tween._startTime >= ignoreBeforeTime) { 25170 tween._startTime += amount; 25171 } 25172 tween = tween._next; 25173 }
25174 if (adjustLabels) { 25175 for (p in labels) { 25176 if (labels[p] >= ignoreBeforeTime) { 25177 labels[p] += amount; 25178 } 25179 } 25180 } 25181 return this._uncache(true); 25182 }; 25183 25184 p._kill = function (vars, target) { 25185 if (!vars && !target) { 25186 return this._enabled(false, false); 25187 } 25188 var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target), 25189 i = tweens.length, 25190 changed = false; 25191 while (--i > -1) { 25192 if (tweens[i]._kill(vars, target)) { 25193 changed = true; 25194 } 25195 } 25196 return changed; 25197 }; 25198 25199 p.clear = function (labels) { 25200 var tweens = this.getChildren(false, true, true), 25201 i = tweens.length; 25202 this._time = this._totalTime = 0; 25203 while (--i > -1) { 25204 tweens[i]._enabled(false, false); 25205 } 25206 if (labels !== false) { 25207 this._labels = {}; 25208 } 25209 return this._uncache(true); 25210 }; 25211 25212 p.invalidate = function () { 25213 var tween = this._first; 25214 while (tween) { 25215 tween.invalidate(); 25216 tween = tween._next; 25217 } 25218 return Animation.prototype.invalidate.call(this);; 25219 }; 25220 25221 p._enabled = function (enabled, ignoreTimeline) { 25222 if (enabled === this._gc) { 25223 var tween = this._first; 25224 while (tween) { 25225 tween._enabled(enabled, true); 25226 tween = tween._next; 25227 } 25228 } 25229 return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline); 25230 }; 25231 25232 p.totalTime = function (time, suppressEvents, uncapped) { 25233 this._forcingPlayhead = true; 25234 var val = Animation.prototype.totalTime.apply(this, arguments); 25235 this._forcingPlayhead = false; 25236 return val; 25237 }; 25238 25239 p.duration = function (value) { 25240 if (!arguments.length) { 25241 if (this._dirty) { 25242 this.totalDuration(); //just triggers recalculation 25243 } 25244 return this._duration; 25245 } 25246 if (this.duration() !== 0 && value !== 0) { 25247 this.timeScale(this._duration / value); 25248 } 25249 return this; 25250 }; 25251 25252 p.totalDuration = function (value) { 25253 if (!arguments.length) { 25254 if (this._dirty) { 25255 var max = 0, 25256 tween = this._last, 25257 prevStart = 999999999999, 25258 prev, 25259 end; 25260 while (tween) { 25261 prev = tween._prev; //record it here in case the tween changes position in the sequence... 25262 if (tween._dirty) { 25263 tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it. 25264 } 25265 if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) { 25266 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 25267 this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel(). 25268 this.add(tween, tween._startTime - tween._delay); 25269 this._calculatingDuration = 0; 25270 } else { 25271 prevStart = tween._startTime; 25272 } 25273 if (tween._startTime < 0 && !tween._paused) { 25274 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 25275 max -= tween._startTime; 25276 if (this._timeline.smoothChildTiming) { 25277 this._startTime += tween._startTime / this._timeScale; 25278 this._time -= tween._startTime; 25279 this._totalTime -= tween._startTime; 25280 this._rawPrevTime -= tween._startTime; 25281 } 25282 this.shiftChildren(-tween._startTime, false, -9999999999); 25283 prevStart = 0; 25284 } 25285 end = tween._startTime + tween._totalDuration / tween._timeScale; 25286 if (end > max) { 25287 max = end; 25288 } 25289 tween = prev; 25290 } 25291 this._duration = this._totalDuration = max; 25292 this._dirty = false; 25293 } 25294 return this._totalDuration; 25295 } 25296 return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this; 25297 }; 25298 25299 p.paused = function (value) { 25300 if (!value) { 25301 //if there's a pause directly at the spot from where we're unpausing, skip it. 25302 var tween = this._first, 25303 time = this._time; 25304 while (tween) { 25305 if (tween._startTime === time && tween.data === "isPause") { 25306 tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. 25307 } 25308 tween = tween._next; 25309 } 25310 } 25311 return Animation.prototype.paused.apply(this, arguments); 25312 }; 25313 25314 p.usesFrames = function () { 25315 var tl = this._timeline; 25316 while (tl._timeline) { 25317 tl = tl._timeline; 25318 } 25319 return tl === Animation._rootFramesTimeline; 25320 }; 25321 25322 p.rawTime = function (wrapRepeats) { 25323 return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale; 25324 }; 25325 25326 return TimelineLite; 25327 }, true); 25328});if (_gsScope._gsDefine) { 25329 _gsScope._gsQueue.pop()(); 25330} 25331 25332//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date) 25333(function (name) { 25334 "use strict"; 25335 25336 var getGlobal = function () { 25337 return (_gsScope.GreenSockGlobals || _gsScope)[name]; 25338 }; 25339 if (typeof module !== "undefined" && module.exports) { 25340 //node 25341 __webpack_require__(1); //dependency 25342 module.exports = getGlobal(); 25343 } else if (true) { 25344 //AMD 25345 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_FACTORY__ = (getGlobal), 25346 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 25347 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
25348 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 25349 } 25350})("TimelineMax"); 25351/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) 25352 25353/***/ }), 25354/* 9 */ 25355/***/ (function(module, __webpack_exports__, __webpack_require__) { 25356 25357"use strict"; 25358/** 25359 * ------------------------------------------------------------------ 25360 * æ¨¡ç» - 25361 * ------------------------------------------------------------------ 25362 */ 25363 25364/** 25365* 彿°åè½ç®è¿°: åä¼ ç»é¢å®½åº¦ 25366* å ·ä½æè¿°ä¸äºç»è: 25367* @date 2017-10-30 25368* @author Telliex<[email protected]> 25369* Fish<[email protected]> 25370*/ 25371 25372const viewport = () => { 25373 let e = window; 25374 let a = 'inner'; 25375 if (!('innerWidth' in window)) { 25376 a = 'client'; 25377 e = document.documentElement || document.body; 25378 } 25379 return e[`${a}Width`]; 25380}; 25381/* harmony default export */ __webpack_exports__["a"] = (viewport); 25382 25383/***/ }), 25384/* 10 */ 25385/***/ (function(module, __webpack_exports__, __webpack_require__) { 25386 25387"use strict"; 25388/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0); 25389/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__); 25390/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__browser__ = __webpack_require__(6); 25391/* eslint consistent-return: "off" */ 25392/* eslint func-names: ["off"] */ 25393/* eslint max-len: ["off", { "code": 200 }] */ 25394/* eslint prefer-destructuring: ["off"] */ 25395/* eslint no-undef: "off" */ 25396 25397/* eslint class-methods-use-this: ["error", { "exceptMethods": ["viewport","ie8Browser"," modernBrowser","modernBrowser","flashSupported"] }] */ 25398/** 25399 * ------------------------------------------------------------------ 25400 * æ¨¡ç» - 25401 * ------------------------------------------------------------------ 25402 */ 25403 25404/** 25405 * 彿°åè½ç®è¿°: åä¼ ç»é¢å®½åº¦ 25406 * å ·ä½æè¿°ä¸äºç»è: 25407 * @date 2017-10-30 25408 * @author Telliex<[email protected]> 25409 * Fish<[email protected]> 25410 */ 25411 25412 25413 25414 25415// ------------ 嵿¸¬ç覽å¨çæ 25416 25417class BrowserChecker { 25418 /* 25419 | 嵿¸¬ Desktop / Mobile 25420 */ 25421 viewport(windowSize) { 25422 if (windowSize >= 1360) { 25423 return 'max'; 25424 } else if (windowSize >= 960 && windowSize < 1360) { 25425 return 'desktop'; 25426 } else if (windowSize >= 768 && windowSize < 960) { 25427 return 'tablet'; 25428 } 25429 return 'mobile'; 25430 } 25431 25432 /* 25433 | 嵿¸¬æ¯å¦çº IE8 以ä¸çæ¬ 25434 */ 25435 ie8Browser() { 25436 if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8') { 25437 return true; 25438 } 25439 return false; 25440 } 25441 25442 /* 25443 | 嵿¸¬æ¯å¦çº Modern Browser 25444 */ 25445 modernBrowser() { 25446 if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE9' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE10') { 25447 return false; 25448 } 25449 return true; 25450 } 25451 25452 /* 25453 | 夿·æ¯å¦æ¯æ´/å®è£ Flash 25454 */ 25455 flashSupported() { 25456 if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE9' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE10' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE11') { 25457 if (window.ActiveXObject) { 25458 try { 25459 if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) { 25460 return true; 25461 } 25462 } catch (e) { 25463 // .. 25464 } 25465 } 25466 if (navigator.plugins) { 25467 for (let i = 0; i < navigator.plugins.length; i += 1) { 25468 if (navigator.plugins[i].name.toLowerCase().indexOf('shockwave flash') >= 0) { 25469 return true; 25470 } 25471 } 25472 return false;
25473 } 25474 return false; 25475 } 25476 return true; 25477 } 25478} 25479 25480// 宣å åå Class 25481const globalBrowserChecker = new BrowserChecker(); 25482/* harmony default export */ __webpack_exports__["a"] = (globalBrowserChecker); 25483 25484/***/ }), 25485/* 11 */, 25486/* 12 */, 25487/* 13 */, 25488/* 14 */, 25489/* 15 */, 25490/* 16 */, 25491/* 17 */, 25492/* 18 */, 25493/* 19 */, 25494/* 20 */, 25495/* 21 */ 25496/***/ (function(module, exports, __webpack_require__) { 25497 25498var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 25499 * ScrollMagic v2.0.5 (2015-04-29) 25500 * The javascript library for magical scroll interactions. 25501 * (c) 2015 Jan Paepke (@janpaepke) 25502 * Project Website: http://scrollmagic.io 25503 * 25504 * @version 2.0.5 25505 * @license Dual licensed under MIT license and GPL. 25506 * @author Jan Paepke - [email protected] 25507 * 25508 * @file ScrollMagic GSAP Animation Plugin. 25509 * 25510 * requires: GSAP ~1.14 25511 * Powered by the Greensock Animation Platform (GSAP): http://www.greensock.com/js 25512 * Greensock License info at http://www.greensock.com/licensing/ 25513 */ 25514/** 25515 * This plugin is meant to be used in conjunction with the Greensock Animation Plattform. 25516 * It offers an easy API to trigger Tweens or synchronize them to the scrollbar movement. 25517 * 25518 * Both the `lite` and the `max` versions of the GSAP library are supported. 25519 * The most basic requirement is `TweenLite`. 25520 * 25521 * To have access to this extension, please include `plugins/animation.gsap.js`. 25522 * @requires {@link http://greensock.com/gsap|GSAP ~1.14.x} 25523 * @mixin animation.GSAP 25524 */ 25525(function (root, factory) { 25526 if (true) { 25527 // AMD. Register as an anonymous module. 25528 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2), __webpack_require__(7), __webpack_require__(8)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 25529 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 25530 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 25531 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 25532 } else if (typeof exports === 'object') { 25533 // CommonJS 25534 // Loads whole gsap package onto global scope. 25535 require('gsap'); 25536 factory(require('scrollmagic'), TweenMax, TimelineMax); 25537 } else { 25538 // Browser globals 25539 factory(root.ScrollMagic || root.jQuery && root.jQuery.ScrollMagic, root.TweenMax || root.TweenLite, root.TimelineMax || root.TimelineLite); 25540 } 25541})(this, function (ScrollMagic, Tween, Timeline) { 25542 "use strict"; 25543 25544 var NAMESPACE = "animation.gsap"; 25545 25546 var console = window.console || {}, 25547 err = Function.prototype.bind.call(console.error || console.log || function () {}, console); 25548 if (!ScrollMagic) { 25549 err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs."); 25550 } 25551 if (!Tween) { 25552 err("(" + NAMESPACE + ") -> ERROR: TweenLite or TweenMax could not be found. Please make sure GSAP is loaded before ScrollMagic or use an asynchronous loader like requirejs."); 25553 } 25554 25555 /* 25556 * ---------------------------------------------------------------- 25557 * Extensions for Scene 25558 * ---------------------------------------------------------------- 25559 */ 25560 /** 25561 * Every instance of ScrollMagic.Scene now accepts an additional option. 25562 * See {@link ScrollMagic.Scene} for a complete list of the standard options. 25563 * @memberof! animation.GSAP# 25564 * @method new ScrollMagic.Scene(options) 25565 * @example 25566 * var scene = new ScrollMagic.Scene({tweenChanges: true}); 25567 * 25568 * @param {object} [options] - Options for the Scene. The options can be updated at any time. 25569 * @param {boolean} [options.tweenChanges=false] - Tweens Animation to the progress target instead of setting it. 25570 Does not affect animations where duration is `0`. 25571 */ 25572 /** 25573 * **Get** or **Set** the tweenChanges option value. 25574 * This only affects scenes with a duration. If `tweenChanges` is `true`, the progress update when scrolling will not be immediate, but instead the animation will smoothly animate to the target state. 25575 * For a better understanding, try enabling and disabling this option in the [Scene Manipulation Example](../examples/basic/scene_manipulation.html). 25576 * @memberof! animation.GSAP# 25577 * @method Scene.tweenChanges 25578 * 25579 * @example 25580 * // get the current tweenChanges option 25581 * var tweenChanges = scene.tweenChanges(); 25582 * 25583 * // set new tweenChanges option 25584 * scene.tweenChanges(true); 25585 * 25586 * @fires {@link Scene.change}, when used as setter 25587 * @param {boolean} [newTweenChanges] - The new tweenChanges setting of the scene. 25588 * @returns {boolean} `get` - Current tweenChanges option value. 25589 * @returns {Scene} `set` - Parent object for chaining. 25590 */ 25591 // add option (TODO: DOC (private for dev)) 25592 ScrollMagic.Scene.addOption("tweenChanges", // name 25593 false, // default 25594 25595 25596 function (val) { 25597 // validation callback 25598 return !!val; 25599 }); 25600 // extend scene 25601 ScrollMagic.Scene.extend(function () { 25602 var Scene = this, 25603 _tween; 25604 25605 var log = function () { 25606 if (Scene._log) { 25607 // not available, when main source minified 25608 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); 25609 Scene._log.apply(this, arguments); 25610 } 25611 }; 25612 25613 // set listeners 25614 Scene.on("progress.plugin_gsap", function () { 25615 updateTweenProgress(); 25616 }); 25617 Scene.on("destroy.plugin_gsap", function (e) { 25618 Scene.removeTween(e.reset); 25619 }); 25620 25621 /** 25622 * Update the tween progress to current position. 25623 * @private 25624 */ 25625 var updateTweenProgress = function () { 25626 if (_tween) { 25627 var progress = Scene.progress(), 25628 state = Scene.state(); 25629 if (_tween.repeat && _tween.repeat() === -1) { 25630 // infinite loop, so not in relation to progress 25631 if (state === 'DURING' && _tween.paused()) { 25632 _tween.play(); 25633 } else if (state !== 'DURING' && !_tween.paused()) { 25634 _tween.pause(); 25635 } 25636 } else if (progress != _tween.progress()) { 25637 // do we even need to update the progress? 25638 // no infinite loop - so should we just play or go to a specific point in t
25638ime? 25639 if (Scene.duration() === 0) { 25640 // play the animation 25641 if (progress > 0) { 25642 // play from 0 to 1 25643 _tween.play(); 25644 } else { 25645 // play from 1 to 0 25646 _tween.reverse(); 25647 } 25648 } else { 25649 // go to a specific point in time 25650 if (Scene.tweenChanges() && _tween.tweenTo) { 25651 // go smooth 25652 _tween.tweenTo(progress * _tween.duration()); 25653 } else { 25654 // just hard set it 25655 _tween.progress(progress).pause(); 25656 } 25657 } 25658 } 25659 } 25660 }; 25661 25662 /** 25663 * Add a tween to the scene. 25664 * If you want to add multiple tweens, add them into a GSAP Timeline object and supply it instead (see example below). 25665 * 25666 * If the scene has a duration, the tween's duration will be projected to the scroll distance of the scene, meaning its progress will be synced to scrollbar movement. 25667 * For a scene with a duration of `0`, the tween will be triggered when scrolling forward past the scene's trigger position and reversed, when scrolling back. 25668 * To gain better understanding, check out the [Simple Tweening example](../examples/basic/simple_tweening.html). 25669 * 25670 * Instead of supplying a tween this method can also be used as a shorthand for `TweenMax.to()` (see example below). 25671 * @memberof! animation.GSAP# 25672 * 25673 * @example 25674 * // add a single tween directly 25675 * scene.setTween(TweenMax.to("obj"), 1, {x: 100}); 25676 * 25677 * // add a single tween via variable 25678 * var tween = TweenMax.to("obj"), 1, {x: 100}; 25679 * scene.setTween(tween); 25680 * 25681 * // add multiple tweens, wrapped in a timeline. 25682 * var timeline = new TimelineMax(); 25683 * var tween1 = TweenMax.from("obj1", 1, {x: 100}); 25684 * var tween2 = TweenMax.to("obj2", 1, {y: 100}); 25685 * timeline 25686 * .add(tween1) 25687 * .add(tween2); 25688 * scene.addTween(timeline); 25689 * 25690 * // short hand to add a TweenMax.to() tween 25691 * scene.setTween("obj3", 0.5, {y: 100}); 25692 * 25693 * // short hand to add a TweenMax.to() tween for 1 second 25694 * // this is useful, when the scene has a duration and the tween duration isn't important anyway 25695 * scene.setTween("obj3", {y: 100}); 25696 * 25697 * @param {(object|string)} TweenObject - A TweenMax, TweenLite, TimelineMax or TimelineLite object that should be animated in the scene. Can also be a Dom Element or Selector, when using direct tween definition (see examples). 25698 * @param {(number|object)} duration - A duration for the tween, or tween parameters. If an object containing parameters are supplied, a default duration of 1 will be used. 25699 * @param {object} params - The parameters for the tween 25700 * @returns {Scene} Parent object for chaining. 25701 */ 25702 Scene.setTween = function (TweenObject, duration, params) { 25703 var newTween; 25704 if (arguments.length > 1) { 25705 if (arguments.length < 3) { 25706 params = duration; 25707 duration = 1; 25708 } 25709 TweenObject = Tween.to(TweenObject, duration, params); 25710 } 25711 try { 25712 // wrap Tween into a Timeline Object if available to include delay and repeats in the duration and standardize methods. 25713 if (Timeline) { 25714 newTween = new Timeline({ 25715 smoothChildTiming: true 25716 }).add(TweenObject); 25717 } else { 25718 newTween = TweenObject; 25719 } 25720 newTween.pause(); 25721 } catch (e) { 25722 log(1, "ERROR calling method 'setTween()': Supplied argument is not a valid TweenObject"); 25723 return Scene; 25724 } 25725 if (_tween) { 25726 // kill old tween? 25727 Scene.removeTween(); 25728 } 25729 _tween = newTween; 25730 25731 // some properties need to be transferred it to the wrapper, otherwise they would get lost. 25732 if (TweenObject.repeat && TweenObject.repeat() === -1) { 25733 // TweenMax or TimelineMax Object? 25734 _tween.repeat(-1); 25735 _tween.yoyo(TweenObject.yoyo()); 25736 } 25737 // Some tween validations and debugging helpers 25738 if (Scene.tweenChanges() && !_tween.tweenTo) { 25739 log(2, "WARNING: tweenChanges will only work if the TimelineMax object is available for ScrollMagic."); 25740 } 25741 25742 // check if there are position tweens defined for the trigger and warn about it :) 25743 if (_tween && Scene.controller() && Scene.triggerElement() && Scene.loglevel() >= 2) { 25744 // controller is needed to know scroll direction. 25745 var triggerTweens = Tween.getTweensOf(Scene.triggerElement()),
25746 vertical = Scene.controller().info("vertical"); 25747 triggerTweens.forEach(function (value, index) { 25748 var tweenvars = value.vars.css || value.vars, 25749 condition = vertical ? tweenvars.top !== undefined || tweenvars.bottom !== undefined : tweenvars.left !== undefined || tweenvars.right !== undefined; 25750 if (condition) { 25751 log(2, "WARNING: Tweening the position of the trigger element affects the scene timing and should be avoided!"); 25752 return false; 25753 } 25754 }); 25755 } 25756 25757 // warn about tween overwrites, when an element is tweened multiple times 25758 if (parseFloat(TweenLite.version) >= 1.14) { 25759 // onOverwrite only present since GSAP v1.14.0 25760 var list = _tween.getChildren ? _tween.getChildren(true, true, false) : [_tween], 25761 25762 // get all nested tween objects 25763 newCallback = function () { 25764 log(2, "WARNING: tween was overwritten by another. To learn how to avoid this issue see here: https://github.com/janpaepke/ScrollMagic/wiki/WARNING:-tween-was-overwritten-by-another"); 25765 }; 25766 for (var i = 0, thisTween, oldCallback; i < list.length; i++) { 25767 /*jshint loopfunc: true */ 25768 thisTween = list[i]; 25769 if (oldCallback !== newCallback) { 25770 // if tweens is added more than once 25771 oldCallback = thisTween.vars.onOverwrite; 25772 thisTween.vars.onOverwrite = function () { 25773 if (oldCallback) { 25774 oldCallback.apply(this, arguments); 25775 } 25776 newCallback.apply(this, arguments); 25777 }; 25778 } 25779 } 25780 } 25781 log(3, "added tween"); 25782 25783 updateTweenProgress(); 25784 return Scene; 25785 }; 25786 25787 /** 25788 * Remove the tween from the scene. 25789 * This will terminate the control of the Scene over the tween. 25790 * 25791 * Using the reset option you can decide if the tween should remain in the current state or be rewound to set the target elements back to the state they were in before the tween was added to the scene. 25792 * @memberof! animation.GSAP# 25793 * 25794 * @example 25795 * // remove the tween from the scene without resetting it 25796 * scene.removeTween(); 25797 * 25798 * // remove the tween from the scene and reset it to initial position 25799 * scene.removeTween(true); 25800 * 25801 * @param {boolean} [reset=false] - If `true` the tween will be reset to its initial values. 25802 * @returns {Scene} Parent object for chaining. 25803 */ 25804 Scene.removeTween = function (reset) { 25805 if (_tween) { 25806 if (reset) { 25807 _tween.progress(0).pause(); 25808 } 25809 _tween.kill(); 25810 _tween = undefined; 25811 log(3, "removed tween (reset: " + (reset ? "true" : "false") + ")"); 25812 } 25813 return Scene; 25814 }; 25815 }); 25816}); 25817 25818/***/ }), 25819/* 22 */ 25820/***/ (function(module, exports, __webpack_require__) { 25821 25822var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 25823 * ScrollMagic v2.0.5 (2015-04-29) 25824 * The javascript library for magical scroll interactions. 25825 * (c) 2015 Jan Paepke (@janpaepke) 25826 * Project Website: http://scrollmagic.io 25827 * 25828 * @version 2.0.5 25829 * @license Dual licensed under MIT license and GPL. 25830 * @author Jan Paepke - [email protected] 25831 * 25832 * @file Debug Extension for ScrollMagic. 25833 */ 25834/** 25835 * This plugin was formerly known as the ScrollMagic debug extension. 25836 * 25837 * It enables you to add visual indicators to your page, to be able to see exactly when a scene is triggered. 25838 * 25839 * To have access to this extension, please include `plugins/debug.addIndicators.js`. 25840 * @mixin debug.addIndicators 25841 */ 25842(function (root, factory) { 25843 if (true) { 25844 // AMD. Register as an anonymous module. 25845 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 25846 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 25847 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 25848 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 25849 } else if (typeof exports === 'object') { 25850 // CommonJS 25851 factory(require('scrollmagic')); 25852 } else { 25853 // no browser global export needed, just execute 25854 factory(root.ScrollMagic || root.jQuery && root.jQuery.ScrollMagic); 25855 } 25856})(this, function (ScrollMagic) { 25857 "use strict"; 25858 25859 var NAMESPACE = "debug.addIndicators"; 25860 25861 var console = window.console || {}, 25862 err = Function.prototype.bind.call(console.error || console.log || function () {}, console); 25863 if (!ScrollMagic) { 25864 err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs."); 25865 } 25866 25867 // plugin settings 25868 var FONT_SIZE = "0.85em", 25869 ZINDEX = "9999", 25870 EDGE_OFFSET = 15; // minimum edge distance, added to indentation 25871 25872 // overall vars 25873 var _util = ScrollMagic._util, 25874 _autoindex = 0; 25875 25876 ScrollMagic.Scene.extend(function () { 25877 var Scene = this, 25878 _indicator; 25879 25880 var log = function () { 25881 if (Scene._log) { 25882 // not available, when main source minified 25883 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); 25884 Scene._log.apply(this, arguments); 25885 } 25886 }; 25887 25888 /** 25889 * Add visual indicators for a ScrollMagic.Scene. 25890 * @memberof! debug.addIndicators# 25891 * 25892 * @example 25893 * // add basic indicators 25894 * scene.addIndicators() 25895 * 25896 * // passing options 25897 * scene.addIndicators({name: "pin scene", colorEnd: "#FFFFFF"}); 25898 * 25899 * @param {object}
25899 [options] - An object containing one or more options for the indicators. 25900 * @param {(string|object)} [options.parent=undefined] - A selector, DOM Object or a jQuery object that the indicators should be added to. 25901 If undefined, the controller's container will be used. 25902 * @param {number} [options.name=""] - This string will be displayed at the start and end indicators of the scene for identification purposes. If no name is supplied an automatic index will be used. 25903 * @param {number} [options.indent=0] - Additional position offset for the indicators (useful, when having multiple scenes starting at the same position). 25904 * @param {string} [options.colorStart=green] - CSS color definition for the start indicator. 25905 * @param {string} [options.colorEnd=red] - CSS color definition for the end indicator. 25906 * @param {string} [options.colorTrigger=blue] - CSS color definition for the trigger indicator. 25907 */ 25908 Scene.addIndicators = function (options) { 25909 if (!_indicator) { 25910 var DEFAULT_OPTIONS = { 25911 name: "", 25912 indent: 0, 25913 parent: undefined, 25914 colorStart: "green", 25915 colorEnd: "red", 25916 colorTrigger: "blue" 25917 }; 25918 25919 options = _util.extend({}, DEFAULT_OPTIONS, options); 25920 25921 _autoindex++; 25922 _indicator = new Indicator(Scene, options); 25923 25924 Scene.on("add.plugin_addIndicators", _indicator.add); 25925 Scene.on("remove.plugin_addIndicators", _indicator.remove); 25926 Scene.on("destroy.plugin_addIndicators", Scene.removeIndicators); 25927 25928 // it the scene already has a controller we can start right away. 25929 if (Scene.controller()) { 25930 _indicator.add(); 25931 } 25932 } 25933 return Scene; 25934 }; 25935 25936 /** 25937 * Removes visual indicators from a ScrollMagic.Scene. 25938 * @memberof! debug.addIndicators# 25939 * 25940 * @example 25941 * // remove previously added indicators 25942 * scene.removeIndicators() 25943 * 25944 */ 25945 Scene.removeIndicators = function () { 25946 if (_indicator) { 25947 _indicator.remove(); 25948 this.off("*.plugin_addIndicators"); 25949 _indicator = undefined; 25950 } 25951 return Scene; 25952 }; 25953 }); 25954 25955 /* 25956 * ---------------------------------------------------------------- 25957 * Extension for controller to store and update related indicators 25958 * ---------------------------------------------------------------- 25959 */ 25960 // add option to globally auto-add indicators to scenes 25961 /** 25962 * Every ScrollMagic.Controller instance now accepts an additional option. 25963 * See {@link ScrollMagic.Controller} for a complete list of the standard options. 25964 * @memberof! debug.addIndicators# 25965 * @method new ScrollMagic.Controller(options) 25966 * @example 25967 * // make a controller and add indicators to all scenes attached 25968 * var controller = new ScrollMagic.Controller({addIndicators: true}); 25969 * // this scene will automatically have indicators added to it 25970 * new ScrollMagic.Scene() 25971 * .addTo(controller); 25972 * 25973 * @param {object} [options] - Options for the Controller. 25974 * @param {boolean} [options.addIndicators=false] - If set to `true` every scene that is added to the controller will automatically get indicators added to it. 25975 */ 25976 ScrollMagic.Controller.addOption("addIndicators", false); 25977 // extend Controller 25978 ScrollMagic.Controller.extend(function () { 25979 var Controller = this, 25980 _info = Controller.info(), 25981 _container = _info.container, 25982 _isDocument = _info.isDocument, 25983 _vertical = _info.vertical, 25984 _indicators = { // container for all indicators and methods 25985 groups: [] 25986 }; 25987 25988 var log = function () { 25989 if (Controller._log) { 25990 // not available, when main source minified 25991 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); 25992 Controller._log.apply(this, arguments); 25993 } 25994 }; 25995 if (Controller._indicators) {
25996 log(2, "WARNING: Scene already has a property '_indicators', which will be overwritten by plugin."); 25997 } 25998 25999 // add indicators container 26000 this._indicators = _indicators; 26001 /* 26002 needed updates: 26003 +++++++++++++++ 26004 start/end position on scene shift (handled in Indicator class) 26005 trigger parameters on triggerHook value change (handled in Indicator class) 26006 bounds position on container scroll or resize (to keep alignment to bottom/right) 26007 trigger position on container resize, window resize (if container isn't document) and window scroll (if container isn't document) 26008 */ 26009 26010 // event handler for when associated bounds markers need to be repositioned 26011 var handleBoundsPositionChange = function () { 26012 _indicators.updateBoundsPositions(); 26013 }; 26014 26015 // event handler for when associated trigger groups need to be repositioned 26016 var handleTriggerPositionChange = function () { 26017 _indicators.updateTriggerGroupPositions(); 26018 }; 26019 26020 _container.addEventListener("resize", handleTriggerPositionChange); 26021 if (!_isDocument) { 26022 window.addEventListener("resize", handleTriggerPositionChange); 26023 window.addEventListener("scroll", handleTriggerPositionChange); 26024 } 26025 // update all related bounds containers 26026 _container.addEventListener("resize", handleBoundsPositionChange); 26027 _container.addEventListener("scroll", handleBoundsPositionChange); 26028 26029 // updates the position of the bounds container to aligned to the right for vertical containers and to the bottom for horizontal 26030 this._indicators.updateBoundsPositions = function (specificIndicator) { 26031 var // constant for all bounds 26032 groups = specificIndicator ? [_util.extend({}, specificIndicator.triggerGroup, { 26033 members: [specificIndicator] 26034 })] : // create a group with only one element 26035 _indicators.groups, 26036 26037 // use all 26038 g = groups.length, 26039 css = {}, 26040 paramPos = _vertical ? "left" : "top", 26041 paramDimension = _vertical ? "width" : "height", 26042 edge = _vertical ? _util.get.scrollLeft(_container) + _util.get.width(_container) - EDGE_OFFSET : _util.get.scrollTop(_container) + _util.get.height(_container) - EDGE_OFFSET, 26043 b, 26044 triggerSize, 26045 group; 26046 while (g--) { 26047 // group loop 26048 group = groups[g]; 26049 b = group.members.length; 26050 triggerSize = _util.get[paramDimension](group.element.firstChild); 26051 while (b--) { 26052 // indicators loop 26053 css[paramPos] = edge - triggerSize; 26054 _util.css(group.members[b].bounds, css); 26055 } 26056 } 26057 }; 26058 26059 // updates the positions of all trigger groups attached to a controller or a specific one, if provided 26060 this._indicators.updateTriggerGroupPositions = function (specificGroup) { 26061 var // constant vars 26062 groups = specificGroup ? [specificGroup] : _indicators.groups, 26063 i = groups.length, 26064 container = _isDocument ? document.body : _container, 26065 containerOffset = _isDocument ? { 26066 top: 0, 26067 left: 0 26068 } : _util.get.offset(container, true), 26069 edge = _vertical ? _util.get.width(_container) - EDGE_OFFSET : _util.get.height(_container) - EDGE_OFFSET, 26070 paramDimension = _vertical ? "width" : "height", 26071 paramTransform = _vertical ? "Y" : "X"; 26072 var // changing vars 26073 group, elem, pos, elemSize, transform; 26074 while (i--) { 26075 group = groups[i]; 26076 elem = group.element; 26077 pos = group.triggerHook * Controller.info("size"); 26078 elemSize = _util.get[paramDimension](elem.firstChild.firstChild); 26079 transform = pos > elemSize ? "translate" + paramTransform + "(-100%)" : ""; 26080 26081 _util.css(elem, { 26082 top: containerOffset.top + (_vertical ? pos : edge - group.members[0].options.indent), 26083 left: containerOffset.left + (_vertical ? edge - group.members[0].options.indent : pos) 26084 }); 26085 _util.css(elem.firstChild.firstChild, { 26086 "-ms-transform": transform, 26087 "-webkit-transform": transform, 26088 "transform": transform 26089 }); 26090 } 26091 }; 26092 26093 // updates the label for the group to contain the name, if it only has one member 26094 this._indicators.updateTriggerGroupLabel = function (group) { 26095 var text = "trigger" + (group.members.length > 1 ? "" : " " + group.members[0].options.name), 26096 elem = group.element.firstChild.firstChild, 26097 doUpdate = elem.textContent !== text; 26098 if (doUpdate) { 26099 elem.textContent = text; 26100 if (_vertical) { 26101 // bounds position is dependent on text length, so update 26102 _indicators.updateBoundsPositions(); 26103 } 26104 } 26105 }; 26106 26107 // add indicators if global option is set 26108 this.addScene = function (newScene) { 26109 26110 if (this._options.addIndicators && newScene instanceof ScrollMagic.Scene && newScene.controller() === Controller) { 26111 newScene.addIndicators(); 26112 } 26113 // call original destroy method 26114 this.$super.addScene.apply(this, arguments); 26115 }; 26116 26117 // remove all previously set listeners on destroy 26118 this.destroy = function () { 26119 _container.removeEventListener("resize", handleTriggerPositionChange); 26120 if (!_isDocument) { 26121 window.removeEventListener("resize", handleTriggerPositionChange); 26122 window.removeEventListener("scroll", handleTriggerPositionChange); 26123 } 26124 _container.removeEventListener("resize", handleBoundsPositionChange); 26125 _container.removeEventListener("scroll", handleBoundsPositionChange); 26126 // call original destroy method 26127 this.$super.destroy.apply(this, arguments); 26128 }; 26129 return Controller; 26130 }); 26131 26132 /* 26133 * ----------------------------------------------------------------
26134 * Internal class for the construction of Indicators 26135 * ---------------------------------------------------------------- 26136 */ 26137 var Indicator = function (Scene, options) { 26138 var Indicator = this, 26139 _elemBounds = TPL.bounds(), 26140 _elemStart = TPL.start(options.colorStart), 26141 _elemEnd = TPL.end(options.colorEnd), 26142 _boundsContainer = options.parent && _util.get.elements(options.parent)[0], 26143 _vertical, 26144 _ctrl; 26145 26146 var log = function () { 26147 if (Scene._log) { 26148 // not available, when main source minified 26149 Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); 26150 Scene._log.apply(this, arguments); 26151 } 26152 }; 26153 26154 options.name = options.name || _autoindex; 26155 26156 // prepare bounds elements 26157 _elemStart.firstChild.textContent += " " + options.name; 26158 _elemEnd.textContent += " " + options.name; 26159 _elemBounds.appendChild(_elemStart); 26160 _elemBounds.appendChild(_elemEnd); 26161 26162 // set public variables 26163 Indicator.options = options; 26164 Indicator.bounds = _elemBounds; 26165 // will be set later 26166 Indicator.triggerGroup = undefined; 26167 26168 // add indicators to DOM 26169 this.add = function () { 26170 _ctrl = Scene.controller(); 26171 _vertical = _ctrl.info("vertical"); 26172 26173 var isDocument = _ctrl.info("isDocument"); 26174 26175 if (!_boundsContainer) { 26176 // no parent supplied or doesnt exist 26177 _boundsContainer = isDocument ? document.body : _ctrl.info("container"); // check if window/document (then use body) 26178 } 26179 if (!isDocument && _util.css(_boundsContainer, "position") === 'static') {
26180 // position mode needed for correct positioning of indicators 26181 _util.css(_boundsContainer, { 26182 position: "relative" 26183 }); 26184 } 26185 26186 // add listeners for updates 26187 Scene.on("change.plugin_addIndicators", handleTriggerParamsChange); 26188 Scene.on("shift.plugin_addIndicators", handleBoundsParamsChange); 26189 26190 // updates trigger & bounds (will add elements if needed) 26191 updateTriggerGroup(); 26192 updateBounds(); 26193 26194 setTimeout(function () { 26195 // do after all execution is finished otherwise sometimes size calculations are off 26196 _ctrl._indicators.updateBoundsPositions(Indicator); 26197 }, 0); 26198 26199 log(3, "added indicators"); 26200 }; 26201 26202 // remove indicators from DOM 26203 this.remove = function () { 26204 if (Indicator.triggerGroup) { 26205 // if not set there's nothing to remove 26206 Scene.off("change.plugin_addIndicators", handleTriggerParamsChange); 26207 Scene.off("shift.plugin_addIndicators", handleBoundsParamsChange); 26208 26209 if (Indicator.triggerGroup.members.length > 1) { 26210 // just remove from memberlist of old group 26211 var group = Indicator.triggerGroup; 26212 group.members.splice(group.members.indexOf(Indicator), 1); 26213 _ctrl._indicators.updateTriggerGroupLabel(group); 26214 _ctrl._indicators.updateTriggerGroupPositions(group); 26215 Indicator.triggerGroup = undefined; 26216 } else { 26217 // remove complete group 26218 removeTriggerGroup(); 26219 } 26220 removeBounds(); 26221 26222 log(3, "removed indicators"); 26223 } 26224 }; 26225 26226 /* 26227 * ---------------------------------------------------------------- 26228 * internal Event Handlers 26229 * ---------------------------------------------------------------- 26230 */ 26231 26232 // event handler for when bounds params change 26233 var handleBoundsParamsChange = function () { 26234 updateBounds(); 26235 }; 26236 26237 // event handler for when trigger params change 26238 var handleTriggerParamsChange = function (e) { 26239 if (e.what === "triggerHook") { 26240 updateTriggerGroup(); 26241 } 26242 }; 26243 26244 /* 26245 * ---------------------------------------------------------------- 26246 * Bounds (start / stop) management 26247 * ---------------------------------------------------------------- 26248 */ 26249 26250 // adds an new bounds elements to the array and to the DOM 26251 var addBounds = function () { 26252 var v = _ctrl.info("vertical"); 26253 // apply stuff we didn't know before... 26254 _util.css(_elemStart.firstChild, { 26255 "border-bottom-width": v ? 1 : 0, 26256 "border-right-width": v ? 0 : 1, 26257 "bottom": v ? -1 : options.indent, 26258 "right": v ? options.indent : -1, 26259 "padding": v ? "0 8px" : "2px 4px" 26260 }); 26261 _util.css(_elemEnd, { 26262 "border-top-width": v ? 1 : 0, 26263 "border-left-width": v ? 0 : 1, 26264 "top": v ? "100%" : "", 26265 "right": v ? options.indent : "", 26266 "bottom": v ? "" : options.indent, 26267 "left": v ? "" : "100%", 26268 "padding": v ? "0 8px" : "2px 4px" 26269 }); 26270 // append 26271 _boundsContainer.appendChild(_elemBounds); 26272 }; 26273 26274 // remove bounds from list and DOM 26275 var removeBounds = function () { 26276 _elemBounds.parentNode.removeChild(_elemBounds); 26277 }; 26278 26279 // update the start and end positions of the scene 26280 var updateBounds = function () { 26281 if (_elemBounds.parentNode !== _boundsContainer) { 26282 addBounds(); // Add Bounds elements (start/end) 26283 } 26284 var css = {}; 26285 css[_vertical ? "top" : "left"] = Scene.triggerPosition(); 26286 css[_vertical ? "height" : "width"] = Scene.duration(); 26287 _util.css(_elemBounds, css); 26288 _util.css(_elemEnd, { 26289 display: Scene.duration() > 0 ? "" : "none" 26290 }); 26291 }; 26292 26293 /* 26294 * ---------------------------------------------------------------- 26295 * trigger and trigger group management 26296 * ---------------------------------------------------------------- 26297 */ 26298 26299 // adds an new trigger group to the array and to the DOM 26300 var addTriggerGroup = function () { 26301 var triggerElem = TPL.trigger(options.colorTrigger); // new trigger element 26302 var css = {}; 26303 css[_vertical ? "right" : "bottom"] = 0; 26304 css[_vertical ? "border-top-width" : "border-left-width"] = 1; 26305 _util.css(triggerElem.firstChild, css); 26306 _util.css(triggerElem.firstChild.firstChild, { 26307 padding: _vertical ? "0 8px 3px 8px" : "3px 4px" 26308 }); 26309 document.body.appendChild(triggerElem); // directly add to body 26310 var newGroup = { 26311 triggerHook: Scene.triggerHook(), 26312 element: triggerElem, 26313 members: [Indicator] 26314 }; 26315 _ctrl._indicators.groups.push(newGroup); 26316 Indicator.triggerGroup = newGroup; 26317 // update right away 26318 _ctrl._indicators.updateTriggerGroupLabel(newGroup); 26319 _ctrl._indicators.updateTriggerGroupPositions(newGroup); 26320 }; 26321 26322 var removeTriggerGroup = function () { 26323 _ctrl._indicators.groups.splice(_ctrl._indicators.groups.indexOf(Indicator.triggerGroup), 1); 26324 Indicator.triggerGroup.element.parentNode.removeChild(Indicator.triggerGroup.element); 26325 Indicator.triggerGroup = undefined; 26326 }; 26327 26328 // updates the trigger group -> either join existing or add new one 26329 /* 26330 * Logic: 26331 * 1 if a trigger group exist, check if it's in sync with Scene settings â if so, nothing else needs to happen 26332 * 2 try to find an existing one that matches Scene parameters 26333 * 2.1 If a match is found check if already assigned to an existing group 26334 * If so: 26335 * A: it was the last member of existing group -> kill whole group 26336 * B: the existing group has other members -> just remove from member list 26337 * 2.2 Assign to matching group 26338 * 3 if no new match could be found, check if assigned to existing group 26339 * A: yes, and it's the only member -> just update parameters and positions and keep using this group 26340 * B: yes but there are other members -> remove from member list and create a new one 26341 * C: no, so create a new one 26342 */ 26343 var updateTriggerGroup = function () { 26344 var triggerHook = Scene.triggerHook(), 26345 closeEnough = 0.0001; 26346 26347 // Have a group, check if it still matches 26348 if (Indicator.triggerGroup) { 26349 if (Math.abs(Indicator.triggerGroup.triggerHook - triggerHook) < closeEnough) { 26350 // _util.log(0, "trigger", options.name, "->", "no need to change, still in sync"); 26351 return; // all good 26352 } 26353 } 26354 // Don't have a group, check if a matching one exists 26355 // _util.log(0, "trigger", options.name, "->", "out of sync!"); 26356 var groups = _ctrl._indicators.groups, 26357 group, 26358 i = groups.length; 26359 while (i--) { 26360 group = groups[i]; 26361 if (Math.abs(group.triggerHook - triggerHook) < closeEnough) { 26362 // found a match! 26363 // _util.log(0, "trigger", options.name, "->", "found match"); 26364 if (Indicator.triggerGroup) { 26365 // do I have an old group that is out of sync? 26366 if (Indicator.triggerGroup.members.length === 1) { 26367 // is it the only remaining group? 26368 // _util.log(0, "trigger", options.name, "->", "kill"); 26369 // was the last member, remove the whole group 26370 removeTriggerGroup(); 26371 } else { 26372 Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group 26373 _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup); 26374 _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); 26375 // _util.log(0, "trigger", options.name, "->", "removing from previous member list"); 26376 } 26377 } 26378 // join new group 26379 group.members.push(Indicator); 26380 Indicator.triggerGroup = group; 26381 _ctrl._indicators.updateTriggerGroupLabel(group); 26382 return; 26383 } 26384 } 26385 26386 // at this point I am obviously out of sync and don't match any other group 26387 if (Indicator.triggerGroup) { 26388 if (Indicator.triggerGroup.members.length === 1) { 26389 // _util.log(0, "trigger", options.name, "->", "updating existing"); 26390 // out of sync but i'm the only member => just change and update 26391 Indicator.triggerGroup.triggerHook = triggerHook; 26392 _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); 26393 return; 26394 } else { 26395 // _util.log(0, "trigger", options.name, "->", "removing from previous member list"); 26396 Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group 26397 _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup); 26398 _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); 26399 Indicator.triggerGroup = undefined; // need a brand new group... 26400 } 26401 } 26402 // _util.log(0, "trigger", options.name, "->", "add a new one"); 26403 // did not find any match, make new trigger group 26404 addTriggerGroup(); 26405 }; 26406 }; 26407 26408 /* 26409 * ---------------------------------------------------------------- 26410 * Templates for the indicators 26411 * ---------------------------------------------------------------- 26412 */ 26413 var TPL = { 26414 start: function (color) { 26415 // inner element (for bottom offset -1, while keeping top position 0) 26416 var inner = document.createElement("div"); 26417 inner.textContent = "start"; 26418 _util.css(inner, { 26419 position: "absolute", 26420 overflow: "visible", 26421 "border-width": 0, 26422 "border-style": "solid", 26423 color: color, 26424 "border-color": color 26425 }); 26426 var e = document.createElement('div'); 26427 // wrapper 26428 _util.css(e, { 26429 position: "absolute", 26430 overflow: "visible", 26431 width: 0, 26432 height: 0 26433 }); 26434 e.appendChild(inner); 26435 return e; 26436 }, 26437 end: function (color) { 26438 var e = document.createElement('div'); 26439 e.textContent = "end"; 26440 _util.css(e, { 26441 position: "absolute", 26442 overflow: "visible", 26443 "border-width": 0, 26444 "border-style": "solid", 26445 color: color, 26446 "border-color": color 26447 }); 26448 return e; 26449 }, 26450 bounds: function () { 26451 var e = document.createElement('div'); 26452 _util.css(e, { 26453 position: "absolute", 26454 overflow: "visible", 26455 "white-space": "nowrap", 26456 "pointer-events": "none", 26457 "font-size": FONT_SIZE 26458 }); 26459 e.style.zIndex = ZINDEX; 26460 return e; 26461 }, 26462 trigger: function (color) { 26463 // inner to be above or below line but keep position 26464 var inner = document.createElement('div'); 26465 inner.textContent = "trigger"; 26466 _util.css(inner, { 26467 position: "relative" 26468 }); 26469 // inner wrapper for right: 0 and main element has no size 26470 var w = document.createElement('div'); 26471 _util.css(w, { 26472 position: "absolute", 26473 overflow: "visible", 26474 "border-width": 0, 26475 "border-style": "solid", 26476 color: color, 26477 "border-color": color 26478 }); 26479 w.appendChild(inner); 26480 // wrapper 26481 var e = document.createElement('div'); 26482 _util.css(e, { 26483 position: "fixed", 26484 overflow: "visible", 26485 "white-space": "nowrap", 26486 "pointer-events": "none", 26487 "font-size": FONT_SIZE 26488 }); 26489 e.style.zIndex = ZINDEX; 26490 e.appendChild(w); 26491 return e; 26492 } 26493 }; 26494}); 26495 26496/***/ }), 26497/* 23 */ 26498/***/ (function(module, exports, __webpack_require__) { 26499 26500/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 26501 * VERSION: 1.20.3 26502 * DATE: 2017-10-02 26503 * UPDATES AND DOCS AT: http://greensock.com 26504 * 26505 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved. 26506 * This work is subject to the terms at http://greensock.com/standard-license or for
26507 * Club GreenSock members, the software agreement that was issued with your membership. 26508 * 26509 * @author: Jack Doyle, [email protected] 26510 */ 26511var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node 26512(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () { 26513 26514 "use strict"; 26515 26516 _gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) { 26517 26518 var TimelineLite = function (vars) { 26519 SimpleTimeline.call(this, vars); 26520 this._labels = {}; 26521 this.autoRemoveChildren = this.vars.autoRemoveChildren === true; 26522 this.smoothChildTiming = this.vars.smoothChildTiming === true; 26523 this._sortChildren = true; 26524 this._onUpdate = this.vars.onUpdate; 26525 var v = this.vars, 26526 val, 26527 p; 26528 for (p in v) { 26529 val = v[p]; 26530 if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) { 26531 v[p] = this._swapSelfInParams(val); 26532 } 26533 } 26534 if (_isArray(v.tweens)) { 26535 this.add(v.tweens, 0, v.align, v.stagger); 26536 } 26537 }, 26538 _tinyNum = 0.0000000001, 26539 TweenLiteInternals = TweenLite._internals, 26540 _internals = TimelineLite._internals = {}, 26541 _isSelector = TweenLiteInternals.isSelector, 26542 _isArray = TweenLiteInternals.isArray, 26543 _lazyTweens = TweenLiteInternals.lazyTweens, 26544 _lazyRender = TweenLiteInternals.lazyRender, 26545 _globals = _gsScope._gsDefine.globals, 26546 _copy = function (vars) { 26547 var copy = {}, 26548 p; 26549 for (p in vars) { 26550 copy[p] = vars[p]; 26551 } 26552 return copy; 26553 }, 26554 _applyCycle = function (vars, targets, i) { 26555 var alt = vars.cycle, 26556 p, 26557 val; 26558 for (p in alt) { 26559 val = alt[p]; 26560 vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length]; 26561 } 26562 delete vars.cycle; 26563 }, 26564 _pauseCallback = _internals.pauseCallback = function () {}, 26565 _slice = function (a) { 26566 //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll() 26567 var b = [], 26568 l = a.length, 26569 i; 26570 for (i = 0; i !== l; b.push(a[i++])); 26571 return b; 26572 }, 26573 p = TimelineLite.prototype = new SimpleTimeline(); 26574 26575 TimelineLite.version = "1.20.3"; 26576 p.constructor = TimelineLite; 26577 p.kill()._gc = p._forcingPlayhead = p._hasPause = false; 26578 26579 /* might use later... 26580 //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales. 26581 function localToGlobal(time, animation) { 26582 while (animation) { 26583 time = (time / animation._timeScale) + animation._startTime; 26584 animation = animation.timeline; 26585 } 26586 return time; 26587 } 26588 //translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales 26589 function globalToLocal(time, animation) { 26590 var scale = 1; 26591 time -= localToGlobal(0, animation); 26592 while (animation) { 26593 scale *= animation._timeScale; 26594 animation = animation.timeline; 26595 } 26596 return time * scale; 26597 } 26598 */ 26599 26600 p.to = function (target, duration, vars, position) { 26601 var Engine = vars.repeat && _globals.TweenMax || TweenLite; 26602 return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position); 26603 }; 26604 26605 p.from = function (target, duration, vars, position) { 26606 return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position); 26607 }; 26608 26609 p.fromTo = function (target, duration, fromVars, toVars, position) { 26610 var Engine = toVars.repeat && _globals.TweenMax || TweenLite; 26611 return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position); 26612 }; 26613 26614 p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 26615 var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }), 26616 cycle = vars.cycle, 26617 copy, 26618 i; 26619 if (typeof targets === "string") { 26620 targets = TweenLite.selector(targets) || targets; 26621 } 26622 targets = targets || []; 26623 if (_isSelector(targets)) { 26624 //senses if the targets object is a selector. If it is, we should translate it into an array.
26625 targets = _slice(targets); 26626 } 26627 stagger = stagger || 0; 26628 if (stagger < 0) { 26629 targets = _slice(targets); 26630 targets.reverse(); 26631 stagger *= -1; 26632 } 26633 for (i = 0; i < targets.length; i++) { 26634 copy = _copy(vars); 26635 if (copy.startAt) { 26636 copy.startAt = _copy(copy.startAt); 26637 if (copy.startAt.cycle) { 26638 _applyCycle(copy.startAt, targets, i); 26639 } 26640 } 26641 if (cycle) { 26642 _applyCycle(copy, targets, i); 26643 if (copy.duration != null) { 26644 duration = copy.duration; 26645 delete copy.duration; 26646 } 26647 } 26648 tl.to(targets[i], duration, copy, i * stagger); 26649 } 26650 return this.add(tl, position); 26651 }; 26652 26653 p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 26654 vars.immediateRender = vars.immediateRender != false; 26655 vars.runBackwards = true; 26656 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 26657 }; 26658 26659 p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) { 26660 toVars.startAt = fromVars; 26661 toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false; 26662 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope); 26663 }; 26664 26665 p.call = function (callback, params, scope, position) { 26666 return this.add(TweenLite.delayedCall(0, callback, params, scope), position); 26667 }; 26668 26669 p.set = function (target, vars, position) { 26670 position = this._parseTimeOrLabel(position, 0, true); 26671 if (vars.immediateRender == null) { 26672 vars.immediateRender = position === this._time && !this._paused; 26673 } 26674 return this.add(new TweenLite(target, 0, vars), position); 26675 }; 26676 26677 TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) { 26678 vars = vars || {}; 26679 if (vars.smoothChildTiming == null) { 26680 vars.smoothChildTiming = true; 26681 } 26682 var tl = new TimelineLite(vars), 26683 root = tl._timeline, 26684 hasNegativeStart, 26685 time, 26686 tween, 26687 next; 26688 if (ignoreDelayedCalls == null) { 26689 ignoreDelayedCalls = true; 26690 } 26691 root._remove(tl, true); 26692 tl._startTime = 0; 26693 tl._rawPrevTime = tl._time = tl._totalTime = root._time; 26694 tween = root._first; 26695 while (tween) { 26696 next = tween._next; 26697 if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) { 26698 time = tween._startTime - tween._delay; 26699 if (time < 0) { 26700 hasNegativeStart = 1; 26701 } 26702 tl.add(tween, time); 26703 } 26704 tween = next; 26705 } 26706 root.add(tl, 0); 26707 if (hasNegativeStart) { 26708 //calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero. 26709 tl.totalDuration(); 26710 } 26711 return tl; 26712 }; 26713 26714 p.add = function (value, position, align, stagger) { 26715 var curTime, l, i, child, tl, beforeRawTime; 26716 if (typeof position !== "number") { 26717 position = this._parseTimeOrLabel(position, 0, true, value); 26718 } 26719 if (!(value instanceof Animation)) { 26720 if (value instanceof Array || value && value.push && _isArray(value)) { 26721 align = align || "normal"; 26722 stagger = stagger || 0; 26723 curTime = position; 26724 l = value.length; 26725 for (i = 0; i < l; i++) { 26726 if (_isArray(child = value[i])) { 26727 child = new TimelineLite({ tweens: child }); 26728 } 26729 this.add(child, curTime); 26730 if (typeof child !== "string" && typeof child !== "function") { 26731 if (align === "sequence") { 26732 curTime = child._startTime + child.totalDuration() / child._timeScale; 26733 } else if (align === "start") { 26734 child._startTime -= child.delay(); 26735 } 26736 } 26737 curTime += stagger; 26738 } 26739 return this._uncache(true); 26740 } else if (typeof value === "string") { 26741 return this.addLabel(value, position); 26742 } else if (typeof value === "function") { 26743 value = TweenLite.delayedCall(0, value); 26744 } else { 26745 throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string."; 26746 } 26747 } 26748 26749 SimpleTimeline.prototype.add.call(this, value, position); 26750 26751 if (value._time) { 26752 //in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 26753 value.render((this.rawTime() - value._startTime) * value._timeScale, false, false); 26754 } 26755 26756 //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 26757 if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) { 26758 //in case any of the ancestors had completed but should now be enabled... 26759 tl = this; 26760 beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect. 26761 while (tl._timeline) { 26762 if (beforeRawTime && tl._timeline.smoothChildTiming) { 26763 tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it. 26764 } else if (tl._gc) { 26765 tl._enabled(true, false); 26766 } 26767 tl = tl._timeline; 26768 } 26769 } 26770 26771 return this; 26772 }; 26773 26774 p.remove = function (value) { 26775 if (value instanceof Animation) { 26776 this._remove(value, false); 26777 var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline. 26778 value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct. 26779 return this; 26780 } else if (value instanceof Array || value && value.push && _isArray(value)) { 26781 var i = value.length; 26782 while (--i > -1) { 26783 this.remove(value[i]); 26784 } 26785 return this; 26786 } else if (typeof value === "string") { 26787 return this.removeLabel(value); 26788 } 26789 return this.kill(null, value); 26790 }; 26791 26792 p._remove = function (tween, skipDisable) { 26793 SimpleTimeline.prototype._remove.call(this, tween, skipDisable); 26794 var last = this._last; 26795 if (!last) { 26796 this._time = this._totalTime = this._duration = this._totalDuration = 0; 26797 } else if (this._time > this.duration()) { 26798 this._time = this._duration; 26799 this._totalTime = this._totalDuration; 26800 } 26801 return this; 26802 }; 26803 26804 p.append = function (value, offsetOrLabel) { 26805 return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value)); 26806 }; 26807 26808 p.insert = p.insertMultiple = function (value, position, align, stagger) { 26809 return this.add(value, position || 0, align, stagger); 26810 }; 26811 26812 p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) { 26813 return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger); 26814 }; 26815 26816 p.addLabel = function (label, position) { 26817 this._labels[label] = this._parseTimeOrLabel(position); 26818 return this; 26819 }; 26820 26821 p.addPause = function (position, callback, params, scope) { 26822 var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this); 26823 t.vars.onComplete = t.vars.onReverseComplete = callback;
26824 t.data = "isPause"; 26825 this._hasPause = true; 26826 return this.add(t, position); 26827 }; 26828 26829 p.removeLabel = function (label) { 26830 delete this._labels[label]; 26831 return this; 26832 }; 26833 26834 p.getLabelTime = function (label) { 26835 return this._labels[label] != null ? this._labels[label] : -1; 26836 }; 26837 26838 p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) { 26839 var clippedDuration, i; 26840 //if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration(). 26841 if (ignore instanceof Animation && ignore.timeline === this) { 26842 this.remove(ignore); 26843 } else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) { 26844 i = ignore.length; 26845 while (--i > -1) { 26846 if (ignore[i] instanceof Animation && ignore[i].timeline === this) { 26847 this.remove(ignore[i]); 26848 } 26849 } 26850 } 26851 clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 26852 if (typeof offsetOrLabel === "string") { 26853 return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent); 26854 } 26855 offsetOrLabel = offsetOrLabel || 0; 26856 if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) { 26857 //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 26858 i = timeOrLabel.indexOf("="); 26859 if (i === -1) { 26860 if (this._labels[timeOrLabel] == null) { 26861 return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel; 26862 } 26863 return this._labels[timeOrLabel] + offsetOrLabel; 26864 } 26865 offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1)); 26866 timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration; 26867 } else if (timeOrLabel == null) { 26868 timeOrLabel = clippedDuration; 26869 } 26870 return Number(timeOrLabel) + offsetOrLabel; 26871 }; 26872 26873 p.seek = function (position, suppressEvents) { 26874 return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false); 26875 }; 26876 26877 p.stop = function () { 26878 return this.paused(true); 26879 }; 26880 26881 p.gotoAndPlay = function (position, suppressEvents) { 26882 return this.play(position, suppressEvents); 26883 }; 26884 26885 p.gotoAndStop = function (position, suppressEvents) { 26886 return this.pause(position, suppressEvents); 26887 }; 26888 26889 p.render = function (time, suppressEvents, force) { 26890 if (this._gc) { 26891 this._enabled(true, false); 26892 } 26893 var prevTime = this._time, 26894 totalDur = !this._dirty ? this._totalDuration : this.totalDuration(), 26895 prevStart = this._startTime, 26896 prevTimeScale = this._timeScale, 26897 prevPaused = this._paused, 26898 tween, 26899 isComplete, 26900 next, 26901 callback, 26902 internalForce, 26903 pauseTween, 26904 curTime; 26905 if (prevTime !== this._time) { 26906 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 26907 time += this._time - prevTime; 26908 } 26909 if (time >= totalDur - 0.0000001 && time >= 0) { 26910 //to work around occasional floating point math artifacts. 26911 this._totalTime = this._time = totalDur; 26912 if (!this._reversed) if (!this._hasPausedChild()) { 26913 isComplete = true; 26914 callback = "onComplete"; 26915 internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline. 26916 if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) { 26917 internalForce = true; 26918 if (this._rawPrevTime > _tinyNum) { 26919 callback = "onReverseComplete"; 26920 } 26921 } 26922 } 26923 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 26924 time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. 26925 } else if (time < 0.0000001) { 26926 //to work around occasional floating point math artifacts, round super small values to 0. 26927 this._totalTime = this._time = 0; 26928 if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) { 26929 callback = "onReverseComplete"; 26930 isComplete = this._reversed; 26931 } 26932 if (time < 0) { 26933 this._active = false;
26934 if (this._timeline.autoRemoveChildren && this._reversed) { 26935 //ensures proper GC if a timeline is resumed after it's finished reversing. 26936 internalForce = isComplete = true; 26937 callback = "onReverseComplete"; 26938 } else if (this._rawPrevTime >= 0 && this._first) { 26939 //when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state. 26940 internalForce = true; 26941 } 26942 this._rawPrevTime = time; 26943 } else { 26944 this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient. 26945 if (time === 0 && isComplete) { 26946 //if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good). 26947 tween = this._first; 26948 while (tween && tween._startTime === 0) { 26949 if (!tween._duration) { 26950 isComplete = false; 26951 } 26952 tween = tween._next; 26953 } 26954 } 26955 time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline) 26956 if (!this._initted) { 26957 internalForce = true; 26958 } 26959 } 26960 } else { 26961 26962 if (this._hasPause && !this._forcingPlayhead && !suppressEvents) { 26963 if (time >= prevTime) { 26964 tween = this._first; 26965 while (tween && tween._startTime <= time && !pauseTween) { 26966 if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) { 26967 pauseTween = tween; 26968 } 26969 tween = tween._next; 26970 } 26971 } else { 26972 tween = this._last; 26973 while (tween && tween._startTime >= time && !pauseTween) { 26974 if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) { 26975 pauseTween = tween; 26976 } 26977 tween = tween._prev; 26978 } 26979 } 26980 if (pauseTween) { 26981 this._time = time = pauseTween._startTime; 26982 this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay); 26983 } 26984 } 26985 26986 this._totalTime = this._time = this._rawPrevTime = time; 26987 } 26988 if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) { 26989 return; 26990 } else if (!this._initted) { 26991 this._initted = true; 26992 } 26993 26994 if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) { 26995 this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example. 26996 } 26997 26998 if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) { 26999 this._callback("onStart"); 27000 } 27001 27002 curTime = this._time; 27003 if (curTime >= prevTime) { 27004 tween = this._first; 27005 while (tween) { 27006 next = tween._next; //record it here because the value could change after rendering... 27007 if (curTime !== this._time || this._paused && !prevPaused) { 27008 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 27009 break; 27010 } else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) { 27011 if (pauseTween === tween) { 27012 this.pause(); 27013 } 27014 if (!tween._reversed) { 27015 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 27016 } else { 27017 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 27018 } 27019 } 27020 tween = next; 27021 } 27022 } else { 27023 tween = this._last; 27024 while (tween) { 27025 next = tween._prev; //record it here because the value could change after rendering... 27026 if (curTime !== this._time || this._paused && !prevPaused) { 27027 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 27028 break; 27029 } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) { 27030 if (pauseTween === tween) { 27031 pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse. 27032 while (pauseTween && pauseTween.endTime() > this._time) { 27033 pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force); 27034 pauseTween = pauseTween._prev; 27035 } 27036 pauseTween = null; 27037 this.pause(); 27038 } 27039 if (!tween._reversed) { 27040 tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force); 27041 } else { 27042 tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force); 27043 } 27044 } 27045 tween = next; 27046 } 27047 } 27048 27049 if (this._onUpdate) if (!suppressEvents) { 27050 if (_lazyTweens.length) { 27051 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 27052 _lazyRender(); 27053 }
27054 this._callback("onUpdate"); 27055 } 27056 27057 if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) { 27058 //if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate 27059 if (isComplete) { 27060 if (_lazyTweens.length) { 27061 //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values. 27062 _lazyRender(); 27063 } 27064 if (this._timeline.autoRemoveChildren) { 27065 this._enabled(false, false); 27066 } 27067 this._active = false; 27068 } 27069 if (!suppressEvents && this.vars[callback]) { 27070 this._callback(callback); 27071 } 27072 } 27073 }; 27074 27075 p._hasPausedChild = function () { 27076 var tween = this._first; 27077 while (tween) { 27078 if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) { 27079 return true; 27080 } 27081 tween = tween._next; 27082 } 27083 return false; 27084 }; 27085 27086 p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) { 27087 ignoreBeforeTime = ignoreBeforeTime || -9999999999; 27088 var a = [], 27089 tween = this._first, 27090 cnt = 0; 27091 while (tween) { 27092 if (tween._startTime < ignoreBeforeTime) { 27093 //do nothing 27094 } else if (tween instanceof TweenLite) { 27095 if (tweens !== false) { 27096 a[cnt++] = tween; 27097 } 27098 } else { 27099 if (timelines !== false) { 27100 a[cnt++] = tween; 27101 } 27102 if (nested !== false) { 27103 a = a.concat(tween.getChildren(true, tweens, timelines)); 27104 cnt = a.length; 27105 } 27106 } 27107 tween = tween._next; 27108 } 27109 return a; 27110 }; 27111 27112 p.getTweensOf = function (target, nested) { 27113 var disabled = this._gc, 27114 a = [], 27115 cnt = 0, 27116 tweens, 27117 i; 27118 if (disabled) { 27119 this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here. 27120 } 27121 tweens = TweenLite.getTweensOf(target); 27122 i = tweens.length; 27123 while (--i > -1) { 27124 if (tweens[i].timeline === this || nested && this._contains(tweens[i])) { 27125 a[cnt++] = tweens[i]; 27126 } 27127 } 27128 if (disabled) { 27129 this._enabled(false, true); 27130 } 27131 return a; 27132 }; 27133 27134 p.recent = function () { 27135 return this._recent; 27136 }; 27137 27138 p._contains = function (tween) { 27139 var tl = tween.timeline; 27140 while (tl) { 27141 if (tl === this) { 27142 return true; 27143 } 27144 tl = tl.timeline; 27145 } 27146 return false; 27147 }; 27148 27149 p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) { 27150 ignoreBeforeTime = ignoreBeforeTime || 0; 27151 var tween = this._first, 27152 labels = this._labels, 27153 p; 27154 while (tween) { 27155 if (tween._startTime >= ignoreBeforeTime) { 27156 tween._startTime += amount; 27157 } 27158 tween = tween._next; 27159 }
27160 if (adjustLabels) { 27161 for (p in labels) { 27162 if (labels[p] >= ignoreBeforeTime) { 27163 labels[p] += amount; 27164 } 27165 } 27166 } 27167 return this._uncache(true); 27168 }; 27169 27170 p._kill = function (vars, target) { 27171 if (!vars && !target) { 27172 return this._enabled(false, false); 27173 } 27174 var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target), 27175 i = tweens.length, 27176 changed = false; 27177 while (--i > -1) { 27178 if (tweens[i]._kill(vars, target)) { 27179 changed = true; 27180 } 27181 } 27182 return changed; 27183 }; 27184 27185 p.clear = function (labels) { 27186 var tweens = this.getChildren(false, true, true), 27187 i = tweens.length; 27188 this._time = this._totalTime = 0; 27189 while (--i > -1) { 27190 tweens[i]._enabled(false, false); 27191 } 27192 if (labels !== false) { 27193 this._labels = {}; 27194 } 27195 return this._uncache(true); 27196 }; 27197 27198 p.invalidate = function () { 27199 var tween = this._first; 27200 while (tween) { 27201 tween.invalidate(); 27202 tween = tween._next; 27203 } 27204 return Animation.prototype.invalidate.call(this);; 27205 }; 27206 27207 p._enabled = function (enabled, ignoreTimeline) { 27208 if (enabled === this._gc) { 27209 var tween = this._first; 27210 while (tween) { 27211 tween._enabled(enabled, true); 27212 tween = tween._next; 27213 } 27214 } 27215 return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline); 27216 }; 27217 27218 p.totalTime = function (time, suppressEvents, uncapped) { 27219 this._forcingPlayhead = true; 27220 var val = Animation.prototype.totalTime.apply(this, arguments); 27221 this._forcingPlayhead = false; 27222 return val; 27223 }; 27224 27225 p.duration = function (value) { 27226 if (!arguments.length) { 27227 if (this._dirty) { 27228 this.totalDuration(); //just triggers recalculation 27229 } 27230 return this._duration; 27231 } 27232 if (this.duration() !== 0 && value !== 0) { 27233 this.timeScale(this._duration / value); 27234 } 27235 return this; 27236 }; 27237 27238 p.totalDuration = function (value) { 27239 if (!arguments.length) { 27240 if (this._dirty) { 27241 var max = 0, 27242 tween = this._last, 27243 prevStart = 999999999999, 27244 prev, 27245 end; 27246 while (tween) { 27247 prev = tween._prev; //record it here in case the tween changes position in the sequence... 27248 if (tween._dirty) { 27249 tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it. 27250 } 27251 if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) { 27252 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 27253 this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel(). 27254 this.add(tween, tween._startTime - tween._delay); 27255 this._calculatingDuration = 0; 27256 } else { 27257 prevStart = tween._startTime; 27258 } 27259 if (tween._startTime < 0 && !tween._paused) { 27260 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 27261 max -= tween._startTime; 27262 if (this._timeline.smoothChildTiming) { 27263 this._startTime += tween._startTime / this._timeScale; 27264 this._time -= tween._startTime; 27265 this._totalTime -= tween._startTime; 27266 this._rawPrevTime -= tween._startTime; 27267 } 27268 this.shiftChildren(-tween._startTime, false, -9999999999); 27269 prevStart = 0; 27270 } 27271 end = tween._startTime + tween._totalDuration / tween._timeScale; 27272 if (end > max) { 27273 max = end; 27274 } 27275 tween = prev; 27276 } 27277 this._duration = this._totalDuration = max; 27278 this._dirty = false; 27279 } 27280 return this._totalDuration; 27281 } 27282 return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this; 27283 }; 27284 27285 p.paused = function (value) { 27286 if (!value) { 27287 //if there's a pause directly at the spot from where we're unpausing, skip it. 27288 var tween = this._first, 27289 time = this._time; 27290 while (tween) { 27291 if (tween._startTime === time && tween.data === "isPause") { 27292 tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire. 27293 } 27294 tween = tween._next; 27295 } 27296 } 27297 return Animation.prototype.paused.apply(this, arguments); 27298 }; 27299 27300 p.usesFrames = function () { 27301 var tl = this._timeline; 27302 while (tl._timeline) { 27303 tl = tl._timeline; 27304 } 27305 return tl === Animation._rootFramesTimeline; 27306 }; 27307 27308 p.rawTime = function (wrapRepeats) { 27309 return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale; 27310 }; 27311 27312 return TimelineLite; 27313 }, true); 27314});if (_gsScope._gsDefine) { 27315 _gsScope._gsQueue.pop()(); 27316} 27317 27318//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date) 27319(function (name) { 27320 "use strict"; 27321 27322 var getGlobal = function () { 27323 return (_gsScope.GreenSockGlobals || _gsScope)[name]; 27324 }; 27325 if (typeof module !== "undefined" && module.exports) { 27326 //node 27327 __webpack_require__(1); //dependency 27328 module.exports = getGlobal(); 27329 } else if (true) { 27330 //AMD 27331 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_FACTORY__ = (getGlobal), 27332 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 27333 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
27334 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 27335 } 27336})("TimelineLite"); 27337/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5))) 27338 27339/***/ }), 27340/* 24 */, 27341/* 25 */, 27342/* 26 */, 27343/* 27 */, 27344/* 28 */, 27345/* 29 */, 27346/* 30 */, 27347/* 31 */, 27348/* 32 */, 27349/* 33 */, 27350/* 34 */, 27351/* 35 */, 27352/* 36 */, 27353/* 37 */, 27354/* 38 */, 27355/* 39 */, 27356/* 40 */, 27357/* 41 */, 27358/* 42 */ 27359/***/ (function(module, __webpack_exports__, __webpack_require__) { 27360 27361"use strict"; 27362Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 27363/* WEBPACK VAR INJECTION */(function($, ScrollMagic) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0); 27364/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__); 27365/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_scrollmagic__ = __webpack_require__(2); 27366/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_scrollmagic___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_scrollmagic__); 27367/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_animation__ = __webpack_require__(21); 27368/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_animation___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_animation__); 27369/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_debug_addIndicators__ = __webpack_require__(22); 27370/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_debug_addIndicators___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_debug_addIndicators__); 27371/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_TweenLite__ = __webpack_require__(1); 27372/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_TweenLite___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_TweenLite__); 27373/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_TweenMax__ = __webpack_require__(7); 27374/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_TweenMax___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_TweenMax__); 27375/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_TimelineLite__ = __webpack_require__(23); 27376/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_TimelineLite___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_TimelineLite__); 27377/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_TimelineMax__ = __webpack_require__(8); 27378/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_TimelineMax___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_TimelineMax__); 27379/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__browser__ = __webpack_require__(6); 27380/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__maxin__ = __webpack_require__(9); 27381/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__base__ = __webpack_require__(10); 27382/* eslint no-loop-func: 0 */ 27383/* eslint no-unused-vars: 0 */ 27384/* eslint prefer-destructuring: ["off", {VariableDeclarator: {object: false}}] */ 27385/* eslint no-lonely-if: "off" */ 27386/* eslint max-len: ["error", { "code": 200 }] */ 27387/* eslint no-undef: "off" */ 27388/* eslint func-names: ["error", "never"] */ 27389 27390/** 27391 * ------------------------------------------------------------------ 27392 * å ³äºæ¬£å - 27393 * ------------------------------------------------------------------ 27394 */ 27395 27396/** 27397* @date 2017-10-30 27398* @author Telliex<[email protected]> 27399* Fish<[email protected]> 27400*/ 27401 27402// import ScrollMagic from 'ScrollMagic'; 27403 27404 27405 27406 27407 27408 27409 27410 27411 27412 27413 27414$(() => { 27415 let controller; 27416 let anchorController; 27417 let showStyle; 27418 let scrollStatus = 'show'; 27419 let scrollMovingTimer; 27420 let anchorPin; 27421 // ææç覽å¨å¤å¥å¼ 27422 const GLOBAL_BROWSER_STAT = {}; 27423 27424 let anchorSelected1; 27425 let anchorSelected2; 27426 let anchorSelected3; 27427 let anchorSelected4; 27428 let anchorSelected5; 27429 let anchorSelected6; 27430 27431 const scrollMovingEle = $('.about-scrollmoving-sticker'); 27432 let scrollMovingAni; 27433 27434 const aboutOutline = '.about-outline'; 27435 const aboutOutlineTitle = '.about-outline-title'; 27436 const aboutOutlineGrahic = '.about-outline-grahic'; 27437 const aboutOutlineContent = '.about-outline-content'; 27438 27439 const aboutShinhoLogo = '.about-shinho-logo'; 27440 const aboutShinhoLogoTitle = '.about-shinho-logo-title'; 27441 const aboutShinhoLogoGrahic = '.about-shinho-logo-grahic'; 27442 const aboutShinhoLogoBox = '.about-shinho-logo-box'; 27443 27444 const aboutSlogan = '.about-slogan'; 27445 const aboutSloganTitle = '.about-slogan-title'; 27446 const aboutSloganContent = '.about-slogan-content'; 27447 27448 const aboutPhilosophy = '.about-philosophy'; 27449 const aboutPhilosophyTitle = '.about-philosophy-title'; 27450 const aboutPhilosophyBox = '.about-philosophy-box'; 27451 const aboutPhilosophyItem1 = '.about-philosophy-item:first-child'; 27452 const aboutPhilosophyItem2 = '.about-philosophy-item:nth-child(2)'; 27453 const aboutPhilosophyItem3 = '.about-philosophy-item:nth-child(3)'; 27454 const aboutPhilosophyItem4 = '.about-philosophy-item:nth-child(4)';
27455 const aboutPhilosophyItemArti1 = '.about-philosophy-item:first-child .about-philosophy-article'; 27456 const aboutPhilosophyItemArti2 = '.about-philosophy-item:nth-child(2) .about-philosophy-article'; 27457 const aboutPhilosophyItemArti3 = '.about-philosophy-item:nth-child(3) .about-philosophy-article'; 27458 const aboutPhilosophyItemArti4 = '.about-philosophy-item:nth-child(4) .about-philosophy-article'; 27459 const aboutPhilosophySubtitle1 = '.about-philosophy-item:first-child .about-philosophy-subtitle'; 27460 const aboutPhilosophySubtitle2 = '.about-philosophy-item:nth-child(2) .about-philosophy-subtitle'; 27461 const aboutPhilosophySubtitle3 = '.about-philosophy-item:nth-child(3) .about-philosophy-subtitle'; 27462 const aboutPhilosophySubtitle4 = '.about-philosophy-item:nth-child(4) .about-philosophy-subtitle'; 27463 const aboutPhilosophyMoreBtn = '.about-philosophy-more-btn'; 27464 27465 const aboutFoodeco = '.about-foodeco'; 27466 const aboutFoodecoTitle = '.about-foodeco-title'; 27467 const aboutFoodecoMain = '.about-foodeco-main'; 27468 const aboutFoodecoGrahics = '.about-foodeco-grahics'; 27469 const aboutFoodecoGrahicsBox = '.about-foodeco-grahics-box'; 27470 const aboutFoodecoIntros = '.about-foodeco-intros'; 27471 const aboutFoodecoGrahicsItems = '.about-foodeco-grahics-item'; 27472 const aboutFoodecoGrahicsItem1 = '.about-foodeco-grahics-item:first-child'; 27473 const aboutFoodecoGrahicsItem2 = '.about-foodeco-grahics-item:nth-child(2)'; 27474 const aboutFoodecoGrahicsItem3 = '.about-foodeco-grahics-item:nth-child(3)'; 27475 const aboutFoodecoGrahicsItem4 = '.about-foodeco-grahics-item:nth-child(4)'; 27476 const aboutFoodecoGrahicsItem5 = '.about-foodeco-grahics-item:nth-child(5)'; 27477 const aboutFoodecoGrahicsItem6 = '.about-foodeco-grahics-item:nth-child(6)'; 27478 const aboutFoodecoGrahicsItem7 = '.about-foodeco-grahics-item:nth-child(7)'; 27479 const aboutFoodecoBox = '.about-foodeco-box'; 27480 const aboutFoodecoItem1 = '.about-foodeco-item:first-child'; 27481 const aboutFoodecoItem2 = '.about-foodeco-item:nth-child(2)'; 27482 const aboutFoodecoItem3 = '.about-foodeco-item:nth-child(3)'; 27483 const aboutFoodecoItem4 = '.about-foodeco-item:nth-child(4)'; 27484 const aboutFoodecoItem5 = '.about-foodeco-item:nth-child(5)'; 27485 const aboutFoodecoItem6 = '.about-foodeco-item:nth-child(6)'; 27486 const aboutFoodecoItem7 = '.about-foodeco-item:nth-child(7)'; 27487 const aboutFoodecoMoreBtn = '.about-foodeco-more-btn'; 27488 27489 const aboutWorldwideBranch = '.about-worldwidebranch'; 27490 const aboutWorldwideBranchTitle = '.about-worldwidebranch-title'; 27491 const aboutWorldwideBranchGrahic = '.about-worldwidebranch-grahic'; 27492 const aboutWorldwideBranchGrahicImg = '.about-worldwidebranch-grahic-img'; 27493 const aboutWorldwideBranchBox = '.about-worldwidebranch-box'; 27494 27495 let aboutOutlineTitlePin; 27496 let aboutOutlineGrahicPin; 27497 let aboutOutlineGrahicAni; 27498 let aboutOutlineContentPin; 27499 27500 let aboutShinhoLogoTitlePin; 27501 let aboutShinhoLogoTitleAni; 27502 let aboutShinhoLogoGrahicPin; 27503 let aboutShinhoLogoGrahicAni; 27504 let aboutShinhoLogoBoxPin; 27505 27506 let aboutSloganTitlePin; 27507 let aboutSloganContentPin; 27508 27509 let aboutPhilosophyTitlePin; 27510 let aboutPhilosophyTitleAni; 27511 let aboutPhilosophyItemArti2Ani; 27512 let aboutPhilosophyItemArti3Ani; 27513 let aboutPhilosophyItemArti4Ani; 27514 let aboutPhilosophySubtitle1Pin; 27515 let aboutPhilosophySubtitle2Pin; 27516 let aboutPhilosophySubtitle3Pin; 27517 let aboutPhilosophySubtitle4Pin; 27518 let aboutPhilosophyBoxMask; 27519 let aboutPhilosophyMoreBtnAni; 27520 let aboutPhilosophySubtitle1Anchor; 27521 let aboutPhilosophySubtitle2Anchor; 27522 let aboutPhilosophySubtitle3Anchor; 27523 let aboutPhilosophySubtitle4Anchor; 27524 27525 let aboutFoodecoTitlePin; 27526 let aboutFoodecoTitleAni; 27527 let aboutFoodecoMainMask; 27528 let aboutFoodecoGrahicsPin; 27529 let aboutFoodecoGrahicsAni; 27530 let aboutFoodecoIntrosAni; 27531 let aboutFoodecoGrahicsItemsAni; 27532 let aboutFoodecoGrahicsItemsSelectClear; 27533 let aboutFoodecoGrahicsItem1Anchor; 27534 let aboutFoodecoGrahicsItem2Anchor; 27535 let aboutFoodecoGrahicsItem3Anchor; 27536 let aboutFoodecoGrahicsItem4Anchor; 27537 let aboutFoodecoGrahicsItem5Anchor; 27538 let aboutFoodecoGrahicsItem6Anchor; 27539 let aboutFoodecoGrahicsItem7Anchor; 27540 let aboutFoodecoMoreBtnAni; 27541 27542 let aboutWorldwideBranchTitlePin; 27543 let aboutWorldwideBranchTitleAni; 27544 let aboutWorldwideBranchGrahicPin; 27545 let aboutWorldwideBranchGrahicAni; 27546 let aboutWorldwideBranchBoxMask; 27547 let aboutWorldwideBranchBoxMaskAni; 27548 27549 function durationCount(boxEleA, triggerEleA, offset) { 27550 const boxEle = $(boxEleA); 27551 const triggerEle = $(triggerEleA); 27552 const eleDuration = boxEle.height() - (triggerEle.offset().top - boxEle.offset().top) + offset - 350; 27553 return eleDuration; 27554 } 27555 27556 function foodecoGrahicsItemsSelectClear(event) { 27557 if (event.type === 'enter') { 27558 $('.about-foodeco-grahics-item').removeClass('status-selected'); 27559 } else { 27560 $('.about-foodeco-grahics-item').addClass('status-selected'); 27561 } 27562 } 27563 27564 function aboutOutlineScrollMagic() { 27565 const aboutOutlineGrahicTween = TweenMax.to(aboutOutlineGrahic, 0.3, { x: 235, ease: Linear.easeNone }); 27566 27567 aboutOutlineTitlePin = new ScrollMagic.Scene().triggerElement(aboutOutlineTitle).offset(-110).duration(durationCount(aboutOutline, aboutOutlineTitle, 60)).setPin(aboutOutlineTitle, { pushFollowers: false }) 27568 // .addIndicators() // add indicators (requires plugin) 27569 .addTo(controller); 27570 27571 aboutOutlineGrahicPin = new ScrollMagic.Scene().triggerElement(aboutOutlineGrahic).offset(-370).duration(durationCount(aboutOutline, aboutOutlineGrahic, 320)).setPin(aboutOutlineGrahic, { pushFollowers: false }) 27572 // .addIndicators() // add indicators (requires plugin) 27573 .addTo(controller); 27574 27575 aboutOutlineGrahicAni = new ScrollMagic.Scene().triggerElement(aboutOutlineGrahic).offset(-370).duration(200).setTween(aboutOutlineGrahicTween) 27576 // .addIndicators() // add indicators (requires plugin) 27577 .addTo(controller); 27578 27579 aboutOutlineContentPin = new ScrollMagic.Scene().triggerElement(aboutOutlineContent).offset(-370).duration(durationCount(aboutOutline, aboutOutlineContent, 320)).setPin(aboutOutlineContent, { pushFollowers: false }) 27580 // .addIndicators() // add indicators (requires plugin) 27581 .addTo(controller); 27582 } 27583 27584 function aboutShinhoLogoScrollMagic() { 27585 const aboutShinhoLogoGrahicTween = TweenMax.to(aboutShinhoLogoGrahic, 0.3, { x: -312, ease: Linear.easeNone }); 27586 const aboutShinhoLogoTitleTween = TweenMax.to(aboutShinhoLogoTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone }); 27587 27588 aboutShinhoLogoTitlePin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoTitle).offset(-110).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoTitle, 60)).setPin(aboutShinhoLogoTitle, { pushFollowers: false }) 27589 // .addIndicators() // add indicators (requires plugin) 27590 .addTo(controller); 27591 27592 aboutShinhoLogoTitleAni = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoTitle).offset(-120).duration(150).setTween(aboutShinhoLogoTitleTween) 27593 // .addIndicators() // add indicators (requires plugin) 27594 .addTo(controller); 27595 27596 aboutShinhoLogoGrahicPin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoGrahic).offset(-240).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoGrahic, 180)).setPin(aboutShinhoLogoGrahic, { pushFollowers: false }) 27597 // .addIndicators() // add indicators (requires plugin) 27598 .addTo(controller); 27599 27600 aboutShinhoLogoGrahicAni = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoGrahic).offset(-240).duration(200).setTween(aboutShinhoLogoGrahicTween) 27601 // .addIndicators() // add indicators (requires plugin) 27602 .addTo(controller); 27603 27604 aboutShinhoLogoBoxPin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoBox).offset(-240).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoBox, 180)).setPin(aboutShinhoLogoBox, { pushFollowers: false }) 27605 // .addIndicators() // add indicators (requires plugin) 27606 .addTo(controller); 27607 } 27608 27609 function aboutSloganScrollMagic() { 27610 aboutSloganTitlePin = new ScrollMagic.Scene().triggerElement(aboutSloganTitle).offset(-120).duration(durationCount(aboutSlogan, aboutSloganTitle, 60)).setPin(aboutSloganTitle, { pushFollowers: false }) 27611 // .addIndicators() // add indicators (requires plugin) 27612 .addTo(controller); 27613 27614 aboutSloganContentPin = new ScrollMagic.Scene().triggerElement(aboutSloganContent).offset(-380).duration(durationCount(aboutSlogan, aboutSloganContent, 320)).setPin(aboutSloganContent, { pushFollowers: false }) 27615 // .addIndicators() // add indicators (requires plugin) 27616 .addTo(controller); 27617 } 27618 27619 function aboutPhilosophyScrollMagic() { 27620 const aboutPhilosophyTitleTween = TweenMax.to(aboutPhilosophyTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone }); 27621 const aboutPhilosophyItemArti2Tween = TweenMax.to(aboutPhilosophyItemArti2, 0.3, { y: -175, ease: Linear.easeNone }); 27622 const aboutPhilosophyItemArti3Tween = TweenMax.to(aboutPhilosophyItemArti3, 0.3, { y: -175, ease: Linear.easeNone }); 27623 const aboutPhilosophyItemArti4Tween = TweenMax.to(aboutPhilosophyItemArti4, 0.3, { y: -175, ease: Linear.easeNone }); 27624 const aboutPhilosophyMoreBtnTween = TweenMax.to(aboutPhilosophyMoreBtn, 0.3, { y: -100, ease: Linear.easeNone }); 27625 27626 aboutPhilosophyTitlePin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyTitle).offset(-120).duration(durationCount(aboutPhilosophy, aboutPhilosophyTitle, -217)).setPin(aboutPhilosophyTitle, { pushFollowers: false }) 27627 // .addIndicators() // add indicators (requires plugin) 27628 .addTo(controller); 27629 27630 aboutPhilosophyTitleAni = new ScrollMagic.Scene().triggerElement(aboutPhilosophyTitle).offset(-120).duration(150).setTween(aboutPhilosophyTitleTween) 27631 // .addIndicators() // add indicators (requires plugin) 27632 .addTo(controller); 27633 27634 aboutPhilosophySubtitle1Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle1, -77)).setPin(aboutPhilosophySubtitle1, { pushFollowers: false }) 27635 // .addIndicators() // add indicators (requires plugin) 27636 .addTo(controller); 27637 27638 aboutPhilosophySubtitle2Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle2, -7)).setPin(aboutPhilosophySubtitle2, { pushFollowers: false }) 27639 // .addIndicators() // add indicators (requires plugin) 27640 .addTo(controller); 27641 27642 aboutPhilosophySubtitle3Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle3, 63)).setPin(aboutPhilosophySubtitle3, { pushFollowers: false }) 27643 // .addIndicators() // add indicators (requires plugin) 27644 .addTo(controller); 27645 27646 aboutPhilosophySubtitle4Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle4, 133)).setPin(aboutPhilosophySubtitle4, { pushFollowers: false }) 27647 // .addIndicators() // add indicators (requires plugin) 27648 .addTo(controller); 27649 27650 aboutPhilosophyBoxMask = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).setClassToggle(aboutPhilosophyBox, 'status-mask').offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophyBox, -40)) 27651 // .addIndicators() // add indicators (requires plugin) 27652 .addTo(controller); 27653 27654 aboutPhilosophyItemArti2Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem2).offset(-864).duration(230).setTween(aboutPhilosophyItemArti2Tween) 27655 // .addIndicators() // add indicators (requires plugin) 27656 .addTo(controller); 27657 27658 aboutPhilosophyItemArti3Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem3).offset(-864).duration(230).setTween(aboutPhilosophyItemArti3Tween) 27659 // .addIndicators() // add indicators (requires plugin) 27660 .addTo(controller); 27661 27662 aboutPhilosophyItemArti4Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem4).offset(-864).duration(230).setTween(aboutPhilosophyItemArti4Tween) 27663 // .addIndicators() // add indicators (requires plugin) 27664 .addTo(controller); 27665 27666 aboutPhilosophyMoreBtnAni = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti3).duration(200).setTween(aboutPhilosophyMoreBtnTween) 27667 // .addIndicators() // add indicators (requires plugin) 27668 .addTo(controller); 27669 27670 aboutPhilosophySubtitle1Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti1).offset(-360).duration($('.about-philosophy-item:first-child').height() + 175).setClassToggle(aboutPhilosophyItem1, 'status-selected') 27671 // .addIndicators() // add indicators (requires plugin) 27672 .addTo(controller); 27673 27674 aboutPhilosophySubtitle2Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti2).offset(-360).duration($('.about-philosophy-item:nth-child(2)').height() + 175).setClassToggle(aboutPhilosophyItem2, 'status-selected') 27675 // .addIndicators() // add indicators (requires plugin) 27676 .addTo(controller); 27677 27678 aboutPhilosophySubtitle3Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti3).offset(-360).duration($('.about-philosophy-item:nth-child(3)').height() + 175).setClassToggle(aboutPhilosophyItem3, 'status-selected') 27679 // .addIndicators() // add indicators (requires plugin) 27680 .addTo(controller); 27681 27682 aboutPhilosophySubtitle4Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti4).offset(-360).duration($('.about-philosophy-item:nth-child(4)').height() + 175).setClassToggle(aboutPhilosophyItem4, 'status-selected') 27683 // .addIndicators() // add indicators (requires plugin) 27684 .addTo(controller); 27685 } 27686 27687 function aboutFoodecoSrollMagic() { 27688 const aboutFoodecoTitleTween = TweenMax.to(aboutFoodecoTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone }); 27689 const aboutFoodecoIntrosTimeline = new TimelineMax(); 27690 // add a tween 27691 aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 0, { opacity: 0 })); 27692 aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 2, { opacity: 1 })); 27693 aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 2, { opacity: 1 })); 27694 aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 0.8, { opacity: 0 })); 27695 27696 const aboutFoodecoGrahicsItemsTween = TweenMax.to(aboutFoodecoGrahicsItems, 0.3, { css: { 'padding-bottom': '16%' }, ease: Power1.easeInOut }); 27697 const aboutFoodecoGrahicsTween = TweenMax.to(aboutFoodecoGrahicsBox, 0.3, { x: -250, ease: Power1.easeInOut }); 27698 const aboutFoodecoMoreBtnTween = TweenMax.from(aboutFoodecoMoreBtn, 0.3, { y: 100, ease: Linear.easeNone }); 27699 27700 aboutFoodecoTitlePin = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).offset(-120).duration(durationCount(aboutFoodeco, aboutFoodecoTitle, -160)).setPin(aboutFoodecoTitle, { pushFollowers: false }) 27701 // .addIndicators() // add indicators (requires plugin) 27702 .addTo(controller); 27703 27704 aboutFoodecoTitleAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).offset(-120).duration(150).setTween(aboutFoodecoTitleTween) 27705 // .addIndicators() // add indicators (requires plugin) 27706 .addTo(controller); 27707 27708 aboutFoodecoMainMask = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).setClassToggle(aboutFoodecoMain, 'status-mask').offset(-120).duration(durationCount(aboutFoodeco, aboutFoodecoTitle, -100)) 27709 // .addIndicators() // add indicators (requires plugin) 27710 .addTo(controller); 27711 27712 aboutFoodecoGrahicsPin = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(-180).duration(durationCount(aboutFoodeco, aboutFoodecoGrahics, -100)).setPin(aboutFoodecoGrahics, { pushFollowers: false }) 27713 // .addIndicators() // add indicators (requires plugin) 27714 .addTo(controller); 27715 27716 aboutFoodecoIntrosAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(-180).duration(300).setTween(aboutFoodecoIntrosTimeline) 27717 // .addIndicators() // add indicators (requires plugin) 27718 .addTo(controller); 27719 27720 aboutFoodecoGrahicsItemsAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(120).duration(200).setTween(aboutFoodecoGrahicsItemsTween) 27721 // .addIndicators() // add indicators (requires plugin) 27722 .addTo(controller); 27723 27724 aboutFoodecoGrahicsAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(320).duration(200).setTween(aboutFoodecoGrahicsTween) 27725 // .addIndicators() // add indicators (requires plugin) 27726 .addTo(controller); 27727 27728 aboutFoodecoGrahics
27728ItemsSelectClear = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(520) 27729 // .addIndicators() // add indicators (requires plugin) 27730 .on('enter leave', foodecoGrahicsItemsSelectClear).addTo(controller); 27731 27732 aboutFoodecoGrahicsItem1Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem1).setClassToggle(aboutFoodecoGrahicsItem1, 'status-selected').duration(351).offset(-291) 27733 // .addIndicators() // add indicators (requires plugin) 27734 .addTo(controller); 27735 27736 aboutFoodecoGrahicsItem2Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem2).setClassToggle(aboutFoodecoGrahicsItem2, 'status-selected').duration(351).offset(-291) 27737 // .addIndicators() // add indicators (requires plugin) 27738 .addTo(controller); 27739 27740 aboutFoodecoGrahicsItem3Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem3).setClassToggle(aboutFoodecoGrahicsItem3, 'status-selected').duration(351).offset(-291) 27741 // .addIndicators() // add indicators (requires plugin) 27742 .addTo(controller); 27743 27744 aboutFoodecoGrahicsItem4Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem4).setClassToggle(aboutFoodecoGrahicsItem4, 'status-selected').duration(351).offset(-291) 27745 // .addIndicators() // add indicators (requires plugin) 27746 .addTo(controller); 27747 27748 aboutFoodecoGrahicsItem5Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem5).setClassToggle(aboutFoodecoGrahicsItem5, 'status-selected').duration(351).offset(-291) 27749 // .addIndicators() // add indicators (requires plugin) 27750 .addTo(controller); 27751 27752 aboutFoodecoGrahicsItem6Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem6).setClassToggle(aboutFoodecoGrahicsItem6, 'status-selected').duration(351).offset(-291) 27753 // .addIndicators() // add indicators (requires plugin) 27754 .addTo(controller); 27755 27756 aboutFoodecoGrahicsItem7Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem7).setClassToggle(aboutFoodecoGrahicsItem7, 'status-selected').duration(351).offset(-291) 27757 // .addIndicators() // add indicators (requires plugin) 27758 .addTo(controller); 27759 27760 aboutFoodecoMoreBtnAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem6).offset(-70).duration(200).setTween(aboutFoodecoMoreBtnTween) 27761 // .addIndicators() // add indicators (requires plugin) 27762 .addTo(controller); 27763 } 27764 27765 function aboutWorldwideBranchScrollMagic() { 27766 const aboutWorldwideBranchGrahicTween = TweenMax.to(aboutWorldwideBranchGrahicImg, 0.5, { css: { width: '470px' }, ease: Linear.easeNone }); 27767 const aboutWorldwideBranchTitleTween = TweenMax.to(aboutWorldwideBranchTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone }); 27768 aboutWorldwideBranchTitlePin = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchTitle).offset(-120).duration(durationCount(aboutWorldwideBranch, aboutWorldwideBranchTitle, 50)).setPin(aboutWorldwideBranchTitle, { pushFollowers: false }) 27769 // .addIndicators() // add indicators (requires plugin) 27770 .addTo(controller); 27771 27772 aboutWorldwideBranchTitleAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchTitle).offset(-120).duration(150).setTween(aboutWorldwideBranchTitleTween) 27773 // .addIndicators() // add indicators (requires plugin) 27774 .addTo(controller); 27775 27776 aboutWorldwideBranchGrahicPin = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchGrahic).offset(-240).duration(durationCount(aboutWorldwideBranch, aboutWorldwideBranchGrahic, 170)).setPin(aboutWorldwideBranchGrahic, { pushFollowers: false }) 27777 // .addIndicators() // add indicators (requires plugin) 27778 .addTo(controller); 27779 27780 aboutWorldwideBranchGrahicAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchGrahic).offset(-240).duration(200).setTween(aboutWorldwideBranchGrahicTween) 27781 // .addIndicators() // add indicators (requires plugin) 27782 .addTo(controller); 27783 27784 aboutWorldwideBranchBoxMask = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchBox).setClassToggle(aboutWorldwideBranchBox, 'status-mask').offset(-260).duration(1500) 27785 // .addIndicators() // add indicators (requires plugin) 27786 .addTo(controller); 27787 27788 scrollMovingAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchBox).setClassToggle('.about-scrollmov
27788ing-sticker', 'status-hide').offset(-250) 27789 // .addIndicators() // add indicators (requires plugin) 27790 .addTo(controller); 27791 } 27792 27793 // å䏿»¾åç®é 27794 const scrollMovingSticker = function (event) { 27795 if (event.type === 'scrollstop') { 27796 scrollMovingEle.stop(true, true); 27797 if (scrollStatus === 'hide') { 27798 scrollMovingEle.animate({ 27799 opacity: '1' 27800 }, 300, () => { 27801 scrollStatus = 'show'; 27802 }); 27803 } 27804 } else if (event.type === 'scrollstart') { 27805 scrollMovingEle.stop(true, true); 27806 if (scrollStatus === 'show') { 27807 scrollMovingEle.animate({ 27808 opacity: '0' 27809 }, 300, () => { 27810 scrollStatus = 'hide'; 27811 }); 27812 } 27813 } 27814 }; 27815 27816 const bodyEle = window.opera ? document.compatMode === 'CSS1Compat' ? $('html') : $('body') : $('html,body'); 27817 const anchorEle = '.about-anchor'; 27818 27819 const anchorOffset = 10; 27820 const anchorLength = $('.about-anchor-item').length; 27821 27822 function anchorScrollTo() { 27823 $(document).on('click', 'a[href^="#anch-marker-"]', function (event) { 27824 const id = $(this).attr('href'); 27825 27826 if ($(id).length > 0) { 27827 event.preventDefault(); 27828 bodyEle.animate({ 27829 scrollTop: $(id).offset().top - anchorOffset 27830 }, 1000); 27831 27832 return false; 27833 } 27834 return true; 27835 }); 27836 } 27837 27838 function anchorNavSelected(offsetNum) { 27839 const anchorDurations = {}; 27840 27841 for (let i = 1; i <= anchorLength; i += 1) { 27842 if (i === anchorLength) { 27843 anchorDurations[i - 1] = $(`#anch-marker-${i}`).offset().top + offsetNum; 27844 } else { 27845 anchorDurations[i - 1] = $(`#anch-marker-${i + 1}`).offset().top - $(`#anch-marker-${i}`).offset().top; 27846 } 27847 27848 window[`anchorSelected${i}`] = new ScrollMagic.Scene().triggerElement(`#anch-marker-${i}`).offset(-200).duration(anchorDurations[i - 1]).setClassToggle(`.about-anchor-item:nth-child(${i})`, 'status-selected') // add class toggle 27849 // .addIndicators() // add indicators (requires plugin) 27850 .addTo(controller); 27851 } 27852 } 27853 27854 const init = () => { 27855 // anchorController = new ScrollMagic.Controller({ 27856 // globalSceneOptions :{ 27857 // triggerHook: 0 27858 // } 27859 // });; 27860 27861 anchorScrollTo(); 27862 27863 if (GLOBAL_BROWSER_STAT.ie8Browser === false) { 27864 controller = new ScrollMagic.Controller({ 27865 globalSceneOptions: { 27866 triggerHook: 0 27867 } 27868 }); 27869 27870 if (__WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].viewport(Object(__WEBPACK_IMPORTED_MODULE_9__maxin__["a" /* default */])()) === 'max') { 27871 if (showStyle !== 'desktop') { 27872 showStyle = 'desktop'; 27873 27874 if (!$('.about').hasClass('status-animate')) { 27875 $('.about').addClass('status-animate'); 27876 } 27877 27878 anchorNavSelected(1000); 27879 27880 aboutOutlineScrollMagic(); 27881 aboutShinhoLogoScrollMagic(); 27882 aboutSloganScrollMagic(); 27883 aboutPhilosophyScrollMagic(); 27884 aboutFoodecoSrollMagic(); 27885 aboutWorldwideBranchScrollMagic(); 27886 27887 anchorPin = new ScrollMagic.Scene().triggerElement('#about-anchor').offset(-120).setPin('#about-anchor', { pushFollowers: false }).duration($('.about').height() - 500) 27888 // .addIndicators() // add indicators (requires plugin) 27889 .addTo(controller); 27890 27891 $(window).on('scrollstop scrollstart', event => { 27892 clearTimeout(scrollMovingTimer); 27893 if (event.type === 'scrollstop') { 27894 scrollMovingTimer = setTimeout(scrollMovingSticker(event), 2000); 27895 } else { 27896 scrollMovingTimer = setTimeout(scrollMovingSticker(event), 0); 27897 } 27898 }); 27899 } 27900 } else { 27901 if (showStyle !== 'mobile') { 27902 showStyle = 'mobile'; 27903 } 27904 27905 if ($('.about').hasClass('status-animate')) { 27906 $('.about').removeClass('status-animate'); 27907 } 27908 } 27909 } 27910 }; 27911 27912 $(window).on('scroll', () => { 27913 if (controller) { 27914 controller.update(true); 27915 } 27916 }); 27917 27918 $(window).resize(() => { 27919 if (GLOBAL_BROWSER_STAT.ie8Browser === false) { 27920 if (__WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].viewport(Object(__WEBPACK_IMPORTED_MODULE_9__maxin__["a" /* default */])()) === 'max') { 27921 if (showStyle !== 'desktop') { 27922 if (controller != null) { 27923 controller.destroy(true); 27924 controller = null; 27925 } else { 27926 // .. 27927 } 27928 init(); 27929 } 27930 } else { 27931 showStyle = 'mobile'; 27932 if (controller != null) { 27933 controller.destroy(true); 27934 controller = null; 27935 } 27936 } 27937 } 27938 }); 27939 const setting = () => { 27940 // 賦äºç覽å¨å¤å¥å¼ 27941 GLOBAL_BROWSER_STAT.modernBrowser = __WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].modernBrowser(); 27942 GLOBAL_BROWSER_STAT.ie8Browser = __WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].ie8Browser(); 27943 setTimeout(() => { 27944 init(); 27945 }, 1000); 27946 27947 // æµ®å¨éå 27948 27949 // let $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body'); 27950 // for (let i = 1; i <= sectionNum; i++) { 27951 // let offset = 110; 27952 27953 // $("#anchor" + i).on("click", function(e) { 27954 // $body.animate({ 27955 // scrollTop: $("#sec" + i).offset().top - offset 27956 // }, 1000); 27957 // return false;
27958 // }) 27959 // } 27960 }; 27961 27962 $(window).load(() => { 27963 setting(); 27964 }); 27965}); 27966/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0), __webpack_require__(2))) 27967 27968/***/ }) 27969/******/ ]); 27970//# sourceMappingURL=../../src/map/lyt-cn-about.js.map
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.