From 99b7baf438c360a79254607a9038d20c80141b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Miernik?= Date: Fri, 13 Sep 2024 11:43:32 +0200 Subject: [PATCH 1/2] Added support for `Promise`s in `#with` (closes #469). --- packages/blaze/builtins.js | 14 +++----------- packages/blaze/lookup.js | 4 ++-- packages/blaze/view.js | 2 +- packages/spacebars-tests/async_tests.html | 4 ++++ packages/spacebars-tests/async_tests.js | 16 +++++++++++++--- packages/templating-runtime/templating.js | 2 +- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/blaze/builtins.js b/packages/blaze/builtins.js index 2d41562e2..f0eb99c78 100644 --- a/packages/blaze/builtins.js +++ b/packages/blaze/builtins.js @@ -16,17 +16,9 @@ Blaze._calculateCondition = function (cond) { Blaze.With = function (data, contentFunc) { const view = Blaze.View('with', contentFunc); - view.dataVar = new ReactiveVar(); - - view.onViewCreated(function () { - if (typeof data === 'function') { - // `data` is a reactive function - view.autorun(function () { - view.dataVar.set(data()); - }, view.parentView, 'setData'); - } else { - view.dataVar.set(data); - } + view.dataVar = null; + view.onViewCreated(() => { + view.dataVar = _createBinding(view, data, 'setData'); }); return view; diff --git a/packages/blaze/lookup.js b/packages/blaze/lookup.js index aa48408be..af30813c3 100644 --- a/packages/blaze/lookup.js +++ b/packages/blaze/lookup.js @@ -278,8 +278,8 @@ Blaze._parentData = function (height, _functionWrapped) { if (! theWith) return null; if (_functionWrapped) - return function () { return theWith.dataVar.get(); }; - return theWith.dataVar.get(); + return function () { return theWith.dataVar.get()?.value; }; + return theWith.dataVar.get()?.value; }; diff --git a/packages/blaze/view.js b/packages/blaze/view.js index ada80fe59..e3ed33921 100644 --- a/packages/blaze/view.js +++ b/packages/blaze/view.js @@ -792,7 +792,7 @@ Blaze.getData = function (elementOrView) { throw new Error("Expected DOM element or View"); } - return theWith ? theWith.dataVar.get() : null; + return theWith ? theWith.dataVar.get()?.value : null; }; // For back-compat diff --git a/packages/spacebars-tests/async_tests.html b/packages/spacebars-tests/async_tests.html index 4f8f8641d..299a790b3 100644 --- a/packages/spacebars-tests/async_tests.html +++ b/packages/spacebars-tests/async_tests.html @@ -105,3 +105,7 @@ + + diff --git a/packages/spacebars-tests/async_tests.js b/packages/spacebars-tests/async_tests.js index 4f859076d..82e20f58d 100644 --- a/packages/spacebars-tests/async_tests.js +++ b/packages/spacebars-tests/async_tests.js @@ -11,12 +11,15 @@ function asyncTest(templateName, testName, fn) { } function asyncSuite(templateName, cases) { - for (const [testName, helpers, before, after] of cases) { + for (const [testName, helpers, before, after, cycles = 1] of cases) { asyncTest(templateName, testName, async (test, template, render) => { template.helpers(helpers); const readHTML = render(); - test.equal(readHTML(), before); - await new Promise(Tracker.afterFlush); + // Some test cases require more cycles to propagate. + for (let cycle = 0; cycle < cycles; ++cycle) { + test.equal(readHTML(), before); + await new Promise(Tracker.afterFlush); + } test.equal(readHTML(), after); }); } @@ -117,6 +120,13 @@ asyncSuite('each_new', [ ['two', { x: Promise.resolve([1, 2]) }, '0', '12'], ]); +asyncSuite('with', [ + ['null', { x: Promise.resolve(null) }, '', '', 2], + ['empty', { x: Promise.resolve({}) }, '', '', 2], + ['direct', { x: Promise.resolve({y: 1}) }, '', '1', 2], + ['wrapped', { x: Promise.resolve({y: Promise.resolve(1)}) }, '', '1', 3], +]); + // In the following tests pending=1, rejected=2, resolved=3. const pending = new Promise(() => {}); const rejected = Promise.reject(); diff --git a/packages/templating-runtime/templating.js b/packages/templating-runtime/templating.js index 9d87667c4..717fd3874 100644 --- a/packages/templating-runtime/templating.js +++ b/packages/templating-runtime/templating.js @@ -138,7 +138,7 @@ Template._applyHmrChanges = function (templateName) { var newView = Blaze.render(Template.body, document.body, comment); Template.body.view = newView; } else if (view.dataVar) { - Blaze.renderWithData(renderFunc, view.dataVar.curValue, parentEl, comment); + Blaze.renderWithData(renderFunc, view.dataVar.curValue?.value, parentEl, comment); } else { Blaze.render(renderFunc, parentEl, comment); } From c743df636a37db673a6de21348f7e2a1066c88e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Miernik?= Date: Mon, 21 Oct 2024 19:25:10 +0200 Subject: [PATCH 2/2] Fixed tracking of changedAt in #each. --- packages/blaze/builtins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blaze/builtins.js b/packages/blaze/builtins.js index f0eb99c78..3740f7cb6 100644 --- a/packages/blaze/builtins.js +++ b/packages/blaze/builtins.js @@ -305,7 +305,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { if (eachView.variableName) { itemView._scopeBindings[eachView.variableName].set({ value: newItem }); } else { - itemView.dataVar.set(newItem); + itemView.dataVar.set({ value: newItem }); } } });