UNPKG

hono

Version:

Web framework built on Web Standards

353 lines (352 loc) 10.4 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var base_exports = {}; __export(base_exports, { Fragment: () => Fragment, JSXFragmentNode: () => JSXFragmentNode, JSXNode: () => JSXNode, cloneElement: () => cloneElement, getNameSpaceContext: () => getNameSpaceContext, isValidElement: () => isValidElement, jsx: () => jsx, jsxFn: () => jsxFn, memo: () => memo, reactAPICompatVersion: () => reactAPICompatVersion }); module.exports = __toCommonJS(base_exports); var import_html = require("../helper/html"); var import_html2 = require("../utils/html"); var import_context = require("./context"); var import_constants = require("./constants"); var import_utils = require("./utils"); var intrinsicElementTags = __toESM(require("./intrinsic-element/components"), 1); var import_common = require("./intrinsic-element/common"); let nameSpaceContext = void 0; const getNameSpaceContext = () => nameSpaceContext; const toSVGAttributeName = (key) => /[A-Z]/.test(key) && key.match( /^(?:al|basel|clip(?:Path|Rule)$|co|do|fill|fl|fo|gl|let|lig|i|marker[EMS]|o|pai|pointe|sh|st[or]|text[^L]|tr|u|ve|w)/ ) ? key.replace(/([A-Z])/g, "-$1").toLowerCase() : key; const emptyTags = [ "area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]; const booleanAttributes = [ "allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "defer", "disabled", "download", "formnovalidate", "hidden", "inert", "ismap", "itemscope", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "selected" ]; const childrenToStringToBuffer = (children, buffer) => { for (let i = 0, len = children.length; i < len; i++) { const child = children[i]; if (typeof child === "string") { (0, import_html2.escapeToBuffer)(child, buffer); } else if (typeof child === "boolean" || child === null || child === void 0) { continue; } else if (child instanceof JSXNode) { child.toStringToBuffer(buffer); } else if (typeof child === "number" || child.isEscaped) { ; buffer[0] += child; } else if (child instanceof Promise) { buffer.unshift("", child); } else { childrenToStringToBuffer(child, buffer); } } }; class JSXNode { tag; props; key; children; isEscaped = true; localContexts; constructor(tag, props, children) { this.tag = tag; this.props = props; this.children = children; } get type() { return this.tag; } get ref() { return this.props.ref || null; } toString() { const buffer = [""]; this.localContexts?.forEach(([context, value]) => { context.values.push(value); }); try { this.toStringToBuffer(buffer); } finally { this.localContexts?.forEach(([context]) => { context.values.pop(); }); } return buffer.length === 1 ? "callbacks" in buffer ? (0, import_html2.resolveCallbackSync)((0, import_html.raw)(buffer[0], buffer.callbacks)).toString() : buffer[0] : (0, import_html2.stringBufferToString)(buffer, buffer.callbacks); } toStringToBuffer(buffer) { const tag = this.tag; const props = this.props; let { children } = this; buffer[0] += `<${tag}`; const normalizeKey = nameSpaceContext && (0, import_context.useContext)(nameSpaceContext) === "svg" ? (key) => toSVGAttributeName((0, import_utils.normalizeIntrinsicElementKey)(key)) : (key) => (0, import_utils.normalizeIntrinsicElementKey)(key); for (let [key, v] of Object.entries(props)) { key = normalizeKey(key); if (key === "children") { } else if (key === "style" && typeof v === "object") { let styleStr = ""; (0, import_utils.styleObjectForEach)(v, (property, value) => { if (value != null) { styleStr += `${styleStr ? ";" : ""}${property}:${value}`; } }); buffer[0] += ' style="'; (0, import_html2.escapeToBuffer)(styleStr, buffer); buffer[0] += '"'; } else if (typeof v === "string") { buffer[0] += ` ${key}="`; (0, import_html2.escapeToBuffer)(v, buffer); buffer[0] += '"'; } else if (v === null || v === void 0) { } else if (typeof v === "number" || v.isEscaped) { buffer[0] += ` ${key}="${v}"`; } else if (typeof v === "boolean" && booleanAttributes.includes(key)) { if (v) { buffer[0] += ` ${key}=""`; } } else if (key === "dangerouslySetInnerHTML") { if (children.length > 0) { throw "Can only set one of `children` or `props.dangerouslySetInnerHTML`."; } children = [(0, import_html.raw)(v.__html)]; } else if (v instanceof Promise) { buffer[0] += ` ${key}="`; buffer.unshift('"', v); } else if (typeof v === "function") { if (!key.startsWith("on")) { throw `Invalid prop '${key}' of type 'function' supplied to '${tag}'.`; } } else { buffer[0] += ` ${key}="`; (0, import_html2.escapeToBuffer)(v.toString(), buffer); buffer[0] += '"'; } } if (emptyTags.includes(tag) && children.length === 0) { buffer[0] += "/>"; return; } buffer[0] += ">"; childrenToStringToBuffer(children, buffer); buffer[0] += `</${tag}>`; } } class JSXFunctionNode extends JSXNode { toStringToBuffer(buffer) { const { children } = this; const res = this.tag.call(null, { ...this.props, children: children.length <= 1 ? children[0] : children }); if (typeof res === "boolean" || res == null) { return; } else if (res instanceof Promise) { if (import_context.globalContexts.length === 0) { buffer.unshift("", res); } else { const currentContexts = import_context.globalContexts.map((c) => [c, c.values.at(-1)]); buffer.unshift( "", res.then((childRes) => { if (childRes instanceof JSXNode) { childRes.localContexts = currentContexts; } return childRes; }) ); } } else if (res instanceof JSXNode) { res.toStringToBuffer(buffer); } else if (typeof res === "number" || res.isEscaped) { buffer[0] += res; if (res.callbacks) { buffer.callbacks ||= []; buffer.callbacks.push(...res.callbacks); } } else { (0, import_html2.escapeToBuffer)(res, buffer); } } } class JSXFragmentNode extends JSXNode { toStringToBuffer(buffer) { childrenToStringToBuffer(this.children, buffer); } } const jsx = (tag, props, ...children) => { props ??= {}; if (children.length) { props.children = children.length === 1 ? children[0] : children; } const key = props.key; delete props["key"]; const node = jsxFn(tag, props, children); node.key = key; return node; }; let initDomRenderer = false; const jsxFn = (tag, props, children) => { if (!initDomRenderer) { for (const k in import_common.domRenderers) { ; intrinsicElementTags[k][import_constants.DOM_RENDERER] = import_common.domRenderers[k]; } initDomRenderer = true; } if (typeof tag === "function") { return new JSXFunctionNode(tag, props, children); } else if (intrinsicElementTags[tag]) { return new JSXFunctionNode( intrinsicElementTags[tag], props, children ); } else if (tag === "svg") { nameSpaceContext ||= (0, import_context.createContext)(""); return new JSXNode(tag, props, [ new JSXFunctionNode( nameSpaceContext, { value: tag }, children ) ]); } else { return new JSXNode(tag, props, children); } }; const shallowEqual = (a, b) => { if (a === b) { return true; } const aKeys = Object.keys(a).sort(); const bKeys = Object.keys(b).sort(); if (aKeys.length !== bKeys.length) { return false; } for (let i = 0, len = aKeys.length; i < len; i++) { if (aKeys[i] === "children" && bKeys[i] === "children" && !a.children?.length && !b.children?.length) { continue; } else if (a[aKeys[i]] !== b[aKeys[i]]) { return false; } } return true; }; const memo = (component, propsAreEqual = shallowEqual) => { let computed = null; let prevProps = void 0; return (props) => { if (prevProps && !propsAreEqual(prevProps, props)) { computed = null; } prevProps = props; return computed ||= component(props); }; }; const Fragment = ({ children }) => { return new JSXFragmentNode( "", { children }, Array.isArray(children) ? children : children ? [children] : [] ); }; const isValidElement = (element) => { return !!(element && typeof element === "object" && "tag" in element && "props" in element); }; const cloneElement = (element, props, ...children) => { return jsx( element.tag, { ...element.props, ...props }, ...children ); }; const reactAPICompatVersion = "19.0.0-hono-jsx"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Fragment, JSXFragmentNode, JSXNode, cloneElement, getNameSpaceContext, isValidElement, jsx, jsxFn, memo, reactAPICompatVersion });