import { type Directive, Phase } from "@mizu/internal/engine"
export type * from "@mizu/internal/engine"
export const _is = {
name: "*is",
phase: Phase.MORPHING,
async execute(renderer, element, { attributes: [attribute], ...options }) {
if (!renderer.isHtmlElement(element)) {
return
}
const tagname = `${await renderer.evaluate(element, attribute.value, options)}`.toLocaleUpperCase()
if (tagname === element.tagName) {
return
}
const original = renderer.cache("*").get(element) ?? element
let morphed = original
if (tagname !== original.tagName) {
morphed = renderer.createElement(tagname)
renderer.cache("*").set(morphed, original)
}
if (element !== morphed) {
for (const child of Array.from(element.childNodes) as HTMLElement[]) {
morphed.appendChild(child)
}
Array.from(element.attributes).forEach((attribute) => morphed.attributes.setNamedItem(attribute.cloneNode(true) as Attr))
element.replaceWith(morphed)
}
if (element !== original) {
renderer.cache("*").delete(element)
}
return { element: morphed }
},
} as Directive
export default _is
|