]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/dtl/tag/loader.js
36c81bc9ff6e852a28c87a412518e2d852785521
[eow] / static / dojo-release-1.1.1 / dojox / dtl / tag / loader.js
1 if(!dojo._hasResource["dojox.dtl.tag.loader"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.dtl.tag.loader"] = true;
3 dojo.provide("dojox.dtl.tag.loader");
4
5 dojo.require("dojox.dtl._base");
6
7 (function(){
8         var dd = dojox.dtl;
9         var ddtl = dd.tag.loader;
10
11         ddtl.BlockNode = dojo.extend(function(name, nodelist){
12                 this.name = name;
13                 this.nodelist = nodelist; // Can be overridden
14         },
15         {
16                 render: function(context, buffer){
17                         var name = this.name;
18                         var nodelist = this.nodelist;
19                         if(buffer.blocks){
20                                 var block = buffer.blocks[name];
21                                 if(block){
22                                         nodelist = block.nodelist;
23                                         block.used = true;
24                                 }
25                         }
26                         this.rendered = nodelist;
27                         return nodelist.render(context, buffer, this);
28                 },
29                 unrender: function(context, buffer){
30                         return this.rendered.unrender(context, buffer);
31                 },
32                 clone: function(buffer){
33                         return new this.constructor(this.name, this.nodelist.clone(buffer));
34                 },
35                 setOverride: function(nodelist){
36                         // summary: In a shared parent, we override, not overwrite
37                         if(!this.override){
38                                 this.override = nodelist;
39                         }
40                 },
41                 toString: function(){ return "dojox.dtl.tag.loader.BlockNode"; }
42         });
43
44         ddtl.ExtendsNode = dojo.extend(function(getTemplate, nodelist, shared, parent, key){
45                 this.getTemplate = getTemplate;
46                 this.nodelist = nodelist;
47                 this.shared = shared;
48                 this.parent = parent;
49                 this.key = key;
50         },
51         {
52                 parents: {},
53                 getParent: function(context){
54                         if(!this.parent){
55                                 this.parent = context.get(this.key, false);
56                                 if(!this.parent){
57                                         throw new Error("extends tag used a variable that did not resolve");
58                                 }
59                                 if(typeof this.parent == "object"){
60                                         if(this.parent.url){
61                                                 if(this.parent.shared){
62                                                         this.shared = true;
63                                                 }
64                                                 this.parent = this.parent.url.toString();
65                                         }else{
66                                                 this.parent = this.parent.toString();
67                                         }
68                                 }
69                                 if(this.parent && this.parent.indexOf("shared:") == 0){
70                                         this.shared = true;
71                                         this.parent = this.parent.substring(7, parent.length);
72                                 }
73                         }
74                         var parent = this.parent;
75                         if(!parent){
76                                 throw new Error("Invalid template name in 'extends' tag.");
77                         }
78                         if(parent.render){
79                                 return parent;
80                         }
81                         if(this.parents[parent]){
82                                 return this.parents[parent];
83                         }
84                         this.parent = this.getTemplate(dojox.dtl.text.getTemplateString(parent));
85                         if(this.shared){
86                                 this.parents[parent] = this.parent;
87                         }
88                         return this.parent;
89                 },
90                 render: function(context, buffer){
91                         var parent = this.getParent(context);
92
93                         buffer.blocks = buffer.blocks || {};
94
95                         // The parent won't always be in the default parent's nodelist
96                         for(var i = 0, node; node = this.nodelist.contents[i]; i++){
97                                 if(node instanceof dojox.dtl.tag.loader.BlockNode){
98                                         buffer.blocks[node.name] = {
99                                                 shared: this.shared,
100                                                 nodelist: node.nodelist,
101                                                 used: false
102                                         }
103                                 }
104                         }
105
106                         this.rendered = parent;
107                         buffer = parent.nodelist.render(context, buffer, this);
108
109                         var rerender = false;
110                         for(var name in buffer.blocks){
111                                 var block = buffer.blocks[name];
112                                 if(!block.used){
113                                         rerender = true;
114                                         parent.nodelist[0].nodelist.append(block.nodelist);
115                                 }
116                         }
117
118                         if(rerender){
119                                 buffer = parent.nodelist.render(context, buffer, this);
120                         }
121
122                         return buffer;
123                 },
124                 unrender: function(context, buffer){
125                         return this.rendered.unrender(context, buffer, this);
126                 },
127                 toString: function(){ return "dojox.dtl.block.ExtendsNode"; }
128         });
129
130         ddtl.IncludeNode = dojo.extend(function(path, constant, getTemplate, TextNode, parsed){
131                 this._path = path;
132                 this.constant = constant;
133                 this.path = (constant) ? path : new dd._Filter(path);
134                 this.getTemplate = getTemplate;
135                 this.TextNode = TextNode;
136                 this.parsed = (arguments.length == 5) ? parsed : true;
137         },
138         {
139                 _cache: [{}, {}],
140                 render: function(context, buffer){
141                         var location = ((this.constant) ? this.path : this.path.resolve(context)).toString();
142                         var parsed = Number(this.parsed);
143                         var dirty = false;
144                         if(location != this.last){
145                                 dirty = true;
146                                 if(this.last){
147                                         buffer = this.unrender(context, buffer);
148                                 }
149                                 this.last = location;
150                         }
151
152                         var cache = this._cache[parsed];
153
154                         if(parsed){
155                                 if(!cache[location]){
156                                         cache[location] = dd.text._resolveTemplateArg(location, true);
157                                 }
158                                 if(dirty){
159                                         var template = this.getTemplate(cache[location]);
160                                         this.rendered = template.nodelist;
161                                 }
162                                 return this.rendered.render(context, buffer, this);
163                         }else{
164                                 if(this.TextNode == dd._TextNode){
165                                         if(dirty){
166                                                 this.rendered = new this.TextNode("");
167                                                 this.rendered.set(dd.text._resolveTemplateArg(location, true));
168                                         }
169                                         return this.rendered.render(context, buffer);
170                                 }else{
171                                         if(!cache[location]){
172                                                 var nodelist = [];
173                                                 var div = document.createElement("div");
174                                                 div.innerHTML = dd.text._resolveTemplateArg(location, true);
175                                                 var children = div.childNodes;
176                                                 while(children.length){
177                                                         var removed = div.removeChild(children[0]);
178                                                         nodelist.push(removed);
179                                                 }
180                                                 cache[location] = nodelist;
181                                         }
182                                         if(dirty){
183                                                 this.nodelist = [];
184                                                 var exists = true;
185                                                 for(var i = 0, child; child = cache[location][i]; i++){
186                                                         this.nodelist.push(child.cloneNode(true));
187                                                 }
188                                         }
189                                         for(var i = 0, node; node = this.nodelist[i]; i++){
190                                                 buffer = buffer.concat(node);
191                                         }
192                                 }
193                         }
194                         return buffer;
195                 },
196                 unrender: function(context, buffer){
197                         if(this.rendered){
198                                 buffer = this.rendered.unrender(context, buffer);
199                         }
200                         if(this.nodelist){
201                                 for(var i = 0, node; node = this.nodelist[i]; i++){
202                                         buffer = buffer.remove(node);
203                                 }
204                         }
205                         return buffer;
206                 },
207                 clone: function(buffer){
208                         return new this.constructor(this._path, this.constant, this.getTemplate, this.TextNode, this.parsed);
209                 }
210         });
211
212         dojo.mixin(ddtl, {
213                 block: function(parser, text){
214                         var parts = text.split(" ");
215                         var name = parts[1];
216
217                         parser._blocks = parser._blocks || {};
218                         parser._blocks[name] = parser._blocks[name] || [];
219                         parser._blocks[name].push(name);
220
221                         var nodelist = parser.parse(["endblock", "endblock " + name]);
222                         parser.next();
223                         return new dojox.dtl.tag.loader.BlockNode(name, nodelist);
224                 },
225                 extends_: function(parser, text){
226                         var parts = text.split(" ");
227                         var shared = false;
228                         var parent = null;
229                         var key = null;
230                         if(parts[1].charAt(0) == '"' || parts[1].charAt(0) == "'"){
231                                 parent = parts[1].substring(1, parts[1].length - 1);
232                         }else{
233                                 key = parts[1];
234                         }
235                         if(parent && parent.indexOf("shared:") == 0){
236                                 shared = true;
237                                 parent = parent.substring(7, parent.length);
238                         }
239                         var nodelist = parser.parse();
240                         return new dojox.dtl.tag.loader.ExtendsNode(parser.getTemplate, nodelist, shared, parent, key);
241                 },
242                 include: function(parser, token){
243                         var parts = dd.text.pySplit(token);
244                         if(parts.length != 2){
245                                 throw new Error(parts[0] + " tag takes one argument: the name of the template to be included");
246                         }
247                         var path = parts[1];
248                         var constant = false;
249                         if((path.charAt(0) == '"' || path.slice(-1) == "'") && path.charAt(0) == path.slice(-1)){
250                                 path = path.slice(1, -1);
251                                 constant = true;
252                         }
253                         return new ddtl.IncludeNode(path, constant, parser.getTemplate, parser.getTextNodeConstructor());
254                 },
255                 ssi: function(parser, token){
256                         // We're going to treat things a little differently here.
257                         // First of all, this tag is *not* portable, so I'm not
258                         // concerned about it being a "drop in" replacement.
259
260                         // Instead, we'll just replicate the include tag, but with that
261                         // optional "parsed" parameter.
262                         var parts = dd.text.pySplit(token);
263                         var parsed = false;
264                         if(parts.length == 3){
265                                 parsed = (parts.pop() == "parsed");
266                                 if(!parsed){
267                                         throw new Error("Second (optional) argument to ssi tag must be 'parsed'");
268                                 }
269                         }
270                         var node = ddtl.include(parser, parts.join(" "));
271                         node.parsed = parsed;
272                         return node;
273                 }
274         });
275 })();
276
277 }