UNPKG

8.57 kBJavaScriptView Raw
1// lib/handlebars/base.js
2
3/*jshint eqnull:true*/
4this.Handlebars = {};
5
6(function(Handlebars) {
7
8Handlebars.VERSION = "1.0.0-rc.3";
9Handlebars.COMPILER_REVISION = 2;
10
11Handlebars.REVISION_CHANGES = {
12 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
13 2: '>= 1.0.0-rc.3'
14};
15
16Handlebars.helpers = {};
17Handlebars.partials = {};
18
19Handlebars.registerHelper = function(name, fn, inverse) {
20 if(inverse) { fn.not = inverse; }
21 this.helpers[name] = fn;
22};
23
24Handlebars.registerPartial = function(name, str) {
25 this.partials[name] = str;
26};
27
28Handlebars.registerHelper('helperMissing', function(arg) {
29 if(arguments.length === 2) {
30 return undefined;
31 } else {
32 throw new Error("Could not find property '" + arg + "'");
33 }
34});
35
36var toString = Object.prototype.toString, functionType = "[object Function]";
37
38Handlebars.registerHelper('blockHelperMissing', function(context, options) {
39 var inverse = options.inverse || function() {}, fn = options.fn;
40
41
42 var ret = "";
43 var type = toString.call(context);
44
45 if(type === functionType) { context = context.call(this); }
46
47 if(context === true) {
48 return fn(this);
49 } else if(context === false || context == null) {
50 return inverse(this);
51 } else if(type === "[object Array]") {
52 if(context.length > 0) {
53 return Handlebars.helpers.each(context, options);
54 } else {
55 return inverse(this);
56 }
57 } else {
58 return fn(context);
59 }
60});
61
62Handlebars.K = function() {};
63
64Handlebars.createFrame = Object.create || function(object) {
65 Handlebars.K.prototype = object;
66 var obj = new Handlebars.K();
67 Handlebars.K.prototype = null;
68 return obj;
69};
70
71Handlebars.logger = {
72 DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
73
74 methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
75
76 // can be overridden in the host environment
77 log: function(level, obj) {
78 if (Handlebars.logger.level <= level) {
79 var method = Handlebars.logger.methodMap[level];
80 if (typeof console !== 'undefined' && console[method]) {
81 console[method].call(console, obj);
82 }
83 }
84 }
85};
86
87Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
88
89Handlebars.registerHelper('each', function(context, options) {
90 var fn = options.fn, inverse = options.inverse;
91 var i = 0, ret = "", data;
92
93 if (options.data) {
94 data = Handlebars.createFrame(options.data);
95 }
96
97 if(context && typeof context === 'object') {
98 if(context instanceof Array){
99 for(var j = context.length; i<j; i++) {
100 if (data) { data.index = i; }
101 ret = ret + fn(context[i], { data: data });
102 }
103 } else {
104 for(var key in context) {
105 if(context.hasOwnProperty(key)) {
106 if(data) { data.key = key; }
107 ret = ret + fn(context[key], {data: data});
108 i++;
109 }
110 }
111 }
112 }
113
114 if(i === 0){
115 ret = inverse(this);
116 }
117
118 return ret;
119});
120
121Handlebars.registerHelper('if', function(context, options) {
122 var type = toString.call(context);
123 if(type === functionType) { context = context.call(this); }
124
125 if(!context || Handlebars.Utils.isEmpty(context)) {
126 return options.inverse(this);
127 } else {
128 return options.fn(this);
129 }
130});
131
132Handlebars.registerHelper('unless', function(context, options) {
133 var fn = options.fn, inverse = options.inverse;
134 options.fn = inverse;
135 options.inverse = fn;
136
137 return Handlebars.helpers['if'].call(this, context, options);
138});
139
140Handlebars.registerHelper('with', function(context, options) {
141 return options.fn(context);
142});
143
144Handlebars.registerHelper('log', function(context, options) {
145 var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
146 Handlebars.log(level, context);
147});
148
149}(this.Handlebars));
150;
151// lib/handlebars/utils.js
152
153var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
154
155Handlebars.Exception = function(message) {
156 var tmp = Error.prototype.constructor.apply(this, arguments);
157
158 // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
159 for (var idx = 0; idx < errorProps.length; idx++) {
160 this[errorProps[idx]] = tmp[errorProps[idx]];
161 }
162};
163Handlebars.Exception.prototype = new Error();
164
165// Build out our basic SafeString type
166Handlebars.SafeString = function(string) {
167 this.string = string;
168};
169Handlebars.SafeString.prototype.toString = function() {
170 return this.string.toString();
171};
172
173(function() {
174 var escape = {
175 "&": "&amp;",
176 "<": "&lt;",
177 ">": "&gt;",
178 '"': "&quot;",
179 "'": "&#x27;",
180 "`": "&#x60;"
181 };
182
183 var badChars = /[&<>"'`]/g;
184 var possible = /[&<>"'`]/;
185
186 var escapeChar = function(chr) {
187 return escape[chr] || "&amp;";
188 };
189
190 Handlebars.Utils = {
191 escapeExpression: function(string) {
192 // don't escape SafeStrings, since they're already safe
193 if (string instanceof Handlebars.SafeString) {
194 return string.toString();
195 } else if (string == null || string === false) {
196 return "";
197 }
198
199 if(!possible.test(string)) { return string; }
200 return string.replace(badChars, escapeChar);
201 },
202
203 isEmpty: function(value) {
204 if (!value && value !== 0) {
205 return true;
206 } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
207 return true;
208 } else {
209 return false;
210 }
211 }
212 };
213})();;
214// lib/handlebars/runtime.js
215Handlebars.VM = {
216 template: function(templateSpec) {
217 // Just add water
218 var container = {
219 escapeExpression: Handlebars.Utils.escapeExpression,
220 invokePartial: Handlebars.VM.invokePartial,
221 programs: [],
222 program: function(i, fn, data) {
223 var programWrapper = this.programs[i];
224 if(data) {
225 return Handlebars.VM.program(fn, data);
226 } else if(programWrapper) {
227 return programWrapper;
228 } else {
229 programWrapper = this.programs[i] = Handlebars.VM.program(fn);
230 return programWrapper;
231 }
232 },
233 programWithDepth: Handlebars.VM.programWithDepth,
234 noop: Handlebars.VM.noop,
235 compilerInfo: null
236 };
237
238 return function(context, options) {
239 options = options || {};
240 var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
241
242 var compilerInfo = container.compilerInfo || [],
243 compilerRevision = compilerInfo[0] || 1,
244 currentRevision = Handlebars.COMPILER_REVISION;
245
246 if (compilerRevision !== currentRevision) {
247 if (compilerRevision < currentRevision) {
248 var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
249 compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
250 throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
251 "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
252 } else {
253 // Use the embedded version info since the runtime doesn't know about this revision yet
254 throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
255 "Please update your runtime to a newer version ("+compilerInfo[1]+").";
256 }
257 }
258
259 return result;
260 };
261 },
262
263 programWithDepth: function(fn, data, $depth) {
264 var args = Array.prototype.slice.call(arguments, 2);
265
266 return function(context, options) {
267 options = options || {};
268
269 return fn.apply(this, [context, options.data || data].concat(args));
270 };
271 },
272 program: function(fn, data) {
273 return function(context, options) {
274 options = options || {};
275
276 return fn(context, options.data || data);
277 };
278 },
279 noop: function() { return ""; },
280 invokePartial: function(partial, name, context, helpers, partials, data) {
281 var options = { helpers: helpers, partials: partials, data: data };
282
283 if(partial === undefined) {
284 throw new Handlebars.Exception("The partial " + name + " could not be found");
285 } else if(partial instanceof Function) {
286 return partial(context, options);
287 } else if (!Handlebars.compile) {
288 throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
289 } else {
290 partials[name] = Handlebars.compile(partial, {data: data !== undefined});
291 return partials[name](context, options);
292 }
293 }
294};
295
296Handlebars.template = Handlebars.VM.template;
297;
\No newline at end of file