import { FiberHost, HTMLElementEx, PropsOf, TAG } from './type' import { isStr } from './reconcile' const defaultObj = {} as const const jointIter =

>( aProps: P, bProps: P, callback: (name: string, a: any, b: any) => void ) => { aProps = aProps || (defaultObj as P) bProps = bProps || (defaultObj as P) Object.keys(aProps).forEach((k) => callback(k, aProps[k], bProps[k])) Object.keys(bProps).forEach( (k) => !aProps.hasOwnProperty(k) && callback(k, undefined, bProps[k]) ) } export const updateElement = ( dom: HTMLElementEx, aProps: PropsOf, bProps: PropsOf ) => { jointIter(aProps, bProps, (name, a, b) => { if (a === b || name === 'children') { } else if (name === 'style' && !isStr(b)) { jointIter(a, b, (styleKey, aStyle, bStyle) => { if (aStyle !== bStyle) { dom[name][styleKey] = bStyle || '' } }) } else if (name[0] === 'o' && name[1] === 'n') { name = name.slice(2).toLowerCase() if (a) dom.removeEventListener(name, a) dom.addEventListener(name, b) } else if (name in dom && !(dom instanceof SVGElement)) { dom[name] = b || '' } else if (b == null || b === false) { // @ts-expect-error Property 'removeAttribute' does not exist on type 'Text'. dom.removeAttribute(name) } else { // @ts-expect-error Property 'setAttribute' does not exist on type 'Text'. dom.setAttribute && dom?.setAttribute(name, b) } }) } export const createElement = (fiber: FiberHost) => { const dom = fiber.type === '#text' ? document.createTextNode('') : fiber.lane & TAG.SVG ? document.createElementNS('http://www.w3.org/2000/svg', fiber.type) : document.createElement(fiber.type) updateElement(dom, {}, fiber.props) return dom }