dust-sinatra 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.DS_Store
2
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dust-rails.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,97 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dust-rails (0.1.0)
5
+ execjs
6
+ rails (~> 3.1.0)
7
+ tilt
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ actionmailer (3.1.3)
13
+ actionpack (= 3.1.3)
14
+ mail (~> 2.3.0)
15
+ actionpack (3.1.3)
16
+ activemodel (= 3.1.3)
17
+ activesupport (= 3.1.3)
18
+ builder (~> 3.0.0)
19
+ erubis (~> 2.7.0)
20
+ i18n (~> 0.6)
21
+ rack (~> 1.3.5)
22
+ rack-cache (~> 1.1)
23
+ rack-mount (~> 0.8.2)
24
+ rack-test (~> 0.6.1)
25
+ sprockets (~> 2.0.3)
26
+ activemodel (3.1.3)
27
+ activesupport (= 3.1.3)
28
+ builder (~> 3.0.0)
29
+ i18n (~> 0.6)
30
+ activerecord (3.1.3)
31
+ activemodel (= 3.1.3)
32
+ activesupport (= 3.1.3)
33
+ arel (~> 2.2.1)
34
+ tzinfo (~> 0.3.29)
35
+ activeresource (3.1.3)
36
+ activemodel (= 3.1.3)
37
+ activesupport (= 3.1.3)
38
+ activesupport (3.1.3)
39
+ multi_json (~> 1.0)
40
+ arel (2.2.1)
41
+ builder (3.0.0)
42
+ erubis (2.7.0)
43
+ execjs (1.2.12)
44
+ multi_json (~> 1.0)
45
+ hike (1.2.1)
46
+ i18n (0.6.0)
47
+ json (1.6.3)
48
+ mail (2.3.0)
49
+ i18n (>= 0.4.0)
50
+ mime-types (~> 1.16)
51
+ treetop (~> 1.4.8)
52
+ mime-types (1.17.2)
53
+ multi_json (1.0.4)
54
+ polyglot (0.3.3)
55
+ rack (1.3.5)
56
+ rack-cache (1.1)
57
+ rack (>= 0.4)
58
+ rack-mount (0.8.3)
59
+ rack (>= 1.0.0)
60
+ rack-ssl (1.3.2)
61
+ rack
62
+ rack-test (0.6.1)
63
+ rack (>= 1.0)
64
+ rails (3.1.3)
65
+ actionmailer (= 3.1.3)
66
+ actionpack (= 3.1.3)
67
+ activerecord (= 3.1.3)
68
+ activeresource (= 3.1.3)
69
+ activesupport (= 3.1.3)
70
+ bundler (~> 1.0)
71
+ railties (= 3.1.3)
72
+ railties (3.1.3)
73
+ actionpack (= 3.1.3)
74
+ activesupport (= 3.1.3)
75
+ rack-ssl (~> 1.3.2)
76
+ rake (>= 0.8.7)
77
+ rdoc (~> 3.4)
78
+ thor (~> 0.14.6)
79
+ rake (0.9.2.2)
80
+ rdoc (3.12)
81
+ json (~> 1.4)
82
+ sprockets (2.0.3)
83
+ hike (~> 1.2)
84
+ rack (~> 1.0)
85
+ tilt (!= 1.3.0, ~> 1.1)
86
+ thor (0.14.6)
87
+ tilt (1.3.3)
88
+ treetop (1.4.10)
89
+ polyglot
90
+ polyglot (>= 0.3.1)
91
+ tzinfo (0.3.31)
92
+
93
+ PLATFORMS
94
+ ruby
95
+
96
+ DEPENDENCIES
97
+ dust-rails!
data/README.markdown ADDED
@@ -0,0 +1,69 @@
1
+ # Dust-Sinatra
2
+
3
+ This gem adds the Dust template and a corresponding assets engine to sinatra applications.
4
+
5
+ For detailed information about Dust, visit <http://akdubya.github.com/dustjs/>
6
+
7
+ ## Installing
8
+
9
+ Add the following line to your Gemfile:
10
+
11
+ gem 'dust-sinatra'
12
+
13
+ Update your bundle:
14
+
15
+ bundle install
16
+
17
+ ## Usage
18
+
19
+ Place individual Dust template file in their own file with `template_name.js.dust` extension.
20
+
21
+ ```javascript
22
+ /* views/js/templates/demo.js.dust */
23
+
24
+ Hello {name}! You have {count} new messages.
25
+ ```
26
+
27
+ Which will be compiled and rendered as:
28
+
29
+ ```javascript
30
+ (function(){dust.register("demo",body_0);function body_0(chk,ctx){return chk.write("Hello ").reference(ctx.get("name"),ctx,"h").write("! You have ").reference(ctx.get("count"),ctx,"h").write(" new messages.");}return body_0;})();
31
+ ```
32
+
33
+
34
+ Dust-sinatra resolves the name of the template out of request path of each template file.
35
+ Relative path starts from `/` by default.
36
+
37
+ /demo1.js -> demo1
38
+ /demos/demo2.js -> demos/demo2
39
+
40
+ If you want to change the default root path of template files, add following configuration:
41
+
42
+ ```ruby
43
+ module YourApp
44
+ class YourApplication < Sinatra::Base
45
+ configure do
46
+ Dust.config.template_root = '/your_path_to_templates/'
47
+ end
48
+ end
49
+ end
50
+ ```
51
+
52
+ In your html files, load `dust-core` and your own template files.
53
+ You are also able to use `require-js` or `sinatra-assetpack` to include the files.
54
+
55
+ ```html
56
+ <!-- index.html -->
57
+ ...
58
+ <script src="js/dust-core.js"></script>
59
+ <script src="js/dust_template_path.js"></script>
60
+ ```
61
+
62
+ ```javascript
63
+ ...
64
+ dust.render("demo", {name: "Fred", count: 10}, function(err, out) {
65
+ console.log(out);
66
+ });
67
+ ```
68
+
69
+ All done. Your template files will be compiled and registered.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dust-sinatra/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dust-sinatra"
7
+ s.version = Dust::Sinatra::VERSION
8
+ s.authors = ["Sean Lee", "Hoseong Hwang"]
9
+ s.email = ["ssowonny@gmail.com", "thefron@wafflestudio.com"]
10
+ s.homepage = "https://github.com/ssowonny/dust-sinatra"
11
+ s.summary = %q{Use dust.js with sinatra}
12
+ s.description = %q{This gem makes you dust.js easy to use with sinatra.}
13
+
14
+ s.rubyforge_project = "dust-sinatra"
15
+
16
+ s.add_dependency('sinatra')
17
+ s.add_dependency('tilt')
18
+ s.add_dependency('execjs')
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+ end
@@ -0,0 +1,20 @@
1
+ require "dust-sinatra/version"
2
+ require "dust-sinatra/sinatra/helpers.rb"
3
+ require "dust-sinatra/sinatra/dust_template.rb"
4
+ require "dust-sinatra/sinatra/base.rb"
5
+
6
+ module Dust
7
+
8
+ class Config
9
+ attr_accessor :template_root
10
+ end
11
+
12
+ def self.config
13
+ @@config ||= Config.new
14
+ end
15
+
16
+ def self.configure
17
+ yield self.config
18
+ end
19
+
20
+ end
@@ -0,0 +1,10 @@
1
+ module Dust
2
+ module Sinatra
3
+ Tilt.register DustTemplate, :dust
4
+
5
+ def self.registered( app )
6
+ app.helpers Dust::Sinatra::Helpers
7
+ Dust.config.template_root ||= "/"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ require 'tilt'
2
+ require 'execjs'
3
+
4
+ module Dust
5
+ module Sinatra
6
+
7
+ module Source
8
+ def self.path
9
+ @path ||= File.expand_path('../../../../vendor/assets/javascripts/dust-full-for-compile.js', __FILE__)
10
+ end
11
+
12
+ def self.contents
13
+ @contents ||= File.read(path)
14
+ end
15
+
16
+ def self.context
17
+ @context ||= ExecJS.compile(contents)
18
+ end
19
+
20
+ end
21
+
22
+ class DustTemplate < ::Tilt::Template
23
+
24
+ def self.default_mime_type
25
+ 'application/javascript'
26
+ end
27
+
28
+ def prepare
29
+ end
30
+
31
+ def evaluate(scope, locals, &block)
32
+ template_root = Dust.config.template_root
33
+ template_name = scope.env["REQUEST_PATH"].split(template_root).last.split('.',2).first
34
+ Source.context.call("dust.compile", data, template_name)
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+
@@ -0,0 +1,7 @@
1
+ module Dust
2
+ module Sinatra
3
+ module Helpers
4
+ def dust(*args) render( :dust, *args ) end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module Dust
2
+ module Sinatra
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -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
+ }