todomvc
Version:
> Helping you select an MV\* framework
121 lines (101 loc) • 3.21 kB
JavaScript
/** @license MIT License (c) copyright B Cavalier & J Hann */
/**
* Licensed under the MIT License at:
* http://www.opensource.org/licenses/mit-license.php
*/
(function(define){ 'use strict';
define(function(require) {
var when, timeout, object;
when = require('when');
timeout = require('when/timeout');
object = require('./object');
/**
* Create a reference resolve that uses the supplied plugins and pluginApi
* @param {object} config
* @param {object} config.plugins plugin registry
* @param {object} config.pluginApi plugin Api to provide to resolver plugins
* when resolving references
* @constructor
*/
function Resolver(resolvers, pluginApi) {
this._resolvers = resolvers;
this._pluginApi = pluginApi;
}
Resolver.prototype = {
/**
* Determine if it is a reference spec that can be resolved by this resolver
* @param {*} it
* @return {boolean} true iff it is a reference
*/
isRef: function(it) {
return it && object.hasOwn(it, '$ref');
},
/**
* Parse it, which must be a reference spec, into a reference object
* @param {object|string} it
* @param {string?} it.$ref
* @return {object} reference object
*/
parse: function(it) {
return this.isRef(it)
? this.create(it.$ref, it)
: this.create(it, {});
},
/**
* Creates a reference object
* @param {string} name reference name
* @param {object} options
* @return {{resolver: String, name: String, options: object, resolve: Function}}
*/
create: function(name, options) {
var self, split, resolver;
self = this;
split = name.indexOf('!');
resolver = name.substring(0, split);
name = name.substring(split + 1);
return {
resolver: resolver,
name: name,
options: options,
resolve: function(fallback, onBehalfOf) {
return this.resolver
? self._resolve(resolver, name, options, onBehalfOf)
: fallback(name, options);
}
};
},
/**
* Do the work of resolving a reference using registered plugins
* @param {string} resolverName plugin resolver name (e.g. "dom"), the part before the "!"
* @param {string} name reference name, the part after the "!"
* @param {object} options additional options to pass thru to a resolver plugin
* @param {string|*} onBehalfOf some indication of another component on whose behalf this
* reference is being resolved. Used to build a reference graph and detect cycles
* @return {object} promise for the resolved reference
* @private
*/
_resolve: function(resolverName, name, options, onBehalfOf) {
var deferred, resolver, api;
deferred = when.defer();
if (resolverName) {
resolver = this._resolvers[resolverName];
if (resolver) {
api = this._pluginApi.contextualize(onBehalfOf);
resolver(deferred.resolver, name, options||{}, api);
} else {
deferred.reject(new Error('No resolver plugin found: ' + resolverName));
}
} else {
deferred.reject(new Error('Cannot resolve ref: ' + name));
}
return deferred.promise;
}
};
return Resolver;
});
})(typeof define == 'function'
// AMD
? define
// CommonJS
: function(factory) { module.exports = factory(require); }
);