summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Katz <wycats@gmail.com>2013-07-01 13:59:58 -0700
committerYehuda Katz <wycats@gmail.com>2013-07-01 13:59:58 -0700
commit88ee4757e77f97afb206132eddb64e688700eb37 (patch)
tree08f7db62a3151dfbd44bfd6f1ec4ec6737a2bdb6
parent8e2416dabb2056c07357a55b9259322f0d794ada (diff)
downloadhandlebars.js-88ee4757e77f97afb206132eddb64e688700eb37.zip
handlebars.js-88ee4757e77f97afb206132eddb64e688700eb37.tar.gz
handlebars.js-88ee4757e77f97afb206132eddb64e688700eb37.tar.bz2
Initial work on ES6 modules
-rw-r--r--Gruntfile.js51
-rw-r--r--configurations/browser.js6
-rw-r--r--configurations/concat.js16
-rw-r--r--configurations/connect.js8
-rw-r--r--configurations/transpile.js25
-rw-r--r--configurations/watch.js4
-rw-r--r--lib/handlebars.js22
-rw-r--r--lib/handlebars/base.js246
-rw-r--r--lib/handlebars/compiler/ast.js39
-rw-r--r--lib/handlebars/compiler/base.js25
-rw-r--r--lib/handlebars/compiler/compiler.js46
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js24
-rw-r--r--lib/handlebars/runtime.js202
-rw-r--r--lib/handlebars/utils.js83
-rw-r--r--package.json54
15 files changed, 452 insertions, 399 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..56231b7
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,51 @@
+function config(name) {
+ return require('./configurations/' + name);
+}
+
+module.exports = function(grunt) {
+
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+
+ clean: ["dist"],
+ watch: config('watch') ,
+ concat: config('concat'),
+ browser: config('browser'),
+ connect: config('connect'),
+ transpile: config('transpile')
+ });
+
+ // By default, (i.e., if you invoke `grunt` without arguments), do
+ // a new build.
+ this.registerTask('default', ['build']);
+
+ // Build a new version of the library
+ this.registerTask('build', "Builds a distributable version of the current project", [
+ 'clean',
+ 'transpile:amd',
+ 'concat:library',
+ 'concat:browser',
+ 'browser:dist',
+ 'bytes']);
+
+ this.registerTask('tests', "Builds the test package", [
+ 'build',
+ 'concat:deps',
+ 'transpile:tests']);
+
+ // Run a server. This is ideal for running the QUnit tests in the browser.
+ this.registerTask('server', [
+ 'build',
+ 'tests',
+ 'connect',
+ 'watch']);
+
+ // Load tasks from npm
+ grunt.loadNpmTasks('grunt-contrib-clean');
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-connect');
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.loadNpmTasks('grunt-es6-module-transpiler');
+
+ grunt.task.loadTasks('tasks');
+};
diff --git a/configurations/browser.js b/configurations/browser.js
new file mode 100644
index 0000000..e3d0dc3
--- /dev/null
+++ b/configurations/browser.js
@@ -0,0 +1,6 @@
+module.exports = {
+ dist: {
+ src: 'tmp/<%= pkg.barename %>.browser1.js',
+ dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
+ }
+};
diff --git a/configurations/concat.js b/configurations/concat.js
new file mode 100644
index 0000000..4111eee
--- /dev/null
+++ b/configurations/concat.js
@@ -0,0 +1,16 @@
+module.exports = {
+ library: {
+ src: ['tmp/<%= pkg.barename %>.amd.js'],
+ dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.amd.js'
+ },
+
+ deps: {
+ src: ['vendor/deps/*.js'],
+ dest: 'tmp/deps.amd.js'
+ },
+
+ browser: {
+ src: ['vendor/loader.js', 'tmp/<%= pkg.barename %>.amd.js'],
+ dest: 'tmp/<%= pkg.barename %>.browser1.js'
+ }
+};
diff --git a/configurations/connect.js b/configurations/connect.js
new file mode 100644
index 0000000..dacc760
--- /dev/null
+++ b/configurations/connect.js
@@ -0,0 +1,8 @@
+module.exports = {
+ server: {},
+ options: {
+ hostname: '0.0.0.0',
+ port: 8000,
+ base: '.'
+ }
+};
diff --git a/configurations/transpile.js b/configurations/transpile.js
new file mode 100644
index 0000000..e912ecf
--- /dev/null
+++ b/configurations/transpile.js
@@ -0,0 +1,25 @@
+module.exports = {
+ amd: {
+ type: 'amd',
+ src: ["lib/<%= pkg.barename %>.js", "lib/*/**/*.js"],
+ dest: "tmp/<%= pkg.barename %>.amd.js"
+ },
+
+ cjs: {
+ type: 'cjs',
+ src: ["lib/<%= pkg.barename %>.js", "lib/*/**/*.js"],
+ dest: "tmp/<%= pkg.barename %>.cjs.js"
+ },
+
+ globals: {
+ type: 'globals',
+ src: ["lib/<%= pkg.barename %>.js", "lib/*/**/*.js"],
+ dest: "tmp/<%= pkg.barename %>.globals.js"
+ },
+
+ tests: {
+ type: 'amd',
+ src: ['test/test_helpers.js', 'test/tests.js', 'test/tests/**/*_test.js'],
+ dest: 'tmp/tests.amd.js'
+ }
+};
diff --git a/configurations/watch.js b/configurations/watch.js
new file mode 100644
index 0000000..49b1c49
--- /dev/null
+++ b/configurations/watch.js
@@ -0,0 +1,4 @@
+module.exports = {
+ files: ['lib/**', 'vendor/*', 'test/**/*'],
+ tasks: ['build', 'tests']
+};
diff --git a/lib/handlebars.js b/lib/handlebars.js
index f82ec3b..e051aa5 100644
--- a/lib/handlebars.js
+++ b/lib/handlebars.js
@@ -1,15 +1,19 @@
-var handlebars = require("./handlebars/base"),
+import handlebars from "handlebars/base";
// Each of these augment the Handlebars object. No need to setup here.
// (This is done to easily share code between commonjs and browse envs)
- utils = require("./handlebars/utils"),
- compiler = require("./handlebars/compiler"),
- runtime = require("./handlebars/runtime");
+import { SafeString, Exception, extend, escapeExpression, isEmpty } from "handlebars/utils";
+import compiler from "handlebars/compiler";
+import runtime from "handlebars/runtime";
+// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function() {
var hb = handlebars.create();
- utils.attach(hb);
+ hb.SafeString = SafeString;
+ hb.Exception = Exception;
+ hb.utils = { extend: extend, escapeExpression: escapeExpression, isEmpty: isEmpty };
+
compiler.attach(hb);
runtime.attach(hb);
@@ -19,10 +23,10 @@ var create = function() {
var Handlebars = create();
Handlebars.create = create;
-module.exports = Handlebars; // instantiate an instance
+export default Handlebars;
// Publish a Node.js require() handler for .handlebars and .hbs files
-if (require.extensions) {
+if (typeof require !== 'undefined' && require.extensions) {
var extension = function(module, filename) {
var fs = require("fs");
var templateString = fs.readFileSync(filename, "utf8");
@@ -32,10 +36,6 @@ if (require.extensions) {
require.extensions[".hbs"] = extension;
}
-// BEGIN(BROWSER)
-
-// END(BROWSER)
-
// USAGE:
// var handlebars = require('handlebars');
diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js
index 44a369c..9849678 100644
--- a/lib/handlebars/base.js
+++ b/lib/handlebars/base.js
@@ -1,166 +1,168 @@
/*jshint eqnull: true */
-module.exports.create = function() {
+import { Exception, extend } from "handlebars/utils";
-var Handlebars = {};
+var K = function() { return this; };
-// BEGIN(BROWSER)
+export VERSION = "1.0.0";
+export COMPILER_REVISION = 4;
-Handlebars.VERSION = "1.0.0";
-Handlebars.COMPILER_REVISION = 4;
-
-Handlebars.REVISION_CHANGES = {
+export REVISION_CHANGES = {
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
2: '== 1.0.0-rc.3',
3: '== 1.0.0-rc.4',
4: '>= 1.0.0'
};
-Handlebars.helpers = {};
-Handlebars.partials = {};
+// TODO: Make this a class
+export default function(helpers, partials) {
-var toString = Object.prototype.toString,
- functionType = '[object Function]',
- objectType = '[object Object]';
+ var exports = {};
-Handlebars.registerHelper = function(name, fn, inverse) {
- if (toString.call(name) === objectType) {
- if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
- Handlebars.Utils.extend(this.helpers, name);
- } else {
- if (inverse) { fn.not = inverse; }
- this.helpers[name] = fn;
- }
-};
-Handlebars.registerPartial = function(name, str) {
- if (toString.call(name) === objectType) {
- Handlebars.Utils.extend(this.partials, name);
- } else {
- this.partials[name] = str;
- }
-};
-
-Handlebars.registerHelper('helperMissing', function(arg) {
- if(arguments.length === 2) {
- return undefined;
- } else {
- throw new Error("Missing helper: '" + arg + "'");
- }
-});
+ helpers = helpers || {};
+ partials = partials || {};
-Handlebars.registerHelper('blockHelperMissing', function(context, options) {
- var inverse = options.inverse || function() {}, fn = options.fn;
+ var toString = Object.prototype.toString,
+ functionType = '[object Function]',
+ objectType = '[object Object]';
- var type = toString.call(context);
+ exports.registerHelper(name, fn, inverse) {
+ if (toString.call(name) === objectType) {
+ if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
+ extend(helpers, name);
+ } else {
+ if (inverse) { fn.not = inverse; }
+ helpers[name] = fn;
+ }
+ };
- if(type === functionType) { context = context.call(this); }
+ exports.registerPartial(name, str) {
+ if (toString.call(name) === objectType) {
+ extend(partials, name);
+ } else {
+ partials[name] = str;
+ }
+ };
- if(context === true) {
- return fn(this);
- } else if(context === false || context == null) {
- return inverse(this);
- } else if(type === "[object Array]") {
- if(context.length > 0) {
- return Handlebars.helpers.each(context, options);
+ exports.registerHelper('helperMissing', function(arg) {
+ if(arguments.length === 2) {
+ return undefined;
} else {
- return inverse(this);
+ throw new Error("Missing helper: '" + arg + "'");
}
- } else {
- return fn(context);
- }
-});
+ });
-Handlebars.K = function() {};
+ exports.registerHelper('blockHelperMissing', function(context, options) {
+ var inverse = options.inverse || function() {}, fn = options.fn;
-Handlebars.createFrame = Object.create || function(object) {
- Handlebars.K.prototype = object;
- var obj = new Handlebars.K();
- Handlebars.K.prototype = null;
- return obj;
-};
-
-Handlebars.logger = {
- DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
+ var type = toString.call(context);
- methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
+ if(type === functionType) { context = context.call(this); }
- // can be overridden in the host environment
- log: function(level, obj) {
- if (Handlebars.logger.level <= level) {
- var method = Handlebars.logger.methodMap[level];
- if (typeof console !== 'undefined' && console[method]) {
- console[method].call(console, obj);
+ if(context === true) {
+ return fn(this);
+ } else if(context === false || context == null) {
+ return inverse(this);
+ } else if(type === "[object Array]") {
+ if(context.length > 0) {
+ return Handlebars.helpers.each(context, options);
+ } else {
+ return inverse(this);
}
+ } else {
+ return fn(context);
}
- }
-};
-
-Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
+ });
-Handlebars.registerHelper('each', function(context, options) {
- var fn = options.fn, inverse = options.inverse;
- var i = 0, ret = "", data;
+ exports.registerHelper('each', function(context, options) {
+ var fn = options.fn, inverse = options.inverse;
+ var i = 0, ret = "", data;
- var type = toString.call(context);
- if(type === functionType) { context = context.call(this); }
+ var type = toString.call(context);
+ if(type === functionType) { context = context.call(this); }
- if (options.data) {
- data = Handlebars.createFrame(options.data);
- }
+ if (options.data) {
+ data = Handlebars.createFrame(options.data);
+ }
- if(context && typeof context === 'object') {
- if(context instanceof Array){
- for(var j = context.length; i<j; i++) {
- if (data) { data.index = i; }
- ret = ret + fn(context[i], { data: data });
- }
- } else {
- for(var key in context) {
- if(context.hasOwnProperty(key)) {
- if(data) { data.key = key; }
- ret = ret + fn(context[key], {data: data});
- i++;
+ if(context && typeof context === 'object') {
+ if(context instanceof Array){
+ for(var j = context.length; i<j; i++) {
+ if (data) { data.index = i; }
+ ret = ret + fn(context[i], { data: data });
+ }
+ } else {
+ for(var key in context) {
+ if(context.hasOwnProperty(key)) {
+ if(data) { data.key = key; }
+ ret = ret + fn(context[key], {data: data});
+ i++;
+ }
}
}
}
- }
- if(i === 0){
- ret = inverse(this);
- }
+ if(i === 0){
+ ret = inverse(this);
+ }
- return ret;
-});
+ return ret;
+ });
-Handlebars.registerHelper('if', function(conditional, options) {
- var type = toString.call(conditional);
- if(type === functionType) { conditional = conditional.call(this); }
+ exports.registerHelper('if', function(conditional, options) {
+ var type = toString.call(conditional);
+ if(type === functionType) { conditional = conditional.call(this); }
- if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
- return options.inverse(this);
- } else {
- return options.fn(this);
- }
-});
+ if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
+ return options.inverse(this);
+ } else {
+ return options.fn(this);
+ }
+ });
+
+ exports.registerHelper('unless', function(conditional, options) {
+ return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
+ });
+
+ exports.registerHelper('with', function(context, options) {
+ var type = toString.call(context);
+ if(type === functionType) { context = context.call(this); }
-Handlebars.registerHelper('unless', function(conditional, options) {
- return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
-});
+ if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
+ });
-Handlebars.registerHelper('with', function(context, options) {
- var type = toString.call(context);
- if(type === functionType) { context = context.call(this); }
+ exports.registerHelper('log', function(context, options) {
+ var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
+ Handlebars.log(level, context);
+ });
- if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
-});
+ return Handlebars;
+}
-Handlebars.registerHelper('log', function(context, options) {
- var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
- Handlebars.log(level, context);
-});
+var levels = {
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3
+}
-// END(BROWSER)
+var methodMap = { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' };
-return Handlebars;
+export logger = {
+ // can be overridden in the host environment
+ log: function(level, obj) {
+ if (Handlebars.logger.level <= level) {
+ var method = Handlebars.logger.methodMap[level];
+ if (typeof console !== 'undefined' && console[method]) {
+ console[method].call(console, obj);
+ }
+ }
+ }
+};
+
+export function log(level, obj) { logger.log(level, obj); };
+
+export createFrame = Object.create || function(object) {
+ K.prototype = object;
+ var obj = new K();
+ K.prototype = null;
+ return obj;
};
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 567e297..fcf5c6e 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -1,15 +1,12 @@
-exports.attach = function(Handlebars) {
+import { Exception } from "handlebars/utils";
-// BEGIN(BROWSER)
-Handlebars.AST = {};
-
-Handlebars.AST.ProgramNode = function(statements, inverse) {
+export function ProgramNode(statements, inverse) {
this.type = "program";
this.statements = statements;
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
};
-Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
+export function MustacheNode(rawParams, hash, unescaped) {
this.type = "mustache";
this.escaped = !unescaped;
this.hash = hash;
@@ -31,15 +28,15 @@ Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
// pass or at runtime.
};
-Handlebars.AST.PartialNode = function(partialName, context) {
+export function PartialNode(partialName, context) {
this.type = "partial";
this.partialName = partialName;
this.context = context;
};
-Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
+export function BlockNode(mustache, program, inverse, close) {
if(mustache.id.original !== close.original) {
- throw new Handlebars.Exception(mustache.id.original + " doesn't match " + close.original);
+ throw new Exception(mustache.id.original + " doesn't match " + close.original);
}
this.type = "block";
@@ -52,17 +49,17 @@ Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
}
};
-Handlebars.AST.ContentNode = function(string) {
+export function ContentNode(string) {
this.type = "content";
this.string = string;
};
-Handlebars.AST.HashNode = function(pairs) {
+export function HashNode(pairs) {
this.type = "hash";
this.pairs = pairs;
};
-Handlebars.AST.IdNode = function(parts) {
+export function IdNode(part) {
this.type = "ID";
var original = "",
@@ -93,43 +90,37 @@ Handlebars.AST.IdNode = function(parts) {
this.stringModeValue = this.string;
};
-Handlebars.AST.PartialNameNode = function(name) {
+export function PartialNameNode(name) {
this.type = "PARTIAL_NAME";
this.name = name.original;
};
-Handlebars.AST.DataNode = function(id) {
+export function DataNode(id) {
this.type = "DATA";
this.id = id;
};
-Handlebars.AST.StringNode = function(string) {
+export function StringNode(string) {
this.type = "STRING";
this.original =
this.string =
this.stringModeValue = string;
};
-Handlebars.AST.IntegerNode = function(integer) {
+export function IntegerNode(integer) {
this.type = "INTEGER";
this.original =
this.integer = integer;
this.stringModeValue = Number(integer);
};
-Handlebars.AST.BooleanNode = function(bool) {
+export function BooleanNode(bool) {
this.type = "BOOLEAN";
this.bool = bool;
this.stringModeValue = bool === "true";
};
-Handlebars.AST.CommentNode = function(comment) {
+export function CommentNode(comment) {
this.type = "comment";
this.comment = comment;
};
-
-// END(BROWSER)
-
-return Handlebars;
-};
-
diff --git a/lib/handlebars/compiler/base.js b/lib/handlebars/compiler/base.js
index 7594451..525cd5b 100644
--- a/lib/handlebars/compiler/base.js
+++ b/lib/handlebars/compiler/base.js
@@ -1,21 +1,12 @@
-var handlebars = require("./parser");
+import { parser } from "handlebars/compiler/parser";
+module AST from "handlebars/compiler/ast":
-exports.attach = function(Handlebars) {
-
-// BEGIN(BROWSER)
-
-Handlebars.Parser = handlebars;
-
-Handlebars.parse = function(input) {
+export Parser = parser;
+export function(input) {
// Just return if an already-compile AST was passed in.
- if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
-
- Handlebars.Parser.yy = Handlebars.AST;
- return Handlebars.Parser.parse(input);
-};
-
-// END(BROWSER)
+ if(input.constructor === AST.ProgramNode) { return input; }
-return Handlebars;
-};
+ parser.yy = AST;
+ return parser.parse(input);
+}
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index 98e12b1..a21ccc0 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -1,13 +1,11 @@
-var compilerbase = require("./base");
-
-exports.attach = function(Handlebars) {
-
-compilerbase.attach(Handlebars);
-
-// BEGIN(BROWSER)
+import { Exception } from "handlebars/utils";
+import parse from "handlebars/compiler/base";
+import { template } from "handlebars/runtime";
/*jshint eqnull:true*/
-var Compiler = Handlebars.Compiler = function() {};
+
+var Compiler = function() {};
+export default Compiler;
// the foundHelper register will disambiguate helper lookup from finding a
// function in a context. This is necessary for mustache compatibility, which
@@ -40,6 +38,7 @@ Compiler.prototype = {
return out.join("\n");
},
+
equals: function(other) {
var len = this.opcodes.length;
if (other.opcodes.length !== len) {
@@ -301,7 +300,7 @@ Compiler.prototype = {
DATA: function(data) {
this.options.data = true;
if (data.id.isScoped || data.id.depth) {
- throw new Handlebars.Exception('Scoped data references are not supported: ' + data.original);
+ throw new Exception('Scoped data references are not supported: ' + data.original);
}
this.opcode('lookupData');
@@ -415,35 +414,39 @@ Compiler.prototype = {
}
};
-Handlebars.precompile = function(input, options) {
+export function precompile(input, options) {
if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
- throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
}
options = options || {};
if (!('data' in options)) {
options.data = true;
}
- var ast = Handlebars.parse(input);
+
+ var ast = parse(input);
var environment = new Compiler().compile(ast, options);
- return new Handlebars.JavaScriptCompiler().compile(environment, options);
+ return new JavaScriptCompiler().compile(environment, options);
};
-Handlebars.compile = function(input, options) {
+export function compile = function(input, options) {
if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
- throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
+ throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
}
options = options || {};
+
if (!('data' in options)) {
options.data = true;
}
+
var compiled;
+
function compile() {
- var ast = Handlebars.parse(input);
+ var ast = parse(input);
var environment = new Compiler().compile(ast, options);
- var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
- return Handlebars.template(templateSpec);
+ var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
+ return template(templateSpec);
}
// Template is only compiled on first use and cached after that point.
@@ -454,10 +457,3 @@ Handlebars.compile = function(input, options) {
return compiled.call(this, context, options);
};
};
-
-
-// END(BROWSER)
-
-return Handlebars;
-
-};
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 4548c6a..49660ff 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -1,18 +1,12 @@
-var compilerbase = require("./base");
+import { COMPILER_REVISION, REVISION_CHANGES } from "handlebars/base";
-exports.attach = function(Handlebars) {
-
-compilerbase.attach(Handlebars);
-
-// BEGIN(BROWSER)
-/*jshint eqnull:true*/
-
-var Literal = function(value) {
+function Literal(value) {
this.value = value;
};
-var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {};
+function JavaScriptCompiler() {};
+export default JavaScriptCompiler;
JavaScriptCompiler.prototype = {
// PUBLIC API: You can override these methods in a subclass to provide
@@ -162,8 +156,8 @@ JavaScriptCompiler.prototype = {
var source = this.mergeSource();
if (!this.isChild) {
- var revision = Handlebars.COMPILER_REVISION,
- versions = Handlebars.REVISION_CHANGES[revision];
+ var revision = COMPILER_REVISION,
+ versions = REVISION_CHANGES[revision];
source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
}
@@ -848,9 +842,3 @@ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
}
return false;
};
-
-// END(BROWSER)
-
-return Handlebars;
-
-};
diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js
index 2e845c4..2585ef3 100644
--- a/lib/handlebars/runtime.js
+++ b/lib/handlebars/runtime.js
@@ -1,106 +1,102 @@
-exports.attach = function(Handlebars) {
-
-// BEGIN(BROWSER)
-
-Handlebars.VM = {
- template: function(templateSpec) {
- // Just add water
- var container = {
- escapeExpression: Handlebars.Utils.escapeExpression,
- invokePartial: Handlebars.VM.invokePartial,
- programs: [],
- program: function(i, fn, data) {
- var programWrapper = this.programs[i];
- if(data) {
- programWrapper = Handlebars.VM.program(i, fn, data);
- } else if (!programWrapper) {
- programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
- }
- return programWrapper;
- },
- merge: function(param, common) {
- var ret = param || common;
-
- if (param && common) {
- ret = {};
- Handlebars.Utils.extend(ret, common);
- Handlebars.Utils.extend(ret, param);
- }
- return ret;
- },
- programWithDepth: Handlebars.VM.programWithDepth,
- noop: Handlebars.VM.noop,
- compilerInfo: null
- };
-
- return function(context, options) {
- options = options || {};
- var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
-
- var compilerInfo = container.compilerInfo || [],
- compilerRevision = compilerInfo[0] || 1,
- currentRevision = Handlebars.COMPILER_REVISION;
-
- if (compilerRevision !== currentRevision) {
- if (compilerRevision < currentRevision) {
- var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
- compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
- throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
- "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
- } else {
- // Use the embedded version info since the runtime doesn't know about this revision yet
- throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
- "Please update your runtime to a newer version ("+compilerInfo[1]+").";
- }
+import { escapeExpression, extend, Exceptions } from "handlebars/utils";
+import { COMPILER_REVISION, REVISION_CHANGES } from "handlebars/base";
+
+// TODO: Deal with the fact that compile is necessary for on-the-fly partial
+// compilation but won't be present for precompiled templates.
+
+export function template(templateSpec) {
+ // Just add water
+ var container = {
+ escapeExpression: escapeExpression,
+ invokePartial: invokePartial,
+ programs: [],
+ program: function(i, fn, data) {
+ var programWrapper = this.programs[i];
+ if(data) {
+ programWrapper = program(i, fn, data);
+ } else if (!programWrapper) {
+ programWrapper = this.programs[i] = program(i, fn);
+ }
+ return programWrapper;
+ },
+ merge: function(param, common) {
+ var ret = param || common;
+
+ if (param && common) {
+ ret = {};
+ extend(ret, common);
+ extend(ret, param);
+ }
+ return ret;
+ },
+ programWithDepth: programWithDepth,
+ noop: noop,
+ compilerInfo: null
+ };
+
+ return function(context, options) {
+ options = options || {};
+ // TODO: Why does templateSpec require a reference to the global Handlebars?
+ var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
+
+ var compilerInfo = container.compilerInfo || [],
+ compilerRevision = compilerInfo[0] || 1,
+ currentRevision = COMPILER_REVISION;
+
+ if (compilerRevision !== currentRevision) {
+ if (compilerRevision < currentRevision) {
+ var runtimeVersions = REVISION_CHANGES[currentRevision],
+ compilerVersions = REVISION_CHANGES[compilerRevision];
+ throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
+ "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
+ } else {
+ // Use the embedded version info since the runtime doesn't know about this revision yet
+ throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
+ "Please update your runtime to a newer version ("+compilerInfo[1]+").";
}
-
- return result;
- };
- },
-
- programWithDepth: function(i, fn, data /*, $depth */) {
- var args = Array.prototype.slice.call(arguments, 3);
-
- var program = function(context, options) {
- options = options || {};
-
- return fn.apply(this, [context, options.data || data].concat(args));
- };
- program.program = i;
- program.depth = args.length;
- return program;
- },
- program: function(i, fn, data) {
- var program = function(context, options) {
- options = options || {};
-
- return fn(context, options.data || data);
- };
- program.program = i;
- program.depth = 0;
- return program;
- },
- noop: function() { return ""; },
- invokePartial: function(partial, name, context, helpers, partials, data) {
- var options = { helpers: helpers, partials: partials, data: data };
-
- if(partial === undefined) {
- throw new Handlebars.Exception("The partial " + name + " could not be found");
- } else if(partial instanceof Function) {
- return partial(context, options);
- } else if (!Handlebars.compile) {
- throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
- } else {
- partials[name] = Handlebars.compile(partial, {data: data !== undefined});
- return partials[name](context, options);
}
- }
-};
-Handlebars.template = Handlebars.VM.template;
-
-// END(BROWSER)
-
-return Handlebars;
-
-};
+ return result;
+ };
+}
+
+export function programWithDepth(i, fn, data /*, $depth */) {
+ var args = Array.prototype.slice.call(arguments, 3);
+
+ var program = function(context, options) {
+ options = options || {};
+
+ return fn.apply(this, [context, options.data || data].concat(args));
+ };
+ program.program = i;
+ program.depth = args.length;
+ return program;
+}
+
+export function program(i, fn, data) {
+ var program = function(context, options) {
+ options = options || {};
+
+ return fn(context, options.data || data);
+ };
+ program.program = i;
+ program.depth = 0;
+ return program;
+}
+
+export function noop() { return ""; }
+
+export function invokePartial(partial, name, context, helpers, partials, data) {
+ var options = { helpers: helpers, partials: partials, data: data };
+
+ if(partial === undefined) {
+ throw new Exception("The partial " + name + " could not be found");
+ } else if(partial instanceof Function) {
+ return partial(context, options);
+ } else if (!compile) {
+ throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
+ } else {
+ partials[name] = compile(partial, {data: data !== undefined});
+ return partials[name](context, options);
+ }
+}
diff --git a/lib/handlebars/utils.js b/lib/handlebars/utils.js
index 1e0e4c9..d14795c 100644
--- a/lib/handlebars/utils.js
+++ b/lib/handlebars/utils.js
@@ -1,12 +1,8 @@
-exports.attach = function(Handlebars) {
-
var toString = Object.prototype.toString;
-// BEGIN(BROWSER)
-
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
-Handlebars.Exception = function(message) {
+export function Exception(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.
@@ -14,13 +10,15 @@ Handlebars.Exception = function(message) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
};
-Handlebars.Exception.prototype = new Error();
+
+Exception.prototype = new Error();
// Build out our basic SafeString type
-Handlebars.SafeString = function(string) {
+export function SafeString(string) {
this.string = string;
};
-Handlebars.SafeString.prototype.toString = function() {
+
+SafeString.prototype.toString = function() {
return this.string.toString();
};
@@ -40,44 +38,37 @@ var escapeChar = function(chr) {
return escape[chr] || "&amp;";
};
-Handlebars.Utils = {
- extend: function(obj, value) {
- for(var key in value) {
- if(value.hasOwnProperty(key)) {
- obj[key] = value[key];
- }
- }
- },
-
- 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 "";
- }
-
- // Force a string conversion as this will be done by the append regardless and
- // the regex test will do this transparently behind the scenes, causing issues if
- // an object's to string has escaped characters in it.
- string = string.toString();
-
- 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;
+export function extend(obj, value) {
+ for(var key in value) {
+ if(value.hasOwnProperty(key)) {
+ obj[key] = value[key];
}
}
-};
-
-// END(BROWSER)
+}
+
+export function escapeExpression(string) {
+ // don't escape SafeStrings, since they're already safe
+ if (string instanceof SafeString) {
+ return string.toString();
+ } else if (string == null || string === false) {
+ return "";
+ }
-return Handlebars;
-};
+ // Force a string conversion as this will be done by the append regardless and
+ // the regex test will do this transparently behind the scenes, causing issues if
+ // an object's to string has escaped characters in it.
+ string = string.toString();
+
+ if(!possible.test(string)) { return string; }
+ return string.replace(badChars, escapeChar);
+}
+
+export function isEmpty(value) {
+ if (!value && value !== 0) {
+ return true;
+ } else if(toString.call(value) === "[object Array]" && value.length === 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/package.json b/package.json
index 13fdc74..024ba0a 100644
--- a/package.json
+++ b/package.json
@@ -1,39 +1,27 @@
{
- "name": "handlebars",
- "description": "Extension of the Mustache logicless template language",
- "version": "1.0.12",
- "homepage": "http://www.handlebarsjs.com/",
- "keywords": [
- "handlebars",
- "mustache",
- "template",
- "html"
- ],
+ "name": "handlebars.js",
+ "barename": "handlebars",
+ "version": "1.1.0",
+ "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
"repository": {
"type": "git",
- "url": "git://github.com/wycats/handlebars.js.git"
- },
- "engines": {
- "node": ">=0.4.7"
- },
- "dependencies": {
- "optimist": "~0.3",
- "uglify-js": "~2.3"
+ "url": "https://github.com/wycats/handlebars.js.git"
},
+ "author": "Yehuda Katz",
+ "license": "BSD",
+ "readmeFilename": "README.md",
"devDependencies": {
- "benchmark": "~1.0",
- "dust": "~0.3",
- "jison": "~0.3",
- "mocha": "*",
- "mustache": "~0.7.2",
- "should": "~1.2.2"
- },
- "main": "lib/handlebars.js",
- "bin": {
- "handlebars": "bin/handlebars"
- },
- "scripts": {
- "test": "node ./spec/env/runner"
- },
- "optionalDependencies": {}
+ "grunt": "~0.4.1",
+ "connect": "~2.7.4",
+ "grunt-contrib-concat": "~0.3.0",
+ "grunt-contrib-clean": "~0.4.1",
+ "grunt-contrib-connect": "~0.3.0",
+ "grunt-contrib-watch": "~0.4.4",
+ "grunt-hang": "~0.1.2",
+ "grunt-es6-module-transpiler": "~0.3.0"
+ }
}