From e4cc5aae735ece2a3538a288f785e049161e87b1 Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Sun, 1 Sep 2024 16:51:32 +0900 Subject: [PATCH] perf(jsx): skip the special behavior when the element is in the head. (#3352) --- src/jsx/base.ts | 2 +- src/jsx/index.test.tsx | 15 +++++++++++++++ src/jsx/intrinsic-element/components.ts | 21 ++++++++++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/jsx/base.ts b/src/jsx/base.ts index 603b09394..029a0d642 100644 --- a/src/jsx/base.ts +++ b/src/jsx/base.ts @@ -327,7 +327,7 @@ export const jsxFn = ( props, children ) - } else if (tag === 'svg') { + } else if (tag === 'svg' || tag === 'head') { nameSpaceContext ||= createContext('') return new JSXNode(tag, props, [ new JSXFunctionNode( diff --git a/src/jsx/index.test.tsx b/src/jsx/index.test.tsx index 5381e642f..82db53a74 100644 --- a/src/jsx/index.test.tsx +++ b/src/jsx/index.test.tsx @@ -470,6 +470,21 @@ describe('render to string', () => { expect(template.toString()).toBe('Hello') }) }) + + describe('head', () => { + it('Simple head elements should be rendered as is', () => { + const template = ( + + Hono! + + + + ) + expect(template.toString()).toBe( + 'Hono!' + ) + }) + }) }) describe('className', () => { diff --git a/src/jsx/intrinsic-element/components.ts b/src/jsx/intrinsic-element/components.ts index d9342bee4..b8ed7dc7c 100644 --- a/src/jsx/intrinsic-element/components.ts +++ b/src/jsx/intrinsic-element/components.ts @@ -106,8 +106,15 @@ const documentMetadataTag = (tag: string, children: Child, props: Props, sort: b export const title: FC = ({ children, ...props }) => { const nameSpaceContext = getNameSpaceContext() - if (nameSpaceContext && useContext(nameSpaceContext) === 'svg') { - new JSXNode('title', props, toArray(children ?? []) as Child[]) + if (nameSpaceContext) { + 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) @@ -116,7 +123,11 @@ export const script: FC> = ({ children, ...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) } @@ -144,6 +155,10 @@ export const link: FC> = ({ childre return documentMetadataTag('link', children, props, 'precedence' in props) } export const meta: FC = ({ children, ...props }) => { + const nameSpaceContext = getNameSpaceContext() + if (nameSpaceContext && useContext(nameSpaceContext) === 'head') { + return returnWithoutSpecialBehavior('meta', children, props) + } return documentMetadataTag('meta', children, props, false) }