hbs_plus 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.mdown +44 -0
- data/Rakefile +5 -0
- data/hbs.gemspec +28 -0
- data/js/.gitignore +5 -0
- data/js/Gemfile +4 -0
- data/js/LICENSE +20 -0
- data/js/README.markdown +224 -0
- data/js/Rakefile +107 -0
- data/js/bench/benchwarmer.js +147 -0
- data/js/bench/handlebars.js +166 -0
- data/js/lib/handlebars.js +15 -0
- data/js/lib/handlebars/ast.js +103 -0
- data/js/lib/handlebars/base.js +114 -0
- data/js/lib/handlebars/compiler.js +739 -0
- data/js/lib/handlebars/debug.js +29 -0
- data/js/lib/handlebars/printer.js +138 -0
- data/js/lib/handlebars/utils.js +66 -0
- data/js/lib/handlebars/visitor.js +13 -0
- data/js/spec/acceptance_spec.rb +100 -0
- data/js/spec/parser_spec.rb +259 -0
- data/js/spec/qunit_spec.js +836 -0
- data/js/spec/spec_helper.rb +106 -0
- data/js/spec/tokenizer_spec.rb +227 -0
- data/js/src/handlebars.l +34 -0
- data/js/src/handlebars.yy +99 -0
- data/lib/handlebars.rb +27 -0
- data/lib/handlebars/loader.rb +29 -0
- data/lib/handlebars/version.rb +3 -0
- data/spec/handlebars_spec.rb +55 -0
- metadata +107 -0
@@ -0,0 +1,147 @@
|
|
1
|
+
|
2
|
+
var Benchmark = require("benchmark");
|
3
|
+
|
4
|
+
var BenchWarmer = function(names) {
|
5
|
+
this.benchmarks = [];
|
6
|
+
this.currentBenches = [];
|
7
|
+
this.names = [];
|
8
|
+
this.errors = {};
|
9
|
+
};
|
10
|
+
|
11
|
+
var print = require("sys").print;
|
12
|
+
|
13
|
+
BenchWarmer.prototype = {
|
14
|
+
winners: function(benches) {
|
15
|
+
var result = Benchmark.filter(benches, function(bench) { return bench.cycles; });
|
16
|
+
|
17
|
+
if (result.length > 1) {
|
18
|
+
result.sort(function(a, b) { return b.compare(a); });
|
19
|
+
first = result[0];
|
20
|
+
last = result[result.length - 1];
|
21
|
+
|
22
|
+
var winners = [];
|
23
|
+
|
24
|
+
Benchmark.each(result, function(bench) {
|
25
|
+
if (bench.compare(first) === 0) {
|
26
|
+
winners.push(bench);
|
27
|
+
}
|
28
|
+
});
|
29
|
+
|
30
|
+
return winners;
|
31
|
+
} else {
|
32
|
+
return result;
|
33
|
+
}
|
34
|
+
},
|
35
|
+
suite: function(suite, fn) {
|
36
|
+
this.suiteName = suite;
|
37
|
+
this.first = true;
|
38
|
+
|
39
|
+
var self = this;
|
40
|
+
|
41
|
+
fn(function(name, benchFn) {
|
42
|
+
self.push(name, benchFn);
|
43
|
+
});
|
44
|
+
},
|
45
|
+
push: function(name, fn) {
|
46
|
+
if(this.names.indexOf(name) == -1) {
|
47
|
+
this.names.push(name);
|
48
|
+
}
|
49
|
+
|
50
|
+
var first = this.first, suiteName = this.suiteName, self = this;
|
51
|
+
this.first = false;
|
52
|
+
|
53
|
+
var bench = new Benchmark(function() {
|
54
|
+
fn();
|
55
|
+
}, {
|
56
|
+
name: this.suiteName + ": " + name,
|
57
|
+
onComplete: function() {
|
58
|
+
if(first) { self.startLine(suiteName); }
|
59
|
+
self.writeBench(bench);
|
60
|
+
self.currentBenches.push(bench);
|
61
|
+
}, onError: function() {
|
62
|
+
self.errors[this.name] = this;
|
63
|
+
}
|
64
|
+
});
|
65
|
+
|
66
|
+
this.benchmarks.push(bench);
|
67
|
+
},
|
68
|
+
bench: function() {
|
69
|
+
var benchSize = 0, names = this.names, self = this, i, l;
|
70
|
+
|
71
|
+
for(i=0, l=names.length; i<l; i++) {
|
72
|
+
var name = names[i];
|
73
|
+
|
74
|
+
if(benchSize < name.length) { benchSize = name.length; }
|
75
|
+
}
|
76
|
+
|
77
|
+
this.nameSize = benchSize + 2;
|
78
|
+
this.benchSize = 20;
|
79
|
+
var horSize = 0;
|
80
|
+
|
81
|
+
this.startLine("ops/msec");
|
82
|
+
horSize = horSize + "ops/msec ".length;
|
83
|
+
for(i=0, l=names.length; i<l; i++) {
|
84
|
+
print(names[i] + new Array(this.benchSize - names[i].length + 1).join(" "));
|
85
|
+
horSize = horSize + this.benchSize;
|
86
|
+
}
|
87
|
+
|
88
|
+
print("WINNER(S)");
|
89
|
+
horSize = horSize + "WINNER(S)".length;
|
90
|
+
|
91
|
+
print("\n" + new Array(horSize + 1).join("-"));
|
92
|
+
|
93
|
+
Benchmark.invoke(this.benchmarks, {
|
94
|
+
name: "run",
|
95
|
+
onComplete: function() {
|
96
|
+
var errors = false, prop, bench;
|
97
|
+
for(prop in self.errors) { if(self.errors.hasOwnProperty(prop)) { errors = true; break; } }
|
98
|
+
|
99
|
+
if(errors) {
|
100
|
+
print("\n\nErrors:\n");
|
101
|
+
for(prop in self.errors) {
|
102
|
+
if(self.errors.hasOwnProperty(prop)) {
|
103
|
+
bench = self.errors[prop];
|
104
|
+
print("\n" + bench.name + ":\n");
|
105
|
+
print(bench.error.message);
|
106
|
+
if(bench.error.stack) {
|
107
|
+
print(bench.error.stack.join("\n"));
|
108
|
+
}
|
109
|
+
print("\n");
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
});
|
115
|
+
},
|
116
|
+
startLine: function(name) {
|
117
|
+
var winners = Benchmark.map(this.winners(this.currentBenches), function(bench) {
|
118
|
+
return bench.name.split(": ")[1];
|
119
|
+
});
|
120
|
+
|
121
|
+
this.currentBenches = [];
|
122
|
+
|
123
|
+
print(winners.join(", "));
|
124
|
+
print("\n");
|
125
|
+
var padding = this.nameSize - name.length + 1;
|
126
|
+
name = name + new Array(padding).join(" ");
|
127
|
+
print(name);
|
128
|
+
},
|
129
|
+
writeBench: function(bench) {
|
130
|
+
var out;
|
131
|
+
|
132
|
+
if(!bench.error) {
|
133
|
+
var count = bench.hz,
|
134
|
+
moe = count * bench.stats.RME / 100;
|
135
|
+
|
136
|
+
out = Math.round(count / 1000) + " ±" + Math.round(moe / 1000) + " (" + bench.cycles + ")";
|
137
|
+
} else {
|
138
|
+
out = "E";
|
139
|
+
}
|
140
|
+
|
141
|
+
var padding = this.benchSize - out.length + 1;
|
142
|
+
out = out + new Array(padding).join(" ");
|
143
|
+
print(out);
|
144
|
+
}
|
145
|
+
};
|
146
|
+
|
147
|
+
module.exports = BenchWarmer;
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require.paths.push("lib");
|
2
|
+
require.paths.push("vendor");
|
3
|
+
require.paths.push("vendor/dustjs/lib");
|
4
|
+
require.paths.push("vendor/coffee/lib");
|
5
|
+
require.paths.push("vendor/eco/lib");
|
6
|
+
|
7
|
+
|
8
|
+
var BenchWarmer = require("./benchwarmer");
|
9
|
+
Handlebars = require("handlebars");
|
10
|
+
|
11
|
+
var dust = require("dust");
|
12
|
+
var Mustache = require("mustache");
|
13
|
+
var ecoExports = require("eco");
|
14
|
+
|
15
|
+
eco = function(str) {
|
16
|
+
var module = {};
|
17
|
+
var template = new Function("module", ecoExports.compile(str));
|
18
|
+
template(module);
|
19
|
+
return module.exports;
|
20
|
+
}
|
21
|
+
|
22
|
+
var benchDetails = {
|
23
|
+
string: {
|
24
|
+
context: {},
|
25
|
+
handlebars: "Hello world",
|
26
|
+
dust: "Hello world",
|
27
|
+
mustache: "Hello world",
|
28
|
+
eco: "Hello world"
|
29
|
+
},
|
30
|
+
variables: {
|
31
|
+
context: {name: "Mick", count: 30},
|
32
|
+
handlebars: "Hello {{name}}! You have {{count}} new messages.",
|
33
|
+
dust: "Hello {name}! You have {count} new messages.",
|
34
|
+
mustache: "Hello {{name}}! You have {{count}} new messages.",
|
35
|
+
eco: "Hello <%= @name %>! You have <%= @count %> new messages."
|
36
|
+
},
|
37
|
+
object: {
|
38
|
+
context: { person: { name: "Larry", age: 45 } },
|
39
|
+
handlebars: "{{#with person}}{{name}}{{age}}{{/with}}",
|
40
|
+
dust: "{#person}{name}{age}{/person}",
|
41
|
+
mustache: "{{#person}}{{name}}{{age}}{{/person}}"
|
42
|
+
},
|
43
|
+
array: {
|
44
|
+
context: { names: [{name: "Moe"}, {name: "Larry"}, {name: "Curly"}, {name: "Shemp"}] },
|
45
|
+
handlebars: "{{#each names}}{{name}}{{/each}}",
|
46
|
+
dust: "{#names}{name}{/names}",
|
47
|
+
mustache: "{{#names}}{{name}}{{/names}}",
|
48
|
+
eco: "<% for item in @names: %><%= item.name %><% end %>"
|
49
|
+
},
|
50
|
+
partial: {
|
51
|
+
context: { peeps: [{name: "Moe", count: 15}, {name: "Larry", count: 5}, {name: "Curly", count: 1}] },
|
52
|
+
partials: {
|
53
|
+
mustache: { variables: "Hello {{name}}! You have {{count}} new messages." },
|
54
|
+
handlebars: { variables: "Hello {{name}}! You have {{count}} new messages." }
|
55
|
+
},
|
56
|
+
handlebars: "{{#each peeps}}{{>variables}}{{/each}}",
|
57
|
+
dust: "{#peeps}{>variables/}{/peeps}",
|
58
|
+
mustache: "{{#peeps}}{{>variables}}{{/peeps}}"
|
59
|
+
},
|
60
|
+
recursion: {
|
61
|
+
context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
|
62
|
+
partials: {
|
63
|
+
mustache: { recursion: "{{name}}{{#kids}}{{>recursion}}{{/kids}}" },
|
64
|
+
handlebars: { recursion: "{{name}}{{#each kids}}{{>recursion}}{{/each}}" }
|
65
|
+
},
|
66
|
+
handlebars: "{{name}}{{#each kids}}{{>recursion}}{{/each}}",
|
67
|
+
dust: "{name}{#kids}{>recursion:./}{/kids}",
|
68
|
+
mustache: "{{name}}{{#kids}}{{>recursion}}{{/kids}}"
|
69
|
+
},
|
70
|
+
complex: {
|
71
|
+
handlebars: "<h1>{{header}}</h1>{{#if items}}<ul>{{#each items}}{{#if current}}" +
|
72
|
+
"<li><strong>{{name}}</strong></li>{{^}}" +
|
73
|
+
"<li><a href=\"{{url}}\">{{name}}</a></li>{{/if}}" +
|
74
|
+
"{{/each}}</ul>{{^}}<p>The list is empty.</p>{{/if}}",
|
75
|
+
|
76
|
+
dust: "<h1>{header}</h1>\n" +
|
77
|
+
"{?items}\n" +
|
78
|
+
" <ul>\n" +
|
79
|
+
" {#items}\n" +
|
80
|
+
" {#current}\n" +
|
81
|
+
" <li><strong>{name}</strong></li>\n" +
|
82
|
+
" {:else}\n" +
|
83
|
+
" <li><a href=\"{url}\">{name}</a></li>\n" +
|
84
|
+
" {/current}\n" +
|
85
|
+
" {/items}\n" +
|
86
|
+
" </ul>\n" +
|
87
|
+
"{:else}\n" +
|
88
|
+
" <p>The list is empty.</p>\n" +
|
89
|
+
"{/items}",
|
90
|
+
context: {
|
91
|
+
header: function() {
|
92
|
+
return "Colors";
|
93
|
+
},
|
94
|
+
items: [
|
95
|
+
{name: "red", current: true, url: "#Red"},
|
96
|
+
{name: "green", current: false, url: "#Green"},
|
97
|
+
{name: "blue", current: false, url: "#Blue"}
|
98
|
+
]
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
};
|
103
|
+
|
104
|
+
handlebarsTemplates = {};
|
105
|
+
ecoTemplates = {};
|
106
|
+
|
107
|
+
var warmer = new BenchWarmer();
|
108
|
+
|
109
|
+
var makeSuite = function(name) {
|
110
|
+
warmer.suite(name, function(bench) {
|
111
|
+
var templateName = name;
|
112
|
+
var details = benchDetails[templateName];
|
113
|
+
var mustachePartials = details.partials && details.partials.mustache;
|
114
|
+
var mustacheSource = details.mustache;
|
115
|
+
var context = details.context;
|
116
|
+
|
117
|
+
var error = function() { throw new Error("EWOT"); };
|
118
|
+
|
119
|
+
|
120
|
+
//bench("dust", function() {
|
121
|
+
//dust.render(templateName, context, function(err, out) { });
|
122
|
+
//});
|
123
|
+
|
124
|
+
bench("handlebars", function() {
|
125
|
+
handlebarsTemplates[templateName](context);
|
126
|
+
});
|
127
|
+
|
128
|
+
//if(ecoTemplates[templateName]) {
|
129
|
+
//bench("eco", function() {
|
130
|
+
//ecoTemplates[templateName](context);
|
131
|
+
//});
|
132
|
+
//} else {
|
133
|
+
//bench("eco", error);
|
134
|
+
//}
|
135
|
+
|
136
|
+
//if(mustacheSource) {
|
137
|
+
//bench("mustache", function() {
|
138
|
+
//Mustache.to_html(mustacheSource, context, mustachePartials);
|
139
|
+
//});
|
140
|
+
//} else {
|
141
|
+
//bench("mustache", error);
|
142
|
+
//}
|
143
|
+
});
|
144
|
+
}
|
145
|
+
|
146
|
+
for(var name in benchDetails) {
|
147
|
+
if(benchDetails.hasOwnProperty(name)) {
|
148
|
+
dust.loadSource(dust.compile(benchDetails[name].dust, name));
|
149
|
+
handlebarsTemplates[name] = Handlebars.compile(benchDetails[name].handlebars);
|
150
|
+
|
151
|
+
if(benchDetails[name].eco) { ecoTemplates[name] = eco(benchDetails[name].eco); }
|
152
|
+
|
153
|
+
var partials = benchDetails[name].partials;
|
154
|
+
if(partials) {
|
155
|
+
for(var partialName in partials.handlebars) {
|
156
|
+
if(partials.handlebars.hasOwnProperty(partialName)) {
|
157
|
+
Handlebars.registerPartial(partialName, partials.handlebars[partialName]);
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
makeSuite(name);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
warmer.bench();
|
@@ -0,0 +1,15 @@
|
|
1
|
+
var Handlebars = require("handlebars/base");
|
2
|
+
module.exports = Handlebars;
|
3
|
+
|
4
|
+
require("handlebars/utils");
|
5
|
+
|
6
|
+
require("handlebars/ast");
|
7
|
+
require("handlebars/printer");
|
8
|
+
require("handlebars/visitor");
|
9
|
+
|
10
|
+
require("handlebars/compiler");
|
11
|
+
|
12
|
+
// BEGIN(BROWSER)
|
13
|
+
|
14
|
+
// END(BROWSER)
|
15
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
var Handlebars = require("handlebars");
|
2
|
+
|
3
|
+
// BEGIN(BROWSER)
|
4
|
+
(function() {
|
5
|
+
|
6
|
+
Handlebars.AST = {};
|
7
|
+
|
8
|
+
Handlebars.AST.ProgramNode = function(statements, inverse) {
|
9
|
+
this.type = "program";
|
10
|
+
this.statements = statements;
|
11
|
+
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
|
12
|
+
};
|
13
|
+
|
14
|
+
Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
|
15
|
+
this.type = "mustache";
|
16
|
+
this.id = params[0];
|
17
|
+
this.params = params.slice(1);
|
18
|
+
this.hash = hash;
|
19
|
+
this.escaped = !unescaped;
|
20
|
+
};
|
21
|
+
|
22
|
+
Handlebars.AST.PartialNode = function(id, context) {
|
23
|
+
this.type = "partial";
|
24
|
+
|
25
|
+
// TODO: disallow complex IDs
|
26
|
+
|
27
|
+
this.id = id;
|
28
|
+
this.context = context;
|
29
|
+
};
|
30
|
+
|
31
|
+
var verifyMatch = function(open, close) {
|
32
|
+
if(open.original !== close.original) {
|
33
|
+
throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
|
34
|
+
}
|
35
|
+
};
|
36
|
+
|
37
|
+
Handlebars.AST.BlockNode = function(mustache, program, close) {
|
38
|
+
verifyMatch(mustache.id, close);
|
39
|
+
this.type = "block";
|
40
|
+
this.mustache = mustache;
|
41
|
+
this.program = program;
|
42
|
+
};
|
43
|
+
|
44
|
+
Handlebars.AST.InverseNode = function(mustache, program, close) {
|
45
|
+
verifyMatch(mustache.id, close);
|
46
|
+
this.type = "inverse";
|
47
|
+
this.mustache = mustache;
|
48
|
+
this.program = program;
|
49
|
+
};
|
50
|
+
|
51
|
+
Handlebars.AST.ContentNode = function(string) {
|
52
|
+
this.type = "content";
|
53
|
+
this.string = string;
|
54
|
+
};
|
55
|
+
|
56
|
+
Handlebars.AST.HashNode = function(pairs) {
|
57
|
+
this.type = "hash";
|
58
|
+
this.pairs = pairs;
|
59
|
+
};
|
60
|
+
|
61
|
+
Handlebars.AST.IdNode = function(parts) {
|
62
|
+
this.type = "ID";
|
63
|
+
this.original = parts.join(".");
|
64
|
+
|
65
|
+
var dig = [], depth = 0;
|
66
|
+
|
67
|
+
for(var i=0,l=parts.length; i<l; i++) {
|
68
|
+
var part = parts[i];
|
69
|
+
|
70
|
+
if(part === "..") { depth++; }
|
71
|
+
else if(part === "." || part === "this") { continue; }
|
72
|
+
else { dig.push(part); }
|
73
|
+
}
|
74
|
+
|
75
|
+
this.parts = dig;
|
76
|
+
this.string = dig.join('.');
|
77
|
+
this.depth = depth;
|
78
|
+
this.isSimple = (dig.length === 1) && (depth === 0);
|
79
|
+
};
|
80
|
+
|
81
|
+
Handlebars.AST.StringNode = function(string) {
|
82
|
+
this.type = "STRING";
|
83
|
+
this.string = string;
|
84
|
+
};
|
85
|
+
|
86
|
+
Handlebars.AST.IntegerNode = function(integer) {
|
87
|
+
this.type = "INTEGER";
|
88
|
+
this.integer = integer;
|
89
|
+
};
|
90
|
+
|
91
|
+
Handlebars.AST.BooleanNode = function(bool) {
|
92
|
+
this.type = "BOOLEAN";
|
93
|
+
this.bool = bool;
|
94
|
+
};
|
95
|
+
|
96
|
+
Handlebars.AST.CommentNode = function(comment) {
|
97
|
+
this.type = "comment";
|
98
|
+
this.comment = comment;
|
99
|
+
};
|
100
|
+
|
101
|
+
})();
|
102
|
+
// END(BROWSER)
|
103
|
+
|
@@ -0,0 +1,114 @@
|
|
1
|
+
var handlebars = require("handlebars/parser").parser;
|
2
|
+
|
3
|
+
// BEGIN(BROWSER)
|
4
|
+
var Handlebars = {};
|
5
|
+
|
6
|
+
Handlebars.VERSION = "1.0.beta.2";
|
7
|
+
|
8
|
+
Handlebars.Parser = handlebars;
|
9
|
+
|
10
|
+
Handlebars.parse = function(string) {
|
11
|
+
Handlebars.Parser.yy = Handlebars.AST;
|
12
|
+
return Handlebars.Parser.parse(string);
|
13
|
+
};
|
14
|
+
|
15
|
+
Handlebars.print = function(ast) {
|
16
|
+
return new Handlebars.PrintVisitor().accept(ast);
|
17
|
+
};
|
18
|
+
|
19
|
+
Handlebars.helpers = {};
|
20
|
+
Handlebars.partials = {};
|
21
|
+
|
22
|
+
Handlebars.registerHelper = function(name, fn, inverse) {
|
23
|
+
if(inverse) { fn.not = inverse; }
|
24
|
+
this.helpers[name] = fn;
|
25
|
+
};
|
26
|
+
|
27
|
+
Handlebars.registerPartial = function(name, str) {
|
28
|
+
this.partials[name] = str;
|
29
|
+
};
|
30
|
+
|
31
|
+
Handlebars.registerHelper('helperMissing', function(arg) {
|
32
|
+
if(arguments.length === 2) {
|
33
|
+
return undefined;
|
34
|
+
} else {
|
35
|
+
throw new Error("Could not find property '" + arg + "'");
|
36
|
+
}
|
37
|
+
});
|
38
|
+
|
39
|
+
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
40
|
+
var inverse = options.inverse || function() {}, fn = options.fn;
|
41
|
+
|
42
|
+
|
43
|
+
var ret = "";
|
44
|
+
var type = Object.prototype.toString.call(context);
|
45
|
+
|
46
|
+
if(type === "[object Function]") {
|
47
|
+
context = context();
|
48
|
+
}
|
49
|
+
|
50
|
+
if(context === true) {
|
51
|
+
return fn(this);
|
52
|
+
} else if(context === false || context == null) {
|
53
|
+
return inverse(this);
|
54
|
+
} else if(type === "[object Array]") {
|
55
|
+
if(context.length > 0) {
|
56
|
+
for(var i=0, j=context.length; i<j; i++) {
|
57
|
+
ret = ret + fn(context[i]);
|
58
|
+
}
|
59
|
+
} else {
|
60
|
+
ret = inverse(this);
|
61
|
+
}
|
62
|
+
return ret;
|
63
|
+
} else {
|
64
|
+
return fn(context);
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
Handlebars.registerHelper('each', function(context, options) {
|
69
|
+
var fn = options.fn, inverse = options.inverse;
|
70
|
+
var ret = "";
|
71
|
+
|
72
|
+
if(context && context.length > 0) {
|
73
|
+
for(var i=0, j=context.length; i<j; i++) {
|
74
|
+
ret = ret + fn(context[i]);
|
75
|
+
}
|
76
|
+
} else {
|
77
|
+
ret = inverse(this);
|
78
|
+
}
|
79
|
+
return ret;
|
80
|
+
});
|
81
|
+
|
82
|
+
Handlebars.registerHelper('if', function(context, options) {
|
83
|
+
if(!context || Handlebars.Utils.isEmpty(context)) {
|
84
|
+
return options.inverse(this);
|
85
|
+
} else {
|
86
|
+
return options.fn(this);
|
87
|
+
}
|
88
|
+
});
|
89
|
+
|
90
|
+
Handlebars.registerHelper('unless', function(context, options) {
|
91
|
+
var fn = options.fn, inverse = options.inverse;
|
92
|
+
options.fn = inverse;
|
93
|
+
options.inverse = fn;
|
94
|
+
|
95
|
+
return Handlebars.helpers['if'].call(this, context, options);
|
96
|
+
});
|
97
|
+
|
98
|
+
Handlebars.registerHelper('with', function(context, options) {
|
99
|
+
return options.fn(context);
|
100
|
+
});
|
101
|
+
|
102
|
+
Handlebars.logger = {
|
103
|
+
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
104
|
+
|
105
|
+
// override in the host environment
|
106
|
+
log: function(level, str) {}
|
107
|
+
};
|
108
|
+
|
109
|
+
Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
|
110
|
+
|
111
|
+
// END(BROWSER)
|
112
|
+
|
113
|
+
module.exports = Handlebars;
|
114
|
+
|