Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed compilation for macros

  • Loading branch information...
commit 5e3a1dea4f906df4e7d4bd48de4e99d3cd97e7bb 1 parent bc3ed24
Armin Ronacher authored December 05, 2011
33  templatetk/jscompiler.py
@@ -206,6 +206,19 @@ def write_context_as_object(self, fstate, reference_node):
206 206
             self.writer.write('%s: %s' % (self.writer.dump_object(name), local_id))
207 207
         self.writer.write('})')
208 208
 
  209
+    def start_buffering(self, fstate):
  210
+        self.writer.write_line('w = rts.startBuffering()')
  211
+
  212
+    def return_buffer_contents(self, fstate, write_to_var=False):
  213
+        tmp = self.ident_manager.temporary()
  214
+        self.writer.write_line('var %s = rts.endBuffering();' % tmp)
  215
+        self.writer.write_line('w = %s[0];' % tmp)
  216
+        if write_to_var:
  217
+            self.writer.write_line('%s = %s[1];' % (tmp, tmp))
  218
+            return tmp
  219
+        else:
  220
+            self.writer.write_line('return %s[1];' % tmp)
  221
+
209 222
     def visit_block(self, nodes, fstate):
210 223
         self.writer.write_newline()
211 224
         try:
@@ -343,10 +356,7 @@ def visit_If(self, node, fstate):
343 356
 
344 357
     def visit_Output(self, node, fstate):
345 358
         for child in node.nodes:
346  
-            if fstate.buffer:
347  
-                self.writer.write_line('%s.push(' % fstate.buffer)
348  
-            else:
349  
-                self.writer.write_line('w(')
  359
+            self.writer.write_line('w(')
350 360
             if isinstance(child, nodes.TemplateData):
351 361
                 self.writer.write_repr(child.data)
352 362
             else:
@@ -360,7 +370,7 @@ def visit_Extends(self, node, fstate):
360 370
         self.visit(node.template, fstate)
361 371
         self.writer.write(', ')
362 372
         self.write_context_as_object(fstate, node)
363  
-        self.writer.write(');')
  373
+        self.writer.write(', w);')
364 374
 
365 375
         if fstate.root:
366 376
             raise StopFrameCompilation()
@@ -371,15 +381,14 @@ def visit_Block(self, node, fstate):
371 381
         self.writer.write(');')
372 382
 
373 383
     def visit_Function(self, node, fstate):
374  
-        buffer_name = self.ident_manager.temporary()
375 384
         func_fstate = fstate.derive()
376 385
         func_fstate.analyze_identfiers(node.args)
377 386
         func_fstate.analyze_identfiers(node.body)
378  
-        func_fstate.buffer = buffer_name
379 387
 
380  
-        self.writer.write('rts.wrapFunction(')
  388
+        argnames = [x.name for x in node.args]
  389
+        self.writer.write('rt.wrapFunction(')
381 390
         self.visit(node.name, fstate)
382  
-        self.writer.write(', %d, [' % len(node.args))
  391
+        self.writer.write(', %s, [' % self.writer.dump_object(argnames))
383 392
 
384 393
         for idx, arg in enumerate(node.defaults or ()):
385 394
             if idx:
@@ -397,15 +406,13 @@ def visit_Function(self, node, fstate):
397 406
         self.writer.write_newline()
398 407
         self.writer.indent()
399 408
 
400  
-        self.writer.write('var %s = [];' % func_fstate.buffer)
401 409
         buffer = self.writer.start_buffering()
  410
+        self.start_buffering(func_fstate)
402 411
         self.visit_block(node.body, func_fstate)
403 412
         self.writer.end_buffering()
404 413
         self.write_scope_code(func_fstate)
405 414
         self.writer.write_from_buffer(buffer)
406  
-
407  
-        self.writer.write_line('return rts.info.concatTemplateData(%s);' %
408  
-            func_fstate.buffer)
  415
+        self.return_buffer_contents(func_fstate)
409 416
 
410 417
         self.writer.outdent()
411 418
         self.writer.write_line('})')
53  templatetk/res/templatetk.runtime.js
@@ -16,6 +16,12 @@
16 16
     });
17 17
   }
18 18
 
  19
+  function makeWriteFunc(buffer) {
  20
+    if (buffer.push.bind)
  21
+      return buffer.push.bind(buffer);
  22
+    return function(x) { buffer.push(x); };
  23
+  }
  24
+
19 25
   function Config() {
20 26
     this.filters = {};
21 27
   };
@@ -66,9 +72,7 @@
66 72
     render : function(context) {
67 73
       context = new Context(context || {}, new Context(rtlib.getGlobals()));
68 74
       var buffer = [];
69  
-      var rtstate = this.makeRuntimeState(context, function(chunk) {
70  
-        buffer.push(chunk);
71  
-      });
  75
+      var rtstate = this.makeRuntimeState(context, makeWriteFunc(buffer));
72 76
       this.run(rtstate);
73 77
       return buffer.join("");
74 78
     },
@@ -124,6 +128,7 @@
124 128
     this.context = context;
125 129
     this.config = config;
126 130
     this.writeFunc = writeFunc;
  131
+    this.buffers = [];
127 132
     if (!info)
128 133
       info = new rtlib.RuntimeInfo(this.config, templateName);
129 134
     this.info = info;
@@ -157,10 +162,25 @@
157 162
       return rv;
158 163
     },
159 164
 
160  
-    extendTemplate : function(name, context) {
  165
+    extendTemplate : function(name, context, writeFunc) {
161 166
       var template = this.getTemplate(name);
162 167
       var info = this.info.makeInfo(template, name, "extends");
163  
-      return this.config.evaluateTemplate(template, context, this.writeFunc, info);
  168
+      return this.config.evaluateTemplate(template, context, writeFunc, info);
  169
+    },
  170
+
  171
+    startBuffering : function() {
  172
+      var buffer = [];
  173
+      this.buffers.push([this.writeFunc, buffer]);
  174
+      return this.writeFunc = makeWriteFunc(buffer);
  175
+    },
  176
+
  177
+    endBuffering : function() {
  178
+      var entry = this.buffers.pop();
  179
+      this.writeFunc = entry[0];
  180
+      var rv = entry[1].join('');
  181
+      if (this.autoescape)
  182
+        rv = rtlib.markSafe(rv);
  183
+      return [this.writeFunc, rv];
164 184
     }
165 185
   };
166 186
 
@@ -198,13 +218,6 @@
198 218
       return rtlib.finalize(value, this.autoescape);
199 219
     },
200 220
 
201  
-    concatTemplateData : function(buffer) {
202  
-      var rv = buffer.join('');
203  
-      if (this.autoescape)
204  
-        rv = rtlib.markSafe(rv);
205  
-      return rv;
206  
-    },
207  
-
208 221
     registerBlock : function(name, executor) {
209 222
       var m = this.blockExecutors;
210 223
       (m[name] = (m[name] || [])).push(executor);
@@ -311,8 +324,20 @@
311 324
         elseFunc();
312 325
     },
313 326
 
314  
-    wrapFunction : function(name, argCount, defaults, func) {
315  
-      return func;
  327
+    wrapFunction : function(name, argNames, defaults, func) {
  328
+      var argCount = argNames.length;
  329
+      return function() {
  330
+        var args = [];
  331
+        for (var i = 0, n = Math.min(arguments.length, argCount); i < n; i++)
  332
+          args.push(arguments[i]);
  333
+        var off = args.length;
  334
+        if (off != argCount)
  335
+          for (var i = 0, n = argCount - off; i < n; i++) {
  336
+            var didx = defaults.length + (i - argCount + off);
  337
+            args.push(rtlib.makeUndefined(defaults[didx], argNames[off + i]));
  338
+          }
  339
+        return func.apply(null, args);
  340
+      };
316 341
     }
317 342
   };
318 343
 
2  templatetk/runtime.py
@@ -133,7 +133,7 @@ def __call__(self, *args, **kwargs):
133 133
         pos_args = list(args[:self._arg_count])
134 134
         off = len(args)
135 135
         if off != self._arg_count:
136  
-            for idx, name in enumerate(self._arguments[:len(pos_args)]):
  136
+            for idx, name in enumerate(self._arguments[len(pos_args):]):
137 137
                 try:
138 138
                     value = kwargs.pop(name)
139 139
                 except KeyError:

0 notes on commit 5e3a1de

Please sign in to comment.
Something went wrong with that request. Please try again.