API Docs for:
Show:

File: dependencies\AssetDownloader.js

/**
 This object is designed to make asset downloading easy. It chooses which method should be used to download the asset based on the file extension. It has added functionality for dealing with inconsistencies in audio file support between browsers.
 @class AssetDownloader
 @constructor
 */
function AssetDownloader(){
    var imageTypes = [],
        audioTypes = [],        
        audioMIMETypes = {};
        
    /**
     @method setImageTypes
     @param type* {String} File extensions signifying assets that should be treated as images.
     @example
            assetDownloader.setImageTypes('png', 'jpg', 'jpeg');
     */
    this.setImageTypes = function(/*type, type, ...*/){
        imageTypes = Array.prototype.slice.call(arguments, 0);
    };
    
    /**
     The downloader will use the MIME type information to deal with inconsistencies in audio support between browsers. If a requested audio file can't be played by the browser, then the downloader will attempt to load a file with the same name, but an extension that can be played. Due to this functionality it is important to only set audio types that you will actualy provide as alternatives if you want to rely on the feature.
     @method setAudioTypes
     @param type* {Array} File extensions and their corresponding MIME types signifying assets that should be treated as audio files.
     @example
            assetDownloader.setAudioTypes(['mp3', 'audio/mpeg'],['wav', 'audio/wav']);
     */
    this.setAudioTypes = function(/*[type, mime], [type, mime] ...*/){
        audioTypes = [];
        audioMIMETypes = {};
        for(var i=0; i<arguments.length; ++i){
            audioTypes.push(arguments[i][0]);
            audioMIMETypes[ arguments[i][0] ] = arguments[i][1];
        }
    };
    
    /**
     The download method used by this function depends on the file extension. For image assets, the Image object will be used, for audio assets the Audio object and all other assets will be downloaded using the XMLHttpRequest object and returned as string.
     @method download
     @param assetPath {String} File path of the asset to be downloaded.
     @param downloadedCallback {Function} A function that will be called back with the asset as the argument once the download is finished.
     */
    this.download = function(assetPath, downloadedCallback){
        var extension = getFileExtension(assetPath);
            
        if(imageTypes.indexOf(extension) > -1){
            downloadImage(assetPath, downloadedCallback);
        }else if(audioTypes.indexOf(extension) > -1){
            downloadAudio(assetPath, downloadedCallback);
        }else{
            downloadOther(assetPath, downloadedCallback);
        }
    };
    
    function downloadImage(imagePath, downloadedCallback){
        var image = new Image();
        
        function load(){
            this.removeEventListener('load', load, false);
            this.removeEventListener('error', error, false);
            downloadedCallback(this);
        }
        
        function error(){
            downloadedCallback(null);
        }
        
        image.addEventListener('load', load, false);
        image.addEventListener('error', error, false);
        image.src = imagePath;
    }
    
    function downloadAudio(audioPath, downloadedCallback){
        var audio = new Audio();
        
        function canplaythrough(){
            this.removeEventListener('canplaythrough', canplaythrough, false);
            this.removeEventListener('error', error, false);
            downloadedCallback(this);
        }
        
        function error(){
            downloadedCallback(null);
        }
            
        audio.addEventListener('canplaythrough', canplaythrough, false);       
        audio.addEventListener('error', error, false);
        
        if(audio.canPlayType( audioMIMETypes[ getFileExtension(audioPath) ] ) !== ''){
            audio.src = audioPath;
        }else{
        //if the browser can't play a file of the type specified in the path
        //then go through the list of alternative types provided by the user and check if the browser can play any of those
        //if it can then download a file with the alternative type
            for(var type in audioMIMETypes){
                if(audio.canPlayType( audioMIMETypes[type] ) !== ''){
                    audio.src = changedFileExtension(audioPath, type);
                    return;
                }
            }
            downloadedCallback(null);
        }
    }
    
    function downloadOther(otherPath, downloadedCallback){
        var xhr = new XMLHttpRequest();
        
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
                    downloadedCallback(xhr.responseText);
                }else{
                    downloadedCallback(null);
                }
            }
        };
        
        xhr.open('get', otherPath, true);
        xhr.send(null);
    }
    
    function getFileExtension(filePath){
        var splitFilePath = filePath.split('.');        
        return splitFilePath[splitFilePath.length - 1].toLowerCase();
    }
    
    function changedFileExtension(filePath, extension){
        var splitFilePath = filePath.split('.');        
        splitFilePath[ splitFilePath.length - 1 ] = extension;        
        return splitFilePath.join('.');
    }
}