summaryrefslogtreecommitdiff
path: root/src/frontend/render/utils.ts
blob: 2a1cc9ecf6c49a4c6f1930a3a611705c31c68ca9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import unified from 'unified';
import parse from 'rehype-parse';
import toH from 'hast-to-hyperscript';
import { ComponentRenderer } from '../../@types/renderer';
import moize from 'moize';

/** @internal */
function childrenToTree(children: string[]) {
  return children.map((child) => (unified().use(parse, { fragment: true }).parse(child) as any).children.pop());
}

/**
 * Converts an HTML fragment string into vnodes for rendering via provided framework
 * @param h framework's `createElement` function
 * @param children the HTML string children
 */
export const childrenToVnodes = moize.deep(function childrenToVnodes(h: any, children: string[]) {
  const tree = childrenToTree(children);
  const vnodes = tree.map((subtree) => toH(h, subtree));
  return vnodes;
});

/**
 * Converts an HTML fragment string into h function calls as a string
 * @param h framework's `createElement` function
 * @param children the HTML string children
 */
export const childrenToH = moize.deep(function childrenToH(renderer: ComponentRenderer<any>, children: string[]): any {
  if (!renderer.jsxPragma) return;
  const tree = childrenToTree(children);
  const innerH = (name: any, attrs: Record<string, any> | null = null, _children: string[] | null = null) => {
    const vnode = renderer.jsxPragma?.(name, attrs, _children);
    const childStr = _children ? `, [${_children.map((child) => serializeChild(child)).join(',')}]` : '';
    /* fix(react): avoid hard-coding keys into the serialized tree */
    if (attrs && attrs.key) attrs.key = undefined;
    const __SERIALIZED = `${renderer.jsxPragmaName}("${name}", ${attrs ? JSON.stringify(attrs) : 'null'}${childStr})` as string;
    return { ...vnode, __SERIALIZED };
  };
  const serializeChild = (child: unknown) => {
    if (typeof child === 'string') return `\`${child}\``;
    if (typeof child === 'number' || typeof child === 'boolean') return `${child}`;
    if (child === null) return `null`;
    if ((child as any).__SERIALIZED) return (child as any).__SERIALIZED;
    return innerH(child).__SERIALIZED;
  };
  return tree.map((subtree) => toH(innerH, subtree).__SERIALIZED);
});
/packages/create-astro/test/integrations.test.js?h=fix-s-island-fallback&id=b21a07500284a3621be4d509f5aa67c0a8fcbf07&follow=1'>Add svelte changesetGravatar bluwy 5-39/+51 2024-11-06[ci] release (#12369)astro@4.16.10@astrojs/svelte@5.7.3Gravatar Houston (Bot) 34-81/+74 2024-11-06Update to Vite 6.0.0-beta.6 (#12323)Gravatar Bjorn Lu 15-100/+123 2024-11-06[ci] formatGravatar Bjorn Lu 2-18/+17 2024-11-06Add support for Svelte 5 @render syntax (#12390)Gravatar Bjorn Lu 3-0/+30 2024-11-06fix(deps): update all non-major dependencies (#12366)Gravatar renovate[bot] 29-533/+552