]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojo/behavior.js
Comment class stub
[eow] / static / dojo-release-1.1.1 / dojo / behavior.js
1 if(!dojo._hasResource["dojo.behavior"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojo.behavior"] = true;
3 dojo.provide("dojo.behavior");
4
5 dojo.behavior = new function(){
6         function arrIn(obj, name){
7                 if(!obj[name]){ obj[name] = []; }
8                 return obj[name];
9         }
10
11         var _inc = 0;
12
13         function forIn(obj, scope, func){
14                 var tmpObj = {};
15                 for(var x in obj){
16                         if(typeof tmpObj[x] == "undefined"){
17                                 if(!func){
18                                         scope(obj[x], x);
19                                 }else{
20                                         func.call(scope, obj[x], x);
21                                 }
22                         }
23                 }
24         }
25
26         // FIXME: need a better test so we don't exclude nightly Safari's!
27         this._behaviors = {};
28         this.add = function(behaviorObj){
29                 //      summary:
30                 //              add the specified behavior to the list of behaviors which will
31                 //              be applied the next time apply() is called. Calls to add() for
32                 //              an already existing behavior do not replace the previous rules,
33                 //              but are instead additive. New nodes which match the rule will
34                 //              have all add()-ed behaviors applied to them when matched.
35                 //
36                 //      description:
37                 //              behavior objects are specified in the following format(s):
38                 //              
39                 //                      { 
40                 //                              "#id": {
41                 //                                      "found": function(element){
42                 //                                              // ...
43                 //                                      },
44                 //                      
45                 //                                      "onblah": {targetObj: foo, targetFunc: "bar"},
46                 //                      
47                 //                                      "onblarg": "/foo/bar/baz/blarg",
48                 //                      
49                 //                                      "onevent": function(evt){
50                 //                                      },
51                 //                      
52                 //                                      "onotherevent: function(evt){
53                 //                                              // ...
54                 //                                      }
55                 //                              },
56                 //                      
57                 //                              "#id2": {
58                 //                                      // ...
59                 //                              },
60                 //                      
61                 //                              "#id3": function(element){
62                 //                                      // ...
63                 //                              },
64                 //                      
65                 //                              // publish the match on a topic
66                 //                              "#id4": "/found/topic/name",
67                 //                      
68                 //                              // match all direct descendants
69                 //                              "#id4 > *": function(element){
70                 //                                      // ...
71                 //                              },
72                 //                      
73                 //                              // match the first child node that's an element
74                 //                              "#id4 > :first-child": { ... },
75                 //                      
76                 //                              // match the last child node that's an element
77                 //                              "#id4 > :last-child":  { ... },
78                 //                      
79                 //                              // all elements of type tagname
80                 //                              "tagname": {
81                 //                                      // ...
82                 //                              },
83                 //                      
84                 //                              "tagname1 tagname2 tagname3": {
85                 //                                      // ...
86                 //                              },
87                 //                      
88                 //                              ".classname": {
89                 //                                      // ...
90                 //                              },
91                 //                      
92                 //                              "tagname.classname": {
93                 //                                      // ...
94                 //                              },
95                 //                      }
96                 //              
97                 //              The "found" method is a generalized handler that's called as soon
98                 //              as the node matches the selector. Rules for values that follow also
99                 //              apply to the "found" key.
100                 //              
101                 //              The "on*" handlers are attached with dojo.connect(). 
102                 //              
103                 //              If the value corresponding to the ID key is a function and not a
104                 //              list, it's treated as though it was the value of "found".
105
106                 var tmpObj = {};
107                 forIn(behaviorObj, this, function(behavior, name){
108                         var tBehavior = arrIn(this._behaviors, name);
109                         if(typeof tBehavior["id"] != "number"){
110                                 tBehavior.id = _inc++;
111                         }
112                         var cversion = [];
113                         tBehavior.push(cversion);
114                         if((dojo.isString(behavior))||(dojo.isFunction(behavior))){
115                                 behavior = { found: behavior };
116                         }
117                         forIn(behavior, function(rule, ruleName){
118                                 arrIn(cversion, ruleName).push(rule);
119                         });
120                 });
121         }
122
123         var _applyToNode = function(node, action, ruleSetName){
124                 if(dojo.isString(action)){
125                         if(ruleSetName == "found"){
126                                 dojo.publish(action, [ node ]);
127                         }else{
128                                 dojo.connect(node, ruleSetName, function(){
129                                         dojo.publish(action, arguments);
130                                 });
131                         }
132                 }else if(dojo.isFunction(action)){
133                         if(ruleSetName == "found"){
134                                 action(node);
135                         }else{
136                                 dojo.connect(node, ruleSetName, action);
137                         }
138                 }
139         }
140
141         this.apply = function(){
142                 // summary:
143                 //              applies all currently registered behaviors to the document,
144                 //              taking care to ensure that only incremental updates are made
145                 //              since the last time add() or apply() were called. If new
146                 //              matching nodes have been added, all rules in a behavior will be
147                 //              applied to that node. For previously matched nodes, only
148                 //              behaviors which have been added since the last call to apply()
149                 //              will be added to the nodes.
150                 forIn(this._behaviors, function(tBehavior, id){
151                         dojo.query(id).forEach( 
152                                 function(elem){
153                                         var runFrom = 0;
154                                         var bid = "_dj_behavior_"+tBehavior.id;
155                                         if(typeof elem[bid] == "number"){
156                                                 runFrom = elem[bid];
157                                                 // console.debug(bid, runFrom);
158                                                 if(runFrom == (tBehavior.length)){
159                                                         return;
160                                                 }
161                                         }
162                                         // run through the versions, applying newer rules at each step
163
164                                         for(var x=runFrom, tver; tver = tBehavior[x]; x++){
165                                                 // console.debug(tver);
166                                                 forIn(tver, function(ruleSet, ruleSetName){
167                                                         if(dojo.isArray(ruleSet)){
168                                                                 dojo.forEach(ruleSet, function(action){
169                                                                         _applyToNode(elem, action, ruleSetName);
170                                                                 });
171                                                         }
172                                                 });
173                                         }
174
175                                         // ensure that re-application only adds new rules to the node
176                                         elem[bid] = tBehavior.length;
177                                 }
178                         );
179                 });
180         }
181 }
182
183 dojo.addOnLoad(dojo.behavior, "apply");
184
185 }