marionette_dust 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +114 -0
  8. data/Rakefile +5 -0
  9. data/lib/generators/marionette_dust/common/templates/app.js +10 -0
  10. data/lib/generators/marionette_dust/common/templates/controller.js +3 -0
  11. data/lib/generators/marionette_dust/common/templates/entity.js +9 -0
  12. data/lib/generators/marionette_dust/common/templates/template.jst.dust +1 -0
  13. data/lib/generators/marionette_dust/common/templates/view.js +5 -0
  14. data/lib/generators/marionette_dust/helpers.rb +71 -0
  15. data/lib/generators/marionette_dust/install/install_generator.rb +58 -0
  16. data/lib/generators/marionette_dust/install/templates/app.js +20 -0
  17. data/lib/generators/marionette_dust/install/templates/app.js.coffee +16 -0
  18. data/lib/generators/marionette_dust/scaffold/scaffold_generator.rb +64 -0
  19. data/lib/generators/marionette_dust/submodule/submodule_generator.rb +52 -0
  20. data/lib/marionette_dust/engine.rb +3 -0
  21. data/lib/marionette_dust/version.rb +3 -0
  22. data/lib/marionette_dust.rb +6 -0
  23. data/marionette_dust.gemspec +23 -0
  24. data/vendor/assets/javascripts/marionette_dust/backbone.js +1581 -0
  25. data/vendor/assets/javascripts/marionette_dust/backbone.marionette.js +2385 -0
  26. data/vendor/assets/javascripts/marionette_dust/dust-full-2.1.0.js +3759 -0
  27. data/vendor/assets/javascripts/marionette_dust/dust-helpers-1.1.1.js +523 -0
  28. data/vendor/assets/javascripts/marionette_dust/index.js +7 -0
  29. data/vendor/assets/javascripts/marionette_dust/marionette_renderer.js +11 -0
  30. data/vendor/assets/javascripts/marionette_dust/template_loader.js +13 -0
  31. data/vendor/assets/javascripts/marionette_dust/underscore.js +1276 -0
  32. metadata +103 -0
@@ -0,0 +1,523 @@
1
+ //
2
+ // Dust-helpers - Additional functionality for dustjs-linkedin package v1.1.1
3
+ //
4
+ // Copyright (c) 2012, LinkedIn
5
+ // Released under the MIT License.
6
+ //
7
+
8
+ (function (dust) {
9
+
10
+ // Note: all error conditions are logged to console and failed silently
11
+
12
+ /* make a safe version of console if it is not available
13
+ * currently supporting:
14
+ * _console.log
15
+ * */
16
+ var _console = (typeof console !== 'undefined') ? console : {
17
+ log: function () {
18
+ /* a noop*/
19
+ }
20
+ };
21
+
22
+ function isSelect(context) {
23
+ var value = context.current();
24
+ return typeof value === "object" && value.isSelect === true;
25
+ }
26
+
27
+ // Utility method : toString() equivalent for functions
28
+
29
+ function jsonFilter(key, value) {
30
+ if (typeof value === "function") {
31
+ return value.toString();
32
+ }
33
+ return value;
34
+ }
35
+
36
+ // Utility method: to invoke the given filter operation such as eq/gt etc
37
+
38
+ function filter(chunk, context, bodies, params, filterOp) {
39
+ params = params || {};
40
+ var body = bodies.block,
41
+ actualKey,
42
+ expectedValue,
43
+ filterOpType = params.filterOpType || '';
44
+ // when @eq, @lt etc are used as standalone helpers, key is required and hence check for defined
45
+ if (typeof params.key !== "undefined") {
46
+ actualKey = dust.helpers.tap(params.key, chunk, context);
47
+ } else if (isSelect(context)) {
48
+ actualKey = context.current().selectKey;
49
+ // supports only one of the blocks in the select to be selected
50
+ if (context.current().isResolved) {
51
+ filterOp = function () {
52
+ return false;
53
+ };
54
+ }
55
+ } else {
56
+ _console.log("No key specified for filter in:" + filterOpType + " helper ");
57
+ return chunk;
58
+ }
59
+ expectedValue = dust.helpers.tap(params.value, chunk, context);
60
+ // coerce both the actualKey and expectedValue to the same type for equality and non-equality compares
61
+ if (filterOp(coerce(expectedValue, params.type, context), coerce(actualKey, params.type, context))) {
62
+ if (isSelect(context)) {
63
+ context.current().isResolved = true;
64
+ }
65
+ // we want helpers without bodies to fail gracefully so check it first
66
+ if (body) {
67
+ return chunk.render(body, context);
68
+ } else {
69
+ _console.log("Missing body block in the " + filterOpType + " helper ");
70
+ return chunk;
71
+ }
72
+ } else if (bodies['else']) {
73
+ return chunk.render(bodies['else'], context);
74
+ }
75
+ return chunk;
76
+ }
77
+
78
+ function coerce(value, type, context) {
79
+ if (value) {
80
+ switch (type || typeof (value)) {
81
+ case 'number':
82
+ return +value;
83
+ case 'string':
84
+ return String(value);
85
+ case 'boolean':
86
+ {
87
+ value = (value === 'false' ? false : value);
88
+ return Boolean(value);
89
+ }
90
+ case 'date':
91
+ return new Date(value);
92
+ case 'context':
93
+ return context.get(value);
94
+ }
95
+ }
96
+
97
+ return value;
98
+ }
99
+
100
+ var helpers = {
101
+
102
+ // Utility helping to resolve dust references in the given chunk
103
+ // uses the Chunk.render method to resolve value
104
+ /*
105
+ Reference resolution rules:
106
+ if value exists in JSON:
107
+ "" or '' will evaluate to false, boolean false, null, or undefined will evaluate to false,
108
+ numeric 0 evaluates to true, so does, string "0", string "null", string "undefined" and string "false".
109
+ Also note that empty array -> [] is evaluated to false and empty object -> {} and non-empty object are evaluated to true
110
+ The type of the return value is string ( since we concatenate to support interpolated references
111
+
112
+ if value does not exist in JSON and the input is a single reference: {x}
113
+ dust render emits empty string, and we then return false
114
+
115
+ if values does not exist in JSON and the input is interpolated references : {x} < {y}
116
+ dust render emits < and we return the partial output
117
+
118
+ */
119
+ "tap": function (input, chunk, context) {
120
+ // return given input if there is no dust reference to resolve
121
+ var output = input;
122
+ // dust compiles a string/reference such as {foo} to function,
123
+ if (typeof input === "function") {
124
+ // just a plain function (a.k.a anonymous functions) in the context, not a dust `body` function created by the dust compiler
125
+ if (input.isFunction === true) {
126
+ output = input();
127
+ } else {
128
+ output = '';
129
+ chunk.tap(function (data) {
130
+ output += data;
131
+ return '';
132
+ }).render(input, context).untap();
133
+ if (output === '') {
134
+ output = false;
135
+ }
136
+ }
137
+ }
138
+ return output;
139
+ },
140
+
141
+ "sep": function (chunk, context, bodies) {
142
+ var body = bodies.block;
143
+ if (context.stack.index === context.stack.of - 1) {
144
+ return chunk;
145
+ }
146
+ if (body) {
147
+ return bodies.block(chunk, context);
148
+ } else {
149
+ return chunk;
150
+ }
151
+ },
152
+
153
+ "idx": function (chunk, context, bodies) {
154
+ var body = bodies.block;
155
+ if (body) {
156
+ return bodies.block(chunk, context.push(context.stack.index));
157
+ } else {
158
+ return chunk;
159
+ }
160
+ },
161
+
162
+ /**
163
+ * contextDump helper
164
+ * @param key specifies how much to dump.
165
+ * "current" dumps current context. "full" dumps the full context stack.
166
+ * @param to specifies where to write dump output.
167
+ * Values can be "console" or "output". Default is output.
168
+ */
169
+ "contextDump": function (chunk, context, bodies, params) {
170
+ var p = params || {},
171
+ to = p.to || 'output',
172
+ key = p.key || 'current',
173
+ dump;
174
+ to = dust.helpers.tap(to, chunk, context),
175
+ key = dust.helpers.tap(key, chunk, context);
176
+ if (key === 'full') {
177
+ dump = JSON.stringify(context.stack, jsonFilter, 2);
178
+ } else {
179
+ dump = JSON.stringify(context.stack.head, jsonFilter, 2);
180
+ }
181
+ if (to === 'console') {
182
+ _console.log(dump);
183
+ return chunk;
184
+ } else {
185
+ return chunk.write(dump);
186
+ }
187
+ },
188
+ /**
189
+ if helper for complex evaluation complex logic expressions.
190
+ Note : #1 if helper fails gracefully when there is no body block nor else block
191
+ #2 Undefined values and false values in the JSON need to be handled specially with .length check
192
+ for e.g @if cond=" '{a}'.length && '{b}'.length" is advised when there are chances of the a and b been
193
+ undefined or false in the context
194
+ #3 Use only when the default ? and ^ dust operators and the select fall short in addressing the given logic,
195
+ since eval executes in the global scope
196
+ #4 All dust references are default escaped as they are resolved, hence eval will block malicious scripts in the context
197
+ Be mindful of evaluating a expression that is passed through the unescape filter -> |s
198
+ @param cond, either a string literal value or a dust reference
199
+ a string literal value, is enclosed in double quotes, e.g. cond="2>3"
200
+ a dust reference is also enclosed in double quotes, e.g. cond="'{val}'' > 3"
201
+ cond argument should evaluate to a valid javascript expression
202
+ **/
203
+
204
+ "if": function (chunk, context, bodies, params) {
205
+ var body = bodies.block,
206
+ skip = bodies['else'];
207
+ if (params && params.cond) {
208
+ var cond = params.cond;
209
+ cond = dust.helpers.tap(cond, chunk, context);
210
+ // eval expressions with given dust references
211
+ if (eval(cond)) {
212
+ if (body) {
213
+ return chunk.render(bodies.block, context);
214
+ } else {
215
+ _console.log("Missing body block in the if helper!");
216
+ return chunk;
217
+ }
218
+ }
219
+ if (skip) {
220
+ return chunk.render(bodies['else'], context);
221
+ }
222
+ }
223
+ // no condition
224
+ else {
225
+ _console.log("No condition given in the if helper!");
226
+ }
227
+ return chunk;
228
+ },
229
+
230
+ /**
231
+ * math helper
232
+ * @param key is the value to perform math against
233
+ * @param method is the math method, is a valid string supported by math helper like mod, add, subtract
234
+ * @param operand is the second value needed for operations like mod, add, subtract, etc.
235
+ * @param round is a flag to assure that an integer is returned
236
+ */
237
+ "math": function (chunk, context, bodies, params) {
238
+ //key and method are required for further processing
239
+ if (params && typeof params.key !== "undefined" && params.method) {
240
+ var key = params.key,
241
+ method = params.method,
242
+ // operand can be null for "abs", ceil and floor
243
+ operand = params.operand,
244
+ round = params.round,
245
+ mathOut = null,
246
+ operError = function () {
247
+ _console.log("operand is required for this math method");
248
+ return null;
249
+ };
250
+ key = dust.helpers.tap(key, chunk, context);
251
+ operand = dust.helpers.tap(operand, chunk, context);
252
+ // TODO: handle and tests for negatives and floats in all math operations
253
+ switch (method) {
254
+ case "mod":
255
+ if (operand === 0 || operand === -0) {
256
+ _console.log("operand for divide operation is 0/-0: expect Nan!");
257
+ }
258
+ mathOut = parseFloat(key) % parseFloat(operand);
259
+ break;
260
+ case "add":
261
+ mathOut = parseFloat(key) + parseFloat(operand);
262
+ break;
263
+ case "subtract":
264
+ mathOut = parseFloat(key) - parseFloat(operand);
265
+ break;
266
+ case "multiply":
267
+ mathOut = parseFloat(key) * parseFloat(operand);
268
+ break;
269
+ case "divide":
270
+ if (operand === 0 || operand === -0) {
271
+ _console.log("operand for divide operation is 0/-0: expect Nan/Infinity!");
272
+ }
273
+ mathOut = parseFloat(key) / parseFloat(operand);
274
+ break;
275
+ case "ceil":
276
+ mathOut = Math.ceil(parseFloat(key));
277
+ break;
278
+ case "floor":
279
+ mathOut = Math.floor(parseFloat(key));
280
+ break;
281
+ case "round":
282
+ mathOut = Math.round(parseFloat(key));
283
+ break;
284
+ case "abs":
285
+ mathOut = Math.abs(parseFloat(key));
286
+ break;
287
+ default:
288
+ _console.log("method passed is not supported");
289
+ }
290
+
291
+ if (mathOut !== null) {
292
+ if (round) {
293
+ mathOut = Math.round(mathOut);
294
+ }
295
+ if (bodies && bodies.block) {
296
+ // with bodies act like the select helper with mathOut as the key
297
+ // like the select helper bodies['else'] is meaningless and is ignored
298
+ return chunk.render(bodies.block, context.push({
299
+ isSelect: true,
300
+ isResolved: false,
301
+ selectKey: mathOut
302
+ }));
303
+ } else {
304
+ // self closing math helper will return the calculated output
305
+ return chunk.write(mathOut);
306
+ }
307
+ } else {
308
+ return chunk;
309
+ }
310
+ }
311
+ // no key parameter and no method
312
+ else {
313
+ _console.log("Key is a required parameter for math helper along with method/operand!");
314
+ }
315
+ return chunk;
316
+ },
317
+ /**
318
+ select helperworks with one of the eq/gt/gte/lt/lte/default providing the functionality
319
+ of branching conditions
320
+ @param key, ( required ) either a string literal value or a dust reference
321
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
322
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
323
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
324
+ **/
325
+ "select": function (chunk, context, bodies, params) {
326
+ var body = bodies.block;
327
+ // key is required for processing, hence check for defined
328
+ if (params && typeof params.key !== "undefined") {
329
+ // returns given input as output, if the input is not a dust reference, else does a context lookup
330
+ var key = dust.helpers.tap(params.key, chunk, context);
331
+ // bodies['else'] is meaningless and is ignored
332
+ if (body) {
333
+ return chunk.render(bodies.block, context.push({
334
+ isSelect: true,
335
+ isResolved: false,
336
+ selectKey: key
337
+ }));
338
+ } else {
339
+ _console.log("Missing body block in the select helper ");
340
+ return chunk;
341
+ }
342
+ }
343
+ // no key
344
+ else {
345
+ _console.log("No key given in the select helper!");
346
+ }
347
+ return chunk;
348
+ },
349
+
350
+ /**
351
+ eq helper compares the given key is same as the expected value
352
+ It can be used standalone or in conjunction with select for multiple branching
353
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
354
+ either a string literal value or a dust reference
355
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
356
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
357
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
358
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
359
+ Note : use type="number" when comparing numeric
360
+ **/
361
+ "eq": function (chunk, context, bodies, params) {
362
+ if (params) {
363
+ params.filterOpType = "eq";
364
+ }
365
+ return filter(chunk, context, bodies, params, function (expected, actual) {
366
+ return actual === expected;
367
+ });
368
+ },
369
+
370
+ /**
371
+ ne helper compares the given key is not the same as the expected value
372
+ It can be used standalone or in conjunction with select for multiple branching
373
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
374
+ either a string literal value or a dust reference
375
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
376
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
377
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
378
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
379
+ Note : use type="number" when comparing numeric
380
+ **/
381
+ "ne": function (chunk, context, bodies, params) {
382
+ if (params) {
383
+ params.filterOpType = "ne";
384
+ return filter(chunk, context, bodies, params, function (expected, actual) {
385
+ return actual !== expected;
386
+ });
387
+ }
388
+ return chunk;
389
+ },
390
+
391
+ /**
392
+ lt helper compares the given key is less than the expected value
393
+ It can be used standalone or in conjunction with select for multiple branching
394
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
395
+ either a string literal value or a dust reference
396
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
397
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
398
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
399
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
400
+ Note : use type="number" when comparing numeric
401
+ **/
402
+ "lt": function (chunk, context, bodies, params) {
403
+ if (params) {
404
+ params.filterOpType = "lt";
405
+ return filter(chunk, context, bodies, params, function (expected, actual) {
406
+ return actual < expected;
407
+ });
408
+ }
409
+ },
410
+
411
+ /**
412
+ lte helper compares the given key is less or equal to the expected value
413
+ It can be used standalone or in conjunction with select for multiple branching
414
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
415
+ either a string literal value or a dust reference
416
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
417
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
418
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
419
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
420
+ Note : use type="number" when comparing numeric
421
+ **/
422
+ "lte": function (chunk, context, bodies, params) {
423
+ if (params) {
424
+ params.filterOpType = "lte";
425
+ return filter(chunk, context, bodies, params, function (expected, actual) {
426
+ return actual <= expected;
427
+ });
428
+ }
429
+ return chunk;
430
+ },
431
+
432
+ /**
433
+ gt helper compares the given key is greater than the expected value
434
+ It can be used standalone or in conjunction with select for multiple branching
435
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
436
+ either a string literal value or a dust reference
437
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
438
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
439
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
440
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
441
+ Note : use type="number" when comparing numeric
442
+ **/
443
+ "gt": function (chunk, context, bodies, params) {
444
+ // if no params do no go further
445
+ if (params) {
446
+ params.filterOpType = "gt";
447
+ return filter(chunk, context, bodies, params, function (expected, actual) {
448
+ return actual > expected;
449
+ });
450
+ }
451
+ return chunk;
452
+ },
453
+
454
+ /**
455
+ gte helper, compares the given key is greater than or equal to the expected value
456
+ It can be used standalone or in conjunction with select for multiple branching
457
+ @param key, The actual key to be compared ( optional when helper used in conjunction with select)
458
+ either a string literal value or a dust reference
459
+ a string literal value, is enclosed in double quotes, e.g. key="foo"
460
+ a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
461
+ @param value, The expected value to compare to, when helper is used standalone or in conjunction with select
462
+ @param type (optional), supported types are number, boolean, string, date, context, defaults to string
463
+ Note : use type="number" when comparing numeric
464
+ **/
465
+ "gte": function (chunk, context, bodies, params) {
466
+ if (params) {
467
+ params.filterOpType = "gte";
468
+ return filter(chunk, context, bodies, params, function (expected, actual) {
469
+ return actual >= expected;
470
+ });
471
+ }
472
+ return chunk;
473
+ },
474
+
475
+ // to be used in conjunction with the select helper
476
+ // TODO: fix the helper to do nothing when used standalone
477
+ "default": function (chunk, context, bodies, params) {
478
+ // does not require any params
479
+ if (params) {
480
+ params.filterOpType = "default";
481
+ }
482
+ return filter(chunk, context, bodies, params, function (expected, actual) {
483
+ return true;
484
+ });
485
+ },
486
+
487
+ /**
488
+ * size helper prints the size of the given key
489
+ * Note : size helper is self closing and does not support bodies
490
+ * @param key, the element whose size is returned
491
+ */
492
+ "size": function (chunk, context, bodies, params) {
493
+ var key, value = 0,
494
+ nr, k;
495
+ params = params || {};
496
+ key = params.key;
497
+ if (!key || key === true) { //undefined, null, "", 0
498
+ value = 0;
499
+ } else if (dust.isArray(key)) { //array
500
+ value = key.length;
501
+ } else if (!isNaN(parseFloat(key)) && isFinite(key)) { //numeric values
502
+ value = key;
503
+ } else if (typeof key === "object") { //object test
504
+ //objects, null and array all have typeof ojbect...
505
+ //null and array are already tested so typeof is sufficient http://jsperf.com/isobject-tests
506
+ nr = 0;
507
+ for (k in key) {
508
+ if (Object.hasOwnProperty.call(key, k)) {
509
+ nr++;
510
+ }
511
+ }
512
+ value = nr;
513
+ } else {
514
+ value = (key + '').length; //any other value (strings etc.)
515
+ }
516
+ return chunk.write(value);
517
+ }
518
+
519
+ };
520
+
521
+ dust.helpers = helpers;
522
+
523
+ })(typeof exports !== 'undefined' ? module.exports = require('dustjs-linkedin') : dust);
@@ -0,0 +1,7 @@
1
+ //= require marionette_dust/underscore
2
+ //= require marionette_dust/backbone
3
+ //= require marionette_dust/backbone.marionette
4
+ //= require marionette_dust/dust-full-2.1.0
5
+ //= require marionette_dust/dust-helpers-1.1.1
6
+ //= require marionette_dust/marionette_renderer
7
+ //= require marionette_dust/template_loader
@@ -0,0 +1,11 @@
1
+ Backbone.Marionette.Renderer.render = function (template, data) {
2
+ var renderedTemplate;
3
+
4
+ if (!JST[template]) throw "Template '" + template + "' not found!";
5
+
6
+ JST[template](data, function (err, out) {
7
+ renderedTemplate = out;
8
+ });
9
+
10
+ return renderedTemplate;
11
+ };
@@ -0,0 +1,13 @@
1
+ left = Object.keys(JST);
2
+
3
+ while (left.length > 0) {
4
+ left.forEach(function (key, idx) {
5
+ try {
6
+ JST[key]({}, function (out, err) {});
7
+ left.splice(idx, 1);
8
+ } catch (err) {
9
+ console.log('failed', key, idx);
10
+ left.splice(idx, 1);
11
+ }
12
+ });
13
+ }