From b6173752192682f8156b791e06e7985913621d76 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 23 Feb 2017 17:44:31 +0100 Subject: [PATCH 1/2] Parser: Change suffix to use ES6 default module export - This export will be transpiled by Babel for the cjs distribution, but will enable others to use a pure ES6 module distribution - Instanbul: Ignore "parser.js" for coverage reporting. This file was ignored before via annotation, but this has no effect anymore due to the above change - Remove istanbul annotation from `parser-prefix` (@nknapp) Squashed by @nknapp (cherry picked from commit 508347e) --- .istanbul.yml | 2 +- src/parser-prefix.js | 2 +- src/parser-suffix.js | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.istanbul.yml b/.istanbul.yml index e6911f19..960643ef 100644 --- a/.istanbul.yml +++ b/.istanbul.yml @@ -1,2 +1,2 @@ instrumentation: - excludes: ['**/spec/**'] + excludes: ['**/spec/**', '**/handlebars/compiler/parser.js'] diff --git a/src/parser-prefix.js b/src/parser-prefix.js index e26b9934..d9ed0411 100644 --- a/src/parser-prefix.js +++ b/src/parser-prefix.js @@ -1 +1 @@ -/* istanbul ignore next */ +// File ignored in coverage tests via setting in .istanbul.yml diff --git a/src/parser-suffix.js b/src/parser-suffix.js index 1f69f7a4..6e4aa20d 100644 --- a/src/parser-suffix.js +++ b/src/parser-suffix.js @@ -1,2 +1 @@ -exports.__esModule = true; -exports['default'] = handlebars; +export default handlebars; From c8f4b570c14746c6e9f0c5a39056e5ee4be2f5e1 Mon Sep 17 00:00:00 2001 From: Nils Knappmeier Date: Thu, 9 Mar 2017 21:17:52 +0100 Subject: [PATCH 2/2] Fix context-stack when calling block-helpers on null values Fixes #1319 Original behaviour: - When a block-helper was called on a null-context, an empty object was used as context instead. (#1093) - The runtime verifies that whether the current context equals the last context and adds the current context to the stack, if it is not. This is done, so that inside a block-helper, the ".." path can be used to go back to the parent element. - If the helper is called on a "null" element, the context was added, even though it shouldn't be, because the "null != {}" Fix: - The commit replaces "null" by the identifiable "container.nullContext" instead of "{}". "nullContext" is a sealed empty object. - An additional check in the runtime verifies that the context is only added to the stack, if it is not the nullContext. Backwards compatibility within 4.0.x-versions: - This commit changes the compiler and compiled templates would not work with runtime-versions 4.0.0 - 4.0.6, because of the "nullContext" property. That's way, the compiled code reads "(container.nullContext || {})" so that the behavior will degrade gracefully with older runtime versions: Everything else will work fine, but GH-1319 will still be broken, if you use a newer compiler with a pre 4.0.7 runtime. --- lib/handlebars/compiler/javascript-compiler.js | 2 +- lib/handlebars/runtime.js | 4 +++- spec/regressions.js | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index ec891176..bf4be8af 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -987,7 +987,7 @@ JavaScriptCompiler.prototype = { let params = [], paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); let foundHelper = this.nameLookup('helpers', name, 'helper'), - callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : {}`); + callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : (container.nullContext || {})`); return { params: params, diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index 5a79b710..1c084ce3 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -124,6 +124,8 @@ export function template(templateSpec, env) { return obj; }, + // An empty object to use as replacement for null-contexts + nullContext: Object.seal({}), noop: env.VM.noop, compilerInfo: templateSpec.compiler @@ -187,7 +189,7 @@ export function template(templateSpec, env) { export function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) { function prog(context, options = {}) { let currentDepths = depths; - if (depths && context != depths[0]) { + if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) { currentDepths = [context].concat(depths); } diff --git a/spec/regressions.js b/spec/regressions.js index 4a2a55cd..6aca9088 100644 --- a/spec/regressions.js +++ b/spec/regressions.js @@ -277,4 +277,9 @@ describe('Regressions', function() { shouldCompileTo(string, { listOne: ['a'], listTwo: ['b']}, 'ab', ''); }); + + it('GH-1319: "unless" breaks when "each" value equals "null"', function() { + var string = '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'; + shouldCompileTo(string, { value: 'parent', list: [ null, 'a'] }, 'parent=parent parent=parent ', ''); + }); });