File:CacheManager.js
/**
* @module cloudkid
*/
(function(undefined){
"use strict";
/**
* Used for managing the browser cache of loading external elements
* can easily load version manifest and apply it to the media loader
* supports cache busting all media load requests
* uses the query string to bust browser versions.
*
* @class CacheManager
*/
var CacheManager = function()
{
this.initialize();
};
/** Easy access to the prototype */
var p = CacheManager.prototype = {};
/**
* The collection of version numbers
* @protected
* @property {Dictionary} _versions
*/
p._versions = null;
/**
* If we are suppose to cache bust every file
* @property {bool} cacheBust
* @public
* @default false
*/
p.cacheBust = false;
/**
* The constructor for the Cache manager
* @public
* @constructor
* @method initialize
*/
p.initialize = function()
{
this._versions = [];
var cb = cloudkid.OS.instance.options.cacheBust;
this.cacheBust = cb ? (cb === "true" || cb === true) : false;
if(DEBUG)
{
if (this.cacheBust) Debug.log("CacheBust all files is on.");
}
};
/**
* Destroy the cache manager, don't use after this
* @public
* @method destroy
*/
p.destroy = function()
{
this._versions = null;
};
/**
* Add the versions
* @public
* @method addVersionsFile
* @param {string} url The url of the versions file
* @param {function} callback Callback when the url has been laoded
* @param {string} baseUrl A base url to prepend all lines of the file
*/
p.addVersionsFile = function(url, callback, baseUrl)
{
Debug.assert(/^.*\.txt$/.test(url), "The versions file must be a *.txt file");
var ml = cloudkid.MediaLoader.instance;
// If we already cache busting, we can ignore this
if (this.cacheBust)
{
if (callback) callback();
return;
}
// Add a random version number to never cache the text file
this.addVersion(url, Math.round(Math.random()*100000));
var cm = this;
// Load the version
ml.load(url,
function(result)
{
// check for a valid result content
if (result && result.content)
{
// Remove carrage returns and split on newlines
var lines = result.content.replace(/\r/g, '').split("\n");
var i, parts;
// Go line by line
for(i = 0; i < lines.length; i++)
{
// Check for a valid line
if (!lines[i]) continue;
// Split lines
parts = lines[i].split(' ');
// Add the parts
if (parts.length != 2) continue;
// Add the versioning
cm.addVersion((baseUrl || "") + parts[0], parts[1]);
}
}
if (callback) callback();
}
);
};
/**
* Add a version number for a file
* @method addVersion
* @public
* @param {string} url The url of the object
* @param {string} version Version number or has of file
*/
p.addVersion = function(url, version)
{
var ver = this._getVersionByUrl(url);
if (!ver)
this._versions.push({'url': url, 'version': version});
};
/**
* Search for a version number by url
* @method _getVersionByUrl
* @private
* @param {string} url The url to search
* @return {string} The version number as a string or null
*/
p._getVersionByUrl = function(url)
{
var i, len = this._versions.length;
for(i = 0; i < len; i++)
{
if (url == this._versions[i].url)
{
return this._versions[i];
}
}
return null;
};
/**
* Prepare a URL with the necessary cache busting and/or versioning
* as well as the base directoryr
* @public
* @method prepare
* @param {string} url The url to prepare
* @param {bool} applyBasePath If the global base path should be applied to the url. This defaults to false because it can
* potentially interfere with later regular expression checks, particularly with PreloadJS
* @return {string} The final url with version/cache and basePath added
*/
p.prepare = function(url, applyBasePath)
{
var ver = this._getVersionByUrl(url);
if (this.cacheBust && /(\?|\&)cb\=[0-9]*/.test(url) === false)
{
if(!this._cbVal)
this._cbVal = new Date().getTime().toString();
url = url + (url.indexOf("?") < 0 ? "?" : "&") + "cb=" + this._cbVal;
}
else if (ver && /(\?|\&)v\=[0-9]*/.test(url) === false)
{
url = url + (url.indexOf("?") < 0 ? "?" : "&") + "v=" + ver.version;
}
if(applyBasePath)
{
var basePath = cloudkid.OS.instance.options.basePath;
if (/^http(s)?\:/.test(url) === false && basePath !== undefined && url.search(basePath) == -1)
{
url = basePath + url;
}
}
return url;
};
namespace('cloudkid').CacheManager = CacheManager;
}());