/* * ManifestLoader * Visit http://createjs.com/ for documentation, updates and examples. * * * Copyright (c) 2012 gskinner.com, inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /** * @module PreloadJS */ // namespace: this.createjs = this.createjs || {}; (function () { "use strict"; // constructor /** * A loader for JSON manifests. Items inside the manifest are loaded before the loader completes. To load manifests * using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} as part of the * {{#crossLink "LoadItem"}}{{/crossLink}}. * * The list of files in the manifest must be defined on the top-level JSON object in a `manifest` property. This * example shows a sample manifest definition, as well as how to to include a sub-manifest. * * { * "path": "assets/", * "manifest": [ * "image.png", * {"src": "image2.png", "id":"image2"}, * {"src": "sub-manifest.json", "type":"manifest", "callback":"jsonCallback"} * ] * } * * When a ManifestLoader has completed loading, the parent loader (usually a {{#crossLink "LoadQueue"}}{{/crossLink}}, * but could also be another ManifestLoader) will inherit all the loaded items, so you can access them directly. * * Note that the {{#crossLink "JSONLoader"}}{{/crossLink}} and {{#crossLink "JSONPLoader"}}{{/crossLink}} are * higher priority loaders, so manifests <strong>must</strong> set the {{#crossLink "LoadItem"}}{{/crossLink}} * {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property to {{#crossLink "Types/MANIFEST:property"}}{{/crossLink}}. * * Additionally, some browsers require the server to serve a JavaScript mime-type for JSONP, so it may not work in * some conditions. * @class ManifestLoader * @param {LoadItem|Object} loadItem * @extends AbstractLoader * @constructor */ function ManifestLoader(loadItem, preferXHR) { this.AbstractLoader_constructor(loadItem, preferXHR, createjs.Types.MANIFEST); // Public Properties /** * An array of the plugins registered using {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}}, * used to pass plugins to new LoadQueues that may be created. * @property _plugins * @type {Array} * @private * @since 0.6.1 */ this.plugins = null; // Protected Properties /** * An internal {{#crossLink "LoadQueue"}}{{/crossLink}} that loads the contents of the manifest. * @property _manifestQueue * @type {LoadQueue} * @private */ this._manifestQueue = null; }; var p = createjs.extend(ManifestLoader, createjs.AbstractLoader); var s = ManifestLoader; // static properties /** * The amount of progress that the manifest itself takes up. * @property MANIFEST_PROGRESS * @type {number} * @default 0.25 (25%) * @private * @static */ s.MANIFEST_PROGRESS = 0.25; // static methods /** * Determines if the loader can load a specific item. This loader can only load items that are of type * {{#crossLink "Types/MANIFEST:property"}}{{/crossLink}} * @method canLoadItem * @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load. * @returns {Boolean} Whether the loader can load the item. * @static */ s.canLoadItem = function (item) { return item.type == createjs.Types.MANIFEST; }; // public methods p.load = function () { this.AbstractLoader_load(); }; // protected methods p._createRequest = function() { var callback = this._item.callback; if (callback != null) { this._request = new createjs.JSONPLoader(this._item); } else { this._request = new createjs.JSONLoader(this._item); } }; p.handleEvent = function (event) { switch (event.type) { case "complete": this._rawResult = event.target.getResult(true); this._result = event.target.getResult(); this._sendProgress(s.MANIFEST_PROGRESS); this._loadManifest(this._result); return; case "progress": event.loaded *= s.MANIFEST_PROGRESS; this.progress = event.loaded / event.total; if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; } this._sendProgress(event); return; } this.AbstractLoader_handleEvent(event); }; p.destroy = function() { this.AbstractLoader_destroy(); this._manifestQueue.close(); }; /** * Create and load the manifest items once the actual manifest has been loaded. * @method _loadManifest * @param {Object} json * @private */ p._loadManifest = function (json) { if (json && json.manifest) { var queue = this._manifestQueue = new createjs.LoadQueue(this._preferXHR); queue.on("fileload", this._handleManifestFileLoad, this); queue.on("progress", this._handleManifestProgress, this); queue.on("complete", this._handleManifestComplete, this, true); queue.on("error", this._handleManifestError, this, true); for(var i = 0, l = this.plugins.length; i < l; i++) { // conserve order of plugins queue.installPlugin(this.plugins[i]); } queue.loadManifest(json); } else { this._sendComplete(); } }; /** * An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed. * @method _handleManifestFileLoad * @param {Event} event * @private */ p._handleManifestFileLoad = function (event) { event.target = null; this.dispatchEvent(event); }; /** * The manifest has completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} * {{#crossLink "Event"}}{{/crossLink}} from the ManifestLoader. * @method _handleManifestComplete * @param {Event} event * @private */ p._handleManifestComplete = function (event) { this._loadedItems = this._manifestQueue.getItems(true); this._sendComplete(); }; /** * The manifest has reported progress. * @method _handleManifestProgress * @param {ProgressEvent} event * @private */ p._handleManifestProgress = function (event) { this.progress = event.progress * (1 - s.MANIFEST_PROGRESS) + s.MANIFEST_PROGRESS; this._sendProgress(this.progress); }; /** * The manifest has reported an error with one of the files. * @method _handleManifestError * @param {ErrorEvent} event * @private */ p._handleManifestError = function (event) { var newEvent = new createjs.Event("fileerror"); newEvent.item = event.data; this.dispatchEvent(newEvent); }; createjs.ManifestLoader = createjs.promote(ManifestLoader, "AbstractLoader"); }());