-
Notifications
You must be signed in to change notification settings - Fork 432
/
Copy pathmorph_elements.js
72 lines (58 loc) · 2.09 KB
/
morph_elements.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { Idiomorph } from "idiomorph/dist/idiomorph.esm.js"
import { dispatch } from "../util"
import { FrameElement } from "../elements/frame_element"
export function morphElements(currentElement, newElement, morphStyle = "outerHTML") {
const renderer = new Renderer()
renderer.morph(currentElement, newElement, morphStyle)
}
class Renderer {
morph(currentElement, newElement, morphStyle) {
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
}
})
}
isFrameReloadedWithMorph(element) {
return (element instanceof FrameElement) && element.shouldReloadWithMorph
}
shouldAddElement = (node) => {
return !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id))
}
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
}
shouldUpdateAttribute = (attributeName, target, mutationType) => {
const event = dispatch("turbo:before-morph-attribute", { cancelable: true, target, detail: { attributeName, mutationType } })
return !event.defaultPrevented
}
shouldRemoveElement = (node) => {
return this.shouldMorphElement(node)
}
didMorphElement = (oldNode, newNode) => {
if (newNode instanceof HTMLElement) {
dispatch("turbo:morph-element", {
target: oldNode,
detail: {
newElement: newNode
}
})
}
}
}