Skip to content

Commit

Permalink
fix(jsx/dom): Intrinsic elements can now also be safely Evaluated mul…
Browse files Browse the repository at this point in the history
…tiple times for the same element
  • Loading branch information
usualoma committed May 21, 2024
1 parent a036181 commit b19749b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 28 deletions.
27 changes: 6 additions & 21 deletions src/jsx/dom/jsx-dev-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
import type { Props, JSXNode } from '../base'
import { normalizeIntrinsicElementProps } from '../utils'

const JSXNodeCompatPrototype = {
type: {
get(this: { tag: string | Function }): string | Function {
return this.tag
},
},
ref: {
get(this: { props?: { ref: unknown } }): unknown {
return this.props?.ref
},
},
}
import { newJSXNode } from './utils'

export const jsxDEV = (tag: string | Function, props: Props, key?: string): JSXNode => {
if (typeof tag === 'string') {
normalizeIntrinsicElementProps(props)
}
return Object.defineProperties(
{
tag,
props,
key,
},
JSXNodeCompatPrototype
) as JSXNode
return newJSXNode({
tag,
props,
key,
})
}

export const Fragment = (props: Record<string, unknown>): JSXNode => jsxDEV('', props, undefined)
18 changes: 11 additions & 7 deletions src/jsx/dom/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { EffectData } from '../hooks'
import { STASH_EFFECT } from '../hooks'
import { styleObjectForEach } from '../utils'
import { createContext } from './context' // import dom-specific versions
import { newJSXNode } from './utils'

const HONO_PORTAL_ELEMENT = '_hp'

Expand Down Expand Up @@ -391,7 +392,7 @@ export const build = (
}
const oldVChildren: Node[] = node.vC ? [...node.vC] : []
const vChildren: Node[] = []
const vChildrenToRemove: Node[] = []
node.vR = []
let prevNode: Node | undefined
try {
children.flat().forEach((c: Child) => {
Expand Down Expand Up @@ -432,7 +433,7 @@ export const build = (
}
child = oldChild
} else if (oldChild.tag !== child.tag) {
vChildrenToRemove.push(oldChild)
node.vR.push(oldChild)
} else {
oldChild.pP = oldChild.props
oldChild.props = child.props
Expand All @@ -455,8 +456,7 @@ export const build = (
}
})
node.vC = vChildren
vChildrenToRemove.push(...oldVChildren)
node.vR = vChildrenToRemove
node.vR.push(...oldVChildren)
} catch (e) {
if (errorHandler) {
const fallbackUpdateFn = () =>
Expand Down Expand Up @@ -494,10 +494,14 @@ const buildNode = (node: Child): Node | undefined => {
} else if (typeof node === 'string' || typeof node === 'number') {
return { t: node.toString(), d: true } as NodeString
} else {
if ('vR' in node) {
node = newJSXNode({
tag: (node as NodeObject).tag,
props: (node as NodeObject).props,
key: (node as NodeObject).key,
})
}
if (typeof (node as JSXNode).tag === 'function') {
if ((node as NodeObject)[DOM_STASH]) {
node = { ...node } as NodeObject
}
;(node as NodeObject)[DOM_STASH] = [0, []]
} else {
const ns = nameSpaceMap[(node as JSXNode).tag as string]
Expand Down
17 changes: 17 additions & 0 deletions src/jsx/dom/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import type { Props, JSXNode } from '../base'
import { DOM_INTERNAL_TAG } from '../constants'

export const setInternalTagFlag = (fn: Function): Function => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(fn as any)[DOM_INTERNAL_TAG] = true
return fn
}

const JSXNodeCompatPrototype = {
type: {
get(this: { tag: string | Function }): string | Function {
return this.tag
},
},
ref: {
get(this: { props?: { ref: unknown } }): unknown {
return this.props?.ref
},
},
}

export const newJSXNode = (obj: { tag: string | Function; props?: Props; key?: string }): JSXNode =>
Object.defineProperties(obj, JSXNodeCompatPrototype) as JSXNode

0 comments on commit b19749b

Please sign in to comment.