Skip to content

Commit adc4b8c

Browse files
committed
make loop closures available in template-based scripts at runtime!
1 parent 2c74e64 commit adc4b8c

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

src/core/runtime/runtime.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,10 @@ export class Runtime {
822822
if (!src) return;
823823
var hash = this.#hashScript(src);
824824
if (internalData.initialized) {
825-
if (internalData.scriptHash === hash) return;
825+
if (internalData.scriptHash === hash) {
826+
this.#resolveTemplateScopes(elt);
827+
return;
828+
}
826829
// Script changed (e.g. morph swap) - clean up and reinitialize
827830
this.cleanup(elt);
828831
internalData = this.getInternalData(elt);

test/core/liveTemplate.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,29 @@ test.describe('live templates', () => {
179179
await expect(find('[data-live-template] li').last().locator('span')).toHaveText('C')
180180
})
181181

182+
test('scope is refreshed after morph so surviving elements get updated indices', async ({html, find, run}) => {
183+
await run("set $morphItems to [{name:'A'},{name:'B'},{name:'C'}]")
184+
await html(`
185+
<script type="text/hypertemplate" live>
186+
<ul>
187+
#for item in $morphItems index i
188+
<li _="on click put i + ':' + item.name into me">${"\x24"}{item.name}</li>
189+
#end
190+
</ul>
191+
</script>
192+
`)
193+
await expect.poll(() => find('[data-live-template] li').count()).toBe(3)
194+
// Verify initial scope: clicking C should show "2:C"
195+
await find('[data-live-template] li').last().click()
196+
await expect(find('[data-live-template] li').last()).toHaveText('2:C')
197+
// Remove B — C shifts from index 2 to index 1
198+
await run("call $morphItems.splice(1, 1)")
199+
await expect.poll(() => find('[data-live-template] li').count()).toBe(2)
200+
// After morph, C's scope should be refreshed: now "1:C"
201+
await find('[data-live-template] li').last().click()
202+
await expect(find('[data-live-template] li').last()).toHaveText('1:C')
203+
})
204+
182205
test('script-based live template preserves ${} in bare attribute position', async ({html, find, page}) => {
183206
await html(`
184207
<script type="text/hypertemplate" live _="init set ^items to [{text:'A', done:true},{text:'B', done:false}]">

0 commit comments

Comments
 (0)