do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0
- The version-range above have compiler version 7 and precompiled templates expecte the (block) HelperMissing-functions in "helpers" and not in "container.hooks". - Handlebars now accepts precompiled templates of version 7. - If a precompiled template with version 7 is loaded, the (block)HelperMissing-functions are kept in "helpers"
This commit is contained in:
@@ -6,6 +6,7 @@ import logger from './logger';
|
|||||||
|
|
||||||
export const VERSION = '4.3.0';
|
export const VERSION = '4.3.0';
|
||||||
export const COMPILER_REVISION = 8;
|
export const COMPILER_REVISION = 8;
|
||||||
|
export const LAST_COMPATIBLE_COMPILER_REVISION = 7;
|
||||||
|
|
||||||
export const REVISION_CHANGES = {
|
export const REVISION_CHANGES = {
|
||||||
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
|||||||
+21
-15
@@ -1,23 +1,25 @@
|
|||||||
import * as Utils from './utils';
|
import * as Utils from './utils';
|
||||||
import Exception from './exception';
|
import Exception from './exception';
|
||||||
import {COMPILER_REVISION, createFrame, REVISION_CHANGES} from './base';
|
import {COMPILER_REVISION, createFrame, LAST_COMPATIBLE_COMPILER_REVISION, REVISION_CHANGES} from './base';
|
||||||
import {moveHelperToHooks} from './helpers';
|
import {moveHelperToHooks} from './helpers';
|
||||||
|
|
||||||
export function checkRevision(compilerInfo) {
|
export function checkRevision(compilerInfo) {
|
||||||
const compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
const compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
currentRevision = COMPILER_REVISION;
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
if (compilerRevision !== currentRevision) {
|
if (compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= COMPILER_REVISION) {
|
||||||
if (compilerRevision < currentRevision) {
|
return;
|
||||||
const runtimeVersions = REVISION_CHANGES[currentRevision],
|
}
|
||||||
compilerVersions = REVISION_CHANGES[compilerRevision];
|
|
||||||
throw new Exception('Template was precompiled with an older version of Handlebars than the current runtime. ' +
|
if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) {
|
||||||
'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
|
const runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
} else {
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
// Use the embedded version info since the runtime doesn't know about this revision yet
|
throw new Exception('Template was precompiled with an older version of Handlebars than the current runtime. ' +
|
||||||
throw new Exception('Template was precompiled with a newer 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 + ').');
|
||||||
'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
|
} 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] + ').');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +39,9 @@ export function template(templateSpec, env) {
|
|||||||
// for external users to override these as pseudo-supported APIs.
|
// for external users to override these as pseudo-supported APIs.
|
||||||
env.VM.checkRevision(templateSpec.compiler);
|
env.VM.checkRevision(templateSpec.compiler);
|
||||||
|
|
||||||
|
// backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)
|
||||||
|
const templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7;
|
||||||
|
|
||||||
function invokePartialWrapper(partial, context, options) {
|
function invokePartialWrapper(partial, context, options) {
|
||||||
if (options.hash) {
|
if (options.hash) {
|
||||||
context = Utils.extend({}, context, options.hash);
|
context = Utils.extend({}, context, options.hash);
|
||||||
@@ -163,9 +168,10 @@ export function template(templateSpec, env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
container.hooks = {};
|
container.hooks = {};
|
||||||
let keepHelper = options.allowCallsToHelperMissing;
|
|
||||||
moveHelperToHooks(container, 'helperMissing', keepHelper);
|
let keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7;
|
||||||
moveHelperToHooks(container, 'blockHelperMissing', keepHelper);
|
moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
|
||||||
|
moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
container.helpers = options.helpers;
|
container.helpers = options.helpers;
|
||||||
|
|||||||
@@ -291,4 +291,36 @@ describe('Regressions', function() {
|
|||||||
};
|
};
|
||||||
shouldCompileToWithPartials(string, [{}, {}, partials], true, 'template block partial block template');
|
shouldCompileToWithPartials(string, [{}, {}, partials], true, 'template block partial block template');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() {
|
||||||
|
|
||||||
|
it('should compile and execute templates', function() {
|
||||||
|
var newHandlebarsInstance = Handlebars.create();
|
||||||
|
|
||||||
|
registerTemplate(newHandlebarsInstance);
|
||||||
|
newHandlebarsInstance.registerHelper('loud', function(value) {
|
||||||
|
return value.toUpperCase();
|
||||||
|
});
|
||||||
|
let result = newHandlebarsInstance.templates['test.hbs']({name: 'yehuda'});
|
||||||
|
equals(result.trim(), 'YEHUDA');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call "helperMissing" if a helper is missing', function() {
|
||||||
|
var newHandlebarsInstance = Handlebars.create();
|
||||||
|
|
||||||
|
shouldThrow(() => {
|
||||||
|
registerTemplate(newHandlebarsInstance);
|
||||||
|
newHandlebarsInstance.templates['test.hbs']({});
|
||||||
|
}, Handlebars.Exception, 'Missing helper: "loud"');
|
||||||
|
});
|
||||||
|
|
||||||
|
// This is a only slightly modified precompiled templated from compiled with 4.2.1
|
||||||
|
function registerTemplate(Handlebars) {
|
||||||
|
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
|
||||||
|
templates['test.hbs'] = template({'compiler': [7, '>= 4.0.0'], 'main': function(container, depth0, helpers, partials, data) {
|
||||||
|
return container.escapeExpression((helpers.loud || (depth0 && depth0.loud) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}), (depth0 != null ? depth0.name : depth0), {'name': 'loud', 'hash': {}, 'data': data}))
|
||||||
|
+ '\n\n';
|
||||||
|
}, 'useData': true});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ describe('runtime', function() {
|
|||||||
shouldThrow(function() {
|
shouldThrow(function() {
|
||||||
Handlebars.template({
|
Handlebars.template({
|
||||||
main: {},
|
main: {},
|
||||||
compiler: [Handlebars.COMPILER_REVISION - 1]
|
compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1]
|
||||||
});
|
});
|
||||||
}, Error, /Template was precompiled with an older version of Handlebars than the current runtime/);
|
}, Error, /Template was precompiled with an older version of Handlebars than the current runtime/);
|
||||||
shouldThrow(function() {
|
shouldThrow(function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user