From 7b8343d482b3b8d03b4c317cff74b3f590a29044 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Tue, 17 Sep 2024 12:07:07 +0200 Subject: [PATCH] FIX: Support getters in hbr `#each` context (#28941) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a risk of overriding and then deleting a prop of the context in case of a naming clash between localName and that prop, e.g. ```js class Test { item = "foo"; items = [1, 2]; } const template = ` {{#each items as |item|}} {{item}} {{/each}} `; const compiledTemplate = compile(template); const object = new Test(); // object.item === "foo" const output = compiledTemplate(object, RUNTIME_OPTIONS); // object.item === undefined ``` …but I think we can accept this risk and just be careful.`#each` isn't widely used in hbr anyway (as proven by the other long-standing and recently fixed bug) and hbr is on its way out anyway. --- .../addon/lib/raw-handlebars-helpers.js | 3 ++- .../tests/integration/helpers/raw-test.gjs | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js b/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js index df1164c3e3a..c9550c038a3 100644 --- a/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js +++ b/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js @@ -44,11 +44,12 @@ export function registerRawHelpers(hbs, handlebarsClass, owner) { } let list = get(this, contextName); let output = []; - let innerContext = { ...options.contexts[0] }; + let innerContext = options.contexts[0]; for (let i = 0; i < list.length; i++) { innerContext[localName] = list[i]; output.push(options.fn(innerContext)); } + delete innerContext[localName]; return output.join(""); } ); diff --git a/app/assets/javascripts/discourse/tests/integration/helpers/raw-test.gjs b/app/assets/javascripts/discourse/tests/integration/helpers/raw-test.gjs index 6f69d142dbb..e9562a30f10 100644 --- a/app/assets/javascripts/discourse/tests/integration/helpers/raw-test.gjs +++ b/app/assets/javascripts/discourse/tests/integration/helpers/raw-test.gjs @@ -8,6 +8,7 @@ import raw from "discourse/helpers/raw"; import rawRenderGlimmer from "discourse/lib/raw-render-glimmer"; import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { compile } from "discourse-common/lib/raw-handlebars"; +import { RUNTIME_OPTIONS } from "discourse-common/lib/raw-handlebars-helpers"; import { addRawTemplate, removeRawTemplate, @@ -121,4 +122,26 @@ module("Integration | Helper | raw", function (hooks) { assert.dom("span").hasText("foo 1 foo 2"); }); + + test("#each helper handles getters", async function (assert) { + const template = ` + {{#each items as |item|}} + {{string}} {{item}} + {{/each}} + `; + const compiledTemplate = compile(template); + + class Test { + items = [1, 2]; + + get string() { + return "foo"; + } + } + + const object = new Test(); + + const output = compiledTemplate(object, RUNTIME_OPTIONS); + assert.true(/\s*foo 1\s*foo 2\s*/.test(output)); + }); });