Add full support for es6

Converts the tool chain to use babel, eslint, and webpack vs. the previous proprietary solutions.

Additionally begins enforcing additional linting concerns as well as updates the code to reflect these rules.

Fixes #855
Fixes #993
This commit is contained in:
kpdecker
2015-04-16 15:42:46 -05:00
parent 2a02261a5b
commit e3d3eda2e1
51 changed files with 1785 additions and 1538 deletions
+18 -20
View File
@@ -1,21 +1,20 @@
/*globals Handlebars: true */
import Handlebars from "./handlebars.runtime";
import Handlebars from './handlebars.runtime';
// Compiler imports
import AST from "./handlebars/compiler/ast";
import { parser as Parser, parse } from "./handlebars/compiler/base";
import { Compiler, compile, precompile } from "./handlebars/compiler/compiler";
import JavaScriptCompiler from "./handlebars/compiler/javascript-compiler";
import Visitor from "./handlebars/compiler/visitor";
import AST from './handlebars/compiler/ast';
import { parser as Parser, parse } from './handlebars/compiler/base';
import { Compiler, compile, precompile } from './handlebars/compiler/compiler';
import JavaScriptCompiler from './handlebars/compiler/javascript-compiler';
import Visitor from './handlebars/compiler/visitor';
var _create = Handlebars.create;
var create = function() {
function create() {
var hb = _create();
hb.compile = function(input, options) {
return compile(input, options, hb);
};
hb.precompile = function (input, options) {
hb.precompile = function(input, options) {
return precompile(input, options, hb);
};
@@ -26,24 +25,23 @@ var create = function() {
hb.parse = parse;
return hb;
};
}
Handlebars = create();
Handlebars.create = create;
var inst = create();
inst.create = create;
Handlebars.Visitor = Visitor;
inst.Visitor = Visitor;
/*jshint -W040 */
/* istanbul ignore next */
var root = typeof global !== 'undefined' ? global : window,
$Handlebars = root.Handlebars;
var $Handlebars = global.Handlebars;
/* istanbul ignore next */
Handlebars.noConflict = function() {
if (root.Handlebars === Handlebars) {
root.Handlebars = $Handlebars;
inst.noConflict = function() {
if (global.Handlebars === inst) {
global.Handlebars = $Handlebars;
}
};
Handlebars['default'] = Handlebars;
inst['default'] = inst;
export default Handlebars;
export default inst;
+8 -8
View File
@@ -1,15 +1,15 @@
/*globals Handlebars: true */
module base from "./handlebars/base";
/*global window */
import * as base 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)
import SafeString from "./handlebars/safe-string";
import Exception from "./handlebars/exception";
module Utils from "./handlebars/utils";
module runtime from "./handlebars/runtime";
import SafeString from './handlebars/safe-string';
import Exception from './handlebars/exception';
import * as Utils from './handlebars/utils';
import * as runtime from './handlebars/runtime';
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
var create = function() {
function create() {
var hb = new base.HandlebarsEnvironment();
Utils.extend(hb, base);
@@ -24,7 +24,7 @@ var create = function() {
};
return hb;
};
}
var Handlebars = create();
Handlebars.create = create;
+31 -31
View File
@@ -1,7 +1,7 @@
module Utils from "./utils";
import Exception from "./exception";
import * as Utils from './utils';
import Exception from './exception';
export var VERSION = "3.0.1";
export var VERSION = '3.0.1';
export var COMPILER_REVISION = 6;
export var REVISION_CHANGES = {
@@ -45,7 +45,7 @@ HandlebarsEnvironment.prototype = {
registerPartial: function(name, partial) {
if (toString.call(name) === objectType) {
Utils.extend(this.partials, name);
Utils.extend(this.partials, name);
} else {
if (typeof partial === 'undefined') {
throw new Exception('Attempting to register a partial as undefined');
@@ -60,12 +60,12 @@ HandlebarsEnvironment.prototype = {
function registerDefaultHelpers(instance) {
instance.registerHelper('helperMissing', function(/* [args, ]options */) {
if(arguments.length === 1) {
if (arguments.length === 1) {
// A missing field in a {{foo}} constuct.
return undefined;
} else {
// Someone is actually trying to call something, blow up.
throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
throw new Exception('Missing helper: "' + arguments[arguments.length - 1].name + '"');
}
});
@@ -73,12 +73,12 @@ function registerDefaultHelpers(instance) {
var inverse = options.inverse,
fn = options.fn;
if(context === true) {
if (context === true) {
return fn(this);
} else if(context === false || context == null) {
} else if (context === false || context == null) {
return inverse(this);
} else if (isArray(context)) {
if(context.length > 0) {
if (context.length > 0) {
if (options.ids) {
options.ids = [options.name];
}
@@ -104,7 +104,7 @@ function registerDefaultHelpers(instance) {
}
var fn = options.fn, inverse = options.inverse;
var i = 0, ret = "", data;
var i = 0, ret = '', data;
var contextPath;
if (options.data && options.ids) {
@@ -117,51 +117,51 @@ function registerDefaultHelpers(instance) {
data = createFrame(options.data);
}
function execIteration(key, i, last) {
function execIteration(field, index, last) {
if (data) {
data.key = key;
data.index = i;
data.first = i === 0;
data.last = !!last;
data.key = field;
data.index = index;
data.first = index === 0;
data.last = !!last;
if (contextPath) {
data.contextPath = contextPath + key;
data.contextPath = contextPath + field;
}
}
ret = ret + fn(context[key], {
ret = ret + fn(context[field], {
data: data,
blockParams: Utils.blockParams([context[key], key], [contextPath + key, null])
blockParams: Utils.blockParams([context[field], field], [contextPath + field, null])
});
}
if(context && typeof context === 'object') {
if (context && typeof context === 'object') {
if (isArray(context)) {
for(var j = context.length; i<j; i++) {
execIteration(i, i, i === context.length-1);
for (var j = context.length; i < j; i++) {
execIteration(i, i, i === context.length - 1);
}
} else {
var priorKey;
for(var key in context) {
if(context.hasOwnProperty(key)) {
for (var key in context) {
if (context.hasOwnProperty(key)) {
// We're running the iterations one step out of sync so we can detect
// the last iteration without have to scan the object twice and create
// an itermediate keys array.
// an itermediate keys array.
if (priorKey) {
execIteration(priorKey, i-1);
execIteration(priorKey, i - 1);
}
priorKey = key;
i++;
}
}
if (priorKey) {
execIteration(priorKey, i-1, true);
execIteration(priorKey, i - 1, true);
}
}
}
if(i === 0){
if (i === 0) {
ret = inverse(this);
}
@@ -194,7 +194,7 @@ function registerDefaultHelpers(instance) {
if (options.data && options.ids) {
var data = createFrame(options.data);
data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
options = {data:data};
options = {data: data};
}
return fn(context, options);
@@ -227,15 +227,15 @@ export var logger = {
log: function(level, message) {
if (typeof console !== 'undefined' && logger.level <= level) {
var method = logger.methodMap[level];
(console[method] || console.log).call(console, message);
(console[method] || console.log).call(console, message); // eslint-disable-line no-console
}
}
};
export var log = logger.log;
export var createFrame = function(object) {
export function createFrame(object) {
var frame = Utils.extend({}, object);
frame._parent = object;
return frame;
};
}
+4 -5
View File
@@ -27,8 +27,8 @@ var AST = {
this.path = path;
this.params = params || [];
this.hash = hash;
this.program = program;
this.inverse = inverse;
this.program = program;
this.inverse = inverse;
this.openStrip = openStrip;
this.inverseStrip = inverseStrip;
@@ -76,8 +76,8 @@ var AST = {
this.data = data;
this.original = original;
this.parts = parts;
this.depth = depth;
this.parts = parts;
this.depth = depth;
},
StringLiteral: function(string, locInfo) {
@@ -130,7 +130,6 @@ var AST = {
// a mustache is definitely a helper if:
// * it is an eligible helper, and
// * it has at least one parameter or hash segment
// TODO: Make these public utility methods
helperExpression: function(node) {
return !!(node.type === 'SubExpression' || node.params.length || node.hash);
},
+5 -5
View File
@@ -1,8 +1,8 @@
import parser from "./parser";
import AST from "./ast";
import WhitespaceControl from "./whitespace-control";
module Helpers from "./helpers";
import { extend } from "../utils";
import parser from './parser';
import AST from './ast';
import WhitespaceControl from './whitespace-control';
import * as Helpers from './helpers';
import { extend } from '../utils';
export { parser };
+5 -4
View File
@@ -1,4 +1,5 @@
import {isArray} from "../utils";
/*global define */
import {isArray} from '../utils';
var SourceNode;
@@ -56,7 +57,7 @@ function castChunk(chunk, codeGen, loc) {
return ret;
} else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
// Handle primitives that the SourceNode will throw up on
return chunk+'';
return chunk + '';
}
return chunk;
}
@@ -90,7 +91,7 @@ CodeGen.prototype = {
},
empty: function(loc) {
loc = loc || this.currentLocation || {start:{}};
loc = loc || this.currentLocation || {start: {}};
return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
},
wrap: function(chunk, loc) {
@@ -98,7 +99,7 @@ CodeGen.prototype = {
return chunk;
}
loc = loc || this.currentLocation || {start:{}};
loc = loc || this.currentLocation || {start: {}};
chunk = castChunk(chunk, this, loc);
return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
+30 -24
View File
@@ -1,6 +1,6 @@
import Exception from "../exception";
import {isArray, indexOf} from "../utils";
import AST from "./ast";
import Exception from '../exception';
import {isArray, indexOf} from '../utils';
import AST from './ast';
var slice = [].slice;
@@ -67,7 +67,9 @@ Compiler.prototype = {
};
if (knownHelpers) {
for (var name in knownHelpers) {
options.knownHelpers[name] = knownHelpers[name];
if (name in knownHelpers) {
options.knownHelpers[name] = knownHelpers[name];
}
}
}
@@ -75,7 +77,7 @@ Compiler.prototype = {
},
compileProgram: function(program) {
var result = new this.compiler().compile(program, this.options);
var result = new this.compiler().compile(program, this.options); // eslint-disable-line new-cap
var guid = this.guid++;
this.usePartial = this.usePartial || result.usePartial;
@@ -97,7 +99,7 @@ Compiler.prototype = {
this.options.blockParams.unshift(program.blockParams);
var body = program.body;
for(var i=0, l=body.length; i<l; i++) {
for (var i = 0, l = body.length; i < l; i++) {
this.accept(body[i]);
}
@@ -174,9 +176,9 @@ Compiler.prototype = {
},
MustacheStatement: function(mustache) {
this.SubExpression(mustache);
this.SubExpression(mustache); // eslint-disable-line new-cap
if(mustache.escaped && !this.options.noEscape) {
if (mustache.escaped && !this.options.noEscape) {
this.opcode('appendEscaped');
} else {
this.opcode('append');
@@ -231,7 +233,7 @@ Compiler.prototype = {
if (this.options.knownHelpers[name]) {
this.opcode('invokeKnownHelper', params.length, name);
} else if (this.options.knownHelpersOnly) {
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
throw new Exception('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
} else {
path.falsy = true;
@@ -250,7 +252,7 @@ Compiler.prototype = {
if (blockParamId) {
this.opcode('lookupBlockParam', blockParamId, path.parts);
} else if (!name) {
} else if (!name) {
// Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
this.opcode('pushContext');
} else if (path.data) {
@@ -286,7 +288,7 @@ Compiler.prototype = {
this.opcode('pushHash');
for (i=0, l=pairs.length; i<l; i++) {
for (i = 0, l = pairs.length; i < l; i++) {
this.pushParam(pairs[i].value);
}
while (i--) {
@@ -336,13 +338,17 @@ Compiler.prototype = {
}
}
if (isHelper) { return 'helper'; }
else if (isEligible) { return 'ambiguous'; }
else { return 'simple'; }
if (isHelper) {
return 'helper';
} else if (isEligible) {
return 'ambiguous';
} else {
return 'simple';
}
},
pushParams: function(params) {
for(var i=0, l=params.length; i<l; i++) {
for (var i = 0, l = params.length; i < l; i++) {
this.pushParam(params[i]);
}
},
@@ -357,7 +363,7 @@ Compiler.prototype = {
.replace(/\//g, '.');
}
if(val.depth) {
if (val.depth) {
this.addDepth(val.depth);
}
this.opcode('getContext', val.depth || 0);
@@ -421,7 +427,7 @@ Compiler.prototype = {
export function precompile(input, options, env) {
if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
throw new 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 || {};
@@ -439,7 +445,7 @@ export function precompile(input, options, env) {
export function compile(input, options, env) {
if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
throw new 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 || {};
@@ -461,17 +467,17 @@ export function compile(input, options, env) {
}
// Template is only compiled on first use and cached after that point.
var ret = function(context, options) {
function ret(context, execOptions) {
if (!compiled) {
compiled = compileInput();
}
return compiled.call(this, context, options);
};
ret._setup = function(options) {
return compiled.call(this, context, execOptions);
}
ret._setup = function(setupOptions) {
if (!compiled) {
compiled = compileInput();
}
return compiled._setup(options);
return compiled._setup(setupOptions);
};
ret._child = function(i, data, blockParams, depths) {
if (!compiled) {
@@ -502,6 +508,6 @@ function transformLiteralToPath(sexpr) {
var literal = sexpr.path;
// Casting to string here to make false and 0 literal values play nicely with the rest
// of the system.
sexpr.path = new AST.PathExpression(false, 0, [literal.original+''], literal.original+'', literal.loc);
sexpr.path = new AST.PathExpression(false, 0, [literal.original + ''], literal.original + '', literal.loc);
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
import Exception from "../exception";
import Exception from '../exception';
export function SourceLocation(source, locInfo) {
this.source = source;
@@ -23,7 +23,7 @@ export function id(token) {
export function stripFlags(open, close) {
return {
open: open.charAt(2) === '~',
close: close.charAt(close.length-3) === '~'
close: close.charAt(close.length - 3) === '~'
};
}
@@ -41,7 +41,7 @@ export function preparePath(data, parts, locInfo) {
depth = 0,
depthString = '';
for(var i=0,l=parts.length; i<l; i++) {
for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i].part,
// If we have [] syntax then we do not treat path references as operators,
// i.e. foo.[this] resolves to approximately context.foo['this']
+44 -40
View File
@@ -1,7 +1,7 @@
import { COMPILER_REVISION, REVISION_CHANGES } from "../base";
import Exception from "../exception";
import {isArray} from "../utils";
import CodeGen from "./code-gen";
import { COMPILER_REVISION, REVISION_CHANGES } from '../base';
import Exception from '../exception';
import {isArray} from '../utils';
import CodeGen from './code-gen';
function Literal(value) {
this.value = value;
@@ -14,7 +14,7 @@ JavaScriptCompiler.prototype = {
// alternative compiled forms for name lookup and buffering semantics
nameLookup: function(parent, name /* , type*/) {
if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
return [parent, ".", name];
return [parent, '.', name];
} else {
return [parent, "['", name, "']"];
}
@@ -50,7 +50,7 @@ JavaScriptCompiler.prototype = {
},
initializeBuffer: function() {
return this.quotedString("");
return this.quotedString('');
},
// END PUBLIC API
@@ -169,8 +169,8 @@ JavaScriptCompiler.prototype = {
var varDeclarations = '';
var locals = this.stackVars.concat(this.registers.list);
if(locals.length > 0) {
varDeclarations += ", " + locals.join(", ");
if (locals.length > 0) {
varDeclarations += ', ' + locals.join(', ');
}
// Generate minimizer alias mappings
@@ -180,7 +180,7 @@ JavaScriptCompiler.prototype = {
// aliases will not be used, but this case is already being run on the client and
// we aren't concern about minimizing the template size.
var aliasCount = 0;
for (var alias in this.aliases) {
for (var alias in this.aliases) { // eslint-disable-line guard-for-in
var node = this.aliases[alias];
if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
@@ -189,7 +189,7 @@ JavaScriptCompiler.prototype = {
}
}
var params = ["depth0", "helpers", "partials", "data"];
var params = ['depth0', 'helpers', 'partials', 'data'];
if (this.useBlockParams || this.useDepths) {
params.push('blockParams');
@@ -252,7 +252,7 @@ JavaScriptCompiler.prototype = {
this.source.push('return "";');
}
} else {
varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());
varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
if (bufferStart) {
bufferStart.prepend('return buffer + ');
@@ -446,6 +446,7 @@ JavaScriptCompiler.prototype = {
var len = parts.length;
for (; i < len; i++) {
/*eslint-disable no-loop-func */
this.replaceStack(function(current) {
var lookup = this.nameLookup(current, parts[i], type);
// We want to ensure that zero and false are handled properly if the context (falsy flag)
@@ -457,6 +458,7 @@ JavaScriptCompiler.prototype = {
return [' && ', lookup];
}
});
/*eslint-enable no-loop-func */
}
},
@@ -633,7 +635,7 @@ JavaScriptCompiler.prototype = {
'(', lookup,
(helper.paramsInit ? ['),(', helper.paramsInit] : []), '),',
'(typeof helper === ', this.aliasable('"function"'), ' ? ',
this.source.functionCall('helper','call', helper.callParams), ' : helper))'
this.source.functionCall('helper', 'call', helper.callParams), ' : helper))'
]);
},
@@ -728,9 +730,9 @@ JavaScriptCompiler.prototype = {
compileChildren: function(environment, options) {
var children = environment.children, child, compiler;
for(var i=0, l=children.length; i<l; i++) {
for (var i = 0, l = children.length; i < l; i++) {
child = children[i];
compiler = new this.compiler();
compiler = new this.compiler(); // eslint-disable-line new-cap
var index = this.matchExistingProgram(child);
@@ -777,7 +779,7 @@ JavaScriptCompiler.prototype = {
},
useRegister: function(name) {
if(!this.registers[name]) {
if (!this.registers[name]) {
this.registers[name] = true;
this.registers.list.push(name);
}
@@ -849,11 +851,11 @@ JavaScriptCompiler.prototype = {
incrStack: function() {
this.stackSlot++;
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
if (this.stackSlot > this.stackVars.length) { this.stackVars.push('stack' + this.stackSlot); }
return this.topStackName();
},
topStackName: function() {
return "stack" + this.stackSlot;
return 'stack' + this.stackSlot;
},
flushInline: function() {
var inlineStack = this.inlineStack;
@@ -1019,33 +1021,35 @@ JavaScriptCompiler.prototype = {
};
var reservedWords = (
"break else new var" +
" case finally return void" +
" catch for switch while" +
" continue function this with" +
" default if throw" +
" delete in try" +
" do instanceof typeof" +
" abstract enum int short" +
" boolean export interface static" +
" byte extends long super" +
" char final native synchronized" +
" class float package throws" +
" const goto private transient" +
" debugger implements protected volatile" +
" double import public let yield await" +
" null true false"
).split(" ");
(function() {
var reservedWords = (
'break else new var' +
' case finally return void' +
' catch for switch while' +
' continue function this with' +
' default if throw' +
' delete in try' +
' do instanceof typeof' +
' abstract enum int short' +
' boolean export interface static' +
' byte extends long super' +
' char final native synchronized' +
' class float package throws' +
' const goto private transient' +
' debugger implements protected volatile' +
' double import public let yield await' +
' null true false'
).split(' ');
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
for(var i=0, l=reservedWords.length; i<l; i++) {
compilerWords[reservedWords[i]] = true;
}
for (var i = 0, l = reservedWords.length; i < l; i++) {
compilerWords[reservedWords[i]] = true;
}
}());
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
return !JavaScriptCompiler.RESERVED_WORDS[name] && (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/).test(name);
};
function strictLookup(requireTerminal, compiler, parts, type) {
+18 -16
View File
@@ -1,4 +1,5 @@
import Visitor from "./visitor";
/*eslint-disable new-cap */
import Visitor from './visitor';
export function print(ast) {
return new PrintVisitor().accept(ast);
@@ -11,13 +12,13 @@ export function PrintVisitor() {
PrintVisitor.prototype = new Visitor();
PrintVisitor.prototype.pad = function(string) {
var out = "";
var out = '';
for(var i=0,l=this.padding; i<l; i++) {
out = out + " ";
for (var i = 0, l = this.padding; i < l; i++) {
out = out + ' ';
}
out = out + string + "\n";
out = out + string + '\n';
return out;
};
@@ -28,14 +29,14 @@ PrintVisitor.prototype.Program = function(program) {
if (program.blockParams) {
var blockParams = 'BLOCK PARAMS: [';
for(i=0, l=program.blockParams.length; i<l; i++) {
for (i = 0, l = program.blockParams.length; i < l; i++) {
blockParams += ' ' + program.blockParams[i];
}
blockParams += ' ]';
out += this.pad(blockParams);
}
for(i=0, l=body.length; i<l; i++) {
for (i = 0, l = body.length; i < l; i++) {
out = out + this.accept(body[i]);
}
@@ -49,7 +50,7 @@ PrintVisitor.prototype.MustacheStatement = function(mustache) {
};
PrintVisitor.prototype.BlockStatement = function(block) {
var out = "";
var out = '';
out = out + this.pad('BLOCK:');
this.padding++;
@@ -75,7 +76,7 @@ PrintVisitor.prototype.BlockStatement = function(block) {
PrintVisitor.prototype.PartialStatement = function(partial) {
var content = 'PARTIAL:' + partial.name.original;
if(partial.params[0]) {
if (partial.params[0]) {
content += ' ' + this.accept(partial.params[0]);
}
if (partial.hash) {
@@ -95,15 +96,15 @@ PrintVisitor.prototype.CommentStatement = function(comment) {
PrintVisitor.prototype.SubExpression = function(sexpr) {
var params = sexpr.params, paramStrings = [], hash;
for(var i=0, l=params.length; i<l; i++) {
for (var i = 0, l = params.length; i < l; i++) {
paramStrings.push(this.accept(params[i]));
}
params = "[" + paramStrings.join(", ") + "]";
params = '[' + paramStrings.join(', ') + ']';
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : '';
return this.accept(sexpr.path) + " " + params + hash;
return this.accept(sexpr.path) + ' ' + params + hash;
};
PrintVisitor.prototype.PathExpression = function(id) {
@@ -117,11 +118,11 @@ PrintVisitor.prototype.StringLiteral = function(string) {
};
PrintVisitor.prototype.NumberLiteral = function(number) {
return "NUMBER{" + number.value + "}";
return 'NUMBER{' + number.value + '}';
};
PrintVisitor.prototype.BooleanLiteral = function(bool) {
return "BOOLEAN{" + bool.value + "}";
return 'BOOLEAN{' + bool.value + '}';
};
PrintVisitor.prototype.UndefinedLiteral = function() {
@@ -136,7 +137,7 @@ PrintVisitor.prototype.Hash = function(hash) {
var pairs = hash.pairs;
var joinedPairs = [];
for (var i=0, l=pairs.length; i<l; i++) {
for (var i = 0, l = pairs.length; i < l; i++) {
joinedPairs.push(this.accept(pairs[i]));
}
@@ -145,3 +146,4 @@ PrintVisitor.prototype.Hash = function(hash) {
PrintVisitor.prototype.HashPair = function(pair) {
return pair.key + '=' + this.accept(pair.value);
};
/*eslint-enable new-cap */
+2 -2
View File
@@ -1,5 +1,5 @@
import Exception from "../exception";
import AST from "./ast";
import Exception from '../exception';
import AST from './ast';
function Visitor() {
this.parents = [];
+10 -13
View File
@@ -1,4 +1,4 @@
import Visitor from "./visitor";
import Visitor from './visitor';
function WhitespaceControl() {
}
@@ -38,7 +38,7 @@ WhitespaceControl.prototype.Program = function(program) {
// If we are on a standalone node, save the indent info for partials
if (current.type === 'PartialStatement') {
// Pull out the whitespace from the final line
current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1];
current.indent = (/([ \t]+$)/).exec(body[i - 1].original)[1];
}
}
}
@@ -73,7 +73,7 @@ WhitespaceControl.prototype.BlockStatement = function(block) {
// Walk the inverse chain to find the last inverse that is actually in the chain.
while (lastInverse.chained) {
lastInverse = lastInverse.body[lastInverse.body.length-1].program;
lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
}
}
@@ -108,14 +108,11 @@ WhitespaceControl.prototype.BlockStatement = function(block) {
// Find standalone else statments
if (isPrevWhitespace(program.body)
&& isNextWhitespace(firstInverse.body)) {
omitLeft(program.body);
omitRight(firstInverse.body);
}
} else {
if (block.closeStrip.open) {
omitLeft(program.body, null, true);
}
} else if (block.closeStrip.open) {
omitLeft(program.body, null, true);
}
return strip;
@@ -125,7 +122,7 @@ WhitespaceControl.prototype.MustacheStatement = function(mustache) {
return mustache.strip;
};
WhitespaceControl.prototype.PartialStatement =
WhitespaceControl.prototype.PartialStatement =
WhitespaceControl.prototype.CommentStatement = function(node) {
/* istanbul ignore next */
var strip = node.strip || {};
@@ -144,8 +141,8 @@ function isPrevWhitespace(body, i, isRoot) {
// Nodes that end with newlines are considered whitespace (but are special
// cased for strip operations)
var prev = body[i-1],
sibling = body[i-2];
var prev = body[i - 1],
sibling = body[i - 2];
if (!prev) {
return isRoot;
}
@@ -159,8 +156,8 @@ function isNextWhitespace(body, i, isRoot) {
i = -1;
}
var next = body[i+1],
sibling = body[i+2];
var next = body[i + 1],
sibling = body[i + 2];
if (!next) {
return isRoot;
}
+30 -30
View File
@@ -1,6 +1,6 @@
module Utils from "./utils";
import Exception from "./exception";
import { COMPILER_REVISION, REVISION_CHANGES, createFrame } from "./base";
import * as Utils from './utils';
import Exception from './exception';
import { COMPILER_REVISION, REVISION_CHANGES, createFrame } from './base';
export function checkRevision(compilerInfo) {
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
@@ -10,12 +10,12 @@ export function checkRevision(compilerInfo) {
if (compilerRevision < currentRevision) {
var runtimeVersions = REVISION_CHANGES[currentRevision],
compilerVersions = REVISION_CHANGES[compilerRevision];
throw new Exception("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+").");
throw new Exception('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 new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
throw new Exception('Template was precompiled with a newer version of Handlebars than the current runtime. ' +
'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
}
}
}
@@ -25,7 +25,7 @@ export function checkRevision(compilerInfo) {
export function template(templateSpec, env) {
/* istanbul ignore next */
if (!env) {
throw new Exception("No environment passed to template");
throw new Exception('No environment passed to template');
}
if (!templateSpec || !templateSpec.main) {
throw new Exception('Unknown template object: ' + typeof templateSpec);
@@ -35,7 +35,7 @@ export function template(templateSpec, env) {
// for external users to override these as psuedo-supported APIs.
env.VM.checkRevision(templateSpec.compiler);
var invokePartialWrapper = function(partial, context, options) {
function invokePartialWrapper(partial, context, options) {
if (options.hash) {
context = Utils.extend({}, context, options.hash);
}
@@ -61,9 +61,9 @@ export function template(templateSpec, env) {
}
return result;
} else {
throw new Exception("The partial " + options.name + " could not be compiled when running in runtime-only mode");
throw new Exception('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
}
};
}
// Just add water
var container = {
@@ -97,34 +97,34 @@ export function template(templateSpec, env) {
var programWrapper = this.programs[i],
fn = this.fn(i);
if (data || depths || blockParams || declaredBlockParams) {
programWrapper = program(this, i, fn, data, declaredBlockParams, blockParams, depths);
programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
} else if (!programWrapper) {
programWrapper = this.programs[i] = program(this, i, fn);
programWrapper = this.programs[i] = wrapProgram(this, i, fn);
}
return programWrapper;
},
data: function(data, depth) {
while (data && depth--) {
data = data._parent;
data: function(value, depth) {
while (value && depth--) {
value = value._parent;
}
return data;
return value;
},
merge: function(param, common) {
var ret = param || common;
var obj = param || common;
if (param && common && (param !== common)) {
ret = Utils.extend({}, common, param);
obj = Utils.extend({}, common, param);
}
return ret;
return obj;
},
noop: env.VM.noop,
compilerInfo: templateSpec.compiler
};
var ret = function(context, options) {
function ret(context, options) {
options = options || {};
var data = options.data;
@@ -139,7 +139,7 @@ export function template(templateSpec, env) {
}
return templateSpec.main.call(container, context, container.helpers, container.partials, data, blockParams, depths);
};
}
ret.isTop = true;
ret._setup = function(options) {
@@ -163,13 +163,13 @@ export function template(templateSpec, env) {
throw new Exception('must pass parent depths');
}
return program(container, i, templateSpec[i], data, 0, blockParams, depths);
return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
};
return ret;
}
export function program(container, i, fn, data, declaredBlockParams, blockParams, depths) {
var prog = function(context, options) {
export function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
function prog(context, options) {
options = options || {};
return fn.call(container,
@@ -178,7 +178,7 @@ export function program(container, i, fn, data, declaredBlockParams, blockParams
options.data || data,
blockParams && [options.blockParams].concat(blockParams),
depths && [context].concat(depths));
};
}
prog.program = i;
prog.depth = depths ? depths.length : 0;
prog.blockParams = declaredBlockParams || 0;
@@ -199,14 +199,14 @@ export function resolvePartial(partial, context, options) {
export function invokePartial(partial, context, options) {
options.partial = true;
if(partial === undefined) {
throw new Exception("The partial " + options.name + " could not be found");
} else if(partial instanceof Function) {
if (partial === undefined) {
throw new Exception('The partial ' + options.name + ' could not be found');
} else if (partial instanceof Function) {
return partial(context, options);
}
}
export function noop() { return ""; }
export function noop() { return ''; }
function initData(context, data) {
if (!data || !('root' in data)) {
+1 -1
View File
@@ -4,7 +4,7 @@ function SafeString(string) {
}
SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
return "" + this.string;
return '' + this.string;
};
export default SafeString;
+8 -6
View File
@@ -1,11 +1,11 @@
/*jshint -W004 */
var escape = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#x27;",
"`": "&#x60;"
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'`': '&#x60;'
};
var badChars = /[&<>"'`]/g;
@@ -31,6 +31,7 @@ export var toString = Object.prototype.toString;
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
/*eslint-disable func-style */
var isFunction = function(value) {
return typeof value === 'function';
};
@@ -42,6 +43,7 @@ if (isFunction(/x/)) {
};
}
export var isFunction;
/*eslint-enable func-style */
/* istanbul ignore next */
export var isArray = Array.isArray || function(value) {
+8 -8
View File
@@ -3,7 +3,7 @@
// var local = handlebars.create();
var handlebars = require('../dist/cjs/handlebars')["default"];
var handlebars = require('../dist/cjs/handlebars')['default'];
var printer = require('../dist/cjs/handlebars/compiler/printer');
handlebars.PrintVisitor = printer.PrintVisitor;
@@ -12,13 +12,13 @@ handlebars.print = printer.print;
module.exports = handlebars;
// Publish a Node.js require() handler for .handlebars and .hbs files
function extension(module, filename) {
var fs = require('fs');
var templateString = fs.readFileSync(filename, 'utf8');
module.exports = handlebars.compile(templateString);
}
/* istanbul ignore else */
if (typeof require !== 'undefined' && require.extensions) {
var extension = function(module, filename) {
var fs = require("fs");
var templateString = fs.readFileSync(filename, "utf8");
module.exports = handlebars.compile(templateString);
};
require.extensions[".handlebars"] = extension;
require.extensions[".hbs"] = extension;
require.extensions['.handlebars'] = extension;
require.extensions['.hbs'] = extension;
}
+9 -9
View File
@@ -1,4 +1,4 @@
/*eslint-disable no-console */
var fs = require('fs'),
Handlebars = require('./index'),
basename = require('path').basename,
@@ -70,10 +70,10 @@ module.exports.cli = function(opts) {
stat = fs.statSync(path);
if (stat.isDirectory()) {
fs.readdirSync(template).map(function(file) {
var path = template + '/' + file;
var childPath = template + '/' + file;
if (extension.test(path) || fs.statSync(path).isDirectory()) {
processTemplate(path, root || template);
if (extension.test(childPath) || fs.statSync(childPath).isDirectory()) {
processTemplate(childPath, root || template);
}
});
} else {
@@ -99,7 +99,7 @@ module.exports.cli = function(opts) {
if (!root) {
template = basename(template);
} else if (template.indexOf(root) === 0) {
template = template.substring(root.length+1);
template = template.substring(root.length + 1);
}
template = template.replace(extension, '');
@@ -114,12 +114,12 @@ module.exports.cli = function(opts) {
if (opts.simple) {
output.add([precompiled, '\n']);
} else if (opts.partial) {
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
if (opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
output.add('return ');
}
output.add(['Handlebars.partials[\'', template, '\'] = template(', precompiled, ');\n']);
} else {
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
if (opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
output.add('return ');
}
output.add(['templates[\'', template, '\'] = template(', precompiled, ');\n']);
@@ -134,8 +134,8 @@ module.exports.cli = function(opts) {
// Output the content
if (!opts.simple) {
if (opts.amd) {
if(opts.templates.length > 1 || (opts.templates.length == 1 && fs.statSync(opts.templates[0]).isDirectory())) {
if(opts.partial){
if (opts.templates.length > 1 || (opts.templates.length == 1 && fs.statSync(opts.templates[0]).isDirectory())) {
if (opts.partial) {
output.add('return Handlebars.partials;\n');
} else {
output.add('return templates;\n');