]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/dtl/tag/logic.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / dtl / tag / logic.js
1 if(!dojo._hasResource["dojox.dtl.tag.logic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.dtl.tag.logic"] = true;
3 dojo.provide("dojox.dtl.tag.logic");
4
5 dojo.require("dojox.dtl._base");
6
7 (function(){
8         var dd = dojox.dtl;
9         var ddt = dd.text;
10         var ddtl = dd.tag.logic;
11
12         ddtl.IfNode = dojo.extend(function(bools, trues, falses, type){
13                 this.bools = bools;
14                 this.trues = trues;
15                 this.falses = falses;
16                 this.type = type;
17         },
18         {
19                 render: function(context, buffer){
20                         var i, bool, ifnot, filter, value;
21                         if(this.type == "or"){
22                                 for(i = 0; bool = this.bools[i]; i++){
23                                         ifnot = bool[0];
24                                         filter = bool[1];
25                                         value = filter.resolve(context);
26                                         if((value && !ifnot) || (ifnot && !value)){
27                                                 if(this.falses){
28                                                         buffer = this.falses.unrender(context, buffer);
29                                                 }
30                                                 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
31                                         }
32                                 }
33                                 if(this.trues){
34                                         buffer = this.trues.unrender(context, buffer);
35                                 }
36                                 return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
37                         }else{
38                                 for(i = 0; bool = this.bools[i]; i++){
39                                         ifnot = bool[0];
40                                         filter = bool[1];
41                                         value = filter.resolve(context);
42                                         // If we ever encounter a false value
43                                         if(value == ifnot){
44                                                 if(this.trues){
45                                                         buffer = this.trues.unrender(context, buffer);
46                                                 }
47                                                 return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
48                                         }
49                                 }
50                                 if(this.falses){
51                                         buffer = this.falses.unrender(context, buffer);
52                                 }
53                                 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
54                         }
55                         return buffer;
56                 },
57                 unrender: function(context, buffer){
58                         buffer = (this.trues) ? this.trues.unrender(context, buffer) : buffer;
59                         buffer = (this.falses) ? this.falses.unrender(context, buffer) : buffer;
60                         return buffer;
61                 },
62                 clone: function(buffer){
63                         var trues = (this.trues) ? this.trues.clone(buffer) : null;
64                         var falses = (this.falses) ? this.falses.clone(buffer) : null;
65                         return new this.constructor(this.bools, trues, falses, this.type);
66                 }
67         });
68
69         ddtl.IfEqualNode = dojo.extend(function(var1, var2, trues, falses, negate){
70                 this.var1 = new dd._Filter(var1);
71                 this.var2 = new dd._Filter(var2);
72                 this.trues = trues;
73                 this.falses = falses;
74                 this.negate = negate;
75         },
76         {
77                 render: function(context, buffer){
78                         var var1 = this.var1.resolve(context);
79                         var var2 = this.var2.resolve(context);
80                         if((this.negate && var1 != var2) || (!this.negate && var1 == var2)){
81                                 if(this.falses){
82                                         buffer = this.falses.unrender(context, buffer);
83                                 }
84                                 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
85                         }
86                         if(this.trues){
87                                 buffer = this.trues.unrender(context, buffer);
88                         }
89                         return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
90                 },
91                 unrender: function(context, buffer){
92                         return ddtl.IfNode.prototype.unrender.call(this, context, buffer);
93                 },
94                 clone: function(buffer){
95                         return new this.constructor(this.var1.getExpression(), this.var2.getExpression(), this.trues.clone(buffer), this.falses.clone(buffer), this.negate);
96                 }
97         });
98
99         ddtl.ForNode = dojo.extend(function(assign, loop, reversed, nodelist){
100                 this.assign = assign;
101                 this.loop = new dd._Filter(loop);
102                 this.reversed = reversed;
103                 this.nodelist = nodelist;
104                 this.pool = [];
105         },
106         {
107                 render: function(context, buffer){
108                         var i, j, k;
109                         var dirty = false;
110                         var assign = this.assign;
111
112                         for(k = 0; k < assign.length; k++){
113                                 if(typeof context[assign[k]] != "undefined"){
114                                         dirty = true;
115                                         context.push();
116                                         break;
117                                 }
118                         }
119
120                         var items = this.loop.resolve(context) || [];
121                         for(i = items.length; i < this.pool.length; i++){
122                                 this.pool[i].unrender(context, buffer);
123                         }
124                         if(this.reversed){
125                                 items = items.slice(0).reverse();
126                         }
127
128                         var isObject = dojo.isObject(items) && !dojo.isArrayLike(items);
129                         var arred = [];
130                         if(isObject){
131                                 for(var key in items){
132                                         arred.push(items[key]);
133                                 }
134                         }else{
135                                 arred = items;
136                         }
137
138                         var forloop = context.forloop = {
139                                 parentloop: context.forloop || {}
140                         };
141                         var j = 0;
142                         for(i = 0; i < arred.length; i++){
143                                 var item = arred[i];
144
145                                 forloop.counter0 = j;
146                                 forloop.counter = j + 1;
147                                 forloop.revcounter0 = arred.length - j - 1;
148                                 forloop.revcounter = arred.length - j;
149                                 forloop.first = !j;
150                                 forloop.last = (j == arred.length - 1);
151
152                                 if(assign.length > 1 && dojo.isArrayLike(item)){
153                                         if(!dirty){
154                                                 dirty = true;
155                                                 context.push();
156                                         }
157                                         var zipped = {};
158                                         for(k = 0; k < item.length && k < assign.length; k++){
159                                                 zipped[assign[k]] = item[k];
160                                         }
161                                         context.update(zipped);
162                                 }else{
163                                         context[assign[0]] = item;
164                                 }
165
166                                 if(j + 1 > this.pool.length){
167                                         this.pool.push(this.nodelist.clone(buffer));
168                                 }
169                                 buffer = this.pool[j].render(context, buffer, this);
170                                 ++j;
171                         }
172
173                         delete context.forloop;
174                         for(k = 0; k < assign.length; k++){
175                                 delete context[assign[k]];
176                         }
177                         if(dirty){
178                                 context.pop();
179                         }
180                         return buffer;
181                 },
182                 unrender: function(context, buffer){
183                         for(var i = 0, pool; pool = this.pool[i]; i++){
184                                 buffer = pool.unrender(context, buffer);
185                         }
186                         return buffer;
187                 },
188                 clone: function(buffer){
189                         return new this.constructor(this.assign, this.loop.getExpression(), this.reversed, this.nodelist.clone(buffer));
190                 }
191         });
192
193         dojo.mixin(ddtl, {
194                 if_: function(parser, text){
195                         var i, part, type, bools = [], parts = ddt.pySplit(text);
196                         parts.shift();
197                         text = parts.join(" ");
198                         parts = text.split(" and ");
199                         if(parts.length == 1){
200                                 type = "or";
201                                 parts = text.split(" or ");
202                         }else{
203                                 type = "and";
204                                 for(i = 0; i < parts.length; i++){
205                                         if(parts[i].indexOf(" or ") != -1){
206                                                 // Note, since we split by and, this is the only place we need to error check
207                                                 throw new Error("'if' tags can't mix 'and' and 'or'");
208                                         }
209                                 }
210                         }
211                         for(i = 0; part = parts[i]; i++){
212                                 var not = false;
213                                 if(part.indexOf("not ") == 0){
214                                         part = part.slice(4);
215                                         not = true;
216                                 }
217                                 bools.push([not, new dd._Filter(part)]);
218                         }
219                         var trues = parser.parse(["else", "endif"]);
220                         var falses = false;
221                         var token = parser.next();
222                         if(token.text == "else"){
223                                 falses = parser.parse(["endif"]);
224                                 parser.next();
225                         }
226                         return new ddtl.IfNode(bools, trues, falses, type);
227                 },
228                 _ifequal: function(parser, text, negate){
229                         var parts = ddt.pySplit(text);
230                         if(parts.length != 3){
231                                 throw new Error(parts[0] + " takes two arguments");
232                         }
233                         var end = 'end' + parts[0];
234                         var trues = parser.parse(["else", end]);
235                         var falses = false;
236                         var token = parser.next();
237                         if(token.text == "else"){
238                                 falses = parser.parse([end]);
239                                 parser.next();
240                         }
241                         return new ddtl.IfEqualNode(parts[1], parts[2], trues, falses, negate);
242                 },
243                 ifequal: function(parser, text){
244                         return ddtl._ifequal(parser, text);
245                 },
246                 ifnotequal: function(parser, text){
247                         return ddtl._ifequal(parser, text, true);
248                 },
249                 for_: function(parser, text){
250                         var parts = ddt.pySplit(text);
251                         if(parts.length < 4){
252                                 throw new Error("'for' statements should have at least four words: " + text);
253                         }
254                         var reversed = parts[parts.length - 1] == "reversed";
255                         var index = (reversed) ? -3 : -2;
256                         if(parts[parts.length + index] != "in"){
257                                 throw new Error("'for' tag received an invalid argument: " + text);
258                         }
259                         var loopvars = parts.slice(1, index).join(" ").split(/ *, */);
260                         for(var i = 0; i < loopvars.length; i++){
261                                 if(!loopvars[i] || loopvars[i].indexOf(" ") != -1){
262                                         throw new Error("'for' tag received an invalid argument: " + text);
263                                 }
264                         }
265                         var nodelist = parser.parse(["endfor"]);
266                         parser.next();
267                         return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist);
268                 }
269         });
270 })();
271
272 }