0
0
mirror of https://github.com/honojs/hono.git synced 2024-12-01 10:51:01 +00:00
hono/src/middleware/jsx/index.ts

50 lines
1.2 KiB
TypeScript
Raw Normal View History

2022-06-07 10:03:42 +00:00
import type { Context } from '../../context'
import type { Next } from '../../hono'
import { escape } from '../../utils/html'
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace h.JSX {
interface IntrinsicElements {
[tagName: string]: Record<string, string>
}
}
}
export const jsx = () => {
return async (c: Context, next: Next) => {
c.render = (content: string) => {
const output = `<!doctype html>${content.toString()}`
return c.html(output)
}
await next()
}
}
type EscapedString = string & { isEscaped: true }
export const h = (
tag: string | Function,
props: Record<string, any>,
...children: (string | EscapedString)[]
): EscapedString => {
if (typeof tag === 'function') {
return tag.call(null, { ...props, children })
}
let attrs = ''
const propsKeys = Object.keys(props || {})
for (let i = 0, len = propsKeys.length; i < len; i++) {
attrs += ` ${propsKeys[i]}="${escape(props[propsKeys[i]])}"`
}
const res: any = new String(
`<${tag}${attrs}>${children
.flat()
.map((c) => ((c as any).isEscaped ? c : escape(c as string)))
.join('')}</${tag}>`
)
res.isEscaped = true
return res
}