Skip to content

Commit

Permalink
Export the morph function
Browse files Browse the repository at this point in the history
  • Loading branch information
hopsoft committed Feb 25, 2024
1 parent 3bf7a3b commit ffd35f3
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 149 deletions.
2 changes: 1 addition & 1 deletion app/assets/builds/@turbo-boost/streams.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions app/assets/builds/@turbo-boost/streams.js.map

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion app/javascript/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import VERSION from './version'
import schema from './schema'
import morph from './morph'
import { invoke, invokeEvents } from './invoke'

if (!self['Turbo'])
Expand All @@ -14,7 +15,7 @@ if (!Turbo['StreamActions'])

Turbo.StreamActions.invoke = invoke
self.TurboBoost = self.TurboBoost || {}
self.TurboBoost.Streams = { invoke, invokeEvents, schema, VERSION }
self.TurboBoost.Streams = { invoke, invokeEvents, morph, schema, VERSION }

console.info('@turbo-boost/streams has initialized and registered new stream actions with Turbo.')

Expand Down
6 changes: 4 additions & 2 deletions app/javascript/invoke.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import morph from './morph'

export const invokeEvents = {
const invokeEvents = {
before: 'turbo-boost:stream:before-invoke',
after: 'turbo-boost:stream:after-invoke',
finish: 'turbo-boost:stream:finish-invoke'
Expand Down Expand Up @@ -93,7 +93,7 @@ function performInvoke(method, args, receivers) {
return invokeMethod(method, args, receivers)
}

export function invoke() {
function invoke() {
const payload = JSON.parse(this.templateContent.textContent)
const { id, selector, receiver, method, args, delay } = payload
let receivers = [{ object: self, target: self }]
Expand All @@ -118,3 +118,5 @@ export function invoke() {
if (delay > 0) setTimeout(() => performInvoke(method, args, receivers), delay)
else performInvoke(method, args, receivers)
}

export { invoke, invokeEvents }
46 changes: 26 additions & 20 deletions app/javascript/morph.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
import { Idiomorph } from 'idiomorph'
import schema from './schema'

const input = /INPUT/i
const inputTypes = /date|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/i
const textarea = /TEXTAREA/i
const trixEditor = /TRIX-EDITOR/i

const morphAllowed = node => {
if (node.nodeType !== Node.ELEMENT_NODE) return true
if (node !== document.activeElement) return true
const defaultOptions = {
callbacks: { beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode) },
morphStyle: 'outerHTML',
ignoreActiveValue: true,
head: { style: 'morph' }
}

function isElement(node) {
return node.nodeType === Node.ELEMENT_NODE
}

// don't morph elements marked as turbo permanent
if (
function isTurboPermanent(node) {
if (!isElement(node)) return false
return (
node.hasAttribute(schema.turboPermanentAttribute) &&
node.getAttribute(schema.turboPermanentAttribute) !== 'false'
)
return false

// don't morph active textarea
if (node.tagName.match(textarea)) return false

// don't morph active trix-editor
if (node.tagName.match(trixEditor)) return false
}

// don't morph active inputs
return node.tagName.match(input) && node.getAttribute('type').match(inputTypes)
function isActive(node) {
if (!isElement(node)) return false
return node === document.activeElement
}

const callbacks = {
beforeNodeMorphed: (oldNode, _newNode) => morphAllowed(oldNode)
function morphAllowed(node) {
if (isTurboPermanent(node)) return false
if (isActive(node) && node.tagName.match(trixEditor)) return false
return true
}

const morph = (element, html) => Idiomorph.morph(element, html, { callbacks })
function morph(element, html, options = {}) {
const callbacks = { ...defaultOptions.callbacks, ...options.callbacks }
options = { ...defaultOptions, ...options, callbacks }
Idiomorph.morph(element, html, options)
}

export default morph
Loading

0 comments on commit ffd35f3

Please sign in to comment.