From 343409ff18c10a25abebe43022b59a95e66c696d Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Wed, 25 Sep 2024 17:49:58 +0200 Subject: [PATCH 1/4] we want to morph text and comment nodes too, not just element nodes. --- src/core/morphing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/morphing.js b/src/core/morphing.js index dfd21e839..f1af99755 100644 --- a/src/core/morphing.js +++ b/src/core/morphing.js @@ -9,7 +9,7 @@ export function morphElements(currentElement, newElement, { callbacks, ...option } export function morphChildren(currentElement, newElement) { - morphElements(currentElement, newElement.children, { + morphElements(currentElement, newElement.childNodes, { morphStyle: "innerHTML" }) } From 7ea6805b995ffbabf586c7c7c0b502710a21283f Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Wed, 11 Sep 2024 14:50:54 +0200 Subject: [PATCH 2/4] expose morphing + data-turbo-permanent bug with failing test. --- src/tests/fixtures/permanent_children.html | 36 ++++++++++++++++++++++ src/tests/functional/page_refresh_tests.js | 22 +++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/tests/fixtures/permanent_children.html diff --git a/src/tests/fixtures/permanent_children.html b/src/tests/fixtures/permanent_children.html new file mode 100644 index 000000000..b7c473106 --- /dev/null +++ b/src/tests/fixtures/permanent_children.html @@ -0,0 +1,36 @@ + + + + + + + + Turbo + + + + +
+

Permanent children

+
+ + + +
+ + + +
+ + + + diff --git a/src/tests/functional/page_refresh_tests.js b/src/tests/functional/page_refresh_tests.js index 252a454c4..21bddba59 100644 --- a/src/tests/functional/page_refresh_tests.js +++ b/src/tests/functional/page_refresh_tests.js @@ -331,6 +331,28 @@ test("it preserves data-turbo-permanent elements that don't match when their ids await expect(page.locator("#preserve-me")).toHaveText("Preserve me, I have a family!") }) +test("it preserves data-turbo-permanent children", async ({ page }) => { + await page.goto("/src/tests/fixtures/permanent_children.html") + + await page.evaluate(() => { + // simulate result of client-side drag-and-drop reordering + document.getElementById("first-li").before(document.getElementById("second-li")) + + // set state of data-turbo-permanent checkbox + document.getElementById("second-checkbox").checked = true + }) + + // morph page back to original li ordering + await page.click("#form-submit") + await nextEventNamed(page, "turbo:render", { renderMethod: "morph" }) + + // data-turbo-permanent checkbox should still be checked + assert.ok( + await hasSelector(page, "#second-checkbox:checked"), + "retains state of data-turbo-permanent child" + ) +}) + test("renders unprocessable entity responses with morphing", async ({ page }) => { await page.goto("/src/tests/fixtures/page_refresh.html") From ac4331e9c745232527e69c32d0b7db79a2f2a20a Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Wed, 25 Sep 2024 16:48:08 +0200 Subject: [PATCH 3/4] upgrade to idiomorph v0.4.0 and use the new two-pass mode. --- package.json | 2 +- src/core/morphing.js | 6 ++++++ yarn.lock | 7 ++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8ff937155..28ada0847 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "chai": "~4.3.4", "eslint": "^8.13.0", "express": "^4.18.2", - "idiomorph": "https://github.com/bigskysoftware/idiomorph.git", + "idiomorph": "~0.4.0", "multer": "^1.4.2", "rollup": "^2.35.1" }, diff --git a/src/core/morphing.js b/src/core/morphing.js index f1af99755..586f246c9 100644 --- a/src/core/morphing.js +++ b/src/core/morphing.js @@ -4,6 +4,7 @@ import { dispatch } from "../util" export function morphElements(currentElement, newElement, { callbacks, ...options } = {}) { Idiomorph.morph(currentElement, newElement, { ...options, + twoPass: true, callbacks: new DefaultIdiomorphCallbacks(callbacks) }) } @@ -21,6 +22,11 @@ class DefaultIdiomorphCallbacks { this.#beforeNodeMorphed = beforeNodeMorphed || (() => true) } + // don't mess with the contents of a permanent node when pantrying + beforeNodePantried = (node) => { + if (node.parentNode instanceof Element && node.parentNode.hasAttribute("data-turbo-permanent")) return false; + } + beforeNodeAdded = (node) => { return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) } diff --git a/yarn.lock b/yarn.lock index 829d82aed..f2e8fd64e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1932,9 +1932,10 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -"idiomorph@https://github.com/bigskysoftware/idiomorph.git": - version "0.3.0" - resolved "https://github.com/bigskysoftware/idiomorph.git#b5115add9f7ab04c04af0624385540dff04e0735" +idiomorph@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/idiomorph/-/idiomorph-0.4.0.tgz#ba63a7a73cf6b8db74acec6e22b7c98341e7d548" + integrity sha512-VdXFpZOTXhLatJmhCWJR5oQKLXT01O6sFCJqT0/EqG71C4tYZdPJ5etvttwWsT2WKRYWz160XkNr1DUqXNMZHg== ieee754@^1.1.13: version "1.2.1" From 78f6e45897fc71d3be199f31fc1e90576ceba019 Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Tue, 24 Dec 2024 14:57:33 -0600 Subject: [PATCH 4/4] use new single-pass idiomorph branch. --- package.json | 2 +- src/core/morphing.js | 6 ------ yarn.lock | 5 ++--- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 28ada0847..2bb7395fc 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "chai": "~4.3.4", "eslint": "^8.13.0", "express": "^4.18.2", - "idiomorph": "~0.4.0", + "idiomorph": "https://github.com/botandrose/idiomorph.git#single-pass-build", "multer": "^1.4.2", "rollup": "^2.35.1" }, diff --git a/src/core/morphing.js b/src/core/morphing.js index 586f246c9..f1af99755 100644 --- a/src/core/morphing.js +++ b/src/core/morphing.js @@ -4,7 +4,6 @@ import { dispatch } from "../util" export function morphElements(currentElement, newElement, { callbacks, ...options } = {}) { Idiomorph.morph(currentElement, newElement, { ...options, - twoPass: true, callbacks: new DefaultIdiomorphCallbacks(callbacks) }) } @@ -22,11 +21,6 @@ class DefaultIdiomorphCallbacks { this.#beforeNodeMorphed = beforeNodeMorphed || (() => true) } - // don't mess with the contents of a permanent node when pantrying - beforeNodePantried = (node) => { - if (node.parentNode instanceof Element && node.parentNode.hasAttribute("data-turbo-permanent")) return false; - } - beforeNodeAdded = (node) => { return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) } diff --git a/yarn.lock b/yarn.lock index f2e8fd64e..cf348d48d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1932,10 +1932,9 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -idiomorph@~0.4.0: +"idiomorph@https://github.com/botandrose/idiomorph.git#single-pass-build": version "0.4.0" - resolved "https://registry.yarnpkg.com/idiomorph/-/idiomorph-0.4.0.tgz#ba63a7a73cf6b8db74acec6e22b7c98341e7d548" - integrity sha512-VdXFpZOTXhLatJmhCWJR5oQKLXT01O6sFCJqT0/EqG71C4tYZdPJ5etvttwWsT2WKRYWz160XkNr1DUqXNMZHg== + resolved "https://github.com/botandrose/idiomorph.git#7c4904418ddba27e991318242423cb22f1f1a9b2" ieee754@^1.1.13: version "1.2.1"