dust-rails 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,522 @@
1
+ //
2
+ // Dust - Asynchronous Templating v0.3.0
3
+ // http://akdubya.github.com/dustjs
4
+ //
5
+ // Copyright (c) 2010, Aleksander Williams
6
+ // Released under the MIT License.
7
+ //
8
+
9
+ var dust = {};
10
+
11
+ (function(dust) {
12
+
13
+ dust.cache = {};
14
+
15
+ dust.register = function(name, tmpl) {
16
+ if (!name) return;
17
+ dust.cache[name] = tmpl;
18
+ };
19
+
20
+ dust.render = function(name, context, callback) {
21
+ var chunk = new Stub(callback).head;
22
+ dust.load(name, chunk, Context.wrap(context)).end();
23
+ };
24
+
25
+ dust.stream = function(name, context) {
26
+ var stream = new Stream();
27
+ dust.nextTick(function() {
28
+ dust.load(name, stream.head, Context.wrap(context)).end();
29
+ });
30
+ return stream;
31
+ };
32
+
33
+ dust.renderSource = function(source, context, callback) {
34
+ return dust.compileFn(source)(context, callback);
35
+ };
36
+
37
+ dust.compileFn = function(source, name) {
38
+ var tmpl = dust.loadSource(dust.compile(source, name));
39
+ return function(context, callback) {
40
+ var master = callback ? new Stub(callback) : new Stream();
41
+ dust.nextTick(function() {
42
+ tmpl(master.head, Context.wrap(context)).end();
43
+ });
44
+ return master;
45
+ }
46
+ };
47
+
48
+ dust.load = function(name, chunk, context) {
49
+ var tmpl = dust.cache[name];
50
+ if (tmpl) {
51
+ return tmpl(chunk, context);
52
+ } else {
53
+ if (dust.onLoad) {
54
+ return chunk.map(function(chunk) {
55
+ dust.onLoad(name, function(err, src) {
56
+ if (err) return chunk.setError(err);
57
+ if (!dust.cache[name]) dust.loadSource(dust.compile(src, name));
58
+ dust.cache[name](chunk, context).end();
59
+ });
60
+ });
61
+ }
62
+ return chunk.setError(new Error("Template Not Found: " + name));
63
+ }
64
+ };
65
+
66
+ dust.loadSource = function(source, path) {
67
+ return eval(source);
68
+ };
69
+
70
+ if (Array.isArray) {
71
+ dust.isArray = Array.isArray;
72
+ } else {
73
+ dust.isArray = function(arr) {
74
+ return Object.prototype.toString.call(arr) == "[object Array]";
75
+ };
76
+ }
77
+
78
+ dust.nextTick = function(callback) {
79
+ setTimeout(callback, 0);
80
+ }
81
+
82
+ dust.isEmpty = function(value) {
83
+ if (dust.isArray(value) && !value.length) return true;
84
+ if (value === 0) return false;
85
+ return (!value);
86
+ };
87
+
88
+ dust.filter = function(string, auto, filters) {
89
+ if (filters) {
90
+ for (var i=0, len=filters.length; i<len; i++) {
91
+ var name = filters[i];
92
+ if (name === "s") {
93
+ auto = null;
94
+ } else {
95
+ string = dust.filters[name](string);
96
+ }
97
+ }
98
+ }
99
+ if (auto) {
100
+ string = dust.filters[auto](string);
101
+ }
102
+ return string;
103
+ };
104
+
105
+ dust.filters = {
106
+ h: function(value) { return dust.escapeHtml(value); },
107
+ j: function(value) { return dust.escapeJs(value); },
108
+ u: encodeURI,
109
+ uc: encodeURIComponent
110
+ }
111
+
112
+ function Context(stack, global, blocks) {
113
+ this.stack = stack;
114
+ this.global = global;
115
+ this.blocks = blocks;
116
+ }
117
+
118
+ dust.makeBase = function(global) {
119
+ return new Context(new Stack(), global);
120
+ }
121
+
122
+ Context.wrap = function(context) {
123
+ if (context instanceof Context) {
124
+ return context;
125
+ }
126
+ return new Context(new Stack(context));
127
+ }
128
+
129
+ Context.prototype.get = function(key) {
130
+ var ctx = this.stack, value;
131
+
132
+ while(ctx) {
133
+ if (ctx.isObject) {
134
+ value = ctx.head[key];
135
+ if (!(value === undefined)) {
136
+ return value;
137
+ }
138
+ }
139
+ ctx = ctx.tail;
140
+ }
141
+ return this.global ? this.global[key] : undefined;
142
+ };
143
+
144
+ Context.prototype.getPath = function(cur, down) {
145
+ var ctx = this.stack,
146
+ len = down.length;
147
+
148
+ if (cur && len === 0) return ctx.head;
149
+ if (!ctx.isObject) return undefined;
150
+ ctx = ctx.head;
151
+ var i = 0;
152
+ while(ctx && i < len) {
153
+ ctx = ctx[down[i]];
154
+ i++;
155
+ }
156
+ return ctx;
157
+ };
158
+
159
+ Context.prototype.push = function(head, idx, len) {
160
+ return new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
161
+ };
162
+
163
+ Context.prototype.rebase = function(head) {
164
+ return new Context(new Stack(head), this.global, this.blocks);
165
+ };
166
+
167
+ Context.prototype.current = function() {
168
+ return this.stack.head;
169
+ };
170
+
171
+ Context.prototype.getBlock = function(key) {
172
+ var blocks = this.blocks;
173
+
174
+ if (!blocks) return;
175
+ var len = blocks.length, fn;
176
+ while (len--) {
177
+ fn = blocks[len][key];
178
+ if (fn) return fn;
179
+ }
180
+ }
181
+
182
+ Context.prototype.shiftBlocks = function(locals) {
183
+ var blocks = this.blocks;
184
+
185
+ if (locals) {
186
+ if (!blocks) {
187
+ newBlocks = [locals];
188
+ } else {
189
+ newBlocks = blocks.concat([locals]);
190
+ }
191
+ return new Context(this.stack, this.global, newBlocks);
192
+ }
193
+ return this;
194
+ }
195
+
196
+ function Stack(head, tail, idx, len) {
197
+ this.tail = tail;
198
+ this.isObject = !dust.isArray(head) && head && typeof head === "object";
199
+ this.head = head;
200
+ this.index = idx;
201
+ this.of = len;
202
+ }
203
+
204
+ function Stub(callback) {
205
+ this.head = new Chunk(this);
206
+ this.callback = callback;
207
+ this.out = '';
208
+ }
209
+
210
+ Stub.prototype.flush = function() {
211
+ var chunk = this.head;
212
+
213
+ while (chunk) {
214
+ if (chunk.flushable) {
215
+ this.out += chunk.data;
216
+ } else if (chunk.error) {
217
+ this.callback(chunk.error);
218
+ this.flush = function() {};
219
+ return;
220
+ } else {
221
+ return;
222
+ }
223
+ chunk = chunk.next;
224
+ this.head = chunk;
225
+ }
226
+ this.callback(null, this.out);
227
+ }
228
+
229
+ function Stream() {
230
+ this.head = new Chunk(this);
231
+ }
232
+
233
+ Stream.prototype.flush = function() {
234
+ var chunk = this.head;
235
+
236
+ while(chunk) {
237
+ if (chunk.flushable) {
238
+ this.emit('data', chunk.data);
239
+ } else if (chunk.error) {
240
+ this.emit('error', chunk.error);
241
+ this.flush = function() {};
242
+ return;
243
+ } else {
244
+ return;
245
+ }
246
+ chunk = chunk.next;
247
+ this.head = chunk;
248
+ }
249
+ this.emit('end');
250
+ }
251
+
252
+ Stream.prototype.emit = function(type, data) {
253
+ var events = this.events;
254
+
255
+ if (events && events[type]) {
256
+ events[type](data);
257
+ }
258
+ }
259
+
260
+ Stream.prototype.on = function(type, callback) {
261
+ if (!this.events) {
262
+ this.events = {};
263
+ }
264
+ this.events[type] = callback;
265
+ return this;
266
+ }
267
+
268
+ function Chunk(root, next, taps) {
269
+ this.root = root;
270
+ this.next = next;
271
+ this.data = '';
272
+ this.flushable = false;
273
+ this.taps = taps;
274
+ }
275
+
276
+ Chunk.prototype.write = function(data) {
277
+ var taps = this.taps;
278
+
279
+ if (taps) {
280
+ data = taps.go(data);
281
+ }
282
+ this.data += data;
283
+ return this;
284
+ }
285
+
286
+ Chunk.prototype.end = function(data) {
287
+ if (data) {
288
+ this.write(data);
289
+ }
290
+ this.flushable = true;
291
+ this.root.flush();
292
+ return this;
293
+ }
294
+
295
+ Chunk.prototype.map = function(callback) {
296
+ var cursor = new Chunk(this.root, this.next, this.taps),
297
+ branch = new Chunk(this.root, cursor, this.taps);
298
+
299
+ this.next = branch;
300
+ this.flushable = true;
301
+ callback(branch);
302
+ return cursor;
303
+ }
304
+
305
+ Chunk.prototype.tap = function(tap) {
306
+ var taps = this.taps;
307
+
308
+ if (taps) {
309
+ this.taps = taps.push(tap);
310
+ } else {
311
+ this.taps = new Tap(tap);
312
+ }
313
+ return this;
314
+ }
315
+
316
+ Chunk.prototype.untap = function() {
317
+ this.taps = this.taps.tail;
318
+ return this;
319
+ }
320
+
321
+ Chunk.prototype.render = function(body, context) {
322
+ return body(this, context);
323
+ }
324
+
325
+ Chunk.prototype.reference = function(elem, context, auto, filters) {
326
+ if (typeof elem === "function") {
327
+ elem = elem(this, context, null, {auto: auto, filters: filters});
328
+ if (elem instanceof Chunk) {
329
+ return elem;
330
+ }
331
+ }
332
+ if (!dust.isEmpty(elem)) {
333
+ return this.write(dust.filter(elem, auto, filters));
334
+ } else {
335
+ return this;
336
+ }
337
+ };
338
+
339
+ Chunk.prototype.section = function(elem, context, bodies, params) {
340
+ if (typeof elem === "function") {
341
+ elem = elem(this, context, bodies, params);
342
+ if (elem instanceof Chunk) {
343
+ return elem;
344
+ }
345
+ }
346
+
347
+ var body = bodies.block,
348
+ skip = bodies['else'];
349
+
350
+ if (params) {
351
+ context = context.push(params);
352
+ }
353
+
354
+ if (dust.isArray(elem)) {
355
+ if (body) {
356
+ var len = elem.length, chunk = this;
357
+ for (var i=0; i<len; i++) {
358
+ chunk = body(chunk, context.push(elem[i], i, len));
359
+ }
360
+ return chunk;
361
+ }
362
+ } else if (elem === true) {
363
+ if (body) return body(this, context);
364
+ } else if (elem || elem === 0) {
365
+ if (body) return body(this, context.push(elem));
366
+ } else if (skip) {
367
+ return skip(this, context);
368
+ }
369
+ return this;
370
+ };
371
+
372
+ Chunk.prototype.exists = function(elem, context, bodies) {
373
+ var body = bodies.block,
374
+ skip = bodies['else'];
375
+
376
+ if (!dust.isEmpty(elem)) {
377
+ if (body) return body(this, context);
378
+ } else if (skip) {
379
+ return skip(this, context);
380
+ }
381
+ return this;
382
+ }
383
+
384
+ Chunk.prototype.notexists = function(elem, context, bodies) {
385
+ var body = bodies.block,
386
+ skip = bodies['else'];
387
+
388
+ if (dust.isEmpty(elem)) {
389
+ if (body) return body(this, context);
390
+ } else if (skip) {
391
+ return skip(this, context);
392
+ }
393
+ return this;
394
+ }
395
+
396
+ Chunk.prototype.block = function(elem, context, bodies) {
397
+ var body = bodies.block;
398
+
399
+ if (elem) {
400
+ body = elem;
401
+ }
402
+
403
+ if (body) {
404
+ return body(this, context);
405
+ }
406
+ return this;
407
+ };
408
+
409
+ Chunk.prototype.partial = function(elem, context) {
410
+ if (typeof elem === "function") {
411
+ return this.capture(elem, context, function(name, chunk) {
412
+ dust.load(name, chunk, context).end();
413
+ });
414
+ }
415
+ return dust.load(elem, this, context);
416
+ };
417
+
418
+ Chunk.prototype.helper = function(name, context, bodies, params) {
419
+ return dust.helpers[name](this, context, bodies, params);
420
+ };
421
+
422
+ Chunk.prototype.capture = function(body, context, callback) {
423
+ return this.map(function(chunk) {
424
+ var stub = new Stub(function(err, out) {
425
+ if (err) {
426
+ chunk.setError(err);
427
+ } else {
428
+ callback(out, chunk);
429
+ }
430
+ });
431
+ body(stub.head, context).end();
432
+ });
433
+ };
434
+
435
+ Chunk.prototype.setError = function(err) {
436
+ this.error = err;
437
+ this.root.flush();
438
+ return this;
439
+ };
440
+
441
+ dust.helpers = {
442
+ sep: function(chunk, context, bodies) {
443
+ if (context.stack.index === context.stack.of - 1) {
444
+ return chunk;
445
+ }
446
+ return bodies.block(chunk, context);
447
+ },
448
+
449
+ idx: function(chunk, context, bodies) {
450
+ return bodies.block(chunk, context.push(context.stack.index));
451
+ }
452
+ }
453
+
454
+ function Tap(head, tail) {
455
+ this.head = head;
456
+ this.tail = tail;
457
+ }
458
+
459
+ Tap.prototype.push = function(tap) {
460
+ return new Tap(tap, this);
461
+ };
462
+
463
+ Tap.prototype.go = function(value) {
464
+ var tap = this;
465
+
466
+ while(tap) {
467
+ value = tap.head(value);
468
+ tap = tap.tail;
469
+ }
470
+ return value;
471
+ };
472
+
473
+ var HCHARS = new RegExp(/[&<>\"]/),
474
+ AMP = /&/g,
475
+ LT = /</g,
476
+ GT = />/g,
477
+ QUOT = /\"/g;
478
+
479
+ dust.escapeHtml = function(s) {
480
+ if (typeof s === "string") {
481
+ if (!HCHARS.test(s)) {
482
+ return s;
483
+ }
484
+ return s.replace(AMP,'&amp;').replace(LT,'&lt;').replace(GT,'&gt;').replace(QUOT,'&quot;');
485
+ }
486
+ return s;
487
+ };
488
+
489
+ var BS = /\\/g,
490
+ CR = /\r/g,
491
+ LS = /\u2028/g,
492
+ PS = /\u2029/g,
493
+ NL = /\n/g,
494
+ LF = /\f/g,
495
+ SQ = /'/g,
496
+ DQ = /"/g,
497
+ TB = /\t/g;
498
+
499
+ dust.escapeJs = function(s) {
500
+ if (typeof s === "string") {
501
+ return s
502
+ .replace(BS, '\\\\')
503
+ .replace(DQ, '\\"')
504
+ .replace(SQ, "\\'")
505
+ .replace(CR, '\\r')
506
+ .replace(LS, '\\u2028')
507
+ .replace(PS, '\\u2029')
508
+ .replace(NL, '\\n')
509
+ .replace(LF, '\\f')
510
+ .replace(TB, "\\t");
511
+ }
512
+ return s;
513
+ };
514
+
515
+ })(dust);
516
+
517
+ if (typeof exports !== "undefined") {
518
+ if (typeof process !== "undefined") {
519
+ require('./server')(dust);
520
+ }
521
+ module.exports = dust;
522
+ }
@@ -0,0 +1,21 @@
1
+ //
2
+ // Dust - Asynchronous Templating v0.3.0
3
+ // http://akdubya.github.com/dustjs
4
+ //
5
+ // Copyright (c) 2010, Aleksander Williams
6
+ // Released under the MIT License.
7
+ //
8
+
9
+ var dust={};
10
+ (function(d){function h(a,b,c){this.stack=a;this.global=b;this.blocks=c}function k(a,b,c,e){this.tail=b;this.isObject=!d.isArray(a)&&a&&typeof a==="object";this.head=a;this.index=c;this.of=e}function l(a){this.head=new f(this);this.callback=a;this.out=""}function j(){this.head=new f(this)}function f(a,b,c){this.root=a;this.next=b;this.data="";this.flushable=false;this.taps=c}function m(a,b){this.head=a;this.tail=b}d.cache={};d.register=function(a,b){if(a)d.cache[a]=b};d.render=function(a,b,c){c=(new l(c)).head;
11
+ d.load(a,c,h.wrap(b)).end()};d.stream=function(a,b){var c=new j;d.nextTick(function(){d.load(a,c.head,h.wrap(b)).end()});return c};d.renderSource=function(a,b,c){return d.compileFn(a)(b,c)};d.compileFn=function(a,b){var c=d.loadSource(d.compile(a,b));return function(e,g){var i=g?new l(g):new j;d.nextTick(function(){c(i.head,h.wrap(e)).end()});return i}};d.load=function(a,b,c){var e=d.cache[a];if(e)return e(b,c);else{if(d.onLoad)return b.map(function(g){d.onLoad(a,function(i,n){if(i)return g.setError(i);
12
+ d.cache[a]||d.loadSource(d.compile(n,a));d.cache[a](g,c).end()})});return b.setError(Error("Template Not Found: "+a))}};d.loadSource=function(a){return eval(a)};d.isArray=Array.isArray?Array.isArray:function(a){return Object.prototype.toString.call(a)=="[object Array]"};d.nextTick=function(a){setTimeout(a,0)};d.isEmpty=function(a){if(d.isArray(a)&&!a.length)return true;if(a===0)return false;return!a};d.filter=function(a,b,c){if(c)for(var e=0,g=c.length;e<g;e++){var i=c[e];if(i==="s")b=null;else a=
13
+ d.filters[i](a)}if(b)a=d.filters[b](a);return a};d.filters={h:function(a){return d.escapeHtml(a)},j:function(a){return d.escapeJs(a)},u:encodeURI,uc:encodeURIComponent};d.makeBase=function(a){return new h(new k,a)};h.wrap=function(a){if(a instanceof h)return a;return new h(new k(a))};h.prototype.get=function(a){for(var b=this.stack,c;b;){if(b.isObject){c=b.head[a];if(c!==undefined)return c}b=b.tail}return this.global?this.global[a]:undefined};h.prototype.getPath=function(a,b){var c=this.stack,e=b.length;
14
+ if(a&&e===0)return c.head;if(c.isObject){c=c.head;for(var g=0;c&&g<e;){c=c[b[g]];g++}return c}};h.prototype.push=function(a,b,c){return new h(new k(a,this.stack,b,c),this.global,this.blocks)};h.prototype.rebase=function(a){return new h(new k(a),this.global,this.blocks)};h.prototype.current=function(){return this.stack.head};h.prototype.getBlock=function(a){var b=this.blocks;if(b)for(var c=b.length,e;c--;)if(e=b[c][a])return e};h.prototype.shiftBlocks=function(a){var b=this.blocks;if(a){newBlocks=
15
+ b?b.concat([a]):[a];return new h(this.stack,this.global,newBlocks)}return this};l.prototype.flush=function(){for(var a=this.head;a;){if(a.flushable)this.out+=a.data;else{if(a.error){this.callback(a.error);this.flush=function(){}}return}this.head=a=a.next}this.callback(null,this.out)};j.prototype.flush=function(){for(var a=this.head;a;){if(a.flushable)this.emit("data",a.data);else{if(a.error){this.emit("error",a.error);this.flush=function(){}}return}this.head=a=a.next}this.emit("end")};j.prototype.emit=
16
+ function(a,b){var c=this.events;c&&c[a]&&c[a](b)};j.prototype.on=function(a,b){if(!this.events)this.events={};this.events[a]=b;return this};f.prototype.write=function(a){var b=this.taps;if(b)a=b.go(a);this.data+=a;return this};f.prototype.end=function(a){a&&this.write(a);this.flushable=true;this.root.flush();return this};f.prototype.map=function(a){var b=new f(this.root,this.next,this.taps),c=new f(this.root,b,this.taps);this.next=c;this.flushable=true;a(c);return b};f.prototype.tap=function(a){var b=
17
+ this.taps;this.taps=b?b.push(a):new m(a);return this};f.prototype.untap=function(){this.taps=this.taps.tail;return this};f.prototype.render=function(a,b){return a(this,b)};f.prototype.reference=function(a,b,c,e){if(typeof a==="function"){a=a(this,b,null,{auto:c,filters:e});if(a instanceof f)return a}return d.isEmpty(a)?this:this.write(d.filter(a,c,e))};f.prototype.section=function(a,b,c,e){if(typeof a==="function"){a=a(this,b,c,e);if(a instanceof f)return a}var g=c.block;c=c["else"];if(e)b=b.push(e);
18
+ if(d.isArray(a)){if(g){e=a.length;c=this;for(var i=0;i<e;i++)c=g(c,b.push(a[i],i,e));return c}}else if(a===true){if(g)return g(this,b)}else if(a||a===0){if(g)return g(this,b.push(a))}else if(c)return c(this,b);return this};f.prototype.exists=function(a,b,c){var e=c.block;c=c["else"];if(d.isEmpty(a)){if(c)return c(this,b)}else if(e)return e(this,b);return this};f.prototype.notexists=function(a,b,c){var e=c.block;c=c["else"];if(d.isEmpty(a)){if(e)return e(this,b)}else if(c)return c(this,b);return this};
19
+ f.prototype.block=function(a,b,c){c=c.block;if(a)c=a;if(c)return c(this,b);return this};f.prototype.partial=function(a,b){if(typeof a==="function")return this.capture(a,b,function(c,e){d.load(c,e,b).end()});return d.load(a,this,b)};f.prototype.helper=function(a,b,c,e){return d.helpers[a](this,b,c,e)};f.prototype.capture=function(a,b,c){return this.map(function(e){var g=new l(function(i,n){i?e.setError(i):c(n,e)});a(g.head,b).end()})};f.prototype.setError=function(a){this.error=a;this.root.flush();
20
+ return this};d.helpers={sep:function(a,b,c){if(b.stack.index===b.stack.of-1)return a;return c.block(a,b)},idx:function(a,b,c){return c.block(a,b.push(b.stack.index))}};m.prototype.push=function(a){return new m(a,this)};m.prototype.go=function(a){for(var b=this;b;){a=b.head(a);b=b.tail}return a};var o=RegExp(/[&<>\"]/),p=/&/g,q=/</g,r=/>/g,s=/\"/g;d.escapeHtml=function(a){if(typeof a==="string"){if(!o.test(a))return a;return a.replace(p,"&amp;").replace(q,"&lt;").replace(r,"&gt;").replace(s,"&quot;")}return a};
21
+ var t=/\\/g,u=/\r/g,v=/\u2028/g,w=/\u2029/g,x=/\n/g,y=/\f/g,z=/'/g,A=/"/g,B=/\t/g;d.escapeJs=function(a){if(typeof a==="string")return a.replace(t,"\\\\").replace(A,'\\"').replace(z,"\\'").replace(u,"\\r").replace(v,"\\u2028").replace(w,"\\u2029").replace(x,"\\n").replace(y,"\\f").replace(B,"\\t");return a}})(dust);if(typeof exports!=="undefined"){typeof process!=="undefined"&&require("./server")(dust);module.exports=dust};