haml_coffee_assets 0.3.0 → 0.4.0

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.
data/README.md CHANGED
@@ -160,14 +160,14 @@ A template `app/assets/templates/header.hamlc` with the given content:
160
160
 
161
161
  ```haml
162
162
  %header
163
- %h2= title
163
+ %h2= @title
164
164
  ```
165
165
 
166
166
  will be accessible in your browser as `JST['header']`. You can now render the precompiled template and pass the data
167
167
  to be rendered:
168
168
 
169
169
  ```javascript
170
- JST['header'].render({ title: 'Hello Haml Coffee' })
170
+ JST['header']({ title: 'Hello Haml Coffee' })
171
171
  ```
172
172
 
173
173
  If you prefer another namespace, you can set it in your `config/application.rb`:
@@ -209,45 +209,13 @@ You can toggle HTML escaping in your `config/application.rb`:
209
209
  config.hamlcoffee.escapeHtml = false
210
210
  ```
211
211
 
212
- #### Custom escape function
213
-
214
- By default your code block in your Haml Coffee template will be escaped through the `HAML.escape` function that is
215
- provided in the `hamlcoffee.js` script.
212
+ ### Uglify generated HTML
216
213
 
217
- You can set a custom escaping function in your `config/application.rb`:
214
+ By default all generated HTML is indented to have a nice reading experience. If you like to ignore indention to have a
215
+ better rendering performance, you can enable the uglify option in your `config/application.rb`:
218
216
 
219
217
  ```ruby
220
- config.hamlcoffee.customHtmlEscape = 'App.myEscape'
221
- ```
222
-
223
- Your custom escape function must take the unescaped text as parameter and returns the escaped text.
224
- The following default implementation comes with `hamlcoffee.js`:
225
-
226
- ```coffeescript
227
- App.myEscape = (text) ->
228
- ('' + text)
229
- .replace(/&/g, '&')
230
- .replace(/</g, '&lt;')
231
- .replace(/>/g, '&gt;')
232
- .replace(/"/g, '&quot;')
233
- ```
234
-
235
- #### Custom clean value function
236
-
237
- All your evaluated CoffeeScript code will go through the clean value function. By default this simply cleans `undefined`
238
- and `null` values, so that they appear as empty string in your template.
239
-
240
- You can set a custom clean value function in your `config/application.rb`:
241
-
242
- ```ruby
243
- config.hamlcoffee.customCleanValue = 'App.myCleanValue'
244
- ```
245
-
246
- Your custom clean value function must take the value as parameter and returns the cleaned value.
247
- The following default implementation comes with `hamlcoffee.js`:
248
-
249
- ```coffeescript
250
- App.myCleanValue = (value) -> if value is null or value is undefined then '' else value
218
+ config.hamlcoffee.uglify = true
251
219
  ```
252
220
 
253
221
  ### Global context
@@ -307,15 +275,151 @@ App.globalTemplateContext = (locals) -> _.extend({}, {
307
275
  }, locals)
308
276
  ```
309
277
 
310
- ## Using on Heroku
278
+ ### Customize the tag lists
279
+
280
+ Haml Coffee contains two list of HTML tags that you can customize. In general you're fine with the defaults, but if
281
+ you need to extend the list, you can instruct Haml Coffee Assets to do so.
282
+
283
+ #### Whitespace sensitive tag list
284
+
285
+ * Tags: `textarea`, `pre`
286
+
287
+ Some HTML tags are whitespace sensitive, which means that whitespace used for proper indention results in a wrong
288
+ display of the tag. In order to avoid this, the content is preserved by converting the nerwlines to a HTML
289
+ entity. You can set your own list of whitespace sensitive tags in your `config/application.rb`:
290
+
291
+ ```ruby
292
+ config.hamlcoffee.preserve = 'pre,textarea,abbr'
293
+ ```
294
+
295
+ This list is also taken into account for the `HAML.preserveAndFind` helper function that is provided and its shortcut
296
+ notation `~`.
297
+
298
+ #### Auto-closing tag list
299
+
300
+ Tags: `meta`, `img`, `link`, `br`, `hr`, `input`, `area`, `param`, `col`, `base`
301
+
302
+ The auto-closing tag list will contains the tags that will be self-closes if they have no content. You can set the
303
+ list of self closing tags in your `config/application.rb`:
304
+
305
+ ```ruby
306
+ config.hamlcoffee.autoclose = 'meta,img,link,br,hr,input,area,param,col,base'
307
+ ```
308
+
309
+ ### Custom helper functions
310
+
311
+ Haml Coffee Assets provides a set of custom functions for Haml Coffee, so that the templates doesn't have to be self
312
+ contained and can make use of the global functions. In general you don't have to customize them further, but if you need
313
+ to, you can.
314
+
315
+ #### Custom escape function
316
+
317
+ By default your code block in your Haml Coffee template will be escaped through the `HAML.escape` function that is
318
+ provided in the `hamlcoffee.js` script.
319
+
320
+ You can set a custom escaping function in your `config/application.rb`:
321
+
322
+ ```ruby
323
+ config.hamlcoffee.customHtmlEscape = 'App.myEscape'
324
+ ```
325
+
326
+ Your custom escape function must take the unescaped text as parameter and returns the escaped text.
327
+ The following default implementation comes with `hamlcoffee.js`:
328
+
329
+ ```coffeescript
330
+ App.myEscape = (text) ->
331
+ ('' + text)
332
+ .replace(/&/g, '&amp;')
333
+ .replace(/</g, '&lt;')
334
+ .replace(/>/g, '&gt;')
335
+ .replace(/'/g, '&apos;')
336
+ .replace(/"/g, '&quot;')
337
+ ```
338
+
339
+ #### Custom clean value function
311
340
 
312
- Using haml_coffee_assets on Heroku with Ruby on Rails 3.1 requires you to set
341
+ All your evaluated CoffeeScript code will go through the clean value function. By default this simply cleans `undefined`
342
+ and `null` values, so that they appear as empty string in your template.
343
+
344
+ You can set a custom clean value function in your `config/application.rb`:
345
+
346
+ ```ruby
347
+ config.hamlcoffee.customCleanValue = 'App.myCleanValue'
348
+ ```
349
+
350
+ Your custom clean value function must take the value as parameter and returns the cleaned value.
351
+ The following default implementation comes with `hamlcoffee.js`:
352
+
353
+ ```coffeescript
354
+ App.myCleanValue = (value) -> if value is null or value is undefined then '' else value
355
+ ```
356
+
357
+ #### Custom preserve function
358
+
359
+ All the content from the HTML tags that are contained in the whitespace sensitive tag list are passed through the
360
+ preserve function.
361
+
362
+ You can set a custom preserve function in your `config/application.rb`:
363
+
364
+ ```ruby
365
+ config.hamlcoffee.customPreserve = 'App.myPreserve'
366
+ ```
367
+
368
+ Your custom preserve function must take the text to be preserved as parameter and returns the preserved content.
369
+ The following default implementation comes with `hamlcoffee.js`:
370
+
371
+ ```coffeescript
372
+ App.myPreserve = (value) -> text.replace /\\n/g, '&#x000A;'
373
+ ```
374
+
375
+ #### Custom find and preserve function
376
+
377
+ The findAndPreserve function is a specialized preserve function, that you can pass a text containing HTML, and only the
378
+ newlines in between a whitespace sensitive tag are preserved. This function uses the previous preserve function to do
379
+ the final preservation.
380
+
381
+ You can set a custom find and preserve function in your `config/application.rb`:
382
+
383
+ ```ruby
384
+ config.hamlcoffee.customFindAndPreserve = 'App.myFindAndPreserve'
385
+ ```
386
+
387
+ Your custom find and preserve function must take the text to search for whitespace sensitive tags as parameter and
388
+ returns the preserved content.
389
+
390
+ The following default implementation comes with `hamlcoffee.js`:
391
+
392
+ ```coffeescript
393
+ App.myPreserve = (value) ->
394
+ text.replace /<(textarea|pre)>([^]*?)<\/\1>/g, (str, tag, content) ->
395
+ "<#{ tag }>#{ HAML.preserve(content) }</#{ tag }>"
396
+ ```
397
+
398
+ ## Prepare your assets for production
399
+
400
+ Using haml_coffee_assets requires you to set
313
401
 
314
402
  config.assets.initialize_on_precompile = true
315
403
 
316
404
  in your `config/environments/production.rb`. Read more about the it at the
317
405
  [Asset Pipeline Guide](http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets).
318
406
 
407
+ ## Development
408
+
409
+ * Issues and feature request hosted at [GitHub Issues](https://github.com/netzpirat/haml_coffee_assets/issues).
410
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/netzpirat/haml_coffee_assets/master/frames).
411
+ * Source hosted at [GitHub](https://github.com/netzpirat/haml_coffee_assets).
412
+
413
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
414
+
415
+ * Please create a topic branch for every separate change you make.
416
+ * Make sure your patches are well tested. All specs must pass.
417
+ * Update the [Yard](http://yardoc.org/) documentation.
418
+ * Update the README.
419
+ * Please **do not change** the version number.
420
+
421
+ For questions please join `#haml` on irc.freenode.net
422
+
319
423
  ## Acknowledgement
320
424
 
321
425
  * [Jeremy Ashkenas](http://twitter.com/#!/jashkenas) for CoffeeScript, that little language that compiles into
@@ -9,13 +9,18 @@ module HamlCoffeeAssets
9
9
  config.hamlcoffee = ActiveSupport::OrderedOptions.new
10
10
 
11
11
  DEFAULT_CONFIG = {
12
- :format => 'html5',
13
- :namespace => 'window.JST',
14
- :escapeHtml => true,
15
- :escapeAttributes => true,
16
- :customHtmlEscape => 'HAML.escape',
17
- :customCleanValue => 'HAML.cleanValue',
18
- :context => 'HAML.context'
12
+ :format => 'html5',
13
+ :namespace => 'window.JST',
14
+ :uglify => false,
15
+ :escapeHtml => true,
16
+ :escapeAttributes => true,
17
+ :customHtmlEscape => 'HAML.escape',
18
+ :customCleanValue => 'HAML.cleanValue',
19
+ :customPreserve => 'HAML.escape',
20
+ :customFindAndPreserve => 'HAML.findAndPreserve',
21
+ :preserve => 'textarea,pre',
22
+ :autoclose => 'meta,img,link,br,hr,input,area,param,col,base',
23
+ :context => 'HAML.context'
19
24
  }
20
25
 
21
26
  # Initialize Haml Coffee Assets after Sprockets
@@ -30,13 +35,18 @@ module HamlCoffeeAssets
30
35
  options = DEFAULT_CONFIG.merge(app.config.hamlcoffee)
31
36
 
32
37
  HamlCoffee.configure do |config|
33
- config.namespace = options[:namespace]
34
- config.format = options[:format]
35
- config.escapeHtml = options[:escapeHtml]
36
- config.escapeAttributes = options[:escapeAttributes]
37
- config.customHtmlEscape = options[:customHtmlEscape]
38
- config.customCleanValue = options[:customCleanValue]
39
- config.context = options[:context]
38
+ config.namespace = options[:namespace]
39
+ config.format = options[:format]
40
+ config.uglify = options[:uglify]
41
+ config.escapeHtml = options[:escapeHtml]
42
+ config.escapeAttributes = options[:escapeAttributes]
43
+ config.customHtmlEscape = options[:customHtmlEscape]
44
+ config.customCleanValue = options[:customCleanValue]
45
+ config.customPreserve = options[:customPreserve]
46
+ config.customFindAndPreserve = options[:customFindAndPreserve]
47
+ config.preserveTags = options[:preserve]
48
+ config.selfCloseTags = options[:autoclose]
49
+ config.context = options[:context]
40
50
  end
41
51
  end
42
52
 
@@ -16,6 +16,11 @@ module HamlCoffeeAssets
16
16
  mattr_accessor :format
17
17
  self.format = 'html5'
18
18
 
19
+ # Uglify HTML output by skip indention
20
+ #
21
+ mattr_accessor :uglify
22
+ self.uglify = false
23
+
19
24
  # Escape template code output
20
25
  #
21
26
  mattr_accessor :escapeHtml
@@ -36,6 +41,26 @@ module HamlCoffeeAssets
36
41
  mattr_accessor :customCleanValue
37
42
  self.customCleanValue = 'window.HAML.cleanValue'
38
43
 
44
+ # Custom preserve function
45
+ #
46
+ mattr_accessor :customPreserve
47
+ self.customPreserve = 'window.HAML.preserve'
48
+
49
+ # Custom find and preserve function
50
+ #
51
+ mattr_accessor :customFindAndPreserve
52
+ self.customFindAndPreserve = 'window.HAML.findAndPreserve'
53
+
54
+ # List of tags to preserve
55
+ #
56
+ mattr_accessor :preserveTags
57
+ self.preserveTags = 'textarea,pre'
58
+
59
+ # List of self closing tags
60
+ #
61
+ mattr_accessor :selfCloseTags
62
+ self.selfCloseTags = 'meta,img,link,br,hr,input,area,param,col,base'
63
+
39
64
  # Custom global context to merge
40
65
  #
41
66
  mattr_accessor :context
@@ -56,9 +81,12 @@ module HamlCoffeeAssets
56
81
  # @return [String] the compiled template in JavaScript
57
82
  #
58
83
  def compile(name, source)
59
- runtime.call('HamlCoffeeAssets.compile', name, source,
60
- HamlCoffee.namespace, HamlCoffee.format, HamlCoffee.escapeHtml, HamlCoffee.escapeAttributes,
61
- HamlCoffee.customHtmlEscape, HamlCoffee.customCleanValue, HamlCoffee.context)
84
+ runtime.call('HamlCoffeeAssets.compile', name, source, HamlCoffee.namespace, HamlCoffee.format, HamlCoffee.uglify,
85
+ HamlCoffee.escapeHtml, HamlCoffee.escapeAttributes,
86
+ HamlCoffee.customHtmlEscape, HamlCoffee.customCleanValue,
87
+ HamlCoffee.customPreserve, HamlCoffee.customFindAndPreserve,
88
+ HamlCoffee.preserveTags, HamlCoffee.selfCloseTags,
89
+ HamlCoffee.context)
62
90
  end
63
91
 
64
92
  private
@@ -19,23 +19,36 @@ var HamlCoffeeAssets = (function(){
19
19
  /**
20
20
  * Compile the HAML Coffee template to JavaScript
21
21
  *
22
- * @param namespace [String] the template namespace
23
22
  * @param name [String] the name of the template that is registered to the namespace
24
23
  * @param source [String] the template source code to be compiled
24
+ * @param namespace [String] the template namespace
25
+ * @param format [String] output HTML format
26
+ * @param uglify [Boolean] skip HTML indention
25
27
  * @param escapeHtml [Boolean] whether to escape HTML output by default or not
26
28
  * @param escapeAttributes [Boolean] whether to escape HTML attributes output by default or not
27
29
  * @param customHtmlEscape [String] the name of the function to escape the output
28
30
  * @param customCleanValue [String] the name of the function to clean the code output
31
+ * @param preserveTags [String] comma separated list of tags to preserve whitespace
32
+ * @param selfCloseTags [String] comma separated list of tags to self-closing tags
29
33
  * @param context [String] the name of the function to merge contexts
30
34
  */
31
- compile: function(name, source, namespace, format, escapeHtml, escapeAttributes, customHtmlEscape, customCleanValue, context) {
35
+ compile: function(name, source, namespace, format, uglify,
36
+ escapeHtml, escapeAttributes,
37
+ customHtmlEscape, customCleanValue, customPreserve, customFindAndPreserve,
38
+ preserveTags, selfCloseTags,
39
+ context) {
32
40
 
33
41
  var compiler = new Compiler({
34
42
  format: format,
43
+ uglify: uglify,
35
44
  escapeHtml: escapeHtml,
36
45
  escapeAttributes: escapeAttributes,
37
46
  customHtmlEscape: customHtmlEscape,
38
- customCleanValue: customCleanValue
47
+ customCleanValue: customCleanValue,
48
+ customPreserve: customPreserve,
49
+ customFindAndPreserve: customFindAndPreserve,
50
+ preserveTags: preserveTags,
51
+ selfCloseTags: selfCloseTags
39
52
  });
40
53
 
41
54
  compiler.parse(source);
@@ -1,5 +1,5 @@
1
1
  # coding: UTF-8
2
2
 
3
3
  module HamlCoffeeAssets
4
- VERSION = '0.3.0' unless defined?(HamlCoffeeAssets::VERSION)
4
+ VERSION = '0.4.0' unless defined?(HamlCoffeeAssets::VERSION)
5
5
  end
@@ -340,6 +340,7 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
340
340
  this.children = [];
341
341
  this.opener = this.closer = null;
342
342
  this.silent = false;
343
+ this.preserveTags = options.preserveTags.split(',');
343
344
  this.preserve = false;
344
345
  this.wsRemoval = {
345
346
  around: false,
@@ -348,6 +349,8 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
348
349
  this.escapeHtml = options.escapeHtml;
349
350
  this.escapeAttributes = options.escapeAttributes;
350
351
  this.format = options.format;
352
+ this.selfCloseTags = options.selfCloseTags.split(',');
353
+ this.uglify = options.uglify;
351
354
  this.codeBlockLevel = options.codeBlockLevel;
352
355
  this.blockLevel = options.blockLevel;
353
356
  }
@@ -391,7 +394,7 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
391
394
  return {
392
395
  type: 'text',
393
396
  cw: this.codeBlockLevel,
394
- hw: this.blockLevel - this.codeBlockLevel + 2,
397
+ hw: this.uglify ? 0 : this.blockLevel - this.codeBlockLevel + 2,
395
398
  text: escape ? e(text) : text
396
399
  };
397
400
  };
@@ -404,13 +407,17 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
404
407
  };
405
408
  };
406
409
 
407
- Node.prototype.markInsertingCode = function(code, escape) {
410
+ Node.prototype.markInsertingCode = function(code, escape, preserve, findAndPreserve) {
408
411
  if (escape == null) escape = false;
412
+ if (preserve == null) preserve = false;
413
+ if (findAndPreserve == null) findAndPreserve = false;
409
414
  return {
410
415
  type: 'insert',
411
416
  cw: this.codeBlockLevel,
412
- hw: this.blockLevel,
417
+ hw: this.uglify ? 0 : this.blockLevel,
413
418
  escape: escape,
419
+ preserve: preserve,
420
+ findAndPreserve: findAndPreserve,
414
421
  code: code
415
422
  };
416
423
  };
@@ -418,7 +425,7 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
418
425
  Node.prototype.evaluate = function() {};
419
426
 
420
427
  Node.prototype.render = function() {
421
- var child, output, preserve, tag, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4;
428
+ var child, output, rendered, tag, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _m, _ref, _ref2, _ref3, _ref4, _ref5;
422
429
  output = [];
423
430
  if (this.silent) return output;
424
431
  if (this.children.length === 0) {
@@ -436,35 +443,39 @@ require.define("/nodes/node.js", function (require, module, exports, __dirname,
436
443
  } else {
437
444
  if (this.opener && this.closer) {
438
445
  if (this.preserve) {
439
- preserve = this.getOpener().text;
446
+ this.wsRemoval.inside = true;
447
+ output.push(this.getOpener());
440
448
  _ref = this.children;
441
449
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
442
450
  child = _ref[_i];
443
- preserve += "" + (child.render()[0].text) + "\\n" + (w(this.blockLevel));
451
+ _ref2 = child.render();
452
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
453
+ rendered = _ref2[_j];
454
+ rendered.hw = this.blockLevel;
455
+ output.push(rendered);
456
+ }
444
457
  }
445
- preserve = preserve.replace(/\\n\s*$/, '');
446
- preserve += this.getCloser().text;
447
- output.push(this.markText(preserve));
458
+ output.push(this.getCloser());
448
459
  } else {
449
460
  output.push(this.getOpener());
450
- _ref2 = this.children;
451
- for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
452
- child = _ref2[_j];
461
+ _ref3 = this.children;
462
+ for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
463
+ child = _ref3[_k];
453
464
  output = output.concat(child.render());
454
465
  }
455
466
  output.push(this.getCloser());
456
467
  }
457
468
  } else if (this.opener) {
458
469
  output.push(this.getOpener());
459
- _ref3 = this.children;
460
- for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
461
- child = _ref3[_k];
462
- output = output.concat(child.render());
463
- }
464
- } else {
465
470
  _ref4 = this.children;
466
471
  for (_l = 0, _len4 = _ref4.length; _l < _len4; _l++) {
467
472
  child = _ref4[_l];
473
+ output = output.concat(child.render());
474
+ }
475
+ } else {
476
+ _ref5 = this.children;
477
+ for (_m = 0, _len5 = _ref5.length; _m < _len5; _m++) {
478
+ child = _ref5[_m];
468
479
  output.push(this.markText(child.render().text));
469
480
  }
470
481
  }
@@ -559,10 +570,6 @@ require.define("/nodes/haml.js", function (require, module, exports, __dirname,
559
570
  Haml.__super__.constructor.apply(this, arguments);
560
571
  }
561
572
 
562
- Haml.selfCloseTags = ['meta', 'img', 'link', 'br', 'hr', 'input', 'area', 'param', 'col', 'base'];
563
-
564
- Haml.preserveTags = ['pre', 'textarea'];
565
-
566
573
  Haml.prototype.evaluate = function() {
567
574
  var assignment, code, identifier, match, prefix, tokens;
568
575
  tokens = this.parseExpression(this.expression);
@@ -576,11 +583,19 @@ require.define("/nodes/haml.js", function (require, module, exports, __dirname,
576
583
  identifier = match[1];
577
584
  assignment = match[2];
578
585
  if (identifier === '~') {
579
- code = p(assignment);
586
+ code = "\#{fp(" + assignment + ")}";
580
587
  } else if (identifier === '&=' || (identifier === '=' && this.escapeHtml)) {
581
- code = "\#{e(c(" + assignment + "))}";
588
+ if (this.preserve) {
589
+ code = "\#{p(e(c(" + assignment + ")))}";
590
+ } else {
591
+ code = "\#{e(c(" + assignment + "))}";
592
+ }
582
593
  } else if (identifier === '!=' || (identifier === '=' && !this.escapeHtml)) {
583
- code = "\#{c(" + assignment + ")}";
594
+ if (this.preserve) {
595
+ code = "\#{p(c(" + assignment + "))}";
596
+ } else {
597
+ code = "\#{c(" + assignment + ")}";
598
+ }
584
599
  }
585
600
  this.opener = this.markText("" + prefix + ">" + code);
586
601
  return this.closer = this.markText("</" + tokens.tag + ">");
@@ -602,7 +617,7 @@ require.define("/nodes/haml.js", function (require, module, exports, __dirname,
602
617
  Haml.prototype.parseExpression = function(exp) {
603
618
  var attribute, attributes, classes, id, tag, _i, _len, _ref, _ref2;
604
619
  tag = this.parseTag(exp);
605
- if (Haml.preserveTags.indexOf(tag.tag) !== -1) this.preserve = true;
620
+ if (this.preserveTags.indexOf(tag.tag) !== -1) this.preserve = true;
606
621
  id = (_ref = tag.ids) != null ? _ref.pop() : void 0;
607
622
  classes = tag.classes;
608
623
  attributes = [];
@@ -813,7 +828,7 @@ require.define("/nodes/haml.js", function (require, module, exports, __dirname,
813
828
  };
814
829
 
815
830
  Haml.prototype.isNotSelfClosing = function(tag) {
816
- return Haml.selfCloseTags.indexOf(tag) === -1 && !tag.match(/\/$/);
831
+ return this.selfCloseTags.indexOf(tag) === -1 && !tag.match(/\/$/);
817
832
  };
818
833
 
819
834
  return Haml;
@@ -852,7 +867,11 @@ require.define("/nodes/code.js", function (require, module, exports, __dirname,
852
867
  return this.closer = this.markRunningCode(" ''");
853
868
  }
854
869
  } else if (identifier === '~') {
855
- return this.opener = this.markInsertingCode(p(code));
870
+ if (this.escapeHtml) {
871
+ return this.opener = this.markInsertingCode(code, true, false, true);
872
+ } else {
873
+ return this.opener = this.markInsertingCode(code, false, false, true);
874
+ }
856
875
  } else if (identifier === '&=' || (identifier === '=' && this.escapeHtml)) {
857
876
  return this.opener = this.markInsertingCode(code, true);
858
877
  } else if (identifier === '!=' || (identifier === '=' && !this.escapeHtml)) {
@@ -1056,7 +1075,7 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1056
1075
  module.exports = Compiler = (function() {
1057
1076
 
1058
1077
  function Compiler(options) {
1059
- var _base, _base2, _base3, _ref, _ref2, _ref3;
1078
+ var _base, _base2, _base3, _base4, _base5, _base6, _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
1060
1079
  this.options = options != null ? options : {};
1061
1080
  if ((_ref = (_base = this.options).escapeHtml) == null) {
1062
1081
  _base.escapeHtml = true;
@@ -1064,8 +1083,15 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1064
1083
  if ((_ref2 = (_base2 = this.options).escapeAttributes) == null) {
1065
1084
  _base2.escapeAttributes = true;
1066
1085
  }
1067
- if ((_ref3 = (_base3 = this.options).format) == null) {
1068
- _base3.format = 'html5';
1086
+ if ((_ref3 = (_base3 = this.options).uglify) == null) _base3.uglify = false;
1087
+ if ((_ref4 = (_base4 = this.options).format) == null) {
1088
+ _base4.format = 'html5';
1089
+ }
1090
+ if ((_ref5 = (_base5 = this.options).preserveTags) == null) {
1091
+ _base5.preserveTags = 'pre,textarea';
1092
+ }
1093
+ if ((_ref6 = (_base6 = this.options).selfCloseTags) == null) {
1094
+ _base6.selfCloseTags = 'meta,img,link,br,hr,input,area,param,col,base';
1069
1095
  }
1070
1096
  }
1071
1097
 
@@ -1132,7 +1158,10 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1132
1158
  codeBlockLevel: override.codeBlockLevel || this.currentCodeBlockLevel,
1133
1159
  escapeHtml: override.escapeHtml || this.options.escapeHtml,
1134
1160
  escapeAttributes: override.escapeAttributes || this.options.escapeAttributes,
1135
- format: override.format || this.options.format
1161
+ format: override.format || this.options.format,
1162
+ preserveTags: override.preserveTags || this.options.preserveTags,
1163
+ selfCloseTags: override.selfCloseTags || this.options.selfCloseTags,
1164
+ uglify: override.uglify || this.options.uglify
1136
1165
  };
1137
1166
  };
1138
1167
 
@@ -1230,7 +1259,7 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1230
1259
  };
1231
1260
 
1232
1261
  Compiler.prototype.render = function(templateName, namespace) {
1233
- var cleanFn, code, escapeFn, output, segment, segments, _i, _len;
1262
+ var cleanFn, code, escapeFn, findAndPreserveFn, output, preserveFn, segment, segments, _i, _len;
1234
1263
  if (namespace == null) namespace = 'window.HAML';
1235
1264
  output = '';
1236
1265
  segments = ("" + namespace + "." + templateName).replace(/(\s|-)+/g, '_').split(/\./);
@@ -1257,11 +1286,25 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1257
1286
  cleanFn = "" + namespace + ".cleanValue";
1258
1287
  output += cleanFn + '||= (text) -> if text is null or text is undefined then \'\' else text\n';
1259
1288
  }
1289
+ if (this.options.customPreserve) {
1290
+ preserveFn = this.options.customPreserve;
1291
+ } else {
1292
+ preserveFn = "" + namespace + ".preserve";
1293
+ output += preserveFn + "||= (text) -> text.replace /\\n/g, '&#x000A;'\n";
1294
+ }
1295
+ if (this.options.customFindAndPreserve) {
1296
+ findAndPreserveFn = this.options.customFindAndPreserve;
1297
+ } else {
1298
+ findAndPreserveFn = "" + namespace + ".findAndPreserve";
1299
+ output += findAndPreserveFn + ("||= (text) ->\n text.replace /<(" + (this.options.preserveTags.split(',').join('|')) + ")>([^]*?)<\\/\\1>/g, (str, tag, content) ->\n \"<\#{ tag }>\#{ " + preserveFn + "(content) }</\#{ tag }>\"\n");
1300
+ }
1260
1301
  output += "" + namespace + "['" + templateName + "'] = (context) ->\n";
1261
1302
  output += " fn = (context) ->\n";
1262
1303
  output += " o = []\n";
1263
1304
  output += " e = " + escapeFn + "\n";
1264
1305
  output += " c = " + cleanFn + "\n";
1306
+ output += " p = " + preserveFn + "\n";
1307
+ output += " fp = findAndPreserve = " + findAndPreserveFn + "\n";
1265
1308
  code = this.createCode();
1266
1309
  output += "" + code + "\n";
1267
1310
  output += " return o.join(\"\\n\")" + (this.cleanupWhitespace(code)) + "\n";
@@ -1291,9 +1334,9 @@ require.define("/compiler.js", function (require, module, exports, __dirname, __
1291
1334
  break;
1292
1335
  case 'insert':
1293
1336
  if (line.hw === 0) {
1294
- code.push("" + (w(line.cw)) + "o.push " + (w(line.escape) ? 'e ' : '') + "c(" + line.code + ")");
1337
+ code.push("" + (w(line.cw)) + "o.push " + (w(line.findAndPreserve) ? 'fp ' : '') + (w(line.preserve) ? 'p ' : '') + (w(line.escape) ? 'e ' : '') + "c " + line.code);
1295
1338
  } else {
1296
- code.push("" + (w(line.cw)) + "o.push " + (w(line.escape) ? 'e' : '') + " \"" + (w(line.hw - line.cw + 2)) + "\" + c(" + line.code + ")");
1339
+ code.push("" + (w(line.cw)) + "o.push \"" + (w(line.hw - line.cw + 2)) + "\" + " + (w(line.findAndPreserve) ? 'fp ' : '') + (w(line.preserve) ? 'p ' : '') + (w(line.escape) ? 'e ' : '') + "c " + line.code);
1297
1340
  }
1298
1341
  }
1299
1342
  }
@@ -0,0 +1,88 @@
1
+ # HAML Coffee namespace
2
+ #
3
+ window.HAML ||= {}
4
+
5
+ # HAML Coffee html escape function
6
+ #
7
+ # @param text [String] the text to escape
8
+ # @return [String] the escaped text
9
+ #
10
+ window.HAML.escape ||= (text) ->
11
+ ("" + text)
12
+ .replace(/&/g, "&amp;")
13
+ .replace(/</g, "&lt;")
14
+ .replace(/>/g, "&gt;")
15
+ .replace(/"/g, "&quot;")
16
+
17
+ # HAML Coffee clean value function
18
+ #
19
+ # @param text [String] the text to be cleaned
20
+ # @return [String] the cleaned text
21
+ #
22
+ window.HAML.cleanValue ||= (text) ->
23
+ if text is null or text is undefined then '' else text
24
+
25
+ # HAML Coffee extend function.
26
+ #
27
+ # This will reuse the extend function from either:
28
+ #
29
+ # - jQuery
30
+ # - Underscore.js
31
+ # - Prototype
32
+ # - MooTools
33
+ # - Zepto.js
34
+ #
35
+ # You can assign a custom extend function if your framework
36
+ # is not supported out of the box.
37
+ #
38
+ window.HAML.extend ||= (globals, locals) ->
39
+ if jQuery?.extend
40
+ jQuery.extend {}, globals, locals
41
+
42
+ else if _?.extend
43
+ _.extend {}, globals, locals
44
+
45
+ else if Zepto?.extend
46
+ Zepto.extend(Zepto.extend({}, globals), locals)
47
+
48
+ else if Object.extend
49
+ Object.extend(Object.extend({}, globals), locals)
50
+
51
+ else if Object.append
52
+ Object.append(Object.append({}, globals), locals)
53
+
54
+ else
55
+ locals
56
+
57
+ # HAML Coffee global template context.
58
+ #
59
+ # @return [Object] the global template context
60
+ #
61
+ window.HAML.globals ||= -> {}
62
+
63
+ # Get the HAML template context. This merges the local
64
+ # and the global template context into a new context.
65
+ #
66
+ # @param locals [Object] the local template context
67
+ # @return [Object] the merged context
68
+ #
69
+ window.HAML.context ||= (locals) ->
70
+ HAML.extend(HAML.globals(), locals)
71
+
72
+ # Preserve newlines in the text
73
+ #
74
+ # @param text [String] the text to preserve
75
+ # @return [String] the preserved text
76
+ #
77
+ window.HAML.preserve ||= (text) ->
78
+ text.replace /\\n/g, '&#x000A;'
79
+
80
+ # Find and preserve newlines in the preserving tags
81
+ #
82
+ # @param text [String] the text to preserve
83
+ # @return [String] the preserved text
84
+ #
85
+ window.HAML.findAndPreserve ||= ->
86
+ tags = '<%= HamlCoffeeAssets::HamlCoffee.preserveTags %>'.split(',').join('|')
87
+ text.replace ///<(#{ tags })>([^]*?)<\/\1>///g, (str, tag, content) ->
88
+ "<#{ tag }>#{ <%= HamlCoffeeAssets::HamlCoffee.customPreserve %>(content) }</#{ tag }>"
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: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-28 00:00:00.000000000Z
12
+ date: 2011-12-08 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70271110267660 !ruby/object:Gem::Requirement
16
+ requirement: &70174079146660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70271110267660
24
+ version_requirements: *70174079146660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: execjs
27
- requirement: &70271110266700 !ruby/object:Gem::Requirement
27
+ requirement: &70174079146160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.2.9
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70271110266700
35
+ version_requirements: *70174079146160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &70271110264040 !ruby/object:Gem::Requirement
38
+ requirement: &70174079145700 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70271110264040
46
+ version_requirements: *70174079145700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70271110263360 !ruby/object:Gem::Requirement
49
+ requirement: &70174079145120 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.7.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70271110263360
57
+ version_requirements: *70174079145120
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &70271110262780 !ruby/object:Gem::Requirement
60
+ requirement: &70174079144540 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.5.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70271110262780
68
+ version_requirements: *70174079144540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
- requirement: &70271110262040 !ruby/object:Gem::Requirement
71
+ requirement: &70174079144040 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.7.3
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70271110262040
79
+ version_requirements: *70174079144040
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: redcarpet
82
- requirement: &70271110261360 !ruby/object:Gem::Requirement
82
+ requirement: &70174079143520 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.17.2
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70271110261360
90
+ version_requirements: *70174079143520
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: pry
93
- requirement: &70271110260900 !ruby/object:Gem::Requirement
93
+ requirement: &70174079143000 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 0.9.6.2
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70271110260900
101
+ version_requirements: *70174079143000
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rake
104
- requirement: &70271110225480 !ruby/object:Gem::Requirement
104
+ requirement: &70174079142540 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: 0.9.2.2
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70271110225480
112
+ version_requirements: *70174079142540
113
113
  description: Compile Haml CoffeeScript templates in the Rails asset pipeline.
114
114
  email:
115
115
  - michi@netzpiraten.ch
@@ -126,7 +126,7 @@ files:
126
126
  - lib/js/coffee-script.js
127
127
  - lib/js/haml-coffee.js
128
128
  - lib/tasks/haml-coffee-rails_tasks.rake
129
- - vendor/assets/javascripts/hamlcoffee.js
129
+ - vendor/assets/javascripts/hamlcoffee.js.coffee.erb
130
130
  - LICENSE
131
131
  - README.md
132
132
  homepage: https://github.com/netzpirat/haml_coffee_assets
@@ -1,85 +0,0 @@
1
- /**
2
- * HAML Coffee namespace
3
- */
4
- window.HAML || (window.HAML = {});
5
-
6
- /**
7
- * HAML Coffee html escape function
8
- *
9
- * @param text [String] the text to escape
10
- * @return [String] the escaped text
11
- */
12
- window.HAML.escape || (window.HAML.escape = function(text) {
13
- return ("" + text)
14
- .replace(/&/g, "&amp;")
15
- .replace(/</g, "&lt;")
16
- .replace(/>/g, "&gt;")
17
- .replace(/"/g, "&quot;");
18
- });
19
-
20
- /**
21
- * HAML Coffee clean value function
22
- *
23
- * @param text [String] the text to be cleaned
24
- * @return [String] the cleaned text
25
- */
26
- window.HAML.cleanValue || (window.HAML.cleanValue = function(text) {
27
- if (text === null || text === void 0) {
28
- return '';
29
- } else {
30
- return text;
31
- }
32
- });
33
-
34
- /**
35
- * HAML Coffee extend function.
36
- *
37
- * This will reuse the extend function from either:
38
- *
39
- * - jQuery
40
- * - Underscore.js
41
- * - Prototype
42
- * - MooTools
43
- * - Zepto.js
44
- *
45
- * You can assign a custom extend function if your framework
46
- * is not supported out of the box.
47
- */
48
- window.HAML.extend || (window.HAML.extend = function(globals, locals) {
49
- if (jQuery && jQuery.extend) {
50
- return jQuery.extend({}, globals, locals);
51
- }
52
- else if (_ && _.extend) {
53
- return _.extend({}, globals, locals);
54
- }
55
- else if (Zepto && Zepto.extend) {
56
- return Zepto.extend(Zepto.extend({}, globals), locals);
57
- }
58
- else if (Object.extend) {
59
- return Object.extend(Object.extend({}, globals), locals)
60
- }
61
- else if (Object.append) {
62
- return Object.append(Object.append({}, globals), locals)
63
- }
64
- else { return locals }
65
- });
66
-
67
- /**
68
- * HAML Coffee global template context.
69
- *
70
- * @return [Object] the global template context
71
- */
72
- window.HAML.globals || (window.HAML.globals = function() {
73
- return {}
74
- });
75
-
76
- /**
77
- * Get the HAML template context. This merges the local
78
- * and the global template context into a new context.
79
- *
80
- * @param locals [Object] the local template context
81
- * @return [Object] the merged context
82
- */
83
- window.HAML.context || (window.HAML.context = function(locals) {
84
- return HAML.extend(HAML.globals(), locals)
85
- });