Repository: honojs/hono
File: src/middleware/jsx/index.ts (TypeScript)

Code before:
const jsxFn = (
  tag: string | Function,
  props: Record<string, any>,
  ...children: (string | HtmlEscapedString)[]
): HtmlEscapedString => {
  if (typeof tag === 'function') {
    return tag.call(null, { ...props, children: children.length <= 1 ? children[0] : children })
  }

  let result = tag !== '' ? `<${tag}` : ''

  const propsKeys = Object.keys(props || {})
  for (let i = 0, len = propsKeys.length; i < len; i++) {
    const v = props[propsKeys[i]]
    if (propsKeys[i] === 'dangerouslySetInnerHTML') {
      if (children.length > 0) {
        throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
      }

      const escapedString = new String(v.__html) as HtmlEscapedString
      escapedString.isEscaped = true
      children = [escapedString]
      continue
    } else if (v === null || v === undefined) {
      continue
    } else if (['checked', 'selected'].includes(propsKeys[i]) && v === false) {
      continue
    } else if (['checked', 'selected'].includes(propsKeys[i]) && (!v || v === true)) {
      result += ` ${propsKeys[i]}="${propsKeys[i].toString().toLowerCase()}"`
      continue
    }

    result += ` ${propsKeys[i]}="${escape(v.toString())}"`
  }

  if (tag !== '') {
    if (emptyTags.includes(tag)) {
      result += '/'
    }
    result += '>'
  }

  const flattenChildren = children.flat(Infinity)
  for (let i = 0, len = flattenChildren.length; i < len; i++) {
    const child = flattenChildren[i]
    if (typeof child === 'boolean' || child === null || child === undefined) {
      continue
    } else if (typeof child === 'object' && (child as any).isEscaped) {
      result += child
    } else {
      result += escape(child.toString())

Review comment (bug):
I've investigated HTML specs. There are other boolean attributes, `disabled`, `readonly` and`multiple`.
See: https://stackoverflow.com/questions/706384/boolean-html-attributes
Lets' add them.

Code after:
const jsxFn = (
  tag: string | Function,
  props: Record<string, any>,
  ...children: (string | HtmlEscapedString)[]
): HtmlEscapedString => {
  if (typeof tag === 'function') {
    return tag.call(null, { ...props, children: children.length <= 1 ? children[0] : children })
  }

  let result = tag !== '' ? `<${tag}` : ''

  const propsKeys = Object.keys(props || {})
  const booleanKeys = ['checked', 'selected', 'disabled', 'readonly', 'multiple']

  for (let i = 0, len = propsKeys.length; i < len; i++) {
    const v = props[propsKeys[i]]
    if (propsKeys[i] === 'dangerouslySetInnerHTML') {
      if (children.length > 0) {
        throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
      }

      const escapedString = new String(v.__html) as HtmlEscapedString
      escapedString.isEscaped = true
      children = [escapedString]
      continue
    } else if (v === null || v === undefined) {
      continue
    } else if (booleanKeys.includes(propsKeys[i]) && v === false) {
      continue
    } else if (booleanKeys.includes(propsKeys[i]) && (!v || v === true)) {
      result += ` ${propsKeys[i]}=""`
      continue
    }

    result += ` ${propsKeys[i]}="${escape(v.toString())}"`
  }

  if (tag !== '') {
    if (emptyTags.includes(tag)) {
      result += '/'
    }
    result += '>'
  }

  const flattenChildren = children.flat(Infinity)
  for (let i = 0, len = flattenChildren.length; i < len; i++) {
    const child = flattenChildren[i]
    if (typeof child === 'boolean' || child === null || child === undefined) {
      continue
    } else if (typeof child === 'object' && (child as any).isEscaped) {
      result += child