import {
ScriptReceivers,
ScriptReceiverFactory
} from './script_receiver_factory';
import Runtime from 'runtime';
import ScriptRequest from './script_request';
/** Handles loading dependency files.
*
* Dependency loaders don't remember whether a resource has been loaded or
* not. It is caller's responsibility to make sure the resource is not loaded
* twice. This is because it's impossible to detect resource loading status
* without knowing its content.
*
* Options:
* - cdn_http - url to HTTP CND
* - cdn_https - url to HTTPS CDN
* - version - version of pusher-js
* - suffix - suffix appended to all names of dependency files
*
* @param {Object} options
*/
export default class DependencyLoader {
options: any;
receivers: ScriptReceiverFactory;
loading: any;
constructor(options: any) {
this.options = options;
this.receivers = options.receivers || ScriptReceivers;
this.loading = {};
}
/** Loads the dependency from CDN.
*
* @param {String} name
* @param {Function} callback
*/
load(name: string, options: any, callback: Function) {
var self = this;
if (self.loading[name] && self.loading[name].length > 0) {
self.loading[name].push(callback);
} else {
self.loading[name] = [callback];
var request = Runtime.createScriptRequest(self.getPath(name, options));
var receiver = self.receivers.create(function(error) {
self.receivers.remove(receiver);
if (self.loading[name]) {
var callbacks = self.loading[name];
delete self.loading[name];
var successCallback = function(wasSuccessful) {
if (!wasSuccessful) {
request.cleanup();
}
};
for (var i = 0; i < callbacks.length; i++) {
callbacks[i](error, successCallback);
}
}
});
request.send(receiver);
}
}
/** Returns a root URL for pusher-js CDN.
*
* @returns {String}
*/
getRoot(options: any): string {
var cdn;
var protocol = Runtime.getDocument().location.protocol;
if ((options && options.useTLS) || protocol === 'https:') {
cdn = this.options.cdn_https;
} else {
cdn = this.options.cdn_http;
}
// make sure there are no double slashes
return cdn.replace(/\/*$/, '') + '/' + this.options.version;
}
/** Returns a full path to a dependency file.
*
* @param {String} name
* @returns {String}
*/
getPath(name: string, options: any): string {
return this.getRoot(options) + '/' + name + this.options.suffix + '.js';
}
}
|