@barefootjs/xslate 0.18.4 → 0.18.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA4HR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAoBR"}
1
+ {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA+IR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAoBR"}
@@ -31,7 +31,7 @@ export declare class XslateFilterEmitter implements ParsedExprEmitter {
31
31
  constructor(param: string, localVarMap: Map<string, string>, isStringName?: (n: string) => boolean, onUnsupported?: ((message: string, reason?: string) => void) | undefined);
32
32
  identifier(name: string): string;
33
33
  literal(value: string | number | boolean | null, literalType: LiteralType): string;
34
- member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
34
+ member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string;
35
35
  indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
36
36
  call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
37
37
  unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
@@ -65,7 +65,7 @@ export declare class XslateTopLevelEmitter implements ParsedExprEmitter {
65
65
  constructor(ctx: XslateEmitContext);
66
66
  identifier(name: string): string;
67
67
  literal(value: string | number | boolean | null, literalType: LiteralType): string;
68
- member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
68
+ member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string;
69
69
  indexAccess(object: ParsedExpr, index: ParsedExpr, emit: (e: ParsedExpr) => string): string;
70
70
  call(callee: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
71
71
  unary(op: string, argument: ParsedExpr, emit: (e: ParsedExpr) => string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
@@ -187365,7 +187365,7 @@ function isAriaBooleanAttr(name) {
187365
187365
  }
187366
187366
 
187367
187367
  // src/adapter/xslate-adapter.ts
187368
- import { BF_SLOT, BF_COND, BF_REGION } from "@barefootjs/shared";
187368
+ import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from "@barefootjs/shared";
187369
187369
 
187370
187370
  // src/adapter/lib/constants.ts
187371
187371
  var XSLATE_TEMPLATE_PRIMITIVES = {
@@ -187374,7 +187374,10 @@ var XSLATE_TEMPLATE_PRIMITIVES = {
187374
187374
  Number: { arity: 1, emit: (args) => `$bf.number(${args[0]})` },
187375
187375
  "Math.floor": { arity: 1, emit: (args) => `$bf.floor(${args[0]})` },
187376
187376
  "Math.ceil": { arity: 1, emit: (args) => `$bf.ceil(${args[0]})` },
187377
- "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` }
187377
+ "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` },
187378
+ "Math.min": { arity: 2, emit: (args) => `$bf.min(${args[0]}, ${args[1]})` },
187379
+ "Math.max": { arity: 2, emit: (args) => `$bf.max(${args[0]}, ${args[1]})` },
187380
+ "Math.abs": { arity: 1, emit: (args) => `$bf.abs(${args[0]})` }
187378
187381
  };
187379
187382
  var XSLATE_PRIMITIVE_EMIT_MAP = Object.fromEntries(Object.entries(XSLATE_TEMPLATE_PRIMITIVES).map(([k, v]) => [k, v.emit]));
187380
187383
 
@@ -187479,6 +187482,12 @@ function renderArrayMethod(method, object, args, emit) {
187479
187482
  const recv = emit(object);
187480
187483
  return `$bf.trim(${recv})`;
187481
187484
  }
187485
+ case "trimStart":
187486
+ case "trimEnd": {
187487
+ const fn = method === "trimStart" ? "trim_start" : "trim_end";
187488
+ const recv = emit(object);
187489
+ return `$bf.${fn}(${recv})`;
187490
+ }
187482
187491
  case "toFixed": {
187483
187492
  const recv = emit(object);
187484
187493
  const digits = args.length >= 1 ? emit(args[0]) : "0";
@@ -187512,6 +187521,12 @@ function renderArrayMethod(method, object, args, emit) {
187512
187521
  const newS = emit(args[1]);
187513
187522
  return `$bf.replace(${recv}, ${oldS}, ${newS})`;
187514
187523
  }
187524
+ case "replaceAll": {
187525
+ const recv = emit(object);
187526
+ const oldS = emit(args[0]);
187527
+ const newS = emit(args[1]);
187528
+ return `$bf.replace_all(${recv}, ${oldS}, ${newS})`;
187529
+ }
187515
187530
  case "repeat": {
187516
187531
  const recv = emit(object);
187517
187532
  const count = args.length === 0 ? "0" : emit(args[0]);
@@ -187655,7 +187670,7 @@ class XslateFilterEmitter {
187655
187670
  return "nil";
187656
187671
  return String(value);
187657
187672
  }
187658
- member(object, property, _computed, emit) {
187673
+ member(object, property, _computed, _optional, emit) {
187659
187674
  if (property === "length") {
187660
187675
  return `$bf.length(${emit(object)})`;
187661
187676
  }
@@ -187767,7 +187782,7 @@ class XslateTopLevelEmitter {
187767
187782
  return "nil";
187768
187783
  return String(value);
187769
187784
  }
187770
- member(object, property, _computed, emit) {
187785
+ member(object, property, _computed, _optional, emit) {
187771
187786
  if (object.kind === "identifier" && object.name === "props") {
187772
187787
  return `$${property}`;
187773
187788
  }
@@ -188208,6 +188223,7 @@ class XslateAdapter extends BaseAdapter {
188208
188223
  options;
188209
188224
  errors = [];
188210
188225
  inLoop = false;
188226
+ currentLoopKeyDepth = 0;
188211
188227
  propsObjectName = null;
188212
188228
  propsParams = [];
188213
188229
  booleanTypedProps = new Set;
@@ -188284,7 +188300,7 @@ class XslateAdapter extends BaseAdapter {
188284
188300
  return this.renderElement(node);
188285
188301
  }
188286
188302
  emitText(node) {
188287
- return node.value;
188303
+ return escapeHtml(node.value);
188288
188304
  }
188289
188305
  emitExpression(node) {
188290
188306
  return this.renderExpression(node);
@@ -188508,9 +188524,12 @@ ${whenTrue}
188508
188524
  }
188509
188525
  const param = loop.param;
188510
188526
  const renderedChildren = this.renderChildren(loop.children);
188511
- const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188527
+ const loopVar = loop.objectIteration === "entries" ? "__bf_pair" : loop.objectIteration ? param : loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188512
188528
  const indexLocalLines = [];
188513
- if (loop.iterationShape === "keys") {
188529
+ if (loop.objectIteration === "entries") {
188530
+ indexLocalLines.push(`: my $${loop.index ?? param} = $${loopVar}.key;`);
188531
+ indexLocalLines.push(`: my $${param} = $${loopVar}.value;`);
188532
+ } else if (loop.objectIteration) {} else if (loop.iterationShape === "keys") {
188514
188533
  indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
188515
188534
  } else if (loop.index) {
188516
188535
  indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
@@ -188530,13 +188549,17 @@ ${whenTrue}
188530
188549
  }
188531
188550
  const prevInLoop = this.inLoop;
188532
188551
  this.inLoop = true;
188552
+ const prevLoopKeyDepth = this.currentLoopKeyDepth;
188553
+ this.currentLoopKeyDepth = loop.depth;
188533
188554
  const childrenUnderLoop = this.renderChildren(loop.children);
188555
+ this.currentLoopKeyDepth = prevLoopKeyDepth;
188534
188556
  this.inLoop = prevInLoop;
188535
188557
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
188536
188558
  ${childrenUnderLoop}` : childrenUnderLoop;
188537
188559
  const lines = [];
188538
188560
  lines.push(`<: $bf.comment("loop:${loop.markerId}") | mark_raw :>`);
188539
- lines.push(`: for ${array} -> $${loopVar} {`);
188561
+ const forHeader = loop.objectIteration === "entries" ? `: for ${array}.kv() -> $${loopVar} {` : loop.objectIteration === "keys" ? `: for ${array}.keys() -> $${loopVar} {` : loop.objectIteration === "values" ? `: for ${array}.values() -> $${loopVar} {` : `: for ${array} -> $${loopVar} {`;
188562
+ lines.push(forHeader);
188540
188563
  for (const il of indexLocalLines)
188541
188564
  lines.push(il);
188542
188565
  if (loop.filterPredicate) {
@@ -188607,9 +188630,20 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188607
188630
  renderComponent(comp) {
188608
188631
  const segments = [{ kind: "entries", parts: [] }];
188609
188632
  const currentEntries = () => this.componentPropSegmentEntries(segments);
188633
+ const namedSlotMacros = [];
188610
188634
  for (const p of comp.props) {
188611
188635
  if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
188612
188636
  continue;
188637
+ if (p.value.kind === "jsx-children" && p.name !== "children") {
188638
+ const prevInLoop = this.inLoop;
188639
+ this.inLoop = false;
188640
+ const slotBody = this.renderChildren(p.value.children);
188641
+ this.inLoop = prevInLoop;
188642
+ const macroName = `bf_prop_${this.childrenCaptureCounter++}`;
188643
+ namedSlotMacros.push(`<: macro ${macroName} -> () { :>${slotBody}<: } :>`);
188644
+ currentEntries().push(`${kolonHashKey(p.name)} => ${macroName}()`);
188645
+ continue;
188646
+ }
188613
188647
  if (p.value.kind === "spread") {
188614
188648
  const trimmed = p.value.expr.trim();
188615
188649
  if (this.propsObjectName && this.propsObjectName === trimmed) {
@@ -188638,11 +188672,11 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188638
188672
  const macroName = `bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
188639
188673
  currentEntries().push(`children => ${macroName}()`);
188640
188674
  const dict = this.combineComponentPropSegments(segments);
188641
- return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188675
+ return `${namedSlotMacros.join("")}<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188642
188676
  }
188643
188677
  const isEmpty = segments.every((s) => s.kind === "entries" && s.parts.length === 0);
188644
188678
  const hashEntries = isEmpty ? "" : `, ${this.combineComponentPropSegments(segments)}`;
188645
- return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188679
+ return `${namedSlotMacros.join("")}<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188646
188680
  }
188647
188681
  childrenCaptureCounter = 0;
188648
188682
  presenceVarCounter = 0;
@@ -188687,7 +188721,7 @@ ${alternate}
188687
188721
  ${children}`;
188688
188722
  }
188689
188723
  elementAttrEmitter = {
188690
- emitLiteral: (value, name) => `${name}="${value.value}"`,
188724
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
188691
188725
  emitExpression: (value, name) => {
188692
188726
  if (name === "style") {
188693
188727
  const css = this.tryLowerStyleObject(value.expr);
@@ -188794,9 +188828,10 @@ ${name}="<: ${val} :>"
188794
188828
  let attrName;
188795
188829
  if (attr.name === "className")
188796
188830
  attrName = "class";
188797
- else if (attr.name === "key")
188798
- attrName = "data-key";
188799
- else
188831
+ else if (attr.name === "key") {
188832
+ const depth = this.currentLoopKeyDepth;
188833
+ attrName = depth > 0 ? `data-key-${depth}` : "data-key";
188834
+ } else
188800
188835
  attrName = attr.name;
188801
188836
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
188802
188837
  if (lowered)
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAOpE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAG9E,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAUpE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAG9E,CAAA"}
@@ -45,6 +45,14 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
45
45
  private options;
46
46
  private errors;
47
47
  private inLoop;
48
+ /**
49
+ * `IRLoop.depth` of the loop currently being rendered (save/restore
50
+ * around `renderChildren(loop.children)`, mirroring `inLoop` above).
51
+ * `renderAttributes` reads this to derive the `key` → `data-key`/
52
+ * `data-key-N` suffix — the depth is IR-computed (jsx-to-ir.ts), not
53
+ * re-derived here (#2168 nested-loop-outer-binding).
54
+ */
55
+ private currentLoopKeyDepth;
48
56
  /**
49
57
  * SolidJS-style props identifier (`function(props: P)`) and the
50
58
  * analyzer-extracted prop names. Stashed at `generate()` entry so the
@@ -1 +1 @@
1
- {"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAG1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,EAyBhB,MAAM,iBAAiB,CAAA;AAMxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AA4BrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AA2C1D,qBAAa,aAAc,SAAQ,WAAY,YAAW,aAAa,CAAC,eAAe,CAAC;IACtF,IAAI,SAAW;IACf,SAAS,SAAQ;IACjB,qBAAqB,UAAO;IAG5B,kBAAkB,EAAG,cAAc,CAAS;IAE5C;;;;;OAKG;IACH,kBAAkB,EAAE,yBAAyB,CAA4B;IAEzE,OAAO,CAAC,aAAa,CAAa;IAClC;;;uCAGmC;IACnC,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAAiB;IAC/B;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,iBAAiB,CAAyB;IAClD;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB,CAAyB;IAEjD;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB,CAAiC;IAE3D;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAyB;IAEpD;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IAEjD;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAmC;IAEzD;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB,CAAyB;IAEtD,YAAY,OAAO,GAAE,oBAAyB,EAM7C;IAED,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CA6EzE;IAMD,OAAO,CAAC,2BAA2B;IAyBnC;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/B;IAMD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAE9F;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEzC;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAEtG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAExF;IAED,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAElG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAEhG;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7B;IAED,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAEtG;IAED,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAehG;IAED,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;IAiB1B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,0BAA0B;IAclC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAE1F;IAMD,aAAa,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAoCxC;IAMD,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAe3C;IAMD,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAuC7C;IAED,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAcnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmN/B;IAMD;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAmCpC;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,2BAA2B;IAUnC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,4BAA4B;IAiBpC,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CA0EzC;IAED,OAAO,CAAC,sBAAsB,CAAI;IAElC;+DAC2D;IAC3D,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,UAAU;IAWT,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQ1C;IAMD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAsJlC;IAED;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAmB3B,8EAA8E;IAC9E,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,gBAAgB;IA2BxB,iBAAiB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAIjD;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvC;IAMD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,kCAAkC;IAwB1C;;;;OAIG;IACH,OAAO,CAAC,iCAAiC;IAmBzC;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAuBvC;;;;;;;OAOG;IACH,OAAO,KAAK,OAAO,GAUlB;IAED;;;;;OAKG;IACH,OAAO,KAAK,SAAS,GAQpB;IAED,sEAAsE;IACtE,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,CAAC,wBAAwB;IAyEhC;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAI/B;oEACgE;IAChE,OAAO,CAAC,kBAAkB;IAI1B;;;;;OAKG;IACH;;;;;OAKG;IACH;;;;;OAKG;IACH;;;;OAIG;IACH,8BAA8B,CAC5B,IAAI,EAAE,MAAM,GACX;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAgBlD;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO3C;IAED;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,2BAA2B;IAQnC,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,gBAAgB;IAcxB,iFAAiF;IACjF,OAAO,CAAC,4BAA4B;CAGrC;AAED,eAAO,MAAM,aAAa,eAAsB,CAAA"}
1
+ {"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"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"}
package/dist/build.js CHANGED
@@ -187365,7 +187365,7 @@ function isAriaBooleanAttr(name) {
187365
187365
  }
187366
187366
 
187367
187367
  // src/adapter/xslate-adapter.ts
187368
- import { BF_SLOT, BF_COND, BF_REGION } from "@barefootjs/shared";
187368
+ import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from "@barefootjs/shared";
187369
187369
 
187370
187370
  // src/adapter/lib/constants.ts
187371
187371
  var XSLATE_TEMPLATE_PRIMITIVES = {
@@ -187374,7 +187374,10 @@ var XSLATE_TEMPLATE_PRIMITIVES = {
187374
187374
  Number: { arity: 1, emit: (args) => `$bf.number(${args[0]})` },
187375
187375
  "Math.floor": { arity: 1, emit: (args) => `$bf.floor(${args[0]})` },
187376
187376
  "Math.ceil": { arity: 1, emit: (args) => `$bf.ceil(${args[0]})` },
187377
- "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` }
187377
+ "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` },
187378
+ "Math.min": { arity: 2, emit: (args) => `$bf.min(${args[0]}, ${args[1]})` },
187379
+ "Math.max": { arity: 2, emit: (args) => `$bf.max(${args[0]}, ${args[1]})` },
187380
+ "Math.abs": { arity: 1, emit: (args) => `$bf.abs(${args[0]})` }
187378
187381
  };
187379
187382
  var XSLATE_PRIMITIVE_EMIT_MAP = Object.fromEntries(Object.entries(XSLATE_TEMPLATE_PRIMITIVES).map(([k, v]) => [k, v.emit]));
187380
187383
 
@@ -187479,6 +187482,12 @@ function renderArrayMethod(method, object, args, emit) {
187479
187482
  const recv = emit(object);
187480
187483
  return `$bf.trim(${recv})`;
187481
187484
  }
187485
+ case "trimStart":
187486
+ case "trimEnd": {
187487
+ const fn = method === "trimStart" ? "trim_start" : "trim_end";
187488
+ const recv = emit(object);
187489
+ return `$bf.${fn}(${recv})`;
187490
+ }
187482
187491
  case "toFixed": {
187483
187492
  const recv = emit(object);
187484
187493
  const digits = args.length >= 1 ? emit(args[0]) : "0";
@@ -187512,6 +187521,12 @@ function renderArrayMethod(method, object, args, emit) {
187512
187521
  const newS = emit(args[1]);
187513
187522
  return `$bf.replace(${recv}, ${oldS}, ${newS})`;
187514
187523
  }
187524
+ case "replaceAll": {
187525
+ const recv = emit(object);
187526
+ const oldS = emit(args[0]);
187527
+ const newS = emit(args[1]);
187528
+ return `$bf.replace_all(${recv}, ${oldS}, ${newS})`;
187529
+ }
187515
187530
  case "repeat": {
187516
187531
  const recv = emit(object);
187517
187532
  const count = args.length === 0 ? "0" : emit(args[0]);
@@ -187655,7 +187670,7 @@ class XslateFilterEmitter {
187655
187670
  return "nil";
187656
187671
  return String(value);
187657
187672
  }
187658
- member(object, property, _computed, emit) {
187673
+ member(object, property, _computed, _optional, emit) {
187659
187674
  if (property === "length") {
187660
187675
  return `$bf.length(${emit(object)})`;
187661
187676
  }
@@ -187767,7 +187782,7 @@ class XslateTopLevelEmitter {
187767
187782
  return "nil";
187768
187783
  return String(value);
187769
187784
  }
187770
- member(object, property, _computed, emit) {
187785
+ member(object, property, _computed, _optional, emit) {
187771
187786
  if (object.kind === "identifier" && object.name === "props") {
187772
187787
  return `$${property}`;
187773
187788
  }
@@ -188208,6 +188223,7 @@ class XslateAdapter extends BaseAdapter {
188208
188223
  options;
188209
188224
  errors = [];
188210
188225
  inLoop = false;
188226
+ currentLoopKeyDepth = 0;
188211
188227
  propsObjectName = null;
188212
188228
  propsParams = [];
188213
188229
  booleanTypedProps = new Set;
@@ -188284,7 +188300,7 @@ class XslateAdapter extends BaseAdapter {
188284
188300
  return this.renderElement(node);
188285
188301
  }
188286
188302
  emitText(node) {
188287
- return node.value;
188303
+ return escapeHtml(node.value);
188288
188304
  }
188289
188305
  emitExpression(node) {
188290
188306
  return this.renderExpression(node);
@@ -188508,9 +188524,12 @@ ${whenTrue}
188508
188524
  }
188509
188525
  const param = loop.param;
188510
188526
  const renderedChildren = this.renderChildren(loop.children);
188511
- const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188527
+ const loopVar = loop.objectIteration === "entries" ? "__bf_pair" : loop.objectIteration ? param : loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188512
188528
  const indexLocalLines = [];
188513
- if (loop.iterationShape === "keys") {
188529
+ if (loop.objectIteration === "entries") {
188530
+ indexLocalLines.push(`: my $${loop.index ?? param} = $${loopVar}.key;`);
188531
+ indexLocalLines.push(`: my $${param} = $${loopVar}.value;`);
188532
+ } else if (loop.objectIteration) {} else if (loop.iterationShape === "keys") {
188514
188533
  indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
188515
188534
  } else if (loop.index) {
188516
188535
  indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
@@ -188530,13 +188549,17 @@ ${whenTrue}
188530
188549
  }
188531
188550
  const prevInLoop = this.inLoop;
188532
188551
  this.inLoop = true;
188552
+ const prevLoopKeyDepth = this.currentLoopKeyDepth;
188553
+ this.currentLoopKeyDepth = loop.depth;
188533
188554
  const childrenUnderLoop = this.renderChildren(loop.children);
188555
+ this.currentLoopKeyDepth = prevLoopKeyDepth;
188534
188556
  this.inLoop = prevInLoop;
188535
188557
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
188536
188558
  ${childrenUnderLoop}` : childrenUnderLoop;
188537
188559
  const lines = [];
188538
188560
  lines.push(`<: $bf.comment("loop:${loop.markerId}") | mark_raw :>`);
188539
- lines.push(`: for ${array} -> $${loopVar} {`);
188561
+ const forHeader = loop.objectIteration === "entries" ? `: for ${array}.kv() -> $${loopVar} {` : loop.objectIteration === "keys" ? `: for ${array}.keys() -> $${loopVar} {` : loop.objectIteration === "values" ? `: for ${array}.values() -> $${loopVar} {` : `: for ${array} -> $${loopVar} {`;
188562
+ lines.push(forHeader);
188540
188563
  for (const il of indexLocalLines)
188541
188564
  lines.push(il);
188542
188565
  if (loop.filterPredicate) {
@@ -188607,9 +188630,20 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188607
188630
  renderComponent(comp) {
188608
188631
  const segments = [{ kind: "entries", parts: [] }];
188609
188632
  const currentEntries = () => this.componentPropSegmentEntries(segments);
188633
+ const namedSlotMacros = [];
188610
188634
  for (const p of comp.props) {
188611
188635
  if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
188612
188636
  continue;
188637
+ if (p.value.kind === "jsx-children" && p.name !== "children") {
188638
+ const prevInLoop = this.inLoop;
188639
+ this.inLoop = false;
188640
+ const slotBody = this.renderChildren(p.value.children);
188641
+ this.inLoop = prevInLoop;
188642
+ const macroName = `bf_prop_${this.childrenCaptureCounter++}`;
188643
+ namedSlotMacros.push(`<: macro ${macroName} -> () { :>${slotBody}<: } :>`);
188644
+ currentEntries().push(`${kolonHashKey(p.name)} => ${macroName}()`);
188645
+ continue;
188646
+ }
188613
188647
  if (p.value.kind === "spread") {
188614
188648
  const trimmed = p.value.expr.trim();
188615
188649
  if (this.propsObjectName && this.propsObjectName === trimmed) {
@@ -188638,11 +188672,11 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188638
188672
  const macroName = `bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
188639
188673
  currentEntries().push(`children => ${macroName}()`);
188640
188674
  const dict = this.combineComponentPropSegments(segments);
188641
- return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188675
+ return `${namedSlotMacros.join("")}<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188642
188676
  }
188643
188677
  const isEmpty = segments.every((s) => s.kind === "entries" && s.parts.length === 0);
188644
188678
  const hashEntries = isEmpty ? "" : `, ${this.combineComponentPropSegments(segments)}`;
188645
- return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188679
+ return `${namedSlotMacros.join("")}<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188646
188680
  }
188647
188681
  childrenCaptureCounter = 0;
188648
188682
  presenceVarCounter = 0;
@@ -188687,7 +188721,7 @@ ${alternate}
188687
188721
  ${children}`;
188688
188722
  }
188689
188723
  elementAttrEmitter = {
188690
- emitLiteral: (value, name) => `${name}="${value.value}"`,
188724
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
188691
188725
  emitExpression: (value, name) => {
188692
188726
  if (name === "style") {
188693
188727
  const css = this.tryLowerStyleObject(value.expr);
@@ -188794,9 +188828,10 @@ ${name}="<: ${val} :>"
188794
188828
  let attrName;
188795
188829
  if (attr.name === "className")
188796
188830
  attrName = "class";
188797
- else if (attr.name === "key")
188798
- attrName = "data-key";
188799
- else
188831
+ else if (attr.name === "key") {
188832
+ const depth = this.currentLoopKeyDepth;
188833
+ attrName = depth > 0 ? `data-key-${depth}` : "data-key";
188834
+ } else
188800
188835
  attrName = attr.name;
188801
188836
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
188802
188837
  if (lowered)
@@ -1 +1 @@
1
- {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAgH7B,CAAA"}
1
+ {"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eA2G7B,CAAA"}
package/dist/index.js CHANGED
@@ -187365,7 +187365,7 @@ function isAriaBooleanAttr(name) {
187365
187365
  }
187366
187366
 
187367
187367
  // src/adapter/xslate-adapter.ts
187368
- import { BF_SLOT, BF_COND, BF_REGION } from "@barefootjs/shared";
187368
+ import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from "@barefootjs/shared";
187369
187369
 
187370
187370
  // src/adapter/lib/constants.ts
187371
187371
  var XSLATE_TEMPLATE_PRIMITIVES = {
@@ -187374,7 +187374,10 @@ var XSLATE_TEMPLATE_PRIMITIVES = {
187374
187374
  Number: { arity: 1, emit: (args) => `$bf.number(${args[0]})` },
187375
187375
  "Math.floor": { arity: 1, emit: (args) => `$bf.floor(${args[0]})` },
187376
187376
  "Math.ceil": { arity: 1, emit: (args) => `$bf.ceil(${args[0]})` },
187377
- "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` }
187377
+ "Math.round": { arity: 1, emit: (args) => `$bf.round(${args[0]})` },
187378
+ "Math.min": { arity: 2, emit: (args) => `$bf.min(${args[0]}, ${args[1]})` },
187379
+ "Math.max": { arity: 2, emit: (args) => `$bf.max(${args[0]}, ${args[1]})` },
187380
+ "Math.abs": { arity: 1, emit: (args) => `$bf.abs(${args[0]})` }
187378
187381
  };
187379
187382
  var XSLATE_PRIMITIVE_EMIT_MAP = Object.fromEntries(Object.entries(XSLATE_TEMPLATE_PRIMITIVES).map(([k, v]) => [k, v.emit]));
187380
187383
 
@@ -187479,6 +187482,12 @@ function renderArrayMethod(method, object, args, emit) {
187479
187482
  const recv = emit(object);
187480
187483
  return `$bf.trim(${recv})`;
187481
187484
  }
187485
+ case "trimStart":
187486
+ case "trimEnd": {
187487
+ const fn = method === "trimStart" ? "trim_start" : "trim_end";
187488
+ const recv = emit(object);
187489
+ return `$bf.${fn}(${recv})`;
187490
+ }
187482
187491
  case "toFixed": {
187483
187492
  const recv = emit(object);
187484
187493
  const digits = args.length >= 1 ? emit(args[0]) : "0";
@@ -187512,6 +187521,12 @@ function renderArrayMethod(method, object, args, emit) {
187512
187521
  const newS = emit(args[1]);
187513
187522
  return `$bf.replace(${recv}, ${oldS}, ${newS})`;
187514
187523
  }
187524
+ case "replaceAll": {
187525
+ const recv = emit(object);
187526
+ const oldS = emit(args[0]);
187527
+ const newS = emit(args[1]);
187528
+ return `$bf.replace_all(${recv}, ${oldS}, ${newS})`;
187529
+ }
187515
187530
  case "repeat": {
187516
187531
  const recv = emit(object);
187517
187532
  const count = args.length === 0 ? "0" : emit(args[0]);
@@ -187655,7 +187670,7 @@ class XslateFilterEmitter {
187655
187670
  return "nil";
187656
187671
  return String(value);
187657
187672
  }
187658
- member(object, property, _computed, emit) {
187673
+ member(object, property, _computed, _optional, emit) {
187659
187674
  if (property === "length") {
187660
187675
  return `$bf.length(${emit(object)})`;
187661
187676
  }
@@ -187767,7 +187782,7 @@ class XslateTopLevelEmitter {
187767
187782
  return "nil";
187768
187783
  return String(value);
187769
187784
  }
187770
- member(object, property, _computed, emit) {
187785
+ member(object, property, _computed, _optional, emit) {
187771
187786
  if (object.kind === "identifier" && object.name === "props") {
187772
187787
  return `$${property}`;
187773
187788
  }
@@ -188208,6 +188223,7 @@ class XslateAdapter extends BaseAdapter {
188208
188223
  options;
188209
188224
  errors = [];
188210
188225
  inLoop = false;
188226
+ currentLoopKeyDepth = 0;
188211
188227
  propsObjectName = null;
188212
188228
  propsParams = [];
188213
188229
  booleanTypedProps = new Set;
@@ -188284,7 +188300,7 @@ class XslateAdapter extends BaseAdapter {
188284
188300
  return this.renderElement(node);
188285
188301
  }
188286
188302
  emitText(node) {
188287
- return node.value;
188303
+ return escapeHtml(node.value);
188288
188304
  }
188289
188305
  emitExpression(node) {
188290
188306
  return this.renderExpression(node);
@@ -188508,9 +188524,12 @@ ${whenTrue}
188508
188524
  }
188509
188525
  const param = loop.param;
188510
188526
  const renderedChildren = this.renderChildren(loop.children);
188511
- const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188527
+ const loopVar = loop.objectIteration === "entries" ? "__bf_pair" : loop.objectIteration ? param : loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
188512
188528
  const indexLocalLines = [];
188513
- if (loop.iterationShape === "keys") {
188529
+ if (loop.objectIteration === "entries") {
188530
+ indexLocalLines.push(`: my $${loop.index ?? param} = $${loopVar}.key;`);
188531
+ indexLocalLines.push(`: my $${param} = $${loopVar}.value;`);
188532
+ } else if (loop.objectIteration) {} else if (loop.iterationShape === "keys") {
188514
188533
  indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
188515
188534
  } else if (loop.index) {
188516
188535
  indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
@@ -188530,13 +188549,17 @@ ${whenTrue}
188530
188549
  }
188531
188550
  const prevInLoop = this.inLoop;
188532
188551
  this.inLoop = true;
188552
+ const prevLoopKeyDepth = this.currentLoopKeyDepth;
188553
+ this.currentLoopKeyDepth = loop.depth;
188533
188554
  const childrenUnderLoop = this.renderChildren(loop.children);
188555
+ this.currentLoopKeyDepth = prevLoopKeyDepth;
188534
188556
  this.inLoop = prevInLoop;
188535
188557
  const bodyChildren = loop.bodyIsItemConditional && loop.key ? `<: $bf.comment("loop-i:" ~ ${this.convertExpressionToKolon(loop.key)}) | mark_raw :>
188536
188558
  ${childrenUnderLoop}` : childrenUnderLoop;
188537
188559
  const lines = [];
188538
188560
  lines.push(`<: $bf.comment("loop:${loop.markerId}") | mark_raw :>`);
188539
- lines.push(`: for ${array} -> $${loopVar} {`);
188561
+ const forHeader = loop.objectIteration === "entries" ? `: for ${array}.kv() -> $${loopVar} {` : loop.objectIteration === "keys" ? `: for ${array}.keys() -> $${loopVar} {` : loop.objectIteration === "values" ? `: for ${array}.values() -> $${loopVar} {` : `: for ${array} -> $${loopVar} {`;
188562
+ lines.push(forHeader);
188540
188563
  for (const il of indexLocalLines)
188541
188564
  lines.push(il);
188542
188565
  if (loop.filterPredicate) {
@@ -188607,9 +188630,20 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188607
188630
  renderComponent(comp) {
188608
188631
  const segments = [{ kind: "entries", parts: [] }];
188609
188632
  const currentEntries = () => this.componentPropSegmentEntries(segments);
188633
+ const namedSlotMacros = [];
188610
188634
  for (const p of comp.props) {
188611
188635
  if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
188612
188636
  continue;
188637
+ if (p.value.kind === "jsx-children" && p.name !== "children") {
188638
+ const prevInLoop = this.inLoop;
188639
+ this.inLoop = false;
188640
+ const slotBody = this.renderChildren(p.value.children);
188641
+ this.inLoop = prevInLoop;
188642
+ const macroName = `bf_prop_${this.childrenCaptureCounter++}`;
188643
+ namedSlotMacros.push(`<: macro ${macroName} -> () { :>${slotBody}<: } :>`);
188644
+ currentEntries().push(`${kolonHashKey(p.name)} => ${macroName}()`);
188645
+ continue;
188646
+ }
188613
188647
  if (p.value.kind === "spread") {
188614
188648
  const trimmed = p.value.expr.trim();
188615
188649
  if (this.propsObjectName && this.propsObjectName === trimmed) {
@@ -188638,11 +188672,11 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188638
188672
  const macroName = `bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
188639
188673
  currentEntries().push(`children => ${macroName}()`);
188640
188674
  const dict = this.combineComponentPropSegments(segments);
188641
- return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188675
+ return `${namedSlotMacros.join("")}<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188642
188676
  }
188643
188677
  const isEmpty = segments.every((s) => s.kind === "entries" && s.parts.length === 0);
188644
188678
  const hashEntries = isEmpty ? "" : `, ${this.combineComponentPropSegments(segments)}`;
188645
- return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188679
+ return `${namedSlotMacros.join("")}<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188646
188680
  }
188647
188681
  childrenCaptureCounter = 0;
188648
188682
  presenceVarCounter = 0;
@@ -188687,7 +188721,7 @@ ${alternate}
188687
188721
  ${children}`;
188688
188722
  }
188689
188723
  elementAttrEmitter = {
188690
- emitLiteral: (value, name) => `${name}="${value.value}"`,
188724
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
188691
188725
  emitExpression: (value, name) => {
188692
188726
  if (name === "style") {
188693
188727
  const css = this.tryLowerStyleObject(value.expr);
@@ -188794,9 +188828,10 @@ ${name}="<: ${val} :>"
188794
188828
  let attrName;
188795
188829
  if (attr.name === "className")
188796
188830
  attrName = "class";
188797
- else if (attr.name === "key")
188798
- attrName = "data-key";
188799
- else
188831
+ else if (attr.name === "key") {
188832
+ const depth = this.currentLoopKeyDepth;
188833
+ attrName = depth > 0 ? `data-key-${depth}` : "data-key";
188834
+ } else
188800
188835
  attrName = attr.name;
188801
188836
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
188802
188837
  if (lowered)
@@ -189037,20 +189072,10 @@ var conformancePins = {
189037
189072
  { code: "BF101", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2038" }
189038
189073
  ],
189039
189074
  "array-map-function-reference": [{ code: "BF101", severity: "error" }],
189040
- "dangerous-inner-html": [{ code: "BF101", severity: "error" }],
189041
- "string-replaceall": [{ code: "BF101", severity: "error" }]
189075
+ "dangerous-inner-html": [{ code: "BF101", severity: "error" }]
189042
189076
  };
189043
189077
  // src/render-divergences.ts
189044
- var renderDivergences = {
189045
- "html-entity-text": "`&copy;` in JSX literal text: Hono decodes to `©`, this adapter re-emits the raw entity — same DOM, different bytes",
189046
- "math-methods": "Math.min/max/abs over a signal render empty (only Math.floor is in the template-primitive registry)",
189047
- "static-attr-escape": 'static attribute values are not HTML-escaped (`title="Fish & Chips"` emitted raw; Hono escapes)',
189048
- "object-entries-map": "`Object.entries(prop).map(([k, v]) => …)` renders an EMPTY list — the object-shaped prop silently produces zero iterations",
189049
- "nested-loop-outer-binding": "nested-loop inner items carry `data-key` where the reference emits the depth-suffixed `data-key-1`",
189050
- "jsx-element-prop": "a JSX element passed as a NON-children prop renders an empty slot — the element value is silently dropped",
189051
- "string-slice": "`.slice()` on a STRING misfires through the array slice helper",
189052
- "string-trim-sided": "`.trimStart()` / `.trimEnd()` render empty (no lowering)"
189053
- };
189078
+ var renderDivergences = {};
189054
189079
  export {
189055
189080
  xslateAdapter,
189056
189081
  renderDivergences,
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAiB/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAAsB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  package BarefootJS::Backend::Xslate;
2
- our $VERSION = "0.18.3";
2
+ our $VERSION = "0.18.4";
3
3
  use strict;
4
4
  use warnings;
5
5
  use utf8;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/xslate",
3
- "version": "0.18.4",
3
+ "version": "0.18.5",
4
4
  "description": "Text::Xslate (Kolon) adapter for BarefootJS — compiles IR to .tx templates and ships the Xslate rendering backend; runs under any PSGI/Plack app",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,14 +55,14 @@
55
55
  "directory": "packages/adapter-xslate"
56
56
  },
57
57
  "dependencies": {
58
- "@barefootjs/shared": "0.18.4"
58
+ "@barefootjs/shared": "0.18.5"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@barefootjs/jsx": ">=0.2.0"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@barefootjs/adapter-tests": "0.1.0",
65
- "@barefootjs/jsx": "0.18.4",
65
+ "@barefootjs/jsx": "0.18.5",
66
66
  "typescript": "^5.0.0"
67
67
  }
68
68
  }
@@ -396,6 +396,26 @@ export { A }
396
396
  })
397
397
  })
398
398
 
399
+ describe('XslateAdapter - named-slot capture identifier safety (#2168 jsx-element-prop)', () => {
400
+ // A JSX-valued prop under a hyphenated name (`data-slot`, a valid JSX
401
+ // attribute name) must not leak into the Kolon macro's identifier — Kolon
402
+ // macro names can't contain `-`. The macro name is purely counter-based
403
+ // (never derived from the prop name); the hash KEY passed to
404
+ // `render_child` still carries the real name, quoted via `kolonHashKey`.
405
+ test('a hyphenated prop name does not appear in the macro name', () => {
406
+ const { template } = compileAndGenerate(`
407
+ function Card(props) { return null }
408
+ export function Parent() {
409
+ return <Card data-slot={<strong>Title</strong>}>text</Card>
410
+ }
411
+ `)
412
+ expect(template).toContain('<: macro bf_prop_0 -> ()')
413
+ expect(template).toContain("'data-slot' => bf_prop_0()")
414
+ expect(template).not.toContain('data-slot -> ()')
415
+ expect(template).not.toContain('data-slot_')
416
+ })
417
+ })
418
+
399
419
  // #2038 nested-callback-predicate loudness is pinned at the shared
400
420
  // conformance layer: `filter-nested-callback-predicate` /
401
421
  // `filter-nested-find-predicate` (BF101 via `expectedDiagnostics` above) and
@@ -89,6 +89,15 @@ export function renderArrayMethod(
89
89
  const recv = emit(object)
90
90
  return `$bf.trim(${recv})`
91
91
  }
92
+ case 'trimStart':
93
+ case 'trimEnd': {
94
+ // `.trimStart()` / `.trimEnd()` — the one-sided siblings of
95
+ // `.trim()` (#2183 follow-up). Dedicated `$bf.trim_start` /
96
+ // `$bf.trim_end` helpers, not `$bf.trim` with a flag.
97
+ const fn = method === 'trimStart' ? 'trim_start' : 'trim_end'
98
+ const recv = emit(object)
99
+ return `$bf.${fn}(${recv})`
100
+ }
92
101
  case 'toFixed': {
93
102
  // `.toFixed(digits?)` — `$bf.to_fixed` mirrors JS rounding +
94
103
  // zero-padding (default 0 digits). #1897.
@@ -124,6 +133,16 @@ export function renderArrayMethod(
124
133
  const newS = emit(args[1])
125
134
  return `$bf.replace(${recv}, ${oldS}, ${newS})`
126
135
  }
136
+ case 'replaceAll': {
137
+ // `.replaceAll(old, new)` — string-pattern form, EVERY occurrence,
138
+ // via the dedicated `$bf.replace_all` helper (not `$bf.replace`
139
+ // with a flag) — the regex-pattern form is refused upstream at
140
+ // the parser, same as `.replace`. See #2182.
141
+ const recv = emit(object)
142
+ const oldS = emit(args[0])
143
+ const newS = emit(args[1])
144
+ return `$bf.replace_all(${recv}, ${oldS}, ${newS})`
145
+ }
127
146
  case 'repeat': {
128
147
  const recv = emit(object)
129
148
  const count = args.length === 0 ? '0' : emit(args[0])
@@ -94,7 +94,7 @@ export class XslateFilterEmitter implements ParsedExprEmitter {
94
94
  return String(value)
95
95
  }
96
96
 
97
- member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string {
97
+ member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string {
98
98
  // `.length` — route through `$bf.length` (handles both array element
99
99
  // count and string char count, JS-compatibly). Kolon's builtin `.size()`
100
100
  // is array-only and faults on a string.
@@ -263,7 +263,7 @@ export class XslateTopLevelEmitter implements ParsedExprEmitter {
263
263
  return String(value)
264
264
  }
265
265
 
266
- member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string {
266
+ member(object: ParsedExpr, property: string, _computed: boolean, _optional: boolean, emit: (e: ParsedExpr) => string): string {
267
267
  // `props.x` flattens to the bare `$x` the SSR caller binds each prop to
268
268
  // (props arrive as individual top-level vars, not a `$props` hashref).
269
269
  if (object.kind === 'identifier' && object.name === 'props') {
@@ -23,6 +23,9 @@ export const XSLATE_TEMPLATE_PRIMITIVES: Record<string, PrimitiveSpec> = {
23
23
  'Math.floor': { arity: 1, emit: (args) => `$bf.floor(${args[0]})` },
24
24
  'Math.ceil': { arity: 1, emit: (args) => `$bf.ceil(${args[0]})` },
25
25
  'Math.round': { arity: 1, emit: (args) => `$bf.round(${args[0]})` },
26
+ 'Math.min': { arity: 2, emit: (args) => `$bf.min(${args[0]}, ${args[1]})` },
27
+ 'Math.max': { arity: 2, emit: (args) => `$bf.max(${args[0]}, ${args[1]})` },
28
+ 'Math.abs': { arity: 1, emit: (args) => `$bf.abs(${args[0]})` },
26
29
  }
27
30
 
28
31
  /**
@@ -77,7 +77,7 @@ import {
77
77
  import { isAriaBooleanAttr, isBooleanResultExpr } from './boolean-result.ts'
78
78
  import ts from 'typescript'
79
79
  import type { ParsedExpr, LoweringMatcher } from '@barefootjs/jsx'
80
- import { BF_SLOT, BF_COND, BF_REGION } from '@barefootjs/shared'
80
+ import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from '@barefootjs/shared'
81
81
 
82
82
  import type { XslateRenderCtx } from './lib/types.ts'
83
83
  import { XSLATE_PRIMITIVE_EMIT_MAP } from './lib/constants.ts'
@@ -176,6 +176,14 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
176
176
  private options: Required<XslateAdapterOptions>
177
177
  private errors: CompilerError[] = []
178
178
  private inLoop: boolean = false
179
+ /**
180
+ * `IRLoop.depth` of the loop currently being rendered (save/restore
181
+ * around `renderChildren(loop.children)`, mirroring `inLoop` above).
182
+ * `renderAttributes` reads this to derive the `key` → `data-key`/
183
+ * `data-key-N` suffix — the depth is IR-computed (jsx-to-ir.ts), not
184
+ * re-derived here (#2168 nested-loop-outer-binding).
185
+ */
186
+ private currentLoopKeyDepth = 0
179
187
  /**
180
188
  * SolidJS-style props identifier (`function(props: P)`) and the
181
189
  * analyzer-extracted prop names. Stashed at `generate()` entry so the
@@ -375,7 +383,9 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
375
383
  }
376
384
 
377
385
  emitText(node: IRText): string {
378
- return node.value
386
+ // IRText carries the entity-DECODED value (Phase 1 decodes JSX
387
+ // character references); re-escape for direct HTML emission.
388
+ return escapeHtml(node.value)
379
389
  }
380
390
 
381
391
  emitExpression(node: IRExpression): string {
@@ -724,9 +734,13 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
724
734
  // For `keys`-shape iterations the callback param IS the index. We iterate
725
735
  // the array but bind the loop var to a throwaway and expose the index as
726
736
  // `$param`. Kolon's `$~loopvar.index` provides the 0-based index.
727
- const loopVar = loop.iterationShape === 'keys'
728
- ? '__bf_item'
729
- : supportableDestructure ? '__bf_item' : param
737
+ const loopVar = loop.objectIteration === 'entries'
738
+ ? '__bf_pair'
739
+ : loop.objectIteration
740
+ ? param
741
+ : loop.iterationShape === 'keys'
742
+ ? '__bf_item'
743
+ : supportableDestructure ? '__bf_item' : param
730
744
 
731
745
  // Index alias: when an explicit `index` param is present (`.map((x, i) =>
732
746
  // ...)`) or the iteration is `keys`-shaped, expose it via a `: my` Kolon
@@ -746,7 +760,16 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
746
760
  // `segments` (empty at the loop root, per the `LoopParamBinding` jsdoc) —
747
761
  // NOT the same as a fixed binding's full-accessor segments.
748
762
  const indexLocalLines: string[] = []
749
- if (loop.iterationShape === 'keys') {
763
+ if (loop.objectIteration === 'entries') {
764
+ // `key`/`value` bind off the `.kv()` pair (see the for-header below)
765
+ // — no derived `.index` local needed, unlike the array
766
+ // `iterationShape` cases.
767
+ indexLocalLines.push(`: my $${loop.index ?? param} = $${loopVar}.key;`)
768
+ indexLocalLines.push(`: my $${param} = $${loopVar}.value;`)
769
+ } else if (loop.objectIteration) {
770
+ // 'keys'/'values': `.keys()`/`.values()` already yield the bound
771
+ // value directly — no derived local needed either.
772
+ } else if (loop.iterationShape === 'keys') {
750
773
  indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`)
751
774
  } else if (loop.index) {
752
775
  indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`)
@@ -769,10 +792,13 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
769
792
 
770
793
  const prevInLoop = this.inLoop
771
794
  this.inLoop = true
795
+ const prevLoopKeyDepth = this.currentLoopKeyDepth
796
+ this.currentLoopKeyDepth = loop.depth
772
797
  // Re-render children now that inLoop is set (so nested components use the
773
798
  // loop-child naming convention). renderedChildren above was computed with
774
799
  // the previous flag; recompute under the loop flag.
775
800
  const childrenUnderLoop = this.renderChildren(loop.children)
801
+ this.currentLoopKeyDepth = prevLoopKeyDepth
776
802
  this.inLoop = prevInLoop
777
803
  void renderedChildren
778
804
 
@@ -789,7 +815,21 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
789
815
  // Scoped per-call-site marker so sibling `.map()`s under the same parent
790
816
  // each get their own reconciliation range.
791
817
  lines.push(`<: $bf.comment("loop:${loop.markerId}") | mark_raw :>`)
792
- lines.push(`: for ${array} -> $${loopVar} {`)
818
+ // `objectIteration` (#2168 object-entries-map): Kolon has no built-in
819
+ // hash-destructure `for` target, so `'entries'` iterates `.kv()`
820
+ // (yielding `{key, value}` pair objects, unpacked via the `: my`
821
+ // locals above) while `'keys'`/`'values'` iterate `.keys()`/`.values()`
822
+ // directly. All three are alphabetically sorted by Text::Xslate itself
823
+ // (verified empirically) — not JS insertion order, a documented known
824
+ // limitation for out-of-alphabetical-order data, same as Go/Rust.
825
+ const forHeader = loop.objectIteration === 'entries'
826
+ ? `: for ${array}.kv() -> $${loopVar} {`
827
+ : loop.objectIteration === 'keys'
828
+ ? `: for ${array}.keys() -> $${loopVar} {`
829
+ : loop.objectIteration === 'values'
830
+ ? `: for ${array}.values() -> $${loopVar} {`
831
+ : `: for ${array} -> $${loopVar} {`
832
+ lines.push(forHeader)
793
833
  for (const il of indexLocalLines) lines.push(il)
794
834
 
795
835
  // Handle filter().map() pattern by wrapping children in if-condition
@@ -932,11 +972,33 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
932
972
  type Segment = { kind: 'entries'; parts: string[] } | { kind: 'spread'; expr: string }
933
973
  const segments: Segment[] = [{ kind: 'entries', parts: [] }]
934
974
  const currentEntries = () => this.componentPropSegmentEntries(segments)
975
+ // Named JSX-valued props OTHER than the reserved `children`
976
+ // (`header={<strong>Title</strong>}`, #2168 jsx-element-prop) each get
977
+ // their own macro, prepended to the final returned string below —
978
+ // same mechanism as the reserved children macro, just keyed by the
979
+ // prop's own name instead of `children`.
980
+ const namedSlotMacros: string[] = []
935
981
 
936
982
  for (const p of comp.props) {
937
983
  // Skip callback props (onXxx) and `ref` — both are client-only for
938
984
  // SSR (Hono renders neither; the client JS wires them at hydration).
939
985
  if ((p.name.match(/^on[A-Z]/) || p.name === 'ref') && p.value.kind === 'expression') continue
986
+ if (p.value.kind === 'jsx-children' && p.name !== 'children') {
987
+ const prevInLoop = this.inLoop
988
+ this.inLoop = false
989
+ const slotBody = this.renderChildren(p.value.children)
990
+ this.inLoop = prevInLoop
991
+ // Purely counter-based — NOT derived from `p.name` or `comp.slotId`.
992
+ // A JSX prop name can contain characters (`data-slot`) that aren't a
993
+ // valid Kolon macro identifier, and `comp.slotId` alone would
994
+ // collide across two named-slot props on the same component
995
+ // invocation (unlike the reserved children slot, there's only ever
996
+ // one of those per invocation).
997
+ const macroName = `bf_prop_${this.childrenCaptureCounter++}`
998
+ namedSlotMacros.push(`<: macro ${macroName} -> () { :>${slotBody}<: } :>`)
999
+ currentEntries().push(`${kolonHashKey(p.name)} => ${macroName}()`)
1000
+ continue
1001
+ }
940
1002
  if (p.value.kind === 'spread') {
941
1003
  const trimmed = p.value.expr.trim()
942
1004
  // SolidJS-style props identifier (`function(props: P)`) has no
@@ -996,12 +1058,12 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
996
1058
  const macroName = `bf_children_${comp.slotId ?? 'c' + this.childrenCaptureCounter++}`
997
1059
  currentEntries().push(`children => ${macroName}()`)
998
1060
  const dict = this.combineComponentPropSegments(segments)
999
- return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`
1061
+ return `${namedSlotMacros.join('')}<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`
1000
1062
  }
1001
1063
 
1002
1064
  const isEmpty = segments.every(s => s.kind === 'entries' && s.parts.length === 0)
1003
1065
  const hashEntries = isEmpty ? '' : `, ${this.combineComponentPropSegments(segments)}`
1004
- return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`
1066
+ return `${namedSlotMacros.join('')}<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`
1005
1067
  }
1006
1068
 
1007
1069
  private childrenCaptureCounter = 0
@@ -1085,7 +1147,7 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
1085
1147
  * AttrValue lowering for intrinsic-element attributes (Kolon).
1086
1148
  */
1087
1149
  private readonly elementAttrEmitter: AttrValueEmitter = {
1088
- emitLiteral: (value, name) => `${name}="${value.value}"`,
1150
+ emitLiteral: (value, name) => `${name}="${escapeHtml(value.value)}"`,
1089
1151
  emitExpression: (value, name) => {
1090
1152
  // `style={{ … }}` object literal → a CSS string with dynamic values
1091
1153
  // interpolated, instead of refusing the bare object with BF101 (#1322).
@@ -1285,7 +1347,10 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
1285
1347
  // Rewrite JSX special-prop names to their HTML-attribute counterparts.
1286
1348
  let attrName: string
1287
1349
  if (attr.name === 'className') attrName = 'class'
1288
- else if (attr.name === 'key') attrName = 'data-key'
1350
+ else if (attr.name === 'key') {
1351
+ const depth = this.currentLoopKeyDepth
1352
+ attrName = depth > 0 ? `data-key-${depth}` : 'data-key'
1353
+ }
1289
1354
  else attrName = attr.name
1290
1355
  const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName)
1291
1356
  if (lowered) parts.push(lowered)
@@ -115,9 +115,4 @@ export const conformancePins: ConformancePins = {
115
115
  // the shape loudly instead of emitting entity-escaped markup that
116
116
  // silently renders tags as text.
117
117
  'dangerous-inner-html': [{ code: 'BF101', severity: 'error' }],
118
- // Edge-case sweep (Priority 12): `.replaceAll` has no lowering yet —
119
- // only first-occurrence `.replace` is wired to the runtime helpers.
120
- // Refused with BF101 rather than reusing the first-only lowering,
121
- // which would silently change semantics.
122
- 'string-replaceall': [{ code: 'BF101', severity: 'error' }],
123
118
  }
@@ -14,21 +14,4 @@
14
14
 
15
15
  import type { RenderDivergences } from '@barefootjs/jsx'
16
16
 
17
- export const renderDivergences: RenderDivergences = {
18
- 'html-entity-text':
19
- '`&copy;` in JSX literal text: Hono decodes to `©`, this adapter re-emits the raw entity — same DOM, different bytes',
20
- 'math-methods':
21
- 'Math.min/max/abs over a signal render empty (only Math.floor is in the template-primitive registry)',
22
- 'static-attr-escape':
23
- 'static attribute values are not HTML-escaped (`title="Fish & Chips"` emitted raw; Hono escapes)',
24
- 'object-entries-map':
25
- '`Object.entries(prop).map(([k, v]) => …)` renders an EMPTY list — the object-shaped prop silently produces zero iterations',
26
- 'nested-loop-outer-binding':
27
- 'nested-loop inner items carry `data-key` where the reference emits the depth-suffixed `data-key-1`',
28
- 'jsx-element-prop':
29
- 'a JSX element passed as a NON-children prop renders an empty slot — the element value is silently dropped',
30
- 'string-slice':
31
- '`.slice()` on a STRING misfires through the array slice helper',
32
- 'string-trim-sided':
33
- '`.trimStart()` / `.trimEnd()` render empty (no lowering)',
34
- }
17
+ export const renderDivergences: RenderDivergences = {}