@tanstack/redact 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/attributes.d.ts +1 -0
- package/dist/core/attributes.js +19 -0
- package/dist/core/attributes.js.map +7 -0
- package/dist/core/internal.d.ts +1 -0
- package/dist/core/internal.js.map +2 -2
- package/dist/dom/dispatcher.js +1 -1
- package/dist/dom/dispatcher.js.map +2 -2
- package/dist/dom/dom.js +9 -7
- package/dist/dom/dom.js.map +2 -2
- package/dist/dom/features/hydration/full.js +19 -3
- package/dist/dom/features/hydration/full.js.map +2 -2
- package/dist/dom/root-internal.js +2 -0
- package/dist/dom/root-internal.js.map +2 -2
- package/dist/server/escape.d.ts +1 -2
- package/dist/server/escape.js +3 -13
- package/dist/server/escape.js.map +2 -2
- package/dist/server/walk.d.ts +1 -0
- package/dist/server/walk.js +9 -4
- package/dist/server/walk.js.map +2 -2
- package/package.json +1 -1
- package/src/core/attributes.ts +17 -0
- package/src/core/internal.ts +1 -0
- package/src/dom/dispatcher.ts +3 -1
- package/src/dom/dom.ts +10 -7
- package/src/dom/features/hydration/full.ts +19 -3
- package/src/dom/root-internal.ts +2 -0
- package/src/server/escape.ts +4 -13
- package/src/server/walk.ts +10 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function attributeName(name: string, isSvg?: boolean): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// packages/redact/src/core/attributes.ts
|
|
2
|
+
function attributeName(name, isSvg = false) {
|
|
3
|
+
if (isSvg && name !== "viewBox" && SVG_KEBAB_PREFIX.test(name)) {
|
|
4
|
+
return name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase());
|
|
5
|
+
}
|
|
6
|
+
if (name === "className") return "class";
|
|
7
|
+
if (name === "htmlFor") return "for";
|
|
8
|
+
if (name === "httpEquiv") return "http-equiv";
|
|
9
|
+
if (name === "acceptCharset") return "accept-charset";
|
|
10
|
+
if (name === "crossOrigin") return "crossorigin";
|
|
11
|
+
if (name === "noModule") return "nomodule";
|
|
12
|
+
if (name === "viewBox") return "viewBox";
|
|
13
|
+
return name.startsWith("aria-") || name.startsWith("data-") ? name : name.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
var SVG_KEBAB_PREFIX = /^(?:clip|fill|stroke)/;
|
|
16
|
+
export {
|
|
17
|
+
attributeName
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=attributes.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/attributes.ts"],
|
|
4
|
+
"sourcesContent": ["export function attributeName(name: string, isSvg = false): string {\n if (isSvg && name !== 'viewBox' && SVG_KEBAB_PREFIX.test(name)) {\n return name.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase())\n }\n if (name === 'className') return 'class'\n if (name === 'htmlFor') return 'for'\n if (name === 'httpEquiv') return 'http-equiv'\n if (name === 'acceptCharset') return 'accept-charset'\n if (name === 'crossOrigin') return 'crossorigin'\n if (name === 'noModule') return 'nomodule'\n if (name === 'viewBox') return 'viewBox'\n return name.startsWith('aria-') || name.startsWith('data-')\n ? name\n : name.toLowerCase()\n}\n\nconst SVG_KEBAB_PREFIX = /^(?:clip|fill|stroke)/\n"],
|
|
5
|
+
"mappings": ";AAAO,SAAS,cAAc,MAAc,QAAQ,OAAe;AACjE,MAAI,SAAS,SAAS,aAAa,iBAAiB,KAAK,IAAI,GAAG;AAC9D,WAAO,KAAK,QAAQ,UAAU,CAAC,MAAM,MAAM,EAAE,YAAY,CAAC;AAAA,EAC5D;AACA,MAAI,SAAS,YAAa,QAAO;AACjC,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,YAAa,QAAO;AACjC,MAAI,SAAS,gBAAiB,QAAO;AACrC,MAAI,SAAS,cAAe,QAAO;AACnC,MAAI,SAAS,WAAY,QAAO;AAChC,MAAI,SAAS,UAAW,QAAO;AAC/B,SAAO,KAAK,WAAW,OAAO,KAAK,KAAK,WAAW,OAAO,IACtD,OACA,KAAK,YAAY;AACvB;AAEA,IAAM,mBAAmB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/core/internal.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export interface FiberRoot {
|
|
|
53
53
|
ce?: ((err: unknown) => void) | undefined;
|
|
54
54
|
ue?: ((err: unknown) => void) | undefined;
|
|
55
55
|
i: string;
|
|
56
|
+
ic: number;
|
|
56
57
|
h: boolean;
|
|
57
58
|
}
|
|
58
59
|
export declare function createFiber(tag: FiberTag, type: any, key: string | null): Fiber;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/internal.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ReactElement, ReactNode, Ref } from './types'\n\nexport const enum FiberTag {\n Host = 0,\n Text = 1,\n Function = 2,\n Class = 3,\n Fragment = 4,\n Portal = 5,\n Provider = 6,\n Consumer = 7,\n ForwardRef = 8,\n Memo = 9,\n Lazy = 10,\n Suspense = 11,\n Root = 12,\n}\n\nexport interface Hook {\n s: any\n q: any\n d: any\n c: any\n n: Hook | null\n}\n\nexport interface Effect {\n t: 0 | 1\n c: () => any\n}\n\nexport interface Fiber {\n tag: FiberTag\n type: any\n key: string | null\n ref: Ref<any> | null\n pp: any\n mp: any\n ms: any\n sn: any\n dom: Node | null\n parent: Fiber | null\n child: Fiber | null\n sibling: Fiber | null\n hooks: Hook | null\n cu: Array<() => void> | null\n dy: boolean\n um: boolean\n root: FiberRoot | null\n}\n\nexport interface FiberRoot {\n c: Element | DocumentFragment\n r: Fiber\n p: Set<Fiber>\n s: boolean\n re?: ((err: unknown) => void) | undefined\n ce?: ((err: unknown) => void) | undefined\n ue?: ((err: unknown) => void) | undefined\n i: string\n h: boolean\n}\n\nexport function createFiber(tag: FiberTag, type: any, key: string | null): Fiber {\n return {\n tag,\n type,\n key,\n ref: null,\n pp: null,\n mp: null,\n ms: null,\n sn: null,\n dom: null,\n parent: null,\n child: null,\n sibling: null,\n hooks: null,\n cu: null,\n dy: false,\n um: false,\n root: null,\n }\n}\n\nexport type ChildNode = ReactElement | string | number | boolean | null | undefined | ChildNode[]\nexport type { ReactElement, ReactNode }\n"],
|
|
5
|
-
"mappings": ";AAEO,IAAW,WAAX,kBAAWA,cAAX;AACL,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,WAAQ,KAAR;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,YAAS,KAAT;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,gBAAa,KAAb;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,MAAP;AACA,EAAAA,oBAAA,cAAW,MAAX;AACA,EAAAA,oBAAA,UAAO,MAAP;AAbgB,SAAAA;AAAA,GAAA;
|
|
4
|
+
"sourcesContent": ["import type { ReactElement, ReactNode, Ref } from './types'\n\nexport const enum FiberTag {\n Host = 0,\n Text = 1,\n Function = 2,\n Class = 3,\n Fragment = 4,\n Portal = 5,\n Provider = 6,\n Consumer = 7,\n ForwardRef = 8,\n Memo = 9,\n Lazy = 10,\n Suspense = 11,\n Root = 12,\n}\n\nexport interface Hook {\n s: any\n q: any\n d: any\n c: any\n n: Hook | null\n}\n\nexport interface Effect {\n t: 0 | 1\n c: () => any\n}\n\nexport interface Fiber {\n tag: FiberTag\n type: any\n key: string | null\n ref: Ref<any> | null\n pp: any\n mp: any\n ms: any\n sn: any\n dom: Node | null\n parent: Fiber | null\n child: Fiber | null\n sibling: Fiber | null\n hooks: Hook | null\n cu: Array<() => void> | null\n dy: boolean\n um: boolean\n root: FiberRoot | null\n}\n\nexport interface FiberRoot {\n c: Element | DocumentFragment\n r: Fiber\n p: Set<Fiber>\n s: boolean\n re?: ((err: unknown) => void) | undefined\n ce?: ((err: unknown) => void) | undefined\n ue?: ((err: unknown) => void) | undefined\n i: string\n ic: number\n h: boolean\n}\n\nexport function createFiber(tag: FiberTag, type: any, key: string | null): Fiber {\n return {\n tag,\n type,\n key,\n ref: null,\n pp: null,\n mp: null,\n ms: null,\n sn: null,\n dom: null,\n parent: null,\n child: null,\n sibling: null,\n hooks: null,\n cu: null,\n dy: false,\n um: false,\n root: null,\n }\n}\n\nexport type ChildNode = ReactElement | string | number | boolean | null | undefined | ChildNode[]\nexport type { ReactElement, ReactNode }\n"],
|
|
5
|
+
"mappings": ";AAEO,IAAW,WAAX,kBAAWA,cAAX;AACL,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,WAAQ,KAAR;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,YAAS,KAAT;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,cAAW,KAAX;AACA,EAAAA,oBAAA,gBAAa,KAAb;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,MAAP;AACA,EAAAA,oBAAA,cAAW,MAAX;AACA,EAAAA,oBAAA,UAAO,MAAP;AAbgB,SAAAA;AAAA,GAAA;AA8DX,SAAS,YAAY,KAAe,MAAW,KAA2B;AAC/E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM;AAAA,EACR;AACF;",
|
|
6
6
|
"names": ["FiberTag"]
|
|
7
7
|
}
|
package/dist/dom/dispatcher.js
CHANGED
|
@@ -173,7 +173,7 @@ function makeDispatcherImpl() {
|
|
|
173
173
|
if (hook.s === void 0) {
|
|
174
174
|
const fiber = getCurrentFiber();
|
|
175
175
|
const root = findRootFromFiber(fiber);
|
|
176
|
-
hook.s =
|
|
176
|
+
hook.s = root ? root.i + (root.ic++).toString(36) : ":r" + (idCounter++).toString(36);
|
|
177
177
|
}
|
|
178
178
|
return hook.s;
|
|
179
179
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/dom/dispatcher.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Hook, Fiber, FiberRoot, Effect } from '../core'\nimport { ReactSharedInternals, REACT_CONTEXT_TYPE } from '../react'\nimport { scheduleUpdate, enqueueEffect, readContext } from './reconcile'\n\nfunction getCurrentFiber(): Fiber {\n const f = ReactSharedInternals.F\n if (!f) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Hook called outside a function component render.')\n }\n throw new Error()\n }\n return f\n}\n\nfunction nextHook(): Hook {\n const fiber = getCurrentFiber()\n const idx = ReactSharedInternals.I++\n\n let prev = ReactSharedInternals.K\n\n if (idx === 0) {\n if (fiber.hooks) {\n ReactSharedInternals.K = fiber.hooks\n return fiber.hooks\n }\n const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }\n fiber.hooks = h\n ReactSharedInternals.K = h\n return h\n }\n\n if (prev && prev.n) {\n ReactSharedInternals.K = prev.n\n return prev.n\n }\n\n const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }\n if (prev) prev.n = h\n else fiber.hooks = h\n ReactSharedInternals.K = h\n return h\n}\n\nfunction depsEqual(\n a: ReadonlyArray<unknown> | undefined,\n b: ReadonlyArray<unknown> | undefined,\n): boolean {\n if (a === b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false\n }\n return true\n}\n\ntype BasicStateAction<S> = S | ((p: S) => S)\n\n// Singleton \u2014 every method reads render context via ReactSharedInternals,\n// and per-hook closures live on the hook itself, so nothing is render-local\n// to capture. Allocating a fresh wrapper + 17 method closures per function-\n// component render was pure GC pressure.\nconst DISPATCHER = makeDispatcherImpl()\n\nexport function makeDispatcher() {\n return DISPATCHER\n}\n\nfunction makeDispatcherImpl() {\n return {\n useState<S>(initial: S | (() => S)): [S, (a: BasicStateAction<S>) => void] {\n return this.useReducer(\n basicReducer as (state: S, action: BasicStateAction<S>) => S,\n typeof initial == 'function' ? (initial as () => S)() : initial,\n )\n },\n\n useReducer<S, A>(reducer: (s: S, a: A) => S, initialArg: any, init?: (a: any) => S) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n if (hook.q === undefined) {\n hook.s = init ? init(initialArg) : initialArg\n const queue: any = { r: reducer }\n const dispatch = (action: A) => {\n const currentState = hook.s as S\n const next = queue.r(currentState, action)\n if (!Object.is(next, currentState)) {\n hook.s = next\n scheduleUpdate(fiber)\n }\n }\n queue.d = dispatch\n hook.q = queue\n } else {\n hook.q.r = reducer\n }\n return [hook.s, hook.q.d] as [S, (a: A) => void]\n },\n\n useEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n const prevDeps = hook.d\n if (prevDeps !== undefined && depsEqual(prevDeps, deps)) return\n hook.d = deps\n const effect: Effect = {\n t: 0,\n c: () => {\n // Run the prior cleanup INSIDE the effect run, not during the\n // dispatch/render phase. If render A \u2192 B \u2192 C all happen back-to-\n // back before the passive microtask drains, dispatch-time cleanup\n // only fires once (between A\u2192B) and fx B + C both run fresh,\n // leaving two side-fx (e.g. two plot SVGs) in the DOM. Doing\n // it here, at effect-run time, means every new create first tears\n // down whatever cleanup is currently live on the hook.\n if (hook.c) {\n try { hook.c() } catch {}\n // The prior cleanup was also pushed onto fiber.cu; remove\n // it so unmount doesn't double-call it.\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n const c = create()\n hook.c = typeof c == 'function' ? c : null\n return hook.c\n },\n }\n enqueueEffect(fiber, effect)\n },\n\n useLayoutEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n const prevDeps = hook.d\n if (prevDeps !== undefined && depsEqual(prevDeps, deps)) return\n hook.d = deps\n const effect: Effect = {\n t: 1,\n c: () => {\n // Mirror useEffect: tear down the prior cleanup at run time so\n // coalesced renders don't leak side-fx.\n if (hook.c) {\n try { hook.c() } catch {}\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n const c = create()\n hook.c = typeof c == 'function' ? c : null\n return hook.c\n },\n }\n enqueueEffect(fiber, effect)\n },\n\n useInsertionEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n return this.useLayoutEffect(create, deps)\n },\n\n useRef<T>(initial: T) {\n const hook = nextHook()\n if (hook.s === undefined) hook.s = { current: initial }\n return hook.s as { current: T }\n },\n\n useMemo<T>(factory: () => T, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n if (hook.d !== undefined && depsEqual(hook.d, deps)) {\n return hook.s as T\n }\n const value = factory()\n hook.s = value\n hook.d = deps\n return value\n },\n\n useCallback<T extends Function>(fn: T, deps?: ReadonlyArray<unknown>): T {\n return this.useMemo(() => fn, deps) as T\n },\n\n useContext<T>(ctx: any): T {\n const fiber = getCurrentFiber()\n return readContext(fiber, ctx)\n },\n\n useImperativeHandle<T>(ref: any, factory: () => T, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n if (hook.d !== undefined && depsEqual(hook.d, deps)) return\n hook.d = deps\n const value = factory()\n if (ref) {\n if (typeof ref == 'function') ref(value)\n else ref.current = value\n }\n },\n\n useDebugValue<T>(_value: T, _formatter?: (v: T) => any): void {\n // noop\n },\n\n useId(): string {\n const hook = nextHook()\n if (hook.s === undefined) {\n const fiber = getCurrentFiber()\n const root = findRootFromFiber(fiber)\n hook.s = (root?.i ?? ':r') + (idCounter++).toString(36)\n }\n return hook.s as string\n },\n\n useTransition(): [boolean, (fn: () => void) => void] {\n return [false, (fn: () => void) => fn()]\n },\n\n useDeferredValue<T>(v: T): T {\n return v\n },\n\n useSyncExternalStore<T>(\n subscribe: (cb: () => void) => () => void,\n getSnapshot: () => T,\n getServerSnapshot?: () => T,\n ): T {\n const fiber = getCurrentFiber()\n const hook = nextHook()\n const store: {\n g: () => T\n s: (() => T) | undefined\n } = hook.q ?? {\n g: getSnapshot,\n s: getServerSnapshot,\n }\n hook.q = store\n store.g = getSnapshot\n store.s = getServerSnapshot\n\n // During hydration, use the server snapshot (if provided) so the tree\n // matches the SSR output. Components like TanStack Router's ClientOnly\n // rely on this: they render `false` on server, `true` on client \u2014 and\n // if we return `true` during hydration, client and server diverge and\n // the tree mounts fresh next to the SSR fallback DOM.\n const root = fiber.root ?? findRootFromFiber(fiber)\n const isHydrating = Boolean(root?.h)\n const value =\n isHydrating && getServerSnapshot ? getServerSnapshot() : getSnapshot()\n hook.s = value\n\n const deps = [subscribe]\n if (hook.d === undefined || !depsEqual(hook.d, deps)) {\n hook.d = deps\n const effect: Effect = {\n t: 1,\n c: () => {\n if (hook.c) {\n try {\n hook.c()\n } catch {\n // ignore cleanup failures\n }\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n\n let unsubscribed = false\n const cleanup = () => {\n unsubscribed = true\n if (typeof unsubscribe == 'function') {\n unsubscribe()\n }\n }\n const forceUpdate = () => {\n if (unsubscribed || fiber.um) {\n return\n }\n\n let next: T\n try {\n next = store.g()\n } catch {\n scheduleUpdate(fiber)\n return\n }\n\n if (!Object.is(hook.s, next)) {\n hook.s = next\n scheduleUpdate(fiber)\n }\n }\n const unsubscribe = subscribe(forceUpdate)\n\n // If we served the server snapshot, run a post-hydration check so\n // components like `useHydrated()` flip from false \u2192 true after the\n // initial render commits. Queued late so hydration finishes first.\n if (isHydrating && store.s) {\n queueMicrotask(() => queueMicrotask(forceUpdate))\n }\n\n forceUpdate()\n hook.c = cleanup\n return cleanup\n },\n }\n enqueueEffect(fiber, effect)\n }\n return value\n },\n\n use<T>(resource: any): T {\n if (resource == null) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('use() received null or undefined')\n }\n throw new Error()\n }\n if (resource.$$typeof === REACT_CONTEXT_TYPE) {\n return readContext(getCurrentFiber(), resource)\n }\n if (typeof resource.then == 'function') {\n const thenable = resource\n switch (thenable.status) {\n case 'fulfilled':\n return thenable.value\n case 'rejected':\n throw thenable.reason\n default: {\n if (thenable.status === undefined) {\n thenable.status = 'pending'\n thenable.then(\n (v: any) => {\n if (thenable.status === 'pending') {\n thenable.status = 'fulfilled'\n thenable.value = v\n }\n },\n (e: any) => {\n if (thenable.status === 'pending') {\n thenable.status = 'rejected'\n thenable.reason = e\n }\n },\n )\n }\n throw thenable\n }\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('use() expected a Promise or Context')\n }\n throw new Error()\n },\n }\n}\n\nfunction basicReducer<S>(state: S, action: BasicStateAction<S>): S {\n return typeof action == 'function' ? (action as (p: S) => S)(state) : action\n}\n\nlet idCounter = 0\n\nfunction findRootFromFiber(fiber: Fiber): FiberRoot | null {\n let f: Fiber | null = fiber\n while (f) {\n if (f.root) return f.root\n f = f.parent\n }\n return null\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { Hook, Fiber, FiberRoot, Effect } from '../core'\nimport { ReactSharedInternals, REACT_CONTEXT_TYPE } from '../react'\nimport { scheduleUpdate, enqueueEffect, readContext } from './reconcile'\n\nfunction getCurrentFiber(): Fiber {\n const f = ReactSharedInternals.F\n if (!f) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Hook called outside a function component render.')\n }\n throw new Error()\n }\n return f\n}\n\nfunction nextHook(): Hook {\n const fiber = getCurrentFiber()\n const idx = ReactSharedInternals.I++\n\n let prev = ReactSharedInternals.K\n\n if (idx === 0) {\n if (fiber.hooks) {\n ReactSharedInternals.K = fiber.hooks\n return fiber.hooks\n }\n const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }\n fiber.hooks = h\n ReactSharedInternals.K = h\n return h\n }\n\n if (prev && prev.n) {\n ReactSharedInternals.K = prev.n\n return prev.n\n }\n\n const h: Hook = { s: undefined, q: undefined, d: undefined, c: undefined, n: null }\n if (prev) prev.n = h\n else fiber.hooks = h\n ReactSharedInternals.K = h\n return h\n}\n\nfunction depsEqual(\n a: ReadonlyArray<unknown> | undefined,\n b: ReadonlyArray<unknown> | undefined,\n): boolean {\n if (a === b) return true\n if (!a || !b) return false\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false\n }\n return true\n}\n\ntype BasicStateAction<S> = S | ((p: S) => S)\n\n// Singleton \u2014 every method reads render context via ReactSharedInternals,\n// and per-hook closures live on the hook itself, so nothing is render-local\n// to capture. Allocating a fresh wrapper + 17 method closures per function-\n// component render was pure GC pressure.\nconst DISPATCHER = makeDispatcherImpl()\n\nexport function makeDispatcher() {\n return DISPATCHER\n}\n\nfunction makeDispatcherImpl() {\n return {\n useState<S>(initial: S | (() => S)): [S, (a: BasicStateAction<S>) => void] {\n return this.useReducer(\n basicReducer as (state: S, action: BasicStateAction<S>) => S,\n typeof initial == 'function' ? (initial as () => S)() : initial,\n )\n },\n\n useReducer<S, A>(reducer: (s: S, a: A) => S, initialArg: any, init?: (a: any) => S) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n if (hook.q === undefined) {\n hook.s = init ? init(initialArg) : initialArg\n const queue: any = { r: reducer }\n const dispatch = (action: A) => {\n const currentState = hook.s as S\n const next = queue.r(currentState, action)\n if (!Object.is(next, currentState)) {\n hook.s = next\n scheduleUpdate(fiber)\n }\n }\n queue.d = dispatch\n hook.q = queue\n } else {\n hook.q.r = reducer\n }\n return [hook.s, hook.q.d] as [S, (a: A) => void]\n },\n\n useEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n const prevDeps = hook.d\n if (prevDeps !== undefined && depsEqual(prevDeps, deps)) return\n hook.d = deps\n const effect: Effect = {\n t: 0,\n c: () => {\n // Run the prior cleanup INSIDE the effect run, not during the\n // dispatch/render phase. If render A \u2192 B \u2192 C all happen back-to-\n // back before the passive microtask drains, dispatch-time cleanup\n // only fires once (between A\u2192B) and fx B + C both run fresh,\n // leaving two side-fx (e.g. two plot SVGs) in the DOM. Doing\n // it here, at effect-run time, means every new create first tears\n // down whatever cleanup is currently live on the hook.\n if (hook.c) {\n try { hook.c() } catch {}\n // The prior cleanup was also pushed onto fiber.cu; remove\n // it so unmount doesn't double-call it.\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n const c = create()\n hook.c = typeof c == 'function' ? c : null\n return hook.c\n },\n }\n enqueueEffect(fiber, effect)\n },\n\n useLayoutEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n const fiber = getCurrentFiber()\n const prevDeps = hook.d\n if (prevDeps !== undefined && depsEqual(prevDeps, deps)) return\n hook.d = deps\n const effect: Effect = {\n t: 1,\n c: () => {\n // Mirror useEffect: tear down the prior cleanup at run time so\n // coalesced renders don't leak side-fx.\n if (hook.c) {\n try { hook.c() } catch {}\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n const c = create()\n hook.c = typeof c == 'function' ? c : null\n return hook.c\n },\n }\n enqueueEffect(fiber, effect)\n },\n\n useInsertionEffect(create: () => any, deps?: ReadonlyArray<unknown>) {\n return this.useLayoutEffect(create, deps)\n },\n\n useRef<T>(initial: T) {\n const hook = nextHook()\n if (hook.s === undefined) hook.s = { current: initial }\n return hook.s as { current: T }\n },\n\n useMemo<T>(factory: () => T, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n if (hook.d !== undefined && depsEqual(hook.d, deps)) {\n return hook.s as T\n }\n const value = factory()\n hook.s = value\n hook.d = deps\n return value\n },\n\n useCallback<T extends Function>(fn: T, deps?: ReadonlyArray<unknown>): T {\n return this.useMemo(() => fn, deps) as T\n },\n\n useContext<T>(ctx: any): T {\n const fiber = getCurrentFiber()\n return readContext(fiber, ctx)\n },\n\n useImperativeHandle<T>(ref: any, factory: () => T, deps?: ReadonlyArray<unknown>) {\n const hook = nextHook()\n if (hook.d !== undefined && depsEqual(hook.d, deps)) return\n hook.d = deps\n const value = factory()\n if (ref) {\n if (typeof ref == 'function') ref(value)\n else ref.current = value\n }\n },\n\n useDebugValue<T>(_value: T, _formatter?: (v: T) => any): void {\n // noop\n },\n\n useId(): string {\n const hook = nextHook()\n if (hook.s === undefined) {\n const fiber = getCurrentFiber()\n const root = findRootFromFiber(fiber)\n hook.s = root\n ? root.i + (root.ic++).toString(36)\n : ':r' + (idCounter++).toString(36)\n }\n return hook.s as string\n },\n\n useTransition(): [boolean, (fn: () => void) => void] {\n return [false, (fn: () => void) => fn()]\n },\n\n useDeferredValue<T>(v: T): T {\n return v\n },\n\n useSyncExternalStore<T>(\n subscribe: (cb: () => void) => () => void,\n getSnapshot: () => T,\n getServerSnapshot?: () => T,\n ): T {\n const fiber = getCurrentFiber()\n const hook = nextHook()\n const store: {\n g: () => T\n s: (() => T) | undefined\n } = hook.q ?? {\n g: getSnapshot,\n s: getServerSnapshot,\n }\n hook.q = store\n store.g = getSnapshot\n store.s = getServerSnapshot\n\n // During hydration, use the server snapshot (if provided) so the tree\n // matches the SSR output. Components like TanStack Router's ClientOnly\n // rely on this: they render `false` on server, `true` on client \u2014 and\n // if we return `true` during hydration, client and server diverge and\n // the tree mounts fresh next to the SSR fallback DOM.\n const root = fiber.root ?? findRootFromFiber(fiber)\n const isHydrating = Boolean(root?.h)\n const value =\n isHydrating && getServerSnapshot ? getServerSnapshot() : getSnapshot()\n hook.s = value\n\n const deps = [subscribe]\n if (hook.d === undefined || !depsEqual(hook.d, deps)) {\n hook.d = deps\n const effect: Effect = {\n t: 1,\n c: () => {\n if (hook.c) {\n try {\n hook.c()\n } catch {\n // ignore cleanup failures\n }\n if (fiber.cu) {\n const i = fiber.cu.indexOf(hook.c)\n if (i >= 0) fiber.cu.splice(i, 1)\n }\n hook.c = null\n }\n\n let unsubscribed = false\n const cleanup = () => {\n unsubscribed = true\n if (typeof unsubscribe == 'function') {\n unsubscribe()\n }\n }\n const forceUpdate = () => {\n if (unsubscribed || fiber.um) {\n return\n }\n\n let next: T\n try {\n next = store.g()\n } catch {\n scheduleUpdate(fiber)\n return\n }\n\n if (!Object.is(hook.s, next)) {\n hook.s = next\n scheduleUpdate(fiber)\n }\n }\n const unsubscribe = subscribe(forceUpdate)\n\n // If we served the server snapshot, run a post-hydration check so\n // components like `useHydrated()` flip from false \u2192 true after the\n // initial render commits. Queued late so hydration finishes first.\n if (isHydrating && store.s) {\n queueMicrotask(() => queueMicrotask(forceUpdate))\n }\n\n forceUpdate()\n hook.c = cleanup\n return cleanup\n },\n }\n enqueueEffect(fiber, effect)\n }\n return value\n },\n\n use<T>(resource: any): T {\n if (resource == null) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('use() received null or undefined')\n }\n throw new Error()\n }\n if (resource.$$typeof === REACT_CONTEXT_TYPE) {\n return readContext(getCurrentFiber(), resource)\n }\n if (typeof resource.then == 'function') {\n const thenable = resource\n switch (thenable.status) {\n case 'fulfilled':\n return thenable.value\n case 'rejected':\n throw thenable.reason\n default: {\n if (thenable.status === undefined) {\n thenable.status = 'pending'\n thenable.then(\n (v: any) => {\n if (thenable.status === 'pending') {\n thenable.status = 'fulfilled'\n thenable.value = v\n }\n },\n (e: any) => {\n if (thenable.status === 'pending') {\n thenable.status = 'rejected'\n thenable.reason = e\n }\n },\n )\n }\n throw thenable\n }\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('use() expected a Promise or Context')\n }\n throw new Error()\n },\n }\n}\n\nfunction basicReducer<S>(state: S, action: BasicStateAction<S>): S {\n return typeof action == 'function' ? (action as (p: S) => S)(state) : action\n}\n\nlet idCounter = 0\n\nfunction findRootFromFiber(fiber: Fiber): FiberRoot | null {\n let f: Fiber | null = fiber\n while (f) {\n if (f.root) return f.root\n f = f.parent\n }\n return null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["h"]
|
|
7
7
|
}
|
package/dist/dom/dom.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// packages/redact/src/dom/dom.ts
|
|
2
|
+
import { attributeName } from "../core/attributes";
|
|
2
3
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
3
4
|
var BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
|
|
4
5
|
"allowfullscreen",
|
|
@@ -50,6 +51,7 @@ function isSvgElement(el) {
|
|
|
50
51
|
}
|
|
51
52
|
function setProp(el, name, next, prev, isSvg) {
|
|
52
53
|
if (name === "children" || name === "key" || name === "ref") return;
|
|
54
|
+
const attr = attributeName(name, isSvg);
|
|
53
55
|
if (name === "defaultValue" || name === "defaultChecked") {
|
|
54
56
|
if (prev === void 0 && next != null) {
|
|
55
57
|
try {
|
|
@@ -103,26 +105,26 @@ function setProp(el, name, next, prev, isSvg) {
|
|
|
103
105
|
}
|
|
104
106
|
}
|
|
105
107
|
if (BOOLEAN_ATTRS.has(name.toLowerCase())) {
|
|
106
|
-
if (next) el.setAttribute(
|
|
107
|
-
else el.removeAttribute(
|
|
108
|
+
if (next) el.setAttribute(attr, "");
|
|
109
|
+
else el.removeAttribute(attr);
|
|
108
110
|
return;
|
|
109
111
|
}
|
|
110
112
|
if (name.length > 5 && (name.charCodeAt(0) === 97 || name.charCodeAt(0) === 100)) {
|
|
111
113
|
if (name.startsWith("aria-") || name.startsWith("data-")) {
|
|
112
114
|
if (next == null) {
|
|
113
|
-
el.removeAttribute(
|
|
115
|
+
el.removeAttribute(attr);
|
|
114
116
|
} else {
|
|
115
|
-
el.setAttribute(
|
|
117
|
+
el.setAttribute(attr, "" + next);
|
|
116
118
|
}
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
122
|
if (next == null || next === false) {
|
|
121
|
-
el.removeAttribute(
|
|
123
|
+
el.removeAttribute(attr);
|
|
122
124
|
} else if (next === true) {
|
|
123
|
-
el.setAttribute(
|
|
125
|
+
el.setAttribute(attr, "");
|
|
124
126
|
} else {
|
|
125
|
-
el.setAttribute(
|
|
127
|
+
el.setAttribute(attr, "" + next);
|
|
126
128
|
}
|
|
127
129
|
}
|
|
128
130
|
function setStyle(el, next, prev) {
|
package/dist/dom/dom.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/dom/dom.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";AAAA,IAAM,SAAS;AAEf,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,eAAe,MAAc,OAAyB;AACpE,MAAI,SAAS,SAAS,OAAO;AAC3B,WAAO,SAAS,gBAAgB,QAAQ,IAAI;AAAA,EAC9C;AACA,SAAO,SAAS,cAAc,IAAI;AACpC;AAEO,SAAS,aAAa,IAAsB;AACjD,SAAQ,GAAW,oBAAoB,UAAa,GAAG,YAAY;AACrE;AAEO,SAAS,QACd,IACA,MACA,MACA,MACA,OACM;AACN,MAAI,SAAS,cAAc,SAAS,SAAS,SAAS,MAAO;
|
|
4
|
+
"sourcesContent": ["import { attributeName } from '../core/attributes'\n\nconst SVG_NS = 'http://www.w3.org/2000/svg'\n\nconst BOOLEAN_ATTRS = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n])\n\nconst IDL_ATTRS = new Set([\n 'value',\n 'checked',\n 'selected',\n 'disabled',\n 'multiple',\n 'muted',\n 'readonly',\n 'contentEditable',\n 'spellcheck',\n 'draggable',\n])\n\nexport function createHostNode(type: string, isSvg: boolean): Element {\n if (isSvg || type === 'svg') {\n return document.createElementNS(SVG_NS, type)\n }\n return document.createElement(type)\n}\n\nexport function isSvgElement(el: Element): boolean {\n return (el as any).ownerSVGElement !== undefined || el.tagName === 'svg'\n}\n\nexport function setProp(\n el: Element,\n name: string,\n next: any,\n prev: any,\n isSvg: boolean,\n): void {\n if (name === 'children' || name === 'key' || name === 'ref') return\n const attr = attributeName(name, isSvg)\n\n // defaultValue / defaultChecked are IDL-property-only \u2014 they seed the\n // initial value/checked of a form control on first mount and must NOT be\n // emitted as HTML attributes (which would leak as `defaultValue=\"...\"`).\n // Setting `el.defaultValue` on a fresh control also sets the initial\n // `el.value`, which is what consumers expect. Skip on hydrated DOM so we\n // don't clobber a live user-typed value.\n if (name === 'defaultValue' || name === 'defaultChecked') {\n if (prev === undefined && next != null) {\n try {\n ;(el as any)[name] = next\n } catch {}\n }\n return\n }\n\n if (name === 'className') {\n if (isSvg) {\n if (next == null) el.removeAttribute('class')\n else el.setAttribute('class', '' + next)\n } else {\n ;(el as HTMLElement).className = next == null ? '' : '' + next\n }\n return\n }\n\n if (name === 'class') {\n if (next == null) el.removeAttribute('class')\n else el.setAttribute('class', '' + next)\n return\n }\n\n if (name === 'style') {\n setStyle(el as HTMLElement, next, prev)\n return\n }\n\n if (name === 'dangerouslySetInnerHTML') {\n const nextHtml = next?.__html ?? ''\n const prevHtml = prev?.__html ?? ''\n if (nextHtml !== prevHtml) (el as HTMLElement).innerHTML = nextHtml\n return\n }\n\n if (name[0] === 'o' && name[1] === 'n') {\n setEventHandler(el, name, next, prev)\n return\n }\n\n if (name === 'htmlFor') {\n if (next == null) el.removeAttribute('for')\n else el.setAttribute('for', '' + next)\n return\n }\n\n if (!isSvg && IDL_ATTRS.has(name) && name in el) {\n try {\n ;(el as any)[name] = next == null ? '' : next\n return\n } catch {}\n }\n\n if (BOOLEAN_ATTRS.has(name.toLowerCase())) {\n if (next) el.setAttribute(attr, '')\n else el.removeAttribute(attr)\n return\n }\n\n // aria-* and data-* attributes stringify booleans to `\"true\"`/`\"false\"`\n // rather than using the HTML boolean-attribute presence/absence semantics.\n // This matches React and the ARIA spec (aria-hidden=\"false\" is meaningful).\n if (name.length > 5 && (name.charCodeAt(0) === 97 /* a */ || name.charCodeAt(0) === 100 /* d */)) {\n if (name.startsWith('aria-') || name.startsWith('data-')) {\n if (next == null) {\n el.removeAttribute(attr)\n } else {\n el.setAttribute(attr, '' + next)\n }\n return\n }\n }\n\n if (next == null || next === false) {\n el.removeAttribute(attr)\n } else if (next === true) {\n el.setAttribute(attr, '')\n } else {\n el.setAttribute(attr, '' + next)\n }\n}\n\nfunction setStyle(el: HTMLElement, next: any, prev: any): void {\n const style = el.style\n if (typeof next === 'string') {\n style.cssText = next\n return\n }\n if (typeof prev === 'string') style.cssText = ''\n if (prev && typeof prev === 'object') {\n for (const k in prev) {\n if (!next || !(k in next)) setStyleProperty(style, k, '')\n }\n }\n if (next && typeof next === 'object') {\n for (const k in next) {\n if (!prev || prev[k] !== next[k]) setStyleProperty(style, k, next[k])\n }\n }\n}\n\nfunction setStyleProperty(style: CSSStyleDeclaration, key: string, value: any): void {\n if (key[0] === '-') {\n style.setProperty(key, value == null ? '' : '' + value)\n } else if (value == null || value === '') {\n ;(style as any)[key] = ''\n } else if (typeof value === 'number' && !UNITLESS_STYLE.has(key)) {\n ;(style as any)[key] = value + 'px'\n } else {\n ;(style as any)[key] = '' + value\n }\n}\n\nconst UNITLESS_STYLE = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n])\n\nexport interface SyntheticEvent extends Event {\n nativeEvent: Event\n isDefaultPrevented(): boolean\n isPropagationStopped(): boolean\n persist(): void\n currentTarget: EventTarget & Element\n}\n\nfunction setEventHandler(el: Element, name: string, next: any, prev: any): void {\n // Only function handlers are accepted. Reject strings/objects/etc \u2014 the\n // legacy `onclick=\"...\"` HTML attribute (string handler) is a known XSS\n // vector if a parent spreads untrusted props onto a host element. React\n // also ignores non-function handlers.\n if (next != null && typeof next != 'function') next = null\n\n const capture = name.endsWith('Capture')\n const reactEventName = name.slice(2, capture ? -7 : undefined)\n const eventName = domEventFor(reactEventName, el)\n\n // Key by the React prop name (not DOM event name) so `onChange` and\n // `onInput` on the same text input \u2014 which both dispatch from the native\n // `input` event \u2014 can coexist without clobbering each other's handlers.\n const handlers = ((el as any).__handlers ||= Object.create(null))\n const key = name\n\n const existing = handlers[key]\n\n if (existing && !next) {\n el.removeEventListener(existing.event, existing.listener, existing.capture)\n handlers[key] = null\n return\n }\n\n if (!existing && next) {\n const entry = {\n current: next as Function,\n listener: null as any,\n event: eventName,\n capture,\n }\n entry.listener = (e: Event) => {\n // React hands handlers a SyntheticEvent that carries `.nativeEvent`.\n // Many libraries check `event.nativeEvent.isComposing` (react-instantsearch)\n // or `event.nativeEvent.shiftKey` (UI kits) \u2014 without the alias they throw\n // on `undefined.foo`. Aliasing the native event to itself is the cheapest\n // way to satisfy the shape without building a full synthetic layer.\n if ((e as any).nativeEvent === undefined) (e as any).nativeEvent = e\n entry.current(e)\n }\n handlers[key] = entry\n el.addEventListener(eventName, entry.listener, capture)\n return\n }\n\n if (existing) {\n // Re-bind if the effective DOM event changed (e.g. <input> whose `type`\n // flipped from \"text\" to \"checkbox\" \u2014 onChange should now follow `change`\n // instead of `input`). This is rare but keeps semantics correct.\n if (existing.event !== eventName || existing.capture !== capture) {\n el.removeEventListener(existing.event, existing.listener, existing.capture)\n existing.event = eventName\n existing.capture = capture\n el.addEventListener(eventName, existing.listener, capture)\n }\n existing.current = next\n }\n}\n\nfunction domEventFor(reactEventName: string, el: Element): string {\n const lower = reactEventName.toLowerCase()\n // React's `onChange` on text-like <input> and <textarea> maps to the\n // native `input` event so handlers fire on every keystroke. On checkbox,\n // radio, file inputs, and <select>, React's `onChange` maps to the\n // native `change` event (which fires on click / option select).\n if (lower === 'change') {\n const tag = el.tagName\n if (tag === 'TEXTAREA') return 'input'\n if (tag === 'INPUT') {\n const type = ((el as HTMLInputElement).type || 'text').toLowerCase()\n if (type !== 'checkbox' && type !== 'radio' && type !== 'file') {\n return 'input'\n }\n }\n }\n if (lower === 'doubleclick') return 'dblclick'\n return lower\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
FiberTag,
|
|
4
4
|
REACT_ELEMENT_TYPE
|
|
5
5
|
} from "../../../core";
|
|
6
|
+
import { attributeName } from "../../../core/attributes";
|
|
6
7
|
import { createHostNode, setProp } from "../../dom";
|
|
7
8
|
import { drainReplayQueue } from "../../event-replay";
|
|
8
9
|
import { discardPendingWork, findRoot, flushSyncWork, renderRoot } from "../../reconcile";
|
|
@@ -84,7 +85,14 @@ var HydrationCursor = class {
|
|
|
84
85
|
has() {
|
|
85
86
|
let n = this.n;
|
|
86
87
|
while (n && n !== this.e) {
|
|
87
|
-
if (n.nodeType === 1
|
|
88
|
+
if (n.nodeType === 1) {
|
|
89
|
+
if (n.tagName === "SCRIPT") {
|
|
90
|
+
n = n.nextSibling;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (n.nodeType === 3 && n.data.trim() !== "") return true;
|
|
88
96
|
n = n.nextSibling;
|
|
89
97
|
}
|
|
90
98
|
return false;
|
|
@@ -104,7 +112,10 @@ function hydrateRootImpl(container, initialChildren, options) {
|
|
|
104
112
|
const target = container;
|
|
105
113
|
const isDocument = container.nodeType === 9;
|
|
106
114
|
const body = isDocument ? target.body : null;
|
|
107
|
-
const root = createFiberRoot(target,
|
|
115
|
+
const root = createFiberRoot(target, {
|
|
116
|
+
...options,
|
|
117
|
+
identifierPrefix: options.identifierPrefix ?? ":R"
|
|
118
|
+
});
|
|
108
119
|
installHydrationScrollGuard();
|
|
109
120
|
const normalizedInitialChildren = isDocument ? normalizeDocumentChildren(initialChildren) : initialChildren;
|
|
110
121
|
let documentBodyFallback = false;
|
|
@@ -138,6 +149,8 @@ function hydrateRootImpl(container, initialChildren, options) {
|
|
|
138
149
|
}
|
|
139
150
|
resetAfterHydrationFailure(root, recoveryContainer);
|
|
140
151
|
try {
|
|
152
|
+
root.i = options.identifierPrefix ?? ":r";
|
|
153
|
+
root.ic = 0;
|
|
141
154
|
flushSyncWork(() => {
|
|
142
155
|
renderRoot(root, recoveryChildren);
|
|
143
156
|
});
|
|
@@ -553,7 +566,7 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
|
|
|
553
566
|
continue;
|
|
554
567
|
}
|
|
555
568
|
const stringifiedBoolean = k.startsWith("aria-") || k.startsWith("data-");
|
|
556
|
-
const attr = k
|
|
569
|
+
const attr = attributeName(k, isSvg);
|
|
557
570
|
let expectedValue;
|
|
558
571
|
if (value == null || value === false && !stringifiedBoolean) {
|
|
559
572
|
expectedValue = null;
|
|
@@ -564,6 +577,9 @@ function validateHydrationProps(fiber, el, props, tag, isSvg) {
|
|
|
564
577
|
}
|
|
565
578
|
const actualValue = el.getAttribute(attr);
|
|
566
579
|
if (expectedValue !== actualValue) {
|
|
580
|
+
if (attr === "id" && expectedValue != null && actualValue != null) {
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
567
583
|
if (true) {
|
|
568
584
|
failHydration(
|
|
569
585
|
fiber,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/dom/features/hydration/full.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n FiberTag,\n REACT_ELEMENT_TYPE,\n type Fiber,\n type FiberRoot,\n type ReactElement,\n type ReactNode,\n} from '../../../core'\nimport { createHostNode, setProp } from '../../dom'\nimport { drainReplayQueue } from '../../event-replay'\nimport { discardPendingWork, findRoot, flushSyncWork, renderRoot } from '../../reconcile'\nimport { attachRootFiber, createFiberRoot } from '../../root-internal'\n\n// Re-export from event-replay so all hydration concerns live behind one\n// feature boundary \u2014 the plugin's stub swap strips drainReplayQueue too.\nexport { drainReplayQueue }\n\n/**\n * Preserve the user's scroll position across hydration. If the user scrolled\n * between SSR paint and hydrate (common in dev where JS takes seconds to\n * load), libraries that wire scroll-restoration into a `useLayoutEffect`\n * near the root (e.g. TanStack Router) will run during our synchronous\n * hydrate and call `window.scrollTo(savedFromLastVisit)` \u2014 overwriting the\n * user's fresh scroll. We install a short-lived wrapper around scrollTo that\n * suppresses programmatic calls when a user-initiated scroll happened\n * recently. Only runs in the hydration feature \u2014 the stub skips it.\n */\nexport function installHydrationScrollGuard(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (w._r) return\n const time = Date.now\n const guardStartedAt = w._r = time()\n let lastUserScrollAt = 0\n let programmatic = false\n w.addEventListener(\n 'scroll',\n () => {\n if (!programmatic) {\n lastUserScrollAt = time()\n }\n },\n { capture: true, passive: true },\n )\n const origScrollTo = w.scrollTo\n w.scrollTo = function (...args: any[]) {\n const now = time()\n if (\n now - guardStartedAt < 3000 &&\n now - lastUserScrollAt < 1500\n ) {\n return\n }\n programmatic = true\n try {\n return (origScrollTo as any).apply(w, args)\n } finally {\n queueMicrotask(() => {\n programmatic = false\n })\n }\n }\n}\n\n/**\n * Hydration cursor: walks existing DOM children in document order so we can\n * adopt them during fiber tree construction. One cursor per host parent.\n *\n * `endBefore` scopes the cursor to a subrange \u2014 used by rehydrateBoundary()\n * so we only adopt DOM up to the closing `/$` marker for that boundary.\n */\nexport class HydrationCursor {\n n: ChildNode | null\n p: Node\n e: ChildNode | null\n constructor(parent: Node, start: ChildNode | null = null, endBefore: ChildNode | null = null) {\n this.p = parent\n this.n = start ?? parent.firstChild\n this.e = endBefore\n }\n take(): ChildNode | null {\n while (this.n && this.n !== this.e) {\n const n = this.n\n // Skip anything that isn't an element (1) or text (3):\n // comments (8), doctype (10), processing instructions (7), cdata (4).\n if (n.nodeType !== 1 && n.nodeType !== 3) {\n this.n = n.nextSibling\n continue\n }\n this.n = n.nextSibling\n return n\n }\n return null\n }\n /**\n * Position-insensitive lookup for head/html adoption. Scans forward past\n * non-matching nodes without removing them, matching by tag AND the key\n * attributes that identify head elements uniquely (rel/href for links,\n * name/property for meta, src for script). Non-matching nodes stay in\n * place so the SSR'd stylesheet/script order is preserved.\n */\n head(tag: string, props: Record<string, any>): ChildNode | null {\n const target = tag.toLowerCase()\n const keyAttrs = HEAD_KEY_ATTRS[target]\n let scan = this.p.firstChild\n while (scan) {\n if (\n scan.nodeType === 1 &&\n (scan as Element).tagName.toLowerCase() === target &&\n headAttrsMatch(scan as Element, props, keyAttrs)\n ) {\n CLAIMED.add(scan)\n return scan\n }\n scan = scan.nextSibling\n }\n return null\n }\n has(): boolean {\n let n = this.n\n while (n && n !== this.e) {\n if (n.nodeType === 1 || n.nodeType === 3) return true\n n = n.nextSibling\n }\n return false\n }\n}\n\nconst hydrationCursors = new WeakMap<Fiber, HydrationCursor>()\nconst PROD_HYDRATION_ERROR = 'Hydration mismatch.'\n\nexport interface HydrationBailoutError extends Error {\n f: Fiber | null\n}\n\nexport function isHydrationBailout(error: unknown): error is HydrationBailoutError {\n return !!error && (error as any).f !== undefined\n}\n\nexport function abortHydration(cause: unknown, fiber: Fiber | null = null): never {\n const error = (cause instanceof Error ? cause : new Error(PROD_HYDRATION_ERROR)) as HydrationBailoutError\n ;(error as any).f = fiber\n throw error\n}\n\ninterface HydrateRootOptions {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\ninterface HydratedRoot {\n render(children: ReactNode): void\n unmount(): void\n}\n\nexport function hydrateRootImpl(\n container: Element | Document,\n initialChildren: ReactNode,\n options: HydrateRootOptions,\n): HydratedRoot {\n const target = container as any as Element | Document\n const isDocument = (container as Node).nodeType === 9\n const body = isDocument ? (target as Document).body : null\n const root = createFiberRoot(target, options)\n\n installHydrationScrollGuard()\n\n const normalizedInitialChildren =\n isDocument ? normalizeDocumentChildren(initialChildren) : initialChildren\n let documentBodyFallback = false\n\n let hydrationError: unknown = null\n beginHydration(root)\n try {\n flushSyncWork(() => {\n renderRoot(root, normalizedInitialChildren)\n })\n } catch (e) {\n hydrationError = e\n }\n endHydration(root)\n\n if (hydrationError) {\n if (!isHydrationBailout(hydrationError)) {\n throw hydrationError\n }\n let recoveryContainer: Element | Document = target\n let recoveryChildren = normalizedInitialChildren\n const hostRecovery = getRecoverableHostChildren(hydrationError)\n if (hostRecovery) {\n recoveryContainer = hostRecovery[0]\n recoveryChildren = hostRecovery[1]\n } else if (body) {\n const bodyChildren = getRecoverableDocumentBodyChildren(hydrationError)\n if (bodyChildren != null) {\n documentBodyFallback = true\n recoveryContainer = body\n recoveryChildren = bodyChildren\n }\n }\n resetAfterHydrationFailure(root, recoveryContainer)\n try {\n flushSyncWork(() => {\n renderRoot(root, recoveryChildren)\n })\n } catch (clientError) {\n resetAfterHydrationFailure(root, recoveryContainer)\n throw clientError\n }\n }\n drainReplayQueue()\n\n return {\n render(children) {\n flushSyncWork(() => {\n const normalized = isDocument ? normalizeDocumentChildren(children) : children\n renderRoot(\n root,\n documentBodyFallback ? getStaticDocumentBodyChildren(normalized) ?? normalized : normalized,\n )\n })\n },\n unmount() {\n flushSyncWork(() => {\n renderRoot(root, null)\n })\n },\n }\n}\n\n// Head elements that we match against server DOM by attribute signature.\nconst HEAD_KEY_ATTRS: Record<string, ReadonlyArray<string>> = {\n link: ['rel', 'href', 'sizes', 'type'],\n meta: ['name', 'property', 'charset', 'http-equiv'],\n script: ['src', 'type'],\n}\n\nconst DOCUMENT_HEAD_TAGS = new Set(['base', 'link', 'meta', 'script', 'style', 'title'])\n\n// DOM elements already claimed by some fiber during this hydration pass.\nconst CLAIMED = new WeakSet<Node>()\n\nfunction headAttrsMatch(\n el: Element,\n props: Record<string, any>,\n keys: ReadonlyArray<string> | undefined,\n): boolean {\n if (CLAIMED.has(el)) return false\n if (!keys) return true\n let matched = false\n for (const k of keys) {\n const propVal = props[k] ?? (k === 'http-equiv' ? props.httpEquiv : undefined)\n const elVal = el.getAttribute(k)\n // If neither defines it, skip this key; if one defines it, they must match.\n if (propVal == null && elVal == null) continue\n matched = true\n if (propVal == null || elVal == null) continue // tolerate missing on either side\n if (String(propVal) !== elVal) return false\n }\n // At least one matching signal must be present.\n return matched\n}\n\nexport function beginHydration(root: FiberRoot): void {\n root.h = true\n hydrationCursors.set(root.r, new HydrationCursor(root.c))\n}\n\nexport function endHydration(root: FiberRoot): void {\n root.h = false\n hydrationCursors.delete(root.r)\n}\n\n/**\n * Inspect the current cursor position for a streaming-suspense boundary\n * marker emitted by the server. Returns info + advances the cursor past the\n * marker pair (start comment + fallback/real content + end comment).\n */\nexport type BoundaryInfo = [0 | 1, number, Comment, Comment]\n\nexport function tryConsumeBoundary(parent: Fiber): BoundaryInfo | null {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return null\n const peek = cursor.n\n if (!peek || peek.nodeType !== 8) return null\n const data = (peek as Comment).data\n const m = /^(\\$\\??)(\\d+)$/.exec(data)\n if (!m) return null\n const kind = m[1] === '$?' ? 1 : 0\n const id = Number(m[2])\n const startMark = peek as Comment\n // Advance past the start comment\n cursor.n = startMark.nextSibling\n // Locate end comment: closest <!--/$-->\n let endMark: Comment | null = null\n let scan = startMark.nextSibling\n while (scan) {\n if (scan.nodeType === 8 && (scan as Comment).data === '/$') {\n endMark = scan as Comment\n break\n }\n scan = scan.nextSibling\n }\n if (!endMark) return null\n return [kind, id, startMark, endMark]\n}\n\nexport function advanceCursorPast(parent: Fiber, node: Node): void {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return\n cursor.n = node.nextSibling\n}\n\nexport function getHydrationCursor(hostFiber: Fiber): HydrationCursor | undefined {\n return hydrationCursors.get(hostFiber)\n}\n\nexport function setHydrationCursor(hostFiber: Fiber, cursor: HydrationCursor): void {\n hydrationCursors.set(hostFiber, cursor)\n}\n\nexport function clearHydrationCursor(hostFiber: Fiber): void {\n hydrationCursors.delete(hostFiber)\n}\n\n/**\n * Try to adopt a DOM node for this host fiber. Returns true if adopted.\n * Attaches existing attrs/children via separate hydrate pass.\n */\nexport function adoptHostDom(fiber: Fiber, parent: Fiber): boolean {\n const hostParent = findHostParent(parent)\n const cursor = hydrationCursors.get(hostParent)\n if (!cursor) return false\n\n const tag = (fiber.type as string).toLowerCase()\n const documentHeadParent =\n cursor.p.nodeType === 9 && DOCUMENT_HEAD_TAGS.has(tag)\n ? (cursor.p as Document).head\n : null\n const parentEl = cursor.p as Element\n const parentTag =\n parentEl.nodeType === 1 ? (parentEl as Element).tagName.toLowerCase() : ''\n const isHeadish = parentTag === 'head' || parentTag === 'html' || !!documentHeadParent\n\n let candidate: ChildNode | null\n if (documentHeadParent) {\n // React 19 can project <meta>/<title>/<link> from anywhere in the tree into\n // document.head. Redact does not have that projection yet, so when a\n // document-root hydration pass sees a top-level head element, adopt it\n // from <head> rather than trying to append it beside <html>.\n candidate = new HydrationCursor(documentHeadParent).head(\n tag,\n fiber.pp ?? {},\n )\n } else if (isHeadish) {\n // Head/html children are position-insensitive \u2014 server may emit them in\n // a different order than the React tree (React 19 head hoisting, etc.).\n // Scan forward without removing non-matching nodes; match on attribute\n // signature so we don't adopt the wrong <link> and clobber its props.\n candidate = cursor.head(tag, fiber.pp ?? {})\n } else {\n candidate = cursor.take()\n }\n\n if (!candidate) {\n // Client expected a host here but the cursor is exhausted \u2014 server gave\n // fewer children than the client tree. Report the structural gap (React\n // fires `onRecoverableError` for this exact case) and let the reconciler\n // mount a fresh DOM for this fiber below.\n // Exception: <head> children are position-insensitive; a missing match\n // there means \"server didn't hoist this one yet\", which we silently mount.\n if (!isHeadish) onMismatch(fiber, null)\n return false\n }\n\n if (candidate.nodeType !== 1 || (candidate as Element).tagName.toLowerCase() !== tag) {\n // mismatch \u2014 log and re-render fresh from this point\n onMismatch(fiber, candidate)\n return false\n }\n fiber.dom = candidate\n // Apply props (attach events, sync IDL props). Don't re-set existing attrs.\n const props = fiber.pp ?? {}\n const isSvg =\n tag === 'svg' ||\n ((candidate as Element).namespaceURI === 'http://www.w3.org/2000/svg' &&\n tag !== 'foreignobject')\n validateHydrationProps(fiber, candidate as Element, props, tag, isSvg)\n for (const k in props) {\n if (k === 'children') continue\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n setProp(candidate as Element, k, props[k], undefined, isSvg)\n }\n // Non-event props: trust the server HTML, skip\n }\n // Set up child cursor for this host's children\n hydrationCursors.set(fiber, new HydrationCursor(candidate))\n return true\n}\n\nexport function adoptTextDom(fiber: Fiber, parent: Fiber, text: string): boolean {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return false\n const candidate = cursor.take()\n if (!candidate) onMismatch(fiber, null)\n if (candidate.nodeType === 3) {\n if ((candidate as Text).data !== text) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration text mismatch: expected \"${text}\" but found \"${(candidate as Text).data}\".`),\n )\n }\n failHydration(fiber)\n }\n fiber.dom = candidate\n return true\n }\n onMismatch(fiber, candidate)\n return false\n}\n\nexport function findHostParent(fiber: Fiber): Fiber {\n let f: Fiber | null = fiber\n while (f) {\n // A fiber explicitly holding a cursor acts as a boundary for hydration\n // (e.g. Suspense with a scoped cursor during fallback/boundary hydration).\n if (hydrationCursors.has(f)) return f\n if (f.tag === FiberTag.Host || f.tag === FiberTag.Root || f.tag === FiberTag.Portal) {\n return f\n }\n f = f.parent\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('No host parent found')\n }\n throw new Error()\n}\n\nfunction onMismatch(fiber: Fiber, actualNode: ChildNode | null): never {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${\n actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'\n }.`,\n ),\n )\n }\n failHydration(fiber)\n}\n\nfunction failHydration(fiber: Fiber, error: Error = new Error(PROD_HYDRATION_ERROR)): never {\n const root = findRoot(fiber)\n if (root?.re) {\n root.re(error)\n }\n abortHydration(error, findHostRecoveryParent(fiber) ?? fiber)\n}\n\nfunction findHostRecoveryParent(fiber: Fiber): Fiber | null {\n if (fiber.tag === FiberTag.Text) {\n let directHost = fiber.parent\n while (directHost && (directHost.tag !== FiberTag.Host || !directHost.dom)) {\n directHost = directHost.parent\n }\n if (!directHost) return null\n let hasEvent\n const props = directHost.pp ?? directHost.mp\n if (props) {\n for (const k in props) {\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n hasEvent = true\n }\n }\n }\n return findNearestSafeHostAboveComposite(\n hasEvent\n ? directHost.parent\n : directHost.parent?.tag === FiberTag.Host\n ? directHost.parent\n : directHost,\n )\n }\n\n return findNearestSafeHostAboveComposite(fiber.parent)\n}\n\nfunction findNearestSafeHostAboveComposite(fiber: Fiber | null): Fiber | null {\n let host: Fiber | null = null\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.dom) {\n if (!isSafeHostRecoveryElement(f)) return null\n const parentTag = f.parent?.tag as number\n if (!host || (parentTag > FiberTag.Text && parentTag < FiberTag.Suspense)) {\n host = f\n }\n }\n f = f.parent\n }\n return host\n}\n\nfunction isSafeHostRecoveryElement(fiber: Fiber): boolean {\n const tag = fiber.type.toLowerCase()\n return tag !== 'html' && tag !== 'head' && tag !== 'body'\n}\n\nfunction resetAfterHydrationFailure(\n root: FiberRoot,\n container: Element | Document,\n): void {\n discardPendingWork(root)\n clearHydrationContainer(container)\n attachRootFiber(root, container)\n root.h = false\n}\n\nfunction clearHydrationContainer(container: Element | Document): void {\n if (container.nodeType === 9) {\n let node = container.firstChild\n while (node) {\n const next = node.nextSibling\n if (node.nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {\n container.removeChild(node)\n }\n node = next\n }\n return\n }\n ;(container as Element).textContent = ''\n}\n\nfunction getRecoverableHostChildren(\n error: HydrationBailoutError,\n): [Element, ReactNode] | null {\n const host = error.f\n if (\n host?.tag !== FiberTag.Host ||\n !host.dom ||\n !findNearestSafeHostAboveComposite(host.parent)\n ) {\n return null\n }\n return [host.dom as Element, (host.pp ?? host.mp)?.children ?? null]\n}\n\nfunction getRecoverableDocumentBodyChildren(error: HydrationBailoutError): ReactNode | null {\n const bodyFiber = findBodyAncestor(error.f)\n if (!bodyFiber) return null\n return (bodyFiber.pp ?? bodyFiber.mp)?.children ?? null\n}\n\nfunction findBodyAncestor(fiber: Fiber | null): Fiber | null {\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.type === 'body') {\n return f === fiber ? null : f\n }\n f = f.parent\n }\n return null\n}\n\nfunction getStaticDocumentBodyChildren(children: ReactNode): ReactNode | null {\n const list = toChildArray(children)\n const html = list.find((child) => isHostElement(child, 'html')) as ReactElement | undefined\n if (!html) return null\n const htmlChildren = toChildArray(html.props?.children)\n const body = htmlChildren.find((child) => isHostElement(child, 'body')) as ReactElement | undefined\n return body ? body.props?.children ?? null : null\n}\n\nfunction normalizeDocumentChildren(children: ReactNode): ReactNode {\n const list = toChildArray(children)\n const htmlIndex = list.findIndex((child) => isHostElement(child, 'html'))\n if (htmlIndex === -1) return children\n\n const headNodes = list.filter(isHeadElement)\n if (headNodes.length === 0) return children\n\n const htmlElement = list[htmlIndex] as ReactElement\n const normalizedHtml = hoistIntoHtmlHead(htmlElement, headNodes)\n return list\n .filter((child, index) => index === htmlIndex || !isHeadElement(child))\n .map((child) => (child === htmlElement ? normalizedHtml : child))\n}\n\nfunction hoistIntoHtmlHead(htmlElement: ReactElement, headNodes: ReactNode[]): ReactElement {\n const htmlChildren = toChildArray(htmlElement.props?.children)\n const headIndex = htmlChildren.findIndex((child) => isHostElement(child, 'head'))\n let nextChildren: ReactNode[]\n\n if (headIndex === -1) {\n nextChildren = [\n createHostElement('head', { children: headNodes }),\n ...htmlChildren,\n ]\n } else {\n const headElement = htmlChildren[headIndex] as ReactElement\n const existingHeadChildren = toChildArray(headElement.props?.children)\n const nextHead = {\n ...headElement,\n props: {\n ...headElement.props,\n children: [...headNodes, ...existingHeadChildren],\n },\n }\n nextChildren = htmlChildren.map((child, index) => (index === headIndex ? nextHead : child))\n }\n\n return {\n ...htmlElement,\n props: {\n ...htmlElement.props,\n children: nextChildren,\n },\n }\n}\n\nfunction toChildArray(children: unknown): ReactNode[] {\n if (children == null || typeof children === 'boolean') return []\n if (Array.isArray(children)) return children as ReactNode[]\n if (isReactElement(children)) return [children]\n if (typeof children !== 'string' && isIterable(children)) return Array.from(children) as ReactNode[]\n return [children as ReactNode]\n}\n\nfunction isHeadElement(value: ReactNode): boolean {\n return isReactElement(value) && typeof value.type === 'string' && DOCUMENT_HEAD_TAGS.has(value.type)\n}\n\nfunction isHostElement(value: ReactNode, tag: string): boolean {\n return isReactElement(value) && value.type === tag\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n return !!value && typeof value === 'object' && (value as ReactElement).$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction isIterable(value: unknown): value is Iterable<ReactNode> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] == 'function'\n}\n\nfunction createHostElement(type: string, props: Record<string, unknown>): ReactElement {\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type,\n key: null,\n ref: null,\n props,\n }\n}\n\nfunction validateHydrationProps(\n fiber: Fiber,\n el: Element,\n props: Record<string, any>,\n tag: string,\n isSvg: boolean,\n): void {\n if (props.suppressHydrationWarning) return\n\n let expected: Element | undefined\n\n for (const k in props) {\n const value = props[k]\n if (\n k === 'children' ||\n k === 'key' ||\n k === 'ref' ||\n k === 'suppressHydrationWarning' ||\n k === 'suppressContentEditableWarning' ||\n (k[0] === 'o' && k[1] === 'n' && typeof value == 'function')\n ) continue\n\n if (k === 'dangerouslySetInnerHTML') {\n const probe = document.createElement('div')\n probe.innerHTML = value?.__html ?? ''\n if ((el as HTMLElement).innerHTML !== probe.innerHTML) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration HTML mismatch inside <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'value' || k === 'defaultValue') {\n if (tag === 'select') continue\n if (tag === 'input' || tag === 'textarea') {\n if (k === 'value' || props.value == null) {\n if (value != null && (el as HTMLInputElement).value !== '' + value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration ${tag} value mismatch on <${tag}>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n }\n\n if (tag === 'input' && (k === 'checked' || k === 'defaultChecked')) {\n if (k === 'checked' || props.checked == null) {\n if (value != null && (el as HTMLInputElement).checked !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration checked mismatch on <input>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n\n if (tag === 'option' && k === 'selected') {\n if (value != null && (el as HTMLOptionElement).selected !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration selected mismatch on <option>.`))\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'style') {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n if ((el as HTMLElement).style.cssText !== (expected as HTMLElement).style.cssText) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration style mismatch on <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n const stringifiedBoolean = k.startsWith('aria-') || k.startsWith('data-')\n const attr = k === 'className' ? 'class' : k === 'htmlFor' ? 'for' : stringifiedBoolean ? k : k.toLowerCase()\n\n let expectedValue: string | null\n if (value == null || (value === false && !stringifiedBoolean)) {\n expectedValue = null\n } else {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n expectedValue = expected.getAttribute(attr)\n }\n const actualValue = el.getAttribute(attr)\n if (expectedValue !== actualValue) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration attribute mismatch on <${tag}> for \"${attr}\": ` +\n `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,\n ),\n )\n }\n failHydration(fiber)\n }\n }\n}\n\nfunction formatHydrationValue(value: string | null): string {\n return value == null ? 'nothing' : JSON.stringify(value)\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n FiberTag,\n REACT_ELEMENT_TYPE,\n type Fiber,\n type FiberRoot,\n type ReactElement,\n type ReactNode,\n} from '../../../core'\nimport { attributeName } from '../../../core/attributes'\nimport { createHostNode, setProp } from '../../dom'\nimport { drainReplayQueue } from '../../event-replay'\nimport { discardPendingWork, findRoot, flushSyncWork, renderRoot } from '../../reconcile'\nimport { attachRootFiber, createFiberRoot } from '../../root-internal'\n\n// Re-export from event-replay so all hydration concerns live behind one\n// feature boundary \u2014 the plugin's stub swap strips drainReplayQueue too.\nexport { drainReplayQueue }\n\n/**\n * Preserve the user's scroll position across hydration. If the user scrolled\n * between SSR paint and hydrate (common in dev where JS takes seconds to\n * load), libraries that wire scroll-restoration into a `useLayoutEffect`\n * near the root (e.g. TanStack Router) will run during our synchronous\n * hydrate and call `window.scrollTo(savedFromLastVisit)` \u2014 overwriting the\n * user's fresh scroll. We install a short-lived wrapper around scrollTo that\n * suppresses programmatic calls when a user-initiated scroll happened\n * recently. Only runs in the hydration feature \u2014 the stub skips it.\n */\nexport function installHydrationScrollGuard(): void {\n if (typeof window === 'undefined') return\n const w = window as any\n if (w._r) return\n const time = Date.now\n const guardStartedAt = w._r = time()\n let lastUserScrollAt = 0\n let programmatic = false\n w.addEventListener(\n 'scroll',\n () => {\n if (!programmatic) {\n lastUserScrollAt = time()\n }\n },\n { capture: true, passive: true },\n )\n const origScrollTo = w.scrollTo\n w.scrollTo = function (...args: any[]) {\n const now = time()\n if (\n now - guardStartedAt < 3000 &&\n now - lastUserScrollAt < 1500\n ) {\n return\n }\n programmatic = true\n try {\n return (origScrollTo as any).apply(w, args)\n } finally {\n queueMicrotask(() => {\n programmatic = false\n })\n }\n }\n}\n\n/**\n * Hydration cursor: walks existing DOM children in document order so we can\n * adopt them during fiber tree construction. One cursor per host parent.\n *\n * `endBefore` scopes the cursor to a subrange \u2014 used by rehydrateBoundary()\n * so we only adopt DOM up to the closing `/$` marker for that boundary.\n */\nexport class HydrationCursor {\n n: ChildNode | null\n p: Node\n e: ChildNode | null\n constructor(parent: Node, start: ChildNode | null = null, endBefore: ChildNode | null = null) {\n this.p = parent\n this.n = start ?? parent.firstChild\n this.e = endBefore\n }\n take(): ChildNode | null {\n while (this.n && this.n !== this.e) {\n const n = this.n\n // Skip anything that isn't an element (1) or text (3):\n // comments (8), doctype (10), processing instructions (7), cdata (4).\n if (n.nodeType !== 1 && n.nodeType !== 3) {\n this.n = n.nextSibling\n continue\n }\n this.n = n.nextSibling\n return n\n }\n return null\n }\n /**\n * Position-insensitive lookup for head/html adoption. Scans forward past\n * non-matching nodes without removing them, matching by tag AND the key\n * attributes that identify head elements uniquely (rel/href for links,\n * name/property for meta, src for script). Non-matching nodes stay in\n * place so the SSR'd stylesheet/script order is preserved.\n */\n head(tag: string, props: Record<string, any>): ChildNode | null {\n const target = tag.toLowerCase()\n const keyAttrs = HEAD_KEY_ATTRS[target]\n let scan = this.p.firstChild\n while (scan) {\n if (\n scan.nodeType === 1 &&\n (scan as Element).tagName.toLowerCase() === target &&\n headAttrsMatch(scan as Element, props, keyAttrs)\n ) {\n CLAIMED.add(scan)\n return scan\n }\n scan = scan.nextSibling\n }\n return null\n }\n has(): boolean {\n let n = this.n\n while (n && n !== this.e) {\n if (n.nodeType === 1) {\n if ((n as Element).tagName === 'SCRIPT') {\n n = n.nextSibling\n continue\n }\n return true\n }\n if (n.nodeType === 3 && (n as Text).data.trim() !== '') return true\n n = n.nextSibling\n }\n return false\n }\n}\n\nconst hydrationCursors = new WeakMap<Fiber, HydrationCursor>()\nconst PROD_HYDRATION_ERROR = 'Hydration mismatch.'\n\nexport interface HydrationBailoutError extends Error {\n f: Fiber | null\n}\n\nexport function isHydrationBailout(error: unknown): error is HydrationBailoutError {\n return !!error && (error as any).f !== undefined\n}\n\nexport function abortHydration(cause: unknown, fiber: Fiber | null = null): never {\n const error = (cause instanceof Error ? cause : new Error(PROD_HYDRATION_ERROR)) as HydrationBailoutError\n ;(error as any).f = fiber\n throw error\n}\n\ninterface HydrateRootOptions {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\ninterface HydratedRoot {\n render(children: ReactNode): void\n unmount(): void\n}\n\nexport function hydrateRootImpl(\n container: Element | Document,\n initialChildren: ReactNode,\n options: HydrateRootOptions,\n): HydratedRoot {\n const target = container as any as Element | Document\n const isDocument = (container as Node).nodeType === 9\n const body = isDocument ? (target as Document).body : null\n const root = createFiberRoot(target, {\n ...options,\n identifierPrefix: options.identifierPrefix ?? ':R',\n })\n\n installHydrationScrollGuard()\n\n const normalizedInitialChildren =\n isDocument ? normalizeDocumentChildren(initialChildren) : initialChildren\n let documentBodyFallback = false\n\n let hydrationError: unknown = null\n beginHydration(root)\n try {\n flushSyncWork(() => {\n renderRoot(root, normalizedInitialChildren)\n })\n } catch (e) {\n hydrationError = e\n }\n endHydration(root)\n\n if (hydrationError) {\n if (!isHydrationBailout(hydrationError)) {\n throw hydrationError\n }\n let recoveryContainer: Element | Document = target\n let recoveryChildren = normalizedInitialChildren\n const hostRecovery = getRecoverableHostChildren(hydrationError)\n if (hostRecovery) {\n recoveryContainer = hostRecovery[0]\n recoveryChildren = hostRecovery[1]\n } else if (body) {\n const bodyChildren = getRecoverableDocumentBodyChildren(hydrationError)\n if (bodyChildren != null) {\n documentBodyFallback = true\n recoveryContainer = body\n recoveryChildren = bodyChildren\n }\n }\n resetAfterHydrationFailure(root, recoveryContainer)\n try {\n root.i = options.identifierPrefix ?? ':r'\n root.ic = 0\n flushSyncWork(() => {\n renderRoot(root, recoveryChildren)\n })\n } catch (clientError) {\n resetAfterHydrationFailure(root, recoveryContainer)\n throw clientError\n }\n }\n drainReplayQueue()\n\n return {\n render(children) {\n flushSyncWork(() => {\n const normalized = isDocument ? normalizeDocumentChildren(children) : children\n renderRoot(\n root,\n documentBodyFallback ? getStaticDocumentBodyChildren(normalized) ?? normalized : normalized,\n )\n })\n },\n unmount() {\n flushSyncWork(() => {\n renderRoot(root, null)\n })\n },\n }\n}\n\n// Head elements that we match against server DOM by attribute signature.\nconst HEAD_KEY_ATTRS: Record<string, ReadonlyArray<string>> = {\n link: ['rel', 'href', 'sizes', 'type'],\n meta: ['name', 'property', 'charset', 'http-equiv'],\n script: ['src', 'type'],\n}\n\nconst DOCUMENT_HEAD_TAGS = new Set(['base', 'link', 'meta', 'script', 'style', 'title'])\n\n// DOM elements already claimed by some fiber during this hydration pass.\nconst CLAIMED = new WeakSet<Node>()\n\nfunction headAttrsMatch(\n el: Element,\n props: Record<string, any>,\n keys: ReadonlyArray<string> | undefined,\n): boolean {\n if (CLAIMED.has(el)) return false\n if (!keys) return true\n let matched = false\n for (const k of keys) {\n const propVal = props[k] ?? (k === 'http-equiv' ? props.httpEquiv : undefined)\n const elVal = el.getAttribute(k)\n // If neither defines it, skip this key; if one defines it, they must match.\n if (propVal == null && elVal == null) continue\n matched = true\n if (propVal == null || elVal == null) continue // tolerate missing on either side\n if (String(propVal) !== elVal) return false\n }\n // At least one matching signal must be present.\n return matched\n}\n\nexport function beginHydration(root: FiberRoot): void {\n root.h = true\n hydrationCursors.set(root.r, new HydrationCursor(root.c))\n}\n\nexport function endHydration(root: FiberRoot): void {\n root.h = false\n hydrationCursors.delete(root.r)\n}\n\n/**\n * Inspect the current cursor position for a streaming-suspense boundary\n * marker emitted by the server. Returns info + advances the cursor past the\n * marker pair (start comment + fallback/real content + end comment).\n */\nexport type BoundaryInfo = [0 | 1, number, Comment, Comment]\n\nexport function tryConsumeBoundary(parent: Fiber): BoundaryInfo | null {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return null\n const peek = cursor.n\n if (!peek || peek.nodeType !== 8) return null\n const data = (peek as Comment).data\n const m = /^(\\$\\??)(\\d+)$/.exec(data)\n if (!m) return null\n const kind = m[1] === '$?' ? 1 : 0\n const id = Number(m[2])\n const startMark = peek as Comment\n // Advance past the start comment\n cursor.n = startMark.nextSibling\n // Locate end comment: closest <!--/$-->\n let endMark: Comment | null = null\n let scan = startMark.nextSibling\n while (scan) {\n if (scan.nodeType === 8 && (scan as Comment).data === '/$') {\n endMark = scan as Comment\n break\n }\n scan = scan.nextSibling\n }\n if (!endMark) return null\n return [kind, id, startMark, endMark]\n}\n\nexport function advanceCursorPast(parent: Fiber, node: Node): void {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return\n cursor.n = node.nextSibling\n}\n\nexport function getHydrationCursor(hostFiber: Fiber): HydrationCursor | undefined {\n return hydrationCursors.get(hostFiber)\n}\n\nexport function setHydrationCursor(hostFiber: Fiber, cursor: HydrationCursor): void {\n hydrationCursors.set(hostFiber, cursor)\n}\n\nexport function clearHydrationCursor(hostFiber: Fiber): void {\n hydrationCursors.delete(hostFiber)\n}\n\n/**\n * Try to adopt a DOM node for this host fiber. Returns true if adopted.\n * Attaches existing attrs/children via separate hydrate pass.\n */\nexport function adoptHostDom(fiber: Fiber, parent: Fiber): boolean {\n const hostParent = findHostParent(parent)\n const cursor = hydrationCursors.get(hostParent)\n if (!cursor) return false\n\n const tag = (fiber.type as string).toLowerCase()\n const documentHeadParent =\n cursor.p.nodeType === 9 && DOCUMENT_HEAD_TAGS.has(tag)\n ? (cursor.p as Document).head\n : null\n const parentEl = cursor.p as Element\n const parentTag =\n parentEl.nodeType === 1 ? (parentEl as Element).tagName.toLowerCase() : ''\n const isHeadish = parentTag === 'head' || parentTag === 'html' || !!documentHeadParent\n\n let candidate: ChildNode | null\n if (documentHeadParent) {\n // React 19 can project <meta>/<title>/<link> from anywhere in the tree into\n // document.head. Redact does not have that projection yet, so when a\n // document-root hydration pass sees a top-level head element, adopt it\n // from <head> rather than trying to append it beside <html>.\n candidate = new HydrationCursor(documentHeadParent).head(\n tag,\n fiber.pp ?? {},\n )\n } else if (isHeadish) {\n // Head/html children are position-insensitive \u2014 server may emit them in\n // a different order than the React tree (React 19 head hoisting, etc.).\n // Scan forward without removing non-matching nodes; match on attribute\n // signature so we don't adopt the wrong <link> and clobber its props.\n candidate = cursor.head(tag, fiber.pp ?? {})\n } else {\n candidate = cursor.take()\n }\n\n if (!candidate) {\n // Client expected a host here but the cursor is exhausted \u2014 server gave\n // fewer children than the client tree. Report the structural gap (React\n // fires `onRecoverableError` for this exact case) and let the reconciler\n // mount a fresh DOM for this fiber below.\n // Exception: <head> children are position-insensitive; a missing match\n // there means \"server didn't hoist this one yet\", which we silently mount.\n if (!isHeadish) onMismatch(fiber, null)\n return false\n }\n\n if (candidate.nodeType !== 1 || (candidate as Element).tagName.toLowerCase() !== tag) {\n // mismatch \u2014 log and re-render fresh from this point\n onMismatch(fiber, candidate)\n return false\n }\n fiber.dom = candidate\n // Apply props (attach events, sync IDL props). Don't re-set existing attrs.\n const props = fiber.pp ?? {}\n const isSvg =\n tag === 'svg' ||\n ((candidate as Element).namespaceURI === 'http://www.w3.org/2000/svg' &&\n tag !== 'foreignobject')\n validateHydrationProps(fiber, candidate as Element, props, tag, isSvg)\n for (const k in props) {\n if (k === 'children') continue\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n setProp(candidate as Element, k, props[k], undefined, isSvg)\n }\n // Non-event props: trust the server HTML, skip\n }\n // Set up child cursor for this host's children\n hydrationCursors.set(fiber, new HydrationCursor(candidate))\n return true\n}\n\nexport function adoptTextDom(fiber: Fiber, parent: Fiber, text: string): boolean {\n const cursor = hydrationCursors.get(findHostParent(parent))\n if (!cursor) return false\n const candidate = cursor.take()\n if (!candidate) onMismatch(fiber, null)\n if (candidate.nodeType === 3) {\n if ((candidate as Text).data !== text) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration text mismatch: expected \"${text}\" but found \"${(candidate as Text).data}\".`),\n )\n }\n failHydration(fiber)\n }\n fiber.dom = candidate\n return true\n }\n onMismatch(fiber, candidate)\n return false\n}\n\nexport function findHostParent(fiber: Fiber): Fiber {\n let f: Fiber | null = fiber\n while (f) {\n // A fiber explicitly holding a cursor acts as a boundary for hydration\n // (e.g. Suspense with a scoped cursor during fallback/boundary hydration).\n if (hydrationCursors.has(f)) return f\n if (f.tag === FiberTag.Host || f.tag === FiberTag.Root || f.tag === FiberTag.Portal) {\n return f\n }\n f = f.parent\n }\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('No host parent found')\n }\n throw new Error()\n}\n\nfunction onMismatch(fiber: Fiber, actualNode: ChildNode | null): never {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration mismatch: expected <${(fiber.type as string) ?? 'text'}> but found ${\n actualNode ? (actualNode.nodeType === 1 ? (actualNode as Element).tagName : 'text') : 'nothing'\n }.`,\n ),\n )\n }\n failHydration(fiber)\n}\n\nfunction failHydration(fiber: Fiber, error: Error = new Error(PROD_HYDRATION_ERROR)): never {\n const root = findRoot(fiber)\n if (root?.re) {\n root.re(error)\n }\n abortHydration(error, findHostRecoveryParent(fiber) ?? fiber)\n}\n\nfunction findHostRecoveryParent(fiber: Fiber): Fiber | null {\n if (fiber.tag === FiberTag.Text) {\n let directHost = fiber.parent\n while (directHost && (directHost.tag !== FiberTag.Host || !directHost.dom)) {\n directHost = directHost.parent\n }\n if (!directHost) return null\n let hasEvent\n const props = directHost.pp ?? directHost.mp\n if (props) {\n for (const k in props) {\n if (k[0] === 'o' && k[1] === 'n' && typeof props[k] == 'function') {\n hasEvent = true\n }\n }\n }\n return findNearestSafeHostAboveComposite(\n hasEvent\n ? directHost.parent\n : directHost.parent?.tag === FiberTag.Host\n ? directHost.parent\n : directHost,\n )\n }\n\n return findNearestSafeHostAboveComposite(fiber.parent)\n}\n\nfunction findNearestSafeHostAboveComposite(fiber: Fiber | null): Fiber | null {\n let host: Fiber | null = null\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.dom) {\n if (!isSafeHostRecoveryElement(f)) return null\n const parentTag = f.parent?.tag as number\n if (!host || (parentTag > FiberTag.Text && parentTag < FiberTag.Suspense)) {\n host = f\n }\n }\n f = f.parent\n }\n return host\n}\n\nfunction isSafeHostRecoveryElement(fiber: Fiber): boolean {\n const tag = fiber.type.toLowerCase()\n return tag !== 'html' && tag !== 'head' && tag !== 'body'\n}\n\nfunction resetAfterHydrationFailure(\n root: FiberRoot,\n container: Element | Document,\n): void {\n discardPendingWork(root)\n clearHydrationContainer(container)\n attachRootFiber(root, container)\n root.h = false\n}\n\nfunction clearHydrationContainer(container: Element | Document): void {\n if (container.nodeType === 9) {\n let node = container.firstChild\n while (node) {\n const next = node.nextSibling\n if (node.nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {\n container.removeChild(node)\n }\n node = next\n }\n return\n }\n ;(container as Element).textContent = ''\n}\n\nfunction getRecoverableHostChildren(\n error: HydrationBailoutError,\n): [Element, ReactNode] | null {\n const host = error.f\n if (\n host?.tag !== FiberTag.Host ||\n !host.dom ||\n !findNearestSafeHostAboveComposite(host.parent)\n ) {\n return null\n }\n return [host.dom as Element, (host.pp ?? host.mp)?.children ?? null]\n}\n\nfunction getRecoverableDocumentBodyChildren(error: HydrationBailoutError): ReactNode | null {\n const bodyFiber = findBodyAncestor(error.f)\n if (!bodyFiber) return null\n return (bodyFiber.pp ?? bodyFiber.mp)?.children ?? null\n}\n\nfunction findBodyAncestor(fiber: Fiber | null): Fiber | null {\n let f = fiber\n while (f) {\n if (f.tag === FiberTag.Host && f.type === 'body') {\n return f === fiber ? null : f\n }\n f = f.parent\n }\n return null\n}\n\nfunction getStaticDocumentBodyChildren(children: ReactNode): ReactNode | null {\n const list = toChildArray(children)\n const html = list.find((child) => isHostElement(child, 'html')) as ReactElement | undefined\n if (!html) return null\n const htmlChildren = toChildArray(html.props?.children)\n const body = htmlChildren.find((child) => isHostElement(child, 'body')) as ReactElement | undefined\n return body ? body.props?.children ?? null : null\n}\n\nfunction normalizeDocumentChildren(children: ReactNode): ReactNode {\n const list = toChildArray(children)\n const htmlIndex = list.findIndex((child) => isHostElement(child, 'html'))\n if (htmlIndex === -1) return children\n\n const headNodes = list.filter(isHeadElement)\n if (headNodes.length === 0) return children\n\n const htmlElement = list[htmlIndex] as ReactElement\n const normalizedHtml = hoistIntoHtmlHead(htmlElement, headNodes)\n return list\n .filter((child, index) => index === htmlIndex || !isHeadElement(child))\n .map((child) => (child === htmlElement ? normalizedHtml : child))\n}\n\nfunction hoistIntoHtmlHead(htmlElement: ReactElement, headNodes: ReactNode[]): ReactElement {\n const htmlChildren = toChildArray(htmlElement.props?.children)\n const headIndex = htmlChildren.findIndex((child) => isHostElement(child, 'head'))\n let nextChildren: ReactNode[]\n\n if (headIndex === -1) {\n nextChildren = [\n createHostElement('head', { children: headNodes }),\n ...htmlChildren,\n ]\n } else {\n const headElement = htmlChildren[headIndex] as ReactElement\n const existingHeadChildren = toChildArray(headElement.props?.children)\n const nextHead = {\n ...headElement,\n props: {\n ...headElement.props,\n children: [...headNodes, ...existingHeadChildren],\n },\n }\n nextChildren = htmlChildren.map((child, index) => (index === headIndex ? nextHead : child))\n }\n\n return {\n ...htmlElement,\n props: {\n ...htmlElement.props,\n children: nextChildren,\n },\n }\n}\n\nfunction toChildArray(children: unknown): ReactNode[] {\n if (children == null || typeof children === 'boolean') return []\n if (Array.isArray(children)) return children as ReactNode[]\n if (isReactElement(children)) return [children]\n if (typeof children !== 'string' && isIterable(children)) return Array.from(children) as ReactNode[]\n return [children as ReactNode]\n}\n\nfunction isHeadElement(value: ReactNode): boolean {\n return isReactElement(value) && typeof value.type === 'string' && DOCUMENT_HEAD_TAGS.has(value.type)\n}\n\nfunction isHostElement(value: ReactNode, tag: string): boolean {\n return isReactElement(value) && value.type === tag\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n return !!value && typeof value === 'object' && (value as ReactElement).$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction isIterable(value: unknown): value is Iterable<ReactNode> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] == 'function'\n}\n\nfunction createHostElement(type: string, props: Record<string, unknown>): ReactElement {\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type,\n key: null,\n ref: null,\n props,\n }\n}\n\nfunction validateHydrationProps(\n fiber: Fiber,\n el: Element,\n props: Record<string, any>,\n tag: string,\n isSvg: boolean,\n): void {\n if (props.suppressHydrationWarning) return\n\n let expected: Element | undefined\n\n for (const k in props) {\n const value = props[k]\n if (\n k === 'children' ||\n k === 'key' ||\n k === 'ref' ||\n k === 'suppressHydrationWarning' ||\n k === 'suppressContentEditableWarning' ||\n (k[0] === 'o' && k[1] === 'n' && typeof value == 'function')\n ) continue\n\n if (k === 'dangerouslySetInnerHTML') {\n const probe = document.createElement('div')\n probe.innerHTML = value?.__html ?? ''\n if ((el as HTMLElement).innerHTML !== probe.innerHTML) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration HTML mismatch inside <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'value' || k === 'defaultValue') {\n if (tag === 'select') continue\n if (tag === 'input' || tag === 'textarea') {\n if (k === 'value' || props.value == null) {\n if (value != null && (el as HTMLInputElement).value !== '' + value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration ${tag} value mismatch on <${tag}>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n }\n\n if (tag === 'input' && (k === 'checked' || k === 'defaultChecked')) {\n if (k === 'checked' || props.checked == null) {\n if (value != null && (el as HTMLInputElement).checked !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration checked mismatch on <input>.`))\n }\n failHydration(fiber)\n }\n }\n continue\n }\n\n if (tag === 'option' && k === 'selected') {\n if (value != null && (el as HTMLOptionElement).selected !== !!value) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(fiber, new Error(`Hydration selected mismatch on <option>.`))\n }\n failHydration(fiber)\n }\n continue\n }\n\n if (k === 'style') {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n if ((el as HTMLElement).style.cssText !== (expected as HTMLElement).style.cssText) {\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(`Hydration style mismatch on <${tag}>.`),\n )\n }\n failHydration(fiber)\n }\n continue\n }\n\n const stringifiedBoolean = k.startsWith('aria-') || k.startsWith('data-')\n const attr = attributeName(k, isSvg)\n\n let expectedValue: string | null\n if (value == null || (value === false && !stringifiedBoolean)) {\n expectedValue = null\n } else {\n expected ??= createHostNode(tag, isSvg)\n setProp(expected, k, value, undefined, isSvg)\n expectedValue = expected.getAttribute(attr)\n }\n const actualValue = el.getAttribute(attr)\n if (expectedValue !== actualValue) {\n if (attr === 'id' && expectedValue != null && actualValue != null) {\n continue\n }\n if (process.env.NODE_ENV !== 'production') {\n failHydration(\n fiber,\n new Error(\n `Hydration attribute mismatch on <${tag}> for \"${attr}\": ` +\n `expected ${formatHydrationValue(expectedValue)} but found ${formatHydrationValue(actualValue)}.`,\n ),\n )\n }\n failHydration(fiber)\n }\n }\n}\n\nfunction formatHydrationValue(value: string | null): string {\n return value == null ? 'nothing' : JSON.stringify(value)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -11,6 +11,7 @@ function createFiberRoot(container, options) {
|
|
|
11
11
|
ce: options.onCaughtError,
|
|
12
12
|
ue: options.onUncaughtError,
|
|
13
13
|
i: options.identifierPrefix ?? ":r",
|
|
14
|
+
ic: 0,
|
|
14
15
|
h: false
|
|
15
16
|
};
|
|
16
17
|
rootFiber.root = root;
|
|
@@ -20,6 +21,7 @@ function createFiberRoot(container, options) {
|
|
|
20
21
|
function attachRootFiber(root, container) {
|
|
21
22
|
const rootFiber = createFiber(FiberTag.Root, null, null);
|
|
22
23
|
root.c = container;
|
|
24
|
+
root.ic = 0;
|
|
23
25
|
rootFiber.root = root;
|
|
24
26
|
rootFiber.sn = container;
|
|
25
27
|
root.r = rootFiber;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/dom/root-internal.ts"],
|
|
4
|
-
"sourcesContent": ["import { FiberTag, createFiber, type Fiber, type FiberRoot } from '../core'\n\nexport interface RootOptionsInternal {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\nexport function createFiberRoot(\n container: Element | Document | DocumentFragment,\n options: RootOptionsInternal,\n): FiberRoot {\n const rootFiber = createFiber(FiberTag.Root, null, null)\n const root: FiberRoot = {\n c: container as any,\n r: rootFiber,\n p: new Set(),\n s: false,\n re: options.onRecoverableError,\n ce: options.onCaughtError,\n ue: options.onUncaughtError,\n i: options.identifierPrefix ?? ':r',\n h: false,\n }\n rootFiber.root = root\n rootFiber.sn = container\n return root\n}\n\nexport function attachRootFiber(\n root: FiberRoot,\n container: Element | Document | DocumentFragment,\n): void {\n const rootFiber = createFiber(FiberTag.Root, null, null)\n root.c = container as any\n rootFiber.root = root\n rootFiber.sn = container\n root.r = rootFiber\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,UAAU,mBAA+C;AAS3D,SAAS,gBACd,WACA,SACW;AACX,QAAM,YAAY,YAAY,SAAS,MAAM,MAAM,IAAI;AACvD,QAAM,OAAkB;AAAA,IACtB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,oBAAI,IAAI;AAAA,IACX,GAAG;AAAA,IACH,IAAI,QAAQ;AAAA,IACZ,IAAI,QAAQ;AAAA,IACZ,IAAI,QAAQ;AAAA,IACZ,GAAG,QAAQ,oBAAoB;AAAA,IAC/B,GAAG;AAAA,EACL;AACA,YAAU,OAAO;AACjB,YAAU,KAAK;AACf,SAAO;AACT;AAEO,SAAS,gBACd,MACA,WACM;AACN,QAAM,YAAY,YAAY,SAAS,MAAM,MAAM,IAAI;AACvD,OAAK,IAAI;AACT,YAAU,OAAO;AACjB,YAAU,KAAK;AACf,OAAK,IAAI;AACX;",
|
|
4
|
+
"sourcesContent": ["import { FiberTag, createFiber, type Fiber, type FiberRoot } from '../core'\n\nexport interface RootOptionsInternal {\n identifierPrefix?: string\n onRecoverableError?: (error: unknown) => void\n onCaughtError?: (error: unknown) => void\n onUncaughtError?: (error: unknown) => void\n}\n\nexport function createFiberRoot(\n container: Element | Document | DocumentFragment,\n options: RootOptionsInternal,\n): FiberRoot {\n const rootFiber = createFiber(FiberTag.Root, null, null)\n const root: FiberRoot = {\n c: container as any,\n r: rootFiber,\n p: new Set(),\n s: false,\n re: options.onRecoverableError,\n ce: options.onCaughtError,\n ue: options.onUncaughtError,\n i: options.identifierPrefix ?? ':r',\n ic: 0,\n h: false,\n }\n rootFiber.root = root\n rootFiber.sn = container\n return root\n}\n\nexport function attachRootFiber(\n root: FiberRoot,\n container: Element | Document | DocumentFragment,\n): void {\n const rootFiber = createFiber(FiberTag.Root, null, null)\n root.c = container as any\n root.ic = 0\n rootFiber.root = root\n rootFiber.sn = container\n root.r = rootFiber\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,UAAU,mBAA+C;AAS3D,SAAS,gBACd,WACA,SACW;AACX,QAAM,YAAY,YAAY,SAAS,MAAM,MAAM,IAAI;AACvD,QAAM,OAAkB;AAAA,IACtB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,oBAAI,IAAI;AAAA,IACX,GAAG;AAAA,IACH,IAAI,QAAQ;AAAA,IACZ,IAAI,QAAQ;AAAA,IACZ,IAAI,QAAQ;AAAA,IACZ,GAAG,QAAQ,oBAAoB;AAAA,IAC/B,IAAI;AAAA,IACJ,GAAG;AAAA,EACL;AACA,YAAU,OAAO;AACjB,YAAU,KAAK;AACf,SAAO;AACT;AAEO,SAAS,gBACd,MACA,WACM;AACN,QAAM,YAAY,YAAY,SAAS,MAAM,MAAM,IAAI;AACvD,OAAK,IAAI;AACT,OAAK,KAAK;AACV,YAAU,OAAO;AACjB,YAAU,KAAK;AACf,OAAK,IAAI;AACX;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server/escape.d.ts
CHANGED
|
@@ -3,5 +3,4 @@ export declare function escapeText(value: string): string;
|
|
|
3
3
|
export declare function escapeScript(value: string): string;
|
|
4
4
|
export declare const VOID_ELEMENTS: Set<string>;
|
|
5
5
|
export declare const RAW_TEXT_ELEMENTS: Set<string>;
|
|
6
|
-
export declare
|
|
7
|
-
export declare function attrToHtml(name: string, value: unknown): string;
|
|
6
|
+
export declare function attrToHtml(name: string, value: unknown, isSvg?: boolean): string;
|
package/dist/server/escape.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// packages/redact/src/server/escape.ts
|
|
2
|
+
import { attributeName } from "../core/attributes";
|
|
2
3
|
var ATTR_MAP = {
|
|
3
4
|
"&": "&",
|
|
4
5
|
'"': """,
|
|
@@ -36,16 +37,6 @@ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
36
37
|
"wbr"
|
|
37
38
|
]);
|
|
38
39
|
var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
39
|
-
var ATTR_ALIASES = {
|
|
40
|
-
className: "class",
|
|
41
|
-
htmlFor: "for",
|
|
42
|
-
httpEquiv: "http-equiv",
|
|
43
|
-
acceptCharset: "accept-charset",
|
|
44
|
-
crossOrigin: "crossorigin",
|
|
45
|
-
viewBox: "viewBox",
|
|
46
|
-
// SVG keeps camelCase
|
|
47
|
-
noModule: "nomodule"
|
|
48
|
-
};
|
|
49
40
|
var BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
|
|
50
41
|
"allowfullscreen",
|
|
51
42
|
"async",
|
|
@@ -73,13 +64,13 @@ var BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
|
|
|
73
64
|
"reversed",
|
|
74
65
|
"selected"
|
|
75
66
|
]);
|
|
76
|
-
function attrToHtml(name, value) {
|
|
67
|
+
function attrToHtml(name, value, isSvg = false) {
|
|
77
68
|
if (name === "children" || name === "key" || name === "ref" || name === "dangerouslySetInnerHTML" || name === "defaultValue" || name === "defaultChecked" || name === "suppressHydrationWarning" || name === "suppressContentEditableWarning") {
|
|
78
69
|
return "";
|
|
79
70
|
}
|
|
80
71
|
if (name[0] === "o" && name[1] === "n" && typeof value === "function") return "";
|
|
81
72
|
if (value == null) return "";
|
|
82
|
-
const htmlName =
|
|
73
|
+
const htmlName = attributeName(name, isSvg);
|
|
83
74
|
if (name.startsWith("aria-") || name.startsWith("data-")) {
|
|
84
75
|
return ` ${htmlName}="${escapeAttr(String(value))}"`;
|
|
85
76
|
}
|
|
@@ -148,7 +139,6 @@ function styleToString(style) {
|
|
|
148
139
|
return out;
|
|
149
140
|
}
|
|
150
141
|
export {
|
|
151
|
-
ATTR_ALIASES,
|
|
152
142
|
RAW_TEXT_ELEMENTS,
|
|
153
143
|
VOID_ELEMENTS,
|
|
154
144
|
attrToHtml,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/server/escape.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";AAAA,IAAM,WAAmC;AAAA,EACvC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AACA,IAAM,WAAmC;AAAA,EACvC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEO,SAAS,WAAW,OAAuB;AAChD,SAAO,MAAM,QAAQ,WAAW,CAAC,MAAM,SAAS,CAAC,CAAE;AACrD;AAEO,SAAS,WAAW,OAAuB;AAChD,SAAO,MAAM,QAAQ,UAAU,CAAC,MAAM,SAAS,CAAC,CAAE;AACpD;AAOO,SAAS,aAAa,OAAuB;AAClD,SAAO,MACJ,QAAQ,uBAAuB,QAAQ,EACvC,QAAQ,SAAS,QAAQ;AAC9B;AAEO,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,oBAAoB,oBAAI,IAAI,CAAC,UAAU,OAAO,CAAC;
|
|
4
|
+
"sourcesContent": ["import { attributeName } from '../core/attributes'\n\nconst ATTR_MAP: Record<string, string> = {\n '&': '&',\n '\"': '"',\n '<': '<',\n '>': '>',\n}\nconst TEXT_MAP: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n}\n\nexport function escapeAttr(value: string): string {\n return value.replace(/[&\"<>]/g, (c) => ATTR_MAP[c]!)\n}\n\nexport function escapeText(value: string): string {\n return value.replace(/[&<>]/g, (c) => TEXT_MAP[c]!)\n}\n\n// Raw-text element body escaping: prevent any closing tag for the raw-text\n// elements (<script>, <style>) from terminating the element early, plus\n// `<!--` (which would start an HTML comment that survives even inside\n// raw-text bodies and can be exploited to alter following script content).\n// React's serializer follows the same approach.\nexport function escapeScript(value: string): string {\n return value\n .replace(/<\\/(script|style)/gi, '<\\\\/$1')\n .replace(/<!--/g, '<\\\\!--')\n}\n\nexport const VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nexport const RAW_TEXT_ELEMENTS = new Set(['script', 'style'])\n\nconst BOOLEAN_ATTRS = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected',\n])\n\nexport function attrToHtml(name: string, value: unknown, isSvg = false): string {\n if (\n name === 'children' ||\n name === 'key' ||\n name === 'ref' ||\n name === 'dangerouslySetInnerHTML' ||\n name === 'defaultValue' ||\n name === 'defaultChecked' ||\n name === 'suppressHydrationWarning' ||\n name === 'suppressContentEditableWarning'\n ) {\n return ''\n }\n if (name[0] === 'o' && name[1] === 'n' && typeof value === 'function') return ''\n if (value == null) return ''\n\n const htmlName = attributeName(name, isSvg)\n\n // aria-* and data-* stringify booleans to `\"true\"`/`\"false\"` rather than\n // using boolean-attribute presence semantics \u2014 matches React and the ARIA\n // spec. Must branch before the general `value === false` / BOOLEAN_ATTRS\n // path, which would drop them.\n if (name.startsWith('aria-') || name.startsWith('data-')) {\n return ` ${htmlName}=\"${escapeAttr(String(value))}\"`\n }\n\n if (value === false) return ''\n\n if (value === true || BOOLEAN_ATTRS.has(htmlName)) {\n return value ? ` ${htmlName}=\"\"` : ''\n }\n\n if (name === 'style' && typeof value === 'object' && value !== null) {\n return ` style=\"${escapeAttr(styleToString(value as Record<string, unknown>))}\"`\n }\n\n return ` ${htmlName}=\"${escapeAttr(String(value))}\"`\n}\n\nconst UNITLESS_STYLE = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n])\n\nfunction styleToString(style: Record<string, unknown>): string {\n let out = ''\n for (const key in style) {\n const v = style[key]\n if (v == null || v === false) continue\n const kebab = key.startsWith('--')\n ? key\n : key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase())\n const value =\n typeof v === 'number' && !UNITLESS_STYLE.has(key) && v !== 0 ? v + 'px' : v\n out += `${kebab}:${value};`\n }\n return out\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/server/walk.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface WalkOptions {
|
|
|
13
13
|
nextBoundaryId: () => number;
|
|
14
14
|
bootstrapped?: boolean | undefined;
|
|
15
15
|
isBoundaryResolution?: boolean | undefined;
|
|
16
|
+
isSvg?: boolean | undefined;
|
|
16
17
|
/**
|
|
17
18
|
* Tracks whether the most recent emission within the *current text flow*
|
|
18
19
|
* ended with a text node. When the next emission is also text, we emit a
|
package/dist/server/walk.js
CHANGED
|
@@ -152,6 +152,7 @@ function walkElement(el, opts) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
function walkHost(tag, props, opts) {
|
|
155
|
+
const isSvg = opts.isSvg || tag === "svg";
|
|
155
156
|
const isTextarea = tag === "textarea";
|
|
156
157
|
const textareaValue = isTextarea ? props.value != null ? props.value : props.defaultValue : void 0;
|
|
157
158
|
const isInput = tag === "input";
|
|
@@ -170,13 +171,13 @@ function walkHost(tag, props, opts) {
|
|
|
170
171
|
if (isInput && (k === "defaultValue" || k === "defaultChecked")) continue;
|
|
171
172
|
if (isSelect && (k === "value" || k === "defaultValue")) continue;
|
|
172
173
|
if (isOption && k === "selected") continue;
|
|
173
|
-
opts.emit(attrToHtml(k, props[k]));
|
|
174
|
+
opts.emit(attrToHtml(k, props[k], isSvg));
|
|
174
175
|
}
|
|
175
176
|
if (inputValueAttr !== void 0) {
|
|
176
|
-
opts.emit(attrToHtml("value", inputValueAttr));
|
|
177
|
+
opts.emit(attrToHtml("value", inputValueAttr, isSvg));
|
|
177
178
|
}
|
|
178
179
|
if (inputCheckedAttr !== void 0) {
|
|
179
|
-
opts.emit(attrToHtml("checked", inputCheckedAttr));
|
|
180
|
+
opts.emit(attrToHtml("checked", inputCheckedAttr, isSvg));
|
|
180
181
|
}
|
|
181
182
|
if (isOption) {
|
|
182
183
|
const selectVal = currentSelectValue();
|
|
@@ -195,7 +196,11 @@ function walkHost(tag, props, opts) {
|
|
|
195
196
|
}
|
|
196
197
|
opts.emit(">");
|
|
197
198
|
const parentTextState = opts.textState;
|
|
198
|
-
const childOpts = {
|
|
199
|
+
const childOpts = {
|
|
200
|
+
...opts,
|
|
201
|
+
isSvg: isSvg && tag !== "foreignObject",
|
|
202
|
+
textState: { lastWasText: false }
|
|
203
|
+
};
|
|
199
204
|
if (tag === "html" && !hasHeadChild(props.children)) {
|
|
200
205
|
opts.emit("<head></head>");
|
|
201
206
|
}
|
package/dist/server/walk.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/server/walk.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n REACT_ELEMENT_TYPE,\n REACT_LEGACY_ELEMENT_TYPE,\n REACT_FRAGMENT_TYPE,\n type ReactNode,\n type ReactElement,\n} from '../core'\nimport {\n REACT_SUSPENSE_TYPE,\n REACT_PROVIDER_TYPE,\n REACT_CONSUMER_TYPE,\n REACT_FORWARD_REF_TYPE,\n REACT_MEMO_TYPE,\n REACT_LAZY_TYPE,\n REACT_STRICT_MODE_TYPE,\n REACT_PROFILER_TYPE,\n REACT_PORTAL_TYPE,\n} from '../react'\nimport {\n attrToHtml,\n escapeText,\n escapeScript,\n VOID_ELEMENTS,\n RAW_TEXT_ELEMENTS,\n} from './escape'\nimport {\n pushContext,\n popContext,\n snapshotContexts,\n type ContextSnapshot,\n} from './dispatcher'\n\nexport interface SuspendedBoundary {\n id: number\n fallbackHTML: string\n children: ReactNode\n thenable: Promise<any>\n contextSnapshot: ContextSnapshot\n}\n\nexport interface WalkOptions {\n emit: (chunk: string) => void\n onSuspend?: ((boundary: SuspendedBoundary) => void) | undefined\n nextBoundaryId: () => number\n bootstrapped?: boolean | undefined\n isBoundaryResolution?: boolean | undefined\n /**\n * Tracks whether the most recent emission within the *current text flow*\n * ended with a text node. When the next emission is also text, we emit a\n * `<!-- -->` separator so the browser's HTML parser doesn't merge them\n * into a single text node \u2014 required for hydration to line up text\n * boundaries with the React tree. Reset to `false` whenever we enter a\n * new host element (`<tag>` opens a fresh text flow).\n */\n textState?: { lastWasText: boolean }\n}\n\n/**\n * Synchronously walk a React node and emit HTML string pieces to `opts.emit`.\n * Suspended boundaries are emitted as fallbacks with marker IDs; if `opts.onSuspend`\n * is provided, the suspension is recorded for later streaming.\n */\nexport function walk(node: ReactNode, opts: WalkOptions): void {\n // Seed a text state if the caller didn't provide one so the separator logic\n // is active for the whole tree.\n if (!opts.textState) opts = { ...opts, textState: { lastWasText: false } }\n walkNode(node, opts)\n}\n\n// --- <select> selection context ----------------------------------------------\n// Stack of active select values (or `undefined` when the current select has\n// no controlled value). `<option>` walks read the top of stack to decide\n// whether to emit `selected=\"\"`.\nconst selectValueStack: unknown[] = []\nfunction pushSelectContext(value: unknown): void {\n selectValueStack.push(value)\n}\nfunction popSelectContext(): void {\n selectValueStack.pop()\n}\nfunction currentSelectValue(): unknown {\n return selectValueStack.length ? selectValueStack[selectValueStack.length - 1] : undefined\n}\n\nfunction optionChildText(children: unknown): string {\n // `<option>Text</option>` \u2014 if no `value` prop, the option's value is its\n // flat string/number child content. Matches DOM semantics (`option.value`\n // defaults to `textContent` when no attribute is set).\n if (children == null) return ''\n if (typeof children === 'string' || typeof children === 'number') return '' + children\n if (Array.isArray(children)) return children.map(optionChildText).join('')\n return ''\n}\n\nfunction emitText(text: string, opts: WalkOptions): void {\n // Empty string renders no text node and doesn't start/extend a text flow \u2014\n // skip entirely so sibling text isn't separated by a stray `<!-- -->`.\n if (text === '') return\n if (opts.textState?.lastWasText) opts.emit('<!-- -->')\n opts.emit(escapeText(text))\n if (opts.textState) opts.textState.lastWasText = true\n}\n\nfunction walkNode(node: ReactNode, opts: WalkOptions): void {\n if (node == null || node === false || node === true) return\n\n if (typeof node === 'string') {\n emitText(node, opts)\n return\n }\n if (typeof node === 'number') {\n emitText(String(node), opts)\n return\n }\n if (Array.isArray(node)) {\n for (const c of node) walkNode(c, opts)\n return\n }\n if (typeof (node as any)[Symbol.iterator] === 'function') {\n for (const item of node as Iterable<ReactNode>) walkNode(item, opts)\n return\n }\n\n if (typeof node !== 'object') return\n const t = (node as any).$$typeof\n\n // Raw React.lazy in the tree (RSC Flight encodes 'use client' components \u2014\n // CodeBlock, CodeExplorer, etc. \u2014 as bare Lazy objects directly in the\n // tree, not wrapped in REACT_ELEMENT_TYPE). SSR previously dropped these\n // here, so code snippets never made it into the server HTML. The RSC\n // decoder server-side awaits payloads before rendering, so status is\n // 'fulfilled' and `_init()` returns the resolved element synchronously.\n // If still pending (shouldn't happen post-awaitLazyElements), throw the\n // thenable so streaming SSR suspends the current boundary and retries.\n if (t === REACT_LAZY_TYPE) {\n const lazy = node as any\n const resolved = lazy._init(lazy._payload)\n walkNode(resolved, opts)\n return\n }\n\n if (t !== REACT_ELEMENT_TYPE && t !== REACT_LEGACY_ELEMENT_TYPE) return\n\n const el = node as ReactElement\n walkElement(el, opts)\n}\n\nfunction walkElement(el: ReactElement, opts: WalkOptions): void {\n const type = el.type\n const props = el.props ?? {}\n\n if (type === REACT_FRAGMENT_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_PROFILER_TYPE) {\n walkNode(props.children, opts)\n return\n }\n\n if (type === REACT_SUSPENSE_TYPE) {\n walkSuspense(props, opts)\n return\n }\n\n if (typeof type === 'string') {\n walkHost(type, props, opts)\n return\n }\n\n const marker = (type as any)?.$$typeof\n\n if (marker === REACT_PORTAL_TYPE) {\n // Portals don't render to the main HTML output on the server.\n return\n }\n\n if (marker === REACT_PROVIDER_TYPE) {\n const ctx = (type as any)._context\n pushContext(ctx, props.value)\n try {\n walkNode(props.children, opts)\n } finally {\n popContext(ctx)\n }\n return\n }\n\n if (marker === REACT_CONSUMER_TYPE) {\n const ctx = (type as any)._context\n const render = props.children\n if (typeof render === 'function') {\n walkNode(render(ctx._currentValue), opts)\n }\n return\n }\n\n if (marker === REACT_FORWARD_REF_TYPE) {\n const render = (type as any).render\n const ref = (props as any).ref ?? null\n const { ref: _omit, ...rest } = props as any\n const rendered = render(rest, ref)\n walkNode(rendered, opts)\n return\n }\n\n if (marker === REACT_MEMO_TYPE) {\n const inner = (type as any).type\n walkElement({ ...el, type: inner } as ReactElement, opts)\n return\n }\n\n if (marker === REACT_LAZY_TYPE) {\n const { _payload, _init } = type as any\n try {\n const resolved = _init(_payload)\n walkElement({ ...el, type: resolved } as ReactElement, opts)\n } catch (thenable: any) {\n if (isThenable(thenable)) {\n // Suspend this point\n throw thenable\n }\n throw thenable\n }\n return\n }\n\n if (typeof type === 'function') {\n walkComponent(type, props, opts)\n return\n }\n}\n\nfunction walkHost(\n tag: string,\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n // <textarea value=\"...\"> serializes its value as a TEXT CHILD, not an\n // attribute. `defaultValue` is the fallback when `value` is absent. This\n // matches React and the HTML spec \u2014 `<textarea value=\"x\">` is not valid\n // HTML; the value is the element's textContent.\n const isTextarea = tag === 'textarea'\n const textareaValue = isTextarea\n ? props.value != null\n ? props.value\n : props.defaultValue\n : undefined\n\n // <input defaultValue=\"...\"> should parse with that value \u2014 emit it as a\n // `value` attribute. Similarly `defaultChecked` becomes `checked`. This\n // keeps hydration consistent: the browser parser sees the initial value,\n // and on client commit our setProp seeds `.defaultValue`/`.defaultChecked`\n // without stomping the user-typed value.\n const isInput = tag === 'input'\n const inputValueAttr =\n isInput && props.value == null && props.defaultValue != null\n ? props.defaultValue\n : undefined\n const inputCheckedAttr =\n isInput && props.checked == null && props.defaultChecked != null\n ? props.defaultChecked\n : undefined\n\n // <select value=\"...\"> does NOT become an attribute on `<select>` \u2014 the\n // HTML spec has no such attribute. React resolves the selection by stamping\n // `selected` on the matching `<option>` children during render. Stash the\n // target value(s) on the walk state and the child `<option>` walk reads it.\n const isSelect = tag === 'select'\n if (isSelect) {\n const val = props.value != null ? props.value : props.defaultValue\n pushSelectContext(val)\n }\n const isOption = tag === 'option'\n\n // Prepend the HTML5 doctype to the stream when rendering an <html> root.\n // Without it the browser parses the document in quirks mode, which breaks\n // CSS sizing (documentElement.clientHeight returns the content height, not\n // the viewport) \u2014 and Floating-UI-based libraries (Radix dropdowns etc.)\n // then compute off-screen positions for overlays.\n if (tag === 'html') opts.emit('<!DOCTYPE html>')\n\n opts.emit('<' + tag)\n for (const k in props) {\n if (isTextarea && (k === 'value' || k === 'defaultValue')) continue\n if (isInput && (k === 'defaultValue' || k === 'defaultChecked')) continue\n if (isSelect && (k === 'value' || k === 'defaultValue')) continue\n if (isOption && k === 'selected') continue\n opts.emit(attrToHtml(k, props[k]))\n }\n if (inputValueAttr !== undefined) {\n opts.emit(attrToHtml('value', inputValueAttr))\n }\n if (inputCheckedAttr !== undefined) {\n opts.emit(attrToHtml('checked', inputCheckedAttr))\n }\n if (isOption) {\n const selectVal = currentSelectValue()\n if (selectVal !== undefined) {\n const optionValue =\n props.value != null ? props.value : optionChildText(props.children)\n const matches = Array.isArray(selectVal)\n ? selectVal.some((v) => '' + v === '' + optionValue)\n : '' + selectVal === '' + optionValue\n if (matches) opts.emit(' selected=\"\"')\n } else if (props.selected) {\n opts.emit(' selected=\"\"')\n }\n }\n\n if (VOID_ELEMENTS.has(tag)) {\n opts.emit('/>')\n if (opts.textState) opts.textState.lastWasText = false\n return\n }\n opts.emit('>')\n // Opening a host element starts a fresh text flow context for its children.\n // Children's text separator tracking is independent of the outer context.\n const parentTextState = opts.textState\n const childOpts: WalkOptions = { ...opts, textState: { lastWasText: false } }\n\n if (tag === 'html' && !hasHeadChild(props.children)) {\n opts.emit('<head></head>')\n }\n\n const dangerouslyHtml = props.dangerouslySetInnerHTML?.__html\n\n if (isTextarea && textareaValue != null) {\n opts.emit(escapeText(String(textareaValue)))\n opts.emit(`</${tag}>`)\n if (parentTextState) parentTextState.lastWasText = false\n return\n }\n\n if (RAW_TEXT_ELEMENTS.has(tag)) {\n // script/style: raw-text. React allows either a string/number child or\n // dangerouslySetInnerHTML \u2014 some libs (Start's Scripts) use the latter.\n if (dangerouslyHtml != null) {\n opts.emit(escapeScript(String(dangerouslyHtml)))\n } else {\n const children = props.children\n if (typeof children === 'string' || typeof children === 'number') {\n opts.emit(escapeScript(String(children)))\n } else if (Array.isArray(children)) {\n opts.emit(escapeScript(children.filter((c) => c != null).join('')))\n }\n }\n opts.emit(`</${tag}>`)\n if (parentTextState) parentTextState.lastWasText = false\n return\n }\n\n if (dangerouslyHtml != null) {\n opts.emit(String(dangerouslyHtml))\n } else {\n walkNode(props.children, childOpts)\n }\n opts.emit(`</${tag}>`)\n if (isSelect) popSelectContext()\n // Host element closing resets outer flow \u2014 next sibling text starts fresh.\n if (parentTextState) parentTextState.lastWasText = false\n}\n\nfunction hasHeadChild(children: unknown): boolean {\n if (children == null || typeof children === 'boolean') return false\n if (Array.isArray(children)) return children.some(hasHeadChild)\n if (typeof children !== 'string' && isIterable(children)) {\n for (const child of children as Iterable<unknown>) {\n if (hasHeadChild(child)) return true\n }\n return false\n }\n return isElementOfType(children, 'head')\n}\n\nfunction isElementOfType(value: unknown, type: string): value is ReactElement {\n const marker = (value as ReactElement | null)?.$$typeof as unknown\n return (\n !!value &&\n typeof value === 'object' &&\n (marker === REACT_ELEMENT_TYPE || marker === REACT_LEGACY_ELEMENT_TYPE) &&\n (value as ReactElement).type === type\n )\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] === 'function'\n}\n\nfunction walkComponent(\n fn: Function,\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n if ((fn as any).prototype?.isReactComponent) {\n const ctxType = (fn as any).contextType\n const ctxValue = ctxType ? ctxType._currentValue : undefined\n const instance = new (fn as any)(props, ctxValue)\n instance.props = props\n instance.context = ctxValue\n if ((fn as any).getDerivedStateFromProps) {\n const d = (fn as any).getDerivedStateFromProps(props, instance.state)\n if (d) instance.state = { ...instance.state, ...d }\n }\n walkNode(instance.render(), opts)\n return\n }\n const rendered = (fn as any)(props)\n walkNode(rendered, opts)\n}\n\nfunction walkSuspense(\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n const id = opts.nextBoundaryId()\n // Snapshot contexts BEFORE attempting children, so if a descendant suspends\n // we can replay the same provider stack when re-rendering the boundary.\n const contextSnapshot = snapshotContexts()\n\n // Try to render the children synchronously. If a thenable is thrown,\n // record the boundary and emit the fallback.\n const childParts: string[] = []\n const childEmit = (s: string) => childParts.push(s)\n try {\n walkNode(props.children, {\n emit: childEmit,\n onSuspend: opts.onSuspend,\n nextBoundaryId: opts.nextBoundaryId,\n })\n } catch (thenable: any) {\n if (isThenable(thenable)) {\n const fallbackParts: string[] = []\n try {\n walkNode(props.fallback, {\n emit: (s) => fallbackParts.push(s),\n onSuspend: opts.onSuspend,\n nextBoundaryId: opts.nextBoundaryId,\n })\n } catch {\n // Fallback suspending is unsupported; emit nothing\n }\n emitBoundary(opts, id, fallbackParts.join(''))\n\n if (opts.onSuspend) {\n opts.onSuspend({\n id,\n fallbackHTML: fallbackParts.join(''),\n children: props.children,\n thenable,\n contextSnapshot,\n })\n }\n return\n }\n throw thenable\n }\n\n // Children rendered fully \u2014 emit them wrapped in resolved-boundary markers\n // (`<!--$N-->` / `<!--/$-->`). Without markers, the client hydrator has no\n // way to know this subtree is inside a Suspense, so if the client version\n // of a descendant (e.g. `React.lazy`) suspends it can't pinpoint which DOM\n // range to adopt on resolve \u2014 it creates fresh DOM next to the SSR content,\n // producing visible duplicates (e.g. double navbar logos). Markers let the\n // client treat this as a resolved boundary and hydrate in-place.\n opts.emit(`<!--$${id}-->`)\n opts.emit(childParts.join(''))\n opts.emit(`<!--/$-->`)\n}\n\nfunction emitBoundary(opts: WalkOptions, id: number, fallbackHTML: string): void {\n // Visible div wrapper so the fallback UI shows; B: id lets $RC locate it on\n // reveal. The leading/trailing comments let hydration detect a pending\n // boundary and register a reveal callback.\n opts.emit(`<!--$?${id}--><div id=\"B:${id}\">`)\n opts.emit(fallbackHTML)\n opts.emit(`</div><!--/$-->`)\n}\n\nfunction isThenable(x: any): x is Promise<any> {\n return x != null && typeof x.then === 'function'\n}\n"],
|
|
5
|
-
"mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;
|
|
4
|
+
"sourcesContent": ["import {\n REACT_ELEMENT_TYPE,\n REACT_LEGACY_ELEMENT_TYPE,\n REACT_FRAGMENT_TYPE,\n type ReactNode,\n type ReactElement,\n} from '../core'\nimport {\n REACT_SUSPENSE_TYPE,\n REACT_PROVIDER_TYPE,\n REACT_CONSUMER_TYPE,\n REACT_FORWARD_REF_TYPE,\n REACT_MEMO_TYPE,\n REACT_LAZY_TYPE,\n REACT_STRICT_MODE_TYPE,\n REACT_PROFILER_TYPE,\n REACT_PORTAL_TYPE,\n} from '../react'\nimport {\n attrToHtml,\n escapeText,\n escapeScript,\n VOID_ELEMENTS,\n RAW_TEXT_ELEMENTS,\n} from './escape'\nimport {\n pushContext,\n popContext,\n snapshotContexts,\n type ContextSnapshot,\n} from './dispatcher'\n\nexport interface SuspendedBoundary {\n id: number\n fallbackHTML: string\n children: ReactNode\n thenable: Promise<any>\n contextSnapshot: ContextSnapshot\n}\n\nexport interface WalkOptions {\n emit: (chunk: string) => void\n onSuspend?: ((boundary: SuspendedBoundary) => void) | undefined\n nextBoundaryId: () => number\n bootstrapped?: boolean | undefined\n isBoundaryResolution?: boolean | undefined\n isSvg?: boolean | undefined\n /**\n * Tracks whether the most recent emission within the *current text flow*\n * ended with a text node. When the next emission is also text, we emit a\n * `<!-- -->` separator so the browser's HTML parser doesn't merge them\n * into a single text node \u2014 required for hydration to line up text\n * boundaries with the React tree. Reset to `false` whenever we enter a\n * new host element (`<tag>` opens a fresh text flow).\n */\n textState?: { lastWasText: boolean }\n}\n\n/**\n * Synchronously walk a React node and emit HTML string pieces to `opts.emit`.\n * Suspended boundaries are emitted as fallbacks with marker IDs; if `opts.onSuspend`\n * is provided, the suspension is recorded for later streaming.\n */\nexport function walk(node: ReactNode, opts: WalkOptions): void {\n // Seed a text state if the caller didn't provide one so the separator logic\n // is active for the whole tree.\n if (!opts.textState) opts = { ...opts, textState: { lastWasText: false } }\n walkNode(node, opts)\n}\n\n// --- <select> selection context ----------------------------------------------\n// Stack of active select values (or `undefined` when the current select has\n// no controlled value). `<option>` walks read the top of stack to decide\n// whether to emit `selected=\"\"`.\nconst selectValueStack: unknown[] = []\nfunction pushSelectContext(value: unknown): void {\n selectValueStack.push(value)\n}\nfunction popSelectContext(): void {\n selectValueStack.pop()\n}\nfunction currentSelectValue(): unknown {\n return selectValueStack.length ? selectValueStack[selectValueStack.length - 1] : undefined\n}\n\nfunction optionChildText(children: unknown): string {\n // `<option>Text</option>` \u2014 if no `value` prop, the option's value is its\n // flat string/number child content. Matches DOM semantics (`option.value`\n // defaults to `textContent` when no attribute is set).\n if (children == null) return ''\n if (typeof children === 'string' || typeof children === 'number') return '' + children\n if (Array.isArray(children)) return children.map(optionChildText).join('')\n return ''\n}\n\nfunction emitText(text: string, opts: WalkOptions): void {\n // Empty string renders no text node and doesn't start/extend a text flow \u2014\n // skip entirely so sibling text isn't separated by a stray `<!-- -->`.\n if (text === '') return\n if (opts.textState?.lastWasText) opts.emit('<!-- -->')\n opts.emit(escapeText(text))\n if (opts.textState) opts.textState.lastWasText = true\n}\n\nfunction walkNode(node: ReactNode, opts: WalkOptions): void {\n if (node == null || node === false || node === true) return\n\n if (typeof node === 'string') {\n emitText(node, opts)\n return\n }\n if (typeof node === 'number') {\n emitText(String(node), opts)\n return\n }\n if (Array.isArray(node)) {\n for (const c of node) walkNode(c, opts)\n return\n }\n if (typeof (node as any)[Symbol.iterator] === 'function') {\n for (const item of node as Iterable<ReactNode>) walkNode(item, opts)\n return\n }\n\n if (typeof node !== 'object') return\n const t = (node as any).$$typeof\n\n // Raw React.lazy in the tree (RSC Flight encodes 'use client' components \u2014\n // CodeBlock, CodeExplorer, etc. \u2014 as bare Lazy objects directly in the\n // tree, not wrapped in REACT_ELEMENT_TYPE). SSR previously dropped these\n // here, so code snippets never made it into the server HTML. The RSC\n // decoder server-side awaits payloads before rendering, so status is\n // 'fulfilled' and `_init()` returns the resolved element synchronously.\n // If still pending (shouldn't happen post-awaitLazyElements), throw the\n // thenable so streaming SSR suspends the current boundary and retries.\n if (t === REACT_LAZY_TYPE) {\n const lazy = node as any\n const resolved = lazy._init(lazy._payload)\n walkNode(resolved, opts)\n return\n }\n\n if (t !== REACT_ELEMENT_TYPE && t !== REACT_LEGACY_ELEMENT_TYPE) return\n\n const el = node as ReactElement\n walkElement(el, opts)\n}\n\nfunction walkElement(el: ReactElement, opts: WalkOptions): void {\n const type = el.type\n const props = el.props ?? {}\n\n if (type === REACT_FRAGMENT_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_PROFILER_TYPE) {\n walkNode(props.children, opts)\n return\n }\n\n if (type === REACT_SUSPENSE_TYPE) {\n walkSuspense(props, opts)\n return\n }\n\n if (typeof type === 'string') {\n walkHost(type, props, opts)\n return\n }\n\n const marker = (type as any)?.$$typeof\n\n if (marker === REACT_PORTAL_TYPE) {\n // Portals don't render to the main HTML output on the server.\n return\n }\n\n if (marker === REACT_PROVIDER_TYPE) {\n const ctx = (type as any)._context\n pushContext(ctx, props.value)\n try {\n walkNode(props.children, opts)\n } finally {\n popContext(ctx)\n }\n return\n }\n\n if (marker === REACT_CONSUMER_TYPE) {\n const ctx = (type as any)._context\n const render = props.children\n if (typeof render === 'function') {\n walkNode(render(ctx._currentValue), opts)\n }\n return\n }\n\n if (marker === REACT_FORWARD_REF_TYPE) {\n const render = (type as any).render\n const ref = (props as any).ref ?? null\n const { ref: _omit, ...rest } = props as any\n const rendered = render(rest, ref)\n walkNode(rendered, opts)\n return\n }\n\n if (marker === REACT_MEMO_TYPE) {\n const inner = (type as any).type\n walkElement({ ...el, type: inner } as ReactElement, opts)\n return\n }\n\n if (marker === REACT_LAZY_TYPE) {\n const { _payload, _init } = type as any\n try {\n const resolved = _init(_payload)\n walkElement({ ...el, type: resolved } as ReactElement, opts)\n } catch (thenable: any) {\n if (isThenable(thenable)) {\n // Suspend this point\n throw thenable\n }\n throw thenable\n }\n return\n }\n\n if (typeof type === 'function') {\n walkComponent(type, props, opts)\n return\n }\n}\n\nfunction walkHost(\n tag: string,\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n const isSvg = opts.isSvg || tag === 'svg'\n // <textarea value=\"...\"> serializes its value as a TEXT CHILD, not an\n // attribute. `defaultValue` is the fallback when `value` is absent. This\n // matches React and the HTML spec \u2014 `<textarea value=\"x\">` is not valid\n // HTML; the value is the element's textContent.\n const isTextarea = tag === 'textarea'\n const textareaValue = isTextarea\n ? props.value != null\n ? props.value\n : props.defaultValue\n : undefined\n\n // <input defaultValue=\"...\"> should parse with that value \u2014 emit it as a\n // `value` attribute. Similarly `defaultChecked` becomes `checked`. This\n // keeps hydration consistent: the browser parser sees the initial value,\n // and on client commit our setProp seeds `.defaultValue`/`.defaultChecked`\n // without stomping the user-typed value.\n const isInput = tag === 'input'\n const inputValueAttr =\n isInput && props.value == null && props.defaultValue != null\n ? props.defaultValue\n : undefined\n const inputCheckedAttr =\n isInput && props.checked == null && props.defaultChecked != null\n ? props.defaultChecked\n : undefined\n\n // <select value=\"...\"> does NOT become an attribute on `<select>` \u2014 the\n // HTML spec has no such attribute. React resolves the selection by stamping\n // `selected` on the matching `<option>` children during render. Stash the\n // target value(s) on the walk state and the child `<option>` walk reads it.\n const isSelect = tag === 'select'\n if (isSelect) {\n const val = props.value != null ? props.value : props.defaultValue\n pushSelectContext(val)\n }\n const isOption = tag === 'option'\n\n // Prepend the HTML5 doctype to the stream when rendering an <html> root.\n // Without it the browser parses the document in quirks mode, which breaks\n // CSS sizing (documentElement.clientHeight returns the content height, not\n // the viewport) \u2014 and Floating-UI-based libraries (Radix dropdowns etc.)\n // then compute off-screen positions for overlays.\n if (tag === 'html') opts.emit('<!DOCTYPE html>')\n\n opts.emit('<' + tag)\n for (const k in props) {\n if (isTextarea && (k === 'value' || k === 'defaultValue')) continue\n if (isInput && (k === 'defaultValue' || k === 'defaultChecked')) continue\n if (isSelect && (k === 'value' || k === 'defaultValue')) continue\n if (isOption && k === 'selected') continue\n opts.emit(attrToHtml(k, props[k], isSvg))\n }\n if (inputValueAttr !== undefined) {\n opts.emit(attrToHtml('value', inputValueAttr, isSvg))\n }\n if (inputCheckedAttr !== undefined) {\n opts.emit(attrToHtml('checked', inputCheckedAttr, isSvg))\n }\n if (isOption) {\n const selectVal = currentSelectValue()\n if (selectVal !== undefined) {\n const optionValue =\n props.value != null ? props.value : optionChildText(props.children)\n const matches = Array.isArray(selectVal)\n ? selectVal.some((v) => '' + v === '' + optionValue)\n : '' + selectVal === '' + optionValue\n if (matches) opts.emit(' selected=\"\"')\n } else if (props.selected) {\n opts.emit(' selected=\"\"')\n }\n }\n\n if (VOID_ELEMENTS.has(tag)) {\n opts.emit('/>')\n if (opts.textState) opts.textState.lastWasText = false\n return\n }\n opts.emit('>')\n // Opening a host element starts a fresh text flow context for its children.\n // Children's text separator tracking is independent of the outer context.\n const parentTextState = opts.textState\n const childOpts: WalkOptions = {\n ...opts,\n isSvg: isSvg && tag !== 'foreignObject',\n textState: { lastWasText: false },\n }\n\n if (tag === 'html' && !hasHeadChild(props.children)) {\n opts.emit('<head></head>')\n }\n\n const dangerouslyHtml = props.dangerouslySetInnerHTML?.__html\n\n if (isTextarea && textareaValue != null) {\n opts.emit(escapeText(String(textareaValue)))\n opts.emit(`</${tag}>`)\n if (parentTextState) parentTextState.lastWasText = false\n return\n }\n\n if (RAW_TEXT_ELEMENTS.has(tag)) {\n // script/style: raw-text. React allows either a string/number child or\n // dangerouslySetInnerHTML \u2014 some libs (Start's Scripts) use the latter.\n if (dangerouslyHtml != null) {\n opts.emit(escapeScript(String(dangerouslyHtml)))\n } else {\n const children = props.children\n if (typeof children === 'string' || typeof children === 'number') {\n opts.emit(escapeScript(String(children)))\n } else if (Array.isArray(children)) {\n opts.emit(escapeScript(children.filter((c) => c != null).join('')))\n }\n }\n opts.emit(`</${tag}>`)\n if (parentTextState) parentTextState.lastWasText = false\n return\n }\n\n if (dangerouslyHtml != null) {\n opts.emit(String(dangerouslyHtml))\n } else {\n walkNode(props.children, childOpts)\n }\n opts.emit(`</${tag}>`)\n if (isSelect) popSelectContext()\n // Host element closing resets outer flow \u2014 next sibling text starts fresh.\n if (parentTextState) parentTextState.lastWasText = false\n}\n\nfunction hasHeadChild(children: unknown): boolean {\n if (children == null || typeof children === 'boolean') return false\n if (Array.isArray(children)) return children.some(hasHeadChild)\n if (typeof children !== 'string' && isIterable(children)) {\n for (const child of children as Iterable<unknown>) {\n if (hasHeadChild(child)) return true\n }\n return false\n }\n return isElementOfType(children, 'head')\n}\n\nfunction isElementOfType(value: unknown, type: string): value is ReactElement {\n const marker = (value as ReactElement | null)?.$$typeof as unknown\n return (\n !!value &&\n typeof value === 'object' &&\n (marker === REACT_ELEMENT_TYPE || marker === REACT_LEGACY_ELEMENT_TYPE) &&\n (value as ReactElement).type === type\n )\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return !!value && typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] === 'function'\n}\n\nfunction walkComponent(\n fn: Function,\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n if ((fn as any).prototype?.isReactComponent) {\n const ctxType = (fn as any).contextType\n const ctxValue = ctxType ? ctxType._currentValue : undefined\n const instance = new (fn as any)(props, ctxValue)\n instance.props = props\n instance.context = ctxValue\n if ((fn as any).getDerivedStateFromProps) {\n const d = (fn as any).getDerivedStateFromProps(props, instance.state)\n if (d) instance.state = { ...instance.state, ...d }\n }\n walkNode(instance.render(), opts)\n return\n }\n const rendered = (fn as any)(props)\n walkNode(rendered, opts)\n}\n\nfunction walkSuspense(\n props: Record<string, any>,\n opts: WalkOptions,\n): void {\n const id = opts.nextBoundaryId()\n // Snapshot contexts BEFORE attempting children, so if a descendant suspends\n // we can replay the same provider stack when re-rendering the boundary.\n const contextSnapshot = snapshotContexts()\n\n // Try to render the children synchronously. If a thenable is thrown,\n // record the boundary and emit the fallback.\n const childParts: string[] = []\n const childEmit = (s: string) => childParts.push(s)\n try {\n walkNode(props.children, {\n emit: childEmit,\n onSuspend: opts.onSuspend,\n nextBoundaryId: opts.nextBoundaryId,\n })\n } catch (thenable: any) {\n if (isThenable(thenable)) {\n const fallbackParts: string[] = []\n try {\n walkNode(props.fallback, {\n emit: (s) => fallbackParts.push(s),\n onSuspend: opts.onSuspend,\n nextBoundaryId: opts.nextBoundaryId,\n })\n } catch {\n // Fallback suspending is unsupported; emit nothing\n }\n emitBoundary(opts, id, fallbackParts.join(''))\n\n if (opts.onSuspend) {\n opts.onSuspend({\n id,\n fallbackHTML: fallbackParts.join(''),\n children: props.children,\n thenable,\n contextSnapshot,\n })\n }\n return\n }\n throw thenable\n }\n\n // Children rendered fully \u2014 emit them wrapped in resolved-boundary markers\n // (`<!--$N-->` / `<!--/$-->`). Without markers, the client hydrator has no\n // way to know this subtree is inside a Suspense, so if the client version\n // of a descendant (e.g. `React.lazy`) suspends it can't pinpoint which DOM\n // range to adopt on resolve \u2014 it creates fresh DOM next to the SSR content,\n // producing visible duplicates (e.g. double navbar logos). Markers let the\n // client treat this as a resolved boundary and hydrate in-place.\n opts.emit(`<!--$${id}-->`)\n opts.emit(childParts.join(''))\n opts.emit(`<!--/$-->`)\n}\n\nfunction emitBoundary(opts: WalkOptions, id: number, fallbackHTML: string): void {\n // Visible div wrapper so the fallback UI shows; B: id lets $RC locate it on\n // reveal. The leading/trailing comments let hydration detect a pending\n // boundary and register a reveal callback.\n opts.emit(`<!--$?${id}--><div id=\"B:${id}\">`)\n opts.emit(fallbackHTML)\n opts.emit(`</div><!--/$-->`)\n}\n\nfunction isThenable(x: any): x is Promise<any> {\n return x != null && typeof x.then === 'function'\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function attributeName(name: string, isSvg = false): string {
|
|
2
|
+
if (isSvg && name !== 'viewBox' && SVG_KEBAB_PREFIX.test(name)) {
|
|
3
|
+
return name.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase())
|
|
4
|
+
}
|
|
5
|
+
if (name === 'className') return 'class'
|
|
6
|
+
if (name === 'htmlFor') return 'for'
|
|
7
|
+
if (name === 'httpEquiv') return 'http-equiv'
|
|
8
|
+
if (name === 'acceptCharset') return 'accept-charset'
|
|
9
|
+
if (name === 'crossOrigin') return 'crossorigin'
|
|
10
|
+
if (name === 'noModule') return 'nomodule'
|
|
11
|
+
if (name === 'viewBox') return 'viewBox'
|
|
12
|
+
return name.startsWith('aria-') || name.startsWith('data-')
|
|
13
|
+
? name
|
|
14
|
+
: name.toLowerCase()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const SVG_KEBAB_PREFIX = /^(?:clip|fill|stroke)/
|
package/src/core/internal.ts
CHANGED
package/src/dom/dispatcher.ts
CHANGED
|
@@ -209,7 +209,9 @@ function makeDispatcherImpl() {
|
|
|
209
209
|
if (hook.s === undefined) {
|
|
210
210
|
const fiber = getCurrentFiber()
|
|
211
211
|
const root = findRootFromFiber(fiber)
|
|
212
|
-
hook.s =
|
|
212
|
+
hook.s = root
|
|
213
|
+
? root.i + (root.ic++).toString(36)
|
|
214
|
+
: ':r' + (idCounter++).toString(36)
|
|
213
215
|
}
|
|
214
216
|
return hook.s as string
|
|
215
217
|
},
|
package/src/dom/dom.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { attributeName } from '../core/attributes'
|
|
2
|
+
|
|
1
3
|
const SVG_NS = 'http://www.w3.org/2000/svg'
|
|
2
4
|
|
|
3
5
|
const BOOLEAN_ATTRS = new Set([
|
|
@@ -60,6 +62,7 @@ export function setProp(
|
|
|
60
62
|
isSvg: boolean,
|
|
61
63
|
): void {
|
|
62
64
|
if (name === 'children' || name === 'key' || name === 'ref') return
|
|
65
|
+
const attr = attributeName(name, isSvg)
|
|
63
66
|
|
|
64
67
|
// defaultValue / defaultChecked are IDL-property-only — they seed the
|
|
65
68
|
// initial value/checked of a form control on first mount and must NOT be
|
|
@@ -123,8 +126,8 @@ export function setProp(
|
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
if (BOOLEAN_ATTRS.has(name.toLowerCase())) {
|
|
126
|
-
if (next) el.setAttribute(
|
|
127
|
-
else el.removeAttribute(
|
|
129
|
+
if (next) el.setAttribute(attr, '')
|
|
130
|
+
else el.removeAttribute(attr)
|
|
128
131
|
return
|
|
129
132
|
}
|
|
130
133
|
|
|
@@ -134,20 +137,20 @@ export function setProp(
|
|
|
134
137
|
if (name.length > 5 && (name.charCodeAt(0) === 97 /* a */ || name.charCodeAt(0) === 100 /* d */)) {
|
|
135
138
|
if (name.startsWith('aria-') || name.startsWith('data-')) {
|
|
136
139
|
if (next == null) {
|
|
137
|
-
el.removeAttribute(
|
|
140
|
+
el.removeAttribute(attr)
|
|
138
141
|
} else {
|
|
139
|
-
el.setAttribute(
|
|
142
|
+
el.setAttribute(attr, '' + next)
|
|
140
143
|
}
|
|
141
144
|
return
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
|
|
145
148
|
if (next == null || next === false) {
|
|
146
|
-
el.removeAttribute(
|
|
149
|
+
el.removeAttribute(attr)
|
|
147
150
|
} else if (next === true) {
|
|
148
|
-
el.setAttribute(
|
|
151
|
+
el.setAttribute(attr, '')
|
|
149
152
|
} else {
|
|
150
|
-
el.setAttribute(
|
|
153
|
+
el.setAttribute(attr, '' + next)
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
156
|
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type ReactElement,
|
|
7
7
|
type ReactNode,
|
|
8
8
|
} from '../../../core'
|
|
9
|
+
import { attributeName } from '../../../core/attributes'
|
|
9
10
|
import { createHostNode, setProp } from '../../dom'
|
|
10
11
|
import { drainReplayQueue } from '../../event-replay'
|
|
11
12
|
import { discardPendingWork, findRoot, flushSyncWork, renderRoot } from '../../reconcile'
|
|
@@ -119,7 +120,14 @@ export class HydrationCursor {
|
|
|
119
120
|
has(): boolean {
|
|
120
121
|
let n = this.n
|
|
121
122
|
while (n && n !== this.e) {
|
|
122
|
-
if (n.nodeType === 1
|
|
123
|
+
if (n.nodeType === 1) {
|
|
124
|
+
if ((n as Element).tagName === 'SCRIPT') {
|
|
125
|
+
n = n.nextSibling
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
return true
|
|
129
|
+
}
|
|
130
|
+
if (n.nodeType === 3 && (n as Text).data.trim() !== '') return true
|
|
123
131
|
n = n.nextSibling
|
|
124
132
|
}
|
|
125
133
|
return false
|
|
@@ -163,7 +171,10 @@ export function hydrateRootImpl(
|
|
|
163
171
|
const target = container as any as Element | Document
|
|
164
172
|
const isDocument = (container as Node).nodeType === 9
|
|
165
173
|
const body = isDocument ? (target as Document).body : null
|
|
166
|
-
const root = createFiberRoot(target,
|
|
174
|
+
const root = createFiberRoot(target, {
|
|
175
|
+
...options,
|
|
176
|
+
identifierPrefix: options.identifierPrefix ?? ':R',
|
|
177
|
+
})
|
|
167
178
|
|
|
168
179
|
installHydrationScrollGuard()
|
|
169
180
|
|
|
@@ -202,6 +213,8 @@ export function hydrateRootImpl(
|
|
|
202
213
|
}
|
|
203
214
|
resetAfterHydrationFailure(root, recoveryContainer)
|
|
204
215
|
try {
|
|
216
|
+
root.i = options.identifierPrefix ?? ':r'
|
|
217
|
+
root.ic = 0
|
|
205
218
|
flushSyncWork(() => {
|
|
206
219
|
renderRoot(root, recoveryChildren)
|
|
207
220
|
})
|
|
@@ -746,7 +759,7 @@ function validateHydrationProps(
|
|
|
746
759
|
}
|
|
747
760
|
|
|
748
761
|
const stringifiedBoolean = k.startsWith('aria-') || k.startsWith('data-')
|
|
749
|
-
const attr = k
|
|
762
|
+
const attr = attributeName(k, isSvg)
|
|
750
763
|
|
|
751
764
|
let expectedValue: string | null
|
|
752
765
|
if (value == null || (value === false && !stringifiedBoolean)) {
|
|
@@ -758,6 +771,9 @@ function validateHydrationProps(
|
|
|
758
771
|
}
|
|
759
772
|
const actualValue = el.getAttribute(attr)
|
|
760
773
|
if (expectedValue !== actualValue) {
|
|
774
|
+
if (attr === 'id' && expectedValue != null && actualValue != null) {
|
|
775
|
+
continue
|
|
776
|
+
}
|
|
761
777
|
if (process.env.NODE_ENV !== 'production') {
|
|
762
778
|
failHydration(
|
|
763
779
|
fiber,
|
package/src/dom/root-internal.ts
CHANGED
|
@@ -21,6 +21,7 @@ export function createFiberRoot(
|
|
|
21
21
|
ce: options.onCaughtError,
|
|
22
22
|
ue: options.onUncaughtError,
|
|
23
23
|
i: options.identifierPrefix ?? ':r',
|
|
24
|
+
ic: 0,
|
|
24
25
|
h: false,
|
|
25
26
|
}
|
|
26
27
|
rootFiber.root = root
|
|
@@ -34,6 +35,7 @@ export function attachRootFiber(
|
|
|
34
35
|
): void {
|
|
35
36
|
const rootFiber = createFiber(FiberTag.Root, null, null)
|
|
36
37
|
root.c = container as any
|
|
38
|
+
root.ic = 0
|
|
37
39
|
rootFiber.root = root
|
|
38
40
|
rootFiber.sn = container
|
|
39
41
|
root.r = rootFiber
|
package/src/server/escape.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { attributeName } from '../core/attributes'
|
|
2
|
+
|
|
1
3
|
const ATTR_MAP: Record<string, string> = {
|
|
2
4
|
'&': '&',
|
|
3
5
|
'"': '"',
|
|
@@ -48,17 +50,6 @@ export const VOID_ELEMENTS = new Set([
|
|
|
48
50
|
|
|
49
51
|
export const RAW_TEXT_ELEMENTS = new Set(['script', 'style'])
|
|
50
52
|
|
|
51
|
-
// Map JSX prop names to HTML attribute names where they differ
|
|
52
|
-
export const ATTR_ALIASES: Record<string, string> = {
|
|
53
|
-
className: 'class',
|
|
54
|
-
htmlFor: 'for',
|
|
55
|
-
httpEquiv: 'http-equiv',
|
|
56
|
-
acceptCharset: 'accept-charset',
|
|
57
|
-
crossOrigin: 'crossorigin',
|
|
58
|
-
viewBox: 'viewBox', // SVG keeps camelCase
|
|
59
|
-
noModule: 'nomodule',
|
|
60
|
-
}
|
|
61
|
-
|
|
62
53
|
const BOOLEAN_ATTRS = new Set([
|
|
63
54
|
'allowfullscreen',
|
|
64
55
|
'async',
|
|
@@ -87,7 +78,7 @@ const BOOLEAN_ATTRS = new Set([
|
|
|
87
78
|
'selected',
|
|
88
79
|
])
|
|
89
80
|
|
|
90
|
-
export function attrToHtml(name: string, value: unknown): string {
|
|
81
|
+
export function attrToHtml(name: string, value: unknown, isSvg = false): string {
|
|
91
82
|
if (
|
|
92
83
|
name === 'children' ||
|
|
93
84
|
name === 'key' ||
|
|
@@ -103,7 +94,7 @@ export function attrToHtml(name: string, value: unknown): string {
|
|
|
103
94
|
if (name[0] === 'o' && name[1] === 'n' && typeof value === 'function') return ''
|
|
104
95
|
if (value == null) return ''
|
|
105
96
|
|
|
106
|
-
const htmlName =
|
|
97
|
+
const htmlName = attributeName(name, isSvg)
|
|
107
98
|
|
|
108
99
|
// aria-* and data-* stringify booleans to `"true"`/`"false"` rather than
|
|
109
100
|
// using boolean-attribute presence semantics — matches React and the ARIA
|
package/src/server/walk.ts
CHANGED
|
@@ -44,6 +44,7 @@ export interface WalkOptions {
|
|
|
44
44
|
nextBoundaryId: () => number
|
|
45
45
|
bootstrapped?: boolean | undefined
|
|
46
46
|
isBoundaryResolution?: boolean | undefined
|
|
47
|
+
isSvg?: boolean | undefined
|
|
47
48
|
/**
|
|
48
49
|
* Tracks whether the most recent emission within the *current text flow*
|
|
49
50
|
* ended with a text node. When the next emission is also text, we emit a
|
|
@@ -232,6 +233,7 @@ function walkHost(
|
|
|
232
233
|
props: Record<string, any>,
|
|
233
234
|
opts: WalkOptions,
|
|
234
235
|
): void {
|
|
236
|
+
const isSvg = opts.isSvg || tag === 'svg'
|
|
235
237
|
// <textarea value="..."> serializes its value as a TEXT CHILD, not an
|
|
236
238
|
// attribute. `defaultValue` is the fallback when `value` is absent. This
|
|
237
239
|
// matches React and the HTML spec — `<textarea value="x">` is not valid
|
|
@@ -282,13 +284,13 @@ function walkHost(
|
|
|
282
284
|
if (isInput && (k === 'defaultValue' || k === 'defaultChecked')) continue
|
|
283
285
|
if (isSelect && (k === 'value' || k === 'defaultValue')) continue
|
|
284
286
|
if (isOption && k === 'selected') continue
|
|
285
|
-
opts.emit(attrToHtml(k, props[k]))
|
|
287
|
+
opts.emit(attrToHtml(k, props[k], isSvg))
|
|
286
288
|
}
|
|
287
289
|
if (inputValueAttr !== undefined) {
|
|
288
|
-
opts.emit(attrToHtml('value', inputValueAttr))
|
|
290
|
+
opts.emit(attrToHtml('value', inputValueAttr, isSvg))
|
|
289
291
|
}
|
|
290
292
|
if (inputCheckedAttr !== undefined) {
|
|
291
|
-
opts.emit(attrToHtml('checked', inputCheckedAttr))
|
|
293
|
+
opts.emit(attrToHtml('checked', inputCheckedAttr, isSvg))
|
|
292
294
|
}
|
|
293
295
|
if (isOption) {
|
|
294
296
|
const selectVal = currentSelectValue()
|
|
@@ -313,7 +315,11 @@ function walkHost(
|
|
|
313
315
|
// Opening a host element starts a fresh text flow context for its children.
|
|
314
316
|
// Children's text separator tracking is independent of the outer context.
|
|
315
317
|
const parentTextState = opts.textState
|
|
316
|
-
const childOpts: WalkOptions = {
|
|
318
|
+
const childOpts: WalkOptions = {
|
|
319
|
+
...opts,
|
|
320
|
+
isSvg: isSvg && tag !== 'foreignObject',
|
|
321
|
+
textState: { lastWasText: false },
|
|
322
|
+
}
|
|
317
323
|
|
|
318
324
|
if (tag === 'html' && !hasHeadChild(props.children)) {
|
|
319
325
|
opts.emit('<head></head>')
|