/*
* RequestUtils
* 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
*/
(function () {
/**
* Utilities that assist with parsing load items, and determining file types, etc.
* @class RequestUtils
*/
var s = {};
/**
* The Regular Expression used to test file URLS for an absolute path.
* @property ABSOLUTE_PATH
* @type {RegExp}
* @static
*/
s.ABSOLUTE_PATT = /^(?:\w+:)?\/{2}/i;
/**
* The Regular Expression used to test file URLS for a relative path.
* @property RELATIVE_PATH
* @type {RegExp}
* @static
*/
s.RELATIVE_PATT = (/^[./]*?\//i);
/**
* The Regular Expression used to test file URLS for an extension. Note that URIs must already have the query string
* removed.
* @property EXTENSION_PATT
* @type {RegExp}
* @static
*/
s.EXTENSION_PATT = /\/?[^/]+\.(\w{1,5})$/i;
/**
* Parse a file path to determine the information we need to work with it. Currently, PreloadJS needs to know:
* <ul>
* <li>If the path is absolute. Absolute paths start with a protocol (such as `http://`, `file://`, or
* `//networkPath`)</li>
* <li>If the path is relative. Relative paths start with `../` or `/path` (or similar)</li>
* <li>The file extension. This is determined by the filename with an extension. Query strings are dropped, and
* the file path is expected to follow the format `name.ext`.</li>
* </ul>
* @method parseURI
* @param {String} path
* @returns {Object} An Object with an `absolute` and `relative` Boolean values, as well as an optional 'extension`
* property, which is the lowercase extension.
* @static
*/
s.parseURI = function (path) {
var info = {absolute: false, relative: false};
if (path == null) { return info; }
// Drop the query string
var queryIndex = path.indexOf("?");
if (queryIndex > -1) {
path = path.substr(0, queryIndex);
}
// Absolute
var match;
if (s.ABSOLUTE_PATT.test(path)) {
info.absolute = true;
// Relative
} else if (s.RELATIVE_PATT.test(path)) {
info.relative = true;
}
// Extension
if (match = path.match(s.EXTENSION_PATT)) {
info.extension = match[1].toLowerCase();
}
return info;
};
/**
* Formats an object into a query string for either a POST or GET request.
* @method formatQueryString
* @param {Object} data The data to convert to a query string.
* @param {Array} [query] Existing name/value pairs to append on to this query.
* @static
*/
s.formatQueryString = function (data, query) {
if (data == null) {
throw new Error('You must specify data.');
}
var params = [];
for (var n in data) {
params.push(n + '=' + escape(data[n]));
}
if (query) {
params = params.concat(query);
}
return params.join('&');
};
/**
* A utility method that builds a file path using a source and a data object, and formats it into a new path.
* @method buildPath
* @param {String} src The source path to add values to.
* @param {Object} [data] Object used to append values to this request as a query string. Existing parameters on the
* path will be preserved.
* @returns {string} A formatted string that contains the path and the supplied parameters.
* @static
*/
s.buildPath = function (src, data) {
if (data == null) {
return src;
}
var query = [];
var idx = src.indexOf('?');
if (idx != -1) {
var q = src.slice(idx + 1);
query = query.concat(q.split('&'));
}
if (idx != -1) {
return src.slice(0, idx) + '?' + this._formatQueryString(data, query);
} else {
return src + '?' + this._formatQueryString(data, query);
}
};
/**
* @method isCrossDomain
* @param {LoadItem|Object} item A load item with a `src` property.
* @return {Boolean} If the load item is loading from a different domain than the current location.
* @static
*/
s.isCrossDomain = function (item) {
var target = document.createElement("a");
target.href = item.src;
var host = document.createElement("a");
host.href = location.href;
var crossdomain = (target.hostname != "") &&
(target.port != host.port ||
target.protocol != host.protocol ||
target.hostname != host.hostname);
return crossdomain;
};
/**
* @method isLocal
* @param {LoadItem|Object} item A load item with a `src` property
* @return {Boolean} If the load item is loading from the "file:" protocol. Assume that the host must be local as
* well.
* @static
*/
s.isLocal = function (item) {
var target = document.createElement("a");
target.href = item.src;
return target.hostname == "" && target.protocol == "file:";
};
/**
* Determine if a specific type should be loaded as a binary file. Currently, only images and items marked
* specifically as "binary" are loaded as binary. Note that audio is <b>not</b> a binary type, as we can not play
* back using an audio tag if it is loaded as binary. Plugins can change the item type to binary to ensure they get
* a binary result to work with. Binary files are loaded using XHR2. Types are defined as static constants on
* {{#crossLink "AbstractLoader"}}{{/crossLink}}.
* @method isBinary
* @param {String} type The item type.
* @return {Boolean} If the specified type is binary.
* @static
*/
s.isBinary = function (type) {
switch (type) {
case createjs.AbstractLoader.IMAGE:
case createjs.AbstractLoader.BINARY:
return true;
default:
return false;
}
};
/**
* Check if item is a valid HTMLImageElement
* @method isImageTag
* @param {Object} item
* @returns {Boolean}
* @static
*/
s.isImageTag = function(item) {
return item instanceof HTMLImageElement;
};
/**
* Check if item is a valid HTMLAudioElement
* @method isAudioTag
* @param {Object} item
* @returns {Boolean}
* @static
*/
s.isAudioTag = function(item) {
if (window.HTMLAudioElement) {
return item instanceof HTMLAudioElement;
} else {
return false;
}
};
/**
* Check if item is a valid HTMLVideoElement
* @method isVideoTag
* @param {Object} item
* @returns {Boolean}
* @static
*/
s.isVideoTag = function(item) {
if (window.HTMLVideoElement) {
return item instanceof HTMLVideoElement;
} else {
return false;
}
};
/**
* Determine if a specific type is a text-based asset, and should be loaded as UTF-8.
* @method isText
* @param {String} type The item type.
* @return {Boolean} If the specified type is text.
* @static
*/
s.isText = function (type) {
switch (type) {
case createjs.AbstractLoader.TEXT:
case createjs.AbstractLoader.JSON:
case createjs.AbstractLoader.MANIFEST:
case createjs.AbstractLoader.XML:
case createjs.AbstractLoader.CSS:
case createjs.AbstractLoader.SVG:
case createjs.AbstractLoader.JAVASCRIPT:
case createjs.AbstractLoader.SPRITESHEET:
return true;
default:
return false;
}
};
/**
* Determine the type of the object using common extensions. Note that the type can be passed in with the load item
* if it is an unusual extension.
* @method getTypeByExtension
* @param {String} extension The file extension to use to determine the load type.
* @return {String} The determined load type (for example, <code>AbstractLoader.IMAGE</code>). Will return `null` if
* the type can not be determined by the extension.
* @static
*/
s.getTypeByExtension = function (extension) {
if (extension == null) {
return createjs.AbstractLoader.TEXT;
}
switch (extension.toLowerCase()) {
case "jpeg":
case "jpg":
case "gif":
case "png":
case "webp":
case "bmp":
return createjs.AbstractLoader.IMAGE;
case "ogg":
case "mp3":
case "webm":
return createjs.AbstractLoader.SOUND;
case "mp4":
case "webm":
case "ts":
return createjs.AbstractLoader.VIDEO;
case "json":
return createjs.AbstractLoader.JSON;
case "xml":
return createjs.AbstractLoader.XML;
case "css":
return createjs.AbstractLoader.CSS;
case "js":
return createjs.AbstractLoader.JAVASCRIPT;
case 'svg':
return createjs.AbstractLoader.SVG;
default:
return createjs.AbstractLoader.TEXT;
}
};
createjs.RequestUtils = s;
}());