diff --git a/src/plugins/format/index.js b/src/plugins/format/index.js index 8d4be8a..4460e56 100644 --- a/src/plugins/format/index.js +++ b/src/plugins/format/index.js @@ -98,7 +98,7 @@ function plugin({ directive, evaluateLater, mutateDom }) { } function process_nodes(node) { - for (let child of node.childNodes) { + for (let child of [...node.childNodes]) { process(child); } } diff --git a/tests/playwright/x-format.spec.js b/tests/playwright/x-format.spec.js index 3f7a2cb..5cb2ac0 100644 --- a/tests/playwright/x-format.spec.js +++ b/tests/playwright/x-format.spec.js @@ -10,6 +10,22 @@ test("x-format", async ({ page }) => { await expect(page.locator("div")).toContainText("[Foo,Bar]"); }); +test("x-format: renders HTML strings as text", async ({ page }) => { + await set_html(page, ` +
+

{{ value }}

+ +
`); + + await expect(page.locator("p")).toHaveText("Text"); + await expect(page.locator("p *")).toHaveCount(0); + + await page.locator("button").click(); + + await expect(page.locator("p")).toHaveText("Updated"); + await expect(page.locator("p *")).toHaveCount(0); +}); + test("x-format: recursively", async ({ page }) => { await set_html(page, `
@@ -108,3 +124,49 @@ test("x-format: nested x-format.once is an independent boundary", async ({ page await expect(page.locator("#once")).toHaveText("initial"); await expect(page.locator("#once")).toHaveAttribute("title", "initial"); }); + +for (const modifier of ["", ".once"]) { + test(`x-format${modifier}: does not re-evaluate interpolated values`, async ({ page }) => { + await set_html(page, ` +
+

{{ value }}

+

+ +
`); + + await expect(page.locator("#formatted")).toHaveText("{{ executed = true }}"); + await expect(page.locator("#executed")).toHaveText("false"); + + await page.locator("button").click(); + + await expect(page.locator("#formatted")).toHaveText(modifier ? "{{ executed = true }}" : "{{ executed = 12345 }}"); + await expect(page.locator("#executed")).toHaveText("false"); + }); +} + +test("x-format: preserves interpolations in following original nodes", async ({ page }) => { + await set_html(page, ` +
+

[{{ value }},{{ name }}]{{ name }}{{ value }}{{ name }}

+ +
`); + + await expect(page.locator("p")).toHaveText("[{{ 1 + 1 }},Foo]Foo{{ 1 + 1 }}Foo"); + await expect(page.locator("p")).toHaveAttribute("title", "{{ 1 + 1 }}/Foo"); + + await page.locator("button").click(); + + await expect(page.locator("p")).toHaveText("[{{ 2 + 2 }},Bar]Bar{{ 2 + 2 }}Bar"); + await expect(page.locator("p")).toHaveAttribute("title", "{{ 2 + 2 }}/Bar"); +}); + +test("x-format: nested x-format does not re-evaluate interpolated values", async ({ page }) => { + await set_html(page, ` +
+
+

{{ value }}

+
+
`); + + await expect(page.locator("p")).toHaveText("{{ 1 + 1 }}"); +});