hbs_plus 0.1.3

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