haml_coffee_assets 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
- });