barber 0.1.1 → 0.1.2

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.
@@ -3,7 +3,7 @@ require File.expand_path('../lib/barber/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["tchak", "twinturbo"]
6
- gem.email = ["paul@chavard.net"]
6
+ gem.email = ["paul@chavard.net", "me@boardcastingadam.com"]
7
7
  gem.description = %q{Handlebars precompilation}
8
8
  gem.summary = %q{Handlebars precompilation toolkit}
9
9
  gem.homepage = "https://github.com/tchak/barber"
@@ -9,7 +9,7 @@ require "barber/ember/precompilers"
9
9
  module Barber
10
10
  class PrecompilerError < StandardError
11
11
  def initialize(template, error)
12
- @template, @error = @template, error
12
+ @template, @error = template, error
13
13
  end
14
14
 
15
15
  def to_s
@@ -1,5 +1,5 @@
1
- require 'json'
2
1
  require 'execjs'
2
+ require 'json'
3
3
 
4
4
  module Barber
5
5
  class Precompiler
@@ -9,18 +9,10 @@ module Barber
9
9
  end
10
10
  end
11
11
 
12
- def compile(source)
13
- # if the source is a prescaped JSON string then
14
- # it should be parse, else just use it as is
15
- content = begin
16
- JSON.load source
17
- rescue JSON::ParserError
18
- source
19
- end
20
-
21
- context.call precompile_function, content
12
+ def compile(template)
13
+ context.call precompile_function, sanitize(template)
22
14
  rescue ExecJS::ProgramError => ex
23
- raise Barber::PrecompilerError.new(source, ex)
15
+ raise Barber::PrecompilerError.new(template, ex)
24
16
  end
25
17
 
26
18
  def precompile_function
@@ -36,6 +28,37 @@ module Barber
36
28
  end
37
29
 
38
30
  private
31
+ # This method handles different types of user input. The precompiler
32
+ # can be called from many different places which create interesting
33
+ # conditions.
34
+ # Case 1: Rake-Pipeline-Web-Filters: calls with a JSON encoded string.
35
+ # Case 2: Matched a string in a Javascript source file that does not
36
+ # behave the same way in ruby. IE: template: Handlebars.compile('{{foo}}\n').
37
+ # Matching that string with a regex in Ruby generates a string with a literal \n.
38
+ # That same string in JavaScript does not contain a literal \n. These semantics
39
+ # break the compiler when \n are present in view helpers. Coffeescript block strings
40
+ # usually cause this problem.
41
+ # Case 3: "Normal" input. Reading from a file or something like that.
42
+ #
43
+ # Each one of these cases is covered by a test case. If you find another breaking
44
+ # use case please address it here with a regression test.
45
+ def sanitize(template)
46
+ begin
47
+ if template =~ /\A".+"\Z/m
48
+ # Case 1
49
+ JSON.load(%Q|{"template":#{template}}|)['template']
50
+ else
51
+ # Case 2: evaluate a literal JS string in Ruby in the JS context
52
+ # to get an equivalent Ruby string back. This will convert liternal \n's
53
+ # to new lines. This is safer than trying to modify the string using regex.
54
+ context.eval("'#{template}'")
55
+ end
56
+ rescue JSON::ParserError, ExecJS::RuntimeError
57
+ # Case 3
58
+ template
59
+ end
60
+ end
61
+
39
62
  def precompiler
40
63
  @precompiler ||= File.new(File.expand_path("../javascripts/handlebars_precompiler.js", __FILE__))
41
64
  end
@@ -1,3 +1,3 @@
1
1
  module Barber
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -16,7 +16,21 @@ class PrecompilerTest < MiniTest::Unit::TestCase
16
16
  {{view Radium.RangeChangerView}}
17
17
  hbs
18
18
 
19
- result = compile JSON.dump({:template => template})['template']
19
+ result = compile template
20
+ assert result
21
+ end
22
+
23
+ def test_handles_multiline_coffeescript_strings
24
+ template = '<h2>{{unbound view.title}}</h2>\n<ul>\n {{#each view.content}}\n {{view view.resultItemView\n contentBinding="this"\n selectedItemBinding="view.selectedItem"}}\n {{/each}}\n</ul>'
25
+
26
+ result = compile template
27
+ assert result
28
+ end
29
+
30
+ def test_handles_prescaped_JSON_strings
31
+ template = '"<div class=\"comments\">\n <div class=\"span5 offset1\">\n {{#if view.comments.length}}\n <ul class=\"comments-list unstyled\">\n {{#each view.comments}}\n {{view Radium.CommentView commentBinding=\"this\"}}\n {{/each}}\n </ul>\n {{/if}}\n {{#if view.isError}}\n <p class=\"error\">Hmm, something wasn\'t done correctly. Try again?</p>\n {{/if}}\n <div style=\"clear: both\"></div>\n {{view view.commentTextArea}}\n </div>\n</div>\n"'
32
+
33
+ result = compile template
20
34
  assert result
21
35
  end
22
36
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: barber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-11-01 00:00:00.000000000 Z
13
+ date: 2012-11-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: execjs
@@ -79,6 +79,7 @@ dependencies:
79
79
  description: Handlebars precompilation
80
80
  email:
81
81
  - paul@chavard.net
82
+ - me@boardcastingadam.com
82
83
  executables: []
83
84
  extensions: []
84
85
  extra_rdoc_files: []
@@ -118,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
119
  version: '0'
119
120
  segments:
120
121
  - 0
121
- hash: -180034689176521228
122
+ hash: -2194861738178296462
122
123
  required_rubygems_version: !ruby/object:Gem::Requirement
123
124
  none: false
124
125
  requirements:
@@ -127,10 +128,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
128
  version: '0'
128
129
  segments:
129
130
  - 0
130
- hash: -180034689176521228
131
+ hash: -2194861738178296462
131
132
  requirements: []
132
133
  rubyforge_project:
133
- rubygems_version: 1.8.23
134
+ rubygems_version: 1.8.24
134
135
  signing_key:
135
136
  specification_version: 3
136
137
  summary: Handlebars precompilation toolkit