[483] | 1 | define(["./_base/kernel", "./_base/lang"], function(dojo, lang){ |
---|
| 2 | // module: |
---|
| 3 | // dojo/AdapterRegistry |
---|
| 4 | |
---|
| 5 | var AdapterRegistry = dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){ |
---|
| 6 | // summary: |
---|
| 7 | // A registry to make contextual calling/searching easier. |
---|
| 8 | // description: |
---|
| 9 | // Objects of this class keep list of arrays in the form [name, check, |
---|
| 10 | // wrap, directReturn] that are used to determine what the contextual |
---|
| 11 | // result of a set of checked arguments is. All check/wrap functions |
---|
| 12 | // in this registry should be of the same arity. |
---|
| 13 | // example: |
---|
| 14 | // | // create a new registry |
---|
| 15 | // | require(["dojo/AdapterRegistry"], |
---|
| 16 | // | function(AdapterRegistry){ |
---|
| 17 | // | var reg = new AdapterRegistry(); |
---|
| 18 | // | reg.register("handleString", |
---|
| 19 | // | function(str){ |
---|
| 20 | // | return typeof val == "string" |
---|
| 21 | // | }, |
---|
| 22 | // | function(str){ |
---|
| 23 | // | // do something with the string here |
---|
| 24 | // | } |
---|
| 25 | // | ); |
---|
| 26 | // | reg.register("handleArr", |
---|
| 27 | // | dojo.isArray, |
---|
| 28 | // | function(arr){ |
---|
| 29 | // | // do something with the array here |
---|
| 30 | // | } |
---|
| 31 | // | ); |
---|
| 32 | // | |
---|
| 33 | // | // now we can pass reg.match() *either* an array or a string and |
---|
| 34 | // | // the value we pass will get handled by the right function |
---|
| 35 | // | reg.match("someValue"); // will call the first function |
---|
| 36 | // | reg.match(["someValue"]); // will call the second |
---|
| 37 | // | }); |
---|
| 38 | |
---|
| 39 | this.pairs = []; |
---|
| 40 | this.returnWrappers = returnWrappers || false; // Boolean |
---|
| 41 | }; |
---|
| 42 | |
---|
| 43 | lang.extend(AdapterRegistry, { |
---|
| 44 | register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){ |
---|
| 45 | // summary: |
---|
| 46 | // register a check function to determine if the wrap function or |
---|
| 47 | // object gets selected |
---|
| 48 | // name: |
---|
| 49 | // a way to identify this matcher. |
---|
| 50 | // check: |
---|
| 51 | // a function that arguments are passed to from the adapter's |
---|
| 52 | // match() function. The check function should return true if the |
---|
| 53 | // given arguments are appropriate for the wrap function. |
---|
| 54 | // directReturn: |
---|
| 55 | // If directReturn is true, the value passed in for wrap will be |
---|
| 56 | // returned instead of being called. Alternately, the |
---|
| 57 | // AdapterRegistry can be set globally to "return not call" using |
---|
| 58 | // the returnWrappers property. Either way, this behavior allows |
---|
| 59 | // the registry to act as a "search" function instead of a |
---|
| 60 | // function interception library. |
---|
| 61 | // override: |
---|
| 62 | // If override is given and true, the check function will be given |
---|
| 63 | // highest priority. Otherwise, it will be the lowest priority |
---|
| 64 | // adapter. |
---|
| 65 | this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]); |
---|
| 66 | }, |
---|
| 67 | |
---|
| 68 | match: function(/* ... */){ |
---|
| 69 | // summary: |
---|
| 70 | // Find an adapter for the given arguments. If no suitable adapter |
---|
| 71 | // is found, throws an exception. match() accepts any number of |
---|
| 72 | // arguments, all of which are passed to all matching functions |
---|
| 73 | // from the registered pairs. |
---|
| 74 | for(var i = 0; i < this.pairs.length; i++){ |
---|
| 75 | var pair = this.pairs[i]; |
---|
| 76 | if(pair[1].apply(this, arguments)){ |
---|
| 77 | if((pair[3])||(this.returnWrappers)){ |
---|
| 78 | return pair[2]; |
---|
| 79 | }else{ |
---|
| 80 | return pair[2].apply(this, arguments); |
---|
| 81 | } |
---|
| 82 | } |
---|
| 83 | } |
---|
| 84 | throw new Error("No match found"); |
---|
| 85 | }, |
---|
| 86 | |
---|
| 87 | unregister: function(name){ |
---|
| 88 | // summary: |
---|
| 89 | // Remove a named adapter from the registry |
---|
| 90 | // name: String |
---|
| 91 | // The name of the adapter. |
---|
| 92 | // returns: Boolean |
---|
| 93 | // Returns true if operation is successful. |
---|
| 94 | // Returns false if operation fails. |
---|
| 95 | |
---|
| 96 | // FIXME: this is kind of a dumb way to handle this. On a large |
---|
| 97 | // registry this will be slow-ish and we can use the name as a lookup |
---|
| 98 | // should we choose to trade memory for speed. |
---|
| 99 | for(var i = 0; i < this.pairs.length; i++){ |
---|
| 100 | var pair = this.pairs[i]; |
---|
| 101 | if(pair[0] == name){ |
---|
| 102 | this.pairs.splice(i, 1); |
---|
| 103 | return true; |
---|
| 104 | } |
---|
| 105 | } |
---|
| 106 | return false; |
---|
| 107 | } |
---|
| 108 | }); |
---|
| 109 | |
---|
| 110 | return AdapterRegistry; |
---|
| 111 | }); |
---|