handlebars 0.3.2 → 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.
Files changed (34) hide show
  1. data/lib/handlebars/context.rb +3 -5
  2. data/lib/handlebars/version.rb +1 -1
  3. data/spec/handlebars_spec.rb +3 -3
  4. data/vendor/handlebars/.gitignore +3 -1
  5. data/vendor/handlebars/.jshintrc +2 -0
  6. data/vendor/handlebars/.npmignore +0 -1
  7. data/vendor/handlebars/.rspec +1 -0
  8. data/vendor/handlebars/Gemfile +1 -1
  9. data/vendor/handlebars/LICENSE +0 -1
  10. data/vendor/handlebars/README.markdown +8 -6
  11. data/vendor/handlebars/Rakefile +14 -21
  12. data/vendor/handlebars/bench/benchwarmer.js +1 -1
  13. data/vendor/handlebars/bench/handlebars.js +43 -34
  14. data/vendor/handlebars/bin/handlebars +56 -2
  15. data/vendor/handlebars/dist/handlebars.js +2201 -0
  16. data/vendor/handlebars/dist/handlebars.runtime.js +321 -0
  17. data/vendor/handlebars/lib/handlebars/base.js +68 -15
  18. data/vendor/handlebars/lib/handlebars/compiler/ast.js +50 -20
  19. data/vendor/handlebars/lib/handlebars/compiler/base.js +7 -13
  20. data/vendor/handlebars/lib/handlebars/compiler/compiler.js +758 -299
  21. data/vendor/handlebars/lib/handlebars/compiler/printer.js +24 -30
  22. data/vendor/handlebars/lib/handlebars/runtime.js +23 -3
  23. data/vendor/handlebars/lib/handlebars/utils.js +9 -10
  24. data/vendor/handlebars/package.json +15 -5
  25. data/vendor/handlebars/spec/acceptance_spec.rb +5 -5
  26. data/vendor/handlebars/spec/parser_spec.rb +201 -32
  27. data/vendor/handlebars/spec/qunit_spec.js +462 -159
  28. data/vendor/handlebars/spec/spec_helper.rb +7 -7
  29. data/vendor/handlebars/spec/tokenizer_spec.rb +55 -8
  30. data/vendor/handlebars/src/handlebars.l +14 -3
  31. data/vendor/handlebars/src/handlebars.yy +15 -5
  32. data/vendor/handlebars/src/parser-prefix.js +1 -0
  33. data/vendor/handlebars/src/parser-suffix.js +4 -0
  34. metadata +8 -3
@@ -47,15 +47,15 @@ module Handlebars
47
47
  def self.load_helpers(context)
48
48
  context["exports"] = nil
49
49
 
50
- context["p"] = proc do |val|
50
+ context["p"] = proc do |this, val|
51
51
  p val if ENV["DEBUG_JS"]
52
52
  end
53
53
 
54
- context["puts"] = proc do |val|
54
+ context["puts"] = proc do |this, val|
55
55
  puts val if ENV["DEBUG_JS"]
56
56
  end
57
57
 
58
- context["puts_node"] = proc do |val|
58
+ context["puts_node"] = proc do |this, val|
59
59
  puts context["Handlebars"]["PrintVisitor"].new.accept(val)
60
60
  puts
61
61
  end
@@ -82,12 +82,12 @@ module Handlebars
82
82
 
83
83
  context["CompilerContext"] = {}
84
84
  CompilerContext = context["CompilerContext"]
85
- CompilerContext["compile"] = proc do |*args|
85
+ CompilerContext["compile"] = proc do |this, *args|
86
86
  template, options = args[0], args[1] || nil
87
87
  templateSpec = COMPILE_CONTEXT["Handlebars"]["precompile"].call(template, options);
88
88
  context["Handlebars"]["template"].call(context.eval("(#{templateSpec})"));
89
89
  end
90
- CompilerContext["compileWithPartial"] = proc do |*args|
90
+ CompilerContext["compileWithPartial"] = proc do |this, *args|
91
91
  template, options = args[0], args[1] || nil
92
92
  FULL_CONTEXT["Handlebars"]["compile"].call(template, options);
93
93
  end
@@ -108,7 +108,7 @@ module Handlebars
108
108
 
109
109
  context["Handlebars"]["logger"]["level"] = ENV["DEBUG_JS"] ? context["Handlebars"]["logger"][ENV["DEBUG_JS"]] : 4
110
110
 
111
- context["Handlebars"]["logger"]["log"] = proc do |level, str|
111
+ context["Handlebars"]["logger"]["log"] = proc do |this, level, str|
112
112
  logger_level = context["Handlebars"]["logger"]["level"].to_i
113
113
 
114
114
  if logger_level <= level
@@ -133,7 +133,7 @@ module Handlebars
133
133
 
134
134
  context["Handlebars"]["logger"]["level"] = ENV["DEBUG_JS"] ? context["Handlebars"]["logger"][ENV["DEBUG_JS"]] : 4
135
135
 
136
- context["Handlebars"]["logger"]["log"] = proc do |level, str|
136
+ context["Handlebars"]["logger"]["log"] = proc do |this, level, str|
137
137
  logger_level = context["Handlebars"]["logger"]["level"].to_i
138
138
 
139
139
  if logger_level <= level
@@ -51,6 +51,15 @@ describe "Tokenizer" do
51
51
  result[4].should be_token("CONTENT", "{{bar}} ")
52
52
  end
53
53
 
54
+ it "supports escaping multiple delimiters" do
55
+ result = tokenize("{{foo}} \\{{bar}} \\{{baz}}")
56
+ result.should match_tokens(%w(OPEN ID CLOSE CONTENT CONTENT CONTENT))
57
+
58
+ result[3].should be_token("CONTENT", " ")
59
+ result[4].should be_token("CONTENT", "{{bar}} ")
60
+ result[5].should be_token("CONTENT", "{{baz}}")
61
+ end
62
+
54
63
  it "supports escaping a triple stash" do
55
64
  result = tokenize("{{foo}} \\{{{bar}}} {{baz}}")
56
65
  result.should match_tokens(%w(OPEN ID CLOSE CONTENT CONTENT OPEN ID CLOSE))
@@ -123,24 +132,24 @@ describe "Tokenizer" do
123
132
  result[4].should be_token("CONTENT", " baz")
124
133
  end
125
134
 
126
- it "tokenizes a partial as 'OPEN_PARTIAL ID CLOSE'" do
135
+ it "tokenizes a partial as 'OPEN_PARTIAL PARTIAL_NAME CLOSE'" do
127
136
  result = tokenize("{{> foo}}")
128
- result.should match_tokens(%w(OPEN_PARTIAL ID CLOSE))
137
+ result.should match_tokens(%w(OPEN_PARTIAL PARTIAL_NAME CLOSE))
129
138
  end
130
139
 
131
- it "tokenizes a partial with context as 'OPEN_PARTIAL ID ID CLOSE'" do
140
+ it "tokenizes a partial with context as 'OPEN_PARTIAL PARTIAL_NAME ID CLOSE'" do
132
141
  result = tokenize("{{> foo bar }}")
133
- result.should match_tokens(%w(OPEN_PARTIAL ID ID CLOSE))
142
+ result.should match_tokens(%w(OPEN_PARTIAL PARTIAL_NAME ID CLOSE))
134
143
  end
135
144
 
136
- it "tokenizes a partial without spaces as 'OPEN_PARTIAL ID CLOSE'" do
145
+ it "tokenizes a partial without spaces as 'OPEN_PARTIAL PARTIAL_NAME CLOSE'" do
137
146
  result = tokenize("{{>foo}}")
138
- result.should match_tokens(%w(OPEN_PARTIAL ID CLOSE))
147
+ result.should match_tokens(%w(OPEN_PARTIAL PARTIAL_NAME CLOSE))
139
148
  end
140
149
 
141
- it "tokenizes a partial space at the end as 'OPEN_PARTIAL ID CLOSE'" do
150
+ it "tokenizes a partial space at the end as 'OPEN_PARTIAL PARTIAL_NAME CLOSE'" do
142
151
  result = tokenize("{{>foo }}")
143
- result.should match_tokens(%w(OPEN_PARTIAL ID CLOSE))
152
+ result.should match_tokens(%w(OPEN_PARTIAL PARTIAL_NAME CLOSE))
144
153
  end
145
154
 
146
155
  it "tokenizes a comment as 'COMMENT'" do
@@ -149,6 +158,18 @@ describe "Tokenizer" do
149
158
  result[1].should be_token("COMMENT", " this is a comment ")
150
159
  end
151
160
 
161
+ it "tokenizes a block comment as 'COMMENT'" do
162
+ result = tokenize("foo {{!-- this is a {{comment}} --}} bar {{ baz }}")
163
+ result.should match_tokens(%w(CONTENT COMMENT CONTENT OPEN ID CLOSE))
164
+ result[1].should be_token("COMMENT", " this is a {{comment}} ")
165
+ end
166
+
167
+ it "tokenizes a block comment with whitespace as 'COMMENT'" do
168
+ result = tokenize("foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}")
169
+ result.should match_tokens(%w(CONTENT COMMENT CONTENT OPEN ID CLOSE))
170
+ result[1].should be_token("COMMENT", " this is a\n{{comment}}\n")
171
+ end
172
+
152
173
  it "tokenizes open and closing blocks as 'OPEN_BLOCK ID CLOSE ... OPEN_ENDBLOCK ID CLOSE'" do
153
174
  result = tokenize("{{#foo}}content{{/foo}}")
154
175
  result.should match_tokens(%w(OPEN_BLOCK ID CLOSE CONTENT OPEN_ENDBLOCK ID CLOSE))
@@ -186,6 +207,12 @@ describe "Tokenizer" do
186
207
  result[3].should be_token("STRING", "baz")
187
208
  end
188
209
 
210
+ it "tokenizes mustaches with String params using single quotes as 'OPEN ID ID STRING CLOSE'" do
211
+ result = tokenize("{{ foo bar \'baz\' }}")
212
+ result.should match_tokens(%w(OPEN ID ID STRING CLOSE))
213
+ result[3].should be_token("STRING", "baz")
214
+ end
215
+
189
216
  it "tokenizes String params with spaces inside as 'STRING'" do
190
217
  result = tokenize("{{ foo bar \"baz bat\" }}")
191
218
  result.should match_tokens(%w(OPEN ID ID STRING CLOSE))
@@ -198,6 +225,12 @@ describe "Tokenizer" do
198
225
  result[2].should be_token("STRING", %{bar"baz})
199
226
  end
200
227
 
228
+ it "tokenizes String params using single quotes with escapes quotes as 'STRING'" do
229
+ result = tokenize(%|{{ foo 'bar\\'baz' }}|)
230
+ result.should match_tokens(%w(OPEN ID STRING CLOSE))
231
+ result[2].should be_token("STRING", %{bar'baz})
232
+ end
233
+
201
234
  it "tokenizes numbers" do
202
235
  result = tokenize(%|{{ foo 1 }}|)
203
236
  result.should match_tokens(%w(OPEN ID INTEGER CLOSE))
@@ -244,6 +277,20 @@ describe "Tokenizer" do
244
277
  result[2].should be_token("ID", "omg")
245
278
  end
246
279
 
280
+ it "tokenizes special @ identifiers" do
281
+ result = tokenize("{{ @foo }}")
282
+ result.should match_tokens %w( OPEN DATA CLOSE )
283
+ result[1].should be_token("DATA", "foo")
284
+
285
+ result = tokenize("{{ foo @bar }}")
286
+ result.should match_tokens %w( OPEN ID DATA CLOSE )
287
+ result[2].should be_token("DATA", "bar")
288
+
289
+ result = tokenize("{{ foo bar=@baz }}")
290
+ result.should match_tokens %w( OPEN ID ID EQUALS DATA CLOSE )
291
+ result[4].should be_token("DATA", "baz")
292
+ end
293
+
247
294
  it "does not time out in a mustache with a single } followed by EOF" do
248
295
  Timeout.timeout(1) { tokenize("{{foo}").should match_tokens(%w(OPEN ID)) }
249
296
  end
@@ -1,5 +1,5 @@
1
1
 
2
- %x mu emu
2
+ %x mu emu com par
3
3
 
4
4
  %%
5
5
 
@@ -11,15 +11,22 @@
11
11
 
12
12
  [^\x00]+ { return 'CONTENT'; }
13
13
 
14
- <emu>[^\x00]{2,}?/("{{") { this.popState(); return 'CONTENT'; }
14
+ <emu>[^\x00]{2,}?/("{{"|<<EOF>>) {
15
+ if(yytext.slice(-1) !== "\\") this.popState();
16
+ if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1);
17
+ return 'CONTENT';
18
+ }
19
+
20
+ <com>[\s\S]*?"--}}" { yytext = yytext.substr(0, yyleng-4); this.popState(); return 'COMMENT'; }
15
21
 
16
- <mu>"{{>" { return 'OPEN_PARTIAL'; }
22
+ <mu>"{{>" { this.begin("par"); return 'OPEN_PARTIAL'; }
17
23
  <mu>"{{#" { return 'OPEN_BLOCK'; }
18
24
  <mu>"{{/" { return 'OPEN_ENDBLOCK'; }
19
25
  <mu>"{{^" { return 'OPEN_INVERSE'; }
20
26
  <mu>"{{"\s*"else" { return 'OPEN_INVERSE'; }
21
27
  <mu>"{{{" { return 'OPEN_UNESCAPED'; }
22
28
  <mu>"{{&" { return 'OPEN_UNESCAPED'; }
29
+ <mu>"{{!--" { this.popState(); this.begin('com'); }
23
30
  <mu>"{{!"[\s\S]*?"}}" { yytext = yytext.substr(3,yyleng-5); this.popState(); return 'COMMENT'; }
24
31
  <mu>"{{" { return 'OPEN'; }
25
32
 
@@ -31,12 +38,16 @@
31
38
  <mu>"}}}" { this.popState(); return 'CLOSE'; }
32
39
  <mu>"}}" { this.popState(); return 'CLOSE'; }
33
40
  <mu>'"'("\\"["]|[^"])*'"' { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
41
+ <mu>"'"("\\"[']|[^'])*"'" { yytext = yytext.substr(1,yyleng-2).replace(/\\'/g,"'"); return 'STRING'; }
42
+ <mu>"@"[a-zA-Z]+ { yytext = yytext.substr(1); return 'DATA'; }
34
43
  <mu>"true"/[}\s] { return 'BOOLEAN'; }
35
44
  <mu>"false"/[}\s] { return 'BOOLEAN'; }
36
45
  <mu>[0-9]+/[}\s] { return 'INTEGER'; }
37
46
  <mu>[a-zA-Z0-9_$-]+/[=}\s\/.] { return 'ID'; }
38
47
  <mu>'['[^\]]*']' { yytext = yytext.substr(1, yyleng-2); return 'ID'; }
39
48
  <mu>. { return 'INVALID'; }
49
+ <par>\s+ { /*ignore whitespace*/ }
50
+ <par>[a-zA-Z0-9_$-/]+ { this.popState(); return 'PARTIAL_NAME'; }
40
51
 
41
52
  <INITIAL,mu><<EOF>> { return 'EOF'; }
42
53
 
@@ -7,8 +7,11 @@ root
7
7
  ;
8
8
 
9
9
  program
10
- : statements simpleInverse statements { $$ = new yy.ProgramNode($1, $3); }
10
+ : simpleInverse statements { $$ = new yy.ProgramNode([], $2); }
11
+ | statements simpleInverse statements { $$ = new yy.ProgramNode($1, $3); }
12
+ | statements simpleInverse { $$ = new yy.ProgramNode($1, []); }
11
13
  | statements { $$ = new yy.ProgramNode($1); }
14
+ | simpleInverse { $$ = new yy.ProgramNode([], []); }
12
15
  | "" { $$ = new yy.ProgramNode([]); }
13
16
  ;
14
17
 
@@ -18,8 +21,8 @@ statements
18
21
  ;
19
22
 
20
23
  statement
21
- : openInverse program closeBlock { $$ = new yy.InverseNode($1, $2, $3); }
22
- | openBlock program closeBlock { $$ = new yy.BlockNode($1, $2, $3); }
24
+ : openInverse program closeBlock { $$ = new yy.BlockNode($1, $2.inverse, $2, $3); }
25
+ | openBlock program closeBlock { $$ = new yy.BlockNode($1, $2, $2.inverse, $3); }
23
26
  | mustache { $$ = $1; }
24
27
  | partial { $$ = $1; }
25
28
  | CONTENT { $$ = new yy.ContentNode($1); }
@@ -45,8 +48,8 @@ mustache
45
48
 
46
49
 
47
50
  partial
48
- : OPEN_PARTIAL path CLOSE { $$ = new yy.PartialNode($2); }
49
- | OPEN_PARTIAL path path CLOSE { $$ = new yy.PartialNode($2, $3); }
51
+ : OPEN_PARTIAL partialName CLOSE { $$ = new yy.PartialNode($2); }
52
+ | OPEN_PARTIAL partialName path CLOSE { $$ = new yy.PartialNode($2, $3); }
50
53
  ;
51
54
 
52
55
  simpleInverse
@@ -58,6 +61,7 @@ inMustache
58
61
  | path params { $$ = [[$1].concat($2), null]; }
59
62
  | path hash { $$ = [[$1], $2]; }
60
63
  | path { $$ = [[$1], null]; }
64
+ | DATA { $$ = [[new yy.DataNode($1)], null]; }
61
65
  ;
62
66
 
63
67
  params
@@ -70,6 +74,7 @@ param
70
74
  | STRING { $$ = new yy.StringNode($1); }
71
75
  | INTEGER { $$ = new yy.IntegerNode($1); }
72
76
  | BOOLEAN { $$ = new yy.BooleanNode($1); }
77
+ | DATA { $$ = new yy.DataNode($1); }
73
78
  ;
74
79
 
75
80
  hash
@@ -86,6 +91,11 @@ hashSegment
86
91
  | ID EQUALS STRING { $$ = [$1, new yy.StringNode($3)]; }
87
92
  | ID EQUALS INTEGER { $$ = [$1, new yy.IntegerNode($3)]; }
88
93
  | ID EQUALS BOOLEAN { $$ = [$1, new yy.BooleanNode($3)]; }
94
+ | ID EQUALS DATA { $$ = [$1, new yy.DataNode($3)]; }
95
+ ;
96
+
97
+ partialName
98
+ : PARTIAL_NAME { $$ = new yy.PartialNameNode($1); }
89
99
  ;
90
100
 
91
101
  path
@@ -0,0 +1 @@
1
+ // BEGIN(BROWSER)
@@ -0,0 +1,4 @@
1
+
2
+ // END(BROWSER)
3
+
4
+ module.exports = handlebars;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handlebars
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.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: 2013-01-08 00:00:00.000000000 Z
12
+ date: 2013-02-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: therubyracer
@@ -103,6 +103,7 @@ files:
103
103
  - vendor/handlebars/.gitignore
104
104
  - vendor/handlebars/.jshintrc
105
105
  - vendor/handlebars/.npmignore
106
+ - vendor/handlebars/.rspec
106
107
  - vendor/handlebars/Gemfile
107
108
  - vendor/handlebars/Gemfile.lock
108
109
  - vendor/handlebars/LICENSE
@@ -111,6 +112,8 @@ files:
111
112
  - vendor/handlebars/bench/benchwarmer.js
112
113
  - vendor/handlebars/bench/handlebars.js
113
114
  - vendor/handlebars/bin/handlebars
115
+ - vendor/handlebars/dist/handlebars.js
116
+ - vendor/handlebars/dist/handlebars.runtime.js
114
117
  - vendor/handlebars/lib/handlebars.js
115
118
  - vendor/handlebars/lib/handlebars/base.js
116
119
  - vendor/handlebars/lib/handlebars/compiler/ast.js
@@ -129,6 +132,8 @@ files:
129
132
  - vendor/handlebars/spec/tokenizer_spec.rb
130
133
  - vendor/handlebars/src/handlebars.l
131
134
  - vendor/handlebars/src/handlebars.yy
135
+ - vendor/handlebars/src/parser-prefix.js
136
+ - vendor/handlebars/src/parser-suffix.js
132
137
  - vendor/handlebars/lib/handlebars/compiler/parser.js
133
138
  homepage: http://github.com/cowboyd/handlebars.rb
134
139
  licenses: []
@@ -150,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
155
  version: '0'
151
156
  requirements: []
152
157
  rubyforge_project: handlebars
153
- rubygems_version: 1.8.24
158
+ rubygems_version: 1.8.25
154
159
  signing_key:
155
160
  specification_version: 3
156
161
  summary: Ruby bindings for the handlebars.js templating library