Initial work on ES6 modules

This commit is contained in:
Yehuda Katz
2013-07-01 13:59:58 -07:00
parent 8e2416dabb
commit 88ee4757e7
15 changed files with 453 additions and 400 deletions
+51
View File
@@ -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');
};
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
dist: {
src: 'tmp/<%= pkg.barename %>.browser1.js',
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
}
};
+16
View File
@@ -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'
}
};
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
server: {},
options: {
hostname: '0.0.0.0',
port: 8000,
base: '.'
}
};
+25
View File
@@ -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'
}
};
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
files: ['lib/**', 'vendor/*', 'test/**/*'],
tasks: ['build', 'tests']
};
+11 -11
View File
@@ -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');
+132 -130
View File
@@ -1,90 +1,152 @@
/*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;
}
};
helpers = helpers || {};
partials = partials || {};
Handlebars.registerHelper('helperMissing', function(arg) {
if(arguments.length === 2) {
return undefined;
} else {
throw new Error("Missing helper: '" + arg + "'");
}
});
var toString = Object.prototype.toString,
functionType = '[object Function]',
objectType = '[object Object]';
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
var inverse = options.inverse || function() {}, fn = options.fn;
var type = toString.call(context);
if(type === functionType) { context = context.call(this); }
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(name, fn, inverse) {
if (toString.call(name) === objectType) {
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
extend(helpers, name);
} else {
return inverse(this);
if (inverse) { fn.not = inverse; }
helpers[name] = fn;
}
} else {
return fn(context);
}
});
};
Handlebars.K = function() {};
exports.registerPartial(name, str) {
if (toString.call(name) === objectType) {
extend(partials, name);
} else {
partials[name] = str;
}
};
Handlebars.createFrame = Object.create || function(object) {
Handlebars.K.prototype = object;
var obj = new Handlebars.K();
Handlebars.K.prototype = null;
return obj;
};
exports.registerHelper('helperMissing', function(arg) {
if(arguments.length === 2) {
return undefined;
} else {
throw new Error("Missing helper: '" + arg + "'");
}
});
Handlebars.logger = {
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
exports.registerHelper('blockHelperMissing', function(context, options) {
var inverse = options.inverse || function() {}, fn = options.fn;
methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
var type = toString.call(context);
if(type === functionType) { context = context.call(this); }
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);
}
});
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); }
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(i === 0){
ret = inverse(this);
}
return ret;
});
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);
}
});
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); }
if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
});
exports.registerHelper('log', function(context, options) {
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
Handlebars.log(level, context);
});
return Handlebars;
}
var levels = {
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3
}
var methodMap = { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' };
export logger = {
// can be overridden in the host environment
log: function(level, obj) {
if (Handlebars.logger.level <= level) {
@@ -96,71 +158,11 @@ Handlebars.logger = {
}
};
Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
export function log(level, obj) { logger.log(level, obj); };
Handlebars.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); }
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(i === 0){
ret = inverse(this);
}
return ret;
});
Handlebars.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);
}
});
Handlebars.registerHelper('unless', function(conditional, options) {
return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
});
Handlebars.registerHelper('with', function(context, options) {
var type = toString.call(context);
if(type === functionType) { context = context.call(this); }
if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
});
Handlebars.registerHelper('log', function(context, options) {
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
Handlebars.log(level, context);
});
// END(BROWSER)
return Handlebars;
export createFrame = Object.create || function(object) {
K.prototype = object;
var obj = new K();
K.prototype = null;
return obj;
};
+15 -24
View File
@@ -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;
};
+8 -17
View File
@@ -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; }
if(input.constructor === AST.ProgramNode) { return input; }
Handlebars.Parser.yy = Handlebars.AST;
return Handlebars.Parser.parse(input);
};
// END(BROWSER)
return Handlebars;
};
parser.yy = AST;
return parser.parse(input);
}
+21 -25
View File
@@ -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;
};
+6 -18
View File
@@ -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;
};
+93 -97
View File
@@ -1,106 +1,102 @@
exports.attach = function(Handlebars) {
import { escapeExpression, extend, Exceptions } from "handlebars/utils";
import { COMPILER_REVISION, REVISION_CHANGES } from "handlebars/base";
// BEGIN(BROWSER)
// TODO: Deal with the fact that compile is necessary for on-the-fly partial
// compilation but won't be present for precompiled templates.
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]+").";
}
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;
return result;
};
},
if (param && common) {
ret = {};
extend(ret, common);
extend(ret, param);
}
return ret;
},
programWithDepth: programWithDepth,
noop: noop,
compilerInfo: null
};
programWithDepth: function(i, fn, data /*, $depth */) {
var args = Array.prototype.slice.call(arguments, 3);
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 program = function(context, options) {
options = options || {};
var compilerInfo = container.compilerInfo || [],
compilerRevision = compilerInfo[0] || 1,
currentRevision = COMPILER_REVISION;
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);
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;
};
}
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);
}
};
Handlebars.template = Handlebars.VM.template;
// END(BROWSER)
return Handlebars;
};
}
+36 -45
View File
@@ -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;
}
}
+21 -33
View File
@@ -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"
}
}