From e1fde68ee582f0d16f5515264e81510aa47c68ec Mon Sep 17 00:00:00 2001 From: Keith Schacht Date: Sun, 25 Feb 2024 17:03:14 -0600 Subject: [PATCH] Refactor code to remove duplication --- src/core/drive/morph_page_renderer.js | 97 ++----------------------- src/core/frames/morph_frame_renderer.js | 80 ++------------------ src/core/morph_elements.js | 66 +++++++++++++++++ 3 files changed, 79 insertions(+), 164 deletions(-) create mode 100644 src/core/morph_elements.js diff --git a/src/core/drive/morph_page_renderer.js b/src/core/drive/morph_page_renderer.js index 356587fef..a62c7f166 100644 --- a/src/core/drive/morph_page_renderer.js +++ b/src/core/drive/morph_page_renderer.js @@ -1,6 +1,6 @@ -import { Idiomorph } from "idiomorph/dist/idiomorph.esm.js" import { dispatch } from "../../util" import { PageRenderer } from "./page_renderer" +import { MorphElements } from "../morph_elements" export class MorphPageRenderer extends PageRenderer { async render() { @@ -14,7 +14,7 @@ export class MorphPageRenderer extends PageRenderer { // Private async #morphBody() { - MorphPageRenderer.morphElements(this.currentElement, this.newElement) + MorphElements.morph(this.currentElement, this.newElement) this.#reloadRemoteFrames() dispatch("turbo:morph", { @@ -25,108 +25,21 @@ export class MorphPageRenderer extends PageRenderer { }) } - static morphElements(currentElement, newElement, morphStyle = "outerHTML") { - this.isMorphingTurboFrame = this.isFrameReloadedWithMorph(currentElement) - - Idiomorph.morph(currentElement, newElement, { - morphStyle: morphStyle, - callbacks: { - beforeNodeAdded: this.shouldAddElement, - beforeNodeMorphed: this.shouldMorphElement, - beforeAttributeUpdated: this.shouldUpdateAttribute, - beforeNodeRemoved: this.shouldRemoveElement, - afterNodeMorphed: this.didMorphElement - } - }) - } - - static shouldAddElement = (node) => { - return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) - } - - static shouldMorphElement = (oldNode, newNode) => { - if (oldNode instanceof HTMLElement) { - if (!oldNode.hasAttribute("data-turbo-permanent") && (this.isMorphingTurboFrame || !this.isFrameReloadedWithMorph(oldNode))) { - const event = dispatch("turbo:before-morph-element", { - cancelable: true, - target: oldNode, - detail: { - newElement: newNode - } - }) - - return !event.defaultPrevented - } else { - return false - } - } - } - - static shouldUpdateAttribute = (attributeName, target, mutationType) => { - const event = dispatch("turbo:before-morph-attribute", { cancelable: true, target, detail: { attributeName, mutationType } }) - - return !event.defaultPrevented - } - - static didMorphElement = (oldNode, newNode) => { - if (newNode instanceof HTMLElement) { - dispatch("turbo:morph-element", { - target: oldNode, - detail: { - newElement: newNode - } - }) - } - } - - static shouldRemoveElement = (node) => { - return this.shouldMorphElement(node) - } - #reloadRemoteFrames() { this.#remoteFrames().forEach((frame) => { if (this.#isFrameReloadedWithMorph(frame)) { - //this.#renderFrameWithMorph(frame) frame.reload() } }) } - #renderFrameWithMorph(frame) { - console.log('renderFrameWithMorph') - frame.addEventListener("turbo:before-frame-render", (event) => { - event.detail.render = this.#morphFrameUpdate - }, { once: true }) - } - - #morphFrameUpdate = (currentElement, newElement) => { - MorphPageRenderer.renderElement(currentElement, newElement.children) - } - - static renderElement(currentElement, newElement) { - console.log(`dispatching turbo:before-frame-morph on `, currentElement.id) - console.log(`and new = `, newElement) - - const morphStyle = 'innerHTML' - - dispatch("turbo:before-frame-morph", { - target: currentElement, - detail: { currentElement, newElement } + #remoteFrames() { + return Array.from(document.querySelectorAll('turbo-frame[src]')).filter(frame => { + return !frame.closest('[data-turbo-permanent]') }) - this.morphElements(currentElement, newElement, morphStyle) } #isFrameReloadedWithMorph(element) { return element.src && element.refresh === "morph" } - - static isFrameReloadedWithMorph(element) { - return element.src && element.refresh === "morph" - } - - #remoteFrames() { - return Array.from(document.querySelectorAll('turbo-frame[src]')).filter(frame => { - return !frame.closest('[data-turbo-permanent]') - }) - } } diff --git a/src/core/frames/morph_frame_renderer.js b/src/core/frames/morph_frame_renderer.js index be53f8375..e95cc02c5 100644 --- a/src/core/frames/morph_frame_renderer.js +++ b/src/core/frames/morph_frame_renderer.js @@ -1,80 +1,16 @@ import { FrameRenderer } from "./frame_renderer" -import { MorphPageRenderer } from "../drive/morph_page_renderer" +import { MorphElements } from "../morph_elements" +import { dispatch } from "../../util" export class MorphFrameRenderer extends FrameRenderer { - static renderElement(currentElement, newElement) { - MorphPageRenderer.renderElement(currentElement, newElement.children) + static renderElement(currentElement, newParentElement) { + const newElement = newParentElement.children - // console.log(`dispatching turbo:before-frame-morph on `, currentElement.id) - // console.log(`and new = `, newElement.id) - // console.log(`and children = `, newElement.children) - - // const morphStyle = 'innerHTML' - - // dispatch("turbo:before-frame-morph", { - // target: currentElement, - // detail: { currentElement, newElement } - // }) - - // this.isMorphingTurboFrame = this.#isFrameReloadedWithMorph(currentElement) - - // Idiomorph.morph(currentElement, newElement, { - // ignoreActiveValue: true, - // morphStyle: morphStyle, - // callbacks: { - // beforeNodeAdded: this.#shouldAddElement, - // beforeNodeMorphed: this.#shouldMorphElement, - // beforeAttributeUpdated: this.#shouldUpdateAttribute, - // beforeNodeRemoved: this.#shouldRemoveElement, - // afterNodeMorphed: this.#didMorphElement - // } - // }) - } - - static #isFrameReloadedWithMorph(element) { - return element.src && element.refresh === "morph" - } - - static #shouldAddElement = (node) => { - return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) - } - - static #shouldMorphElement = (oldNode, newNode) => { - if (!(oldNode instanceof HTMLElement)) return - - if (oldNode.hasAttribute("data-turbo-permanent")) return false - - if (!this.isMorphingTurboFrame && this.#isFrameReloadedWithMorph(oldNode)) return false - - const event = dispatch("turbo:before-morph-element", { - cancelable: true, - target: oldNode, - detail: { - newElement: newNode - } + dispatch("turbo:before-frame-morph", { + target: currentElement, + detail: { currentElement, newElement } }) - return !event.defaultPrevented - } - - static #shouldUpdateAttribute = (attributeName, target, mutationType) => { - const event = dispatch("turbo:before-morph-attribute", { cancelable: true, target, detail: { attributeName, mutationType } }) - - return !event.defaultPrevented - } - - static #shouldRemoveElement = (node) => { - return this.#shouldMorphElement(node) - } - - static #didMorphElement = (oldNode, newNode) => { - if (newNode instanceof HTMLElement) { - dispatch("turbo:morph-element", { - target: oldNode, - detail: { - newElement: newNode - } - }) - } + MorphElements.morph(currentElement, newElement, 'innerHTML') } } diff --git a/src/core/morph_elements.js b/src/core/morph_elements.js new file mode 100644 index 000000000..4936a15fb --- /dev/null +++ b/src/core/morph_elements.js @@ -0,0 +1,66 @@ +import { Idiomorph } from "idiomorph/dist/idiomorph.esm.js" +import { dispatch } from "../util" + +export class MorphElements { + static morph(currentElement, newElement, morphStyle = "outerHTML") { + this.isMorphingTurboFrame = this.isFrameReloadedWithMorph(currentElement) + + Idiomorph.morph(currentElement, newElement, { + morphStyle: morphStyle, + callbacks: { + beforeNodeAdded: this.shouldAddElement, + beforeNodeMorphed: this.shouldMorphElement, + beforeAttributeUpdated: this.shouldUpdateAttribute, + beforeNodeRemoved: this.shouldRemoveElement, + afterNodeMorphed: this.didMorphElement + } + }) + } + + static isFrameReloadedWithMorph(element) { + return element.src && element.refresh === "morph" + } + + static shouldAddElement = (node) => { + return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id)) + } + + static shouldMorphElement = (oldNode, newNode) => { + if (!(oldNode instanceof HTMLElement)) return + + if (oldNode.hasAttribute("data-turbo-permanent")) return false + + if (!this.isMorphingTurboFrame && this.isFrameReloadedWithMorph(oldNode)) return false + + const event = dispatch("turbo:before-morph-element", { + cancelable: true, + target: oldNode, + detail: { + newElement: newNode + } + }) + + return !event.defaultPrevented + } + + static shouldUpdateAttribute = (attributeName, target, mutationType) => { + const event = dispatch("turbo:before-morph-attribute", { cancelable: true, target, detail: { attributeName, mutationType } }) + + return !event.defaultPrevented + } + + static shouldRemoveElement = (node) => { + return this.shouldMorphElement(node) + } + + static didMorphElement = (oldNode, newNode) => { + if (newNode instanceof HTMLElement) { + dispatch("turbo:morph-element", { + target: oldNode, + detail: { + newElement: newNode + } + }) + } + } +}