Skip to content

Commit

Permalink
Refactor code to remove duplication
Browse files Browse the repository at this point in the history
  • Loading branch information
krschacht committed Feb 25, 2024
1 parent 047a479 commit e1fde68
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 164 deletions.
97 changes: 5 additions & 92 deletions src/core/drive/morph_page_renderer.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand All @@ -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", {
Expand All @@ -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]')
})
}
}
80 changes: 8 additions & 72 deletions src/core/frames/morph_frame_renderer.js
Original file line number Diff line number Diff line change
@@ -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')
}
}
66 changes: 66 additions & 0 deletions src/core/morph_elements.js
Original file line number Diff line number Diff line change
@@ -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
}
})
}
}
}

0 comments on commit e1fde68

Please sign in to comment.