1/*! 2* PreloadJS 3* Visit http://createjs.com/ for documentation, updates and examples. 4* 5* Copyright (c) 2010 gskinner.com, inc. 6* 7* Permission is hereby granted, free of charge, to any person 8* obtaining a copy of this software and associated documentation 9* files (the "Software"), to deal in the Software without 10* restriction, including without limitation the rights to use, 11* copy, modify, merge, publish, distribute, sublicense, and/or sell 12* copies of the Software, and to permit persons to whom the 13* Software is furnished to do so, subject to the following 14* conditions: 15* 16* The above copyright notice and this permission notice shall be 17* included in all copies or substantial portions of the Software. 18* 19* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26* OTHER DEALINGS IN THE SOFTWARE. 27*/ 28 29 30//############################################################################## 31// version.js 32//############################################################################## 33 34this.createjs = this.createjs || {}; 35 36(function () { 37 "use strict"; 38 39 /** 40 * Static class holding library specific information such as the version and buildDate of the library. 41 * @class PreloadJS 42 **/ 43 var s = createjs.PreloadJS = createjs.PreloadJS || {}; 44 45 /** 46 * The version string for this release. 47 * @property version 48 * @type {String} 49 * @static 50 **/ 51 s.version = /*=version*/"NEXT"; // injected by build process 52 53 /** 54 * The build date for this release in UTC format. 55 * @property buildDate 56 * @type {String} 57 * @static 58 **/ 59 s.buildDate = /*=date*/"Fri, 04 Dec 2015 17:26:39 GMT"; // injected by build process 60 61})(); 62 63//############################################################################## 64// extend.js 65//############################################################################## 66 67this.createjs = this.createjs||{}; 68 69/** 70 * @class Utility Methods 71 */ 72 73/** 74 * Sets up the prototype chain and constructor property for a new class. 75 * 76 * This should be called right after creating the class constructor. 77 * 78 * function MySubClass() {} 79 * createjs.extend(MySubClass, MySuperClass); 80 * MySubClass.prototype.doSomething = function() { } 81 * 82 * var foo = new MySubClass(); 83 * console.log(foo instanceof MySuperClass); // true 84 * console.log(foo.prototype.constructor === MySubClass); // true 85 * 86 * @method extend 87 * @param {Function} subclass The subclass. 88 * @param {Function} superclass The superclass to extend. 89 * @return {Function} Returns the subclass's new prototype. 90 */ 91createjs.extend = function(subclass, superclass) { 92 "use strict"; 93 94 function o() { this.constructor = subclass; } 95 o.prototype = superclass.prototype; 96 return (subclass.prototype = new o()); 97}; 98 99//############################################################################## 100// promote.js 101//############################################################################## 102 103this.createjs = this.createjs||{}; 104 105/** 106 * @class Utility Methods 107 */ 108 109/** 110 * Promotes any methods on the super class that were overridden, by creating an alias in the format `prefix_methodName`. 111 * It is recommended to use the super class's name as the prefix. 112 * An alias to the super class's constructor is always added in the format `prefix_constructor`. 113 * This allows the subclass to call super class methods without using `function.call`, providing better performance. 114 * 115 * For example, if `MySubClass` extends `MySuperClass`, and both define a `draw` method, then calling `promote(MySubClass, "MySuperClass")` 116 * would add a `MySuperClass_constructor` method to MySubClass and promote the `draw` method on `MySuperClass` to the 117 * prototype of `MySubClass` as `MySuperClass_draw`. 118 * 119 * This should be called after the class's prototype is fully defined. 120 * 121 * function ClassA(name) { 122 * this.name = name; 123 * } 124 * ClassA.prototype.greet = function() { 125 * return "Hello "+this.name; 126 * } 127 * 128 * function ClassB(name, punctuation) { 129 * this.ClassA_constructor(name); 130 * this.punctuation = punctuation; 131 * } 132 * createjs.extend(ClassB, ClassA); 133 * ClassB.prototype.greet = function() { 134 * return this.ClassA_greet()+this.punctuation; 135 * } 136 * createjs.promote(ClassB, "ClassA"); 137 * 138 * var foo = new ClassB("World", "!?!"); 139 * console.log(foo.greet()); // Hello World!?! 140 * 141 * @method promote 142 * @param {Function} subclass The class to promote super class methods on. 143 * @param {String}
143 prefix The prefix to add to the promoted method names. Usually the name of the superclass. 144 * @return {Function} Returns the subclass. 145 */ 146createjs.promote = function(subclass, prefix) { 147 "use strict"; 148 149 var subP = subclass.prototype, supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__; 150 if (supP) { 151 subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable 152 for (var n in supP) { 153 if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; } 154 } 155 } 156 return subclass; 157}; 158 159//############################################################################## 160// proxy.js 161//############################################################################## 162 163this.createjs = this.createjs||{}; 164 165/** 166 * Various utilities that the CreateJS Suite uses. Utilities are created as separate files, and will be available on the 167 * createjs namespace directly. 168 * 169 * <h4>Example</h4> 170 * 171 * myObject.addEventListener("change", createjs.proxy(myMethod, scope)); 172 * 173 * @class Utility Methods 174 * @main Utility Methods 175 */ 176 177(function() { 178 "use strict"; 179 180 /** 181 * A function proxy for methods. By default, JavaScript methods do not maintain scope, so passing a method as a 182 * callback will result in the method getting called in the scope of the caller. Using a proxy ensures that the 183 * method gets called in the correct scope. 184 * 185 * Additional arguments can be passed that will be applied to the function when it is called. 186 * 187 * <h4>Example</h4> 188 * 189 * myObject.addEventListener("event", createjs.proxy(myHandler, this, arg1, arg2)); 190 * 191 * function myHandler(arg1, arg2) { 192 * // This gets called when myObject.myCallback is executed. 193 * } 194 * 195 * @method proxy 196 * @param {Function} method The function to call 197 * @param {Object} scope The scope to call the method name on 198 * @param {mixed} [arg] * Arguments that are appended to the callback for additional params. 199 * @public 200 * @static 201 */ 202 createjs.proxy = function (method, scope) { 203 var aArgs = Array.prototype.slice.call(arguments, 2); 204 return function () { 205 return method.apply(scope, Array.prototype.slice.call(arguments, 0).concat(aArgs)); 206 }; 207 } 208 209}()); 210 211//############################################################################## 212// indexOf.js 213//############################################################################## 214 215this.createjs = this.createjs||{}; 216 217/** 218 * @class Utility Methods 219 */ 220 221/** 222 * Finds the first occurrence of a specified value searchElement in the passed in array, and returns the index of 223 * that value. Returns -1 if value is not found. 224 * 225 * var i = createjs.indexOf(myArray, myElementToFind); 226 * 227 * @method indexOf 228 * @param {Array} array Array to search for searchElement 229 * @param searchElement Element to find in array. 230 * @return {Number} The first index of searchElement in array. 231 */ 232createjs.indexOf = function (array, searchElement){ 233 "use strict"; 234 235 for (var i = 0,l=array.length; i < l; i++) { 236 if (searchElement === array[i]) { 237 return i; 238 } 239 } 240 return -1; 241}; 242 243//############################################################################## 244// Event.js 245//############################################################################## 246 247this.createjs = this.createjs||{}; 248 249(function() { 250 "use strict"; 251 252// constructor: 253 /** 254 * Contains properties and methods shared by all events for use with 255 * {{#crossLink "EventDispatcher"}}{{/crossLink}}. 256 * 257 * Note that Event objects are often reused, so you should never 258 * rely on an event object's state outside of the call stack it was received in. 259 * @class Event 260 * @param {String} type The event type. 261 * @param {Boolean} bubbles Indicates whether the event will bubble through the display list. 262 * @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled. 263 * @constructor 264 **/ 265 function Event(type, bubbles, cancelable) { 266 267 268 // public properties: 269 /** 270 * The type of event. 271 * @property type
272 * @type String 273 **/ 274 this.type = type; 275 276 /** 277 * The object that generated an event. 278 * @property target 279 * @type Object 280 * @default null 281 * @readonly 282 */ 283 this.target = null; 284 285 /** 286 * The current target that a bubbling event is being dispatched from. For non-bubbling events, this will 287 * always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event 288 * is generated from childObj, then a listener on parentObj would receive the event with 289 * target=childObj (the original target) and currentTarget=parentObj (where the listener was added). 290 * @property currentTarget 291 * @type Object 292 * @default null 293 * @readonly 294 */ 295 this.currentTarget = null; 296 297 /** 298 * For bubbling events, this indicates the current event phase:<OL> 299 * <LI> capture phase: starting from the top parent to the target</LI> 300 * <LI> at target phase: currently being dispatched from the target</LI> 301 * <LI> bubbling phase: from the target to the top parent</LI> 302 * </OL> 303 * @property eventPhase 304 * @type Number 305 * @default 0 306 * @readonly 307 */ 308 this.eventPhase = 0; 309 310 /** 311 * Indicates whether the event will bubble through the display list. 312 * @property bubbles 313 * @type Boolean 314 * @default false 315 * @readonly 316 */ 317 this.bubbles = !!bubbles; 318 319 /** 320 * Indicates whether the default behaviour of this event can be cancelled via 321 * {{#crossLink "Event/preventDefault"}}{{/crossLink}}. This is set via the Event constructor. 322 * @property cancelable 323 * @type Boolean 324 * @default false 325 * @readonly 326 */ 327 this.cancelable = !!cancelable; 328 329 /** 330 * The epoch time at which this event was created. 331 * @property timeStamp 332 * @type Number 333 * @default 0 334 * @readonly 335 */ 336 this.timeStamp = (new Date()).getTime(); 337 338 /** 339 * Indicates if {{#crossLink "Event/preventDefault"}}{{/crossLink}} has been called 340 * on this event. 341 * @property defaultPrevented 342 * @type Boolean 343 * @default false 344 * @readonly 345 */ 346 this.defaultPrevented = false; 347 348 /** 349 * Indicates if {{#crossLink "Event/stopPropagation"}}{{/crossLink}} or 350 * {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called on this event. 351 * @property propagationStopped 352 * @type Boolean 353 * @default false 354 * @readonly 355 */ 356 this.propagationStopped = false; 357 358 /** 359 * Indicates if {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called 360 * on this event. 361 * @property immediatePropagationStopped 362 * @type Boolean 363 * @default false 364 * @readonly 365 */ 366 this.immediatePropagationStopped = false; 367 368 /** 369 * Indicates if {{#crossLink "Event/remove"}}{{/crossLink}} has been called on this event. 370 * @property removed 371 * @type Boolean 372 * @default false 373 * @readonly 374 */ 375 this.removed = false; 376 } 377 var p = Event.prototype; 378 379 /** 380 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 381 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 382 * for details. 383 * 384 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 385 * 386 * @method initialize 387 * @protected 388 * @deprecated 389 */ 390 // p.initialize = function() {}; // searchable for devs wondering where it is. 391 392// public methods: 393 /** 394 * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true if the event is cancelable. 395 * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will 396 * cancel the default behaviour associated with the event. 397 * @method preventDefault 398 **/ 399 p.preventDefault = function() { 400 this.defaultPrevented = this.cancelable&&true; 401 }; 402 403 /** 404 * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} to true. 405 * Mirrors the DOM event standard. 406 * @method stopPropagation 407 **/ 408 p.stopPropagation = function() { 409 this.propagationStopped = true; 410 }; 411 412 /** 413 * Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} and 414 * {{#crossLink "Event/immediatePropagationStopped"}}{{/crossLink}} to true. 415 * Mirrors the DOM event standard. 416 * @method stopImmediatePropagation 417 **/ 418 p.stopImmediatePropagation = function() {
419 this.immediatePropagationStopped = this.propagationStopped = true; 420 }; 421 422 /** 423 * Causes the active listener to be removed via removeEventListener(); 424 * 425 * myBtn.addEventListener("click", function(evt) { 426 * // do stuff... 427 * evt.remove(); // removes this listener. 428 * }); 429 * 430 * @method remove 431 **/ 432 p.remove = function() { 433 this.removed = true; 434 }; 435 436 /** 437 * Returns a clone of the Event instance. 438 * @method clone 439 * @return {Event} a clone of the Event instance. 440 **/ 441 p.clone = function() { 442 return new Event(this.type, this.bubbles, this.cancelable); 443 }; 444 445 /** 446 * Provides a chainable shortcut method for setting a number of properties on the instance. 447 * 448 * @method set 449 * @param {Object} props A generic object containing properties to copy to the instance. 450 * @return {Event} Returns the instance the method is called on (useful for chaining calls.) 451 * @chainable 452 */ 453 p.set = function(props) { 454 for (var n in props) { this[n] = props[n]; } 455 return this; 456 }; 457 458 /** 459 * Returns a string representation of this object. 460 * @method toString 461 * @return {String} a string representation of the instance. 462 **/ 463 p.toString = function() { 464 return "[Event (type="+this.type+")]"; 465 }; 466 467 createjs.Event = Event; 468}()); 469 470//############################################################################## 471// ErrorEvent.js 472//############################################################################## 473 474this.createjs = this.createjs||{}; 475 476(function() { 477 "use strict"; 478 479 /** 480 * A general error {{#crossLink "Event"}}{{/crossLink}}, that describes an error that occurred, as well as any details. 481 * @class ErrorEvent 482 * @param {String} [title] The error title 483 * @param {String} [message] The error description 484 * @param {Object} [data] Additional error data 485 * @constructor 486 */ 487 function ErrorEvent(title, message, data) { 488 this.Event_constructor("error"); 489 490 /** 491 * The short error title, which indicates the type of error that occurred. 492 * @property title
493 * @type String 494 */ 495 this.title = title; 496 497 /** 498 * The verbose error message, containing details about the error. 499 * @property message 500 * @type String 501 */ 502 this.message = message; 503 504 /** 505 * Additional data attached to an error. 506 * @property data 507 * @type {Object} 508 */ 509 this.data = data; 510 } 511 512 var p = createjs.extend(ErrorEvent, createjs.Event); 513 514 p.clone = function() { 515 return new createjs.ErrorEvent(this.title, this.message, this.data); 516 }; 517 518 createjs.ErrorEvent = createjs.promote(ErrorEvent, "Event"); 519 520}()); 521 522//############################################################################## 523// EventDispatcher.js 524//############################################################################## 525 526this.createjs = this.createjs||{}; 527 528(function() { 529 "use strict"; 530 531 532// constructor: 533 /** 534 * EventDispatcher provides methods for managing queues of event listeners and dispatching events. 535 * 536 * You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the 537 * EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method. 538 * 539 * Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the 540 * DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports 541 * bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent. 542 * 543 * EventDispatcher also exposes a {{#crossLink "EventDispatcher/on"}}{{/crossLink}} method, which makes it easier 544 * to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The 545 * {{#crossLink "EventDispatcher/off"}}{{/crossLink}} method is merely an alias to 546 * {{#crossLink "EventDispatcher/removeEventListener"}}{{/crossLink}}. 547 * 548 * Another addition to the DOM Level 2 model is the {{#crossLink "EventDispatcher/removeAllEventListeners"}}{{/crossLink}} 549 * method, which can be used to listeners for all events, or listeners for a specific event. The Event object also 550 * includes a {{#crossLink "Event/remove"}}{{/crossLink}} method which removes the active listener. 551 * 552 * <h4>Example</h4> 553 * Add EventDispatcher capabilities to the "MyClass" class. 554 * 555 * EventDispatcher.initialize(MyClass.prototype); 556 * 557 * Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}). 558 * 559 * instance.addEventListener("eventName", handlerMethod); 560 * function handlerMethod(event) { 561 * console.log(event.target + " Was Clicked"); 562 * } 563 * 564 * <b>Maintaining proper scope</b><br /> 565 * Scope (ie. "this") can be be a challenge with events. Using the {{#crossLink "EventDispatcher/on"}}{{/crossLink}} 566 * method to subscribe to events simplifies this. 567 * 568 * instance.addEventListener("click", function(event) { 569 * console.log(instance == this); // false, scope is ambiguous. 570 * }); 571 * 572 * instance.on("click", function(event) { 573 * console.log(instance == this); // true, "on" uses dispatcher scope by default. 574 * }); 575 * 576 * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage 577 * scope. 578 * 579 * <b>Browser support</b> 580 * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model 581 * requires modern browsers (IE9+). 582 * 583 * 584 * @class EventDispatcher 585 * @constructor 586 **/ 587 function EventDispatcher() { 588 589 590 // private properties: 591 /** 592 * @protected 593 * @property _listeners 594 * @type Object 595 **/ 596 this._listeners = null; 597 598 /** 599 * @protected 600 * @property _captureListeners 601 * @type Object 602 **/ 603 this._captureListeners = null; 604 } 605 var p = EventDispatcher.prototype; 606 607 /** 608 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 609 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 610 * for details. 611 * 612 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 613 * 614 * @method initialize 615 * @protected 616 * @deprecated 617 */ 618 // p.initialize = function() {}; // searchable for devs wondering where it is. 619 620 621// static public methods: 622 /** 623 * Static initializer to mix EventDispatcher methods into a target object or prototype. 624 * 625 * EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class 626 * EventDispatcher.initialize(myObject);
626 // add to a specific instance 627 * 628 * @method initialize 629 * @static 630 * @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a 631 * prototype. 632 **/ 633 EventDispatcher.initialize = function(target) { 634 target.addEventListener = p.addEventListener; 635 target.on = p.on; 636 target.removeEventListener = target.off = p.removeEventListener; 637 target.removeAllEventListeners = p.removeAllEventListeners; 638 target.hasEventListener = p.hasEventListener; 639 target.dispatchEvent = p.dispatchEvent; 640 target._dispatchEvent = p._dispatchEvent; 641 target.willTrigger = p.willTrigger; 642 }; 643 644 645// public methods: 646 /** 647 * Adds the specified event listener. Note that adding multiple listeners to the same function will result in 648 * multiple callbacks getting fired. 649 * 650 * <h4>Example</h4> 651 * 652 * displayObject.addEventListener("click", handleClick); 653 * function handleClick(event) { 654 * // Click happened. 655 * } 656 * 657 * @method addEventListener 658 * @param {String} type The string type of the event. 659 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when 660 * the event is dispatched. 661 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 662 * @return {Function | Object} Returns the listener for chaining or assignment. 663 **/ 664 p.addEventListener = function(type, listener, useCapture) { 665 var listeners; 666 if (useCapture) { 667 listeners = this._captureListeners = this._captureListeners||{}; 668 } else { 669 listeners = this._listeners = this._listeners||{}; 670 } 671 var arr = listeners[type]; 672 if (arr) { this.removeEventListener(type, listener, useCapture); } 673 arr = listeners[type]; // remove may have deleted the array 674 if (!arr) { listeners[type] = [listener]; } 675 else { arr.push(listener); } 676 return listener; 677 }; 678 679 /** 680 * A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener 681 * only run once, associate arbitrary data with the listener, and remove the listener. 682 * 683 * This method works by creating an anonymous wrapper function and subscribing it with addEventListener. 684 * The wrapper function is returned for use with `removeEventListener` (or `off`). 685 * 686 * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use 687 * {{#crossLink "Event/remove"}}{{/crossLink}}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls 688 * to `on` with the same params will create multiple listeners. 689 * 690 * <h4>Example</h4> 691 * 692 * var listener = myBtn.on("click", handleClick, null, false, {count:3}); 693 * function handleClick(evt, data) { 694 * data.count -= 1; 695 * console.log(this == myBtn); // true - scope defaults to the dispatcher 696 * if (data.count == 0) { 697 * alert("clicked 3 times!"); 698 * myBtn.off("click", listener); 699 * // alternately: evt.remove(); 700 * } 701 * } 702 * 703 * @method on 704 * @param {String} type The string type of the event. 705 * @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when 706 * the event is dispatched. 707 * @param {Object} [scope] The scope to execute the listener in. Defaults to the dispatcher/currentTarget for function listeners, and to the listener itself for object listeners (ie. using handleEvent). 708 * @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered. 709 * @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called. 710 * @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 711 * @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener. 712 **/ 713 p.on = function(type, listener, scope, once, data, useCapture) { 714 if (listener.handleEvent) { 715 scope = scope||listener; 716 listener = listener.handleEvent; 717 } 718 scope = scope||this; 719 return this.addEventListener(type, function(evt) { 720 listener.call(scope, evt, data); 721 once&&evt.remove(); 722 }, useCapture); 723 }; 724 725 /** 726 * Removes the specified event listener. 727 * 728 * <b>Important Note:</b> that you must pass the exact function reference used when the event was added. If a proxy 729 * function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or 730 * closure will not work. 731 * 732 * <h4>Example</h4> 733 * 734 * displayObject.removeEventListener("click", handleClick); 735 * 736 * @method removeEventListener 737 * @param {String} type The string type of the event. 738 * @param {Function | Object} listener The listener function or object. 739 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 740 **/ 741 p.removeEventListener = function(type, listener, useCapture) { 742 var listeners = useCapture ? this._captureListeners : this._listeners; 743 if (!listeners) { return; } 744 var arr = listeners[type]; 745 if (!arr) { return; } 746 for (var i=0,l=arr.length; i<l; i++) { 747 if (arr[i] == listener) { 748 if (l==1) { delete(listeners[type]); } // allows for faster checks. 749 else { arr.splice(i,1); } 750 break; 751 } 752 } 753 }; 754 755 /** 756 * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the 757 * .on method. 758 * 759 * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See 760 * {{#crossLink "EventDispatcher/on"}}{{/crossLink}} for an example. 761 * 762 * @method off 763 * @param {String} type The string type of the event. 764 * @param {Function | Object} listener The listener function or object. 765 * @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase. 766 **/ 767 p.off = p.removeEventListener; 768 769 /** 770 * Removes all listeners for the specified type, or all listeners of all types. 771 * 772 * <h4>Example</h4> 773 * 774 * // Remove all listeners 775 * displayObject.removeAllEventListeners(); 776 * 777 * // Remove all click listeners 778 * displayObject.removeAllEventListeners("click"); 779 * 780 * @method removeAllEventListeners 781 * @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed. 782 **/ 783 p.removeAllEventListeners = function(type) { 784 if (!type) { this._listeners = this._captureListeners = null; } 785 else { 786 if (this._listeners) { delete(this._listeners[type]); } 787 if (this._captureListeners) { delete(this._captureListeners[type]); } 788 } 789 }; 790 791 /** 792 * Dispatches the specified event to all listeners. 793 * 794 * <h4>Example</h4> 795 * 796 * // Use a string event 797 * this.dispatchEvent("complete"); 798 * 799 * // Use an Event instance 800 * var event = new createjs.Event("progress"); 801 * this.dispatchEvent(event); 802 * 803 * @method dispatchEvent 804 * @param {Object | String | Event} eventObj An object with a "type" property, or a string type. 805 * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used, 806 * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can 807 * be used to avoid event object instantiation for non-bubbling events that may not have any listeners. 808 * @param {Boolean} [bubbles] Specifies the `bubbles` value when a string was passed to eventObj. 809 * @param {Boolean} [cancelable] Specifies the `cancelable` value when a string was passed to eventObj. 810 * @return {Boolean} Returns false if `preventDefault()` was called on a cancelable event, true otherwise. 811 **/
812 p.dispatchEvent = function(eventObj, bubbles, cancelable) { 813 if (typeof eventObj == "string") { 814 // skip everything if there's no listeners and it doesn't bubble: 815 var listeners = this._listeners; 816 if (!bubbles && (!listeners || !listeners[eventObj])) { return true; } 817 eventObj = new createjs.Event(eventObj, bubbles, cancelable); 818 } else if (eventObj.target && eventObj.clone) { 819 // redispatching an active event object, so clone it: 820 eventObj = eventObj.clone(); 821 } 822 823 // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent 824 try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events 825 826 if (!eventObj.bubbles || !this.parent) { 827 this._dispatchEvent(eventObj, 2); 828 } else { 829 var top=this, list=[top]; 830 while (top.parent) { list.push(top = top.parent); } 831 var i, l=list.length; 832 833 // capture & atTarget 834 for (i=l-1; i>=0 && !eventObj.propagationStopped; i--) { 835 list[i]._dispatchEvent(eventObj, 1+(i==0)); 836 } 837 // bubbling 838 for (i=1; i<l && !eventObj.propagationStopped; i++) { 839 list[i]._dispatchEvent(eventObj, 3); 840 } 841 } 842 return !eventObj.defaultPrevented; 843 }; 844 845 /** 846 * Indicates whether there is at least one listener for the specified event type. 847 * @method hasEventListener 848 * @param {String} type The string type of the event. 849 * @return {Boolean} Returns true if there is at least one listener for the specified event. 850 **/ 851 p.hasEventListener = function(type) { 852 var listeners = this._listeners, captureListeners = this._captureListeners; 853 return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type])); 854 }; 855 856 /** 857 * Indicates whether there is at least one listener for the specified event type on this object or any of its 858 * ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the 859 * specified type is dispatched from this object, it will trigger at least one listener. 860 * 861 * This is similar to {{#crossLink "EventDispatcher/hasEventListener"}}{{/crossLink}}, but it searches the entire 862 * event flow for a listener, not just this object. 863 * @method willTrigger 864 * @param {String} type The string type of the event. 865 * @return {Boolean} Returns `true` if there is at least one listener for the specified event. 866 **/ 867 p.willTrigger = function(type) { 868 var o = this; 869 while (o) { 870 if (o.hasEventListener(type)) { return true; } 871 o = o.parent; 872 } 873 return false; 874 }; 875 876 /** 877 * @method toString 878 * @return {String} a string representation of the instance. 879 **/ 880 p.toString = function() { 881 return "[EventDispatcher]"; 882 }; 883 884 885// private methods: 886 /** 887 * @method _dispatchEvent 888 * @param {Object | String | Event} eventObj 889 * @param {Object} eventPhase 890 * @protected 891 **/ 892 p._dispatchEvent = function(eventObj, eventPhase) { 893 var l, listeners = (eventPhase==1) ? this._captureListeners : this._listeners; 894 if (eventObj && listeners) { 895 var arr = listeners[eventObj.type]; 896 if (!arr||!(l=arr.length)) { return; } 897 try { eventObj.currentTarget = this; } catch (e) {} 898 try { eventObj.eventPhase = eventPhase; } catch (e) {} 899 eventObj.removed = false; 900 901 arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch 902 for (var i=0; i<l && !eventObj.immediatePropagationStopped; i++) { 903 var o = arr[i]; 904 if (o.handleEvent) { o.handleEvent(eventObj); } 905 else { o(eventObj); } 906 if (eventObj.removed) { 907 this.off(eventObj.type, o, eventPhase==1); 908 eventObj.removed = false; 909 } 910 } 911 } 912 }; 913 914 915 createjs.EventDispatcher = EventDispatcher; 916}()); 917 918//############################################################################## 919// ProgressEvent.js 920//############################################################################## 921 922this.createjs = this.createjs || {}; 923 924(function (scope) { 925 "use strict"; 926 927 // constructor 928 /** 929 * A CreateJS {{#crossLink "Event"}}{{/crossLink}} that is dispatched when progress changes. 930 * @class ProgressEvent 931 * @param {Number} loaded The amount that has been loaded. This can be any number relative to the total. 932 * @param {Number} [total=1] The total amount that will load. This will default to 1, so if the `loaded` value is 933 * a percentage (between 0 and 1), it can be omitted. 934 * @todo Consider having this event be a "fileprogress" event as well 935 * @constructor 936 */ 937 function ProgressEvent(loaded, total) { 938 this.Event_constructor("progress"); 939 940 /** 941 * The amount that has been loaded (out of a total amount) 942 * @property loaded 943 * @type {Number} 944 */ 945 this.loaded = loaded; 946 947 /** 948 * The total "size" of the load. 949 * @property total 950 * @type {Number} 951 * @default 1 952 */ 953 this.total = (total == null) ? 1 : total; 954 955 /** 956 * The percentage (out of 1) that the load has been completed. This is calculated using `loaded/total`. 957 * @property progress 958 * @type {Number} 959 * @default 0 960 */ 961 this.progress = (total == 0) ? 0 : this.loaded / this.total; 962 }; 963
964 var p = createjs.extend(ProgressEvent, createjs.Event); 965 966 /** 967 * Returns a clone of the ProgressEvent instance. 968 * @method clone 969 * @return {ProgressEvent} a clone of the Event instance. 970 **/ 971 p.clone = function() { 972 return new createjs.ProgressEvent(this.loaded, this.total); 973 }; 974 975 createjs.ProgressEvent = createjs.promote(ProgressEvent, "Event"); 976 977}(window)); 978 979//############################################################################## 980// json3.js 981//##############################################################################
vendor: 43,298 bytes, lines 982-1885
982 983/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ 984;(function () { 985 // Detect the `define` function exposed by asynchronous module loaders. The 986 // strict `define` check is necessary for compatibility with `r.js`. 987 var isLoader = typeof define === "function" && define.amd; 988 989 // A set of types used to distinguish objects from primitives. 990 var objectTypes = { 991 "function": true, 992 "object": true 993 }; 994 995 // Detect the `exports` object exposed by CommonJS implementations. 996 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; 997 998 // Use the `global` object exposed by Node (including Browserify via 999 // `insert-module-globals`), Narwhal, and Ringo as the default context, 1000 // and the `window` object in browsers. Rhino exports a `global` function 1001 // instead. 1002 var root = objectTypes[typeof window] && window || this, 1003 freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global; 1004 1005 if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) { 1006 root = freeGlobal; 1007 } 1008 1009 // Public: Initializes JSON 3 using the given `context` object, attaching the 1010 // `stringify` and `parse` functions to the specified `exports` object. 1011 function runInContext(context, exports) { 1012 context || (context = root["Object"]()); 1013 exports || (exports = root["Object"]()); 1014 1015 // Native constructor aliases. 1016 var Number = context["Number"] || root["Number"], 1017 String = context["String"] || root["String"], 1018 Object = context["Object"] || root["Object"], 1019 Date = context["Date"] || root["Date"], 1020 SyntaxError = context["SyntaxError"] || root["SyntaxError"], 1021 TypeError = context["TypeError"] || root["TypeError"], 1022 Math = context["Math"] || root["Math"], 1023 nativeJSON = context["JSON"] || root["JSON"]; 1024 1025 // Delegate to the native `stringify` and `parse` implementations. 1026 if (typeof nativeJSON == "object" && nativeJSON) { 1027 exports.stringify = nativeJSON.stringify; 1028 exports.parse = nativeJSON.parse; 1029 } 1030 1031 // Convenience aliases. 1032 var objectProto = Object.prototype, 1033 getClass = objectProto.toString, 1034 isProperty, forEach, undef; 1035 1036 // Test the `Date#getUTC*` methods. Based on work by @Yaffle. 1037 var isExtended = new Date(-3509827334573292); 1038 try { 1039 // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical 1040 // results for certain dates in Opera >= 10.53. 1041 isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && 1042 // Safari < 2.0.2 stores the internal millisecond time value correctly, 1043 // but clips the values returned by the date methods to the range of 1044 // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). 1045 isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; 1046 } catch (exception) {} 1047 1048 // Internal: Determines whether the native `JSON.stringify` and `parse` 1049 // implementations are spec-compliant. Based on work by Ken Snyder. 1050 function has(name) { 1051 if (has[name] !== undef) { 1052 // Return cached feature test result. 1053 return has[name]; 1054 } 1055 var isSupported; 1056 if (name == "bug-string-char-index") { 1057 // IE <= 7 doesn't support accessing string characters using square 1058 // bracket notation. IE 8 only supports this for primitives. 1059 isSupported = "a"[0] != "a"; 1060 } else if (name == "json") { 1061 // Indicates whether both `JSON.stringify` and `JSON.parse` are 1062 // supported. 1063 isSupported = has("json-stringify") && has("json-parse"); 1064 } else { 1065 var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; 1066 // Test `JSON.stringify`. 1067 if (name == "json-stringify") { 1068 var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; 1069 if (stringifySupported) { 1070 // A test function object with a custom `toJSON` method. 1071 (value = function () { 1072 return 1; 1073 }).toJSON = value; 1074 try { 1075 stringifySupported = 1076 // Firefox 3.1b1 and b2 serialize string, number, and boolean 1077 // primitives as object literals. 1078 stringify(0) === "0" && 1079 // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object 1080 // literals. 1081 stringify(new Number()) === "0" && 1082 stringify(new String()) == '""' && 1083 // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or 1084 // does not define a canonical JSON representation (this applies to 1085 // objects with `toJSON` properties as well, *unless* they are nested 1086 // within an object or array). 1087 stringify(getClass) === undef && 1088 // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and 1089 // FF 3.1b3 pass this test. 1090 stringify(undef) === undef && 1091 // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, 1092 // respectively, if the value is omitted entirely. 1093 stringify() === undef && 1094 // FF 3.1b1, 2 throw an error if the given value is not a number, 1095 // string, array, object, Boolean, or `null` literal. This applies to 1096 // objects with custom `toJSON` methods as well, unless they are nested 1097 // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` 1098 // methods entirely. 1099 stringify(value) === "1" && 1100 stringify([value]) == "[1]" && 1101 // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of 1102 // `"[null]"`. 1103 stringify([undef]) == "[null]" && 1104 // YUI 3.0.0b1 fails to serialize `null` literals. 1105 stringify(null) == "null" && 1106 // FF 3.1b1, 2 halts serialization if an array contains a function: 1107 // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 1108 // elides non-JSON values from objects and arrays, unless they 1109 // define custom `toJSON` methods. 1110 stringify([undef, getClass, null]) == "[null,null,null]" && 1111 // Simple serialization test. FF 3.1b1 uses Unicode escape sequences 1112 // where character escape codes are expected (e.g., `\b` => `\u0008`). 1113 stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && 1114 // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. 1115 stringify(null, value) === "1" && 1116 stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && 1117 // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly 1118 // serialize extended years. 1119 stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && 1120 // The milliseconds are optional in ES 5, but required in 5.1. 1121 stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && 1122 // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative 1123 // four-digit years instead of six-digit years. Credits: @Yaffle. 1124 stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && 1125 // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond 1126 // values less than 1000. Credits: @Yaffle. 1127 stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; 1128 } catch (exception) { 1129 stringifySupported = false; 1130 } 1131 } 1132 isSupported = stringifySupported; 1133 } 1134 // Test `JSON.parse`. 1135 if (name == "json-parse") { 1136 var parse = exports.parse; 1137 if (typeof parse == "function") { 1138 try { 1139 // FF 3.1b1, b2 will throw an exception if a bare literal is provided. 1140 // Conforming implementations should also coerce the initial argument to 1141 // a string prior to parsing. 1142 if (parse("0") === 0 && !parse(false)) { 1143 // Simple parsing test. 1144 value = parse(serialized); 1145 var parseSupported = value["a"].length == 5 && value["a"][0] === 1; 1146 if (parseSupported) { 1147 try { 1148 // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. 1149 parseSupported = !parse('"\t"'); 1150 } catch (exception) {} 1151 if (parseSupported) { 1152 try { 1153 // FF 4.0 and 4.0.1 allow leading `+` signs and leading 1154 // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow 1155 // certain octal literals. 1156 parseSupported = parse("01") !== 1; 1157 } catch (exception) {} 1158 } 1159 if (parseSupported) { 1160 try { 1161 // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal 1162 // points. These environments, along with FF 3.1b1 and 2, 1163 // also allow trailing commas in JSON objects and arrays. 1164 parseSupported = parse("1.") !== 1; 1165 } catch (exception) {} 1166 } 1167 } 1168 } 1169 } catch (exception) { 1170 parseSupported = false; 1171 } 1172 } 1173 isSupported = parseSupported; 1174 } 1175 } 1176 return has[name] = !!isSupported; 1177 } 1178 1179 if (!has("json")) { 1180 // Common `[[Class]]` name aliases. 1181 var functionClass = "[object Function]", 1182 dateClass = "[object Date]", 1183 numberClass = "[object Number]", 1184 stringClass = "[object String]", 1185 arrayClass = "[object Array]", 1186 booleanClass = "[object Boolean]"; 1187 1188 // Detect incomplete support for accessing string characters by index. 1189 var charIndexBuggy = has("bug-string-char-index"); 1190 1191 // Define additional utility methods if the `Date` methods are buggy. 1192 if (!isExtended) { 1193 var floor = Math.floor; 1194 // A mapping between the months of the year and the number of days between 1195 // January 1st and the first of the respective month. 1196 var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; 1197 // Internal: Calculates the number of days between the Unix epoch and the 1198 // first day of the given month. 1199 var getDay = function (year, month) { 1200 return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); 1201 }; 1202 } 1203 1204 // Internal: Determines if a property is a direct property of the given 1205 // object. Delegates to the native `Object#hasOwnProperty` method. 1206 if (!(isProperty = objectProto.hasOwnProperty)) { 1207 isProperty = function (property) { 1208 var members = {}, constructor; 1209 if ((members.__proto__ = null, members.__proto__ = { 1210 // The *proto* property cannot be set multiple times in recent 1211 // versions of Firefox and SeaMonkey. 1212 "toString": 1 1213 }, members).toString != getClass) { 1214 // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but 1215 // supports the mutable *proto* property. 1216 isProperty = function (property) { 1217 // Capture and break the object's prototype chain (see section 8.6.2 1218 // of the ES 5.1 spec). The parenthesized expression prevents an 1219 // unsafe transformation by the Closure Compiler. 1220 var original = this.__proto__, result = property in (this.__proto__ = null, this); 1221 // Restore the original prototype chain. 1222 this.__proto__ = original; 1223 return result; 1224 }; 1225 } else { 1226 // Capture a reference to the top-level `Object` constructor. 1227 constructor = members.constructor; 1228 // Use the `constructor` property to simulate `Object#hasOwnProperty` in 1229 // other environments. 1230 isProperty = function (property) { 1231 var parent = (this.constructor || constructor).prototype; 1232 return property in this && !(property in parent && this[property] === parent[property]); 1233 }; 1234 } 1235 members = null; 1236 return isProperty.call(this, property); 1237 }; 1238 } 1239 1240 // Internal: Normalizes the `for...in` iteration algorithm across 1241 // environments. Each enumerated key is yielded to a `callback` function. 1242 forEach = function (object, callback) { 1243 var size = 0, Properties, members, property; 1244 1245 // Tests for bugs in the current environment's `for...in` algorithm. The 1246 // `valueOf` property inherits the non-enumerable flag from 1247 // `Object.prototype` in older versions of IE, Netscape, and Mozilla. 1248 (Properties = function () { 1249 this.valueOf = 0; 1250 }).prototype.valueOf = 0; 1251 1252 // Iterate over a new instance of the `Properties` class. 1253 members = new Properties(); 1254 for (property in members) { 1255 // Ignore all properties inherited from `Object.prototype`. 1256 if (isProperty.call(members, property)) { 1257 size++; 1258 } 1259 } 1260 Properties = members = null; 1261 1262 // Normalize the iteration algorithm. 1263 if (!size) { 1264 // A list of non-enumerable properties inherited from `Object.prototype`. 1265 members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; 1266 // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable 1267 // properties. 1268 forEach = function (object, callback) { 1269 var isFunction = getClass.call(object) == functionClass, property, length; 1270 var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty; 1271 for (property in object) { 1272 // Gecko <= 1.0 enumerates the `prototype` property of functions under 1273 // certain conditions; IE does not. 1274 if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { 1275 callback(property); 1276 } 1277 } 1278 // Manually invoke the callback for each non-enumerable property. 1279 for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); 1280 }; 1281 } else if (size == 2) { 1282 // Safari <= 2.0.4 enumerates shadowed properties twice. 1283 forEach = function (object, callback) { 1284 // Create a set of iterated properties. 1285 var members = {}, isFunction = getClass.call(object) == functionClass, property; 1286 for (property in object) { 1287 // Store each property name to prevent double enumeration. The 1288 // `prototype` property of functions is not enumerated due to cross- 1289 // environment inconsistencies. 1290 if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { 1291 callback(property); 1292 } 1293 } 1294 }; 1295 } else { 1296 // No bugs detected; use the standard `for...in` algorithm. 1297 forEach = function (object, callback) { 1298 var isFunction = getClass.call(object) == functionClass, property, isConstructor; 1299 for (property in object) { 1300 if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { 1301 callback(property); 1302 } 1303 } 1304 // Manually invoke the callback for the `constructor` property due to 1305 // cross-environment inconsistencies. 1306 if (isConstructor || isProperty.call(object, (property = "constructor"))) { 1307 callback(property); 1308 } 1309 }; 1310 } 1311 return forEach(object, callback); 1312 }; 1313 1314 // Public: Serializes a JavaScript `value` as a JSON string. The optional 1315 // `filter` argument may specify either a function that alters how object and 1316 // array members are serialized, or an array of strings and numbers that 1317 // indicates which properties should be serialized. The optional `width` 1318 // argument may be either a string or number that specifies the indentation 1319 // level of the output. 1320 if (!has("json-stringify")) { 1321 // Internal: A map of control characters and their escaped equivalents. 1322 var Escapes = { 1323 92: "\\\\", 1324 34: '\\"', 1325 8: "\\b", 1326 12: "\\f", 1327 10: "\\n", 1328 13: "\\r", 1329 9: "\\t" 1330 }; 1331 1332 // Internal: Converts `value` into a zero-padded string such that its 1333 // length is at least equal to `width`. The `width` must be <= 6. 1334 var leadingZeroes = "000000"; 1335 var toPaddedString = function (width, value) { 1336 // The `|| 0` expression is necessary to work around a bug in 1337 // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. 1338 return (leadingZeroes + (value || 0)).slice(-width); 1339 }; 1340 1341 // Internal: Double-quotes a string `value`, replacing all ASCII control 1342 // characters (characters with code unit values between 0 and 31) with 1343 // their escaped equivalents. This is an implementation of the 1344 // `Quote(value)` operation defined in ES 5.1 section 15.12.3. 1345 var unicodePrefix = "\\u00"; 1346 var quote = function (value) { 1347 var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; 1348 var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value); 1349 for (; index < length; index++) { 1350 var charCode = value.charCodeAt(index); 1351 // If the character is a control character, append its Unicode or 1352 // shorthand escape sequence; otherwise, append the character as-is. 1353 switch (charCode) { 1354 case 8: case 9: case 10: case 12: case 13: case 34: case 92: 1355 result += Escapes[charCode]; 1356 break; 1357 default: 1358 if (charCode < 32) { 1359 result += unicodePrefix + toPaddedString(2, charCode.toString(16)); 1360 break; 1361 } 1362 result += useCharIndex ? symbols[index] : value.charAt(index); 1363 } 1364 } 1365 return result + '"'; 1366 }; 1367 1368 // Internal: Recursively serializes an object. Implements the 1369 // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. 1370 var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { 1371 var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; 1372 try { 1373 // Necessary for host object support. 1374 value = object[property]; 1375 } catch (exception) {} 1376 if (typeof value == "object" && value) { 1377 className = getClass.call(value); 1378 if (className == dateClass && !isProperty.call(value, "toJSON")) { 1379 if (value > -1 / 0 && value < 1 / 0) { 1380 // Dates are serialized according to the `Date#toJSON` method 1381 // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 1382 // for the ISO 8601 date time string format. 1383 if (getDay) { 1384 // Manually compute the year, month, date, hours, minutes, 1385 // seconds, and milliseconds if the `getUTC*` methods are 1386 // buggy. Adapted from @Yaffle's `date-shim` project. 1387 date = floor(value / 864e5); 1388 for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); 1389 for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); 1390 date = 1 + date - getDay(year, month); 1391 // The `time` value specifies the time within the day (see ES 1392 // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used 1393 // to compute `A modulo B`, as the `%` operator does not 1394 // correspond to the `modulo` operation for negative numbers. 1395 time = (value % 864e5 + 864e5) % 864e5; 1396 // The hours, minutes, seconds, and milliseconds are obtained by 1397 // decomposing the time within the day. See section 15.9.1.10. 1398 hours = floor(time / 36e5) % 24; 1399 minutes = floor(time / 6e4) % 60; 1400 seconds = floor(time / 1e3) % 60; 1401 milliseconds = time % 1e3; 1402 } else { 1403 year = value.getUTCFullYear(); 1404 month = value.getUTCMonth(); 1405 date = value.getUTCDate(); 1406 hours = value.getUTCHours(); 1407 minutes = value.getUTCMinutes(); 1408 seconds = value.getUTCSeconds(); 1409 milliseconds = value.getUTCMilliseconds(); 1410 } 1411 // Serialize extended years correctly. 1412 value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + 1413 "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + 1414 // Months, dates, hours, minutes, and seconds should have two 1415 // digits; milliseconds should have three. 1416 "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + 1417 // Milliseconds are optional in ES 5.0, but required in 5.1. 1418 "." + toPaddedString(3, milliseconds) + "Z"; 1419 } else { 1420 value = null; 1421 } 1422 } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { 1423 // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the 1424 // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 1425 // ignores all `toJSON` methods on these objects unless they are 1426 // defined directly on an instance. 1427 value = value.toJSON(property); 1428 } 1429 } 1430 if (callback) { 1431 // If a replacement function was provided, call it to obtain the value 1432 // for serialization. 1433 value = callback.call(object, property, value); 1434 } 1435 if (value === null) { 1436 return "null"; 1437 } 1438 className = getClass.call(value); 1439 if (className == booleanClass) { 1440 // Booleans are represented literally. 1441 return "" + value; 1442 } else if (className == numberClass) { 1443 // JSON numbers must be finite. `Infinity` and `NaN` are serialized as 1444 // `"null"`. 1445 return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; 1446 } else if (className == stringClass) { 1447 // Strings are double-quoted and escaped. 1448 return quote("" + value); 1449 } 1450 // Recursively serialize objects and arrays. 1451 if (typeof value == "object") { 1452 // Check for cyclic structures. This is a linear search; performance 1453 // is inversely proportional to the number of unique nested objects. 1454 for (length = stack.length; length--;) { 1455 if (stack[length] === value) { 1456 // Cyclic structures cannot be serialized by `JSON.stringify`. 1457 throw TypeError(); 1458 } 1459 } 1460 // Add the object to the stack of traversed objects. 1461 stack.push(value); 1462 results = []; 1463 // Save the current indentation level and indent one additional level. 1464 prefix = indentation; 1465 indentation += whitespace; 1466 if (className == arrayClass) { 1467 // Recursively serialize array elements. 1468 for (index = 0, length = value.length; index < length; index++) { 1469 element = serialize(index, value, callback, properties, whitespace, indentation, stack); 1470 results.push(element === undef ? "null" : element); 1471 } 1472 result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; 1473 } else { 1474 // Recursively serialize object members. Members are selected from 1475 // either a user-specified list of property names, or the object 1476 // itself. 1477 forEach(properties || value, function (property) { 1478 var element = serialize(property, value, callback, properties, whitespace, indentation, stack); 1479 if (element !== undef) { 1480 // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} 1481 // is not the empty string, let `member` {quote(property) + ":"} 1482 // be the concatenation of `member` and the `space` character." 1483 // The "`space` character" refers to the literal space 1484 // character, not the `space` {width} argument provided to 1485 // `JSON.stringify`. 1486 results.push(quote(property) + ":" + (whitespace ? " " : "") + element); 1487 } 1488 }); 1489 result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; 1490 } 1491 // Remove the object from the traversed object stack. 1492 stack.pop(); 1493 return result; 1494 } 1495 }; 1496 1497 // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. 1498 exports.stringify = function (source, filter, width) { 1499 var whitespace, callback, properties, className; 1500 if (objectTypes[typeof filter] && filter) { 1501 if ((className = getClass.call(filter)) == functionClass) { 1502 callback = filter; 1503 } else if (className == arrayClass) { 1504 // Convert the property names array into a makeshift set. 1505 properties = {}; 1506 for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); 1507 } 1508 } 1509 if (width) { 1510 if ((className = getClass.call(width)) == numberClass) { 1511 // Convert the `width` to an integer and create a string containing 1512 // `width` number of space characters. 1513 if ((width -= width % 1) > 0) { 1514 for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); 1515 } 1516 } else if (className == stringClass) { 1517 whitespace = width.length <= 10 ? width : width.slice(0, 10); 1518 } 1519 } 1520 // Opera <= 7.54u2 discards the values associated with empty string keys 1521 // (`""`) only if they are used directly within an object member list 1522 // (e.g., `!("" in { "": 1})`). 1523 return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); 1524 }; 1525 } 1526 1527 // Public: Parses a JSON source string. 1528 if (!has("json-parse")) { 1529 var fromCharCode = String.fromCharCode; 1530 1531 // Internal: A map of escaped control characters and their unescaped 1532 // equivalents. 1533 var Unescapes = { 1534 92: "\\", 1535 34: '"', 1536 47: "/", 1537 98: "\b", 1538 116: "\t", 1539 110: "\n", 1540 102: "\f", 1541 114: "\r" 1542 }; 1543 1544 // Internal: Stores the parser state. 1545 var Index, Source; 1546 1547 // Internal: Resets the parser state and throws a `SyntaxError`. 1548 var abort = function () { 1549 Index = Source = null; 1550 throw SyntaxError(); 1551 }; 1552 1553 // Internal: Returns the next token, or `"$"` if the parser has reached 1554 // the end of the source string. A token may be a string, number, `null` 1555 // literal, or Boolean literal. 1556 var lex = function () { 1557 var source = Source, length = source.length, value, begin, position, isSigned, charCode; 1558 while (Index < length) { 1559 charCode = source.charCodeAt(Index); 1560 switch (charCode) { 1561 case 9: case 10: case 13: case 32: 1562 // Skip whitespace tokens, including tabs, carriage returns, line 1563 // feeds, and space characters. 1564 Index++; 1565 break; 1566 case 123: case 125: case 91: case 93: case 58: case 44: 1567 // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at 1568 // the current position. 1569 value = charIndexBuggy ? source.charAt(Index) : source[Index]; 1570 Index++; 1571 return value; 1572 case 34: 1573 // `"` delimits a JSON string; advance to the next character and 1574 // begin parsing the string. String tokens are prefixed with the 1575 // sentinel `@` character to distinguish them from punctuators and 1576 // end-of-string tokens. 1577 for (value = "@", Index++; Index < length;) { 1578 charCode = source.charCodeAt(Index); 1579 if (charCode < 32) { 1580 // Unescaped ASCII control characters (those with a code unit 1581 // less than the space character) are not permitted. 1582 abort(); 1583 } else if (charCode == 92) { 1584 // A reverse solidus (`\`) marks the beginning of an escaped 1585 // control character (including `"`, `\`, and `/`) or Unicode 1586 // escape sequence. 1587 charCode = source.charCodeAt(++Index); 1588 switch (charCode) { 1589 case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: 1590 // Revive escaped control characters. 1591 value += Unescapes[charCode]; 1592 Index++; 1593 break; 1594 case 117: 1595 // `\u` marks the beginning of a Unicode escape sequence. 1596 // Advance to the first character and validate the 1597 // four-digit code point. 1598 begin = ++Index; 1599 for (position = Index + 4; Index < position; Index++) { 1600 charCode = source.charCodeAt(Index); 1601 // A valid sequence comprises four hexdigits (case- 1602 // insensitive) that form a single hexadecimal value. 1603 if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { 1604 // Invalid Unicode escape sequence. 1605 abort(); 1606 } 1607 } 1608 // Revive the escaped character. 1609 value += fromCharCode("0x" + source.slice(begin, Index)); 1610 break; 1611 default: 1612 // Invalid escape sequence. 1613 abort(); 1614 } 1615 } else { 1616 if (charCode == 34) { 1617 // An unescaped double-quote character marks the end of the 1618 // string. 1619 break; 1620 } 1621 charCode = source.charCodeAt(Index); 1622 begin = Index; 1623 // Optimize for the common case where a string is valid. 1624 while (charCode >= 32 && charCode != 92 && charCode != 34) { 1625 charCode = source.charCodeAt(++Index); 1626 } 1627 // Append the string as-is. 1628 value += source.slice(begin, Index); 1629 } 1630 } 1631 if (source.charCodeAt(Index) == 34) { 1632 // Advance to the next character and return the revived string. 1633 Index++; 1634 return value; 1635 } 1636 // Unterminated string. 1637 abort(); 1638 default: 1639 // Parse numbers and literals. 1640 begin = Index; 1641 // Advance past the negative sign, if one is specified. 1642 if (charCode == 45) { 1643 isSigned = true; 1644 charCode = source.charCodeAt(++Index); 1645 } 1646 // Parse an integer or floating-point value. 1647 if (charCode >= 48 && charCode <= 57) { 1648 // Leading zeroes are interpreted as octal literals. 1649 if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { 1650 // Illegal octal literal. 1651 abort(); 1652 } 1653 isSigned = false; 1654 // Parse the integer component. 1655 for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); 1656 // Floats cannot contain a leading decimal point; however, this 1657 // case is already accounted for by the parser. 1658 if (source.charCodeAt(Index) == 46) { 1659 position = ++Index; 1660 // Parse the decimal component. 1661 for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); 1662 if (position == Index) { 1663 // Illegal trailing decimal. 1664 abort(); 1665 } 1666 Index = position; 1667 } 1668 // Parse exponents. The `e` denoting the exponent is 1669 // case-insensitive. 1670 charCode = source.charCodeAt(Index); 1671 if (charCode == 101 || charCode == 69) { 1672 charCode = source.charCodeAt(++Index); 1673 // Skip past the sign following the exponent, if one is 1674 // specified. 1675 if (charCode == 43 || charCode == 45) { 1676 Index++; 1677 } 1678 // Parse the exponential component. 1679 for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); 1680 if (position == Index) { 1681 // Illegal empty exponent. 1682 abort(); 1683 } 1684 Index = position; 1685 } 1686 // Coerce the parsed value to a JavaScript number. 1687 return +source.slice(begin, Index); 1688 } 1689 // A negative sign may only precede numbers. 1690 if (isSigned) { 1691 abort(); 1692 } 1693 // `true`, `false`, and `null` literals. 1694 if (source.slice(Index, Index + 4) == "true") { 1695 Index += 4; 1696 return true; 1697 } else if (source.slice(Index, Index + 5) == "false") { 1698 Index += 5; 1699 return false; 1700 } else if (source.slice(Index, Index + 4) == "null") { 1701 Index += 4; 1702 return null; 1703 } 1704 // Unrecognized token. 1705 abort(); 1706 } 1707 } 1708 // Return the sentinel `$` character if the parser has reached the end 1709 // of the source string. 1710 return "$"; 1711 }; 1712 1713 // Internal: Parses a JSON `value` token. 1714 var get = function (value) { 1715 var results, hasMembers; 1716 if (value == "$") { 1717 // Unexpected end of input. 1718 abort(); 1719 } 1720 if (typeof value == "string") { 1721 if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { 1722 // Remove the sentinel `@` character. 1723 return value.slice(1); 1724 } 1725 // Parse object and array literals. 1726 if (value == "[") { 1727 // Parses a JSON array, returning a new JavaScript array. 1728 results = []; 1729 for (;; hasMembers || (hasMembers = true)) { 1730 value = lex(); 1731 // A closing square bracket marks the end of the array literal. 1732 if (value == "]") { 1733 break; 1734 } 1735 // If the array literal contains elements, the current token 1736 // should be a comma separating the previous element from the 1737 // next. 1738 if (hasMembers) { 1739 if (value == ",") { 1740 value = lex(); 1741 if (value == "]") { 1742 // Unexpected trailing `,` in array literal. 1743 abort(); 1744 } 1745 } else { 1746 // A `,` must separate each array element. 1747 abort(); 1748 } 1749 } 1750 // Elisions and leading commas are not permitted. 1751 if (value == ",") { 1752 abort(); 1753 } 1754 results.push(get(value)); 1755 } 1756 return results; 1757 } else if (value == "{") { 1758 // Parses a JSON object, returning a new JavaScript object. 1759 results = {}; 1760 for (;; hasMembers || (hasMembers = true)) { 1761 value = lex(); 1762 // A closing curly brace marks the end of the object literal. 1763 if (value == "}") { 1764 break; 1765 } 1766 // If the object literal contains members, the current token 1767 // should be a comma separator. 1768 if (hasMembers) { 1769 if (value == ",") { 1770 value = lex(); 1771 if (value == "}") { 1772 // Unexpected trailing `,` in object literal. 1773 abort(); 1774 } 1775 } else { 1776 // A `,` must separate each object member. 1777 abort(); 1778 } 1779 } 1780 // Leading commas are not permitted, object property names must be 1781 // double-quoted strings, and a `:` must separate each property 1782 // name and value. 1783 if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { 1784 abort(); 1785 } 1786 results[value.slice(1)] = get(lex()); 1787 } 1788 return results; 1789 } 1790 // Unexpected token encountered. 1791 abort(); 1792 } 1793 return value; 1794 }; 1795 1796 // Internal: Updates a traversed object member. 1797 var update = function (source, property, callback) { 1798 var element = walk(source, property, callback); 1799 if (element === undef) { 1800 delete source[property]; 1801 } else { 1802 source[property] = element; 1803 } 1804 }; 1805 1806 // Internal: Recursively traverses a parsed JSON object, invoking the 1807 // `callback` function for each value. This is an implementation of the 1808 // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. 1809 var walk = function (source, property, callback) { 1810 var value = source[property], length; 1811 if (typeof value == "object" && value) { 1812 // `forEach` can't be used to traverse an array in Opera <= 8.54 1813 // because its `Object#hasOwnProperty` implementation returns `false` 1814 // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). 1815 if (getClass.call(value) == arrayClass) { 1816 for (length = value.length; length--;) { 1817 update(value, length, callback); 1818 } 1819 } else { 1820 forEach(value, function (property) { 1821 update(value, property, callback); 1822 }); 1823 } 1824 } 1825 return callback.call(source, property, value); 1826 }; 1827 1828 // Public: `JSON.parse`. See ES 5.1 section 15.12.2. 1829 exports.parse = function (source, callback) { 1830 var result, value; 1831 Index = 0; 1832 Source = "" + source; 1833 result = get(lex()); 1834 // If a JSON string contains multiple tokens, it is invalid. 1835 if (lex() != "$") { 1836 abort(); 1837 } 1838 // Reset the parser state. 1839 Index = Source = null; 1840 return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; 1841 }; 1842 } 1843 } 1844 1845 exports["runInContext"] = runInContext; 1846 return exports; 1847 } 1848 1849 if (freeExports && !isLoader) { 1850 // Export for CommonJS environments. 1851 runInContext(root, freeExports); 1852 } else { 1853 // Export for web browsers and JavaScript engines. 1854 var nativeJSON = root.JSON, 1855 previousJSON = root["JSON3"], 1856 isRestored = false; 1857 1858 var JSON3 = runInContext(root, (root["JSON3"] = { 1859 // Public: Restores the original value of the global `JSON` object and 1860 // returns a reference to the `JSON3` object. 1861 "noConflict": function () { 1862 if (!isRestored) { 1863 isRestored = true; 1864 root.JSON = nativeJSON; 1865 root["JSON3"] = previousJSON; 1866 nativeJSON = previousJSON = null; 1867 } 1868 return JSON3; 1869 } 1870 })); 1871 1872 root.JSON = { 1873 "parse": JSON3.parse, 1874 "stringify": JSON3.stringify 1875 }; 1876 } 1877 1878 // Export for asynchronous module loaders. 1879 if (isLoader) { 1880 define(function () { 1881 return JSON3; 1882 }); 1883 } 1884}).call(this); 1885
1886//############################################################################## 1887// DomUtils.js 1888//############################################################################## 1889 1890(function () { 1891 1892 /** 1893 * A few utilities for interacting with the dom. 1894 * @class DomUtils 1895 */ 1896 var s = {}; 1897 1898 s.appendToHead = function (el) { 1899 s.getHead().appendChild(el) 1900 } 1901 1902 s.getHead = function () { 1903 return document.head || document.getElementsByTagName("head")[0]; 1904 } 1905 1906 s.getBody = function () { 1907 return document.body || document.getElementsByTagName("body")[0]; 1908 } 1909 1910 createjs.DomUtils = s; 1911 1912}()); 1913 1914//############################################################################## 1915// DataUtils.js 1916//############################################################################## 1917 1918(function () { 1919 1920 /** 1921 * A few data utilities for formatting different data types. 1922 * @class DataUtils 1923 */ 1924 var s = {}; 1925 1926 // static methods 1927 /** 1928 * Parse XML using the DOM. This is required when preloading XML or SVG. 1929 * @method parseXML 1930 * @param {String} text The raw text or XML that is loaded by XHR. 1931 * @param {String} type The mime type of the XML. Use "text/xml" for XML, and "image/svg+xml" for SVG parsing. 1932 * @return {XML} An XML document 1933 * @static 1934 */ 1935 s.parseXML = function (text, type) { 1936 var xml = null; 1937 // CocoonJS does not support XML parsing with either method. 1938 1939 // Most browsers will use DOMParser 1940 // IE fails on certain SVG files, so we have a fallback below. 1941 try { 1942 if (window.DOMParser) { 1943 var parser = new DOMParser(); 1944 xml = parser.parseFromString(text, type); 1945 } 1946 } catch (e) { 1947 } 1948 1949 // Fallback for IE support. 1950 if (!xml) { 1951 try { 1952 xml = new ActiveXObject("Microsoft.XMLDOM"); 1953 xml.async = false; 1954 xml.loadXML(text); 1955 } catch (e) { 1956 xml = null; 1957 } 1958 } 1959 1960 return xml; 1961 }; 1962 1963 /** 1964 * Parse a string into an Object. 1965 * @method parseJSON 1966 * @param {String} value The loaded JSON string 1967 * @returns {Object} A JavaScript object. 1968 */ 1969 s.parseJSON = function (value) { 1970 if (value == null) { 1971 return null; 1972 } 1973 1974 try { 1975 return JSON.parse(value); 1976 } catch (e) { 1977 // TODO; Handle this with a custom error? 1978 throw e; 1979 } 1980 }; 1981 1982 createjs.DataUtils = s; 1983 1984}()); 1985 1986//############################################################################## 1987// LoadItem.js 1988//############################################################################## 1989 1990this.createjs = this.createjs || {}; 1991 1992(function () { 1993 "use strict"; 1994 1995 /** 1996 * All loaders accept an item containing the properties defined in this class. If a raw object is passed instead, 1997 * it will not be affected, but it must contain at least a {{#crossLink "src:property"}}{{/crossLink}} property. A 1998 * string path or HTML tag is also acceptable, but it will be automatically converted to a LoadItem using the 1999 * {{#crossLink "create"}}{{/crossLink}} method by {{#crossLink "AbstractLoader"}}{{/crossLink}} 2000 * @class LoadItem 2001 * @constructor 2002 * @since 0.6.0 2003 */ 2004 function LoadItem() { 2005 /** 2006 * The source of the file that is being loaded. This property is <b>required</b>. The source can either be a 2007 * string (recommended), or an HTML tag. 2008 * This can also be an object, but in that case it has to include a type and be handled by a plugin. 2009 * @property src 2010 * @type {String} 2011 * @default null 2012 */ 2013 this.src = null; 2014 2015 /** 2016 * The type file that is being loaded. The type of the file is usually inferred by the extension, but can also 2017 * be set manually. This is helpful in cases where a file does not have an extension. 2018 * @property type 2019 * @type {String} 2020 * @default null 2021 */ 2022 this.type = null; 2023 2024 /** 2025 * A string identifier which can be used to reference the loaded object. If none is provided, this will be 2026 * automatically set to the {{#crossLink "src:property"}}{{/crossLink}}. 2027 * @property id 2028 * @type {String} 2029 * @default null 2030 */ 2031 this.id = null; 2032 2033 /** 2034 * Determines if a manifest will maintain the order of this item, in relation to other items in the manifest 2035 * that have also set the `maintainOrder` property to `true`. This only applies when the max connections has 2036 * been set above 1 (using {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}). Everything with this 2037 * property set to `false` will finish as it is loaded. Ordered items are combined with script tags loading in 2038 * order when {{#crossLink "LoadQueue/maintainScriptOrder:property"}}{{/crossLink}} is set to `true`. 2039 * @property maintainOrder 2040 * @type {Boolean} 2041 * @default false 2042 */ 2043 this.maintainOrder = false;
2044 2045 /** 2046 * A callback used by JSONP requests that defines what global method to call when the JSONP content is loaded. 2047 * @property callback 2048 * @type {String} 2049 * @default null 2050 */ 2051 this.callback = null; 2052 2053 /** 2054 * An arbitrary data object, which is included with the loaded object. 2055 * @property data 2056 * @type {Object} 2057 * @default null 2058 */ 2059 this.data = null; 2060 2061 /** 2062 * The request method used for HTTP calls. Both {{#crossLink "AbstractLoader/GET:property"}}{{/crossLink}} or 2063 * {{#crossLink "AbstractLoader/POST:property"}}{{/crossLink}} request types are supported, and are defined as 2064 * constants on {{#crossLink "AbstractLoader"}}{{/crossLink}}. 2065 * @property method 2066 * @type {String} 2067 * @default get 2068 */ 2069 this.method = createjs.LoadItem.GET; 2070 2071 /** 2072 * An object hash of name/value pairs to send to the server. 2073 * @property values 2074 * @type {Object} 2075 * @default null 2076 */ 2077 this.values = null; 2078 2079 /** 2080 * An object hash of headers to attach to an XHR request. PreloadJS will automatically attach some default 2081 * headers when required, including "Origin", "Content-Type", and "X-Requested-With". You may override the 2082 * default headers by including them in your headers object. 2083 * @property headers 2084 * @type {Object} 2085 * @default null 2086 */ 2087 this.headers = null; 2088 2089 /** 2090 * Enable credentials for XHR requests. 2091 * @property withCredentials 2092 * @type {Boolean} 2093 * @default false 2094 */ 2095 this.withCredentials = false; 2096 2097 /** 2098 * Set the mime type of XHR-based requests. This is automatically set to "text/plain; charset=utf-8" for text 2099 * based files (json, xml, text, css, js). 2100 * @property mimeType 2101 * @type {String} 2102 * @default null 2103 */ 2104 this.mimeType = null; 2105 2106 /** 2107 * Sets the crossOrigin attribute for CORS-enabled images loading cross-domain. 2108 * @property crossOrigin 2109 * @type {boolean} 2110 * @default Anonymous 2111 */ 2112 this.crossOrigin = null; 2113 2114 /** 2115 * The duration in milliseconds to wait before a request times out. This only applies to tag-based and and XHR 2116 * (level one) loading, as XHR (level 2) provides its own timeout event. 2117 * @property loadTimeout 2118 * @type {Number} 2119 * @default 8000 (8 seconds) 2120 */ 2121 this.loadTimeout = s.LOAD_TIMEOUT_DEFAULT; 2122 }; 2123 2124 var p = LoadItem.prototype = {}; 2125 var s = LoadItem; 2126 2127 /** 2128 * Default duration in milliseconds to wait before a request times out. This only applies to tag-based and and XHR 2129 * (level one) loading, as XHR (level 2) provides its own timeout event. 2130 * @property LOAD_TIMEOUT_DEFAULT 2131 * @type {number} 2132 * @static 2133 */ 2134 s.LOAD_TIMEOUT_DEFAULT = 8000; 2135 2136 /** 2137 * Create a LoadItem. 2138 * <ul> 2139 * <li>String-based items are converted to a LoadItem with a populated {{#crossLink "src:property"}}{{/crossLink}}.</li> 2140 * <li>LoadItem instances are returned as-is</li> 2141 * <li>Objects are returned with any needed properties added</li> 2142 * </ul> 2143 * @method create 2144 * @param {LoadItem|String|Object} value The load item value 2145 * @returns {LoadItem|Object} 2146 * @static 2147 */ 2148 s.create = function (value) { 2149 if (typeof value == "string") { 2150 var item = new LoadItem(); 2151 item.src = value; 2152 return item; 2153 } else if (value instanceof s) { 2154 return value; 2155 } else if (value instanceof Object && value.src) { 2156 if (value.loadTimeout == null) { 2157 value.loadTimeout = s.LOAD_TIMEOUT_DEFAULT; 2158 } 2159 return value; 2160 } else { 2161 throw new Error("Type not recognized."); 2162 } 2163 }; 2164 2165 /** 2166 * Provides a chainable shortcut method for setting a number of properties on the instance. 2167 * 2168 * <h4>Example</h4> 2169 * 2170 * var loadItem = new createjs.LoadItem().set({src:"image.png", maintainOrder:true}); 2171 * 2172 * @method set 2173 * @param {Object}
2173 props A generic object containing properties to copy to the LoadItem instance. 2174 * @return {LoadItem} Returns the instance the method is called on (useful for chaining calls.) 2175 */ 2176 p.set = function(props) { 2177 for (var n in props) { this[n] = props[n]; } 2178 return this; 2179 }; 2180 2181 createjs.LoadItem = s; 2182 2183}()); 2184 2185//############################################################################## 2186// RequestUtils.js 2187//############################################################################## 2188 2189(function () { 2190 2191 /** 2192 * Utilities that assist with parsing load items, and determining file types, etc. 2193 * @class RequestUtils 2194 */ 2195 var s = {}; 2196 2197 /** 2198 * The Regular Expression used to test file URLS for an absolute path. 2199 * @property ABSOLUTE_PATH 2200 * @type {RegExp} 2201 * @static 2202 */ 2203 s.ABSOLUTE_PATT = /^(?:\w+:)?\/{2}/i; 2204 2205 /** 2206 * The Regular Expression used to test file URLS for a relative path. 2207 * @property RELATIVE_PATH 2208 * @type {RegExp} 2209 * @static 2210 */ 2211 s.RELATIVE_PATT = (/^[./]*?\//i); 2212 2213 /** 2214 * The Regular Expression used to test file URLS for an extension. Note that URIs must already have the query string 2215 * removed. 2216 * @property EXTENSION_PATT 2217 * @type {RegExp} 2218 * @static 2219 */ 2220 s.EXTENSION_PATT = /\/?[^/]+\.(\w{1,5})$/i; 2221 2222 /** 2223 * Parse a file path to determine the information we need to work with it. Currently, PreloadJS needs to know: 2224 * <ul> 2225 * <li>If the path is absolute. Absolute paths start with a protocol (such as `http://`, `file://`, or 2226 * `//networkPath`)</li> 2227 * <li>If the path is relative. Relative paths start with `../` or `/path` (or similar)</li> 2228 * <li>The file extension. This is determined by the filename with an extension. Query strings are dropped, and 2229 * the file path is expected to follow the format `name.ext`.</li> 2230 * </ul> 2231 * @method parseURI 2232 * @param {String} path 2233 * @returns {Object} An Object with an `absolute` and `relative` Boolean values, as well as an optional 'extension` 2234 * property, which is the lowercase extension. 2235 * @static 2236 */ 2237 s.parseURI = function (path) { 2238 var info = {absolute: false, relative: false}; 2239 if (path == null) { return info; } 2240 2241 // Drop the query string 2242 var queryIndex = path.indexOf("?"); 2243 if (queryIndex > -1) { 2244 path = path.substr(0, queryIndex); 2245 } 2246 2247 // Absolute 2248 var match; 2249 if (s.ABSOLUTE_PATT.test(path)) { 2250 info.absolute = true; 2251 2252 // Relative 2253 } else if (s.RELATIVE_PATT.test(path)) { 2254 info.relative = true; 2255 } 2256 2257 // Extension 2258 if (match = path.match(s.EXTENSION_PATT)) { 2259 info.extension = match[1].toLowerCase(); 2260 } 2261 return info; 2262 }; 2263 2264 /** 2265 * Formats an object into a query string for either a POST or GET request. 2266 * @method formatQueryString 2267 * @param {Object} data The data to convert to a query string. 2268 * @param {Array} [query] Existing name/value pairs to append on to this query. 2269 * @static 2270 */ 2271 s.formatQueryString = function (data, query) { 2272 if (data == null) { 2273 throw new Error('You must specify data.'); 2274 } 2275 var params = []; 2276 for (var n in data) { 2277 params.push(n + '=' + escape(data[n])); 2278 } 2279 if (query) { 2280 params = params.concat(query); 2281 } 2282 return params.join('&'); 2283 }; 2284 2285 /** 2286 * A utility method that builds a file path using a source and a data object, and formats it into a new path. 2287 * @method buildPath 2288 * @param {String} src The source path to add values to. 2289 * @param {Object} [data] Object used to append values to this request as a query string. Existing parameters on the 2290 * path will be preserved. 2291 * @returns {string} A formatted string that contains the path and the supplied parameters. 2292 * @static 2293 */ 2294 s.buildPath = function (src, data) { 2295 if (data == null) { 2296 return src; 2297 } 2298 2299 var query = []; 2300 var idx = src.indexOf('?'); 2301 2302 if (idx != -1) { 2303 var q = src.slice(idx + 1); 2304 query = query.concat(q.split('&')); 2305 } 2306 2307 if (idx != -1) { 2308 return src.slice(0, idx) + '?' + this.formatQueryString(data, query); 2309 } else { 2310 return src + '?' + this.formatQueryString(data, query); 2311 } 2312 }; 2313 2314 /** 2315 * @method isCrossDomain 2316 * @param {LoadItem|Object} item A load item with a `src` property. 2317 * @return {Boolean} If the load item is loading from a different domain than the current location. 2318 * @static 2319 */
2320 s.isCrossDomain = function (item) { 2321 var target = document.createElement("a"); 2322 target.href = item.src; 2323 2324 var host = document.createElement("a"); 2325 host.href = location.href; 2326 2327 var crossdomain = (target.hostname != "") && 2328 (target.port != host.port || 2329 target.protocol != host.protocol || 2330 target.hostname != host.hostname); 2331 return crossdomain; 2332 }; 2333 2334 /** 2335 * @method isLocal 2336 * @param {LoadItem|Object} item A load item with a `src` property 2337 * @return {Boolean} If the load item is loading from the "file:" protocol. Assume that the host must be local as 2338 * well. 2339 * @static 2340 */ 2341 s.isLocal = function (item) { 2342 var target = document.createElement("a"); 2343 target.href = item.src; 2344 return target.hostname == "" && target.protocol == "file:"; 2345 }; 2346 2347 /** 2348 * Determine if a specific type should be loaded as a binary file. Currently, only images and items marked 2349 * specifically as "binary" are loaded as binary. Note that audio is <b>not</b> a binary type, as we can not play 2350 * back using an audio tag if it is loaded as binary. Plugins can change the item type to binary to ensure they get 2351 * a binary result to work with. Binary files are loaded using XHR2. Types are defined as static constants on 2352 * {{#crossLink "AbstractLoader"}}{{/crossLink}}. 2353 * @method isBinary 2354 * @param {String} type The item type. 2355 * @return {Boolean} If the specified type is binary. 2356 * @static 2357 */ 2358 s.isBinary = function (type) { 2359 switch (type) { 2360 case createjs.AbstractLoader.IMAGE: 2361 case createjs.AbstractLoader.BINARY: 2362 return true; 2363 default: 2364 return false; 2365 } 2366 }; 2367 2368 /** 2369 * Check if item is a valid HTMLImageElement 2370 * @method isImageTag 2371 * @param {Object} item 2372 * @returns {Boolean} 2373 * @static 2374 */ 2375 s.isImageTag = function(item) { 2376 return item instanceof HTMLImageElement; 2377 }; 2378 2379 /** 2380 * Check if item is a valid HTMLAudioElement 2381 * @method isAudioTag 2382 * @param {Object} item 2383 * @returns {Boolean} 2384 * @static 2385 */ 2386 s.isAudioTag = function(item) { 2387 if (window.HTMLAudioElement) { 2388 return item instanceof HTMLAudioElement; 2389 } else { 2390 return false; 2391 } 2392 }; 2393 2394 /** 2395 * Check if item is a valid HTMLVideoElement 2396 * @method isVideoTag 2397 * @param {Object} item 2398 * @returns {Boolean} 2399 * @static 2400 */ 2401 s.isVideoTag = function(item) { 2402 if (window.HTMLVideoElement) { 2403 return item instanceof HTMLVideoElement; 2404 } else { 2405 return false; 2406 } 2407 }; 2408 2409 /** 2410 * Determine if a specific type is a text-based asset, and should be loaded as UTF-8. 2411 * @method isText 2412 * @param {String} type The item type. 2413 * @return {Boolean} If the specified type is text. 2414 * @static 2415 */ 2416 s.isText = function (type) { 2417 switch (type) { 2418 case createjs.AbstractLoader.TEXT: 2419 case createjs.AbstractLoader.JSON: 2420 case createjs.AbstractLoader.MANIFEST: 2421 case createjs.AbstractLoader.XML: 2422 case createjs.AbstractLoader.CSS: 2423 case createjs.AbstractLoader.SVG: 2424 case createjs.AbstractLoader.JAVASCRIPT: 2425 case createjs.AbstractLoader.SPRITESHEET: 2426 return true; 2427 default: 2428 return false; 2429 } 2430 }; 2431 2432 /** 2433 * Determine the type of the object using common extensions. Note that the type can be passed in with the load item 2434 * if it is an unusual extension. 2435 * @method getTypeByExtension 2436 * @param {String} extension The file extension to use to determine the load type. 2437 * @return {String} The determined load type (for example, <code>AbstractLoader.IMAGE</code>). Will return `null` if 2438 * the type can not be determined by the extension. 2439 * @static 2440 */ 2441 s.getTypeByExtension = function (extension) { 2442 if (extension == null) { 2443 return createjs.AbstractLoader.TEXT; 2444 } 2445 2446 switch (extension.toLowerCase()) { 2447 case "jpeg": 2448 case "jpg": 2449 case "gif": 2450 case "png": 2451 case "webp": 2452 case "bmp": 2453 return createjs.AbstractLoader.IMAGE; 2454 case "ogg": 2455 case "mp3": 2456 case "webm": 2457 return createjs.AbstractLoader.SOUND; 2458 case "mp4": 2459 case "webm": 2460 case "ts": 2461 return createjs.AbstractLoader.VIDEO; 2462 case "json": 2463 return createjs.AbstractLoader.JSON; 2464 case "xml": 2465 return createjs.AbstractLoader.XML; 2466 case "css": 2467 return createjs.AbstractLoader.CSS; 2468 case "js":
2469 return createjs.AbstractLoader.JAVASCRIPT; 2470 case 'svg': 2471 return createjs.AbstractLoader.SVG; 2472 default: 2473 return createjs.AbstractLoader.TEXT; 2474 } 2475 }; 2476 2477 createjs.RequestUtils = s; 2478 2479}()); 2480 2481//############################################################################## 2482// AbstractLoader.js 2483//############################################################################## 2484 2485this.createjs = this.createjs || {}; 2486 2487(function () { 2488 "use strict"; 2489 2490// constructor 2491 /** 2492 * The base loader, which defines all the generic methods, properties, and events. All loaders extend this class, 2493 * including the {{#crossLink "LoadQueue"}}{{/crossLink}}. 2494 * @class AbstractLoader 2495 * @param {LoadItem|object|string} loadItem The item to be loaded. 2496 * @param {Boolean} [preferXHR] Determines if the LoadItem should <em>try</em> and load using XHR, or take a 2497 * tag-based approach, which can be better in cross-domain situations. Not all loaders can load using one or the 2498 * other, so this is a suggested directive. 2499 * @param {String} [type] The type of loader. Loader types are defined as constants on the AbstractLoader class, 2500 * such as {{#crossLink "IMAGE:property"}}{{/crossLink}}, {{#crossLink "CSS:property"}}{{/crossLink}}, etc. 2501 * @extends EventDispatcher 2502 */ 2503 function AbstractLoader(loadItem, preferXHR, type) { 2504 this.EventDispatcher_constructor(); 2505 2506 // public properties 2507 /** 2508 * If the loader has completed loading. This provides a quick check, but also ensures that the different approaches 2509 * used for loading do not pile up resulting in more than one `complete` {{#crossLink "Event"}}{{/crossLink}}. 2510 * @property loaded 2511 * @type {Boolean} 2512 * @default false 2513 */ 2514 this.loaded = false; 2515 2516 /** 2517 * Determine if the loader was canceled. Canceled loads will not fire complete events. Note that this property 2518 * is readonly, so {{#crossLink "LoadQueue"}}{{/crossLink}} queues should be closed using {{#crossLink "LoadQueue/close"}}{{/crossLink}} 2519 * instead. 2520 * @property canceled 2521 * @type {Boolean} 2522 * @default false 2523 * @readonly 2524 */ 2525 this.canceled = false; 2526 2527 /** 2528 * The current load progress (percentage) for this item. This will be a number between 0 and 1. 2529 * 2530 * <h4>Example</h4> 2531 * 2532 * var queue = new createjs.LoadQueue(); 2533 * queue.loadFile("largeImage.png"); 2534 * queue.on("progress", function() { 2535 * console.log("Progress:", queue.progress, event.progress); 2536 * }); 2537 * 2538 * @property progress 2539 * @type {Number} 2540 * @default 0 2541 */ 2542 this.progress = 0; 2543 2544 /** 2545 * The type of item this loader will load. See {{#crossLink "AbstractLoader"}}{{/crossLink}} for a full list of 2546 * supported types. 2547 * @property type 2548 * @type {String} 2549 */ 2550 this.type = type; 2551 2552 /** 2553 * A formatter function that converts the loaded raw result into the final result. For example, the JSONLoader 2554 * converts a string of text into a JavaScript object. Not all loaders have a resultFormatter, and this property 2555 * can be overridden to provide custom formatting. 2556 * 2557 * Optionally, a resultFormatter can return a callback function in cases where the formatting needs to be 2558 * asynchronous, such as creating a new image. The callback function is passed 2 parameters, which are callbacks 2559 * to handle success and error conditions in the resultFormatter. Note that the resultFormatter method is 2560 * called in the current scope, as well as the success and error callbacks. 2561 * 2562 * <h4>Example asynchronous resultFormatter</h4> 2563 * 2564 * function _formatResult(loader) { 2565 * return function(success, error) { 2566 * if (errorCondition) { error(errorDetailEvent); } 2567 * success(result); 2568 * } 2569 * } 2570 * @property resultFormatter 2571 * @type {Function} 2572 * @default null 2573 */ 2574 this.resultFormatter = null; 2575 2576 // protected properties 2577 /** 2578 * The {{#crossLink "LoadItem"}}{{/crossLink}} this loader represents. Note that this is null in a {{#crossLink "LoadQueue"}}{{/crossLink}}, 2579 * but will be available on loaders such as {{#crossLink "XMLLoader"}}{{/crossLink}} and {{#crossLink "ImageLoader"}}{{/crossLink}}. 2580 * @property _item 2581 * @type {LoadItem|Object} 2582 * @private 2583 */ 2584 if (loadItem) { 2585 this._item = createjs.LoadItem.create(loadItem); 2586 } else { 2587 this._item = null; 2588 } 2589 2590 /** 2591 * Whether the loader will try and load content using XHR (true) or HTML tags (false). 2592 * @property _preferXHR 2593 * @type {Boolean} 2594 * @private 2595 */ 2596 this._preferXHR = preferXHR; 2597 2598 /** 2599 * The loaded result after it is formatted by an optional {{#crossLink "resultFormatter"}}{{/crossLink}}. For 2600 * items that are not formatted, this will be the same as the {{#crossLink "_rawResult:property"}}{{/crossLink}}. 2601 * The result is accessed using the {{#crossLink "getResult"}}{{/crossLink}} method. 2602 * @property _result 2603 * @type {Object|String} 2604 * @private 2605 */ 2606 this._result = null; 2607 2608 /** 2609 * The loaded result before it is formatted. The rawResult is accessed using the {{#crossLink "getResult"}}{{/crossLink}} 2610 * method, and passing `true`. 2611 * @property _rawResult 2612 * @type {Object|String} 2613 * @private 2614 */ 2615 this._rawResult = null; 2616 2617 /** 2618 * A list of items that loaders load behind the scenes. This does not include the main item the loader is 2619 * responsible for loading. Examples of loaders that have sub-items include the {{#crossLink "SpriteSheetLoader"}}{{/crossLink}} and 2620 * {{#crossLink "ManifestLoader"}}{{/crossLink}}. 2621 * @property _loadItems 2622 * @type {null} 2623 * @protected 2624 */ 2625 this._loadedItems = null; 2626 2627 /** 2628 * The attribute the items loaded using tags use for the source. 2629 * @type {string} 2630 * @default null 2631 * @private 2632 */ 2633 this._tagSrcAttribute = null; 2634 2635 /** 2636 * An HTML tag (or similar) that a loader may use to load HTML content, such as images, scripts, etc. 2637 * @property _tag 2638 * @type {Object} 2639 * @private 2640 */ 2641 this._tag = null; 2642 }; 2643
2644 var p = createjs.extend(AbstractLoader, createjs.EventDispatcher); 2645 var s = AbstractLoader; 2646 2647 // TODO: deprecated 2648 // p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details. 2649 2650 2651 /** 2652 * Defines a POST request, use for a method value when loading data. 2653 * @property POST 2654 * @type {string} 2655 * @default post 2656 * @static 2657 */ 2658 s.POST = "POST"; 2659 2660 /** 2661 * Defines a GET request, use for a method value when loading data. 2662 * @property GET 2663 * @type {string} 2664 * @default get 2665 * @static 2666 */ 2667 s.GET = "GET"; 2668 2669 /** 2670 * The preload type for generic binary types. Note that images are loaded as binary files when using XHR. 2671 * @property BINARY 2672 * @type {String} 2673 * @default binary 2674 * @static 2675 * @since 0.6.0 2676 */ 2677 s.BINARY = "binary"; 2678 2679 /** 2680 * The preload type for css files. CSS files are loaded using a <link> when loaded with XHR, or a 2681 * <style> tag when loaded with tags. 2682 * @property CSS 2683 * @type {String} 2684 * @default css 2685 * @static 2686 * @since 0.6.0 2687 */ 2688 s.CSS = "css"; 2689 2690 /** 2691 * The preload type for image files, usually png, gif, or jpg/jpeg. Images are loaded into an <image> tag. 2692 * @property IMAGE 2693 * @type {String} 2694 * @default image 2695 * @static 2696 * @since 0.6.0 2697 */ 2698 s.IMAGE = "image"; 2699 2700 /** 2701 * The preload type for javascript files, usually with the "js" file extension. JavaScript files are loaded into a 2702 * <script> tag. 2703 * 2704 * Since version 0.4.1+, due to how tag-loaded scripts work, all JavaScript files are automatically injected into 2705 * the body of the document to maintain parity between XHR and tag-loaded scripts. In version 0.4.0 and earlier, 2706 * only tag-loaded scripts are injected. 2707 * @property JAVASCRIPT 2708 * @type {String} 2709 * @default javascript 2710 * @static 2711 * @since 0.6.0 2712 */ 2713 s.JAVASCRIPT = "javascript"; 2714 2715 /** 2716 * The preload type for json files, usually with the "json" file extension. JSON data is loaded and parsed into a 2717 * JavaScript object. Note that if a `callback` is present on the load item, the file will be loaded with JSONP, 2718 * no matter what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} property is set to, and the JSON 2719 * must contain a matching wrapper function. 2720 * @property JSON 2721 * @type {String} 2722 * @default json 2723 * @static 2724 * @since 0.6.0 2725 */ 2726 s.JSON = "json"; 2727 2728 /** 2729 * The preload type for jsonp files, usually with the "json" file extension. JSON data is loaded and parsed into a 2730 * JavaScript object. You are required to pass a callback parameter that matches the function wrapper in the JSON. 2731 * Note that JSONP will always be used if there is a callback present, no matter what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} 2732 * property is set to. 2733 * @property JSONP 2734 * @type {String} 2735 * @default jsonp 2736 * @static 2737 * @since 0.6.0 2738 */ 2739 s.JSONP = "jsonp"; 2740 2741 /** 2742 * The preload type for json-based manifest files, usually with the "json" file extension. The JSON data is loaded 2743 * and parsed into a JavaScript object. PreloadJS will then look for a "manifest" property in the JSON, which is an 2744 * Array of files to load, following the same format as the {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} 2745 * method. If a "callback" is specified on the manifest object, then it will be loaded using JSONP instead, 2746 * regardless of what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} property is set to. 2747 * @property MANIFEST 2748 * @type {String} 2749 * @default manifest 2750 * @static 2751 * @since 0.6.0 2752 */ 2753 s.MANIFEST = "manifest"; 2754 2755 /** 2756 * The preload type for sound files, usually mp3, ogg, or wav. When loading via tags, audio is loaded into an 2757 * <audio> tag. 2758 * @property SOUND 2759 * @type {String} 2760 * @default sound 2761 * @static 2762 * @since 0.6.0 2763 */ 2764 s.SOUND = "sound"; 2765 2766 /** 2767 * The preload type for video files, usually mp4, ts, or ogg. When loading via tags, video is loaded into an 2768 * <video> tag. 2769 * @property VIDEO 2770 * @type {String} 2771 * @default video 2772 * @static 2773 * @since 0.6.0 2774 */ 2775 s.VIDEO = "video"; 2776 2777 /** 2778 * The preload type for SpriteSheet files. SpriteSheet files are JSON files that contain string image paths. 2779 * @property SPRITESHEET 2780 * @type {String} 2781 * @default spritesheet 2782 * @static 2783 * @since 0.6.0 2784 */ 2785 s.SPRITESHEET = "spritesheet"; 2786 2787 /** 2788 * The preload type for SVG files. 2789 * @property SVG 2790 * @type {String} 2791 * @default svg 2792 * @static 2793 * @since 0.6.0 2794 */ 2795 s.SVG = "svg"; 2796 2797 /** 2798 * The preload type for text files, which is also the default file type if the type can not be determined. Text is 2799 * loaded as raw text. 2800 * @property TEXT 2801 * @type {String} 2802 * @default text 2803 * @static 2804 * @since 0.6.0 2805 */ 2806 s.TEXT = "text"; 2807 2808 /** 2809 * The preload type for xml files. XML is loaded into an XML document. 2810 * @property XML 2811 * @type {String} 2812 * @default xml 2813 * @static 2814 * @since 0.6.0 2815 */ 2816 s.XML = "xml"; 2817 2818// Events 2819 /** 2820 * The {{#crossLink "ProgressEvent"}}{{/crossLink}}
2820 that is fired when the overall progress changes. Prior to 2821 * version 0.6.0, this was just a regular {{#crossLink "Event"}}{{/crossLink}}. 2822 * @event progress 2823 * @since 0.3.0 2824 */ 2825 2826 /** 2827 * The {{#crossLink "Event"}}{{/crossLink}} that is fired when a load starts. 2828 * @event loadstart 2829 * @param {Object} target The object that dispatched the event. 2830 * @param {String} type The event type. 2831 * @since 0.3.1 2832 */ 2833 2834 /** 2835 * The {{#crossLink "Event"}}{{/crossLink}} that is fired when the entire queue has been loaded. 2836 * @event complete 2837 * @param {Object} target The object that dispatched the event. 2838 * @param {String} type The event type. 2839 * @since 0.3.0 2840 */ 2841 2842 /** 2843 * The {{#crossLink "ErrorEvent"}}{{/crossLink}} that is fired when the loader encounters an error. If the error was 2844 * encountered by a file, the event will contain the item that caused the error. Prior to version 0.6.0, this was 2845 * just a regular {{#crossLink "Event"}}{{/crossLink}}. 2846 * @event error 2847 * @since 0.3.0 2848 */ 2849 2850 /** 2851 * The {{#crossLink "Event"}}{{/crossLink}} that is fired when the loader encounters an internal file load error. 2852 * This enables loaders to maintain internal queues, and surface file load errors. 2853 * @event fileerror 2854 * @param {Object} target The object that dispatched the event. 2855 * @param {String} type The even type ("fileerror") 2856 * @param {LoadItem|object} The item that encountered the error 2857 * @since 0.6.0 2858 */ 2859 2860 /** 2861 * The {{#crossLink "Event"}}{{/crossLink}} that is fired when a loader internally loads a file. This enables 2862 * loaders such as {{#crossLink "ManifestLoader"}}{{/crossLink}} to maintain internal {{#crossLink "LoadQueue"}}{{/crossLink}}s 2863 * and notify when they have loaded a file. The {{#crossLink "LoadQueue"}}{{/crossLink}} class dispatches a 2864 * slightly different {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event. 2865 * @event fileload 2866 * @param {Object} target The object that dispatched the event. 2867 * @param {String} type The event type ("fileload") 2868 * @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} 2869 * or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the 2870 * object will contain that value as a `src` property. 2871 * @param {Object} result The HTML tag or parsed result of the loaded item. 2872 * @param {Object} rawResult The unprocessed result, usually the raw text or binary data before it is converted 2873 * to a usable object. 2874 * @since 0.6.0 2875 */ 2876 2877 /** 2878 * The {{#crossLink "Event"}}{{/crossLink}} that is fired after the internal request is created, but before a load. 2879 * This allows updates to the loader for specific loading needs, such as binary or XHR image loading. 2880 * @event initialize 2881 * @param {Object} target The object that dispatched the event. 2882 * @param {String} type The event type ("initialize") 2883 * @param {AbstractLoader} loader The loader that has been initialized. 2884 */ 2885 2886 2887 /** 2888 * Get a reference to the manifest item that is loaded by this loader. In some cases this will be the value that was 2889 * passed into {{#crossLink "LoadQueue"}}{{/crossLink}} using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or 2890 * {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. However if only a String path was passed in, then it will 2891 * be a {{#crossLink "LoadItem"}}{{/crossLink}}. 2892 * @method getItem 2893 * @return {Object} The manifest item that this loader is responsible for loading. 2894 * @since 0.6.0 2895 */ 2896 p.getItem = function () { 2897 return this._item; 2898 }; 2899 2900 /** 2901 * Get a reference to the content that was loaded by the loader (only available after the {{#crossLink "complete:event"}}{{/crossLink}} 2902 * event is dispatched. 2903 * @method getResult 2904 * @param {Boolean} [raw=false] Determines if the returned result will be the formatted content, or the raw loaded 2905 * data (if it exists). 2906 * @return {Object} 2907 * @since 0.6.0 2908 */ 2909 p.getResult = function (raw) { 2910 return raw ? this._rawResult : this._result; 2911 }; 2912 2913 /** 2914 * Return the `tag` this object creates or uses for loading. 2915 * @method getTag 2916 * @return {Object} The tag instance 2917 * @since 0.6.0 2918 */ 2919 p.getTag = function () { 2920 return this._tag; 2921 }; 2922 2923 /** 2924 * Set the `tag` this item uses for loading. 2925 * @method setTag 2926 * @param {Object} tag The tag instance 2927 * @since 0.6.0 2928 */ 2929 p.setTag = function(tag) { 2930 this._tag = tag; 2931 }; 2932 2933 /** 2934 * Begin loading the item. This method is required when using a loader by itself. 2935 * 2936 * <h4>Example</h4> 2937 * 2938 * var queue = new createjs.LoadQueue(); 2939 * queue.on("complete", handleComplete); 2940 * queue.loadManifest(fileArray, false); // Note the 2nd argument that tells the queue not to start loading yet 2941 * queue.load(); 2942 * 2943 * @method load 2944 */ 2945 p.load = function () { 2946 this._createRequest(); 2947 2948 this._request.on("complete", this, this); 2949 this._request.on("progress", this, this); 2950 this._request.on("loadStart", this, this); 2951 this._request.on("abort", this, this); 2952 this._request.on("timeout", this, this); 2953 this._request.on("error", this, this); 2954 2955 var evt = new createjs.Event("initialize"); 2956 evt.loader = this._request; 2957 this.dispatchEvent(evt); 2958 2959 this._request.load(); 2960 }; 2961 2962 /** 2963 * Close the the item. This will stop any open requests (although downloads using HTML tags may still continue in 2964 * the background), but events will not longer be dispatched. 2965 * @method cancel 2966 */ 2967 p.cancel = function () { 2968 this.canceled = true; 2969 this.destroy(); 2970 }; 2971 2972 /** 2973 * Clean up the loader. 2974 * @method destroy 2975 */ 2976 p.destroy = function() { 2977 if (this._request) { 2978 this._request.removeAllEventListeners(); 2979 this._request.destroy(); 2980 } 2981 2982 this._request = null; 2983 2984 this._item = null; 2985 this._rawResult = null; 2986 this._result = null; 2987 2988 this._loadItems = null; 2989 2990 this.removeAllEventListeners(); 2991 }; 2992 2993 /** 2994 * Get any items loaded internally by the loader. The enables loaders such as {{#crossLink "ManifestLoader"}}{{/crossLink}} 2995 * to expose items it loads internally. 2996 * @method getLoadedItems 2997 * @return {Array} A list of the items loaded by the loader. 2998 * @since 0.6.0 2999 */
3000 p.getLoadedItems = function () { 3001 return this._loadedItems; 3002 }; 3003 3004 3005 // Private methods 3006 /** 3007 * Create an internal request used for loading. By default, an {{#crossLink "XHRRequest"}}{{/crossLink}} or 3008 * {{#crossLink "TagRequest"}}{{/crossLink}} is created, depending on the value of {{#crossLink "preferXHR:property"}}{{/crossLink}}. 3009 * Other loaders may override this to use different request types, such as {{#crossLink "ManifestLoader"}}{{/crossLink}}, 3010 * which uses {{#crossLink "JSONLoader"}}{{/crossLink}} or {{#crossLink "JSONPLoader"}}{{/crossLink}} under the hood. 3011 * @method _createRequest 3012 * @protected 3013 */ 3014 p._createRequest = function() { 3015 if (!this._preferXHR) { 3016 this._request = new createjs.TagRequest(this._item, this._tag || this._createTag(), this._tagSrcAttribute); 3017 } else { 3018 this._request = new createjs.XHRRequest(this._item); 3019 } 3020 }; 3021 3022 /** 3023 * Create the HTML tag used for loading. This method does nothing by default, and needs to be implemented 3024 * by loaders that require tag loading. 3025 * @method _createTag 3026 * @param {String} src The tag source 3027 * @return {HTMLElement} The tag that was created 3028 * @protected 3029 */ 3030 p._createTag = function(src) { return null; }; 3031 3032 /** 3033 * Dispatch a loadstart {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/loadstart:event"}}{{/crossLink}} 3034 * event for details on the event payload. 3035 * @method _sendLoadStart 3036 * @protected 3037 */ 3038 p._sendLoadStart = function () { 3039 if (this._isCanceled()) { return; } 3040 this.dispatchEvent("loadstart"); 3041 }; 3042 3043 /** 3044 * Dispatch a {{#crossLink "ProgressEvent"}}{{/crossLink}}. 3045 * @method _sendProgress 3046 * @param {Number | Object} value The progress of the loaded item, or an object containing <code>loaded</code> 3047 * and <code>total</code> properties. 3048 * @protected 3049 */ 3050 p._sendProgress = function (value) { 3051 if (this._isCanceled()) { return; } 3052 var event = null; 3053 if (typeof(value) == "number") { 3054 this.progress = value; 3055 event = new createjs.ProgressEvent(this.progress); 3056 } else { 3057 event = value; 3058 this.progress = value.loaded / value.total; 3059 event.progress = this.progress; 3060 if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; } 3061 } 3062 this.hasEventListener("progress") && this.dispatchEvent(event); 3063 }; 3064 3065 /** 3066 * Dispatch a complete {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} event 3067 * @method _sendComplete 3068 * @protected 3069 */ 3070 p._sendComplete = function () { 3071 if (this._isCanceled()) { return; } 3072 3073 this.loaded = true; 3074 3075 var event = new createjs.Event("complete"); 3076 event.rawResult = this._rawResult; 3077 3078 if (this._result != null) { 3079 event.result = this._result; 3080 } 3081 3082 this.dispatchEvent(event); 3083 }; 3084 3085 /** 3086 * Dispatch an error {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/error:event"}}{{/crossLink}} 3087 * event for details on the event payload. 3088 * @method _sendError 3089 * @param {ErrorEvent} event The event object containing specific error properties. 3090 * @protected 3091 */ 3092 p._sendError = function (event) { 3093 if (this._isCanceled() || !this.hasEventListener("error")) { return; } 3094 if (event == null) { 3095 event = new createjs.ErrorEvent("PRELOAD_ERROR_EMPTY"); // TODO: Populate error 3096 } 3097 this.dispatchEvent(event); 3098 }; 3099 3100 /** 3101 * Determine if the load has been canceled. This is important to ensure that method calls or asynchronous events 3102 * do not cause issues after the queue has been cleaned up. 3103 * @method _isCanceled 3104 * @return {Boolean} If the loader has been canceled. 3105 * @protected 3106 */ 3107 p._isCanceled = function () { 3108 if (window.createjs == null || this.canceled) { 3109 return true; 3110 } 3111 return false; 3112 }; 3113 3114 /** 3115 * A custom result formatter function, which is called just before a request dispatches its complete event. Most 3116 * loader types already have an internal formatter, but this can be user-overridden for custom formatting. The 3117 * formatted result will be available on Loaders using {{#crossLink "getResult"}}{{/crossLink}}, and passing `true`. 3118 * @property resultFormatter 3119 * @type Function 3120 * @return {Object} The formatted result 3121 * @since 0.6.0 3122 */ 3123 p.resultFormatter = null; 3124 3125 /** 3126 * Handle events from internal requests. By default, loaders will handle, and redispatch the necessary events, but 3127 * this method can be overridden for custom behaviours. 3128 * @method handleEvent 3129 * @param {Event} event The event that the internal request dispatches. 3130 * @protected 3131 * @since 0.6.0 3132 */ 3133 p.handleEvent = function (event) { 3134 switch (event.type) { 3135 case "complete": 3136 this._rawResult = event.target._response; 3137 var result = this.resultFormatter && this.resultFormatter(this); 3138 if (result instanceof Function) { 3139 result.call(this, 3140 createjs.proxy(this._resultFormatSuccess, this), 3141 createjs.proxy(this._resultFormatFailed, this) 3142 ); 3143 } else { 3144 this._result = result || this._rawResult; 3145 this._sendComplete(); 3146 } 3147 break; 3148 case "progress": 3149 this._sendProgress(event); 3150 break; 3151 case "error": 3152 this._sendError(event); 3153 break; 3154 case "loadstart": 3155 this._sendLoadStart(); 3156 break; 3157 case "abort": 3158 case "timeout": 3159 if (!this._isCanceled()) { 3160 this.dispatchEvent(new createjs.ErrorEvent("PRELOAD_" + event.type.toUpperCase() + "_ERROR")); 3161 } 3162 break; 3163 } 3164 }; 3165 3166 /** 3167 * The "success" callback passed to {{#crossLink "AbstractLoader/resultFormatter"}}{{/crossLink}} asynchronous 3168 * functions. 3169 * @method _resultFormatSuccess 3170 * @param {Object} result The formatted result 3171 * @private 3172 */ 3173 p._resultFormatSuccess = function (result) { 3174 this._result = result; 3175 this._sendComplete(); 3176 }; 3177 3178 /** 3179 * The "error" callback passed to {{#crossLink "AbstractLoader/resultFormatter"}}{{/crossLink}} asynchronous 3180 * functions. 3181 * @method _resultFormatSuccess 3182 * @param {Object} error The error event 3183 * @private 3184 */ 3185 p._resultFormatFailed = function (event) { 3186 this._sendError(event); 3187 }; 3188 3189 /** 3190 * @method buildPath 3191 * @protected 3192 * @deprecated Use the {{#crossLink "RequestUtils"}}{{/crossLink}} method {{#crossLink "RequestUtils/buildPath"}}{{/crossLink}} 3193 * instead. 3194 */ 3195 p.buildPath = function (src, data) { 3196 return createjs.RequestUtils.buildPath(src, data); 3197 }; 3198 3199 /** 3200 * @method toString 3201 * @return {String} a string representation of the instance. 3202 */ 3203 p.toString = function () { 3204 return "[PreloadJS AbstractLoader]"; 3205 }; 3206 3207 createjs.AbstractLoader = createjs.promote(AbstractLoader, "EventDispatcher"); 3208 3209}()); 3210 3211//############################################################################## 3212// AbstractMediaLoader.js 3213//############################################################################## 3214 3215this.createjs = this.createjs || {}; 3216 3217(function () { 3218 "use strict"; 3219 3220 // constructor 3221 /** 3222 * The AbstractMediaLoader is a base class that handles some of the shared methods and properties of loaders that 3223 * handle HTML media elements, such as Video and Audio. 3224 * @class AbstractMediaLoader 3225 * @param {LoadItem|Object} loadItem 3226 * @param {Boolean} preferXHR 3227 * @param {String} type The type of media to load. Usually "video" or "audio". 3228 * @extends AbstractLoader 3229 * @constructor 3230 */ 3231 function AbstractMediaLoader(loadItem, preferXHR, type) { 3232 this.AbstractLoader_constructor(loadItem, preferXHR, type); 3233 3234 // public properties 3235 this.resultFormatter = this._formatResult; 3236 3237 // protected properties 3238 this._tagSrcAttribute = "src"; 3239 3240 this.on("initialize", this._updateXHR, this); 3241 }; 3242
3243 var p = createjs.extend(AbstractMediaLoader, createjs.AbstractLoader); 3244 3245 // static properties 3246 // public methods 3247 p.load = function () { 3248 // TagRequest will handle most of this, but Sound / Video need a few custom properties, so just handle them here. 3249 if (!this._tag) { 3250 this._tag = this._createTag(this._item.src); 3251 } 3252 3253 this._tag.preload = "auto"; 3254 this._tag.load(); 3255 3256 this.AbstractLoader_load(); 3257 }; 3258 3259 // protected methods 3260 /** 3261 * Creates a new tag for loading if it doesn't exist yet. 3262 * @method _createTag 3263 * @private 3264 */ 3265 p._createTag = function () {}; 3266 3267 3268 p._createRequest = function() { 3269 if (!this._preferXHR) { 3270 this._request = new createjs.MediaTagRequest(this._item, this._tag || this._createTag(), this._tagSrcAttribute); 3271 } else { 3272 this._request = new createjs.XHRRequest(this._item); 3273 } 3274 }; 3275 3276 // protected methods 3277 /** 3278 * Before the item loads, set its mimeType and responseType. 3279 * @property _updateXHR 3280 * @param {Event} event 3281 * @private 3282 */ 3283 p._updateXHR = function (event) { 3284 // Only exists for XHR 3285 if (event.loader.setResponseType) { 3286 event.loader.setResponseType("blob"); 3287 } 3288 }; 3289 3290 /** 3291 * The result formatter for media files. 3292 * @method _formatResult 3293 * @param {AbstractLoader} loader 3294 * @returns {HTMLVideoElement|HTMLAudioElement} 3295 * @private 3296 */ 3297 p._formatResult = function (loader) { 3298 this._tag.removeEventListener && this._tag.removeEventListener("canplaythrough", this._loadedHandler); 3299 this._tag.onstalled = null; 3300 if (this._preferXHR) { 3301 var URL = window.URL || window.webkitURL; 3302 var result = loader.getResult(true); 3303 3304 loader.getTag().src = URL.createObjectURL(result); 3305 } 3306 return loader.getTag(); 3307 }; 3308 3309 createjs.AbstractMediaLoader = createjs.promote(AbstractMediaLoader, "AbstractLoader"); 3310 3311}()); 3312 3313//############################################################################## 3314// AbstractRequest.js 3315//############################################################################## 3316 3317this.createjs = this.createjs || {}; 3318 3319(function () { 3320 "use strict"; 3321 3322 /** 3323 * A base class for actual data requests, such as {{#crossLink "XHRRequest"}}{{/crossLink}}, {{#crossLink "TagRequest"}}{{/crossLink}}, 3324 * and {{#crossLink "MediaRequest"}}{{/crossLink}}. PreloadJS loaders will typically use a data loader under the 3325 * hood to get data. 3326 * @class AbstractRequest 3327 * @param {LoadItem} item 3328 * @constructor 3329 */ 3330 var AbstractRequest = function (item) { 3331 this._item = item; 3332 }; 3333 3334 var p = createjs.extend(AbstractRequest, createjs.EventDispatcher); 3335 3336 // public methods 3337 /** 3338 * Begin a load. 3339 * @method load 3340 */ 3341 p.load = function() {}; 3342 3343 /** 3344 * Clean up a request. 3345 * @method destroy 3346 */ 3347 p.destroy = function() {}; 3348 3349 /** 3350 * Cancel an in-progress request. 3351 * @method cancel 3352 */ 3353 p.cancel = function() {}; 3354 3355 createjs.AbstractRequest = createjs.promote(AbstractRequest, "EventDispatcher"); 3356 3357}()); 3358 3359//############################################################################## 3360// TagRequest.js 3361//############################################################################## 3362 3363this.createjs = this.createjs || {}; 3364 3365(function () { 3366 "use strict"; 3367 3368 // constructor 3369 /** 3370 * An {{#crossLink "AbstractRequest"}}{{/crossLink}} that loads HTML tags, such as images and scripts. 3371 * @class TagRequest 3372 * @param {LoadItem} loadItem 3373 * @param {HTMLElement} tag 3374 * @param {String} srcAttribute The tag attribute that specifies the source, such as "src", "href", etc. 3375 */ 3376 function TagRequest(loadItem, tag, srcAttribute) { 3377 this.AbstractRequest_constructor(loadItem); 3378 3379 // protected properties 3380 /** 3381 * The HTML tag instance that is used to load. 3382 * @property _tag 3383 * @type {HTMLElement} 3384 * @protected 3385 */ 3386 this._tag = tag; 3387 3388 /** 3389 * The tag attribute that specifies the source, such as "src", "href", etc. 3390 * @property _tagSrcAttribute 3391 * @type {String} 3392 * @protected 3393 */ 3394 this._tagSrcAttribute = srcAttribute; 3395 3396 /** 3397 * A method closure used for handling the tag load event. 3398 * @property _loadedHandler 3399 * @type {Function} 3400 * @private 3401 */
3402 this._loadedHandler = createjs.proxy(this._handleTagComplete, this); 3403 3404 /** 3405 * Determines if the element was added to the DOM automatically by PreloadJS, so it can be cleaned up after. 3406 * @property _addedToDOM 3407 * @type {Boolean} 3408 * @private 3409 */ 3410 this._addedToDOM = false; 3411 3412 /** 3413 * Determines what the tags initial style.visibility was, so we can set it correctly after a load. 3414 * 3415 * @type {null} 3416 * @private 3417 */ 3418 this._startTagVisibility = null; 3419 }; 3420 3421 var p = createjs.extend(TagRequest, createjs.AbstractRequest); 3422 3423 // public methods 3424 p.load = function () { 3425 this._tag.onload = createjs.proxy(this._handleTagComplete, this); 3426 this._tag.onreadystatechange = createjs.proxy(this._handleReadyStateChange, this); 3427 this._tag.onerror = createjs.proxy(this._handleError, this); 3428 3429 var evt = new createjs.Event("initialize"); 3430 evt.loader = this._tag; 3431 3432 this.dispatchEvent(evt); 3433 3434 this._hideTag(); 3435 3436 this._loadTimeout = setTimeout(createjs.proxy(this._handleTimeout, this), this._item.loadTimeout); 3437 3438 this._tag[this._tagSrcAttribute] = this._item.src; 3439 3440 // wdg:: Append the tag AFTER setting the src, or SVG loading on iOS will fail. 3441 if (this._tag.parentNode == null) { 3442 window.document.body.appendChild(this._tag); 3443 this._addedToDOM = true; 3444 } 3445 }; 3446 3447 p.destroy = function() { 3448 this._clean(); 3449 this._tag = null; 3450 3451 this.AbstractRequest_destroy(); 3452 }; 3453 3454 // private methods 3455 /** 3456 * Handle the readyStateChange event from a tag. We need this in place of the `onload` callback (mainly SCRIPT 3457 * and LINK tags), but other cases may exist. 3458 * @method _handleReadyStateChange 3459 * @private 3460 */ 3461 p._handleReadyStateChange = function () { 3462 clearTimeout(this._loadTimeout); 3463 // This is strictly for tags in browsers that do not support onload. 3464 var tag = this._tag; 3465 3466 // Complete is for old IE support. 3467 if (tag.readyState == "loaded" || tag.readyState == "complete") { 3468 this._handleTagComplete(); 3469 } 3470 }; 3471 3472 /** 3473 * Handle any error events from the tag. 3474 * @method _handleError 3475 * @protected 3476 */ 3477 p._handleError = function() { 3478 this._clean(); 3479 this.dispatchEvent("error"); 3480 }; 3481 3482 /** 3483 * Handle the tag's onload callback. 3484 * @method _handleTagComplete 3485 * @private 3486 */ 3487 p._handleTagComplete = function () { 3488 this._rawResult = this._tag; 3489 this._result = this.resultFormatter && this.resultFormatter(this) || this._rawResult; 3490 3491 this._clean(); 3492 this._showTag(); 3493 3494 this.dispatchEvent("complete"); 3495 }; 3496 3497 /** 3498 * The tag request has not loaded within the time specified in loadTimeout. 3499 * @method _handleError 3500 * @param {Object} event The XHR error event. 3501 * @private 3502 */ 3503 p._handleTimeout = function () { 3504 this._clean(); 3505 this.dispatchEvent(new createjs.Event("timeout")); 3506 }; 3507 3508 /** 3509 * Remove event listeners, but don't destroy the request object 3510 * @method _clean 3511 * @private 3512 */ 3513 p._clean = function() { 3514 this._tag.onload = null; 3515 this._tag.onreadystatechange = null; 3516 this._tag.onerror = null; 3517 if (this._addedToDOM && this._tag.parentNode != null) { 3518 this._tag.parentNode.removeChild(this._tag); 3519 } 3520 clearTimeout(this._loadTimeout); 3521 }; 3522 3523 p._hideTag = function() { 3524 this._startTagVisibility = this._tag.style.visibility; 3525 this._tag.style.visibility = "hidden"; 3526 }; 3527 3528 p._showTag = function() { 3529 this._tag.style.visibility = this._startTagVisibility; 3530 }; 3531 3532 /** 3533 * Handle a stalled audio event. The main place this happens is with HTMLAudio in Chrome when playing back audio 3534 * that is already in a load, but not complete. 3535 * @method _handleStalled 3536 * @private 3537 */ 3538 p._handleStalled = function () { 3539 //Ignore, let the timeout take care of it. Sometimes its not really stopped. 3540 }; 3541 3542 createjs.TagRequest = createjs.promote(TagRequest, "AbstractRequest"); 3543 3544}()); 3545 3546//############################################################################## 3547// MediaTagRequest.js 3548//############################################################################## 3549 3550this.createjs = this.createjs || {}; 3551 3552(function () { 3553 "use strict"; 3554 3555 // constructor 3556 /** 3557 * An {{#crossLink "TagRequest"}}{{/crossLink}} that loads HTML tags for video and audio. 3558 * @class MediaTagRequest 3559 * @param {LoadItem} loadItem 3560 * @param {HTMLAudioElement|HTMLVideoElement} tag 3561 * @param {String} srcAttribute The tag attribute that specifies the source, such as "src", "href", etc. 3562 * @constructor 3563 */ 3564 function MediaTagRequest(loadItem, tag, srcAttribute) {
3565 this.AbstractRequest_constructor(loadItem); 3566 3567 // protected properties 3568 this._tag = tag; 3569 this._tagSrcAttribute = srcAttribute; 3570 this._loadedHandler = createjs.proxy(this._handleTagComplete, this); 3571 }; 3572 3573 var p = createjs.extend(MediaTagRequest, createjs.TagRequest); 3574 var s = MediaTagRequest; 3575 3576 // public methods 3577 p.load = function () { 3578 var sc = createjs.proxy(this._handleStalled, this); 3579 this._stalledCallback = sc; 3580 3581 var pc = createjs.proxy(this._handleProgress, this); 3582 this._handleProgress = pc; 3583 3584 this._tag.addEventListener("stalled", sc); 3585 this._tag.addEventListener("progress", pc); 3586 3587 // This will tell us when audio is buffered enough to play through, but not when its loaded. 3588 // The tag doesn't keep loading in Chrome once enough has buffered, and we have decided that behaviour is sufficient. 3589 this._tag.addEventListener && this._tag.addEventListener("canplaythrough", this._loadedHandler, false); // canplaythrough callback doesn't work in Chrome, so we use an event. 3590 3591 this.TagRequest_load(); 3592 }; 3593 3594 // private methods 3595 p._handleReadyStateChange = function () { 3596 clearTimeout(this._loadTimeout); 3597 // This is strictly for tags in browsers that do not support onload. 3598 var tag = this._tag; 3599 3600 // Complete is for old IE support. 3601 if (tag.readyState == "loaded" || tag.readyState == "complete") { 3602 this._handleTagComplete(); 3603 } 3604 }; 3605 3606 p._handleStalled = function () { 3607 //Ignore, let the timeout take care of it. Sometimes its not really stopped. 3608 }; 3609 3610 /** 3611 * An XHR request has reported progress. 3612 * @method _handleProgress 3613 * @param {Object} event The XHR progress event. 3614 * @private 3615 */ 3616 p._handleProgress = function (event) { 3617 if (!event || event.loaded > 0 && event.total == 0) { 3618 return; // Sometimes we get no "total", so just ignore the progress event. 3619 } 3620 3621 var newEvent = new createjs.ProgressEvent(event.loaded, event.total); 3622 this.dispatchEvent(newEvent); 3623 }; 3624 3625 // protected methods 3626 p._clean = function () { 3627 this._tag.removeEventListener && this._tag.removeEventListener("canplaythrough", this._loadedHandler); 3628 this._tag.removeEventListener("stalled", this._stalledCallback); 3629 this._tag.removeEventListener("progress", this._progressCallback); 3630 3631 this.TagRequest__clean(); 3632 }; 3633 3634 createjs.MediaTagRequest = createjs.promote(MediaTagRequest, "TagRequest"); 3635 3636}()); 3637 3638//############################################################################## 3639// XHRRequest.js 3640//############################################################################## 3641 3642this.createjs = this.createjs || {}; 3643 3644(function () { 3645 "use strict"; 3646 3647// constructor 3648 /** 3649 * A preloader that loads items using XHR requests, usually XMLHttpRequest. However XDomainRequests will be used 3650 * for cross-domain requests if possible, and older versions of IE fall back on to ActiveX objects when necessary. 3651 * XHR requests load the content as text or binary data, provide progress and consistent completion events, and 3652 * can be canceled during load. Note that XHR is not supported in IE 6 or earlier, and is not recommended for 3653 * cross-domain loading. 3654 * @class XHRRequest 3655 * @constructor 3656 * @param {Object} item The object that defines the file to load. Please see the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} 3657 * for an overview of supported file properties. 3658 * @extends AbstractLoader 3659 */ 3660 function XHRRequest (item) { 3661 this.AbstractRequest_constructor(item); 3662 3663 // protected properties 3664 /** 3665 * A reference to the XHR request used to load the content. 3666 * @property _request 3667 * @type {XMLHttpRequest | XDomainRequest | ActiveX.XMLHTTP} 3668 * @private 3669 */ 3670 this._request = null; 3671 3672 /** 3673 * A manual load timeout that is used for browsers that do not support the onTimeout event on XHR (XHR level 1, 3674 * typically IE9). 3675 * @property _loadTimeout 3676 * @type {Number} 3677 * @private 3678 */ 3679 this._loadTimeout = null; 3680 3681 /** 3682 * The browser's XHR (XMLHTTPRequest) version. Supported versions are 1 and 2. There is no official way to detect 3683 * the version, so we use capabilities to make a best guess. 3684 * @property _xhrLevel 3685 * @type {Number} 3686 * @default 1 3687 * @private 3688 */ 3689 this._xhrLevel = 1; 3690 3691 /** 3692 * The response of a loaded file. This is set because it is expensive to look up constantly. This property will be 3693 * null until the file is loaded. 3694 * @property _response 3695 * @type {mixed} 3696 * @private 3697 */ 3698 this._response = null; 3699 3700 /** 3701 * The response of the loaded file before it is modified. In most cases, content is converted from raw text to 3702 * an HTML tag or a formatted object which is set to the <code>result</code> property, but the developer may still 3703 * want to access the raw content as it was loaded. 3704 * @property _rawResponse 3705 * @type {String|Object} 3706 * @private 3707 */ 3708 this._rawResponse = null; 3709 3710 this._canceled = false;
3711 3712 // Setup our event handlers now. 3713 this._handleLoadStartProxy = createjs.proxy(this._handleLoadStart, this); 3714 this._handleProgressProxy = createjs.proxy(this._handleProgress, this); 3715 this._handleAbortProxy = createjs.proxy(this._handleAbort, this); 3716 this._handleErrorProxy = createjs.proxy(this._handleError, this); 3717 this._handleTimeoutProxy = createjs.proxy(this._handleTimeout, this); 3718 this._handleLoadProxy = createjs.proxy(this._handleLoad, this); 3719 this._handleReadyStateChangeProxy = createjs.proxy(this._handleReadyStateChange, this); 3720 3721 if (!this._createXHR(item)) { 3722 //TODO: Throw error? 3723 } 3724 }; 3725 3726 var p = createjs.extend(XHRRequest, createjs.AbstractRequest); 3727 3728// static properties 3729 /** 3730 * A list of XMLHTTP object IDs to try when building an ActiveX object for XHR requests in earlier versions of IE. 3731 * @property ACTIVEX_VERSIONS 3732 * @type {Array} 3733 * @since 0.4.2 3734 * @private 3735 */ 3736 XHRRequest.ACTIVEX_VERSIONS = [ 3737 "Msxml2.XMLHTTP.6.0", 3738 "Msxml2.XMLHTTP.5.0", 3739 "Msxml2.XMLHTTP.4.0", 3740 "MSXML2.XMLHTTP.3.0", 3741 "MSXML2.XMLHTTP", 3742 "Microsoft.XMLHTTP" 3743 ]; 3744 3745// Public methods 3746 /** 3747 * Look up the loaded result. 3748 * @method getResult 3749 * @param {Boolean} [raw=false] Return a raw result instead of a formatted result. This applies to content 3750 * loaded via XHR such as scripts, XML, CSS, and Images. If there is no raw result, the formatted result will be 3751 * returned instead. 3752 * @return {Object} A result object containing the content that was loaded, such as: 3753 * <ul> 3754 * <li>An image tag (<image />) for images</li> 3755 * <li>A script tag for JavaScript (<script />). Note that scripts loaded with tags may be added to the 3756 * HTML head.</li> 3757 * <li>A style tag for CSS (<style />)</li> 3758 * <li>Raw text for TEXT</li> 3759 * <li>A formatted JavaScript object defined by JSON</li> 3760 * <li>An XML document</li> 3761 * <li>An binary arraybuffer loaded by XHR</li> 3762 * </ul> 3763 * Note that if a raw result is requested, but not found, the result will be returned instead. 3764 */ 3765 p.getResult = function (raw) { 3766 if (raw && this._rawResponse) { 3767 return this._rawResponse; 3768 } 3769 return this._response; 3770 }; 3771 3772 // Overrides abstract method in AbstractRequest 3773 p.cancel = function () { 3774 this.canceled = true; 3775 this._clean(); 3776 this._request.abort(); 3777 }; 3778 3779 // Overrides abstract method in AbstractLoader 3780 p.load = function () { 3781 if (this._request == null) { 3782 this._handleError(); 3783 return; 3784 } 3785 3786 //Events 3787 if (this._request.addEventListener != null) { 3788 this._request.addEventListener("loadstart", this._handleLoadStartProxy, false); 3789 this._request.addEventListener("progress", this._handleProgressProxy, false); 3790 this._request.addEventListener("abort", this._handleAbortProxy, false); 3791 this._request.addEventListener("error", this._handleErrorProxy, false); 3792 this._request.addEventListener("timeout", this._handleTimeoutProxy, false); 3793 3794 // Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these. 3795 this._request.addEventListener("load", this._handleLoadProxy, false); 3796 this._request.addEventListener("readystatechange", this._handleReadyStateChangeProxy, false); 3797 } else { 3798 // IE9 support 3799 this._request.onloadstart = this._handleLoadStartProxy; 3800 this._request.onprogress = this._handleProgressProxy; 3801 this._request.onabort = this._handleAbortProxy; 3802 this._request.onerror = this._handleErrorProxy; 3803 this._request.ontimeout = this._handleTimeoutProxy; 3804 3805 // Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these. 3806 this._request.onload = this._handleLoadProxy; 3807 this._request.onreadystatechange = this._handleReadyStateChangeProxy; 3808 } 3809 3810 // Set up a timeout if we don't have XHR2 3811 if (this._xhrLevel == 1) { 3812 this._loadTimeout = setTimeout(createjs.proxy(this._handleTimeout, this), this._item.loadTimeout); 3813 } 3814 3815 // Sometimes we get back 404s immediately, particularly when there is a cross origin request. // note this does not catch in Chrome 3816 try { 3817 if (!this._item.values || this._item.method == createjs.AbstractLoader.GET) { 3818 this._request.send(); 3819 } else if (this._item.method == createjs.AbstractLoader.POST) { 3820 this._request.send(createjs.RequestUtils.formatQueryString(this._item.values)); 3821 } 3822 } catch (error) { 3823 this.dispatchEvent(new createjs.ErrorEvent("XHR_SEND", null, error)); 3824 } 3825 }; 3826 3827 p.setResponseType = function (type) { 3828 // Some old browsers doesn't support blob, so we convert arraybuffer to blob after response is downloaded 3829 if (type === 'blob') { 3830 type = window.URL ? 'blob' : 'arraybuffer'; 3831 this._responseType = type; 3832 } 3833 this._request.responseType = type; 3834 }; 3835 3836 /** 3837 * Get all the response headers from the XmlHttpRequest. 3838 * 3839 * <strong>From the docs:</strong> Return all the HTTP headers, excluding headers that are a case-insensitive match
3840 * for Set-Cookie or Set-Cookie2, as a single string, with each header line separated by a U+000D CR U+000A LF pair, 3841 * excluding the status line, and with each header name and header value separated by a U+003A COLON U+0020 SPACE 3842 * pair. 3843 * @method getAllResponseHeaders 3844 * @return {String} 3845 * @since 0.4.1 3846 */ 3847 p.getAllResponseHeaders = function () { 3848 if (this._request.getAllResponseHeaders instanceof Function) { 3849 return this._request.getAllResponseHeaders(); 3850 } else { 3851 return null; 3852 } 3853 }; 3854 3855 /** 3856 * Get a specific response header from the XmlHttpRequest. 3857 * 3858 * <strong>From the docs:</strong> Returns the header field value from the response of which the field name matches 3859 * header, unless the field name is Set-Cookie or Set-Cookie2. 3860 * @method getResponseHeader 3861 * @param {String} header The header name to retrieve. 3862 * @return {String} 3863 * @since 0.4.1 3864 */ 3865 p.getResponseHeader = function (header) { 3866 if (this._request.getResponseHeader instanceof Function) { 3867 return this._request.getResponseHeader(header); 3868 } else { 3869 return null; 3870 } 3871 }; 3872 3873// protected methods 3874 /** 3875 * The XHR request has reported progress. 3876 * @method _handleProgress 3877 * @param {Object} event The XHR progress event. 3878 * @private 3879 */ 3880 p._handleProgress = function (event) { 3881 if (!event || event.loaded > 0 && event.total == 0) { 3882 return; // Sometimes we get no "total", so just ignore the progress event. 3883 } 3884 3885 var newEvent = new createjs.ProgressEvent(event.loaded, event.total); 3886 this.dispatchEvent(newEvent); 3887 }; 3888 3889 /** 3890 * The XHR request has reported a load start. 3891 * @method _handleLoadStart 3892 * @param {Object} event The XHR loadStart event. 3893 * @private 3894 */ 3895 p._handleLoadStart = function (event) { 3896 clearTimeout(this._loadTimeout); 3897 this.dispatchEvent("loadstart"); 3898 }; 3899 3900 /** 3901 * The XHR request has reported an abort event. 3902 * @method handleAbort 3903 * @param {Object} event The XHR abort event. 3904 * @private 3905 */ 3906 p._handleAbort = function (event) { 3907 this._clean(); 3908 this.dispatchEvent(new createjs.ErrorEvent("XHR_ABORTED", null, event)); 3909 }; 3910 3911 /** 3912 * The XHR request has reported an error event. 3913 * @method _handleError 3914 * @param {Object} event The XHR error event. 3915 * @private 3916 */ 3917 p._handleError = function (event) { 3918 this._clean(); 3919 this.dispatchEvent(new createjs.ErrorEvent(event.message)); 3920 }; 3921 3922 /** 3923 * The XHR request has reported a readyState change. Note that older browsers (IE 7 & 8) do not provide an onload 3924 * event, so we must monitor the readyStateChange to determine if the file is loaded. 3925 * @method _handleReadyStateChange 3926 * @param {Object} event The XHR readyStateChange event. 3927 * @private 3928 */ 3929 p._handleReadyStateChange = function (event) { 3930 if (this._request.readyState == 4) { 3931 this._handleLoad(); 3932 } 3933 }; 3934 3935 /** 3936 * The XHR request has completed. This is called by the XHR request directly, or by a readyStateChange that has 3937 * <code>request.readyState == 4</code>. Only the first call to this method will be processed. 3938 * @method _handleLoad 3939 * @param {Object} event The XHR load event. 3940 * @private 3941 */ 3942 p._handleLoad = function (event) { 3943 if (this.loaded) { 3944 return; 3945 } 3946 this.loaded = true; 3947 3948 var error = this._checkError(); 3949 if (error) { 3950 this._handleError(error); 3951 return; 3952 } 3953 3954 this._response = this._getResponse(); 3955 // Convert arraybuffer back to blob 3956 if (this._responseType === 'arraybuffer') { 3957 try { 3958 this._response = new Blob([this._response]); 3959 } catch (e) { 3960 // Fallback to use BlobBuilder if Blob constructor is not supported 3961 // Tested on Android 2.3 ~ 4.2 and iOS5 safari 3962 window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; 3963 if (e.name === 'TypeError' && window.BlobBuilder) { 3964 var builder = new BlobBuilder(); 3965 builder.append(this._response); 3966 this._response = builder.getBlob(); 3967 } 3968 } 3969 } 3970 this._clean(); 3971 3972 this.dispatchEvent(new createjs.Event("complete")); 3973 }; 3974 3975 /** 3976 * The XHR request has timed out. This is called by the XHR request directly, or via a <code>setTimeout</code> 3977 * callback. 3978 * @method _handleTimeout 3979 * @param {Object} [event] The XHR timeout event. This is occasionally null when called by the backup setTimeout. 3980 * @private 3981 */ 3982 p._handleTimeout = function (event) { 3983 this._clean(); 3984 3985 this.dispatchEvent(new createjs.ErrorEvent("PRELOAD_TIMEOUT", null, event)); 3986 }; 3987 3988// Protected 3989 /** 3990 * Determine if there is an error in the current load. This checks the status of the request for problem codes. Note 3991 * that this does not check for an actual response. Currently, it only checks for 404 or 0 error code.
3992 * @method _checkError 3993 * @return {int} If the request status returns an error code. 3994 * @private 3995 */ 3996 p._checkError = function () { 3997 //LM: Probably need additional handlers here, maybe 501 3998 var status = parseInt(this._request.status); 3999 4000 switch (status) { 4001 case 404: // Not Found 4002 case 0: // Not Loaded 4003 return new Error(status); 4004 } 4005 return null; 4006 }; 4007 4008 /** 4009 * Validate the response. Different browsers have different approaches, some of which throw errors when accessed 4010 * in other browsers. If there is no response, the <code>_response</code> property will remain null. 4011 * @method _getResponse 4012 * @private 4013 */ 4014 p._getResponse = function () { 4015 if (this._response != null) { 4016 return this._response; 4017 } 4018 4019 if (this._request.response != null) { 4020 return this._request.response; 4021 } 4022 4023 // Android 2.2 uses .responseText 4024 try { 4025 if (this._request.responseText != null) { 4026 return this._request.responseText; 4027 } 4028 } catch (e) { 4029 } 4030 4031 // When loading XML, IE9 does not return .response, instead it returns responseXML.xml 4032 try { 4033 if (this._request.responseXML != null) { 4034 return this._request.responseXML; 4035 } 4036 } catch (e) { 4037 } 4038 4039 return null; 4040 }; 4041 4042 /** 4043 * Create an XHR request. Depending on a number of factors, we get totally different results. 4044 * <ol><li>Some browsers get an <code>XDomainRequest</code> when loading cross-domain.</li> 4045 * <li>XMLHttpRequest are created when available.</li> 4046 * <li>ActiveX.XMLHTTP objects are used in older IE browsers.</li> 4047 * <li>Text requests override the mime type if possible</li> 4048 * <li>Origin headers are sent for crossdomain requests in some browsers.</li> 4049 * <li>Binary loads set the response type to "arraybuffer"</li></ol> 4050 * @method _createXHR 4051 * @param {Object} item The requested item that is being loaded. 4052 * @return {Boolean} If an XHR request or equivalent was successfully created. 4053 * @private 4054 */ 4055 p._createXHR = function (item) { 4056 // Check for cross-domain loads. We can't fully support them, but we can try. 4057 var crossdomain = createjs.RequestUtils.isCrossDomain(item); 4058 var headers = {}; 4059 4060 // Create the request. Fallback to whatever support we have. 4061 var req = null; 4062 if (window.XMLHttpRequest) { 4063 req = new XMLHttpRequest(); 4064 // This is 8 or 9, so use XDomainRequest instead. 4065 if (crossdomain && req.withCredentials === undefined && window.XDomainRequest) { 4066 req = new XDomainRequest(); 4067 } 4068 } else { // Old IE versions use a different approach 4069 for (var i = 0, l = s.ACTIVEX_VERSIONS.length; i < l; i++) { 4070 var axVersion = s.ACTIVEX_VERSIONS[i]; 4071 try { 4072 req = new ActiveXObject(axVersion); 4073 break; 4074 } catch (e) { 4075 } 4076 } 4077 if (req == null) { 4078 return false; 4079 } 4080 } 4081 4082 // Default to utf-8 for Text requests. 4083 if (item.mimeType == null && createjs.RequestUtils.isText(item.type)) { 4084 item.mimeType = "text/plain; charset=utf-8"; 4085 } 4086 4087 // IE9 doesn't support overrideMimeType(), so we need to check for it. 4088 if (item.mimeType && req.overrideMimeType) { 4089 req.overrideMimeType(item.mimeType); 4090 } 4091 4092 // Determine the XHR level 4093 this._xhrLevel = (typeof req.responseType === "string") ? 2 : 1; 4094 4095 var src = null; 4096 if (item.method == createjs.AbstractLoader.GET) { 4097 src = createjs.RequestUtils.buildPath(item.src, item.values); 4098 } else { 4099 src = item.src; 4100 } 4101 4102 // Open the request. Set cross-domain flags if it is supported (XHR level 1 only) 4103 req.open(item.method || createjs.AbstractLoader.GET, src, true); 4104 4105 if (crossdomain && req instanceof XMLHttpRequest && this._xhrLevel == 1) { 4106 headers["Origin"] = location.origin; 4107 } 4108 4109 // To send data we need to set the Content-type header) 4110 if (item.values && item.method == createjs.AbstractLoader.POST) { 4111 headers["Content-Type"] = "application/x-www-form-urlencoded"; 4112 } 4113 4114 if (!crossdomain && !headers["X-Requested-With"]) { 4115 headers["X-Requested-With"] = "XMLHttpRequest"; 4116 } 4117 4118 if (item.headers) { 4119 for (var n in item.headers) { 4120 headers[n] = item.headers[n]; 4121 } 4122 } 4123 4124 for (n in headers) { 4125 req.setRequestHeader(n, headers[n]) 4126 } 4127 4128 if (req instanceof XMLHttpRequest && item.withCredentials !== undefined) { 4129 req.withCredentials = item.withCredentials; 4130 } 4131 4132 this._request = req; 4133 4134 return true; 4135 }; 4136 4137 /** 4138 * A request has completed (or failed or canceled), and needs to be disposed.
4139 * @method _clean 4140 * @private 4141 */ 4142 p._clean = function () { 4143 clearTimeout(this._loadTimeout); 4144 4145 if (this._request.removeEventListener != null) { 4146 this._request.removeEventListener("loadstart", this._handleLoadStartProxy); 4147 this._request.removeEventListener("progress", this._handleProgressProxy); 4148 this._request.removeEventListener("abort", this._handleAbortProxy); 4149 this._request.removeEventListener("error", this._handleErrorProxy); 4150 this._request.removeEventListener("timeout", this._handleTimeoutProxy); 4151 this._request.removeEventListener("load", this._handleLoadProxy); 4152 this._request.removeEventListener("readystatechange", this._handleReadyStateChangeProxy); 4153 } else { 4154 this._request.onloadstart = null; 4155 this._request.onprogress = null; 4156 this._request.onabort = null; 4157 this._request.onerror = null; 4158 this._request.ontimeout = null; 4159 this._request.onload = null; 4160 this._request.onreadystatechange = null; 4161 } 4162 }; 4163 4164 p.toString = function () { 4165 return "[PreloadJS XHRRequest]"; 4166 }; 4167 4168 createjs.XHRRequest = createjs.promote(XHRRequest, "AbstractRequest"); 4169 4170}()); 4171 4172//############################################################################## 4173// LoadQueue.js 4174//############################################################################## 4175 4176this.createjs = this.createjs || {}; 4177 4178/* 4179 TODO: WINDOWS ISSUES 4180 * No error for HTML audio in IE 678 4181 * SVG no failure error in IE 67 (maybe 8) TAGS AND XHR 4182 * No script complete handler in IE 67 TAGS (XHR is fine) 4183 * No XML/JSON in IE6 TAGS 4184 * Need to hide loading SVG in Opera TAGS 4185 * No CSS onload/readystatechange in Safari or Android TAGS (requires rule checking) 4186 * SVG no load or failure in Opera XHR 4187 * Reported issues with IE7/8 4188 */ 4189 4190(function () { 4191 "use strict"; 4192 4193// constructor 4194 /** 4195 * The LoadQueue class is the main API for preloading content. LoadQueue is a load manager, which can preload either 4196 * a single file, or queue of files. 4197 * 4198 * <b>Creating a Queue</b><br /> 4199 * To use LoadQueue, create a LoadQueue instance. If you want to force tag loading where possible, set the preferXHR 4200 * argument to false. 4201 * 4202 * var queue = new createjs.LoadQueue(true); 4203 * 4204 * <b>Listening for Events</b><br /> 4205 * Add any listeners you want to the queue. Since PreloadJS 0.3.0, the {{#crossLink "EventDispatcher"}}{{/crossLink}} 4206 * lets you add as many listeners as you want for events. You can subscribe to the following events:<ul> 4207 * <li>{{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}}: fired when a queue completes loading all 4208 * files</li> 4209 * <li>{{#crossLink "AbstractLoader/error:event"}}{{/crossLink}}: fired when the queue encounters an error with 4210 * any file.</li> 4211 * <li>{{#crossLink "AbstractLoader/progress:event"}}{{/crossLink}}: Progress for the entire queue has 4212 * changed.</li> 4213 * <li>{{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}}: A single file has completed loading.</li> 4214 * <li>{{#crossLink "LoadQueue/fileprogress:event"}}{{/crossLink}}: Progress for a single file has changes. Note 4215 * that only files loaded with XHR (or possibly by plugins) will fire progress events other than 0 or 100%.</li> 4216 * </ul> 4217 * 4218 * queue.on("fileload", handleFileLoad, this); 4219 * queue.on("complete", handleComplete, this); 4220 * 4221 * <b>Adding files and manifests</b><br /> 4222 * Add files you want to load using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or add multiple files at a 4223 * time using a list or a manifest definition using {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. Files are 4224 * appended to the end of the active queue, so you can use these methods as many times as you like, whenever you 4225 * like. 4226 * 4227 * queue.loadFile("filePath/file.jpg"); 4228 * queue.loadFile({id:"image", src:"filePath/file.jpg"}); 4229 * queue.loadManifest(["filePath/file.jpg", {id:"image", src:"filePath/file.jpg"}]); 4230 * 4231 * // Use an external manifest 4232 * queue.loadManifest("path/to/manifest.json"); 4233 * queue.loadManifest({src:"manifest.json", type:"manifest"}); 4234 * 4235 * If you pass `false` as the `loadNow` parameter, the queue will not kick of the load of the files, but it will not 4236 * stop if it has already been started. Call the {{#crossLink "AbstractLoader/load"}}{{/crossLink}} method to begin 4237 * a paused queue. Note that a paused queue will automatically resume when new files are added to it with a 4238 * `loadNow` argument of `true`. 4239 * 4240 * queue.load(); 4241 * 4242 * <b>File Types</b><br /> 4243 * The file type of a manifest item is auto-determined by the file extension. The pattern matching in PreloadJS 4244 * should handle the majority of standard file and url formats, and works with common file extensions. If you have 4245 * either a non-standard file extension, or are serving the file using a proxy script, then you can pass in a 4246 * <code>type</code> property with any manifest item. 4247 * 4248 * queue.loadFile({src:"path/to/myFile.mp3x", type:createjs.AbstractLoader.SOUND}); 4249 * 4250 * // Note that PreloadJS will not read a file extension from the query string 4251 * queue.loadFile({src:"http://server.com/proxy?file=image.jpg", type:createjs.AbstractLoader.IMAGE}); 4252 * 4253 * Supported types are defined on the {{#crossLink "AbstractLoader"}}{{/crossLink}} class, and include: 4254 * <ul> 4255 * <li>{{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}}: Raw binary data via XHR</li> 4256 * <li>{{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}}: CSS files</li> 4257 * <li>{{#crossLink "AbstractLoader/IMAGE:property"}}{{/crossLink}}: Common image formats</li> 4258 * <li>{{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}}: JavaScript files</li> 4259 * <li>{{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}}: JSON data</li> 4260 * <li>{{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}}: JSON files cross-domain</li> 4261 * <li>{{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}: A list of files to load in JSON format, see 4262 * {{#crossLink "AbstractLoader/loadManifest"}}{{/crossLink}}</li> 4263 * <li>{{#crossLink "AbstractLoader/SOUND:property"}}{{/crossLink}}: Audio file formats</li> 4264 * <li>{{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}: JSON SpriteSheet definitions. This 4265 * will also load sub-images, and provide a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance.</li> 4266 * <li>{{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}}: SVG files</li> 4267 * <li>{{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}}: Text files - XHR only</li> 4268 * <li>{{#crossLink "AbstractLoader/VIDEO:property"}}{{/crossLink}}: Video objects</li> 4269 * <li>{{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}}: XML data</li> 4270 * </ul> 4271 * 4272 * <em>Note: Loader types used to be defined on LoadQueue, but have been moved to AbstractLoader for better 4273 * portability of loader classes, which can be used individually now. The properties on Loa
4273dQueue still exist, but 4274 * are deprecated.</em> 4275 * 4276 * <b>Handling Results</b><br /> 4277 * When a file is finished downloading, a {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event is 4278 * dispatched. In an example above, there is an event listener snippet for fileload. Loaded files are usually a 4279 * formatted object that can be used immediately, including: 4280 * <ul> 4281 * <li>Binary: The binary loaded result</li> 4282 * <li>CSS: A <link /> tag</li> 4283 * <li>Image: An <img /> tag</li> 4284 * <li>JavaScript: A <script /> tag</li> 4285 * <li>JSON/JSONP: A formatted JavaScript Object</li> 4286 * <li>Manifest: A JavaScript object. 4287 * <li>Sound: An <audio /> tag</a> 4288 * <li>SpriteSheet: A {{#crossLink "SpriteSheet"}}{{/crossLink}} instance, containing loaded images. 4289 * <li>SVG: An <object /> tag</li> 4290 * <li>Text: Raw text</li> 4291 * <li>Video: A Video DOM node</li> 4292 * <li>XML: An XML DOM node</li> 4293 * </ul> 4294 * 4295 * function handleFileLoad(event) { 4296 * var item = event.item; // A reference to the item that was passed in to the LoadQueue 4297 * var type = item.type; 4298 * 4299 * // Add any images to the page body. 4300 * if (type == createjs.LoadQueue.IMAGE) { 4301 * document.body.appendChild(event.result); 4302 * } 4303 * } 4304 * 4305 * At any time after the file has been loaded (usually after the queue has completed), any result can be looked up 4306 * via its "id" using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}. If no id was provided, then the 4307 * "src" or file path can be used instead, including the `path` defined by a manifest, but <strong>not including</strong> 4308 * a base path defined on the LoadQueue. It is recommended to always pass an id if you want to look up content. 4309 * 4310 * var image = queue.getResult("image"); 4311 * document.body.appendChild(image); 4312 * 4313 * Raw loaded content can be accessed using the <code>rawResult</code> property of the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} 4314 * event, or can be looked up using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}, passing `true` as the 2nd 4315 * argument. This is only applicable for content that has been parsed for the browser, specifically: JavaScript, 4316 * CSS, XML, SVG, and JSON objects, or anything loaded with XHR. 4317 * 4318 * var image = queue.getResult("image", true); // load the binary image data loaded with XHR. 4319 * 4320 * <b>Plugins</b><br /> 4321 * LoadQueue has a simple plugin architecture to help process and preload content. For example, to preload audio, 4322 * make sure to install the <a href="http://soundjs.com">SoundJS</a> Sound class, which will help load HTML audio, 4323 * Flash audio, and WebAudio files. This should be installed <strong>before</strong> loading any audio files. 4324 * 4325 * queue.installPlugin(createjs.Sound); 4326 * 4327 * <h4>Known Browser Issues</h4> 4328 * <ul> 4329 * <li>Browsers without audio support can not load audio files.</li> 4330 * <li>Safari on Mac OS X can only play HTML audio if QuickTime is installed</li> 4331 * <li>HTML Audio tags will only download until their <code>canPlayThrough</code> event is fired. Browsers other 4332 * than Chrome will continue to download in the background.</li> 4333 * <li>When loading scripts using tags, they are automatically added to the document.</li> 4334 * <li>Scripts loaded via XHR may not be properly inspectable with browser tools.</li> 4335 * <li>IE6 and IE7 (and some other browsers) may not be able to load XML, Text, or JSON, since they require 4336 * XHR to work.</li> 4337 * <li>Content loaded via tags will not show progress, and will continue to download in the background when 4338 * canceled, although no events will be dispatched.</li> 4339 * </ul> 4340 * 4341 * @class LoadQueue 4342 * @param {Boolean} [preferXHR=true] Determines whether the preload instance will favor loading with XHR (XML HTTP 4343 * Requests), or HTML tags. When this is `false`, the queue will use tag loading when possible, and fall back on XHR 4344 * when necessary. 4345 * @param {String} [basePath=""] A path that will be prepended on to the source parameter of all items in the queue 4346 * before they are loaded. Sources beginning with a protocol such as `http://` or a relative path such as `../` 4347 * will not receive a base path.
4348 * @param {String|Boolean} [crossOrigin=""] An optional flag to support images loaded from a CORS-enabled server. To 4349 * use it, set this value to `true`, which will default the crossOrigin property on images to "Anonymous". Any 4350 * string value will be passed through, but only "" and "Anonymous" are recommended. <strong>Note: The crossOrigin 4351 * parameter is deprecated. Use LoadItem.crossOrigin instead</strong> 4352 * 4353 * @constructor 4354 * @extends AbstractLoader 4355 */ 4356 function LoadQueue (preferXHR, basePath, crossOrigin) { 4357 this.AbstractLoader_constructor(); 4358 4359 /** 4360 * An array of the plugins registered using {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}}. 4361 * @property _plugins 4362 * @type {Array} 4363 * @private 4364 * @since 0.6.1 4365 */ 4366 this._plugins = []; 4367 4368 /** 4369 * An object hash of callbacks that are fired for each file type before the file is loaded, giving plugins the 4370 * ability to override properties of the load. Please see the {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}} 4371 * method for more information. 4372 * @property _typeCallbacks 4373 * @type {Object} 4374 * @private 4375 */ 4376 this._typeCallbacks = {}; 4377 4378 /** 4379 * An object hash of callbacks that are fired for each file extension before the file is loaded, giving plugins the 4380 * ability to override properties of the load. Please see the {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}} 4381 * method for more information. 4382 * @property _extensionCallbacks 4383 * @type {null} 4384 * @private 4385 */ 4386 this._extensionCallbacks = {}; 4387 4388 /** 4389 * The next preload queue to process when this one is complete. If an error is thrown in the current queue, and 4390 * {{#crossLink "LoadQueue/stopOnError:property"}}{{/crossLink}} is `true`, the next queue will not be processed. 4391 * @property next 4392 * @type {LoadQueue} 4393 * @default null 4394 */ 4395 this.next = null; 4396 4397 /** 4398 * Ensure loaded scripts "complete" in the order they are specified. Loaded scripts are added to the document head 4399 * once they are loaded. Scripts loaded via tags will load one-at-a-time when this property is `true`, whereas 4400 * scripts loaded using XHR can load in any order, but will "finish" and be added to the document in the order 4401 * specified. 4402 * 4403 * Any items can be set to load in order by setting the {{#crossLink "maintainOrder:property"}}{{/crossLink}} 4404 * property on the load item, or by ensuring that only one connection can be open at a time using 4405 * {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}. Note that when the `maintainScriptOrder` property 4406 * is set to `true`, scripts items are automatically set to `maintainOrder=true`, and changing the 4407 * `maintainScriptOrder` to `false` during a load will not change items already in a queue. 4408 * 4409 * <h4>Example</h4> 4410 * 4411 * var queue = new createjs.LoadQueue(); 4412 * queue.setMaxConnections(3); // Set a higher number to load multiple items at once 4413 * queue.maintainScriptOrder = true; // Ensure scripts are loaded in order 4414 * queue.loadManifest([ 4415 * "script1.js", 4416 * "script2.js", 4417 * "image.png", // Load any time 4418 * {src: "image2.png", maintainOrder: true} // Will wait for script2.js 4419 * "image3.png", 4420 * "script3.js" // Will wait for image2.png before loading (or completing when loading with XHR) 4421 * ]); 4422 * 4423 * @property maintainScriptOrder 4424 * @type {Boolean} 4425 * @default true 4426 */ 4427 this.maintainScriptOrder = true; 4428 4429 /** 4430 * Determines if the LoadQueue will stop processing the current queue when an error is encountered. 4431 * @property stopOnError 4432 * @type {Boolean} 4433 * @default false 4434 */ 4435 this.stopOnError = false; 4436 4437 /** 4438 * The number of maximum open connections that a loadQueue tries to maintain. Please see 4439 * {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}} for more information. 4440 * @property _maxConnections 4441 * @type {Number} 4442 * @default 1 4443 * @private 4444 */ 4445 this._maxConnections = 1; 4446 4447 /** 4448 * An internal list of all the default Loaders that are included with PreloadJS. Before an item is loaded, the 4449 * available loader list is iterated, in the order they are included, and as soon as a loader indicates it can 4450 * handle the content, it will be selected. The default loader, ({{#crossLink "TextLoader"}}{{/crossLink}} is 4451 * last in the list, so it will be used if no other match is found. Typically, loaders will match based on the 4452 * {{#crossLink "LoadItem/type"}}{{/crossLink}}, which is automatically determined using the file extension of 4453 * the {{#crossLink "LoadItem/src:property"}}{{/crossLink}}. 4454 * 4455 * Loaders can be removed from PreloadJS by simply not including them. 4456 * 4457 * Custom loaders installed using {{#crossLink "registerLoader"}}{{/crossLink}} will be prepended to this list 4458 * so that they are checked first. 4459 * @property _availableLoaders 4460 * @type {Array} 4461 * @private 4462 * @since 0.6.0 4463 */ 4464 this._availableLoaders = [ 4465 createjs.ImageLoader, 4466 createjs.JavaScriptLoader, 4467 createjs.CSSLoader, 4468 createjs.JSONLoader, 4469 createjs.JSONPLoader, 4470 createjs.SoundLoader, 4471 createjs.ManifestLoader, 4472 createjs.SpriteSheetLoader, 4473 createjs.XMLLoader, 4474 createjs.SVGLoader, 4475 createjs.BinaryLoader, 4476 createjs.VideoLoader, 4477 createjs.TextLoader 4478 ]; 4479 4480 /** 4481 * The number of built in loaders, so they can't be removed by {{#crossLink "unregisterLoader"}}{{/crossLink}. 4482 * @property _defaultLoaderLength 4483 * @type {Number} 4484 * @private 4485 * @since 0.6.0 4486 */ 4487 this._defaultLoaderLength = this._availableLoaders.length; 4488 4489 this.init(preferXHR, basePath, crossOrigin); 4490 } 4491
4492 var p = createjs.extend(LoadQueue, createjs.AbstractLoader); 4493 var s = LoadQueue; 4494 4495 /** 4496 * <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`. 4497 * See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}} 4498 * for details. 4499 * 4500 * There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance. 4501 * 4502 * @method initialize 4503 * @protected 4504 * @deprecated 4505 */ 4506 // p.initialize = function() {}; // searchable for devs wondering where it is. 4507 4508 /** 4509 * An internal initialization method, which is used for initial set up, but also to reset the LoadQueue. 4510 * @method init 4511 * @param preferXHR 4512 * @param basePath 4513 * @param crossOrigin 4514 * @private 4515 */ 4516 p.init = function (preferXHR, basePath, crossOrigin) { 4517 4518 // public properties 4519 /** 4520 * @property useXHR 4521 * @type {Boolean} 4522 * @readonly 4523 * @default true 4524 * @deprecated Use preferXHR instead. 4525 */ 4526 this.useXHR = true; 4527 4528 /** 4529 * Try and use XMLHttpRequest (XHR) when possible. Note that LoadQueue will default to tag loading or XHR 4530 * loading depending on the requirements for a media type. For example, HTML audio can not be loaded with XHR, 4531 * and plain text can not be loaded with tags, so it will default the the correct type instead of using the 4532 * user-defined type. 4533 * @type {Boolean} 4534 * @default true 4535 * @since 0.6.0 4536 */ 4537 this.preferXHR = true; //TODO: Get/Set 4538 this._preferXHR = true; 4539 this.setPreferXHR(preferXHR); 4540 4541 // protected properties 4542 /** 4543 * Whether the queue is currently paused or not. 4544 * @property _paused 4545 * @type {boolean} 4546 * @private 4547 */ 4548 this._paused = false; 4549 4550 /** 4551 * A path that will be prepended on to the item's {{#crossLink "LoadItem/src:property"}}{{/crossLink}}. The 4552 * `_basePath` property will only be used if an item's source is relative, and does not include a protocol such 4553 * as `http://`, or a relative path such as `../`. 4554 * @property _basePath 4555 * @type {String} 4556 * @private 4557 * @since 0.3.1 4558 */ 4559 this._basePath = basePath; 4560 4561 /** 4562 * An optional flag to set on images that are loaded using PreloadJS, which enables CORS support. Images loaded 4563 * cross-domain by servers that support CORS require the crossOrigin flag to be loaded and interacted with by 4564 * a canvas. When loading locally, or with a server with no CORS support, this flag can cause other security issues, 4565 * so it is recommended to only set it if you are sure the server supports it. Currently, supported values are "" 4566 * and "Anonymous". 4567 * @property _crossOrigin 4568 * @type {String} 4569 * @default "" 4570 * @private 4571 * @since 0.4.1 4572 */ 4573 this._crossOrigin = crossOrigin; 4574 4575 /** 4576 * Determines if the loadStart event was dispatched already. This event is only fired one time, when the first 4577 * file is requested. 4578 * @property _loadStartWasDispatched 4579 * @type {Boolean} 4580 * @default false 4581 * @private 4582 */ 4583 this._loadStartWasDispatched = false; 4584 4585 /** 4586 * Determines if there is currently a script loading. This helps ensure that only a single script loads at once when 4587 * using a script tag to do preloading. 4588 * @property _currentlyLoadingScript 4589 * @type {Boolean} 4590 * @private 4591 */ 4592 this._currentlyLoadingScript = null; 4593 4594 /** 4595 * An array containing the currently downloading files. 4596 * @property _currentLoads 4597 * @type {Array} 4598 * @private 4599 */ 4600 this._currentLoads = []; 4601 4602 /** 4603 * An array containing the queued items that have not yet started downloading. 4604 * @property _loadQueue 4605 * @type {Array} 4606 * @private 4607 */ 4608 this._loadQueue = []; 4609 4610 /** 4611 * An array containing downloads that have not completed, so that the LoadQueue can be properly reset. 4612 * @property _loadQueueBackup 4613 * @type {Array} 4614 * @private 4615 */ 4616 this._loadQueueBackup = []; 4617 4618 /** 4619 * An object hash of items that have finished downloading, indexed by the {{#crossLink "LoadItem"}}{{/crossLink}} 4620 * id. 4621 * @property _loadItemsById 4622 * @type {Object} 4623 * @private 4624 */ 4625 this._loadItemsById = {}; 4626 4627 /** 4628 * An object hash of items that have finished downloading, indexed by {{#crossLink "LoadItem"}}{{/crossLink}} 4629 * source. 4630 * @property _loadItemsBySrc 4631 * @type {Object} 4632 * @private 4633 */ 4634 this._loadItemsBySrc = {}; 4635 4636 /** 4637 * An object hash of loaded items, indexed by the ID of the {{#crossLink "LoadItem"}}{{/crossLink}}. 4638 * @property _loadedResults 4639 * @type {Object} 4640 * @private 4641 */ 4642 this._loadedResults = {}; 4643 4644 /** 4645 * An object hash of un-parsed loaded items, indexed by the ID of the {{#crossLink "LoadItem"}}{{/crossLink}}. 4646 * @property _loadedRawResults 4647 * @type {Object} 4648 * @private 4649 */ 4650 this._loadedRawResults = {}; 4651 4652 /** 4653 * The number of items that have been requested. This helps manage an overall progress without knowing how large 4654 * the files are before they are downloaded. This does not include items inside of loaders such as the 4655 * {{#crossLink "ManifestLoader"}}{{/crossLink}}. 4656 * @property _numItems 4657 * @type {Number} 4658 * @default 0 4659 * @private 4660 */ 4661 this._numItems = 0; 4662 4663 /** 4664 * The number of items that have completed loaded. This helps manage an overall progress without knowing how large 4665 * the files are before they are downloaded.
4666 * @property _numItemsLoaded 4667 * @type {Number} 4668 * @default 0 4669 * @private 4670 */ 4671 this._numItemsLoaded = 0; 4672 4673 /** 4674 * A list of scripts in the order they were requested. This helps ensure that scripts are "completed" in the right 4675 * order. 4676 * @property _scriptOrder 4677 * @type {Array} 4678 * @private 4679 */ 4680 this._scriptOrder = []; 4681 4682 /** 4683 * A list of scripts that have been loaded. Items are added to this list as <code>null</code> when they are 4684 * requested, contain the loaded item if it has completed, but not been dispatched to the user, and <code>true</true> 4685 * once they are complete and have been dispatched. 4686 * @property _loadedScripts 4687 * @type {Array} 4688 * @private 4689 */ 4690 this._loadedScripts = []; 4691 4692 /** 4693 * The last progress amount. This is used to suppress duplicate progress events. 4694 * @property _lastProgress 4695 * @type {Number} 4696 * @private 4697 * @since 0.6.0 4698 */ 4699 this._lastProgress = NaN; 4700 4701 }; 4702 4703// static properties 4704 /** 4705 * The time in milliseconds to assume a load has failed. An {{#crossLink "AbstractLoader/error:event"}}{{/crossLink}} 4706 * event is dispatched if the timeout is reached before any data is received. 4707 * @property loadTimeout 4708 * @type {Number} 4709 * @default 8000 4710 * @static 4711 * @since 0.4.1 4712 * @deprecated In favour of {{#crossLink "LoadItem/LOAD_TIMEOUT_DEFAULT:property}}{{/crossLink}} property. 4713 */ 4714 s.loadTimeout = 8000; 4715 4716 /** 4717 * The time in milliseconds to assume a load has failed. 4718 * @property LOAD_TIMEOUT 4719 * @type {Number} 4720 * @default 0 4721 * @deprecated in favor of the {{#crossLink "LoadQueue/loadTimeout:property"}}{{/crossLink}} property. 4722 */ 4723 s.LOAD_TIMEOUT = 0; 4724 4725// Preload Types 4726 /** 4727 * @property BINARY 4728 * @type {String} 4729 * @default binary 4730 * @static 4731 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}} instead. 4732 */ 4733 s.BINARY = createjs.AbstractLoader.BINARY; 4734 4735 /** 4736 * @property CSS 4737 * @type {String} 4738 * @default css 4739 * @static 4740 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}} instead. 4741 */ 4742 s.CSS = createjs.AbstractLoader.CSS; 4743 4744 /** 4745 * @property IMAGE 4746 * @type {String} 4747 * @default image 4748 * @static 4749 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}} instead. 4750 */ 4751 s.IMAGE = createjs.AbstractLoader.IMAGE; 4752 4753 /** 4754 * @property JAVASCRIPT 4755 * @type {String} 4756 * @default javascript 4757 * @static 4758 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead. 4759 */ 4760 s.JAVASCRIPT = createjs.AbstractLoader.JAVASCRIPT; 4761 4762 /** 4763 * @property JSON 4764 * @type {String} 4765 * @default json 4766 * @static 4767 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}} instead. 4768 */ 4769 s.JSON = createjs.AbstractLoader.JSON; 4770 4771 /** 4772 * @property JSONP 4773 * @type {String} 4774 * @default jsonp 4775 * @static 4776 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}} instead. 4777 */ 4778 s.JSONP = createjs.AbstractLoader.JSONP; 4779 4780 /** 4781 * @property MANIFEST 4782 * @type {String} 4783 * @default manifest 4784 * @static 4785 * @since 0.4.1 4786 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}} instead. 4787 */ 4788 s.MANIFEST = createjs.AbstractLoader.MANIFEST; 4789 4790 /** 4791 * @property SOUND 4792 * @type {String} 4793 * @default sound 4794 * @static 4795 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead. 4796 */ 4797 s.SOUND = createjs.AbstractLoader.SOUND; 4798 4799 /** 4800 * @property VIDEO 4801 * @type {String} 4802 * @default video 4803 * @static 4804 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead. 4805 */ 4806 s.VIDEO = createjs.AbstractLoader.VIDEO; 4807 4808 /** 4809 * @property SVG 4810 * @type {String} 4811 * @default svg 4812 * @static 4813 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}} instead. 4814 */ 4815 s.SVG = createjs.AbstractLoader.SVG; 4816 4817 /** 4818 * @property TEXT 4819 * @type {String} 4820 * @default text 4821 * @static 4822 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}} instead. 4823 */ 4824 s.TEXT = createjs.AbstractLoader.TEXT; 4825 4826 /** 4827 * @property XML 4828 * @type {String} 4829 * @default xml 4830 * @static 4831 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}} instead. 4832 */ 4833 s.XML = createjs.AbstractLoader.XML; 4834 4835 /** 4836 * @property POST 4837 * @type {string} 4838 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/POST:property"}}{{/crossLink}} instead. 4839 */ 4840 s.POST = createjs.AbstractLoader.POST; 4841 4842 /** 4843 * @property GET 4844 * @type {string} 4845 * @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/GET:property"}}{{/crossLink}} instead. 4846 */ 4847 s.GET = createjs.AbstractLoader.GET; 4848 4849// events 4850 /**
4851 * This event is fired when an individual file has loaded, and been processed. 4852 * @event fileload 4853 * @param {Object} target The object that dispatched the event. 4854 * @param {String} type The event type. 4855 * @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} 4856 * or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the 4857 * object will contain that value as a `src` property. 4858 * @param {Object} result The HTML tag or parsed result of the loaded item. 4859 * @param {Object} rawResult The unprocessed result, usually the raw text or binary data before it is converted 4860 * to a usable object. 4861 * @since 0.3.0 4862 */ 4863 4864 /** 4865 * This {{#crossLink "ProgressEvent"}}{{/crossLink}} that is fired when an an individual file's progress changes. 4866 * @event fileprogress 4867 * @since 0.3.0 4868 */ 4869 4870 /** 4871 * This event is fired when an individual file starts to load. 4872 * @event filestart 4873 * @param {Object} The object that dispatched the event. 4874 * @param {String} type The event type. 4875 * @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} 4876 * or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the 4877 * object will contain that value as a property. 4878 */ 4879 4880 /** 4881 * Although it extends {{#crossLink "AbstractLoader"}}{{/crossLink}}, the `initialize` event is never fired from 4882 * a LoadQueue instance. 4883 * @event initialize 4884 * @private 4885 */ 4886 4887// public methods 4888 /** 4889 * Register a custom loaders class. New loaders are given precedence over loaders added earlier and default loaders. 4890 * It is recommended that loaders extend {{#crossLink "AbstractLoader"}}{{/crossLink}}. Loaders can only be added 4891 * once, and will be prepended to the list of available loaders. 4892 * @method registerLoader 4893 * @param {Function|AbstractLoader} loader The AbstractLoader class to add. 4894 * @since 0.6.0 4895 */ 4896 p.registerLoader = function (loader) { 4897 if (!loader || !loader.canLoadItem) { 4898 throw new Error("loader is of an incorrect type."); 4899 } else if (this._availableLoaders.indexOf(loader) != -1) { 4900 throw new Error("loader already exists."); //LM: Maybe just silently fail here 4901 } 4902 4903 this._availableLoaders.unshift(loader); 4904 }; 4905 4906 /** 4907 * Remove a custom loader added using {{#crossLink "registerLoader"}}{{/crossLink}}. Only custom loaders can be 4908 * unregistered, the default loaders will always be available. 4909 * @method unregisterLoader 4910 * @param {Function|AbstractLoader} loader The AbstractLoader class to remove 4911 */ 4912 p.unregisterLoader = function (loader) { 4913 var idx = this._availableLoaders.indexOf(loader); 4914 if (idx != -1 && idx < this._defaultLoaderLength - 1) { 4915 this._availableLoaders.splice(idx, 1); 4916 } 4917 }; 4918 4919 /** 4920 * @method setUseXHR 4921 * @param {Boolean} value The new useXHR value to set. 4922 * @return {Boolean} The new useXHR value. If XHR is not supported by the browser, this will return false, even if 4923 * the provided value argument was true. 4924 * @since 0.3.0 4925 * @deprecated use the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} property, or the 4926 * {{#crossLink "LoadQueue/setUseXHR"}}{{/crossLink}} method instead. 4927 */ 4928 p.setUseXHR = function (value) { 4929 return this.setPreferXHR(value); 4930 }; 4931 4932 /** 4933 * Change the {{#crossLink "preferXHR:property"}}{{/crossLink}} value. Note that if this is set to `true`, it may 4934 * fail, or be ignored depending on the browser's capabilities and the load type. 4935 * @method setPreferXHR 4936 * @param {Boolean} value 4937 * @returns {Boolean} The value of {{#crossLink "preferXHR"}}{{/crossLink}} that was successfully set. 4938 * @since 0.6.0 4939 */ 4940 p.setPreferXHR = function (value) { 4941 // Determine if we can use XHR. XHR defaults to TRUE, but the browser may not support it. 4942 //TODO: Should we be checking for the other XHR types? Might have to do a try/catch on the different types similar to createXHR. 4943 this.preferXHR = (value != false && window.XMLHttpRequest != null); 4944 return this.preferXHR; 4945 }; 4946 4947 /** 4948 * Stops all queued and loading items, and clears the queue. This also removes all internal references to loaded 4949 * content, and allows the queue to be used again. 4950 * @method removeAll 4951 * @since 0.3.0 4952 */ 4953 p.removeAll = function () { 4954 this.remove(); 4955 }; 4956 4957 /** 4958 * Stops an item from being loaded, and removes it from the queue. If nothing is passed, all items are removed.
4959 * This also removes internal references to loaded item(s). 4960 * 4961 * <h4>Example</h4> 4962 * 4963 * queue.loadManifest([ 4964 * {src:"test.png", id:"png"}, 4965 * {src:"test.jpg", id:"jpg"}, 4966 * {src:"test.mp3", id:"mp3"} 4967 * ]); 4968 * queue.remove("png"); // Single item by ID 4969 * queue.remove("png", "test.jpg"); // Items as arguments. Mixed id and src. 4970 * queue.remove(["test.png", "jpg"]); // Items in an Array. Mixed id and src. 4971 * 4972 * @method remove 4973 * @param {String | Array} idsOrUrls* The id or ids to remove from this queue. You can pass an item, an array of 4974 * items, or multiple items as arguments. 4975 * @since 0.3.0 4976 */ 4977 p.remove = function (idsOrUrls) { 4978 var args = null; 4979 4980 if (idsOrUrls && !Array.isArray(idsOrUrls)) { 4981 args = [idsOrUrls]; 4982 } else if (idsOrUrls) { 4983 args = idsOrUrls; 4984 } else if (arguments.length > 0) { 4985 return; 4986 } 4987 4988 var itemsWereRemoved = false; 4989 4990 // Destroy everything 4991 if (!args) { 4992 this.close(); 4993 for (var n in this._loadItemsById) { 4994 this._disposeItem(this._loadItemsById[n]); 4995 } 4996 this.init(this.preferXHR, this._basePath); 4997 4998 // Remove specific items 4999 } else { 5000 while (args.length) { 5001 var item = args.pop(); 5002 var r = this.getResult(item); 5003 5004 //Remove from the main load Queue 5005 for (i = this._loadQueue.length - 1; i >= 0; i--) { 5006 loadItem = this._loadQueue[i].getItem(); 5007 if (loadItem.id == item || loadItem.src == item) { 5008 this._loadQueue.splice(i, 1)[0].cancel(); 5009 break; 5010 } 5011 } 5012 5013 //Remove from the backup queue 5014 for (i = this._loadQueueBackup.length - 1; i >= 0; i--) { 5015 loadItem = this._loadQueueBackup[i].getItem(); 5016 if (loadItem.id == item || loadItem.src == item) { 5017 this._loadQueueBackup.splice(i, 1)[0].cancel(); 5018 break; 5019 } 5020 } 5021 5022 if (r) { 5023 this._disposeItem(this.getItem(item)); 5024 } else { 5025 for (var i = this._currentLoads.length - 1; i >= 0; i--) { 5026 var loadItem = this._currentLoads[i].getItem(); 5027 if (loadItem.id == item || loadItem.src == item) { 5028 this._currentLoads.splice(i, 1)[0].cancel(); 5029 itemsWereRemoved = true; 5030 break; 5031 } 5032 } 5033 } 5034 } 5035 5036 // If this was called during a load, try to load the next item. 5037 if (itemsWereRemoved) { 5038 this._loadNext(); 5039 } 5040 } 5041 }; 5042 5043 /** 5044 * Stops all open loads, destroys any loaded items, and resets the queue, so all items can 5045 * be reloaded again by calling {{#crossLink "AbstractLoader/load"}}{{/crossLink}}. Items are not removed from the 5046 * queue. To remove items use the {{#crossLink "LoadQueue/remove"}}{{/crossLink}} or 5047 * {{#crossLink "LoadQueue/removeAll"}}{{/crossLink}} method. 5048 * @method reset 5049 * @since 0.3.0 5050 */ 5051 p.reset = function () { 5052 this.close(); 5053 for (var n in this._loadItemsById) { 5054 this._disposeItem(this._loadItemsById[n]); 5055 } 5056 5057 //Reset the queue to its start state 5058 var a = []; 5059 for (var i = 0, l = this._loadQueueBackup.length; i < l; i++) { 5060 a.push(this._loadQueueBackup[i].getItem()); 5061 } 5062 5063 this.loadManifest(a, false); 5064 }; 5065 5066 /** 5067 * Register a plugin. Plugins can map to load types (sound, image, etc), or specific extensions (png, mp3, etc). 5068 * Currently, only one plugin can exist per type/extension. 5069 * 5070 * When a plugin is installed, a <code>getPreloadHandlers()</code> method will be called on it. For more information 5071 * on this method, check out the {{#crossLink "SamplePlugin/getPreloadHandlers"}}{{/crossLink}} method in the 5072 * {{#crossLink "SamplePlugin"}}{{/crossLink}} class. 5073 * 5074 * Before a file is loaded, a matching plugin has an opportunity to modify the load. If a `callback` is returned 5075 * from the {{#crossLink "SamplePlugin/getPreloadHandlers"}}{{/crossLink}} method, it will be invoked first, and its 5076 * result may cancel or modify the item. The callback method can also return a `completeHandler` to be fired when 5077 * the file is loaded, or a `tag` object, which will manage the actual download. For more information on these 5078 * methods, check out the {{#crossLink "SamplePlugin/preloadHandler"}}{{/crossLink}} and {{#crossLink "SamplePlugin/fileLoadHandler"}}{{/crossLink}} 5079 * methods on the {{#crossLink "SamplePlugin"}}{{/crossLink}}. 5080 * 5081 * @method installPlugin 5082 * @param {Function} plugin The plugin class to install. 5083 */ 5084 p.installPlugin = function (plugin) { 5085 if (plugin == null) { 5086 return; 5087 } 5088 5089 if (plugin.getPreloadHandlers != null) { 5090 this._plugins.push(plugin); 5091 var map = plugin.getPreloadHandlers(); 5092 map.scope = plugin; 5093 5094 if (map.types != null) { 5095 for (var i = 0, l = map.types.length; i < l; i++) { 5096 this._typeCallbacks[map.types[i]] = map; 5097 } 5098 } 5099 5100 if (map.extensions != null) { 5101 for (i = 0, l = map.extensions.length; i < l; i++) { 5102 this._extensionCallbacks[map.extensions[i]] = map; 5103 } 5104 } 5105 } 5106 }; 5107 5108 /** 5109 * Set the maximum number of concurrent connections. Note that browsers and servers may have a built-in maximum 5110 * number of open connections, so any additional connections may remain in a pending state until the browser 5111 * opens the connection. When loading scripts using tags, and when {{#crossLink "LoadQueue/maintainScriptOrder:property"}}{{/crossLink}} 5112 * is `true`, only one script is loaded at a time due to browser limitations. 5113 * 5114 * <h4>Example</h4> 5115 * 5116 * var queue = new createjs.LoadQueue(); 5117 * queue.setMaxConnections(10); // Allow 10 concurrent loads 5118 * 5119 * @method setMaxConnections 5120 * @param {Number} value The number of concurrent loads to allow. By default, only a single connection per LoadQueue 5121 * is open at any time. 5122 */ 5123 p.setMaxConnections = function (value) { 5124 this._maxConnections = value; 5125 if (!this._paused && this._loadQueue.length > 0) { 5126 this._loadNext(); 5127 } 5128 }; 5129 5130 /** 5131 * Load a single file. To add multiple files at once, use the {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} 5132 * method. 5133 * 5134 * Files are always appended to the current queue, so this method can be used multiple times to add files. 5135 * To clear the queue first, use the {{#crossLink "AbstractLoader/close"}}{{/crossLink}} method. 5136 * @method loadFile 5137 * @param {LoadItem|Object|String} file The file object or path to load. A file can be either 5138 * <ul> 5139 * <li>A {{#crossLink "LoadItem"}}{{/crossLink}} instance</li> 5140 * <li>
5140An object containing properties defined by {{#crossLink "LoadItem"}}{{/crossLink}}</li> 5141 * <li>OR A string path to a resource. Note that this kind of load item will be converted to a {{#crossLink "LoadItem"}}{{/crossLink}} 5142 * in the background.</li> 5143 * </ul> 5144 * @param {Boolean} [loadNow=true] Kick off an immediate load (true) or wait for a load call (false). The default 5145 * value is true. If the queue is paused using {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}}, and the value is 5146 * `true`, the queue will resume automatically. 5147 * @param {String} [basePath] A base path that will be prepended to each file. The basePath argument overrides the 5148 * path specified in the constructor. Note that if you load a manifest using a file of type {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}, 5149 * its files will <strong>NOT</strong> use the basePath parameter. <strong>The basePath parameter is deprecated.</strong> 5150 * This parameter will be removed in a future version. Please either use the `basePath` parameter in the LoadQueue 5151 * constructor, or a `path` property in a manifest definition. 5152 */ 5153 p.loadFile = function (file, loadNow, basePath) { 5154 if (file == null) { 5155 var event = new createjs.ErrorEvent("PRELOAD_NO_FILE"); 5156 this._sendError(event); 5157 return; 5158 } 5159 this._addItem(file, null, basePath); 5160 5161 if (loadNow !== false) { 5162 this.setPaused(false); 5163 } else { 5164 this.setPaused(true); 5165 } 5166 }; 5167 5168 /** 5169 * Load an array of files. To load a single file, use the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} method. 5170 * The files in the manifest are requested in the same order, but may complete in a different order if the max 5171 * connections are set above 1 using {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}. Scripts will load 5172 * in the right order as long as {{#crossLink "LoadQueue/maintainScriptOrder"}}{{/crossLink}} is true (which is 5173 * default). 5174 * 5175 * Files are always appended to the current queue, so this method can be used multiple times to add files. 5176 * To clear the queue first, use the {{#crossLink "AbstractLoader/close"}}{{/crossLink}} method. 5177 * @method loadManifest 5178 * @param {Array|String|Object} manifest An list of files to load. The loadManifest call supports four types of 5179 * manifests: 5180 * <ol> 5181 * <li>A string path, which points to a manifest file, which is a JSON file that contains a "manifest" property, 5182 * which defines the list of files to load, and can optionally contain a "path" property, which will be 5183 * prepended to each file in the list.</li> 5184 * <li>An object which defines a "src", which is a JSON or JSONP file. A "callback" can be defined for JSONP 5185 * file. The JSON/JSONP file should contain a "manifest" property, which defines the list of files to load, 5186 * and can optionally contain a "path" property, which will be prepended to each file in the list.</li> 5187 * <li>An object which contains a "manifest" property, which defines the list of files to load, and can 5188 * optionally contain a "path" property, which will be prepended to each file in the list.</li> 5189 * <li>An Array of files to load.</li> 5190 * </ol> 5191 * 5192 * Each "file" in a manifest can be either: 5193 * <ul> 5194 * <li>A {{#crossLink "LoadItem"}}{{/crossLink}} instance</li> 5195 * <li>An object containing properties defined by {{#crossLink "LoadItem"}}{{/crossLink}}</li> 5196 * <li>OR A string path to a resource. Note that this kind of load item will be converted to a {{#crossLink "LoadItem"}}{{/crossLink}} 5197 * in the background.</li> 5198 * </ul> 5199 * 5200 * @param {Boolean} [loadNow=true] Kick off an immediate load (true) or wait for a load call (false). The default 5201 * value is true. If the queue is paused using {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}} and this value is 5202 * `true`, the queue will resume automatically. 5203 * @param {String} [basePath] A base path that will be prepended to each file. The basePath argument overrides the 5204 * path specified in the constructor. Note that if you load a manifest using a file of type {{#crossLink "LoadQueue/MANIFEST:property"}}{{/crossLink}}, 5205 * its files will <strong>NOT</strong> use the basePath parameter. <strong>The basePath parameter is deprecated.</strong> 5206 * This parameter will be removed in a future version. Please either use the `basePath` parameter in the LoadQueue 5207 * constructor, or a `path` property in a manifest definition. 5208 */ 5209 p.loadManifest = function (manifest, loadNow, basePath) { 5210 var fileList = null; 5211 var path = null; 5212 5213 // Array-based list of items 5214 if (Array.isArray(manifest)) { 5215 if (manifest.length == 0) { 5216 var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_EMPTY"); 5217 this._sendError(event); 5218 return; 5219 } 5220 fileList = manifest; 5221 5222 // String-based. Only file manifests can be specified this way. Any other types will cause an error when loaded. 5223 } else if (typeof(manifest) === "string") { 5224 fileList = [ 5225 { 5226 src: manifest, 5227 type: s.MANIFEST 5228 } 5229 ]; 5230 5231 } else if (typeof(manifest) == "object") { 5232 5233 // An object that defines a manifest path 5234 if (manifest.src !== undefined) { 5235 if (manifest.type == null) { 5236 manifest.type = s.MANIFEST; 5237 } else if (manifest.type != s.MANIFEST) { 5238 var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_TYPE"); 5239 this._sendError(event); 5240 } 5241 fileList = [manifest]; 5242 5243 // An object that defines a manifest 5244 } else if (manifest.manifest !== undefined) { 5245 fileList = manifest.manifest; 5246 path = manifest.path; 5247 } 5248 5249 // Unsupported. This will throw an error. 5250 } else { 5251 var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_NULL"); 5252 this._sendError(event); 5253 return; 5254 } 5255 5256 for (var i = 0, l = fileList.length; i < l; i++) { 5257 this._addItem(fileList[i], path, basePath); 5258 } 5259 5260 if (loadNow !== false) { 5261 this.setPaused(false); 5262 } else { 5263 this.setPaused(true); 5264 } 5265 5266 }; 5267 5268 /** 5269 * Start a LoadQueue that was created, but not automatically started. 5270 * @method load 5271 */ 5272 p.load = function () { 5273 this.setPaused(false); 5274 }; 5275 5276 /** 5277 * Look up a {{#crossLink "LoadItem"}}{{/crossLink}} using either the "id" or "src" that was specified when loading it. Note that if no "id" was 5278 * supplied with the load item, the ID will be the "src", including a `path` property defined by a manifest. The 5279 * `basePath` will not be part of the ID. 5280 * @method getItem 5281 * @param {String} value The <code>id</code> or <code>src</code> of the load item. 5282 * @return {Object} The load item that was initially requested using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} 5283 * or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. This object is also returned via the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} 5284 * event as the `item` parameter. 5285 */ 5286 p.getItem = function (value) { 5287 return this._loadItemsById[value] || this._loadItemsBySrc[value]; 5288 }; 5289 5290 /** 5291 * Look up a loaded result using either the "id" or "src" that was specified when loading it. Note that if no "id" 5292 * was supplied with the load item, the ID will be the "src", including a `path` property defined by a manifest. The 5293 * `basePath` will not be part of the ID. 5294 * @method getResult 5295 * @param {String} value The <code>id</code> or <code>src</code> of the load item. 5296 * @param {Boolean} [rawResult=false] Return a raw result instead of a formatted result. This applies to content 5297 * loaded via XHR such as scripts, XML, CSS, and Images. If there is no raw result, the formatted result will be 5298 * returned instead. 5299 * @return {Object}
5299 A result object containing the content that was loaded, such as: 5300 * <ul> 5301 * <li>An image tag (<image />) for images</li> 5302 * <li>A script tag for JavaScript (<script />). Note that scripts are automatically added to the HTML 5303 * DOM.</li> 5304 * <li>A style tag for CSS (<style /> or <link >)</li> 5305 * <li>Raw text for TEXT</li> 5306 * <li>A formatted JavaScript object defined by JSON</li> 5307 * <li>An XML document</li> 5308 * <li>A binary arraybuffer loaded by XHR</li> 5309 * <li>An audio tag (<audio >) for HTML audio. Note that it is recommended to use SoundJS APIs to play 5310 * loaded audio. Specifically, audio loaded by Flash and WebAudio will return a loader object using this method 5311 * which can not be used to play audio back.</li> 5312 * </ul> 5313 * This object is also returned via the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event as the 'item` 5314 * parameter. Note that if a raw result is requested, but not found, the result will be returned instead. 5315 */ 5316 p.getResult = function (value, rawResult) { 5317 var item = this._loadItemsById[value] || this._loadItemsBySrc[value]; 5318 if (item == null) { 5319 return null; 5320 } 5321 var id = item.id; 5322 if (rawResult && this._loadedRawResults[id]) { 5323 return this._loadedRawResults[id]; 5324 } 5325 return this._loadedResults[id]; 5326 }; 5327 5328 /** 5329 * Generate an list of items loaded by this queue. 5330 * @method getItems 5331 * @param {Boolean} loaded Determines if only items that have been loaded should be returned. If false, in-progress 5332 * and failed load items will also be included. 5333 * @returns {Array} A list of objects that have been loaded. Each item includes the {{#crossLink "LoadItem"}}{{/crossLink}}, 5334 * result, and rawResult. 5335 * @since 0.6.0 5336 */ 5337 p.getItems = function (loaded) { 5338 var arr = []; 5339 for (var n in this._loadItemsById) { 5340 var item = this._loadItemsById[n]; 5341 var result = this.getResult(n); 5342 if (loaded === true && result == null) { 5343 continue; 5344 } 5345 arr.push({ 5346 item: item, 5347 result: result, 5348 rawResult: this.getResult(n, true) 5349 }); 5350 } 5351 return arr; 5352 }; 5353 5354 /** 5355 * Pause or resume the current load. Active loads will not be cancelled, but the next items in the queue will not 5356 * be processed when active loads complete. LoadQueues are not paused by default. 5357 * 5358 * Note that if new items are added to the queue using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or 5359 * {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}, a paused queue will be resumed, unless the `loadNow` 5360 * argument is `false`. 5361 * @method setPaused 5362 * @param {Boolean} value Whether the queue should be paused or not. 5363 */ 5364 p.setPaused = function (value) { 5365 this._paused = value; 5366 if (!this._paused) { 5367 this._loadNext(); 5368 } 5369 }; 5370 5371 /** 5372 * Close the active queue. Closing a queue completely empties the queue, and prevents any remaining items from 5373 * starting to download. Note that currently any active loads will remain open, and events may be processed. 5374 * 5375 * To stop and restart a queue, use the {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}} method instead. 5376 * @method close 5377 */ 5378 p.close = function () { 5379 while (this._currentLoads.length) { 5380 this._currentLoads.pop().cancel(); 5381 } 5382 this._scriptOrder.length = 0; 5383 this._loadedScripts.length = 0; 5384 this.loadStartWasDispatched = false; 5385 this._itemCount = 0; 5386 this._lastProgress = NaN; 5387 }; 5388 5389// protected methods 5390 /** 5391 * Add an item to the queue. Items are formatted into a usable object containing all the properties necessary to 5392 * load the content. The load queue is populated with the loader instance that handles preloading, and not the load 5393 * item that was passed in by the user. To look up the load item by id or src, use the {{#crossLink "LoadQueue.getItem"}}{{/crossLink}} 5394 * method. 5395 * @method _addItem 5396 * @param {String|Object} value The item to add to the queue. 5397 * @param {String} [path] An optional path prepended to the `src`. The path will only be prepended if the src is 5398 * relative, and does not start with a protocol such as `http://`, or a path like `../`. If the LoadQueue was 5399 * provided a {{#crossLink "_basePath"}}{{/crossLink}}, then it will optionally be prepended after. 5400 * @param {String} [basePath] <strong>Deprecated</strong>An optional basePath passed into a {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} 5401 * or {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} call. This parameter will be removed in a future tagged
5402 * version. 5403 * @private 5404 */ 5405 p._addItem = function (value, path, basePath) { 5406 var item = this._createLoadItem(value, path, basePath); // basePath and manifest path are added to the src. 5407 if (item == null) { 5408 return; 5409 } // Sometimes plugins or types should be skipped. 5410 var loader = this._createLoader(item); 5411 if (loader != null) { 5412 if ("plugins" in loader) { 5413 loader.plugins = this._plugins; 5414 } 5415 item._loader = loader; 5416 this._loadQueue.push(loader); 5417 this._loadQueueBackup.push(loader); 5418 5419 this._numItems++; 5420 this._updateProgress(); 5421 5422 // Only worry about script order when using XHR to load scripts. Tags are only loading one at a time. 5423 if ((this.maintainScriptOrder 5424 && item.type == createjs.LoadQueue.JAVASCRIPT 5425 //&& loader instanceof createjs.XHRLoader //NOTE: Have to track all JS files this way 5426 ) 5427 || item.maintainOrder === true) { 5428 this._scriptOrder.push(item); 5429 this._loadedScripts.push(null); 5430 } 5431 } 5432 }; 5433 5434 /** 5435 * Create a refined {{#crossLink "LoadItem"}}{{/crossLink}}, which contains all the required properties. The type of 5436 * item is determined by browser support, requirements based on the file type, and developer settings. For example, 5437 * XHR is only used for file types that support it in new browsers. 5438 * 5439 * Before the item is returned, any plugins registered to handle the type or extension will be fired, which may 5440 * alter the load item. 5441 * @method _createLoadItem 5442 * @param {String | Object | HTMLAudioElement | HTMLImageElement} value The item that needs to be preloaded. 5443 * @param {String} [path] A path to prepend to the item's source. Sources beginning with http:// or similar will 5444 * not receive a path. Since PreloadJS 0.4.1, the src will be modified to include the `path` and {{#crossLink "LoadQueue/_basePath:property"}}{{/crossLink}} 5445 * when it is added. 5446 * @param {String} [basePath] <strong>Deprectated</strong> A base path to prepend to the items source in addition to 5447 * the path argument. 5448 * @return {Object} The loader instance that will be used. 5449 * @private 5450 */ 5451 p._createLoadItem = function (value, path, basePath) { 5452 var item = createjs.LoadItem.create(value); 5453 if (item == null) { 5454 return null; 5455 } 5456 5457 var bp = ""; // Store the generated basePath 5458 var useBasePath = basePath || this._basePath; 5459 5460 if (item.src instanceof Object) { 5461 if (!item.type) { 5462 return null; 5463 } // the the src is an object, type is required to pass off to plugin 5464 if (path) { 5465 bp = path; 5466 var pathMatch = createjs.RequestUtils.parseURI(path); 5467 // Also append basePath 5468 if (useBasePath != null && !pathMatch.absolute && !pathMatch.relative) { 5469 bp = useBasePath + bp; 5470 } 5471 } else if (useBasePath != null) { 5472 bp = useBasePath; 5473 } 5474 } else { 5475 // Determine Extension, etc. 5476 var match = createjs.RequestUtils.parseURI(item.src); 5477 if (match.extension) { 5478 item.ext = match.extension; 5479 } 5480 if (item.type == null) { 5481 item.type = createjs.RequestUtils.getTypeByExtension(item.ext); 5482 } 5483 5484 // Inject path & basePath 5485 var autoId = item.src; 5486 if (!match.absolute && !match.relative) { 5487 if (path) { 5488 bp = path; 5489 var pathMatch = createjs.RequestUtils.parseURI(path); 5490 autoId = path + autoId; 5491 // Also append basePath 5492 if (useBasePath != null && !pathMatch.absolute && !pathMatch.relative) { 5493 bp = useBasePath + bp; 5494 } 5495 } else if (useBasePath != null) { 5496 bp = useBasePath; 5497 } 5498 } 5499 item.src = bp + item.src; 5500 } 5501 item.path = bp; 5502 5503 // If there's no id, set one now. 5504 if (item.id === undefined || item.id === null || item.id === "") { 5505 item.id = autoId; 5506 } 5507 5508 // Give plugins a chance to modify the loadItem: 5509 var customHandler = this._typeCallbacks[item.type] || this._extensionCallbacks[item.ext]; 5510 if (customHandler) { 5511 // Plugins are now passed both the full source, as well as a combined path+basePath (appropriately) 5512 var result = customHandler.callback.call(customHandler.scope, item, this); 5513 5514 // The plugin will handle the load, or has canceled it. Ignore it. 5515 if (result === false) { 5516 return null; 5517 5518 // Load as normal: 5519 } else if (result === true) { 5520 // Do Nothing 5521 5522 // Result is a loader class: 5523 } else if (result != null) { 5524 item._loader = result; 5525 } 5526 5527 // Update the extension in case the type changed: 5528 match = createjs.RequestUtils.parseURI(item.src); 5529 if (match.extension != null) { 5530 item.ext = match.extension; 5531 } 5532 } 5533 5534 // Store the item for lookup. This also helps clean-up later. 5535 this._loadItemsById[item.id] = item; 5536 this._loadItemsBySrc[item.src] = item; 5537 5538 if (item.crossOrigin == null) { 5539 item.crossOrigin = this._crossOrigin; 5540 } 5541 5542 return item; 5543 }; 5544 5545 /** 5546 * Create a loader for a load item.
5547 * @method _createLoader 5548 * @param {Object} item A formatted load item that can be used to generate a loader. 5549 * @return {AbstractLoader} A loader that can be used to load content. 5550 * @private 5551 */ 5552 p._createLoader = function (item) { 5553 if (item._loader != null) { // A plugin already specified a loader 5554 return item._loader; 5555 } 5556 5557 // Initially, try and use the provided/supported XHR mode: 5558 var preferXHR = this.preferXHR; 5559 5560 for (var i = 0; i < this._availableLoaders.length; i++) { 5561 var loader = this._availableLoaders[i]; 5562 if (loader && loader.canLoadItem(item)) { 5563 return new loader(item, preferXHR); 5564 } 5565 } 5566 5567 // TODO: Log error (requires createjs.log) 5568 return null; 5569 }; 5570 5571 /** 5572 * Load the next item in the queue. If the queue is empty (all items have been loaded), then the complete event 5573 * is processed. The queue will "fill up" any empty slots, up to the max connection specified using 5574 * {{#crossLink "LoadQueue.setMaxConnections"}}{{/crossLink}} method. The only exception is scripts that are loaded 5575 * using tags, which have to be loaded one at a time to maintain load order. 5576 * @method _loadNext 5577 * @private 5578 */ 5579 p._loadNext = function () { 5580 if (this._paused) { 5581 return; 5582 } 5583
5584 // Only dispatch loadstart event when the first file is loaded. 5585 if (!this._loadStartWasDispatched) { 5586 this._sendLoadStart(); 5587 this._loadStartWasDispatched = true; 5588 } 5589 5590 // The queue has completed. 5591 if (this._numItems == this._numItemsLoaded) { 5592 this.loaded = true; 5593 this._sendComplete(); 5594 5595 // Load the next queue, if it has been defined. 5596 if (this.next && this.next.load) { 5597 this.next.load(); 5598 } 5599 } else { 5600 this.loaded = false; 5601 } 5602 5603 // Must iterate forwards to load in the right order. 5604 for (var i = 0; i < this._loadQueue.length; i++) { 5605 if (this._currentLoads.length >= this._maxConnections) { 5606 break; 5607 } 5608 var loader = this._loadQueue[i]; 5609 5610 // Determine if we should be only loading one tag-script at a time: 5611 // Note: maintainOrder items don't do anything here because we can hold onto their loaded value 5612 if (!this._canStartLoad(loader)) { 5613 continue; 5614 } 5615 this._loadQueue.splice(i, 1); 5616 i--; 5617 this._loadItem(loader); 5618 } 5619 }; 5620 5621 /** 5622 * Begin loading an item. Event listeners are not added to the loaders until the load starts. 5623 * @method _loadItem 5624 * @param {AbstractLoader} loader The loader instance to start. Currently, this will be an XHRLoader or TagLoader. 5625 * @private 5626 */ 5627 p._loadItem = function (loader) { 5628 loader.on("fileload", this._handleFileLoad, this); 5629 loader.on("progress", this._handleProgress, this); 5630 loader.on("complete", this._handleFileComplete, this); 5631 loader.on("error", this._handleError, this); 5632 loader.on("fileerror", this._handleFileError, this); 5633 this._currentLoads.push(loader); 5634 this._sendFileStart(loader.getItem()); 5635 loader.load(); 5636 }; 5637 5638 /** 5639 * The callback that is fired when a loader loads a file. This enables loaders like {{#crossLink "ManifestLoader"}}{{/crossLink}} 5640 * to maintain internal queues, but for this queue to dispatch the {{#crossLink "fileload:event"}}{{/crossLink}} 5641 * events. 5642 * @param {Event} event The {{#crossLink "AbstractLoader/fileload:event"}}{{/crossLink}} event from the loader. 5643 * @private 5644 * @since 0.6.0 5645 */ 5646 p._handleFileLoad = function (event) { 5647 event.target = null; 5648 this.dispatchEvent(event); 5649 }; 5650 5651 /** 5652 * The callback that is fired when a loader encounters an error from an internal file load operation. This enables 5653 * loaders like M 5654 * @param event 5655 * @private 5656 */ 5657 p._handleFileError = function (event) { 5658 var newEvent = new createjs.ErrorEvent("FILE_LOAD_ERROR", null, event.item); 5659 this._sendError(newEvent); 5660 }; 5661 5662 /** 5663 * The callback that is fired when a loader encounters an error. The queue will continue loading unless {{#crossLink "LoadQueue/stopOnError:property"}}{{/crossLink}} 5664 * is set to `true`. 5665 * @method _handleError 5666 * @param {ErrorEvent} event The error event, containing relevant error information. 5667 * @private 5668 */ 5669 p._handleError = function (event) { 5670 var loader = event.target; 5671 this._numItemsLoaded++; 5672 5673 this._finishOrderedItem(loader, true); 5674 this._updateProgress(); 5675 5676 var newEvent = new createjs.ErrorEvent("FILE_LOAD_ERROR", null, loader.getItem()); 5677 // TODO: Propagate actual error message. 5678 5679 this._sendError(newEvent); 5680 5681 if (!this.stopOnError) { 5682 this._removeLoadItem(loader); 5683 this._cleanLoadItem(loader); 5684 this._loadNext(); 5685 } else { 5686 this.setPaused(true); 5687 } 5688 }; 5689 5690 /** 5691 * An item has finished loading. We can assume that it is totally loaded, has been parsed for immediate use, and 5692 * is available as the "result" property on the load item. The raw text result for a parsed item (such as JSON, XML, 5693 * CSS, JavaScript, etc) is available as the "rawResult" property, and can also be looked up using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}. 5694 * @method _handleFileComplete 5695 * @param {Event} event The event object from the loader. 5696 * @private 5697 */ 5698 p._handleFileComplete = function (event) { 5699 var loader = event.target; 5700 var item = loader.getItem(); 5701 5702 var result = loader.getResult(); 5703 this._loadedResults[item.id] = result; 5704 var rawResult = loader.getResult(true); 5705 if (rawResult != null && rawResult !== result) { 5706 this._loadedRawResults[item.id] = rawResult; 5707 } 5708 5709 this._saveLoadedItems(loader); 5710 5711 // Remove the load item 5712 this._removeLoadItem(loader); 5713 5714 if (!this._finishOrderedItem(loader)) { 5715 // The item was NOT managed, so process it now 5716 this._processFinishedLoad(item, loader); 5717 } 5718 5719 // Clean up the load item 5720 this._cleanLoadItem(loader); 5721 }; 5722 5723 /** 5724 * Some loaders might load additional content, other than the item they were passed (such as {{#crossLink "ManifestLoader"}}{{/crossLink}}). 5725 * Any items exposed by the loader using {{#crossLink "AbstractLoader/getLoadItems"}}{{/crossLink}} are added to the 5726 * LoadQueue's look-ups, including {{#crossLink "getItem"}}{{/crossLink}} and {{#crossLink "getResult"}}{{/crossLink}} 5727 * methods. 5728 * @method _saveLoadedItems 5729 * @param {AbstractLoader} loader 5730 * @protected 5731 * @since 0.6.0 5732 */ 5733 p._saveLoadedItems = function (loader) { 5734 // TODO: Not sure how to handle this. Would be nice to expose the items. 5735 // Loaders may load sub-items. This adds them to this queue 5736 var list = loader.getLoadedItems(); 5737 if (list === null) { 5738 return; 5739 } 5740 5741 for (var i = 0; i < list.length; i++) { 5742 var item = list[i].item; 5743 5744 // Store item lookups 5745 this._loadItemsBySrc[item.src] = item; 5746 this._loadItemsById[item.id] = item; 5747 5748 // Store loaded content 5749 this._loadedResults[item.id] = list[i].result; 5750 this._loadedRawResults[item.id] = list[i].rawResult; 5751 } 5752 }; 5753 5754 /** 5755 * Flag an item as finished. If the item's order is being managed, then ensure that it is allowed to finish, and if 5756 * so, trigger prior items to trigger as well. 5757 * @method _finishOrderedItem 5758 * @param {AbstractLoader} loader 5759 * @param {Boolean} loadFailed 5760 * @return {Boolean} If the item's order is being managed. This allows the caller to take an alternate 5761 * behaviour if it is. 5762 * @private 5763 */ 5764 p._finishOrderedItem = function (loader, loadFailed) { 5765 var item = loader.getItem(); 5766 5767 if ((this.maintainScriptOrder && item.type == createjs.LoadQueue.JAVASCRIPT) 5768 || item.maintainOrder) { 5769 5770 //TODO: Evaluate removal of the _currentlyLoadingScript 5771 if (loader instanceof createjs.JavaScriptLoader) { 5772 this._currentlyLoadingScript = false;
5773 } 5774 5775 var index = createjs.indexOf(this._scriptOrder, item); 5776 if (index == -1) { 5777 return false; 5778 } // This loader no longer exists 5779 this._loadedScripts[index] = (loadFailed === true) ? true : item; 5780 5781 this._checkScriptLoadOrder(); 5782 return true; 5783 } 5784 5785 return false; 5786 }; 5787 5788 /** 5789 * Ensure the scripts load and dispatch in the correct order. When using XHR, scripts are stored in an array in the 5790 * order they were added, but with a "null" value. When they are completed, the value is set to the load item, 5791 * and then when they are processed and dispatched, the value is set to `true`. This method simply 5792 * iterates the array, and ensures that any loaded items that are not preceded by a `null` value are 5793 * dispatched. 5794 * @method _checkScriptLoadOrder 5795 * @private 5796 */ 5797 p._checkScriptLoadOrder = function () { 5798 var l = this._loadedScripts.length; 5799 5800 for (var i = 0; i < l; i++) { 5801 var item = this._loadedScripts[i]; 5802 if (item === null) { 5803 break; 5804 } // This is still loading. Do not process further. 5805 if (item === true) { 5806 continue; 5807 } // This has completed, and been processed. Move on. 5808 5809 var loadItem = this._loadedResults[item.id]; 5810 if (item.type == createjs.LoadQueue.JAVASCRIPT) { 5811 // Append script tags to the head automatically. 5812 createjs.DomUtils.appendToHead(loadItem); 5813 } 5814 5815 var loader = item._loader; 5816 this._processFinishedLoad(item, loader); 5817 this._loadedScripts[i] = true; 5818 } 5819 }; 5820 5821 /** 5822 * A file has completed loading, and the LoadQueue can move on. This triggers the complete event, and kick-starts 5823 * the next item. 5824 * @method _processFinishedLoad 5825 * @param {LoadItem|Object} item 5826 * @param {AbstractLoader} loader 5827 * @protected 5828 */ 5829 p._processFinishedLoad = function (item, loader) { 5830 this._numItemsLoaded++; 5831 5832 // Since LoadQueue needs maintain order, we can't append scripts in the loader. 5833 // So we do it here instead. Or in _checkScriptLoadOrder(); 5834 if (!this.maintainScriptOrder && item.type == createjs.LoadQueue.JAVASCRIPT) { 5835 var tag = loader.getTag(); 5836 createjs.DomUtils.appendToHead(tag); 5837 } 5838 5839 this._updateProgress(); 5840 this._sendFileComplete(item, loader); 5841 this._loadNext(); 5842 }; 5843 5844 /** 5845 * Ensure items with `maintainOrder=true` that are before the specified item have loaded. This only applies to 5846 * JavaScript items that are being loaded with a TagLoader, since they have to be loaded and completed <strong>before</strong> 5847 * the script can even be started, since it exist in the DOM while loading. 5848 * @method _canStartLoad 5849 * @param {AbstractLoader} loader The loader for the item 5850 * @return {Boolean} Whether the item can start a load or not. 5851 * @private 5852 */ 5853 p._canStartLoad = function (loader) { 5854 if (!this.maintainScriptOrder || loader.preferXHR) { 5855 return true; 5856 } 5857 var item = loader.getItem(); 5858 if (item.type != createjs.LoadQueue.JAVASCRIPT) { 5859 return true; 5860 } 5861 if (this._currentlyLoadingScript) { 5862 return false; 5863 } 5864 5865 var index = this._scriptOrder.indexOf(item); 5866 var i = 0; 5867 while (i < index) { 5868 var checkItem = this._loadedScripts[i]; 5869 if (checkItem == null) { 5870 return false; 5871 } 5872 i++; 5873 } 5874 this._currentlyLoadingScript = true; 5875 return true; 5876 }; 5877 5878 /** 5879 * A load item is completed or was canceled, and needs to be removed from the LoadQueue. 5880 * @method _removeLoadItem 5881 * @param {AbstractLoader} loader A loader instance to remove. 5882 * @private 5883 */ 5884 p._removeLoadItem = function (loader) { 5885 var l = this._currentLoads.length; 5886 for (var i = 0; i < l; i++) { 5887 if (this._currentLoads[i] == loader) { 5888 this._currentLoads.splice(i, 1); 5889 break; 5890 } 5891 } 5892 }; 5893 5894 /** 5895 * Remove unneeded references from a loader. 5896 * 5897 * @param loader 5898 * @private 5899 */ 5900 p._cleanLoadItem = function(loader) { 5901 var item = loader.getItem(); 5902 if (item) { 5903 delete item._loader; 5904 } 5905 } 5906 5907 /** 5908 * An item has dispatched progress. Propagate that progress, and update the LoadQueue's overall progress. 5909 * @method _handleProgress 5910 * @param {ProgressEvent} event The progress event from the item. 5911 * @private 5912 */ 5913 p._handleProgress = function (event) { 5914 var loader = event.target; 5915 this._sendFileProgress(loader.getItem(), loader.progress); 5916 this._updateProgress(); 5917 }; 5918 5919 /** 5920 * Overall progress has changed, so determine the new progress amount and dispatch it. This changes any time an 5921 * item dispatches progress or completes. Note that since we don't always know the actual filesize of items before 5922 * they are loaded. In this case, we define a "slot" for each item (1 item in 10 would get 10%), and then append 5923 * loaded progress on top of the already-loaded items. 5924 * 5925 * For example, if 5/10 items have loaded, and item 6 is 20% loaded, the total progress would be: 5926 * <ul> 5927 * <li>5/10 of the items in the queue (50%)</li> 5928 * <li>plus 20% of item 6's slot (2%)</li> 5929 * <li>equals 52%</li> 5930 * </ul> 5931 * @method _updateProgress 5932 * @private 5933 */ 5934 p._updateProgress = function () { 5935 var loaded = this._numItemsLoaded / this._numItems; // Fully Loaded Progress 5936 var remaining = this._numItems - this._numItemsLoaded; 5937 if (remaining > 0) { 5938 var chunk = 0; 5939 for (var i = 0, l = this._currentLoads.length; i < l; i++) { 5940 chunk += this._currentLoads[i].progress; 5941 } 5942 loaded += (chunk / remaining) * (remaining / this._numItems); 5943 } 5944 5945 if (this._lastProgress != loaded) { 5946 this._sendProgress(loaded); 5947 this._lastProgress = loaded; 5948 } 5949 }; 5950 5951 /** 5952 * Clean out item results, to free them from memory. Mainly, the loaded item and results are cleared from internal 5953 * hashes. 5954 * @method _disposeItem 5955 * @param {LoadItem|Object} item The item that was passed in for preloading. 5956 * @private 5957 */ 5958 p._disposeItem = function (item) { 5959 delete this._loadedResults[item.id]; 5960 delete this._loadedRawResults[item.id]; 5961 delete this._loadItemsById[item.id]; 5962 delete this._loadItemsBySrc[item.src]; 5963 }; 5964 5965 /** 5966 * Dispatch a "fileprogress" {{#crossLink "Event"}}{{/crossLink}}. Please see the LoadQueue {{#crossLink "LoadQueue/fileprogress:event"}}{{/crossLink}} 5967 * event for details on the event payload. 5968 * @method _sendFileProgress 5969 * @param {LoadItem|Object} item The item that is being loaded. 5970 * @param {Number} progress The amount the item has been loaded (between 0 and 1). 5971 * @protected 5972 */ 5973 p._sendFileProgress = function (item, progress) { 5974 if (this._isCanceled() || this._paused) { 5975 return; 5976 } 5977 if (!this.hasEventListener("fileprogress")) { 5978 return; 5979 } 5980
5981 //LM: Rework ProgressEvent to support this? 5982 var event = new createjs.Event("fileprogress"); 5983 event.progress = progress; 5984 event.loaded = progress; 5985 event.total = 1; 5986 event.item = item; 5987 5988 this.dispatchEvent(event); 5989 }; 5990 5991 /** 5992 * Dispatch a fileload {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event for 5993 * details on the event payload. 5994 * @method _sendFileComplete 5995 * @param {LoadItemObject} item The item that is being loaded. 5996 * @param {AbstractLoader} loader 5997 * @protected 5998 */ 5999 p._sendFileComplete = function (item, loader) { 6000 if (this._isCanceled() || this._paused) { 6001 return; 6002 } 6003 6004 var event = new createjs.Event("fileload"); 6005 event.loader = loader; 6006 event.item = item; 6007 event.result = this._loadedResults[item.id]; 6008 event.rawResult = this._loadedRawResults[item.id]; 6009 6010 // This calls a handler specified on the actual load item. Currently, the SoundJS plugin uses this. 6011 if (item.completeHandler) { 6012 item.completeHandler(event); 6013 } 6014 6015 this.hasEventListener("fileload") && this.dispatchEvent(event); 6016 }; 6017 6018 /** 6019 * Dispatch a filestart {{#crossLink "Event"}}{{/crossLink}} immediately before a file starts to load. Please see 6020 * the {{#crossLink "LoadQueue/filestart:event"}}{{/crossLink}} event for details on the event payload. 6021 * @method _sendFileStart 6022 * @param {LoadItem|Object} item The item that is being loaded. 6023 * @protected 6024 */ 6025 p._sendFileStart = function (item) { 6026 var event = new createjs.Event("filestart"); 6027 event.item = item; 6028 this.hasEventListener("filestart") && this.dispatchEvent(event); 6029 }; 6030 6031 p.toString = function () { 6032 return "[PreloadJS LoadQueue]"; 6033 }; 6034 6035 createjs.LoadQueue = createjs.promote(LoadQueue, "AbstractLoader"); 6036}()); 6037 6038//############################################################################## 6039// TextLoader.js 6040//############################################################################## 6041 6042this.createjs = this.createjs || {}; 6043 6044(function () { 6045 "use strict"; 6046 6047 // constructor 6048 /** 6049 * A loader for Text files. 6050 * @class TextLoader 6051 * @param {LoadItem|Object} loadItem 6052 * @extends AbstractLoader 6053 * @constructor 6054 */ 6055 function TextLoader(loadItem) { 6056 this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.TEXT); 6057 }; 6058 6059 var p = createjs.extend(TextLoader, createjs.AbstractLoader); 6060 var s = TextLoader; 6061 6062 // static methods 6063 /** 6064 * Determines if the loader can load a specific item. This loader loads items that are of type {{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}}, 6065 * but is also the default loader if a file type can not be determined. 6066 * @method canLoadItem 6067 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6068 * @returns {Boolean} Whether the loader can load the item. 6069 * @static 6070 */ 6071 s.canLoadItem = function (item) { 6072 return item.type == createjs.AbstractLoader.TEXT; 6073 }; 6074 6075 createjs.TextLoader = createjs.promote(TextLoader, "AbstractLoader"); 6076 6077}()); 6078 6079//############################################################################## 6080// BinaryLoader.js 6081//############################################################################## 6082 6083this.createjs = this.createjs || {}; 6084 6085(function () { 6086 "use strict"; 6087 6088 // constructor 6089 /** 6090 * A loader for binary files. This is useful for loading web audio, or content that requires an ArrayBuffer. 6091 * @class BinaryLoader 6092 * @param {LoadItem|Object} loadItem 6093 * @extends AbstractLoader 6094 * @constructor 6095 */ 6096 function BinaryLoader(loadItem) { 6097 this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.BINARY); 6098 this.on("initialize", this._updateXHR, this); 6099 }; 6100 6101 var p = createjs.extend(BinaryLoader, createjs.AbstractLoader); 6102 var s = BinaryLoader; 6103 6104 // static methods 6105 /** 6106 * Determines if the loader can load a specific item. This loader can only load items that are of type 6107 * {{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}} 6108 * @method canLoadItem 6109 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6110 * @returns {Boolean} Whether the loader can load the item. 6111 * @static 6112 */
6113 s.canLoadItem = function (item) { 6114 return item.type == createjs.AbstractLoader.BINARY; 6115 }; 6116 6117 // private methods 6118 /** 6119 * Before the item loads, set the response type to "arraybuffer" 6120 * @property _updateXHR 6121 * @param {Event} event 6122 * @private 6123 */ 6124 p._updateXHR = function (event) { 6125 event.loader.setResponseType("arraybuffer"); 6126 }; 6127 6128 createjs.BinaryLoader = createjs.promote(BinaryLoader, "AbstractLoader"); 6129 6130}()); 6131 6132//############################################################################## 6133// CSSLoader.js 6134//############################################################################## 6135 6136this.createjs = this.createjs || {}; 6137 6138(function () { 6139 "use strict"; 6140 6141 // constructor 6142 /** 6143 * A loader for CSS files. 6144 * @class CSSLoader 6145 * @param {LoadItem|Object} loadItem 6146 * @param {Boolean} preferXHR 6147 * @extends AbstractLoader 6148 * @constructor 6149 */ 6150 function CSSLoader(loadItem, preferXHR) { 6151 this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.CSS); 6152 6153 // public properties 6154 this.resultFormatter = this._formatResult; 6155 6156 // protected properties 6157 this._tagSrcAttribute = "href"; 6158 6159 if (preferXHR) { 6160 this._tag = document.createElement("style"); 6161 } else { 6162 this._tag = document.createElement("link"); 6163 } 6164 6165 this._tag.rel = "stylesheet"; 6166 this._tag.type = "text/css"; 6167 }; 6168 6169 var p = createjs.extend(CSSLoader, createjs.AbstractLoader); 6170 var s = CSSLoader; 6171 6172 // static methods 6173 /** 6174 * Determines if the loader can load a specific item. This loader can only load items that are of type 6175 * {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}}. 6176 * @method canLoadItem 6177 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6178 * @returns {Boolean} Whether the loader can load the item. 6179 * @static 6180 */ 6181 s.canLoadItem = function (item) { 6182 return item.type == createjs.AbstractLoader.CSS; 6183 }; 6184 6185 // protected methods 6186 /** 6187 * The result formatter for CSS files. 6188 * @method _formatResult 6189 * @param {AbstractLoader} loader 6190 * @returns {HTMLLinkElement|HTMLStyleElement} 6191 * @private 6192 */ 6193 p._formatResult = function (loader) { 6194 if (this._preferXHR) { 6195 var tag = loader.getTag(); 6196 6197 if (tag.styleSheet) { // IE 6198 tag.styleSheet.cssText = loader.getResult(true); 6199 } else { 6200 var textNode = document.createTextNode(loader.getResult(true)); 6201 tag.appendChild(textNode); 6202 } 6203 } else { 6204 tag = this._tag; 6205 } 6206 6207 createjs.DomUtils.appendToHead(tag); 6208 6209 return tag; 6210 }; 6211 6212 createjs.CSSLoader = createjs.promote(CSSLoader, "AbstractLoader"); 6213 6214}()); 6215 6216//############################################################################## 6217// ImageLoader.js 6218//############################################################################## 6219 6220this.createjs = this.createjs || {}; 6221 6222(function () { 6223 "use strict"; 6224 6225 // constructor 6226 /** 6227 * A loader for image files. 6228 * @class ImageLoader 6229 * @param {LoadItem|Object} loadItem 6230 * @param {Boolean} preferXHR 6231 * @extends AbstractLoader 6232 * @constructor 6233 */ 6234 function ImageLoader (loadItem, preferXHR) { 6235 this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.IMAGE); 6236 6237 // public properties 6238 this.resultFormatter = this._formatResult; 6239 6240 // protected properties 6241 this._tagSrcAttribute = "src"; 6242 6243 // Check if the preload item is already a tag. 6244 if (createjs.RequestUtils.isImageTag(loadItem)) { 6245 this._tag = loadItem; 6246 } else if (createjs.RequestUtils.isImageTag(loadItem.src)) { 6247 this._tag = loadItem.src; 6248 } else if (createjs.RequestUtils.isImageTag(loadItem.tag)) { 6249 this._tag = loadItem.tag; 6250 } 6251 6252 if (this._tag != null) { 6253 this._preferXHR = false; 6254 } else { 6255 this._tag = document.createElement("img"); 6256 } 6257 6258 this.on("initialize", this._updateXHR, this); 6259 }; 6260 6261 var p = createjs.extend(ImageLoader, createjs.AbstractLoader); 6262 var s = ImageLoader; 6263 6264 // static methods 6265 /** 6266 * Determines if the loader can load a specific item. This loader can only load items that are of type 6267 * {{#crossLink "AbstractLoader/IMAGE:property"}}{{/crossLink}}. 6268 * @method canLoadItem 6269 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6270 * @returns {Boolean} Whether the loader can load the item. 6271 * @static 6272 */
6273 s.canLoadItem = function (item) { 6274 return item.type == createjs.AbstractLoader.IMAGE; 6275 }; 6276 6277 // public methods 6278 p.load = function () { 6279 if (this._tag.src != "" && this._tag.complete) { 6280 this._sendComplete(); 6281 return; 6282 } 6283 6284 var crossOrigin = this._item.crossOrigin; 6285 if (crossOrigin == true) { crossOrigin = "Anonymous"; } 6286 if (crossOrigin != null && !createjs.RequestUtils.isLocal(this._item.src)) { 6287 this._tag.crossOrigin = crossOrigin; 6288 } 6289 6290 this.AbstractLoader_load(); 6291 }; 6292 6293 // protected methods 6294 /** 6295 * Before the item loads, set its mimeType and responseType. 6296 * @property _updateXHR 6297 * @param {Event} event 6298 * @private 6299 */ 6300 p._updateXHR = function (event) { 6301 event.loader.mimeType = 'text/plain; charset=x-user-defined-binary'; 6302 6303 // Only exists for XHR 6304 if (event.loader.setResponseType) { 6305 event.loader.setResponseType("blob"); 6306 } 6307 }; 6308 6309 /** 6310 * The result formatter for Image files. 6311 * @method _formatResult 6312 * @param {AbstractLoader} loader 6313 * @returns {HTMLImageElement} 6314 * @private 6315 */ 6316 p._formatResult = function (loader) { 6317 return this._formatImage; 6318 }; 6319 6320 /** 6321 * The asynchronous image formatter function. This is required because images have 6322 * a short delay before they are ready. 6323 * @method _formatImage 6324 * @param {Function} successCallback The method to call when the result has finished formatting 6325 * @param {Function} errorCallback The method to call if an error occurs during formatting 6326 * @private 6327 */ 6328 p._formatImage = function (successCallback, errorCallback) { 6329 var tag = this._tag; 6330 var URL = window.URL || window.webkitURL; 6331 6332 if (!this._preferXHR) { 6333 //document.body.removeChild(tag); 6334 } else if (URL) { 6335 var objURL = URL.createObjectURL(this.getResult(true)); 6336 tag.src = objURL; 6337 6338 tag.addEventListener("load", this._cleanUpURL, false); 6339 tag.addEventListener("error", this._cleanUpURL, false); 6340 } else { 6341 tag.src = this._item.src; 6342 } 6343 6344 if (tag.complete) { 6345 successCallback(tag); 6346 } else { 6347 tag.onload = createjs.proxy(function() { 6348 successCallback(this._tag); 6349 }, this); 6350 6351 tag.onerror = createjs.proxy(function() { 6352 errorCallback(_this._tag); 6353 }, this); 6354 } 6355 }; 6356 6357 /** 6358 * Clean up the ObjectURL, the tag is done with it. Note that this function is run 6359 * as an event listener without a proxy/closure, as it doesn't require it - so do not 6360 * include any functionality that requires scope without changing it. 6361 * @method _cleanUpURL 6362 * @param event 6363 * @private 6364 */ 6365 p._cleanUpURL = function (event) { 6366 var URL = window.URL || window.webkitURL; 6367 URL.revokeObjectURL(event.target.src); 6368 }; 6369 6370 createjs.ImageLoader = createjs.promote(ImageLoader, "AbstractLoader"); 6371 6372}()); 6373 6374//############################################################################## 6375// JavaScriptLoader.js 6376//############################################################################## 6377 6378this.createjs = this.createjs || {}; 6379 6380(function () { 6381 "use strict"; 6382 6383 // constructor 6384 /** 6385 * A loader for JavaScript files. 6386 * @class JavaScriptLoader 6387 * @param {LoadItem|Object} loadItem 6388 * @param {Boolean} preferXHR 6389 * @extends AbstractLoader 6390 * @constructor 6391 */ 6392 function JavaScriptLoader(loadItem, preferXHR) { 6393 this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.JAVASCRIPT); 6394 6395 // public properties 6396 this.resultFormatter = this._formatResult; 6397 6398 // protected properties 6399 this._tagSrcAttribute = "src"; 6400 this.setTag(document.createElement("script")); 6401 }; 6402 6403 var p = createjs.extend(JavaScriptLoader, createjs.AbstractLoader); 6404 var s = JavaScriptLoader; 6405 6406 // static methods 6407 /** 6408 * Determines if the loader can load a specific item. This loader can only load items that are of type 6409 * {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} 6410 * @method canLoadItem 6411 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6412 * @returns {Boolean} Whether the loader can load the item. 6413 * @static 6414 */ 6415 s.canLoadItem = function (item) { 6416 return item.type == createjs.AbstractLoader.JAVASCRIPT; 6417 }; 6418 6419 // protected methods 6420 /** 6421 * The result formatter for JavaScript files. 6422 * @method _formatResult 6423 * @param {AbstractLoader} loader 6424 * @returns {HTMLLinkElement|HTMLStyleElement} 6425 * @private 6426 */ 6427 p._formatResult = function (loader) { 6428 var tag = loader.getTag(); 6429 if (this._preferXHR) { 6430 tag.text = loader.getResult(true); 6431 } 6432 return tag; 6433 }; 6434 6435 createjs.JavaScriptLoader = createjs.promote(JavaScriptLoader, "AbstractLoader"); 6436 6437}()); 6438 6439//############################################################################## 6440// JSONLoader.js 6441//############################################################################## 6442 6443this.createjs = this.createjs || {}; 6444 6445(function () { 6446 "use strict"; 6447 6448 // constructor 6449 /** 6450 * A loader for JSON files. To load JSON cross-domain, use JSONP and the {{#crossLink "JSONPLoader"}}{{/crossLink}} 6451 * instead. To load JSON-formatted manifests, use {{#crossLink "ManifestLoader"}}{{/crossLink}}, and to 6452 * load EaselJS SpriteSheets, use {{#crossLink "SpriteSheetLoader"}}{{/crossLink}}. 6453 * @class JSONLoader 6454 * @param {LoadItem|Object} loadItem 6455 * @extends AbstractLoader 6456 * @constructor 6457 */ 6458 function JSONLoader(loadItem) { 6459 this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.JSON); 6460 6461 // public properties 6462 this.resultFormatter = this._formatResult; 6463 }; 6464
6465 var p = createjs.extend(JSONLoader, createjs.AbstractLoader); 6466 var s = JSONLoader; 6467 6468 // static methods 6469 /** 6470 * Determines if the loader can load a specific item. This loader can only load items that are of type 6471 * {{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}}. 6472 * @method canLoadItem 6473 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6474 * @returns {Boolean} Whether the loader can load the item. 6475 * @static 6476 */ 6477 s.canLoadItem = function (item) { 6478 return item.type == createjs.AbstractLoader.JSON; 6479 }; 6480 6481 // protected methods 6482 /** 6483 * The result formatter for JSON files. 6484 * @method _formatResult 6485 * @param {AbstractLoader} loader 6486 * @returns {HTMLLinkElement|HTMLStyleElement} 6487 * @private 6488 */ 6489 p._formatResult = function (loader) { 6490 var json = null; 6491 try { 6492 json = createjs.DataUtils.parseJSON(loader.getResult(true)); 6493 } catch (e) { 6494 var event = new createjs.ErrorEvent("JSON_FORMAT", null, e); 6495 this._sendError(event); 6496 return e; 6497 } 6498 6499 return json; 6500 }; 6501 6502 createjs.JSONLoader = createjs.promote(JSONLoader, "AbstractLoader"); 6503 6504}()); 6505 6506//############################################################################## 6507// JSONPLoader.js 6508//############################################################################## 6509 6510this.createjs = this.createjs || {}; 6511 6512(function () { 6513 "use strict"; 6514 6515 // constructor 6516 /** 6517 * A loader for JSONP files, which are JSON-formatted text files, wrapped in a callback. To load regular JSON 6518 * without a callback use the {{#crossLink "JSONLoader"}}{{/crossLink}} instead. To load JSON-formatted manifests, 6519 * use {{#crossLink "ManifestLoader"}}{{/crossLink}}, and to load EaselJS SpriteSheets, use 6520 * {{#crossLink "SpriteSheetLoader"}}{{/crossLink}}. 6521 * 6522 * JSONP is a format that provides a solution for loading JSON files cross-domain <em>without</em> requiring CORS. 6523 * JSONP files are loaded as JavaScript, and the "callback" is executed once they are loaded. The callback in the 6524 * JSONP must match the callback passed to the loadItem. 6525 * 6526 * <h4>Example JSONP</h4> 6527 * 6528 * callbackName({ 6529 * "name": "value", 6530 * "num": 3, 6531 * "obj": { "bool":true } 6532 * }); 6533 * 6534 * <h4>Example</h4> 6535 * 6536 * var loadItem = {id:"json", type:"jsonp", src:"http://server.com/text.json", callback:"callbackName"} 6537 * var queue = new createjs.LoadQueue(); 6538 * queue.on("complete", handleComplete); 6539 * queue.loadItem(loadItem); 6540 * 6541 * function handleComplete(event) } 6542 * var json = queue.getResult("json"); 6543 * console.log(json.obj.bool); // true 6544 * } 6545 * 6546 * Note that JSONP files loaded concurrently require a <em>unique</em> callback. To ensure JSONP files are loaded 6547 * in order, either use the {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}} method (set to 1), 6548 * or set {{#crossLink "LoadItem/maintainOrder:property"}}{{/crossLink}} on items with the same callback. 6549 * 6550 * @class JSONPLoader 6551 * @param {LoadItem|Object} loadItem 6552 * @extends AbstractLoader 6553 * @constructor 6554 */ 6555 function JSONPLoader(loadItem) { 6556 this.AbstractLoader_constructor(loadItem, false, createjs.AbstractLoader.JSONP); 6557 this.setTag(document.createElement("script")); 6558 this.getTag().type = "text/javascript"; 6559 }; 6560 6561 var p = createjs.extend(JSONPLoader, createjs.AbstractLoader); 6562 var s = JSONPLoader; 6563 6564 6565 // static methods 6566 /** 6567 * Determines if the loader can load a specific item. This loader can only load items that are of type 6568 * {{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}}. 6569 * @method canLoadItem 6570 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6571 * @returns {Boolean} Whether the loader can load the item. 6572 * @static 6573 */ 6574 s.canLoadItem = function (item) { 6575 return item.type == createjs.AbstractLoader.JSONP; 6576 }; 6577 6578 // public methods 6579 p.cancel = function () { 6580 this.AbstractLoader_cancel(); 6581 this._dispose(); 6582 }; 6583 6584 /** 6585 * Loads the JSONp file. Because of the unique loading needs of JSONp 6586 * we don't use the AbstractLoader.load() method. 6587 * 6588 * @method load 6589 * 6590 */ 6591 p.load = function () { 6592 if (this._item.callback == null) { 6593 throw new Error('callback is required for loading JSONP requests.'); 6594 } 6595 6596 // TODO: Look into creating our own iFrame to handle the load 6597 // In the first attempt, FF did not get the result 6598 // result instanceof Object did not work either 6599 // so we would need to clone the result. 6600 if (window[this._item.callback] != null) { 6601 throw new Error( 6602 "JSONP callback '" + 6603 this._item.callback + 6604 "' already exists on window. You need to specify a different callback or re-name the current one."); 6605 } 6606 6607 window[this._item.callback] = createjs.proxy(this._handleLoad, this); 6608 window.document.body.appendChild(this._tag); 6609 6610 this._loadTimeout = setTimeout(createjs.proxy(this._handleTimeout, this), this._item.loadTimeout); 6611 6612 // Load the tag 6613 this._tag.src = this._item.src; 6614 }; 6615 6616 // private methods 6617 /** 6618 * Handle the JSONP callback, which is a public method defined on `window`. 6619 * @method _handleLoad 6620 * @param {Object} data The formatted JSON data. 6621 * @private 6622 */ 6623 p._handleLoad = function (data) { 6624 this._result = this._rawResult = data; 6625 this._sendComplete(); 6626 6627 this._dispose(); 6628 }; 6629 6630 /** 6631 * The tag request has not loaded within the time specfied in loadTimeout. 6632 * @method _handleError 6633 * @param {Object} event The XHR error event. 6634 * @private 6635 */ 6636 p._handleTimeout = function () { 6637 this._dispose(); 6638 this.dispatchEvent(new createjs.ErrorEvent("timeout")); 6639 }; 6640 6641 /** 6642 * Clean up the JSONP load. This clears out the callback and script tag that this loader creates. 6643 * @method _dispose 6644 * @private 6645 */ 6646 p._dispose = function () { 6647 window.document.body.removeChild(this._tag); 6648 delete window[this._item.callback]; 6649 6650 clearTimeout(this._loadTimeout); 6651 }; 6652 6653 createjs.JSONPLoader = createjs.promote(JSONPLoader, "AbstractLoader"); 6654 6655}()); 6656 6657//############################################################################## 6658// ManifestLoader.js 6659//############################################################################## 6660 6661this.createjs = this.createjs || {}; 6662 6663(function () { 6664 "use strict"; 6665 6666 // constructor 6667 /** 6668 * A loader for JSON manifests. Items inside the manifest are loaded before the loader completes. To load manifests 6669 * using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} as part of the 6670 * {{#crossLink "LoadItem"}}{{/crossLink}}. 6671 * 6672 * The list of files in the manifest must be defined on the top-level JSON object in a `manifest` property. This 6673 * example shows a sample manifest definition, as well as how to to include a sub-manifest. 6674 * 6675 * { 6676 * "path": "assets/", 6677 * "manifest": [ 6678 * "image.png", 6679 * {"src": "image2.png", "id":"image2"}, 6680 * {"src": "sub-manifest.json", "type":"manifest", "callback":"jsonCallback"} 6681 * ] 6682 * } 6683 * 6684 * When a ManifestLoader has completed loading, the parent loader (usually a {{#crossLink "LoadQueue"}}{{/crossLink}}, 6685 * but could also be another ManifestLoader) will inherit all the loaded items, so you can access them directly. 6686 * 6687 * Note that the {{#crossLink "JSONLoader"}}{{/crossLink}} and {{#crossLink "JSONPLoader"}}{{/crossLink}} are 6688 * higher priority loaders, so manifests <strong>must</strong> set the {{#crossLink "LoadItem"}}{{/crossLink}} 6689 * {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property to {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}. 6690 * @class ManifestLoader 6691 * @param {LoadItem|Object} loadItem 6692 * @extends AbstractLoader 6693 * @constructor 6694 */ 6695 function ManifestLoader(loadItem) { 6696 this.AbstractLoader_constructor(loadItem, null, createjs.AbstractLoader.MANIFEST); 6697 6698 // Public Properties 6699 /** 6700 * An array of the plugins registered using {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}}, 6701 * used to pass plugins to new LoadQueues that may be created. 6702 * @property _plugins 6703 * @type {Array} 6704 * @private 6705 * @since 0.6.1 6706 */ 6707 this.plugins = null; 6708 6709 6710 // Protected Properties 6711 /** 6712 * An internal {{#crossLink "LoadQueue"}}{{/crossLink}} that loads the contents of the manifest. 6713 * @property _manifestQueue 6714 * @type {LoadQueue} 6715 * @private 6716 */ 6717 this._manifestQueue = null; 6718 }; 6719
6720 var p = createjs.extend(ManifestLoader, createjs.AbstractLoader); 6721 var s = ManifestLoader; 6722 6723 // static properties 6724 /** 6725 * The amount of progress that the manifest itself takes up. 6726 * @property MANIFEST_PROGRESS 6727 * @type {number} 6728 * @default 0.25 (25%) 6729 * @private 6730 * @static 6731 */ 6732 s.MANIFEST_PROGRESS = 0.25; 6733 6734 // static methods 6735 /** 6736 * Determines if the loader can load a specific item. This loader can only load items that are of type 6737 * {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}} 6738 * @method canLoadItem 6739 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6740 * @returns {Boolean} Whether the loader can load the item. 6741 * @static 6742 */ 6743 s.canLoadItem = function (item) { 6744 return item.type == createjs.AbstractLoader.MANIFEST; 6745 }; 6746 6747 // public methods 6748 p.load = function () { 6749 this.AbstractLoader_load(); 6750 }; 6751 6752 // protected methods 6753 p._createRequest = function() { 6754 var callback = this._item.callback; 6755 if (callback != null) { 6756 this._request = new createjs.JSONPLoader(this._item); 6757 } else { 6758 this._request = new createjs.JSONLoader(this._item); 6759 } 6760 }; 6761 6762 p.handleEvent = function (event) { 6763 switch (event.type) { 6764 case "complete": 6765 this._rawResult = event.target.getResult(true); 6766 this._result = event.target.getResult(); 6767 this._sendProgress(s.MANIFEST_PROGRESS); 6768 this._loadManifest(this._result); 6769 return; 6770 case "progress": 6771 event.loaded *= s.MANIFEST_PROGRESS; 6772 this.progress = event.loaded / event.total; 6773 if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; } 6774 this._sendProgress(event); 6775 return; 6776 } 6777 this.AbstractLoader_handleEvent(event); 6778 }; 6779 6780 p.destroy = function() { 6781 this.AbstractLoader_destroy(); 6782 this._manifestQueue.close(); 6783 }; 6784 6785 /** 6786 * Create and load the manifest items once the actual manifest has been loaded. 6787 * @method _loadManifest 6788 * @param {Object} json 6789 * @private 6790 */ 6791 p._loadManifest = function (json) { 6792 if (json && json.manifest) { 6793 var queue = this._manifestQueue = new createjs.LoadQueue(); 6794 queue.on("fileload", this._handleManifestFileLoad, this); 6795 queue.on("progress", this._handleManifestProgress, this); 6796 queue.on("complete", this._handleManifestComplete, this, true); 6797 queue.on("error", this._handleManifestError, this, true); 6798 for(var i = 0, l = this.plugins.length; i < l; i++) { // conserve order of plugins 6799 queue.installPlugin(this.plugins[i]); 6800 } 6801 queue.loadManifest(json); 6802 } else { 6803 this._sendComplete(); 6804 } 6805 }; 6806 6807 /** 6808 * An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed. 6809 * @method _handleManifestFileLoad 6810 * @param {Event} event 6811 * @private 6812 */ 6813 p._handleManifestFileLoad = function (event) { 6814 event.target = null; 6815 this.dispatchEvent(event); 6816 }; 6817 6818 /** 6819 * The manifest has completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} 6820 * {{#crossLink "Event"}}{{/crossLink}} from the ManifestLoader. 6821 * @method _handleManifestComplete 6822 * @param {Event} event 6823 * @private 6824 */ 6825 p._handleManifestComplete = function (event) { 6826 this._loadedItems = this._manifestQueue.getItems(true); 6827 this._sendComplete(); 6828 }; 6829 6830 /** 6831 * The manifest has reported progress. 6832 * @method _handleManifestProgress 6833 * @param {ProgressEvent} event 6834 * @private 6835 */ 6836 p._handleManifestProgress = function (event) { 6837 this.progress = event.progress * (1 - s.MANIFEST_PROGRESS) + s.MANIFEST_PROGRESS; 6838 this._sendProgress(this.progress); 6839 }; 6840 6841 /** 6842 * The manifest has reported an error with one of the files. 6843 * @method _handleManifestError 6844 * @param {ErrorEvent} event 6845 * @private 6846 */ 6847 p._handleManifestError = function (event) { 6848 var newEvent = new createjs.Event("fileerror"); 6849 newEvent.item = event.data; 6850 this.dispatchEvent(newEvent); 6851 }; 6852 6853 createjs.ManifestLoader = createjs.promote(ManifestLoader, "AbstractLoader"); 6854 6855}()); 6856 6857//############################################################################## 6858// SoundLoader.js 6859//############################################################################## 6860 6861this.createjs = this.createjs || {}; 6862 6863(function () { 6864 "use strict"; 6865 6866 // constructor 6867 /** 6868 * A loader for HTML audio files. PreloadJS can not load WebAudio files, as a WebAudio context is required, which 6869 * should be created by either a library playing the sound (such as <a href="http://soundjs.com">SoundJS</a>, or an 6870 * external framework that handles audio playback. To load content that can be played by WebAudio, use the 6871 * {{#crossLink "BinaryLoader"}}{{/crossLink}}, and handle the audio context decoding manually. 6872 * @class SoundLoader 6873 * @param {LoadItem|Object} loadItem 6874 * @param {Boolean} preferXHR 6875 * @extends AbstractMediaLoader 6876 * @constructor 6877 */ 6878 function SoundLoader(loadItem, preferXHR) { 6879 this.AbstractMediaLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.SOUND); 6880 6881 // protected properties 6882 if (createjs.RequestUtils.isAudioTag(loadItem)) { 6883 this._tag = loadItem; 6884 } else if (createjs.RequestUtils.isAudioTag(loadItem.src)) { 6885 this._tag = loadItem; 6886 } else if (createjs.RequestUtils.isAudioTag(loadItem.tag)) { 6887 this._tag = createjs.RequestUtils.isAudioTag(loadItem) ? loadItem : loadItem.src; 6888 } 6889 6890 if (this._tag != null) { 6891 this._preferXHR = false;
6892 } 6893 }; 6894 6895 var p = createjs.extend(SoundLoader, createjs.AbstractMediaLoader); 6896 var s = SoundLoader; 6897 6898 // static methods 6899 /** 6900 * Determines if the loader can load a specific item. This loader can only load items that are of type 6901 * {{#crossLink "AbstractLoader/SOUND:property"}}{{/crossLink}}. 6902 * @method canLoadItem 6903 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6904 * @returns {Boolean} Whether the loader can load the item. 6905 * @static 6906 */ 6907 s.canLoadItem = function (item) { 6908 return item.type == createjs.AbstractLoader.SOUND; 6909 }; 6910 6911 // protected methods 6912 p._createTag = function (src) { 6913 var tag = document.createElement("audio"); 6914 tag.autoplay = false; 6915 tag.preload = "none"; 6916 6917 //LM: Firefox fails when this the preload="none" for other tags, but it needs to be "none" to ensure PreloadJS works. 6918 tag.src = src; 6919 return tag; 6920 }; 6921 6922 createjs.SoundLoader = createjs.promote(SoundLoader, "AbstractMediaLoader"); 6923 6924}()); 6925 6926//############################################################################## 6927// VideoLoader.js 6928//############################################################################## 6929 6930this.createjs = this.createjs || {}; 6931 6932(function () { 6933 "use strict"; 6934 6935 // constructor 6936 /** 6937 * A loader for video files. 6938 * @class VideoLoader 6939 * @param {LoadItem|Object} loadItem 6940 * @param {Boolean} preferXHR 6941 * @extends AbstractMediaLoader 6942 * @constructor 6943 */ 6944 function VideoLoader(loadItem, preferXHR) { 6945 this.AbstractMediaLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.VIDEO); 6946 6947 if (createjs.RequestUtils.isVideoTag(loadItem) || createjs.RequestUtils.isVideoTag(loadItem.src)) { 6948 this.setTag(createjs.RequestUtils.isVideoTag(loadItem)?loadItem:loadItem.src); 6949 6950 // We can't use XHR for a tag that's passed in. 6951 this._preferXHR = false; 6952 } else { 6953 this.setTag(this._createTag()); 6954 } 6955 }; 6956 6957 var p = createjs.extend(VideoLoader, createjs.AbstractMediaLoader); 6958 var s = VideoLoader; 6959 6960 /** 6961 * Create a new video tag 6962 * 6963 * @returns {HTMLElement} 6964 * @private 6965 */ 6966 p._createTag = function () { 6967 return document.createElement("video"); 6968 }; 6969 6970 // static methods 6971 /** 6972 * Determines if the loader can load a specific item. This loader can only load items that are of type 6973 * {{#crossLink "AbstractLoader/VIDEO:property"}}{{/crossLink}}. 6974 * @method canLoadItem 6975 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 6976 * @returns {Boolean} Whether the loader can load the item. 6977 * @static 6978 */ 6979 s.canLoadItem = function (item) { 6980 return item.type == createjs.AbstractLoader.VIDEO; 6981 }; 6982 6983 createjs.VideoLoader = createjs.promote(VideoLoader, "AbstractMediaLoader"); 6984 6985}()); 6986 6987//############################################################################## 6988// SpriteSheetLoader.js 6989//############################################################################## 6990 6991this.createjs = this.createjs || {}; 6992 6993(function () { 6994 "use strict"; 6995 6996 // constructor 6997 /** 6998 * A loader for EaselJS SpriteSheets. Images inside the spritesheet definition are loaded before the loader 6999 * completes. To load SpriteSheets using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} 7000 * as part of the {{#crossLink "LoadItem"}}{{/crossLink}}. Note that the {{#crossLink "JSONLoader"}}{{/crossLink}} 7001 * and {{#crossLink "JSONPLoader"}}{{/crossLink}} are higher priority loaders, so SpriteSheets <strong>must</strong> 7002 * set the {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property 7003 * to {{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}. 7004 * 7005 * The {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/crossOrigin:property"}}{{/crossLink}} as well 7006 * as the {{#crossLink "LoadQueue's"}}{{/crossLink}} `basePath` argument and {{#crossLink "LoadQueue/_preferXHR"}}{{/crossLink}} 7007 * property supplied to the {{#crossLink "LoadQueue"}}{{/crossLink}} are passed on to the sub-manifest that loads 7008 * the SpriteSheet images. 7009 * 7010 * Note that the SpriteSheet JSON does not respect the {{#crossLink "LoadQueue/_preferXHR:property"}}{{/crossLink}} 7011 * property, which should instead be determined by the presence of a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} 7012 * property on the SpriteSheet load item. This is because the JSON loaded will have a different format depending on 7013 * if it is loaded as JSON, so just changing `preferXHR` is not enough to change how it is loaded. 7014 * @class SpriteSheetLoader 7015 * @param {LoadItem|Object} loadItem 7016 * @extends AbstractLoader 7017 * @constructor 7018 */ 7019 function SpriteSheetLoader(loadItem, preferXHR) { 7020 this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.SPRITESHEET); 7021 7022 // protected properties 7023 /** 7024 * An internal queue which loads the SpriteSheet's images. 7025 * @method _manifestQueue 7026 * @type {LoadQueue} 7027 * @private 7028 */ 7029 this._manifestQueue = null; 7030 } 7031
7032 var p = createjs.extend(SpriteSheetLoader, createjs.AbstractLoader); 7033 var s = SpriteSheetLoader; 7034 7035 // static properties 7036 /** 7037 * The amount of progress that the manifest itself takes up. 7038 * @property SPRITESHEET_PROGRESS 7039 * @type {number} 7040 * @default 0.25 (25%) 7041 * @private 7042 * @static 7043 */ 7044 s.SPRITESHEET_PROGRESS = 0.25; 7045 7046 // static methods 7047 /** 7048 * Determines if the loader can load a specific item. This loader can only load items that are of type 7049 * {{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}} 7050 * @method canLoadItem 7051 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 7052 * @returns {Boolean} Whether the loader can load the item. 7053 * @static 7054 */ 7055 s.canLoadItem = function (item) { 7056 return item.type == createjs.AbstractLoader.SPRITESHEET; 7057 }; 7058 7059 // public methods 7060 p.destroy = function() { 7061 this.AbstractLoader_destroy; 7062 this._manifestQueue.close(); 7063 }; 7064 7065 // protected methods 7066 p._createRequest = function() { 7067 var callback = this._item.callback; 7068 if (callback != null) { 7069 this._request = new createjs.JSONPLoader(this._item); 7070 } else { 7071 this._request = new createjs.JSONLoader(this._item); 7072 } 7073 }; 7074 7075 p.handleEvent = function (event) { 7076 switch (event.type) { 7077 case "complete": 7078 this._rawResult = event.target.getResult(true); 7079 this._result = event.target.getResult(); 7080 this._sendProgress(s.SPRITESHEET_PROGRESS); 7081 this._loadManifest(this._result); 7082 return; 7083 case "progress": 7084 event.loaded *= s.SPRITESHEET_PROGRESS; 7085 this.progress = event.loaded / event.total; 7086 if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; } 7087 this._sendProgress(event); 7088 return; 7089 } 7090 this.AbstractLoader_handleEvent(event); 7091 }; 7092 7093 /** 7094 * Create and load the images once the SpriteSheet JSON has been loaded. 7095 * @method _loadManifest 7096 * @param {Object} json 7097 * @private 7098 */ 7099 p._loadManifest = function (json) { 7100 if (json && json.images) { 7101 var queue = this._manifestQueue = new createjs.LoadQueue(this._preferXHR, this._item.path, this._item.crossOrigin); 7102 queue.on("complete", this._handleManifestComplete, this, true); 7103 queue.on("fileload", this._handleManifestFileLoad, this); 7104 queue.on("progress", this._handleManifestProgress, this); 7105 queue.on("error", this._handleManifestError, this, true); 7106 queue.loadManifest(json.images); 7107 } 7108 }; 7109 7110 /** 7111 * An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed. 7112 * @method _handleManifestFileLoad 7113 * @param {Event} event 7114 * @private 7115 */ 7116 p._handleManifestFileLoad = function (event) { 7117 var image = event.result; 7118 if (image != null) { 7119 var images = this.getResult().images; 7120 var pos = images.indexOf(event.item.src); 7121 images[pos] = image; 7122 } 7123 }; 7124 7125 /** 7126 * The images have completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} 7127 * {{#crossLink "Event"}}{{/crossLink}} from the SpriteSheetLoader. 7128 * @method _handleManifestComplete 7129 * @param {Event} event 7130 * @private 7131 */ 7132 p._handleManifestComplete = function (event) { 7133 this._result = new createjs.SpriteSheet(this._result); 7134 this._loadedItems = this._manifestQueue.getItems(true); 7135 this._sendComplete(); 7136 }; 7137 7138 /** 7139 * The images {{#crossLink "LoadQueue"}}{{/crossLink}} has reported progress. 7140 * @method _handleManifestProgress 7141 * @param {ProgressEvent} event 7142 * @private 7143 */ 7144 p._handleManifestProgress = function (event) { 7145 this.progress = event.progress * (1 - s.SPRITESHEET_PROGRESS) + s.SPRITESHEET_PROGRESS; 7146 this._sendProgress(this.progress); 7147 }; 7148 7149 /** 7150 * An image has reported an error. 7151 * @method _handleManifestError 7152 * @param {ErrorEvent} event 7153 * @private 7154 */ 7155 p._handleManifestError = function (event) { 7156 var newEvent = new createjs.Event("fileerror"); 7157 newEvent.item = event.data; 7158 this.dispatchEvent(newEvent); 7159 }; 7160 7161 createjs.SpriteSheetLoader = createjs.promote(SpriteSheetLoader, "AbstractLoader"); 7162 7163}()); 7164 7165//############################################################################## 7166// SVGLoader.js 7167//############################################################################## 7168 7169this.createjs = this.createjs || {}; 7170 7171(function () { 7172 "use strict"; 7173 7174 // constructor 7175 /** 7176 * A loader for SVG files.
7177 * @class SVGLoader 7178 * @param {LoadItem|Object} loadItem 7179 * @param {Boolean} preferXHR 7180 * @extends AbstractLoader 7181 * @constructor 7182 */ 7183 function SVGLoader(loadItem, preferXHR) { 7184 this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.SVG); 7185 7186 // public properties 7187 this.resultFormatter = this._formatResult; 7188 7189 // protected properties 7190 this._tagSrcAttribute = "data"; 7191 7192 if (preferXHR) { 7193 this.setTag(document.createElement("svg")); 7194 } else { 7195 this.setTag(document.createElement("object")); 7196 this.getTag().type = "image/svg+xml"; 7197 } 7198 }; 7199 7200 var p = createjs.extend(SVGLoader, createjs.AbstractLoader); 7201 var s = SVGLoader; 7202 7203 // static methods 7204 /** 7205 * Determines if the loader can load a specific item. This loader can only load items that are of type 7206 * {{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}} 7207 * @method canLoadItem 7208 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 7209 * @returns {Boolean} Whether the loader can load the item. 7210 * @static 7211 */ 7212 s.canLoadItem = function (item) { 7213 return item.type == createjs.AbstractLoader.SVG; 7214 }; 7215 7216 // protected methods 7217 /** 7218 * The result formatter for SVG files. 7219 * @method _formatResult 7220 * @param {AbstractLoader} loader 7221 * @returns {Object} 7222 * @private 7223 */ 7224 p._formatResult = function (loader) { 7225 // mime should be image/svg+xml, but Opera requires text/xml 7226 var xml = createjs.DataUtils.parseXML(loader.getResult(true), "text/xml"); 7227 var tag = loader.getTag(); 7228 7229 if (!this._preferXHR && document.body.contains(tag)) { 7230 document.body.removeChild(tag); 7231 } 7232 7233 if (xml.documentElement != null) { 7234 tag.appendChild(xml.documentElement); 7235 tag.style.visibility = "visible"; 7236 return tag; 7237 } else { // For browsers that don't support SVG, just give them the XML. (IE 9-8) 7238 return xml; 7239 } 7240 }; 7241 7242 createjs.SVGLoader = createjs.promote(SVGLoader, "AbstractLoader"); 7243 7244}()); 7245 7246//############################################################################## 7247// XMLLoader.js 7248//############################################################################## 7249 7250this.createjs = this.createjs || {}; 7251 7252(function () { 7253 "use strict"; 7254 7255 // constructor 7256 /** 7257 * A loader for CSS files. 7258 * @class XMLLoader 7259 * @param {LoadItem|Object} loadItem 7260 * @extends AbstractLoader 7261 * @constructor 7262 */ 7263 function XMLLoader(loadItem) { 7264 this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.XML); 7265 7266 // public properties 7267 this.resultFormatter = this._formatResult; 7268 }; 7269 7270 var p = createjs.extend(XMLLoader, createjs.AbstractLoader); 7271 var s = XMLLoader; 7272 7273 // static methods 7274 /** 7275 * Determines if the loader can load a specific item. This loader can only load items that are of type 7276 * {{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}}. 7277 * @method canLoadItem 7278 * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. 7279 * @returns {Boolean} Whether the loader can load the item. 7280 * @static 7281 */ 7282 s.canLoadItem = function (item) { 7283 return item.type == createjs.AbstractLoader.XML; 7284 }; 7285 7286 // protected methods 7287 /** 7288 * The result formatter for XML files. 7289 * @method _formatResult 7290 * @param {AbstractLoader} loader 7291 * @returns {XMLDocument} 7292 * @private 7293 */ 7294 p._formatResult = function (loader) { 7295 return createjs.DataUtils.parseXML(loader.getResult(true), "text/xml"); 7296 }; 7297 7298 createjs.XMLLoader = createjs.promote(XMLLoader, "AbstractLoader"); 7299 7300}());
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.