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");
5 dojo.require("dojox.dtl._base");
10 var ddtl = dd.tag.logic;
12 ddtl.IfNode = dojo.extend(function(bools, trues, falses, type){
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++){
25 value = filter.resolve(context);
26 if((value && !ifnot) || (ifnot && !value)){
28 buffer = this.falses.unrender(context, buffer);
30 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
34 buffer = this.trues.unrender(context, buffer);
36 return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
38 for(i = 0; bool = this.bools[i]; i++){
41 value = filter.resolve(context);
42 // If we ever encounter a false value
45 buffer = this.trues.unrender(context, buffer);
47 return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
51 buffer = this.falses.unrender(context, buffer);
53 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
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;
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);
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);
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)){
82 buffer = this.falses.unrender(context, buffer);
84 return (this.trues) ? this.trues.render(context, buffer, this) : buffer;
87 buffer = this.trues.unrender(context, buffer);
89 return (this.falses) ? this.falses.render(context, buffer, this) : buffer;
91 unrender: function(context, buffer){
92 return ddtl.IfNode.prototype.unrender.call(this, context, buffer);
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);
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;
107 render: function(context, buffer){
110 var assign = this.assign;
112 for(k = 0; k < assign.length; k++){
113 if(typeof context[assign[k]] != "undefined"){
120 var items = this.loop.resolve(context) || [];
121 for(i = items.length; i < this.pool.length; i++){
122 this.pool[i].unrender(context, buffer);
125 items = items.slice(0).reverse();
128 var isObject = dojo.isObject(items) && !dojo.isArrayLike(items);
131 for(var key in items){
132 arred.push(items[key]);
138 var forloop = context.forloop = {
139 parentloop: context.forloop || {}
142 for(i = 0; i < arred.length; i++){
145 forloop.counter0 = j;
146 forloop.counter = j + 1;
147 forloop.revcounter0 = arred.length - j - 1;
148 forloop.revcounter = arred.length - j;
150 forloop.last = (j == arred.length - 1);
152 if(assign.length > 1 && dojo.isArrayLike(item)){
158 for(k = 0; k < item.length && k < assign.length; k++){
159 zipped[assign[k]] = item[k];
161 context.update(zipped);
163 context[assign[0]] = item;
166 if(j + 1 > this.pool.length){
167 this.pool.push(this.nodelist.clone(buffer));
169 buffer = this.pool[j].render(context, buffer, this);
173 delete context.forloop;
174 for(k = 0; k < assign.length; k++){
175 delete context[assign[k]];
182 unrender: function(context, buffer){
183 for(var i = 0, pool; pool = this.pool[i]; i++){
184 buffer = pool.unrender(context, buffer);
188 clone: function(buffer){
189 return new this.constructor(this.assign, this.loop.getExpression(), this.reversed, this.nodelist.clone(buffer));
194 if_: function(parser, text){
195 var i, part, type, bools = [], parts = ddt.pySplit(text);
197 text = parts.join(" ");
198 parts = text.split(" and ");
199 if(parts.length == 1){
201 parts = text.split(" or ");
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'");
211 for(i = 0; part = parts[i]; i++){
213 if(part.indexOf("not ") == 0){
214 part = part.slice(4);
217 bools.push([not, new dd._Filter(part)]);
219 var trues = parser.parse(["else", "endif"]);
221 var token = parser.next();
222 if(token.text == "else"){
223 falses = parser.parse(["endif"]);
226 return new ddtl.IfNode(bools, trues, falses, type);
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");
233 var end = 'end' + parts[0];
234 var trues = parser.parse(["else", end]);
236 var token = parser.next();
237 if(token.text == "else"){
238 falses = parser.parse([end]);
241 return new ddtl.IfEqualNode(parts[1], parts[2], trues, falses, negate);
243 ifequal: function(parser, text){
244 return ddtl._ifequal(parser, text);
246 ifnotequal: function(parser, text){
247 return ddtl._ifequal(parser, text, true);
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);
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);
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);
265 var nodelist = parser.parse(["endfor"]);
267 return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist);