marionette_dust 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }