0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-22 02:27:49 +01:00

perf(jsx): skip the special behavior when the element is in the head. (#3352)

This commit is contained in:
Taku Amano 2024-09-01 16:51:32 +09:00 committed by GitHub
parent 07125309b2
commit e4cc5aae73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 4 deletions

View File

@ -327,7 +327,7 @@ export const jsxFn = (
props, props,
children children
) )
} else if (tag === 'svg') { } else if (tag === 'svg' || tag === 'head') {
nameSpaceContext ||= createContext('') nameSpaceContext ||= createContext('')
return new JSXNode(tag, props, [ return new JSXNode(tag, props, [
new JSXFunctionNode( new JSXFunctionNode(

View File

@ -470,6 +470,21 @@ describe('render to string', () => {
expect(template.toString()).toBe('<span data-text="&lt;html-escaped-string&gt;">Hello</span>') expect(template.toString()).toBe('<span data-text="&lt;html-escaped-string&gt;">Hello</span>')
}) })
}) })
describe('head', () => {
it('Simple head elements should be rendered as is', () => {
const template = (
<head>
<title>Hono!</title>
<meta name='description' content='A description' />
<script src='script.js'></script>
</head>
)
expect(template.toString()).toBe(
'<head><title>Hono!</title><meta name="description" content="A description"/><script src="script.js"></script></head>'
)
})
})
}) })
describe('className', () => { describe('className', () => {

View File

@ -106,8 +106,15 @@ const documentMetadataTag = (tag: string, children: Child, props: Props, sort: b
export const title: FC<PropsWithChildren> = ({ children, ...props }) => { export const title: FC<PropsWithChildren> = ({ children, ...props }) => {
const nameSpaceContext = getNameSpaceContext() const nameSpaceContext = getNameSpaceContext()
if (nameSpaceContext && useContext(nameSpaceContext) === 'svg') { if (nameSpaceContext) {
new JSXNode('title', props, toArray(children ?? []) as Child[]) const context = useContext(nameSpaceContext)
if (context === 'svg' || context === 'head') {
return new JSXNode(
'title',
props,
toArray(children ?? []) as Child[]
) as unknown as HtmlEscapedString
}
} }
return documentMetadataTag('title', children, props, false) return documentMetadataTag('title', children, props, false)
@ -116,7 +123,11 @@ export const script: FC<PropsWithChildren<IntrinsicElements['script']>> = ({
children, children,
...props ...props
}) => { }) => {
if (['src', 'async'].some((k) => !props[k])) { const nameSpaceContext = getNameSpaceContext()
if (
['src', 'async'].some((k) => !props[k]) ||
(nameSpaceContext && useContext(nameSpaceContext) === 'head')
) {
return returnWithoutSpecialBehavior('script', children, props) return returnWithoutSpecialBehavior('script', children, props)
} }
@ -144,6 +155,10 @@ export const link: FC<PropsWithChildren<IntrinsicElements['link']>> = ({ childre
return documentMetadataTag('link', children, props, 'precedence' in props) return documentMetadataTag('link', children, props, 'precedence' in props)
} }
export const meta: FC<PropsWithChildren> = ({ children, ...props }) => { export const meta: FC<PropsWithChildren> = ({ children, ...props }) => {
const nameSpaceContext = getNameSpaceContext()
if (nameSpaceContext && useContext(nameSpaceContext) === 'head') {
return returnWithoutSpecialBehavior('meta', children, props)
}
return documentMetadataTag('meta', children, props, false) return documentMetadataTag('meta', children, props, false)
} }