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.
- 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
|