exports.attach = function(Handlebars) { // BEGIN(BROWSER) var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; Handlebars.Exception = function(message) { var tmp = Error.prototype.constructor.apply(this, arguments); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (var idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } }; Handlebars.Exception.prototype = new Error(); // Build out our basic SafeString type Handlebars.SafeString = function(string) { this.string = string; }; Handlebars.SafeString.prototype.toString = function() { return this.string.toString(); }; var escape = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'", "`": "`" }; var badChars = /[&<>"'`]/g; var possible = /[&<>"'`]/; var escapeChar = function(chr) { return escape[chr] || "&"; }; Handlebars.Utils = { escapeExpression: function(string) { // don't escape SafeStrings, since they're already safe if (string instanceof Handlebars.SafeString) { return string.toString(); } else if (string == null || string === false) { return ""; } if(!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); }, isEmpty: function(value) { if (!value && value !== 0) { return true; } else if(toString.call(value) === "[object Array]" && value.length === 0) { return true; } else { return false; } } }; // END(BROWSER) return Handlebars; };