diff --git a/components/bower.json b/components/bower.json index 60e09e4d4..f26015d4c 100644 --- a/components/bower.json +++ b/components/bower.json @@ -1,6 +1,6 @@ { "name": "handlebars", - "version": "4.3.0", + "version": "4.3.1", "main": "handlebars.js", "license": "MIT", "dependencies": {} diff --git a/components/handlebars.js.nuspec b/components/handlebars.js.nuspec index ff656b2ea..7f708a582 100644 --- a/components/handlebars.js.nuspec +++ b/components/handlebars.js.nuspec @@ -2,7 +2,7 @@ handlebars.js - 4.3.0 + 4.3.1 handlebars.js Authors https://github.com/wycats/handlebars.js/blob/master/LICENSE https://github.com/wycats/handlebars.js/ diff --git a/components/package.json b/components/package.json index a8cfd290a..09278636f 100644 --- a/components/package.json +++ b/components/package.json @@ -1,6 +1,6 @@ { "name": "handlebars", - "version": "4.3.0", + "version": "4.3.1", "license": "MIT", "jspm": { "main": "handlebars", diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js index 2703dafd6..631f5b0f8 100644 --- a/lib/handlebars/base.js +++ b/lib/handlebars/base.js @@ -4,8 +4,9 @@ import {registerDefaultHelpers} from './helpers'; import {registerDefaultDecorators} from './decorators'; import logger from './logger'; -export const VERSION = '4.3.0'; +export const VERSION = '4.3.1'; export const COMPILER_REVISION = 8; +export const LAST_COMPATIBLE_COMPILER_REVISION = 7; export const REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index ce4630463..763016de7 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -1,23 +1,25 @@ import * as Utils from './utils'; 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'; export function checkRevision(compilerInfo) { const compilerRevision = compilerInfo && compilerInfo[0] || 1, currentRevision = COMPILER_REVISION; - if (compilerRevision !== currentRevision) { - if (compilerRevision < currentRevision) { - 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. ' + - '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] + ').'); - } + if (compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= COMPILER_REVISION) { + return; + } + + if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) { + 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. ' + + '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] + ').'); } } @@ -37,6 +39,9 @@ export function template(templateSpec, env) { // for external users to override these as pseudo-supported APIs. 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) { if (options.hash) { context = Utils.extend({}, context, options.hash); @@ -163,9 +168,10 @@ export function template(templateSpec, env) { } container.hooks = {}; - let keepHelper = options.allowCallsToHelperMissing; - moveHelperToHooks(container, 'helperMissing', keepHelper); - moveHelperToHooks(container, 'blockHelperMissing', keepHelper); + + let keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7; + moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers); + moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers); } else { container.helpers = options.helpers; diff --git a/package.json b/package.json index 6b56332cb..f616e4879 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "handlebars", "barename": "handlebars", - "version": "4.3.0", + "version": "4.3.1", "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration", "homepage": "http://www.handlebarsjs.com/", "keywords": [ diff --git a/release-notes.md b/release-notes.md index 8d11f07ba..45c90a162 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,7 +2,17 @@ ## Development -[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...master) +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.1...master) + +## v4.3.1 - September 25th, 2019 +Fixes: + +- do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0 - 1266838, #1561 +- Ensure allowCallsToHelperMissing runtime option is optional in typings - 93444c5, 64ecb9e, #1560 + + + +[Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...v4.3.1) ## v4.3.0 - September 24th, 2019 Fixes: diff --git a/spec/regressions.js b/spec/regressions.js index 1678d80c1..58db65bcd 100644 --- a/spec/regressions.js +++ b/spec/regressions.js @@ -291,4 +291,36 @@ describe('Regressions', function() { }; 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(); + }); + var 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(function() { + 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}); + } + }); }); diff --git a/spec/runtime.js b/spec/runtime.js index a4830ad0c..3549640b7 100644 --- a/spec/runtime.js +++ b/spec/runtime.js @@ -21,7 +21,7 @@ describe('runtime', function() { shouldThrow(function() { Handlebars.template({ 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/); shouldThrow(function() { diff --git a/types/index.d.ts b/types/index.d.ts index bf8d17564..a1b1693e9 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -29,7 +29,7 @@ declare namespace Handlebars { decorators?: { [name: string]: Function }; data?: any; blockParams?: any[]; - allowCallsToHelperMissing: boolean; + allowCallsToHelperMissing?: boolean; } export interface HelperOptions { diff --git a/types/test.ts b/types/test.ts index 341a3c2f9..72d6ff70a 100644 --- a/types/test.ts +++ b/types/test.ts @@ -97,7 +97,7 @@ Handlebars.VM.resolvePartial = (partial: HandlebarsTemplateDelegate | unde // transform name. options.name = name; return originalResolvePartial(partial, context, options); -} +}; // #1544, allow custom helpers in knownHelpers @@ -107,3 +107,7 @@ Handlebars.compile('test', { customHelper: true } }); + +Handlebars.compile('test')({},{allowCallsToHelperMissing: true}); + +Handlebars.compile('test')({},{}); \ No newline at end of file