@barefootjs/client 0.31.8 → 0.31.10

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.
@@ -169911,6 +169911,34 @@ var SVG_ROOT_TAGS = new Set([
169911
169911
  "animateTransform",
169912
169912
  "animateMotion"
169913
169913
  ]);
169914
+ var MATHML_ROOT_TAGS = new Set([
169915
+ "math",
169916
+ "mrow",
169917
+ "mfrac",
169918
+ "msup",
169919
+ "msub",
169920
+ "msubsup",
169921
+ "mn",
169922
+ "mi",
169923
+ "mo",
169924
+ "mtext",
169925
+ "munder",
169926
+ "mover",
169927
+ "munderover",
169928
+ "mtable",
169929
+ "mtr",
169930
+ "mtd",
169931
+ "msqrt",
169932
+ "mroot",
169933
+ "mstyle",
169934
+ "merror",
169935
+ "mpadded",
169936
+ "mphantom",
169937
+ "menclose",
169938
+ "semantics",
169939
+ "annotation",
169940
+ "annotation-xml"
169941
+ ]);
169914
169942
 
169915
169943
  // ../jsx/src/ir-to-client-js/collect-elements.ts
169916
169944
  var EMPTY_RENDER_EXPRS = new Set(["null", "undefined", "false", "''", '""', "``"]);
@@ -141,6 +141,60 @@ export declare function escapeAttr(value: unknown): string;
141
141
  * the reactive path.
142
142
  */
143
143
  export declare function escapeText(value: unknown): string;
144
+ /**
145
+ * Brand carried by `bfMarkup()` — see that function's docstring. A string
146
+ * key (not a `Symbol`) because the brand must survive `structuredClone`
147
+ * (props cloned across an SSR seed / island-serialization boundary): a
148
+ * symbol-keyed property is silently dropped by the structured-clone
149
+ * algorithm, which would un-brand the value in transit.
150
+ */
151
+ declare const BF_MARKUP_BRAND = "__bfMarkup";
152
+ /**
153
+ * Shape produced by `bfMarkup()` (#2651). Compiler-emitted code only —
154
+ * never construct one by hand from userland; doing so is exactly as unsafe
155
+ * as writing raw `innerHTML` yourself, since `escapeTextOrMarkup` /
156
+ * `escapeTextOrNode` (below) trust `__bfMarkup`'s contents to already be
157
+ * safe-to-splice HTML and skip escaping it.
158
+ */
159
+ export interface BfMarkup {
160
+ readonly [BF_MARKUP_BRAND]: string;
161
+ }
162
+ /**
163
+ * Brand a compiler-built HTML string as pre-escaped markup safe to splice
164
+ * raw into a template (#2651). The compiler emits this ONLY around HTML it
165
+ * itself assembled from a JSX element passed at a non-`children` component
166
+ * prop position (`header={<strong>Title</strong>}`) — every text segment
167
+ * inside that assembly was already escaped node-by-node during the
168
+ * assembly (the same `escapeHtml` / `escapeTextSlotExpr` calls
169
+ * `html-template.ts` uses for ordinary element children), so the
170
+ * concatenated result is exactly as safe as any other compiler-emitted
171
+ * template fragment.
172
+ *
173
+ * Not exported from the public `@barefootjs/client` surface: this is
174
+ * compiler-emitted-code only, exported solely from
175
+ * `@barefootjs/client/runtime`. Calling it directly from userland to wrap
176
+ * an arbitrary string is exactly as unsafe as assigning that string to
177
+ * `innerHTML` yourself — the value is trusted verbatim by every consumer
178
+ * below.
179
+ */
180
+ export declare function bfMarkup(html: string): BfMarkup;
181
+ /** Type guard for the `bfMarkup()` brand (#2651). Compiler-emitted code only — see `bfMarkup`'s docstring. */
182
+ export declare function isBfMarkup(value: unknown): value is BfMarkup;
183
+ /**
184
+ * `escapeText`'s counterpart for a claim-plan slot the compiler has
185
+ * classified `kind: 'markup'` at STATIC/initial-render time
186
+ * (`html-template.ts`'s `escapeTextSlotExpr`, gated on the same
187
+ * `ctx.dynamicElements` membership `emit-reactive.ts` reads to pick the
188
+ * writer kind for the REACTIVE side, below) — #2651. A `bfMarkup()`-branded
189
+ * value is compiler-built HTML the compiler already escaped piecewise
190
+ * while assembling it, and must reach the template raw, unescaped a second
191
+ * time; anything else (plain string, number, nullish) gets the ordinary
192
+ * `escapeText` treatment — this function is a strict superset of
193
+ * `escapeText`'s behaviour for every non-branded value, so switching a
194
+ * call site from one to the other never changes output unless the value
195
+ * is actually branded.
196
+ */
197
+ export declare function escapeTextOrMarkup(value: unknown): string;
144
198
  /**
145
199
  * `escapeText`'s counterpart for a claimed 'markup' slot's REACTIVE write
146
200
  * (slot unification A3 follow-up), where the value is a plain-JS expression
@@ -160,6 +214,14 @@ export declare function escapeText(value: unknown): string;
160
214
  * before handing it to a 'markup' writer — NOT the preamble-region case
161
215
  * (`stringify/loop.ts`), whose value is already-built HTML from a nested
162
216
  * compiled render and must stay unescaped.
217
+ *
218
+ * A `bfMarkup()`-branded value (#2651) — a component prop re-read on every
219
+ * reactive re-run, e.g. `initChild`'s `get header() { return bfMarkup(...) }`
220
+ * getter — is unwrapped to its raw string for the same reason a `Node` is
221
+ * passed through untouched: the compiler already escaped its contents once
222
+ * during assembly, so re-escaping it (or, worse, `String()`-stringifying
223
+ * the wrapper object into `"[object Object]"`) would corrupt it. Checked
224
+ * before the `Node` branch since the two shapes are mutually exclusive.
163
225
  */
164
226
  export declare function escapeTextOrNode(value: unknown): string | Node;
165
227
  /**
@@ -167,14 +229,16 @@ export declare function escapeTextOrNode(value: unknown): string | Node;
167
229
  * attribute values. All code that sets innerHTML on dynamic HTML should
168
230
  * use this instead of raw innerHTML assignment.
169
231
  *
170
- * When `parent` is provided and lives in the SVG namespace, the markup
171
- * is parsed under SVG foreign-content context by wrapping it in
172
- * `<svg>...</svg>`; the wrapper's children are moved into the returned
173
- * fragment so callers see the same shape as the HTML path. Without
174
- * this, dynamically-inserted SVG elements (e.g., a `<path>` in a
175
- * conditional drag preview) end up as `HTMLUnknownElement` in the
176
- * xhtml namespace and the SVG renderer ignores them. Surfaced by the
177
- * Graph/DAG Editor block (#135).
232
+ * When `parent` is provided and lives in the SVG or MathML namespace, the
233
+ * markup is parsed under the matching foreign-content context by wrapping
234
+ * it in `<svg>...</svg>` / `<math>...</math>`; the wrapper's children are
235
+ * moved into the returned fragment so callers see the same shape as the
236
+ * HTML path. Without this, dynamically-inserted SVG/MathML elements (e.g.,
237
+ * a `<path>` in a conditional drag preview, or an `<mrow>` in a dynamic
238
+ * equation) end up as `HTMLUnknownElement` in the xhtml namespace and the
239
+ * SVG/MathML renderer ignores them. Surfaced by the Graph/DAG Editor block
240
+ * (#135); ported to MathML in #1096.
178
241
  */
179
242
  export declare function parseHTML(html: string, parent?: Element | null): DocumentFragment;
243
+ export {};
180
244
  //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/runtime/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAS9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAA;AAsB9F,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAI9E;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAQjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;;;GAGG;AACH;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,EAC9B,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,WAAW,CAcb;AA4OD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CA6ER;AA+DD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG9D;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAcjF"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/runtime/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAS9C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAA;AAsB9F,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAI9E;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAQjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH;;;GAGG;AACH;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,EAC9B,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,WAAW,CAcb;AA4OD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CA6ER;AA+DD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED;;;;;;GAMG;AACH,QAAA,MAAM,eAAe,eAAe,CAAA;AAEpC;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CACnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAED,8GAA8G;AAC9G,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAU5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI9D;AAaD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAejF"}
@@ -15,7 +15,7 @@ export { mapArrayLazy, type LazyRowEntry, type LazyRowPlan } from './map-array-l
15
15
  export { patchLeaf } from './patch-leaf.ts';
16
16
  export { claimSlots, lazySlots, lazyClaimSlots, textOrNode, type SlotSpec, type ClaimPlan, type ClaimedSlots, type ClaimedSlotsRW, type SlotWriter } from './claim-slots.ts';
17
17
  export { registerTemplate, getTemplate, hasTemplate, type TemplateFn } from './template.ts';
18
- export { createComponent, mountRowRoot, renderChild, parseHTML, escapeAttr, escapeText, escapeTextOrNode, } from './component.ts';
18
+ export { createComponent, mountRowRoot, renderChild, parseHTML, escapeAttr, escapeText, escapeTextOrNode, bfMarkup, isBfMarkup, escapeTextOrMarkup, type BfMarkup, } from './component.ts';
19
19
  export { applyRestAttrs } from './apply-rest-attrs.ts';
20
20
  export { spreadAttrs } from './spread-attrs.ts';
21
21
  export { styleToCss } from './style.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,cAAc,EACd,UAAU,EACV,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,eAAe,EACf,SAAS,EACT,OAAO,EACP,gBAAgB,EAOhB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAI9C,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,eAAe,EACf,KAAK,OAAO,GACb,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,eAAe,EACf,wBAAwB,EACxB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;AAIpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAI3D,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACvF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAK3C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG5K,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAG3F,OAAO,EACL,eAAe,EACf,YAAY,EACZ,WAAW,EACX,SAAS,EACT,UAAU,EACV,UAAU,EACV,gBAAgB,GACjB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGvC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC9G,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpH,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3F,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAQ3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAGrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG1D,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"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"}
@@ -1543,17 +1543,47 @@ function escapeText(value) {
1543
1543
  return "";
1544
1544
  return escapeAttr(value);
1545
1545
  }
1546
+ var BF_MARKUP_BRAND = "__bfMarkup";
1547
+ function bfMarkup(html) {
1548
+ return { [BF_MARKUP_BRAND]: html };
1549
+ }
1550
+ function isBfMarkup(value) {
1551
+ if (typeof value !== "object" || value === null)
1552
+ return false;
1553
+ const proto = Object.getPrototypeOf(value);
1554
+ if (proto !== Object.prototype && proto !== null)
1555
+ return false;
1556
+ return typeof value[BF_MARKUP_BRAND] === "string";
1557
+ }
1558
+ function escapeTextOrMarkup(value) {
1559
+ if (isBfMarkup(value))
1560
+ return value[BF_MARKUP_BRAND];
1561
+ return escapeText(value);
1562
+ }
1546
1563
  function escapeTextOrNode(value) {
1564
+ if (isBfMarkup(value))
1565
+ return value[BF_MARKUP_BRAND];
1547
1566
  if (typeof Node !== "undefined" && value instanceof Node)
1548
1567
  return value;
1549
1568
  return escapeText(value);
1550
1569
  }
1551
1570
  var SVG_NS = "http://www.w3.org/2000/svg";
1571
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
1572
+ function namespaceWrapTagFor(parent) {
1573
+ if (!parent)
1574
+ return null;
1575
+ if (parent.namespaceURI === SVG_NS)
1576
+ return "svg";
1577
+ if (parent.namespaceURI === MATHML_NS)
1578
+ return "math";
1579
+ return null;
1580
+ }
1552
1581
  function parseHTML(html, parent) {
1553
1582
  const tpl = document.createElement("template");
1554
1583
  const escaped = escapeAttrGt(html);
1555
- if (parent && parent.namespaceURI === SVG_NS) {
1556
- tpl.innerHTML = `<svg>${escaped}</svg>`;
1584
+ const wrapTag = namespaceWrapTagFor(parent);
1585
+ if (wrapTag) {
1586
+ tpl.innerHTML = `<${wrapTag}>${escaped}</${wrapTag}>`;
1557
1587
  const wrapper = tpl.content.firstElementChild;
1558
1588
  const frag = document.createDocumentFragment();
1559
1589
  if (wrapper) {
@@ -3273,6 +3303,7 @@ export {
3273
3303
  lazySlots,
3274
3304
  lazyClaimSlots,
3275
3305
  isSSRPortal,
3306
+ isBfMarkup,
3276
3307
  insert,
3277
3308
  initChild,
3278
3309
  hydratedScopes,
@@ -3290,6 +3321,7 @@ export {
3290
3321
  findScope,
3291
3322
  find,
3292
3323
  escapeTextOrNode,
3324
+ escapeTextOrMarkup,
3293
3325
  escapeText,
3294
3326
  escapeAttr,
3295
3327
  endTurn,
@@ -3309,6 +3341,7 @@ export {
3309
3341
  createComponent,
3310
3342
  cleanupPortalPlaceholder,
3311
3343
  claimSlots,
3344
+ bfMarkup,
3312
3345
  beginTurn,
3313
3346
  batch,
3314
3347
  applyRestAttrs,
@@ -1949,17 +1949,47 @@ function escapeText(value) {
1949
1949
  return "";
1950
1950
  return escapeAttr(value);
1951
1951
  }
1952
+ var BF_MARKUP_BRAND = "__bfMarkup";
1953
+ function bfMarkup(html) {
1954
+ return { [BF_MARKUP_BRAND]: html };
1955
+ }
1956
+ function isBfMarkup(value) {
1957
+ if (typeof value !== "object" || value === null)
1958
+ return false;
1959
+ const proto = Object.getPrototypeOf(value);
1960
+ if (proto !== Object.prototype && proto !== null)
1961
+ return false;
1962
+ return typeof value[BF_MARKUP_BRAND] === "string";
1963
+ }
1964
+ function escapeTextOrMarkup(value) {
1965
+ if (isBfMarkup(value))
1966
+ return value[BF_MARKUP_BRAND];
1967
+ return escapeText(value);
1968
+ }
1952
1969
  function escapeTextOrNode(value) {
1970
+ if (isBfMarkup(value))
1971
+ return value[BF_MARKUP_BRAND];
1953
1972
  if (typeof Node !== "undefined" && value instanceof Node)
1954
1973
  return value;
1955
1974
  return escapeText(value);
1956
1975
  }
1957
1976
  var SVG_NS = "http://www.w3.org/2000/svg";
1977
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
1978
+ function namespaceWrapTagFor(parent) {
1979
+ if (!parent)
1980
+ return null;
1981
+ if (parent.namespaceURI === SVG_NS)
1982
+ return "svg";
1983
+ if (parent.namespaceURI === MATHML_NS)
1984
+ return "math";
1985
+ return null;
1986
+ }
1958
1987
  function parseHTML(html, parent) {
1959
1988
  const tpl = document.createElement("template");
1960
1989
  const escaped = escapeAttrGt(html);
1961
- if (parent && parent.namespaceURI === SVG_NS) {
1962
- tpl.innerHTML = `<svg>${escaped}</svg>`;
1990
+ const wrapTag = namespaceWrapTagFor(parent);
1991
+ if (wrapTag) {
1992
+ tpl.innerHTML = `<${wrapTag}>${escaped}</${wrapTag}>`;
1963
1993
  const wrapper = tpl.content.firstElementChild;
1964
1994
  const frag = document.createDocumentFragment();
1965
1995
  if (wrapper) {
@@ -3672,6 +3702,7 @@ export {
3672
3702
  lazySlots,
3673
3703
  lazyClaimSlots,
3674
3704
  isSSRPortal,
3705
+ isBfMarkup,
3675
3706
  insert,
3676
3707
  initChild,
3677
3708
  hydratedScopes,
@@ -3689,6 +3720,7 @@ export {
3689
3720
  findScope,
3690
3721
  find,
3691
3722
  escapeTextOrNode,
3723
+ escapeTextOrMarkup,
3692
3724
  escapeText,
3693
3725
  escapeAttr,
3694
3726
  endTurn,
@@ -3708,6 +3740,7 @@ export {
3708
3740
  createComponent,
3709
3741
  cleanupPortalPlaceholder,
3710
3742
  claimSlots,
3743
+ bfMarkup,
3711
3744
  beginTurn,
3712
3745
  batch,
3713
3746
  applyRestAttrs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/client",
3
- "version": "0.31.8",
3
+ "version": "0.31.10",
4
4
  "description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,7 +55,7 @@
55
55
  "directory": "packages/client"
56
56
  },
57
57
  "dependencies": {
58
- "@barefootjs/shared": "0.31.8"
58
+ "@barefootjs/shared": "0.31.10"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@barefootjs/jsx": ">=0.2.0"
@@ -612,6 +612,80 @@ export function escapeText(value: unknown): string {
612
612
  return escapeAttr(value)
613
613
  }
614
614
 
615
+ /**
616
+ * Brand carried by `bfMarkup()` — see that function's docstring. A string
617
+ * key (not a `Symbol`) because the brand must survive `structuredClone`
618
+ * (props cloned across an SSR seed / island-serialization boundary): a
619
+ * symbol-keyed property is silently dropped by the structured-clone
620
+ * algorithm, which would un-brand the value in transit.
621
+ */
622
+ const BF_MARKUP_BRAND = '__bfMarkup'
623
+
624
+ /**
625
+ * Shape produced by `bfMarkup()` (#2651). Compiler-emitted code only —
626
+ * never construct one by hand from userland; doing so is exactly as unsafe
627
+ * as writing raw `innerHTML` yourself, since `escapeTextOrMarkup` /
628
+ * `escapeTextOrNode` (below) trust `__bfMarkup`'s contents to already be
629
+ * safe-to-splice HTML and skip escaping it.
630
+ */
631
+ export interface BfMarkup {
632
+ readonly [BF_MARKUP_BRAND]: string
633
+ }
634
+
635
+ /**
636
+ * Brand a compiler-built HTML string as pre-escaped markup safe to splice
637
+ * raw into a template (#2651). The compiler emits this ONLY around HTML it
638
+ * itself assembled from a JSX element passed at a non-`children` component
639
+ * prop position (`header={<strong>Title</strong>}`) — every text segment
640
+ * inside that assembly was already escaped node-by-node during the
641
+ * assembly (the same `escapeHtml` / `escapeTextSlotExpr` calls
642
+ * `html-template.ts` uses for ordinary element children), so the
643
+ * concatenated result is exactly as safe as any other compiler-emitted
644
+ * template fragment.
645
+ *
646
+ * Not exported from the public `@barefootjs/client` surface: this is
647
+ * compiler-emitted-code only, exported solely from
648
+ * `@barefootjs/client/runtime`. Calling it directly from userland to wrap
649
+ * an arbitrary string is exactly as unsafe as assigning that string to
650
+ * `innerHTML` yourself — the value is trusted verbatim by every consumer
651
+ * below.
652
+ */
653
+ export function bfMarkup(html: string): BfMarkup {
654
+ return { [BF_MARKUP_BRAND]: html }
655
+ }
656
+
657
+ /** Type guard for the `bfMarkup()` brand (#2651). Compiler-emitted code only — see `bfMarkup`'s docstring. */
658
+ export function isBfMarkup(value: unknown): value is BfMarkup {
659
+ if (typeof value !== 'object' || value === null) return false
660
+ // Plain carrier objects only (Copilot review on #2651's PR): without the
661
+ // prototype check, a DOM Node (or any host object) carrying a string
662
+ // `__bfMarkup` expando would satisfy the shape test and be unwrapped as
663
+ // raw HTML — the brand must stay mutually exclusive with the Node branch
664
+ // of `escapeTextOrNode` by construction, not by property-name luck.
665
+ const proto = Object.getPrototypeOf(value)
666
+ if (proto !== Object.prototype && proto !== null) return false
667
+ return typeof (value as Record<string, unknown>)[BF_MARKUP_BRAND] === 'string'
668
+ }
669
+
670
+ /**
671
+ * `escapeText`'s counterpart for a claim-plan slot the compiler has
672
+ * classified `kind: 'markup'` at STATIC/initial-render time
673
+ * (`html-template.ts`'s `escapeTextSlotExpr`, gated on the same
674
+ * `ctx.dynamicElements` membership `emit-reactive.ts` reads to pick the
675
+ * writer kind for the REACTIVE side, below) — #2651. A `bfMarkup()`-branded
676
+ * value is compiler-built HTML the compiler already escaped piecewise
677
+ * while assembling it, and must reach the template raw, unescaped a second
678
+ * time; anything else (plain string, number, nullish) gets the ordinary
679
+ * `escapeText` treatment — this function is a strict superset of
680
+ * `escapeText`'s behaviour for every non-branded value, so switching a
681
+ * call site from one to the other never changes output unless the value
682
+ * is actually branded.
683
+ */
684
+ export function escapeTextOrMarkup(value: unknown): string {
685
+ if (isBfMarkup(value)) return value[BF_MARKUP_BRAND]
686
+ return escapeText(value)
687
+ }
688
+
615
689
  /**
616
690
  * `escapeText`'s counterpart for a claimed 'markup' slot's REACTIVE write
617
691
  * (slot unification A3 follow-up), where the value is a plain-JS expression
@@ -631,33 +705,53 @@ export function escapeText(value: unknown): string {
631
705
  * before handing it to a 'markup' writer — NOT the preamble-region case
632
706
  * (`stringify/loop.ts`), whose value is already-built HTML from a nested
633
707
  * compiled render and must stay unescaped.
708
+ *
709
+ * A `bfMarkup()`-branded value (#2651) — a component prop re-read on every
710
+ * reactive re-run, e.g. `initChild`'s `get header() { return bfMarkup(...) }`
711
+ * getter — is unwrapped to its raw string for the same reason a `Node` is
712
+ * passed through untouched: the compiler already escaped its contents once
713
+ * during assembly, so re-escaping it (or, worse, `String()`-stringifying
714
+ * the wrapper object into `"[object Object]"`) would corrupt it. Checked
715
+ * before the `Node` branch since the two shapes are mutually exclusive.
634
716
  */
635
717
  export function escapeTextOrNode(value: unknown): string | Node {
718
+ if (isBfMarkup(value)) return value[BF_MARKUP_BRAND]
636
719
  if (typeof Node !== 'undefined' && value instanceof Node) return value
637
720
  return escapeText(value)
638
721
  }
639
722
 
640
723
  const SVG_NS = 'http://www.w3.org/2000/svg'
724
+ const MATHML_NS = 'http://www.w3.org/1998/Math/MathML'
725
+
726
+ /** Synthetic wrap tag for a parent's namespace, or null when it's plain HTML. */
727
+ function namespaceWrapTagFor(parent: Element | null | undefined): 'svg' | 'math' | null {
728
+ if (!parent) return null
729
+ if (parent.namespaceURI === SVG_NS) return 'svg'
730
+ if (parent.namespaceURI === MATHML_NS) return 'math'
731
+ return null
732
+ }
641
733
 
642
734
  /**
643
735
  * Parse an HTML string into a DocumentFragment, safely escaping ">" in
644
736
  * attribute values. All code that sets innerHTML on dynamic HTML should
645
737
  * use this instead of raw innerHTML assignment.
646
738
  *
647
- * When `parent` is provided and lives in the SVG namespace, the markup
648
- * is parsed under SVG foreign-content context by wrapping it in
649
- * `<svg>...</svg>`; the wrapper's children are moved into the returned
650
- * fragment so callers see the same shape as the HTML path. Without
651
- * this, dynamically-inserted SVG elements (e.g., a `<path>` in a
652
- * conditional drag preview) end up as `HTMLUnknownElement` in the
653
- * xhtml namespace and the SVG renderer ignores them. Surfaced by the
654
- * Graph/DAG Editor block (#135).
739
+ * When `parent` is provided and lives in the SVG or MathML namespace, the
740
+ * markup is parsed under the matching foreign-content context by wrapping
741
+ * it in `<svg>...</svg>` / `<math>...</math>`; the wrapper's children are
742
+ * moved into the returned fragment so callers see the same shape as the
743
+ * HTML path. Without this, dynamically-inserted SVG/MathML elements (e.g.,
744
+ * a `<path>` in a conditional drag preview, or an `<mrow>` in a dynamic
745
+ * equation) end up as `HTMLUnknownElement` in the xhtml namespace and the
746
+ * SVG/MathML renderer ignores them. Surfaced by the Graph/DAG Editor block
747
+ * (#135); ported to MathML in #1096.
655
748
  */
656
749
  export function parseHTML(html: string, parent?: Element | null): DocumentFragment {
657
750
  const tpl = document.createElement('template')
658
751
  const escaped = escapeAttrGt(html)
659
- if (parent && parent.namespaceURI === SVG_NS) {
660
- tpl.innerHTML = `<svg>${escaped}</svg>`
752
+ const wrapTag = namespaceWrapTagFor(parent)
753
+ if (wrapTag) {
754
+ tpl.innerHTML = `<${wrapTag}>${escaped}</${wrapTag}>`
661
755
  const wrapper = tpl.content.firstElementChild
662
756
  const frag = document.createDocumentFragment()
663
757
  if (wrapper) {
@@ -105,6 +105,14 @@ export {
105
105
  escapeAttr,
106
106
  escapeText,
107
107
  escapeTextOrNode,
108
+ // JSX-element-as-prop markup brand (#2651) — compiler-emitted code only.
109
+ // NOT re-exported from the public `@barefootjs/client` top-level entry;
110
+ // see `bfMarkup`'s docstring in `component.ts` for why calling it
111
+ // directly from userland is unsafe.
112
+ bfMarkup,
113
+ isBfMarkup,
114
+ escapeTextOrMarkup,
115
+ type BfMarkup,
108
116
  } from './component.ts'
109
117
 
110
118
  // Spread props helpers