yzt
2023-05-26 2f70f6727314edd84d8ec2bfe3ce832803f1ea77
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
define(["./_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
    //  |   require(["dojo/AdapterRegistry"],
    //  |   function(AdapterRegistry){
    //  |       var reg = new AdapterRegistry();
    //  |       reg.register("handleString",
    //  |           function(str){
    //  |               return typeof val == "string"
    //  |           },
    //  |           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;
});