| /* |
| Copyright (c) 2004-2006, The Dojo Foundation |
| All Rights Reserved. |
| |
| Licensed under the Academic Free License version 2.1 or above OR the |
| modified BSD license. For more information on Dojo licensing, see: |
| |
| http://dojotoolkit.org/community/licensing.shtml |
| */ |
| |
| dojo.provide("dojo.AdapterRegistry"); |
| dojo.require("dojo.lang.func"); |
| |
| 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. |
| this.pairs = []; |
| this.returnWrappers = returnWrappers || false; |
| } |
| |
| dojo.lang.extend(dojo.AdapterRegistry, { |
| register: function(name, check, /*Function*/ wrap, directReturn, override){ |
| // summary: |
| // register a check function to determine if the wrap function or |
| // object gets selected |
| // name: String |
| // a way to identify this matcher. |
| // check: Function |
| // 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: Boolean? |
| // 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: Boolean? |
| // If override is given and true, the check function will be given |
| // highest priority. Otherwise, it will be the lowest priority |
| // adapter. |
| |
| var type = (override) ? "unshift" : "push"; |
| this.pairs[type]([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"); |
| // dojo.raise("No match found"); |
| }, |
| |
| unregister: function(name){ |
| // summary: Remove a named adapter from the registry |
| |
| // 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; |
| } |
| }); |