Convert template spec to object literal
This allows for metadata to be associated with the template and a simplification of the template init logic.
This commit is contained in:
@@ -35,7 +35,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
compilerInfo: function() {
|
compilerInfo: function() {
|
||||||
var revision = COMPILER_REVISION,
|
var revision = COMPILER_REVISION,
|
||||||
versions = REVISION_CHANGES[revision];
|
versions = REVISION_CHANGES[revision];
|
||||||
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
return [revision, versions];
|
||||||
},
|
},
|
||||||
|
|
||||||
appendToBuffer: function(string) {
|
appendToBuffer: function(string) {
|
||||||
@@ -62,6 +62,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.options = options || {};
|
this.options = options || {};
|
||||||
this.stringParams = this.options.stringParams;
|
this.stringParams = this.options.stringParams;
|
||||||
this.trackIds = this.options.trackIds;
|
this.trackIds = this.options.trackIds;
|
||||||
|
this.precompile = !asObject;
|
||||||
|
|
||||||
log('debug', this.environment.disassemble() + "\n\n");
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
@@ -69,14 +70,14 @@ JavaScriptCompiler.prototype = {
|
|||||||
this.isChild = !!context;
|
this.isChild = !!context;
|
||||||
this.context = context || {
|
this.context = context || {
|
||||||
programs: [],
|
programs: [],
|
||||||
environments: [],
|
environments: []
|
||||||
aliases: { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.preamble();
|
this.preamble();
|
||||||
|
|
||||||
this.stackSlot = 0;
|
this.stackSlot = 0;
|
||||||
this.stackVars = [];
|
this.stackVars = [];
|
||||||
|
this.aliases = {};
|
||||||
this.registers = { list: [] };
|
this.registers = { list: [] };
|
||||||
this.hashes = [];
|
this.hashes = [];
|
||||||
this.compileStack = [];
|
this.compileStack = [];
|
||||||
@@ -110,23 +111,39 @@ JavaScriptCompiler.prototype = {
|
|||||||
throw new Exception('Compile completed with content left on stack');
|
throw new Exception('Compile completed with content left on stack');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.createFunctionContext(asObject);
|
var fn = this.createFunctionContext(asObject);
|
||||||
|
if (!this.isChild) {
|
||||||
|
var ret = {
|
||||||
|
compiler: this.compilerInfo(),
|
||||||
|
main: fn
|
||||||
|
};
|
||||||
|
this.context.programs.map(function(program, index) {
|
||||||
|
if (program) {
|
||||||
|
ret[index] = program;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.environment.usePartial) {
|
||||||
|
ret.usePartial = true;
|
||||||
|
}
|
||||||
|
if (this.options.data) {
|
||||||
|
ret.useData = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!asObject) {
|
||||||
|
ret.compiler = JSON.stringify(ret.compiler);
|
||||||
|
ret = this.objectLiteral(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
preamble: function() {
|
preamble: function() {
|
||||||
var out = [];
|
var out = [];
|
||||||
|
|
||||||
if (!this.isChild) {
|
|
||||||
var namespace = this.namespace;
|
|
||||||
|
|
||||||
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
|
||||||
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
|
||||||
if (this.options.data) { copies = copies + " data = this.initData(depth0, data);"; }
|
|
||||||
out.push(copies);
|
|
||||||
} else {
|
|
||||||
out.push('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.environment.isSimple) {
|
if (!this.environment.isSimple) {
|
||||||
out.push(", buffer = " + this.initializeBuffer());
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
} else {
|
} else {
|
||||||
@@ -143,32 +160,25 @@ JavaScriptCompiler.prototype = {
|
|||||||
var locals = this.stackVars.concat(this.registers.list);
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
if(locals.length > 0) {
|
if(locals.length > 0) {
|
||||||
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
this.source[0] += ", " + locals.join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate minimizer alias mappings
|
// Generate minimizer alias mappings
|
||||||
if (!this.isChild) {
|
for (var alias in this.aliases) {
|
||||||
for (var alias in this.context.aliases) {
|
if (this.aliases.hasOwnProperty(alias)) {
|
||||||
if (this.context.aliases.hasOwnProperty(alias)) {
|
this.source[0] += ', ' + alias + '=' + this.aliases[alias];
|
||||||
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.source[1]) {
|
if (this.source[0]) {
|
||||||
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
this.source[0] = "var " + this.source[0].substring(2) + ";";
|
||||||
}
|
|
||||||
|
|
||||||
// Merge children
|
|
||||||
if (!this.isChild) {
|
|
||||||
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.environment.isSimple) {
|
if (!this.environment.isSimple) {
|
||||||
this.pushSource("return buffer;");
|
this.pushSource("return buffer;");
|
||||||
}
|
}
|
||||||
|
|
||||||
var params = this.isChild ? ["depth0", "data"] : [this.namespace, "depth0", "helpers", "partials", "data"];
|
var params = ["depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
params.push("depth" + this.environment.depths.list[i]);
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
@@ -177,18 +187,12 @@ JavaScriptCompiler.prototype = {
|
|||||||
// Perform a second pass over the output to merge content when possible
|
// Perform a second pass over the output to merge content when possible
|
||||||
var source = this.mergeSource();
|
var source = this.mergeSource();
|
||||||
|
|
||||||
if (!this.isChild) {
|
|
||||||
source = this.compilerInfo()+source;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asObject) {
|
if (asObject) {
|
||||||
params.push(source);
|
params.push(source);
|
||||||
|
|
||||||
return Function.apply(this, params);
|
return Function.apply(this, params);
|
||||||
} else {
|
} else {
|
||||||
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
return 'function(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
log('debug', functionSource + "\n\n");
|
|
||||||
return functionSource;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mergeSource: function() {
|
mergeSource: function() {
|
||||||
@@ -225,7 +229,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// replace it on the stack with the result of properly
|
// replace it on the stack with the result of properly
|
||||||
// invoking blockHelperMissing.
|
// invoking blockHelperMissing.
|
||||||
blockValue: function(name) {
|
blockValue: function(name) {
|
||||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
var params = ["depth0"];
|
var params = ["depth0"];
|
||||||
this.setupParams(name, 0, params);
|
this.setupParams(name, 0, params);
|
||||||
@@ -243,7 +247,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// On stack, after, if no lastHelper: same as [blockValue]
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
// On stack, after, if lastHelper: value
|
// On stack, after, if lastHelper: value
|
||||||
ambiguousBlockValue: function() {
|
ambiguousBlockValue: function() {
|
||||||
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
// We're being a bit cheeky and reusing the options value from the prior exec
|
// We're being a bit cheeky and reusing the options value from the prior exec
|
||||||
var params = ["depth0"];
|
var params = ["depth0"];
|
||||||
@@ -315,7 +319,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// Escape `value` and append it to the buffer
|
// Escape `value` and append it to the buffer
|
||||||
appendEscaped: function() {
|
appendEscaped: function() {
|
||||||
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
this.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
},
|
},
|
||||||
@@ -362,7 +366,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// If the `value` is a lambda, replace it on the stack by
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
// the return value of the lambda
|
// the return value of the lambda
|
||||||
resolvePossibleLambda: function() {
|
resolvePossibleLambda: function() {
|
||||||
this.context.aliases.functionType = '"function"';
|
this.aliases.functionType = '"function"';
|
||||||
|
|
||||||
this.replaceStack(function(current) {
|
this.replaceStack(function(current) {
|
||||||
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
@@ -507,7 +511,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
//
|
//
|
||||||
// If the helper is not found, `helperMissing` is called.
|
// If the helper is not found, `helperMissing` is called.
|
||||||
invokeHelper: function(paramSize, name, isRoot) {
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
this.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
this.useRegister('helper');
|
this.useRegister('helper');
|
||||||
|
|
||||||
var nonHelper = this.popStack();
|
var nonHelper = this.popStack();
|
||||||
@@ -553,7 +557,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// and can be avoided by passing the `knownHelpers` and
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
// `knownHelpersOnly` flags at compile-time.
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
invokeAmbiguous: function(name, helperCall) {
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
this.context.aliases.functionType = '"function"';
|
this.aliases.functionType = '"function"';
|
||||||
this.useRegister('helper');
|
this.useRegister('helper');
|
||||||
|
|
||||||
this.emptyHash();
|
this.emptyHash();
|
||||||
@@ -582,8 +586,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
params.push("data");
|
params.push("data");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.context.aliases.self = "this";
|
this.push("this.invokePartial(" + params.join(", ") + ")");
|
||||||
this.push("self.invokePartial(" + params.join(", ") + ")");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// [assignToHash]
|
// [assignToHash]
|
||||||
@@ -648,7 +651,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
index = this.context.programs.length;
|
index = this.context.programs.length;
|
||||||
child.index = index;
|
child.index = index;
|
||||||
child.name = 'program' + index;
|
child.name = 'program' + index;
|
||||||
this.context.programs[index] = compiler.compile(child, options, this.context);
|
this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
|
||||||
this.context.environments[index] = child;
|
this.context.environments[index] = child;
|
||||||
} else {
|
} else {
|
||||||
child.index = index;
|
child.index = index;
|
||||||
@@ -666,25 +669,22 @@ JavaScriptCompiler.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
programExpression: function(guid) {
|
programExpression: function(guid) {
|
||||||
this.context.aliases.self = "this";
|
|
||||||
|
|
||||||
if(guid == null) {
|
if(guid == null) {
|
||||||
return "self.noop";
|
return 'this.noop';
|
||||||
}
|
}
|
||||||
|
|
||||||
var child = this.environment.children[guid],
|
var child = this.environment.children[guid],
|
||||||
depths = child.depths.list, depth;
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
var programParams = [child.index, child.name, "data"];
|
var programParams = [child.index, 'data'];
|
||||||
|
|
||||||
for(var i=0, l = depths.length; i<l; i++) {
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
depth = depths[i];
|
depth = depths[i];
|
||||||
|
|
||||||
if(depth === 1) { programParams.push("depth0"); }
|
programParams.push('depth' + (depth - 1));
|
||||||
else { programParams.push("depth" + (depth - 1)); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
return (depths.length === 0 ? 'this.program(' : 'this.programWithDepth(') + programParams.join(', ') + ')';
|
||||||
},
|
},
|
||||||
|
|
||||||
register: function(name, val) {
|
register: function(name, val) {
|
||||||
@@ -842,7 +842,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
.replace(/\u2029/g, '\\u2029') + '"';
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
},
|
},
|
||||||
|
|
||||||
setupHash: function(obj) {
|
objectLiteral: function(obj) {
|
||||||
var pairs = [];
|
var pairs = [];
|
||||||
|
|
||||||
for (var key in obj) {
|
for (var key in obj) {
|
||||||
@@ -888,13 +888,11 @@ JavaScriptCompiler.prototype = {
|
|||||||
// helpers to do a check for `if (options.fn)`
|
// helpers to do a check for `if (options.fn)`
|
||||||
if (program || inverse) {
|
if (program || inverse) {
|
||||||
if (!program) {
|
if (!program) {
|
||||||
this.context.aliases.self = "this";
|
program = 'this.noop';
|
||||||
program = "self.noop";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inverse) {
|
if (!inverse) {
|
||||||
this.context.aliases.self = "this";
|
inverse = 'this.noop';
|
||||||
inverse = "self.noop";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options.fn = program;
|
options.fn = program;
|
||||||
@@ -932,7 +930,7 @@ JavaScriptCompiler.prototype = {
|
|||||||
// the params and contexts arguments are passed in arrays
|
// the params and contexts arguments are passed in arrays
|
||||||
// to fill in
|
// to fill in
|
||||||
setupParams: function(helperName, paramSize, params, useRegister) {
|
setupParams: function(helperName, paramSize, params, useRegister) {
|
||||||
var options = this.setupHash(this.setupOptions(helperName, paramSize, params));
|
var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params));
|
||||||
|
|
||||||
if (useRegister) {
|
if (useRegister) {
|
||||||
this.useRegister('options');
|
this.useRegister('options');
|
||||||
|
|||||||
+37
-25
@@ -29,6 +29,8 @@ export function template(templateSpec, env) {
|
|||||||
|
|
||||||
// Note: Using env.VM references rather than local var references throughout this section to allow
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
// for external users to override these as psuedo-supported APIs.
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
env.VM.checkRevision(templateSpec.compiler);
|
||||||
|
|
||||||
var invokePartialWrapper = function(partial, name, context, hash, helpers, partials, data) {
|
var invokePartialWrapper = function(partial, name, context, hash, helpers, partials, data) {
|
||||||
if (hash) {
|
if (hash) {
|
||||||
context = Utils.extend({}, context, hash);
|
context = Utils.extend({}, context, hash);
|
||||||
@@ -50,16 +52,24 @@ export function template(templateSpec, env) {
|
|||||||
var container = {
|
var container = {
|
||||||
escapeExpression: Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: invokePartialWrapper,
|
invokePartial: invokePartialWrapper,
|
||||||
|
|
||||||
|
fn: function(i) {
|
||||||
|
return templateSpec[i];
|
||||||
|
},
|
||||||
|
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, fn, data) {
|
program: function(i, data) {
|
||||||
var programWrapper = this.programs[i];
|
var programWrapper = this.programs[i],
|
||||||
|
fn = this.fn(i);
|
||||||
if(data) {
|
if(data) {
|
||||||
programWrapper = program(i, fn, data);
|
programWrapper = program(this, i, fn, data);
|
||||||
} else if (!programWrapper) {
|
} else if (!programWrapper) {
|
||||||
programWrapper = this.programs[i] = program(i, fn);
|
programWrapper = this.programs[i] = program(this, i, fn);
|
||||||
}
|
}
|
||||||
return programWrapper;
|
return programWrapper;
|
||||||
},
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
|
||||||
initData: function(context, data) {
|
initData: function(context, data) {
|
||||||
if (!data || !('root' in data)) {
|
if (!data || !('root' in data)) {
|
||||||
data = data ? createFrame(data) : {};
|
data = data ? createFrame(data) : {};
|
||||||
@@ -76,54 +86,56 @@ export function template(templateSpec, env) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
programWithDepth: env.VM.programWithDepth,
|
|
||||||
noop: env.VM.noop,
|
noop: env.VM.noop,
|
||||||
compilerInfo: null
|
compilerInfo: templateSpec.compiler
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(context, options) {
|
return function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var namespace = options.partial ? options : env,
|
var namespace = options.partial ? options : env,
|
||||||
helpers,
|
helpers,
|
||||||
partials;
|
partials,
|
||||||
|
data = options.data;
|
||||||
|
|
||||||
if (!options.partial) {
|
if (!options.partial) {
|
||||||
helpers = options.helpers;
|
helpers = container.helpers = container.merge(options.helpers, namespace.helpers);
|
||||||
partials = options.partials;
|
|
||||||
}
|
|
||||||
var result = templateSpec.call(
|
|
||||||
container,
|
|
||||||
namespace, context,
|
|
||||||
helpers,
|
|
||||||
partials,
|
|
||||||
options.data);
|
|
||||||
|
|
||||||
if (!options.partial) {
|
if (templateSpec.usePartial) {
|
||||||
env.VM.checkRevision(container.compilerInfo);
|
partials = container.partials = container.merge(options.partials, namespace.partials);
|
||||||
|
}
|
||||||
|
if (templateSpec.useData) {
|
||||||
|
data = container.initData(context, data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
helpers = container.helpers = options.helpers;
|
||||||
|
partials = container.partials = options.partials;
|
||||||
}
|
}
|
||||||
|
return templateSpec.main.call(container, context, helpers, partials, data);
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function programWithDepth(i, fn, data /*, $depth */) {
|
export function programWithDepth(i, data /*, $depth */) {
|
||||||
var args = Array.prototype.slice.call(arguments, 3);
|
/*jshint -W040 */
|
||||||
|
var args = Array.prototype.slice.call(arguments, 2),
|
||||||
|
container = this,
|
||||||
|
fn = container.fn(i);
|
||||||
|
|
||||||
var prog = function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn.apply(this, [context, options.data || data].concat(args));
|
return fn.apply(container, [context, container.helpers, container.partials, options.data || data].concat(args));
|
||||||
};
|
};
|
||||||
prog.program = i;
|
prog.program = i;
|
||||||
prog.depth = args.length;
|
prog.depth = args.length;
|
||||||
return prog;
|
return prog;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function program(i, fn, data) {
|
export function program(container, i, fn, data) {
|
||||||
var prog = function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn(context, options.data || data);
|
return fn.call(container, context, container.helpers, container.partials, options.data || data);
|
||||||
};
|
};
|
||||||
prog.program = i;
|
prog.program = i;
|
||||||
prog.depth = 0;
|
prog.depth = 0;
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
define(['handlebars.runtime'], function(Handlebars) {
|
define(['handlebars.runtime'], function(Handlebars) {
|
||||||
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
||||||
return templates['empty'] = template(function (Handlebars,depth0,helpers,partials,data) {
|
return templates['empty'] = template({"compiler":[4,">= 1.0.0"],"main":function(depth0,helpers,partials,data) {
|
||||||
this.compilerInfo = [4,'>= 1.0.0'];
|
|
||||||
helpers = this.merge(helpers, Handlebars.helpers); data = this.initData(depth0, data);
|
|
||||||
var buffer = "";
|
var buffer = "";
|
||||||
|
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
});
|
},"useData":true});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ describe('javascript-compiler api', function() {
|
|||||||
});
|
});
|
||||||
it('should allow compilerInfo override', function() {
|
it('should allow compilerInfo override', function() {
|
||||||
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function() {
|
handlebarsEnv.JavaScriptCompiler.prototype.compilerInfo = function() {
|
||||||
return 'this.compilerInfo = "crazy";';
|
return 'crazy';
|
||||||
};
|
};
|
||||||
handlebarsEnv.VM.checkRevision = function(compilerInfo) {
|
handlebarsEnv.VM.checkRevision = function(compilerInfo) {
|
||||||
if (compilerInfo !== 'crazy') {
|
if (compilerInfo !== 'crazy') {
|
||||||
|
|||||||
Reference in New Issue
Block a user