/*
* 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 "AbstractLoader/MANIFEST:property"}}{{/crossLink}}.
* @class ManifestLoader
* @param {LoadItem|Object} loadItem
* @extends AbstractLoader
* @constructor
*/
function ManifestLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, null, createjs.AbstractLoader.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 "AbstractLoader/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.AbstractLoader.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();
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");
}());