haml_coffee_assets 1.6.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -32,7 +32,8 @@ Haml Coffee allows you to write inline [CoffeeScript](http://jashkenas.github.co
32
32
  %a{ :href => "/cart/item/remove/#{ item.id }" } Remove Item
33
33
  ```
34
34
 
35
- You can try Haml Coffee online by visiting [Haml Coffee Online](http://haml-coffee-online.herokuapp.com/).
35
+ You can try Haml Coffee online by visiting [Haml Coffee Online](http://haml-coffee-online.herokuapp.com/) and have a
36
+ look [the AMD example Rails app](https://github.com/netzpirat/haml_coffee_assets_amd).
36
37
 
37
38
  ## Installation
38
39
 
@@ -52,6 +53,8 @@ And require the `hamlcoffee.js` in your `app/assets/javascripts/application.js.c
52
53
  #= require hamlcoffee
53
54
  ```
54
55
 
56
+ If you're using AMD support then you do not need to include the above helper, since it will be automatically included.
57
+
55
58
  This provides the default escaping and the global context functions. Read more about it in the configuration section
56
59
  below.
57
60
 
@@ -63,7 +66,26 @@ If you want to use Haml Coffee with Sinatra, please have a look at the
63
66
 
64
67
  ## Usage
65
68
 
66
- Haml Coffee Assets allows two different ways of generating your JavaScript templates:
69
+ Haml Coffee Assets allows two different ways of generating your JavaScript templates, but the Haml Coffee template
70
+ generation is preferred, since it provides more configuration options and a smoother experience.
71
+
72
+ ### Haml Coffee template generation
73
+
74
+ * Extension: `.hamlc`
75
+
76
+ If you omit the `.jst` and give your templates only a `.hamlc` extension, then Haml Coffee Assets will handle the
77
+ JavaScript template generation. With this approach you can easily define your own namespace with a simple configuration
78
+ and you can use the template name filter.
79
+
80
+ You can place all your Haml Coffee templates in the `app/assets/javascripts/templates` directory and include all
81
+ templates from your `app/assets/javascripts/application.js.coffee`:
82
+
83
+ ```coffeescript
84
+ #= require_tree ./templates
85
+ ```
86
+
87
+ Because Haml Coffee Assets provides a default template name filter, the `templates/` prefix will be automatically
88
+ removed.
67
89
 
68
90
  ### Sprocket JST processor template generation
69
91
 
@@ -72,7 +94,7 @@ Haml Coffee Assets allows two different ways of generating your JavaScript templ
72
94
  When you give your templates the extension `.jst.hamlc`, Haml Coffee Assets will only generate the template function,
73
95
  which then in turn will be further processed by the
74
96
  [Sprocket JST processor](https://github.com/sstephenson/sprockets/blob/master/lib/sprockets/jst_processor.rb). Because
75
- Haml Coffee Assets will not generate the template, you can't use the template name filter and the JST namespace
97
+ Haml Coffee Assets will not generate the template, you can't use the AMD support, template name filter and the JST namespace
76
98
  definition is more cumbersome compared to the Haml Coffee template generation.
77
99
 
78
100
  With this approach you should place all your Haml Coffee templates in the `app/assets/templates` directory and include
@@ -85,24 +107,6 @@ all templates from your `app/assets/javascripts/application.js.coffee`:
85
107
  If you would place your templates into `app/assets/javascripts/templates`, then all your JST template names would begin
86
108
  with `templates/`, which may be not what you want.
87
109
 
88
- ### Haml Coffee template generation
89
-
90
- * Extension: `.hamlc`
91
-
92
- If you omit the `.jst` and give your templates only a `.hamlc` extension, then Haml Coffee Assets will handle the
93
- JavaScript template generation. With this approach you can easily define your own namespace with a simple configuration
94
- and you can use the template name filter.
95
-
96
- You can place all your Haml Coffee templates in the `app/assets/javascripts/templates` directory and include all
97
- templates from your `app/assets/javascripts/application.js.coffee`:
98
-
99
- ```coffeescript
100
- #= require_tree ./templates
101
- ```
102
-
103
- Because Haml Coffee Assets provides a default template name filter, the `templates/` prefix will be automatically
104
- removed.
105
-
106
110
  ## Configuration
107
111
 
108
112
  _Please note that all configuration examples will use the paths of the Haml Coffee template generation and not the
@@ -169,6 +173,18 @@ Please note, the `placement` option is only applicable if you use the `.hamlc` e
169
173
  handle the JST generation. The global `hamlcoffee` helpers must be loaded normally before making use of any
170
174
  templates due to the current template design.
171
175
 
176
+ ### Global template dependencies
177
+
178
+ Haml Coffee Assets allows you to globally define the module dependencies for all templates. By default, the Haml Coffee
179
+ Assets helper is included, but you can add your own:
180
+
181
+ ```ruby
182
+ config.hamlcoffee.dependencies = { '_' => 'underscore', :hc => 'hamlcoffee_amd' }
183
+ ```
184
+
185
+ If you do not include the `hamlcoffee_amd` module as `hc` in the list, then the helper methods will be included in each
186
+ template, increasing its size. It's recommended to always have the `hamlcoffee` module included.
187
+
172
188
  ### Template namespace
173
189
 
174
190
  By default all Haml Coffee templates are registered under the `JST` namespace. A template
@@ -235,6 +251,8 @@ applicable if you use the `.hamlc` extension and let Haml Coffee Assets handle t
235
251
  `.jst.hamlc` extension, then Sprockets JST processor will name things accordingly (e.g., with `templates/` intact in
236
252
  this case).
237
253
 
254
+ The template name filter is not used with AMD loader.
255
+
238
256
  ### Basename
239
257
 
240
258
  If you don't want to have your directory names under which your template is located to be contained in the JST name,
@@ -407,6 +425,49 @@ You can see the [default implementation](https://github.com/netzpirat/haml_coffe
407
425
  and the [Haml Coffee documentation](https://github.com/netzpirat/haml-coffee#custom-helper-function-options)
408
426
  for more information about each helper function.
409
427
 
428
+ ## Partial rendering
429
+
430
+ With Haml Coffee Assets you can render partials when using plain JST approach and also with AMD support.
431
+
432
+ ### JST partial rendering
433
+
434
+ With the traditional JST approach, all the templates are globally accessible in your defined namespace, which is `JST`
435
+ by default. This allows you to render a template within another template like:
436
+
437
+ ```
438
+ %h1 Comments for this article
439
+ - for comment in @article.comments
440
+ != JST['articles/comment'](comment)
441
+ ```
442
+
443
+ ### AMD partial rendering
444
+
445
+ Haml Coffee parses the template source code for `require` statements and adds them to the template module dependencies.
446
+ This allows you to require other templates like this:
447
+
448
+ ```Haml
449
+ - require 'module'
450
+ - require 'deep/nested/other'
451
+ ```
452
+
453
+ Now your dependencies are available in the template, allowing you to render it with:
454
+
455
+ ```Haml
456
+ != module()
457
+ != other()
458
+ ```
459
+
460
+ Please note that only the basename ot the template is used as module variable name.
461
+
462
+ Of course you can also directly require and render a template like:
463
+
464
+ ```haml
465
+ != require("another/other")()
466
+ ```
467
+
468
+ Please have a look at [the AMD example Rails app](https://github.com/netzpirat/haml_coffee_assets_amd) for a working
469
+ example.
470
+
410
471
  ## Author
411
472
 
412
473
  Developed by Michael Kessler, [mksoft.ch](https://mksoft.ch).
@@ -23,7 +23,7 @@ module HamlCoffeeAssets
23
23
 
24
24
  runtime.call('HamlCoffeeAssets.compile', name, source, jst,
25
25
  config.namespace, config.format, config.uglify, config.basename,
26
- config.escapeHtml, config.escapeAttributes, config.cleanValue, config.placement,
26
+ config.escapeHtml, config.escapeAttributes, config.cleanValue, config.placement, config.dependencies,
27
27
  config.customHtmlEscape, config.customCleanValue,
28
28
  config.customPreserve, config.customFindAndPreserve,
29
29
  config.customSurround, config.customSucceed, config.customPrecede,
@@ -25,6 +25,7 @@ module HamlCoffeeAssets
25
25
  self.escapeAttributes = true
26
26
  self.cleanValue = true
27
27
  self.placement = 'global'
28
+ self.dependencies = { :hc => 'hamlcoffee_amd' }
28
29
  self.customHtmlEscape = 'window.HAML.escape'
29
30
  self.customCleanValue = 'window.HAML.cleanValue'
30
31
  self.customPreserve = 'window.HAML.preserve'
@@ -71,6 +72,10 @@ module HamlCoffeeAssets
71
72
  #
72
73
  attr_accessor :placement
73
74
 
75
+ # Define the global amd module dependencies
76
+ #
77
+ attr_accessor :dependencies
78
+
74
79
  # Custom global HTML escaping function
75
80
  #
76
81
  attr_accessor :customHtmlEscape
@@ -1,5 +1,5 @@
1
1
  # coding: UTF-8
2
2
 
3
3
  module HamlCoffeeAssets
4
- VERSION = '1.6.2' unless defined?(HamlCoffeeAssets::VERSION)
4
+ VERSION = '1.7.0' unless defined?(HamlCoffeeAssets::VERSION)
5
5
  end
@@ -21,6 +21,7 @@ var HamlCoffeeAssets = (function(){
21
21
  * @param escapeAttributes [Boolean] whether to escape HTML attributes output by default or not
22
22
  * @param cleanValue [String] the name of the function to clean the values
23
23
  * @param placement [String] where to place the function, either `global` or `amd`
24
+ * @param dependencies [Object] the amd module dependencies
24
25
  * @param customHtmlEscape [String] the name of the function to escape the output
25
26
  * @param customCleanValue [String] the name of the function to clean the code output
26
27
  * @param customSurround [String] the name of the function for the surround helper
@@ -32,7 +33,7 @@ var HamlCoffeeAssets = (function(){
32
33
  * @param extendScope [Boolean] extend the scope with the context
33
34
  */
34
35
  compile: function(name, source, jst, namespace, format, uglify, basename,
35
- escapeHtml, escapeAttributes, cleanValue, placement,
36
+ escapeHtml, escapeAttributes, cleanValue, placement, dependencies,
36
37
  customHtmlEscape, customCleanValue, customPreserve, customFindAndPreserve,
37
38
  customSurround, customSucceed, customPrecede,
38
39
  preserveTags, selfCloseTags,
@@ -46,6 +47,7 @@ var HamlCoffeeAssets = (function(){
46
47
  escapeAttributes: escapeAttributes,
47
48
  cleanValue: cleanValue,
48
49
  placement: placement,
50
+ dependencies: dependencies,
49
51
  customHtmlEscape: customHtmlEscape,
50
52
  customCleanValue: customCleanValue,
51
53
  customPreserve: customPreserve,
@@ -76,6 +78,9 @@ var HamlCoffeeAssets = (function(){
76
78
  }
77
79
 
78
80
  if (context !== '' && context !== false) {
81
+ if (placement === 'amd' && context === 'window.HAML.context') {
82
+ context = 'hc.context';
83
+ }
79
84
  template = template.replace('.call(context);', '.call(' + context + '(context));');
80
85
  }
81
86
 
@@ -363,38 +363,43 @@ require.define("/haml-coffee.coffee", function (require, module, exports, __dirn
363
363
 
364
364
  module.exports = HamlCoffee = (function() {
365
365
 
366
- HamlCoffee.VERSION = '1.6.2';
366
+ HamlCoffee.VERSION = '1.7.0';
367
367
 
368
368
  function HamlCoffee(options) {
369
- var _base, _base10, _base2, _base3, _base4, _base5, _base6, _base7, _base8, _base9, _ref, _ref10, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
369
+ var _base, _base10, _base11, _base2, _base3, _base4, _base5, _base6, _base7, _base8, _base9, _ref, _ref10, _ref11, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9;
370
370
  this.options = options != null ? options : {};
371
371
  if ((_ref = (_base = this.options).placement) == null) {
372
372
  _base.placement = 'global';
373
373
  }
374
- if ((_ref2 = (_base2 = this.options).escapeHtml) == null) {
375
- _base2.escapeHtml = true;
374
+ if ((_ref2 = (_base2 = this.options).dependencies) == null) {
375
+ _base2.dependencies = {
376
+ hc: 'hamlcoffee'
377
+ };
378
+ }
379
+ if ((_ref3 = (_base3 = this.options).escapeHtml) == null) {
380
+ _base3.escapeHtml = true;
376
381
  }
377
- if ((_ref3 = (_base3 = this.options).escapeAttributes) == null) {
378
- _base3.escapeAttributes = true;
382
+ if ((_ref4 = (_base4 = this.options).escapeAttributes) == null) {
383
+ _base4.escapeAttributes = true;
379
384
  }
380
- if ((_ref4 = (_base4 = this.options).cleanValue) == null) {
381
- _base4.cleanValue = true;
385
+ if ((_ref5 = (_base5 = this.options).cleanValue) == null) {
386
+ _base5.cleanValue = true;
382
387
  }
383
- if ((_ref5 = (_base5 = this.options).uglify) == null) _base5.uglify = false;
384
- if ((_ref6 = (_base6 = this.options).basename) == null) {
385
- _base6.basename = false;
388
+ if ((_ref6 = (_base6 = this.options).uglify) == null) _base6.uglify = false;
389
+ if ((_ref7 = (_base7 = this.options).basename) == null) {
390
+ _base7.basename = false;
386
391
  }
387
- if ((_ref7 = (_base7 = this.options).extendScope) == null) {
388
- _base7.extendScope = false;
392
+ if ((_ref8 = (_base8 = this.options).extendScope) == null) {
393
+ _base8.extendScope = false;
389
394
  }
390
- if ((_ref8 = (_base8 = this.options).format) == null) {
391
- _base8.format = 'html5';
395
+ if ((_ref9 = (_base9 = this.options).format) == null) {
396
+ _base9.format = 'html5';
392
397
  }
393
- if ((_ref9 = (_base9 = this.options).preserveTags) == null) {
394
- _base9.preserveTags = 'pre,textarea';
398
+ if ((_ref10 = (_base10 = this.options).preserveTags) == null) {
399
+ _base10.preserveTags = 'pre,textarea';
395
400
  }
396
- if ((_ref10 = (_base10 = this.options).selfCloseTags) == null) {
397
- _base10.selfCloseTags = 'meta,img,link,br,hr,input,area,param,col,base';
401
+ if ((_ref11 = (_base11 = this.options).selfCloseTags) == null) {
402
+ _base11.selfCloseTags = 'meta,img,link,br,hr,input,area,param,col,base';
398
403
  }
399
404
  }
400
405
 
@@ -570,17 +575,56 @@ require.define("/haml-coffee.coffee", function (require, module, exports, __dirn
570
575
  if (namespace == null) namespace = 'window.HAML';
571
576
  switch (this.options.placement) {
572
577
  case 'amd':
573
- return this._render_amd();
578
+ return this.renderAmd();
574
579
  default:
575
- return this._render_global(templateName, namespace);
580
+ return this.renderGlobal(templateName, namespace);
576
581
  }
577
582
  };
578
583
 
579
- HamlCoffee.prototype._render_amd = function() {
580
- return "define ->\n (context) ->\n render = ->\n \n" + (indent(this.precompile(), 4)) + "\n render.call(context)";
584
+ HamlCoffee.prototype.renderAmd = function() {
585
+ var m, module, modules, param, params, template, _ref, _ref2;
586
+ if (/^hamlcoffee/.test(this.options.dependencies['hc'])) {
587
+ this.options.customHtmlEscape = 'hc.escape';
588
+ this.options.customCleanValue = 'hc.cleanValue';
589
+ this.options.customPreserve = 'hc.preserve';
590
+ this.options.customFindAndPreserve = 'hc.findAndPreserve';
591
+ this.options.customSurround = 'hc.surround';
592
+ this.options.customSucceed = 'hc.succeed';
593
+ this.options.customPrecede = 'hc.precede';
594
+ }
595
+ modules = [];
596
+ params = [];
597
+ _ref = this.options.dependencies;
598
+ for (param in _ref) {
599
+ module = _ref[param];
600
+ modules.push(module);
601
+ params.push(param);
602
+ }
603
+ template = indent(this.precompile(), 4);
604
+ _ref2 = this.findDependencies(template);
605
+ for (param in _ref2) {
606
+ module = _ref2[param];
607
+ modules.push(module);
608
+ params.push(param);
609
+ }
610
+ if (modules.length !== 0) {
611
+ modules = (function() {
612
+ var _i, _len, _results;
613
+ _results = [];
614
+ for (_i = 0, _len = modules.length; _i < _len; _i++) {
615
+ m = modules[_i];
616
+ _results.push("'" + m + "'");
617
+ }
618
+ return _results;
619
+ })();
620
+ modules = "[" + modules + "], (" + (params.join(', ')) + ")";
621
+ } else {
622
+ modules = '';
623
+ }
624
+ return "define " + modules + " ->\n (context) ->\n render = ->\n \n" + template + "\n render.call(context)";
581
625
  };
582
626
 
583
- HamlCoffee.prototype._render_global = function(templateName, namespace) {
627
+ HamlCoffee.prototype.renderGlobal = function(templateName, namespace) {
584
628
  var segment, segments, template, _i, _len;
585
629
  if (namespace == null) namespace = 'window.HAML';
586
630
  template = '';
@@ -618,7 +662,7 @@ require.define("/haml-coffee.coffee", function (require, module, exports, __dirn
618
662
  if (this.options.customHtmlEscape) {
619
663
  fn += "$e = " + this.options.customHtmlEscape + "\n";
620
664
  } else {
621
- fn += "$e = (text, escape) ->\n \"\#{ text }\"\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\'/g, '&#39;')\n .replace(/\"/g, '&quot;')\n";
665
+ fn += "$e = (text, escape) ->\n \"\#{ text }\"\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\'/g, '&#39;')\n .replace(/\\//g, '&#47;')\n .replace(/\"/g, '&quot;')\n";
622
666
  }
623
667
  }
624
668
  if (code.indexOf('$c') !== -1) {
@@ -767,6 +811,18 @@ require.define("/haml-coffee.coffee", function (require, module, exports, __dirn
767
811
  }
768
812
  };
769
813
 
814
+ HamlCoffee.prototype.findDependencies = function(code) {
815
+ var dependencies, match, module, name, requireRegexp;
816
+ requireRegexp = /require(?:\s+|\()(['"])(.+?)(\1)\)?/gm;
817
+ dependencies = {};
818
+ while (match = requireRegexp.exec(code)) {
819
+ module = match[2];
820
+ name = module.split('/').pop();
821
+ dependencies[name] = module;
822
+ }
823
+ return dependencies;
824
+ };
825
+
770
826
  return HamlCoffee;
771
827
 
772
828
  })();
@@ -14,6 +14,7 @@ class window.HAML
14
14
  .replace(/>/g, "&gt;")
15
15
  .replace(/"/g, "&quot;")
16
16
  .replace(/'/g, "&#39;")
17
+ .replace(/\//g, "&#47;")
17
18
 
18
19
  # HAML Coffee clean value function. Beside just
19
20
  # cleaning `null` and `undefined` values, it
@@ -0,0 +1,91 @@
1
+ # HAML Coffee helper module
2
+ #
3
+ define ->
4
+
5
+ # HAML Coffee html escape function.
6
+ #
7
+ # @param text [String] the text to escape
8
+ # @return [String] the escaped text
9
+ #
10
+ escape: (text) ->
11
+ ("" + text)
12
+ .replace(/&/g, "&amp;")
13
+ .replace(/</g, "&lt;")
14
+ .replace(/>/g, "&gt;")
15
+ .replace(/"/g, "&quot;")
16
+ .replace(/'/g, "&#39;")
17
+ .replace(/\//g, "&#47;")
18
+
19
+ # HAML Coffee clean value function. Beside just
20
+ # cleaning `null` and `undefined` values, it
21
+ # adds a hidden unicode marker character to
22
+ # boolean values, so that the render time boolean
23
+ # logic can distinguish between real booleans and
24
+ # boolean-like strings.
25
+ #
26
+ # @param text [String] the text to be cleaned
27
+ # @return [String] the cleaned text
28
+ #
29
+ cleanValue: (text) ->
30
+ switch text
31
+ when null, undefined then ''
32
+ when true, false then '\u0093' + text
33
+ else
34
+ text
35
+
36
+ # Preserve newlines in the text
37
+ #
38
+ # @param text [String] the text to preserve
39
+ # @return [String] the preserved text
40
+ #
41
+ preserve: (text) ->
42
+ text.replace /\n/g, '&#x000A;'
43
+
44
+ # Find and preserve newlines in the preserving tags
45
+ #
46
+ # @param text [String] the text to preserve
47
+ # @return [String] the preserved text
48
+ #
49
+ findAndPreserve: (text) ->
50
+ tags = '<%= HamlCoffeeAssets.config.preserveTags %>'.split(',').join('|')
51
+ text = text.replace ///<(#{ tags })>([^]*?)<\/\1>/// g, (str, tag, content) ->
52
+ "<#{ tag }>#{ <%= HamlCoffeeAssets.config.customPreserve %>(content) }</#{ tag }>"
53
+
54
+ # The surround helper surrounds the function output
55
+ # with the start and end string without whitespace in between.
56
+ #
57
+ # @param [String] start the text to prepend to the text
58
+ # @param [String] end the text to append to the text
59
+ # @param [Function] fn the text generating function
60
+ # @return [String] the surrounded text
61
+ #
62
+ surround: (start, end, fn) ->
63
+ start + fn.call(@)?.replace(/^\s+|\s+$/g, '') + end
64
+
65
+ # The succeed helper appends text to the function output
66
+ # without whitespace in between.
67
+ #
68
+ # @param [String] end the text to append to the text
69
+ # @param [Function] fn the text generating function
70
+ # @return [String] the succeeded text
71
+ #
72
+ succeed: (end, fn) ->
73
+ fn.call(@)?.replace(/\s+$/g, '') + end
74
+
75
+ # The precede helper prepends text to the function output
76
+ # without whitespace in between.
77
+ #
78
+ # @param [String] start the text to prepend to the text
79
+ # @param [Function] fn the text generating function
80
+ # @return [String] the preeceded text
81
+ #
82
+ precede: (start, fn) ->
83
+ start + fn.call(@)?.replace(/^\s+/g, '')
84
+
85
+ # Get the HAML template context. This merges the local
86
+ # and the global template context into a new context.
87
+ #
88
+ # @param locals [Object] the local template context
89
+ # @return [Object] the merged context
90
+ #
91
+ context: (locals) -> locals
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml_coffee_assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-27 00:00:00.000000000 Z
12
+ date: 2012-11-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: coffee-script
@@ -92,6 +92,7 @@ files:
92
92
  - lib/js/haml_coffee_assets.js
93
93
  - lib/js/hamlcoffee.js
94
94
  - vendor/assets/javascripts/hamlcoffee.js.coffee.erb
95
+ - vendor/assets/javascripts/hamlcoffee_amd.js.coffee.erb
95
96
  - LICENSE
96
97
  - README.md
97
98
  homepage: https://github.com/netzpirat/haml_coffee_assets
@@ -108,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
109
  version: '0'
109
110
  segments:
110
111
  - 0
111
- hash: -2825006732775094402
112
+ hash: 794208290192263430
112
113
  required_rubygems_version: !ruby/object:Gem::Requirement
113
114
  none: false
114
115
  requirements: