From 18dc72c445e5feaed852e15d649d21e28992cb81 Mon Sep 17 00:00:00 2001 From: clover caruso Date: Tue, 23 Dec 2025 14:18:14 -0800 Subject: [PATCH] chore(lib/render): rename `children` to `content` this is not React and i want to make it extremely clear. i don't think `children` is a great word for the property. this now also lets you do this with meta tags: ( // -- html -- let page: render.Element = render.element(component, props); - if (layout) page = render.element(layout, { children: page }); + if (layout) page = render.element(layout, { content: page }); const sitegen = sg.context.init(); const { text: body } = await render.async(page, [sitegen]); diff --git a/framework/mdx-hack.tsx b/framework/mdx-hack.tsx index 61e2cc424968a8514b703934bdc34a70b2de921d..927416e6e57dfadea28f4540a996db8a239461cf 100644 --- a/framework/mdx-hack.tsx +++ b/framework/mdx-hack.tsx @@ -1,15 +1,15 @@ export function useMDXComponents() { return { pre: async ( - { filename, whitespace, tint, children: [, , { className, children }] }, + { filename, whitespace, tint, content: [, , { className, content }] }, ) => { const lang = className.split("-")?.[1] ?? null; const code = ["tsx", "jsx", "json", "html", "ts", "js"].includes(lang) ? await highlight.highlightCode( - children.trim(), + content.trim(), lang, ) - : children.trim(); + : content.trim(); return (
{filename &&
{filename}
} @@ -19,10 +19,10 @@ export function useMDXComponents() {
); }, - code: ({ children }) => { + code: ({ content }) => { return ( - {children} + {content} ); }, diff --git a/lib/render.ts b/lib/render.ts index 1ae93c8684f3d942f39c497475132b1023fa7e6a..2758a25b5f6ef48c3310ae9ff594549754076215 100644 --- a/lib/render.ts +++ b/lib/render.ts @@ -14,7 +14,7 @@ * import * as render from "@clo/lib/render.ts"; * console.info(render.sync(

good morning

)); * // jsx is equivilent to: - * console.info(render.sync(render.element("h1", { children: "good morning" }))); + * console.info(render.sync(render.element("h1", { content: "good morning" }))); * ``` * * NOTE: This module is not production ready, but it is in use at https://paperclover.net @@ -154,9 +154,9 @@ export function element( export function resolvedElement( type: ResolvedElement[1], attrs: ResolvedElement[2], - children: ResolvedElement[3], + content: ResolvedElement[3], ): ResolvedElement { - return [kElement, type, attrs, children]; + return [kElement, type, attrs, content]; } /** internal global state while rendering */ @@ -259,8 +259,8 @@ export function resolveNode(r: State, node: unknown): ResolvedNode { } } if (typeof tag !== "string") throw new Error("Unexpected " + inspect(type)); - const children = attrs?.children; - if (children) return [kElement, tag, attrs, resolveNode(r, children)]; + const content = attrs?.content; + if (content) return [kElement, tag, attrs, resolveNode(r, content)]; return node; } if (type === kRaw) return node[1]; @@ -275,7 +275,7 @@ export type ResolvedElement = [ tag: typeof kElement, type: string, attrs: Record, - children: ResolvedNode, + content: ResolvedNode, ]; /** * async rendering is done by creating an array of one item, which is already a @@ -307,7 +307,7 @@ export function stringifyNode(node: ResolvedNode): string { } function stringifyElement(element: ResolvedElement) { - const { 1: tag, 2: attrs, 3: children } = element; + const { 1: tag, 2: attrs, 3: content } = element; let out = "<" + tag; for (const prop in attrs) { const value = attrs[prop]; @@ -336,8 +336,17 @@ function stringifyElement(element: ResolvedElement) { throw new Error( "Do not use the `dangerouslySetInnerHTML` attribute. Use `render.raw()`", ); - // Do not process these case "children": + throw new Error( + "Do not set the `children` attribute to set element contents. Use `content`", + ); + // Do not process these + case "content": + if (tag === "meta") { + attr = `${prop}=${quoteIfNeeded(escapeAttribute(String(value)))}`; + break; + } + continue; case "ref": case "key": continue; @@ -346,7 +355,7 @@ function stringifyElement(element: ResolvedElement) { out += attr; } out = out.trimEnd() + ">"; - if (children) out += stringifyNode(children); + if (content) out += stringifyNode(content); if ( tag !== "br" && tag !== "img" && diff --git a/lib/render/jsx-runtime.ts b/lib/render/jsx-runtime.ts index 71d6900f11fce596389bd3bb58ffe64b02b7a963..cff64b68aff50622f3c109df6ac13b5fbe3a8632 100644 --- a/lib/render/jsx-runtime.ts +++ b/lib/render/jsx-runtime.ts @@ -6,11 +6,11 @@ * * declare global { * namespace JSX { - * export type IntrinsicElements = jsx.IntrinsicElements; - * export type ElementChildrenAttribute = jsx.ElementChildrenAttribute; - * export type Element = jsx.Element; - * export type ElementType = jsx.ElementType; - * export type ElementClass = jsx.ElementClass; + * export type IntrinsicElements = jsx.ts.IntrinsicElements; + * export type ElementChildrenAttribute = jsx.ts.ElementChildrenAttribute; + * export type Element = jsx.ts.Element; + * export type ElementType = jsx.ts.ElementType; + * export type ElementClass = jsx.ts.ElementClass; * } * } * import * as jsx from "@clo/lib/render/jsx-runtime.ts"; @@ -18,30 +18,30 @@ /** this element returns just its contents, and is used by `<>` fragment syntax. */ export function Fragment( - { children }: { children: render.Node[] }, + { content }: { content: render.Node[] }, ): render.Node[] { - return children; + return content; } /** construct a JSX element in production mode. */ export function jsx( type: string | render.Component, - attrs: Record, + { children, ...attrs }: Record, ): render.Element { if (typeof type !== "function" && typeof type !== "string") { throw new Error("Invalid component type: " + render.inspect(type)); } - return render.element(type, attrs); + return render.element(type, { content: children, ...attrs }); } /** construct a JSX element in development mode. */ export function jsxDEV( type: string | render.Component, - attrs: Record, + { children, ...attrs }: Record, // Unused with the clover engine _key: string, // Unused with the clover engine - _isStaticChildren: boolean, + _staticContent: boolean, source: render.SrcLoc, ): render.Element { ASSERT( @@ -59,21 +59,23 @@ export function jsxDEV( ); } - return render.element(type, attrs, source); + return render.element(type, { content: children, ...attrs }, source); } // Clover SSR engine does not yet distinguish between static and non-static JSX. export { jsx as jsxs }; -export interface IntrinsicElements { - [name: string]: Record; +export declare namespace ts { + export interface IntrinsicElements { + [name: string]: Record; + } + export interface ElementChildrenAttribute { + content: render.Node; + } + export type Element = render.Element; + export type ElementType = keyof IntrinsicElements | render.Component; + export type ElementClass = ReturnType; } -export interface ElementChildrenAttribute { - children: render.Node; -} -export type Element = render.Element; -export type ElementType = keyof IntrinsicElements | render.Component; -export type ElementClass = ReturnType; import * as render from "../render.ts"; import { ASSERT } from "../assert.ts"; diff --git a/run.js b/run.js index 89465a89fde98a3898e3750ff566ae90d1a2d028..40290a8d2b2944d28d664b578bf613b8a45b014f 100644 --- a/run.js +++ b/run.js @@ -49,6 +49,7 @@ console.debug = log.debug; console["log"] = log.log; process.on("uncaughtException", (error) => { + console.error("Uncaught Exception"); console.error(error); process.exit(1); }); diff --git a/src/blog/pages/community-translations.mdx b/src/blog/pages/community-translations.mdx index c1ea092b0fc54259b44d1aa9d27c754ca1837b27..18bf9534827fb30351199367d31a13ffa1ebf561 100644 --- a/src/blog/pages/community-translations.mdx +++ b/src/blog/pages/community-translations.mdx @@ -1,5 +1,5 @@ export const meta = { title: "about clover's community translations" }; -export const layout = { default: ({ children }) =>
{children}
}; +export const layout = { default: ({ content }) =>
{content}
}; back to the home page diff --git a/src/blog/tags/heading.tsx b/src/blog/tags/heading.tsx index c396a93a3fb3f1206db13e248cadf2401131aad3..7c0044481a5372040aeae4c6a0d4f3455ec79849 100644 --- a/src/blog/tags/heading.tsx +++ b/src/blog/tags/heading.tsx @@ -1,9 +1,9 @@ -export default function ({ level: Level, slug, children }) { +export default function ({ level: Level, slug, content }) { return ( <> ยง - {children} + {content} ); diff --git a/src/blog/tags/layout.tsx b/src/blog/tags/layout.tsx index 67a3dc6cdf2f5800b98a9b950e93089bca10301b..85450d6f0c4a52cf0bc5ae1149258aa5d77402a5 100644 --- a/src/blog/tags/layout.tsx +++ b/src/blog/tags/layout.tsx @@ -11,7 +11,7 @@ interface LayoutProps { meta: { title: string; description: string; keywords: string[] }; date: string; slug: string; - children: render.Node; + content: render.Node; translation?: { lang: string; @@ -26,7 +26,7 @@ export async function Layout({ meta: { title, description, keywords }, date, slug, - children, + content, translation, }: LayoutProps) { const translations = @@ -95,7 +95,7 @@ export async function Layout({
- {children} + {content} ); diff --git a/src/blog/tags/table-of-contents.tsx b/src/blog/tags/table-of-contents.tsx index 7e95590d62521b35cf430f0a8b689b6d7ccd161c..bf04ef4df73493c7e179d236df3c8e7f1e7e97a1 100644 --- a/src/blog/tags/table-of-contents.tsx +++ b/src/blog/tags/table-of-contents.tsx @@ -1,10 +1,10 @@ import "./table-of-contents.css"; -export default function ({ children }) { +export default function ({ content }) { return (

Contents:

- {children} + {content}
); } diff --git a/src/file-viewer/backend.tsx b/src/file-viewer/backend.tsx index 324f61fd58a0f1052e6599263deee17c0fd341ad..6e28496c0f3451ab784cdaea27a264fd91839bf1 100644 --- a/src/file-viewer/backend.tsx +++ b/src/file-viewer/backend.tsx @@ -249,7 +249,7 @@ function getPartialPage(c: Context, rawFilePath: string) { if (!checkCotyledonCookie(c)) { let root = Speedbump(); // Remove the root element, it's created client side! - root = root[2].children as render.Element; + root = root[2].content as render.Element; const html = render.sync(root).text; c.header("X-Cotyledon", "true"); diff --git a/src/pages/license.mdx b/src/pages/license.mdx index 52a30a3f40698d3228009b62b99d3f93b854b77d..2eebe3a8964c81c7d26d19e54cb9466822c4ece9 100644 --- a/src/pages/license.mdx +++ b/src/pages/license.mdx @@ -1,5 +1,5 @@ export const CurrentYear = () => new Date().getFullYear(); -export default ({children}) =>
{children}
; +export default ({ content }) =>
{content}
; export const theme = { fg: '#ffe', bg: '#434', diff --git a/src/q+a/layout.tsx b/src/q+a/layout.tsx index 06d41ebfd76a319f85b2514f6754895b8626b75e..157d82300eb698cb95f31864ddb91277aae5cf32 100644 --- a/src/q+a/layout.tsx +++ b/src/q+a/layout.tsx @@ -1,6 +1,6 @@ import "./questions.css"; -export default function QuestionLayout({ children }: { children: any }) { +export default function QuestionLayout({ content }: render.Node) { addScript("./header.client.ts"); return (
@@ -9,7 +9,7 @@ export default function QuestionLayout({ children }: { children: any }) { & questions - {children} + {content}
); } @@ -21,10 +21,9 @@ export const theme = { }; export const minimal = { - default: ({ children }: { children: any }) => ( -
{children}
- ), + default: ({ content }: { content: any }) =>
{content}
, theme, }; import { addScript } from "#sitegen"; +import * as render from "lib/render.ts"; diff --git a/src/q+a/tags/clickable-links.client.ts b/src/q+a/tags/clickable-links.client.ts index 549e45721d1a6a3d6b83059e3749502035e0b861..c0c37cdbdd419cdb9ac92aeae2aeab75d6034cd7 100644 --- a/src/q+a/tags/clickable-links.client.ts +++ b/src/q+a/tags/clickable-links.client.ts @@ -11,6 +11,7 @@ async function qaDate(el: HTMLAnchorElement) { time.textContent = "copied permalink to question"; time.classList.add("winner"); } catch (error) { + console.error(error); time.textContent = "failed to copy :("; } setTimeout(() => { diff --git a/tsconfig.json b/tsconfig.json index e7217bd66f71ea30ed7db9188d4c7e9ef7ce3842..f7f1f285334768d35581547abc0f4fb52959e436 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,5 +18,5 @@ "noUncheckedIndexedAccess": true, "resolveJsonModule": true }, - "include": ["framework/**/*", "src/**/*", "lib/**/*"] + "include": ["framework/**/*", "src/**/*", "lib/**/*", "framework/global.d.ts"] } -- 2.54.0