107 lines
3.6 KiB
JavaScript
107 lines
3.6 KiB
JavaScript
define("dojo/AdapterRegistry", ["./_base/kernel", "./_base/lang"], function(dojo, lang){
|
|
// module:
|
|
// dojo/AdapterRegistry
|
|
|
|
var AdapterRegistry = dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
|
|
// summary:
|
|
// A registry to make contextual calling/searching easier.
|
|
// description:
|
|
// Objects of this class keep list of arrays in the form [name, check,
|
|
// wrap, directReturn] that are used to determine what the contextual
|
|
// result of a set of checked arguments is. All check/wrap functions
|
|
// in this registry should be of the same arity.
|
|
// example:
|
|
// | // create a new registry
|
|
// | var reg = new dojo.AdapterRegistry();
|
|
// | reg.register("handleString",
|
|
// | dojo.isString,
|
|
// | function(str){
|
|
// | // do something with the string here
|
|
// | }
|
|
// | );
|
|
// | reg.register("handleArr",
|
|
// | dojo.isArray,
|
|
// | function(arr){
|
|
// | // do something with the array here
|
|
// | }
|
|
// | );
|
|
// |
|
|
// | // now we can pass reg.match() *either* an array or a string and
|
|
// | // the value we pass will get handled by the right function
|
|
// | reg.match("someValue"); // will call the first function
|
|
// | reg.match(["someValue"]); // will call the second
|
|
|
|
this.pairs = [];
|
|
this.returnWrappers = returnWrappers || false; // Boolean
|
|
};
|
|
|
|
lang.extend(AdapterRegistry, {
|
|
register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
|
|
// summary:
|
|
// register a check function to determine if the wrap function or
|
|
// object gets selected
|
|
// name:
|
|
// a way to identify this matcher.
|
|
// check:
|
|
// a function that arguments are passed to from the adapter's
|
|
// match() function. The check function should return true if the
|
|
// given arguments are appropriate for the wrap function.
|
|
// directReturn:
|
|
// If directReturn is true, the value passed in for wrap will be
|
|
// returned instead of being called. Alternately, the
|
|
// AdapterRegistry can be set globally to "return not call" using
|
|
// the returnWrappers property. Either way, this behavior allows
|
|
// the registry to act as a "search" function instead of a
|
|
// function interception library.
|
|
// override:
|
|
// If override is given and true, the check function will be given
|
|
// highest priority. Otherwise, it will be the lowest priority
|
|
// adapter.
|
|
this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
|
|
},
|
|
|
|
match: function(/* ... */){
|
|
// summary:
|
|
// Find an adapter for the given arguments. If no suitable adapter
|
|
// is found, throws an exception. match() accepts any number of
|
|
// arguments, all of which are passed to all matching functions
|
|
// from the registered pairs.
|
|
for(var i = 0; i < this.pairs.length; i++){
|
|
var pair = this.pairs[i];
|
|
if(pair[1].apply(this, arguments)){
|
|
if((pair[3])||(this.returnWrappers)){
|
|
return pair[2];
|
|
}else{
|
|
return pair[2].apply(this, arguments);
|
|
}
|
|
}
|
|
}
|
|
throw new Error("No match found");
|
|
},
|
|
|
|
unregister: function(name){
|
|
// summary:
|
|
// Remove a named adapter from the registry
|
|
// name: String
|
|
// The name of the adapter.
|
|
// returns: Boolean
|
|
// Returns true if operation is successful.
|
|
// Returns false if operation fails.
|
|
|
|
// FIXME: this is kind of a dumb way to handle this. On a large
|
|
// registry this will be slow-ish and we can use the name as a lookup
|
|
// should we choose to trade memory for speed.
|
|
for(var i = 0; i < this.pairs.length; i++){
|
|
var pair = this.pairs[i];
|
|
if(pair[0] == name){
|
|
this.pairs.splice(i, 1);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return AdapterRegistry;
|
|
});
|