Files
2023-08-01 13:49:46 +02:00

100 lines
2.7 KiB
JavaScript

/**
* @license
* Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node:true
'use strict';
// jshint -W079
// Promise polyfill
var Promise = global.Promise || require('es6-promise').Promise;
// jshint +W079
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.resolve = resolve;
self.reject = reject;
});
}
/**
* An object that knows how to resolve resources.
* @typedef {Object} Resolver
* @memberof hydrolysis
* @property {function(string, Deferred): boolean} accept Attempt to resolve
* `deferred` with the contents the specified URL. Returns false if the
* Resolver is unable to resolve the URL.
*/
/**
* A FileLoader lets you resolve URLs with a set of potential resolvers.
* @constructor
* @memberof hydrolysis
*/
function FileLoader() {
this.resolvers = [];
// map url -> Deferred
this.requests = {};
}
FileLoader.prototype = {
/**
* Add an instance of a Resolver class to the list of url resolvers
*
* Ordering of resolvers is most to least recently added
* The first resolver to "accept" the url wins.
* @param {Resolver} resolver The resolver to add.
*/
addResolver: function(resolver) {
this.resolvers.push(resolver);
},
/**
* Return a promise for an absolute url
*
* Url requests are deduplicated by the loader, returning the same Promise for
* identical urls
*
* @param {string} url The absolute url to request.
* @return {Promise.<string>} A promise that resolves to the contents of the URL.
*/
request: function(uri) {
var promise;
if (!(uri in this.requests)) {
var handled = false;
var deferred = new Deferred();
this.requests[uri] = deferred;
// loop backwards through resolvers until one "accepts" the request
for (var i = this.resolvers.length - 1, r; i >= 0; i--) {
r = this.resolvers[i];
if (r.accept(uri, deferred)) {
handled = true;
break;
}
}
if (!handled) {
deferred.reject(new Error('no resolver found for ' + uri));
}
promise = deferred.promise;
} else {
promise = this.requests[uri].promise;
}
return promise;
}
};
module.exports = FileLoader;