UNPKG

sprae

Version:

DOM microhydration

55 lines (43 loc) 1.75 kB
import sprae, { untracked, frag, _dispose, _state } from "../core.js" const isTemplate = v => !!v?.content /** * HTML directive - sets innerHTML and initializes nested directives. * Supports templates for fragment insertion. * @param {Element | HTMLTemplateElement} el - Target element * @param {Object} state - State object * @returns {(v: string | HTMLTemplateElement | ((html: string) => string)) => void | (() => void)} Update function */ export default (el, state) => { // <template :html="a"/> - fragment case: use placeholder + frag if (el.content) { let _el, html = el.innerHTML, doc = el.ownerDocument, holder = el._holder if (!holder) el.replaceWith(holder = doc.createTextNode('')) return v => { if (typeof v === 'function') v = v(html) // :if case: remove current content from DOM if (el._holder) el.remove(), el.content.replaceChildren() _el?.[_dispose]?.() _el?.remove() if (v != null && v !== '') { _el = isTemplate(v) ? (html = v.innerHTML, frag(v)) : frag((_el = doc.createElement('template'), _el.innerHTML = html = v, _el)) untracked(() => sprae(_el, state)) holder.before(_el.content) // :if case: update childNodes in-place for remove() closure if (el._holder) el.childNodes.splice(0, Infinity, ..._el.childNodes) return _el[_dispose] } else if (el._holder) el.childNodes.length = 0, html = '' } } return v => ( v = typeof v === 'function' ? v(el.innerHTML) : v, isTemplate(v) ? el.replaceChildren(v.content.cloneNode(true)) : (el.innerHTML = v == null ? "" : v), el[_state] &&= null, untracked(() => sprae(el, state)), el[_dispose] ) }