From 0b5715e2046cf9c780e11e963b7fb0a8cbbb5451 Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Mon, 23 Dec 2024 13:46:10 -0600 Subject: [PATCH] workaround for corner case where a data-turbo-permanent node is moved to a random spot in the doc before morphing. --- src/core/morphing.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/morphing.js b/src/core/morphing.js index 8a7274ff2..96a257951 100644 --- a/src/core/morphing.js +++ b/src/core/morphing.js @@ -2,11 +2,13 @@ import { Idiomorph } from "idiomorph/dist/idiomorph.esm.js" import { dispatch } from "../util" export function morphElements(currentElement, newElement, { callbacks, ...options } = {}) { + const cbs = new DefaultIdiomorphCallbacks(callbacks) Idiomorph.morph(currentElement, newElement, { ...options, twoPass: true, - callbacks: new DefaultIdiomorphCallbacks(callbacks) + callbacks: cbs }) + cbs.pruneDuplicatedPermanentNodes(currentElement) } export function morphChildren(currentElement, newElement) { @@ -22,6 +24,25 @@ class DefaultIdiomorphCallbacks { this.#beforeNodeMorphed = beforeNodeMorphed || (() => true) } + // workaround for data-turbo-permanent elements being moved to a weird location in the DOM pre-morph + #permanentNodesWithDuplicates = [] + + beforeNodePantried = (node) => { + if (node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) { + this.#permanentNodesWithDuplicates.push(node) + return false + } + } + + pruneDuplicatedPermanentNodes(root) { + this.#permanentNodesWithDuplicates.forEach(node => { + root.querySelectorAll(`[id=${node.id}]`).forEach(dup => { + if (dup !== node) dup.remove() + }) + }) + } + // end workaround + beforeNodeAdded = (node) => { return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) }