handlebars 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/handlebars/context.rb +3 -5
- data/lib/handlebars/version.rb +1 -1
- data/spec/handlebars_spec.rb +3 -3
- data/vendor/handlebars/.gitignore +3 -1
- data/vendor/handlebars/.jshintrc +2 -0
- data/vendor/handlebars/.npmignore +0 -1
- data/vendor/handlebars/.rspec +1 -0
- data/vendor/handlebars/Gemfile +1 -1
- data/vendor/handlebars/LICENSE +0 -1
- data/vendor/handlebars/README.markdown +8 -6
- data/vendor/handlebars/Rakefile +14 -21
- data/vendor/handlebars/bench/benchwarmer.js +1 -1
- data/vendor/handlebars/bench/handlebars.js +43 -34
- data/vendor/handlebars/bin/handlebars +56 -2
- data/vendor/handlebars/dist/handlebars.js +2201 -0
- data/vendor/handlebars/dist/handlebars.runtime.js +321 -0
- data/vendor/handlebars/lib/handlebars/base.js +68 -15
- data/vendor/handlebars/lib/handlebars/compiler/ast.js +50 -20
- data/vendor/handlebars/lib/handlebars/compiler/base.js +7 -13
- data/vendor/handlebars/lib/handlebars/compiler/compiler.js +758 -299
- data/vendor/handlebars/lib/handlebars/compiler/printer.js +24 -30
- data/vendor/handlebars/lib/handlebars/runtime.js +23 -3
- data/vendor/handlebars/lib/handlebars/utils.js +9 -10
- data/vendor/handlebars/package.json +15 -5
- data/vendor/handlebars/spec/acceptance_spec.rb +5 -5
- data/vendor/handlebars/spec/parser_spec.rb +201 -32
- data/vendor/handlebars/spec/qunit_spec.js +462 -159
- data/vendor/handlebars/spec/spec_helper.rb +7 -7
- data/vendor/handlebars/spec/tokenizer_spec.rb +55 -8
- data/vendor/handlebars/src/handlebars.l +14 -3
- data/vendor/handlebars/src/handlebars.yy +15 -5
- data/vendor/handlebars/src/parser-prefix.js +1 -0
- data/vendor/handlebars/src/parser-suffix.js +4 -0
- 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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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,}?/("{{")
|
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
|
-
:
|
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.
|
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
|
49
|
-
| OPEN_PARTIAL
|
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)
|
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.
|
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-
|
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.
|
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
|