barber 0.1.1 → 0.1.2

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