@barefootjs/go-template 0.9.2 → 0.9.4
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/adapter/go-template-adapter.d.ts +21 -0
- package/dist/adapter/go-template-adapter.d.ts.map +1 -1
- package/dist/adapter/index.d.ts +2 -2
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +79 -3
- package/dist/build.d.ts +2 -2
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +88 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -3
- package/dist/test-render.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/go-template-adapter.test.ts +67 -36
- package/src/adapter/go-template-adapter.ts +145 -3
- package/src/adapter/index.ts +2 -2
- package/src/build.ts +16 -3
- package/src/index.ts +2 -2
- package/src/test-render.ts +98 -13
|
@@ -30,6 +30,7 @@ export interface GoTemplateAdapterOptions {
|
|
|
30
30
|
export declare class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter, IRNodeEmitter<GoRenderCtx> {
|
|
31
31
|
name: string;
|
|
32
32
|
extension: string;
|
|
33
|
+
private static readonly SCOPE_SENTINEL;
|
|
33
34
|
importMapInjection: 'html-snippet';
|
|
34
35
|
private filterExprDepth;
|
|
35
36
|
private filterExprUnsupported;
|
|
@@ -109,6 +110,10 @@ export declare class GoTemplateAdapter extends BaseAdapter implements ParsedExpr
|
|
|
109
110
|
/** Set during type generation when any emit references
|
|
110
111
|
* `template.HTML(...)`; toggles the `"html/template"` import. */
|
|
111
112
|
private usesHtmlTemplate;
|
|
113
|
+
/** Component root scope element(s) — each carries `data-key` for a keyed loop
|
|
114
|
+
* item. A plain element root is one node; an `if-statement` (early-return)
|
|
115
|
+
* root contributes the top element of every branch. (#1297) */
|
|
116
|
+
private rootScopeNodes;
|
|
112
117
|
/** Set during type generation when any emit references
|
|
113
118
|
* `fmt.Sprint(...)` — e.g. a `Record<staticKeys, scalar>[propKey]`
|
|
114
119
|
* indexed-map spread value (#checkbox); toggles the `"fmt"` import. */
|
|
@@ -367,7 +372,23 @@ export declare class GoTemplateAdapter extends BaseAdapter implements ParsedExpr
|
|
|
367
372
|
* "drop children" fallback. Dynamic / component-bearing children
|
|
368
373
|
* stay on the drop path until a re-evaluation hook lands.
|
|
369
374
|
*/
|
|
375
|
+
/**
|
|
376
|
+
* Pull the IR nodes out of a `children={<…/>}` attribute (a `jsx-children`
|
|
377
|
+
* prop value). Empty when the component takes no such prop. (#1326 / #1335)
|
|
378
|
+
*/
|
|
379
|
+
private jsxChildrenPropNodes;
|
|
370
380
|
private extractHtmlChildren;
|
|
381
|
+
/**
|
|
382
|
+
* Build a Go string-concat expression for hoisted-JSX children whose root
|
|
383
|
+
* carries `needsScope` (`children={<span/>}` — #1326 / #1335). Such roots
|
|
384
|
+
* render in the PARENT's scope, so their `bf-s` is the runtime parent
|
|
385
|
+
* `scopeID`, not a bake-time constant. We render the fragment, swap the
|
|
386
|
+
* parent-scope hydration marker for a sentinel, and splice `scopeID` back
|
|
387
|
+
* in. Returns null when the plain static `childrenHtml` path already
|
|
388
|
+
* applies, or when any other template action survives (genuinely dynamic —
|
|
389
|
+
* those stay on the drop path).
|
|
390
|
+
*/
|
|
391
|
+
private extractScopedHtmlChildren;
|
|
371
392
|
private collectStaticChildInstancesRecursive;
|
|
372
393
|
/**
|
|
373
394
|
* Extend the active provider-context map with one `<Ctx.Provider value>`. A
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"go-template-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/go-template-adapter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"go-template-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/go-template-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Go html/template Adapter Exports
|
|
3
3
|
*/
|
|
4
|
-
export { GoTemplateAdapter, goTemplateAdapter } from './go-template-adapter';
|
|
5
|
-
export type { GoTemplateAdapterOptions } from './go-template-adapter';
|
|
4
|
+
export { GoTemplateAdapter, goTemplateAdapter } from './go-template-adapter.ts';
|
|
5
|
+
export type { GoTemplateAdapterOptions } from './go-template-adapter.ts';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC/E,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -69,6 +69,42 @@ function capitalize(s) {
|
|
|
69
69
|
}
|
|
70
70
|
return s[0].toUpperCase() + s.slice(1);
|
|
71
71
|
}
|
|
72
|
+
function loopKeyToGoFieldPath(key, param) {
|
|
73
|
+
if (!key || !param)
|
|
74
|
+
return null;
|
|
75
|
+
const segs = key.split(".");
|
|
76
|
+
if (segs[0] !== param)
|
|
77
|
+
return null;
|
|
78
|
+
const rest = segs.slice(1);
|
|
79
|
+
if (rest.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
if (!rest.every((s) => /^[A-Za-z_]\w*$/.test(s)))
|
|
82
|
+
return null;
|
|
83
|
+
return "item." + rest.map(capitalize).join(".");
|
|
84
|
+
}
|
|
85
|
+
function collectRootScopeNodes(node) {
|
|
86
|
+
const out = new Set;
|
|
87
|
+
const visit = (n) => {
|
|
88
|
+
if (!n)
|
|
89
|
+
return;
|
|
90
|
+
if (n.type === "element") {
|
|
91
|
+
out.add(n);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (n.type === "if-statement") {
|
|
95
|
+
const s = n;
|
|
96
|
+
visit(s.consequent);
|
|
97
|
+
visit(s.alternate);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (n.type === "fragment") {
|
|
101
|
+
for (const c of n.children)
|
|
102
|
+
visit(c);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
visit(node);
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
72
108
|
function slotIdToFieldSuffix(slotId) {
|
|
73
109
|
const cleanId = slotId.startsWith("^") ? slotId.slice(1) : slotId;
|
|
74
110
|
const match = cleanId.match(/^s(\d+)$/);
|
|
@@ -101,6 +137,7 @@ var GO_TEMPLATE_PRIMITIVES = {
|
|
|
101
137
|
class GoTemplateAdapter extends BaseAdapter {
|
|
102
138
|
name = "go-template";
|
|
103
139
|
extension = ".tmpl";
|
|
140
|
+
static SCOPE_SENTINEL = "__BF_SCOPE_SENTINEL__";
|
|
104
141
|
importMapInjection = "html-snippet";
|
|
105
142
|
filterExprDepth = 0;
|
|
106
143
|
filterExprUnsupported = false;
|
|
@@ -120,6 +157,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
120
157
|
localStructFields = new Map;
|
|
121
158
|
synthStructTypes = new Map;
|
|
122
159
|
usesHtmlTemplate = false;
|
|
160
|
+
rootScopeNodes = new Set;
|
|
123
161
|
usesFmt = false;
|
|
124
162
|
childComponentShapes = new Map;
|
|
125
163
|
moduleStringConsts = new Map;
|
|
@@ -152,6 +190,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
152
190
|
const hasInteractivity = this.hasClientInteractivity(ir);
|
|
153
191
|
const isRootComponent = ir.root.type === "component";
|
|
154
192
|
const isIfStatement = ir.root.type === "if-statement";
|
|
193
|
+
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
155
194
|
const templateBody = isIfStatement ? this.renderIfStatement(ir.root, { isRootOfClientComponent: hasInteractivity }) : this.renderNode(ir.root, { isRootOfClientComponent: hasInteractivity && isRootComponent });
|
|
156
195
|
const scriptRegistrations = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName);
|
|
157
196
|
const template = `{{define "${this.componentName}"}}
|
|
@@ -683,6 +722,7 @@ ${goFields.join(`
|
|
|
683
722
|
lines.push('\tBfIsChild bool `json:"-"`');
|
|
684
723
|
lines.push('\tBfParent string `json:"-"`');
|
|
685
724
|
lines.push('\tBfMount string `json:"-"`');
|
|
725
|
+
lines.push('\tBfDataKey string `json:"-"`');
|
|
686
726
|
lines.push('\tScripts *bf.ScriptCollector `json:"-"`');
|
|
687
727
|
const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
|
|
688
728
|
const propFieldNames = new Set;
|
|
@@ -798,6 +838,11 @@ ${goFields.join(`
|
|
|
798
838
|
lines.push(` ${varName}[i] = New${nested.name}Props(item)`);
|
|
799
839
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
800
840
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
841
|
+
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
842
|
+
if (keyField) {
|
|
843
|
+
lines.push(` ${varName}[i].BfDataKey = fmt.Sprint(${keyField})`);
|
|
844
|
+
this.usesFmt = true;
|
|
845
|
+
}
|
|
801
846
|
lines.push("\t}");
|
|
802
847
|
lines.push("");
|
|
803
848
|
}
|
|
@@ -934,6 +979,9 @@ ${goFields.join(`
|
|
|
934
979
|
} else if (child.childrenHtml !== null) {
|
|
935
980
|
this.usesHtmlTemplate = true;
|
|
936
981
|
lines.push(` Children: template.HTML(${JSON.stringify(child.childrenHtml)}),`);
|
|
982
|
+
} else if (child.childrenScopedHtmlExpr !== null) {
|
|
983
|
+
this.usesHtmlTemplate = true;
|
|
984
|
+
lines.push(` Children: template.HTML(${child.childrenScopedHtmlExpr}),`);
|
|
937
985
|
}
|
|
938
986
|
lines.push(` }),`);
|
|
939
987
|
}
|
|
@@ -972,7 +1020,9 @@ ${goFields.join(`
|
|
|
972
1020
|
result.push({
|
|
973
1021
|
...loop.childComponent,
|
|
974
1022
|
isDynamic: !loop.isStaticArray,
|
|
975
|
-
isPropDerived: !!loop.isPropDerivedArray
|
|
1023
|
+
isPropDerived: !!loop.isPropDerivedArray,
|
|
1024
|
+
loopKey: loop.key ?? undefined,
|
|
1025
|
+
loopParam: loop.param ?? undefined
|
|
976
1026
|
});
|
|
977
1027
|
}
|
|
978
1028
|
}
|
|
@@ -1013,6 +1063,13 @@ ${goFields.join(`
|
|
|
1013
1063
|
}
|
|
1014
1064
|
return out;
|
|
1015
1065
|
}
|
|
1066
|
+
jsxChildrenPropNodes(props) {
|
|
1067
|
+
for (const p of props) {
|
|
1068
|
+
if (p.value.kind === "jsx-children")
|
|
1069
|
+
return p.value.children;
|
|
1070
|
+
}
|
|
1071
|
+
return [];
|
|
1072
|
+
}
|
|
1016
1073
|
extractHtmlChildren(children) {
|
|
1017
1074
|
if (children.length === 0)
|
|
1018
1075
|
return null;
|
|
@@ -1023,6 +1080,20 @@ ${goFields.join(`
|
|
|
1023
1080
|
return null;
|
|
1024
1081
|
return html;
|
|
1025
1082
|
}
|
|
1083
|
+
extractScopedHtmlChildren(children) {
|
|
1084
|
+
if (children.length === 0)
|
|
1085
|
+
return null;
|
|
1086
|
+
if (children.every((c) => c.type === "text"))
|
|
1087
|
+
return null;
|
|
1088
|
+
const html = this.renderChildren(children);
|
|
1089
|
+
const marker = this.renderScopeMarker(".ScopeID");
|
|
1090
|
+
const withSentinel = html.split(marker).join(`bf-s="${GoTemplateAdapter.SCOPE_SENTINEL}"`);
|
|
1091
|
+
if (!withSentinel.includes(GoTemplateAdapter.SCOPE_SENTINEL))
|
|
1092
|
+
return null;
|
|
1093
|
+
if (withSentinel.includes("{{"))
|
|
1094
|
+
return null;
|
|
1095
|
+
return withSentinel.split(GoTemplateAdapter.SCOPE_SENTINEL).map((seg) => JSON.stringify(seg)).join(" + scopeID + ");
|
|
1096
|
+
}
|
|
1026
1097
|
collectStaticChildInstancesRecursive(node, result, inLoop, providerCtx) {
|
|
1027
1098
|
if (node.type === "component") {
|
|
1028
1099
|
const comp = node;
|
|
@@ -1034,13 +1105,15 @@ ${goFields.join(`
|
|
|
1034
1105
|
}
|
|
1035
1106
|
if (comp.name !== "Portal" && !inLoop && comp.slotId) {
|
|
1036
1107
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
1108
|
+
const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
|
|
1037
1109
|
result.push({
|
|
1038
1110
|
name: comp.name,
|
|
1039
1111
|
slotId: comp.slotId,
|
|
1040
1112
|
props: comp.props,
|
|
1041
1113
|
fieldName: `${comp.name}${suffix}`,
|
|
1042
|
-
childrenText: this.extractTextChildren(
|
|
1043
|
-
childrenHtml: this.extractHtmlChildren(
|
|
1114
|
+
childrenText: this.extractTextChildren(effectiveChildren),
|
|
1115
|
+
childrenHtml: this.extractHtmlChildren(effectiveChildren),
|
|
1116
|
+
childrenScopedHtmlExpr: this.extractScopedHtmlChildren(effectiveChildren),
|
|
1044
1117
|
contextBindings: providerCtx.size > 0 ? providerCtx : undefined
|
|
1045
1118
|
});
|
|
1046
1119
|
}
|
|
@@ -2153,6 +2226,9 @@ ${goFields.join(`
|
|
|
2153
2226
|
if (element.needsScope) {
|
|
2154
2227
|
hydrationAttrs += ` ${this.renderScopeMarker(".ScopeID")}`;
|
|
2155
2228
|
}
|
|
2229
|
+
if (this.rootScopeNodes.has(element) && element.needsScope) {
|
|
2230
|
+
hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`;
|
|
2231
|
+
}
|
|
2156
2232
|
if (element.slotId) {
|
|
2157
2233
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
2158
2234
|
}
|
package/dist/build.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BuildOptions, PostBuildContext } from '@barefootjs/jsx';
|
|
2
|
-
import { GoTemplateAdapter } from './adapter';
|
|
3
|
-
import type { GoTemplateAdapterOptions } from './adapter';
|
|
2
|
+
import { GoTemplateAdapter } from './adapter/index.ts';
|
|
3
|
+
import type { GoTemplateAdapterOptions } from './adapter/index.ts';
|
|
4
4
|
export interface GoTemplateBuildOptions extends BuildOptions {
|
|
5
5
|
/** Adapter-specific options passed to GoTemplateAdapter */
|
|
6
6
|
adapterOptions?: GoTemplateAdapterOptions;
|
package/dist/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAElE,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAC1D,2DAA2D;IAC3D,cAAc,CAAC,EAAE,wBAAwB,CAAA;IACzC,gGAAgG;IAChG,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,uFAAuF;IACvF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1C,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAID;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA0C1D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmD3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3C,GAAG,MAAM,CAsET;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,sBAA2B;IAyC7D,OAAO;IACP,KAAK;IACL,UAAU;IACV,MAAM;IACN,MAAM;IACN,WAAW;IACX,SAAS;IACT,iBAAiB;IACjB,aAAa;IACb,mBAAmB;IACnB,YAAY;IAKZ,SAAS,QApDmB,gBAAgB;EAsD/C"}
|
package/dist/build.js
CHANGED
|
@@ -409,6 +409,42 @@ function capitalize(s) {
|
|
|
409
409
|
}
|
|
410
410
|
return s[0].toUpperCase() + s.slice(1);
|
|
411
411
|
}
|
|
412
|
+
function loopKeyToGoFieldPath(key, param) {
|
|
413
|
+
if (!key || !param)
|
|
414
|
+
return null;
|
|
415
|
+
const segs = key.split(".");
|
|
416
|
+
if (segs[0] !== param)
|
|
417
|
+
return null;
|
|
418
|
+
const rest = segs.slice(1);
|
|
419
|
+
if (rest.length === 0)
|
|
420
|
+
return null;
|
|
421
|
+
if (!rest.every((s) => /^[A-Za-z_]\w*$/.test(s)))
|
|
422
|
+
return null;
|
|
423
|
+
return "item." + rest.map(capitalize).join(".");
|
|
424
|
+
}
|
|
425
|
+
function collectRootScopeNodes(node) {
|
|
426
|
+
const out = new Set;
|
|
427
|
+
const visit = (n) => {
|
|
428
|
+
if (!n)
|
|
429
|
+
return;
|
|
430
|
+
if (n.type === "element") {
|
|
431
|
+
out.add(n);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
if (n.type === "if-statement") {
|
|
435
|
+
const s = n;
|
|
436
|
+
visit(s.consequent);
|
|
437
|
+
visit(s.alternate);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (n.type === "fragment") {
|
|
441
|
+
for (const c of n.children)
|
|
442
|
+
visit(c);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
visit(node);
|
|
446
|
+
return out;
|
|
447
|
+
}
|
|
412
448
|
function slotIdToFieldSuffix(slotId) {
|
|
413
449
|
const cleanId = slotId.startsWith("^") ? slotId.slice(1) : slotId;
|
|
414
450
|
const match = cleanId.match(/^s(\d+)$/);
|
|
@@ -441,6 +477,7 @@ var GO_TEMPLATE_PRIMITIVES = {
|
|
|
441
477
|
class GoTemplateAdapter extends BaseAdapter {
|
|
442
478
|
name = "go-template";
|
|
443
479
|
extension = ".tmpl";
|
|
480
|
+
static SCOPE_SENTINEL = "__BF_SCOPE_SENTINEL__";
|
|
444
481
|
importMapInjection = "html-snippet";
|
|
445
482
|
filterExprDepth = 0;
|
|
446
483
|
filterExprUnsupported = false;
|
|
@@ -460,6 +497,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
460
497
|
localStructFields = new Map;
|
|
461
498
|
synthStructTypes = new Map;
|
|
462
499
|
usesHtmlTemplate = false;
|
|
500
|
+
rootScopeNodes = new Set;
|
|
463
501
|
usesFmt = false;
|
|
464
502
|
childComponentShapes = new Map;
|
|
465
503
|
moduleStringConsts = new Map;
|
|
@@ -492,6 +530,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
492
530
|
const hasInteractivity = this.hasClientInteractivity(ir);
|
|
493
531
|
const isRootComponent = ir.root.type === "component";
|
|
494
532
|
const isIfStatement = ir.root.type === "if-statement";
|
|
533
|
+
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
495
534
|
const templateBody = isIfStatement ? this.renderIfStatement(ir.root, { isRootOfClientComponent: hasInteractivity }) : this.renderNode(ir.root, { isRootOfClientComponent: hasInteractivity && isRootComponent });
|
|
496
535
|
const scriptRegistrations = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName);
|
|
497
536
|
const template = `{{define "${this.componentName}"}}
|
|
@@ -1023,6 +1062,7 @@ ${goFields.join(`
|
|
|
1023
1062
|
lines.push('\tBfIsChild bool `json:"-"`');
|
|
1024
1063
|
lines.push('\tBfParent string `json:"-"`');
|
|
1025
1064
|
lines.push('\tBfMount string `json:"-"`');
|
|
1065
|
+
lines.push('\tBfDataKey string `json:"-"`');
|
|
1026
1066
|
lines.push('\tScripts *bf.ScriptCollector `json:"-"`');
|
|
1027
1067
|
const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
|
|
1028
1068
|
const propFieldNames = new Set;
|
|
@@ -1138,6 +1178,11 @@ ${goFields.join(`
|
|
|
1138
1178
|
lines.push(` ${varName}[i] = New${nested.name}Props(item)`);
|
|
1139
1179
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
1140
1180
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
1181
|
+
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
1182
|
+
if (keyField) {
|
|
1183
|
+
lines.push(` ${varName}[i].BfDataKey = fmt.Sprint(${keyField})`);
|
|
1184
|
+
this.usesFmt = true;
|
|
1185
|
+
}
|
|
1141
1186
|
lines.push("\t}");
|
|
1142
1187
|
lines.push("");
|
|
1143
1188
|
}
|
|
@@ -1274,6 +1319,9 @@ ${goFields.join(`
|
|
|
1274
1319
|
} else if (child.childrenHtml !== null) {
|
|
1275
1320
|
this.usesHtmlTemplate = true;
|
|
1276
1321
|
lines.push(` Children: template.HTML(${JSON.stringify(child.childrenHtml)}),`);
|
|
1322
|
+
} else if (child.childrenScopedHtmlExpr !== null) {
|
|
1323
|
+
this.usesHtmlTemplate = true;
|
|
1324
|
+
lines.push(` Children: template.HTML(${child.childrenScopedHtmlExpr}),`);
|
|
1277
1325
|
}
|
|
1278
1326
|
lines.push(` }),`);
|
|
1279
1327
|
}
|
|
@@ -1312,7 +1360,9 @@ ${goFields.join(`
|
|
|
1312
1360
|
result.push({
|
|
1313
1361
|
...loop.childComponent,
|
|
1314
1362
|
isDynamic: !loop.isStaticArray,
|
|
1315
|
-
isPropDerived: !!loop.isPropDerivedArray
|
|
1363
|
+
isPropDerived: !!loop.isPropDerivedArray,
|
|
1364
|
+
loopKey: loop.key ?? undefined,
|
|
1365
|
+
loopParam: loop.param ?? undefined
|
|
1316
1366
|
});
|
|
1317
1367
|
}
|
|
1318
1368
|
}
|
|
@@ -1353,6 +1403,13 @@ ${goFields.join(`
|
|
|
1353
1403
|
}
|
|
1354
1404
|
return out;
|
|
1355
1405
|
}
|
|
1406
|
+
jsxChildrenPropNodes(props) {
|
|
1407
|
+
for (const p of props) {
|
|
1408
|
+
if (p.value.kind === "jsx-children")
|
|
1409
|
+
return p.value.children;
|
|
1410
|
+
}
|
|
1411
|
+
return [];
|
|
1412
|
+
}
|
|
1356
1413
|
extractHtmlChildren(children) {
|
|
1357
1414
|
if (children.length === 0)
|
|
1358
1415
|
return null;
|
|
@@ -1363,6 +1420,20 @@ ${goFields.join(`
|
|
|
1363
1420
|
return null;
|
|
1364
1421
|
return html;
|
|
1365
1422
|
}
|
|
1423
|
+
extractScopedHtmlChildren(children) {
|
|
1424
|
+
if (children.length === 0)
|
|
1425
|
+
return null;
|
|
1426
|
+
if (children.every((c) => c.type === "text"))
|
|
1427
|
+
return null;
|
|
1428
|
+
const html = this.renderChildren(children);
|
|
1429
|
+
const marker = this.renderScopeMarker(".ScopeID");
|
|
1430
|
+
const withSentinel = html.split(marker).join(`bf-s="${GoTemplateAdapter.SCOPE_SENTINEL}"`);
|
|
1431
|
+
if (!withSentinel.includes(GoTemplateAdapter.SCOPE_SENTINEL))
|
|
1432
|
+
return null;
|
|
1433
|
+
if (withSentinel.includes("{{"))
|
|
1434
|
+
return null;
|
|
1435
|
+
return withSentinel.split(GoTemplateAdapter.SCOPE_SENTINEL).map((seg) => JSON.stringify(seg)).join(" + scopeID + ");
|
|
1436
|
+
}
|
|
1366
1437
|
collectStaticChildInstancesRecursive(node, result, inLoop, providerCtx) {
|
|
1367
1438
|
if (node.type === "component") {
|
|
1368
1439
|
const comp = node;
|
|
@@ -1374,13 +1445,15 @@ ${goFields.join(`
|
|
|
1374
1445
|
}
|
|
1375
1446
|
if (comp.name !== "Portal" && !inLoop && comp.slotId) {
|
|
1376
1447
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
1448
|
+
const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
|
|
1377
1449
|
result.push({
|
|
1378
1450
|
name: comp.name,
|
|
1379
1451
|
slotId: comp.slotId,
|
|
1380
1452
|
props: comp.props,
|
|
1381
1453
|
fieldName: `${comp.name}${suffix}`,
|
|
1382
|
-
childrenText: this.extractTextChildren(
|
|
1383
|
-
childrenHtml: this.extractHtmlChildren(
|
|
1454
|
+
childrenText: this.extractTextChildren(effectiveChildren),
|
|
1455
|
+
childrenHtml: this.extractHtmlChildren(effectiveChildren),
|
|
1456
|
+
childrenScopedHtmlExpr: this.extractScopedHtmlChildren(effectiveChildren),
|
|
1384
1457
|
contextBindings: providerCtx.size > 0 ? providerCtx : undefined
|
|
1385
1458
|
});
|
|
1386
1459
|
}
|
|
@@ -2493,6 +2566,9 @@ ${goFields.join(`
|
|
|
2493
2566
|
if (element.needsScope) {
|
|
2494
2567
|
hydrationAttrs += ` ${this.renderScopeMarker(".ScopeID")}`;
|
|
2495
2568
|
}
|
|
2569
|
+
if (this.rootScopeNodes.has(element) && element.needsScope) {
|
|
2570
|
+
hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`;
|
|
2571
|
+
}
|
|
2496
2572
|
if (element.slotId) {
|
|
2497
2573
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
2498
2574
|
}
|
|
@@ -4026,12 +4102,20 @@ function combineGoTypes(options) {
|
|
|
4026
4102
|
if (transformTypes) {
|
|
4027
4103
|
combinedContent = transformTypes(combinedContent);
|
|
4028
4104
|
}
|
|
4105
|
+
const usageScan = combinedContent + `
|
|
4106
|
+
` + (manualTypes ?? "");
|
|
4107
|
+
const stdlibImports = [` "math/rand"`];
|
|
4108
|
+
if (/\bfmt\./.test(usageScan))
|
|
4109
|
+
stdlibImports.push(` "fmt"`);
|
|
4110
|
+
if (/\btemplate\.HTML\b/.test(usageScan))
|
|
4111
|
+
stdlibImports.push(` "html/template"`);
|
|
4112
|
+
stdlibImports.sort();
|
|
4029
4113
|
const parts = [
|
|
4030
4114
|
`// Code generated by BarefootJS. DO NOT EDIT.`,
|
|
4031
4115
|
`package ${packageName}`,
|
|
4032
4116
|
"",
|
|
4033
4117
|
`import (`,
|
|
4034
|
-
|
|
4118
|
+
...stdlibImports,
|
|
4035
4119
|
"",
|
|
4036
4120
|
` bf "github.com/barefootjs/runtime/bf"`,
|
|
4037
4121
|
`)`,
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates Go html/template files from BarefootJS IR.
|
|
5
5
|
*/
|
|
6
|
-
export { GoTemplateAdapter, goTemplateAdapter } from './adapter';
|
|
7
|
-
export type { GoTemplateAdapterOptions } from './adapter';
|
|
6
|
+
export { GoTemplateAdapter, goTemplateAdapter } from './adapter/index.ts';
|
|
7
|
+
export type { GoTemplateAdapterOptions } from './adapter/index.ts';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACzE,YAAY,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,42 @@ function capitalize(s) {
|
|
|
69
69
|
}
|
|
70
70
|
return s[0].toUpperCase() + s.slice(1);
|
|
71
71
|
}
|
|
72
|
+
function loopKeyToGoFieldPath(key, param) {
|
|
73
|
+
if (!key || !param)
|
|
74
|
+
return null;
|
|
75
|
+
const segs = key.split(".");
|
|
76
|
+
if (segs[0] !== param)
|
|
77
|
+
return null;
|
|
78
|
+
const rest = segs.slice(1);
|
|
79
|
+
if (rest.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
if (!rest.every((s) => /^[A-Za-z_]\w*$/.test(s)))
|
|
82
|
+
return null;
|
|
83
|
+
return "item." + rest.map(capitalize).join(".");
|
|
84
|
+
}
|
|
85
|
+
function collectRootScopeNodes(node) {
|
|
86
|
+
const out = new Set;
|
|
87
|
+
const visit = (n) => {
|
|
88
|
+
if (!n)
|
|
89
|
+
return;
|
|
90
|
+
if (n.type === "element") {
|
|
91
|
+
out.add(n);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (n.type === "if-statement") {
|
|
95
|
+
const s = n;
|
|
96
|
+
visit(s.consequent);
|
|
97
|
+
visit(s.alternate);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (n.type === "fragment") {
|
|
101
|
+
for (const c of n.children)
|
|
102
|
+
visit(c);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
visit(node);
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
72
108
|
function slotIdToFieldSuffix(slotId) {
|
|
73
109
|
const cleanId = slotId.startsWith("^") ? slotId.slice(1) : slotId;
|
|
74
110
|
const match = cleanId.match(/^s(\d+)$/);
|
|
@@ -101,6 +137,7 @@ var GO_TEMPLATE_PRIMITIVES = {
|
|
|
101
137
|
class GoTemplateAdapter extends BaseAdapter {
|
|
102
138
|
name = "go-template";
|
|
103
139
|
extension = ".tmpl";
|
|
140
|
+
static SCOPE_SENTINEL = "__BF_SCOPE_SENTINEL__";
|
|
104
141
|
importMapInjection = "html-snippet";
|
|
105
142
|
filterExprDepth = 0;
|
|
106
143
|
filterExprUnsupported = false;
|
|
@@ -120,6 +157,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
120
157
|
localStructFields = new Map;
|
|
121
158
|
synthStructTypes = new Map;
|
|
122
159
|
usesHtmlTemplate = false;
|
|
160
|
+
rootScopeNodes = new Set;
|
|
123
161
|
usesFmt = false;
|
|
124
162
|
childComponentShapes = new Map;
|
|
125
163
|
moduleStringConsts = new Map;
|
|
@@ -152,6 +190,7 @@ class GoTemplateAdapter extends BaseAdapter {
|
|
|
152
190
|
const hasInteractivity = this.hasClientInteractivity(ir);
|
|
153
191
|
const isRootComponent = ir.root.type === "component";
|
|
154
192
|
const isIfStatement = ir.root.type === "if-statement";
|
|
193
|
+
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
155
194
|
const templateBody = isIfStatement ? this.renderIfStatement(ir.root, { isRootOfClientComponent: hasInteractivity }) : this.renderNode(ir.root, { isRootOfClientComponent: hasInteractivity && isRootComponent });
|
|
156
195
|
const scriptRegistrations = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName);
|
|
157
196
|
const template = `{{define "${this.componentName}"}}
|
|
@@ -683,6 +722,7 @@ ${goFields.join(`
|
|
|
683
722
|
lines.push('\tBfIsChild bool `json:"-"`');
|
|
684
723
|
lines.push('\tBfParent string `json:"-"`');
|
|
685
724
|
lines.push('\tBfMount string `json:"-"`');
|
|
725
|
+
lines.push('\tBfDataKey string `json:"-"`');
|
|
686
726
|
lines.push('\tScripts *bf.ScriptCollector `json:"-"`');
|
|
687
727
|
const nestedArrayFields = new Set(nestedComponents.map((n) => `${n.name}s`));
|
|
688
728
|
const propFieldNames = new Set;
|
|
@@ -798,6 +838,11 @@ ${goFields.join(`
|
|
|
798
838
|
lines.push(` ${varName}[i] = New${nested.name}Props(item)`);
|
|
799
839
|
lines.push(` ${varName}[i].BfParent = scopeID`);
|
|
800
840
|
lines.push(` ${varName}[i].BfMount = "${nested.slotId}"`);
|
|
841
|
+
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam);
|
|
842
|
+
if (keyField) {
|
|
843
|
+
lines.push(` ${varName}[i].BfDataKey = fmt.Sprint(${keyField})`);
|
|
844
|
+
this.usesFmt = true;
|
|
845
|
+
}
|
|
801
846
|
lines.push("\t}");
|
|
802
847
|
lines.push("");
|
|
803
848
|
}
|
|
@@ -934,6 +979,9 @@ ${goFields.join(`
|
|
|
934
979
|
} else if (child.childrenHtml !== null) {
|
|
935
980
|
this.usesHtmlTemplate = true;
|
|
936
981
|
lines.push(` Children: template.HTML(${JSON.stringify(child.childrenHtml)}),`);
|
|
982
|
+
} else if (child.childrenScopedHtmlExpr !== null) {
|
|
983
|
+
this.usesHtmlTemplate = true;
|
|
984
|
+
lines.push(` Children: template.HTML(${child.childrenScopedHtmlExpr}),`);
|
|
937
985
|
}
|
|
938
986
|
lines.push(` }),`);
|
|
939
987
|
}
|
|
@@ -972,7 +1020,9 @@ ${goFields.join(`
|
|
|
972
1020
|
result.push({
|
|
973
1021
|
...loop.childComponent,
|
|
974
1022
|
isDynamic: !loop.isStaticArray,
|
|
975
|
-
isPropDerived: !!loop.isPropDerivedArray
|
|
1023
|
+
isPropDerived: !!loop.isPropDerivedArray,
|
|
1024
|
+
loopKey: loop.key ?? undefined,
|
|
1025
|
+
loopParam: loop.param ?? undefined
|
|
976
1026
|
});
|
|
977
1027
|
}
|
|
978
1028
|
}
|
|
@@ -1013,6 +1063,13 @@ ${goFields.join(`
|
|
|
1013
1063
|
}
|
|
1014
1064
|
return out;
|
|
1015
1065
|
}
|
|
1066
|
+
jsxChildrenPropNodes(props) {
|
|
1067
|
+
for (const p of props) {
|
|
1068
|
+
if (p.value.kind === "jsx-children")
|
|
1069
|
+
return p.value.children;
|
|
1070
|
+
}
|
|
1071
|
+
return [];
|
|
1072
|
+
}
|
|
1016
1073
|
extractHtmlChildren(children) {
|
|
1017
1074
|
if (children.length === 0)
|
|
1018
1075
|
return null;
|
|
@@ -1023,6 +1080,20 @@ ${goFields.join(`
|
|
|
1023
1080
|
return null;
|
|
1024
1081
|
return html;
|
|
1025
1082
|
}
|
|
1083
|
+
extractScopedHtmlChildren(children) {
|
|
1084
|
+
if (children.length === 0)
|
|
1085
|
+
return null;
|
|
1086
|
+
if (children.every((c) => c.type === "text"))
|
|
1087
|
+
return null;
|
|
1088
|
+
const html = this.renderChildren(children);
|
|
1089
|
+
const marker = this.renderScopeMarker(".ScopeID");
|
|
1090
|
+
const withSentinel = html.split(marker).join(`bf-s="${GoTemplateAdapter.SCOPE_SENTINEL}"`);
|
|
1091
|
+
if (!withSentinel.includes(GoTemplateAdapter.SCOPE_SENTINEL))
|
|
1092
|
+
return null;
|
|
1093
|
+
if (withSentinel.includes("{{"))
|
|
1094
|
+
return null;
|
|
1095
|
+
return withSentinel.split(GoTemplateAdapter.SCOPE_SENTINEL).map((seg) => JSON.stringify(seg)).join(" + scopeID + ");
|
|
1096
|
+
}
|
|
1026
1097
|
collectStaticChildInstancesRecursive(node, result, inLoop, providerCtx) {
|
|
1027
1098
|
if (node.type === "component") {
|
|
1028
1099
|
const comp = node;
|
|
@@ -1034,13 +1105,15 @@ ${goFields.join(`
|
|
|
1034
1105
|
}
|
|
1035
1106
|
if (comp.name !== "Portal" && !inLoop && comp.slotId) {
|
|
1036
1107
|
const suffix = slotIdToFieldSuffix(comp.slotId);
|
|
1108
|
+
const effectiveChildren = comp.children.length > 0 ? comp.children : this.jsxChildrenPropNodes(comp.props);
|
|
1037
1109
|
result.push({
|
|
1038
1110
|
name: comp.name,
|
|
1039
1111
|
slotId: comp.slotId,
|
|
1040
1112
|
props: comp.props,
|
|
1041
1113
|
fieldName: `${comp.name}${suffix}`,
|
|
1042
|
-
childrenText: this.extractTextChildren(
|
|
1043
|
-
childrenHtml: this.extractHtmlChildren(
|
|
1114
|
+
childrenText: this.extractTextChildren(effectiveChildren),
|
|
1115
|
+
childrenHtml: this.extractHtmlChildren(effectiveChildren),
|
|
1116
|
+
childrenScopedHtmlExpr: this.extractScopedHtmlChildren(effectiveChildren),
|
|
1044
1117
|
contextBindings: providerCtx.size > 0 ? providerCtx : undefined
|
|
1045
1118
|
});
|
|
1046
1119
|
}
|
|
@@ -2153,6 +2226,9 @@ ${goFields.join(`
|
|
|
2153
2226
|
if (element.needsScope) {
|
|
2154
2227
|
hydrationAttrs += ` ${this.renderScopeMarker(".ScopeID")}`;
|
|
2155
2228
|
}
|
|
2229
|
+
if (this.rootScopeNodes.has(element) && element.needsScope) {
|
|
2230
|
+
hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`;
|
|
2231
|
+
}
|
|
2156
2232
|
if (element.slotId) {
|
|
2157
2233
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
2158
2234
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"test-render.d.ts","sourceRoot":"","sources":["../src/test-render.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAA;AAqBnE,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAgCD,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA6RvF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/go-template",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Go html/template adapter for BarefootJS - generates Go template files from IR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,6 +54,6 @@
|
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
57
|
-
"@barefootjs/jsx": "0.9.
|
|
57
|
+
"@barefootjs/jsx": "0.9.4"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -34,42 +34,10 @@ runAdapterConformanceTests({
|
|
|
34
34
|
// below, asserting that the adapter emits `BF101` / `BF103` /
|
|
35
35
|
// `BF104` at build time instead of silently emitting invalid
|
|
36
36
|
// template syntax (#1266).
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// render a hoisted-JSX child handed in through the `children`
|
|
42
|
-
// attribute, so the child is DROPPED: the parent renders
|
|
43
|
-
// `<div bf-s="test_s0"></div>` with an empty body (verified — no
|
|
44
|
-
// compile error, no literal `{{bfScopeAttr}}` text either; that
|
|
45
|
-
// older literal-survives-in-output failure mode no longer occurs).
|
|
46
|
-
// Closing the gap needs the inner span re-emitted as its own named
|
|
47
|
-
// template definition the outer template can pass its struct to, or
|
|
48
|
-
// the resolved scope id embedded at compile time. Neither lands
|
|
49
|
-
// here; the Mojo / Xslate siblings already pass by routing the
|
|
50
|
-
// hoisted JSX through the same nested-children capture.
|
|
51
|
-
'children-jsx-expression',
|
|
52
|
-
// #1335: fragment-wrapped form of the same shape. Once the IR
|
|
53
|
-
// unwraps `<><span/></>` into the bare-element form the Go adapter
|
|
54
|
-
// hits the identical drop as `children-jsx-expression` above.
|
|
55
|
-
'fragment-wrapped-children-jsx-expression',
|
|
56
|
-
// `toggle-shared`: the parent maps a `ToggleItemProps[]` prop into
|
|
57
|
-
// sibling `ToggleItem` children inside a keyed `.map`. The Go
|
|
58
|
-
// child-slice init types the loop input as `[]any` rather than
|
|
59
|
-
// `[]ToggleItemInput`, so the generated `NewToggleProps` struct
|
|
60
|
-
// literal fails to compile (`cannot use []any{…} as
|
|
61
|
-
// []ToggleItemInput value in struct literal`). Separate follow-up —
|
|
62
|
-
// needs the loop-child init to emit the typed element slice, plus
|
|
63
|
-
// per-item `defaultOn` seeding and the `data-key` attribute shape.
|
|
64
|
-
//
|
|
65
|
-
// `props-reactivity-comparison` graduated: the Go test-render now
|
|
66
|
-
// honours the fixture's `componentName` (`PropsReactivityComparison`,
|
|
67
|
-
// the second export of `ReactiveProps.tsx`) instead of always
|
|
68
|
-
// rendering the first export, and the generated child constructors
|
|
69
|
-
// compute the `displayValue = props.value * 10` memo from the
|
|
70
|
-
// passed prop — so SSR matches Hono byte-for-byte.
|
|
71
|
-
'toggle-shared',
|
|
72
|
-
],
|
|
37
|
+
// No JSX-render skips: every shared conformance fixture renders to Hono
|
|
38
|
+
// parity on real Go. Shapes the adapter intentionally refuses at build time
|
|
39
|
+
// are pinned in `expectedDiagnostics` below.
|
|
40
|
+
skipJsx: [],
|
|
73
41
|
// Per-fixture build-time contracts for shapes the Go template
|
|
74
42
|
// adapter intentionally refuses to lower. Lives here (not on the
|
|
75
43
|
// shared fixtures) so adding a new adapter doesn't require touching
|
|
@@ -1216,6 +1184,33 @@ export function Page() {
|
|
|
1216
1184
|
expect(types).not.toContain('template.HTML')
|
|
1217
1185
|
})
|
|
1218
1186
|
|
|
1187
|
+
test('bakes hoisted children={<span/>} with the parent scopeID spliced into bf-s (#1326 / #1335)', () => {
|
|
1188
|
+
// `children` passed as an attribute lands as a `jsx-children` prop and
|
|
1189
|
+
// its span carries `needsScope: true`. The root `bf-s` must resolve to
|
|
1190
|
+
// the *parent* scope at render time, so the bake splices `scopeID`
|
|
1191
|
+
// (matching the client `__BF_PARENT_SCOPE__` placeholder) rather than
|
|
1192
|
+
// emitting a static string or dropping the child.
|
|
1193
|
+
const adapter = new GoTemplateAdapter()
|
|
1194
|
+
const ir = compileToIR(`
|
|
1195
|
+
export function Host() { return <Box children={<span>x</span>} /> }
|
|
1196
|
+
function Box({ children }: { children: any }) { return <div>{children}</div> }
|
|
1197
|
+
`)
|
|
1198
|
+
const types = adapter.generateTypes(ir)!
|
|
1199
|
+
expect(types).toContain('Children: template.HTML("<span bf-s=\\"" + scopeID + "\\">x</span>")')
|
|
1200
|
+
expect(types).toContain('"html/template"')
|
|
1201
|
+
})
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
test('fragment-wrapped hoisted children bake to the same scoped shape (#1335)', () => {
|
|
1205
|
+
const adapter = new GoTemplateAdapter()
|
|
1206
|
+
const ir = compileToIR(`
|
|
1207
|
+
export function Host() { return <Box children={<><span>x</span></>} /> }
|
|
1208
|
+
function Box({ children }: { children: any }) { return <div>{children}</div> }
|
|
1209
|
+
`)
|
|
1210
|
+
const types = adapter.generateTypes(ir)!
|
|
1211
|
+
expect(types).toContain('Children: template.HTML("<span bf-s=\\"" + scopeID + "\\">x</span>")')
|
|
1212
|
+
})
|
|
1213
|
+
|
|
1219
1214
|
test('drops dynamic children that would emit Go template actions', () => {
|
|
1220
1215
|
// V1 limitation: a `template.HTML` value isn't re-parsed by the
|
|
1221
1216
|
// parent's `{{.Children}}` pipeline, so any `{{...}}` inside the
|
|
@@ -2493,6 +2488,42 @@ import { fixture as arrayEntriesFixture } from '../../../adapter-tests/fixtures/
|
|
|
2493
2488
|
import { fixture as arrayKeysFixture } from '../../../adapter-tests/fixtures/methods/array-keys'
|
|
2494
2489
|
import { fixture as arrayValuesFixture } from '../../../adapter-tests/fixtures/methods/array-values'
|
|
2495
2490
|
|
|
2491
|
+
describe('GoTemplateAdapter - keyed loop-child data-key (#1297, toggle-shared)', () => {
|
|
2492
|
+
// A keyed `.map` of a child component stamps each item's `data-key` from the
|
|
2493
|
+
// loop `key` expression, emitted on the child component's scope root —
|
|
2494
|
+
// matching Hono.
|
|
2495
|
+
// `List` is declared first so `compileToIR` (which picks the first IR)
|
|
2496
|
+
// returns the parent that owns the keyed loop.
|
|
2497
|
+
const source = `
|
|
2498
|
+
"use client"
|
|
2499
|
+
import { createSignal } from "@barefootjs/client"
|
|
2500
|
+
type ItemProps = { label: string; defaultOn?: boolean }
|
|
2501
|
+
export function List({ items }: { items: ItemProps[] }) {
|
|
2502
|
+
return <ul>{items.map((item) => <Item key={item.label} label={item.label} defaultOn={item.defaultOn} />)}</ul>
|
|
2503
|
+
}
|
|
2504
|
+
function Item(props: ItemProps) {
|
|
2505
|
+
const [on] = createSignal(props.defaultOn ?? false)
|
|
2506
|
+
return <div className="item">{on() ? props.label : ''}</div>
|
|
2507
|
+
}
|
|
2508
|
+
`
|
|
2509
|
+
test('Props carries a BfDataKey field', () => {
|
|
2510
|
+
const { types } = compileAndGenerate(source)
|
|
2511
|
+
expect(types).toContain('BfDataKey string `json:"-"`')
|
|
2512
|
+
})
|
|
2513
|
+
|
|
2514
|
+
test('loop-child init stamps BfDataKey from the loop key (item.Label)', () => {
|
|
2515
|
+
const { types } = compileAndGenerate(source)
|
|
2516
|
+
expect(types).toContain('[i].BfDataKey = fmt.Sprint(item.Label)')
|
|
2517
|
+
expect(types).toContain('\t"fmt"')
|
|
2518
|
+
})
|
|
2519
|
+
|
|
2520
|
+
test('child component root emits data-key from BfDataKey', () => {
|
|
2521
|
+
const { template } = compileAndGenerate(source)
|
|
2522
|
+
// Space is inside the `{{if}}` so a non-keyed render adds nothing.
|
|
2523
|
+
expect(template).toContain('{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}')
|
|
2524
|
+
})
|
|
2525
|
+
})
|
|
2526
|
+
|
|
2496
2527
|
describe('GoTemplateAdapter - #1448 Tier A/B fixture-driven lowering pins', () => {
|
|
2497
2528
|
const cases = [
|
|
2498
2529
|
// The `.includes` fixtures sit at condition position
|
|
@@ -82,6 +82,10 @@ type GoRenderCtx = {
|
|
|
82
82
|
interface NestedComponentInfo extends IRLoopChildComponent {
|
|
83
83
|
isDynamic: boolean
|
|
84
84
|
isPropDerived: boolean
|
|
85
|
+
/** The enclosing loop's `key` expression (e.g. `item.label`) and map param
|
|
86
|
+
* name (`item`), so the loop-child init can stamp `data-key` per item. */
|
|
87
|
+
loopKey?: string
|
|
88
|
+
loopParam?: string
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
interface StaticChildInstance {
|
|
@@ -104,6 +108,16 @@ interface StaticChildInstance {
|
|
|
104
108
|
* through the parent's `{{.Children}}` read; those cases stay on
|
|
105
109
|
* the existing drop path. */
|
|
106
110
|
childrenHtml: string | null
|
|
111
|
+
/** Go string-concat expression for hoisted-JSX children that carry a
|
|
112
|
+
* `needsScope` root (`children={<span/>}` — #1326 / #1335). The root's
|
|
113
|
+
* `bf-s` resolves to the PARENT scope (mirroring the client
|
|
114
|
+
* `__BF_PARENT_SCOPE__` placeholder + Mojo's begin/end capture), so the
|
|
115
|
+
* fragment can't bake to a static string — the runtime `scopeID` is
|
|
116
|
+
* spliced in (`"<span bf-s=\"" + scopeID + "\">x</span>"`). Null when the
|
|
117
|
+
* static `childrenHtml` path already covers the children, or when any
|
|
118
|
+
* other template action survives (genuinely dynamic — kept on the drop
|
|
119
|
+
* path). */
|
|
120
|
+
childrenScopedHtmlExpr: string | null
|
|
107
121
|
/**
|
|
108
122
|
* Context values from enclosing `<Ctx.Provider value>` ancestors
|
|
109
123
|
* (`createContext` identifier → Go value literal), wired into this child
|
|
@@ -287,6 +301,48 @@ function capitalize(s: string): string {
|
|
|
287
301
|
return s[0].toUpperCase() + s.slice(1)
|
|
288
302
|
}
|
|
289
303
|
|
|
304
|
+
/**
|
|
305
|
+
* Lower a keyed-loop `key` expression to the Go field path on the loop's range
|
|
306
|
+
* variable (always `item` in the generated `for i, item := range …`), e.g.
|
|
307
|
+
* `item.label` → `item.Label`. Returns null for a non-simple key (computed
|
|
308
|
+
* expression, whole-element key, mismatched param) so the loop-child init just
|
|
309
|
+
* skips `data-key` rather than emitting something that won't compile. (#1297)
|
|
310
|
+
*/
|
|
311
|
+
function loopKeyToGoFieldPath(key: string | undefined, param: string | undefined): string | null {
|
|
312
|
+
if (!key || !param) return null
|
|
313
|
+
const segs = key.split('.')
|
|
314
|
+
if (segs[0] !== param) return null
|
|
315
|
+
const rest = segs.slice(1)
|
|
316
|
+
if (rest.length === 0) return null
|
|
317
|
+
if (!rest.every(s => /^[A-Za-z_]\w*$/.test(s))) return null
|
|
318
|
+
return 'item.' + rest.map(capitalize).join('.')
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Collect the component's root scope element node(s) — the elements that become
|
|
323
|
+
* the rendered root and so carry `data-key` for a keyed loop item. A plain
|
|
324
|
+
* element root is itself; an `if-statement` (early-return) root contributes the
|
|
325
|
+
* top element of each branch, since exactly one renders at runtime. (#1297)
|
|
326
|
+
*/
|
|
327
|
+
function collectRootScopeNodes(node: IRNode): Set<IRNode> {
|
|
328
|
+
const out = new Set<IRNode>()
|
|
329
|
+
const visit = (n: IRNode | null): void => {
|
|
330
|
+
if (!n) return
|
|
331
|
+
if (n.type === 'element') { out.add(n); return }
|
|
332
|
+
if (n.type === 'if-statement') {
|
|
333
|
+
const s = n as IRIfStatement
|
|
334
|
+
visit(s.consequent)
|
|
335
|
+
visit(s.alternate)
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
if (n.type === 'fragment') {
|
|
339
|
+
for (const c of (n as IRFragment).children) visit(c)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
visit(node)
|
|
343
|
+
return out
|
|
344
|
+
}
|
|
345
|
+
|
|
290
346
|
/**
|
|
291
347
|
* Convert a slot ID (e.g., 's6') to a Go struct field suffix (e.g., 'Slot6').
|
|
292
348
|
* Keeps field names human-readable regardless of the internal slot ID format.
|
|
@@ -342,6 +398,11 @@ const GO_TEMPLATE_PRIMITIVES: Record<string, PrimitiveSpec> = {
|
|
|
342
398
|
export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter, IRNodeEmitter<GoRenderCtx> {
|
|
343
399
|
name = 'go-template'
|
|
344
400
|
extension = '.tmpl'
|
|
401
|
+
|
|
402
|
+
// Sentinel marking a parent-scope `bf-s` slot inside a hoisted-JSX
|
|
403
|
+
// children bake (see `extractScopedHtmlChildren`). The token can't appear
|
|
404
|
+
// in real HTML text, so splitting on it is unambiguous.
|
|
405
|
+
private static readonly SCOPE_SENTINEL = '__BF_SCOPE_SENTINEL__'
|
|
345
406
|
// Template-string target with no component layer: `bf build` emits a static
|
|
346
407
|
// `barefoot-importmap.html` to `{{ template }}` into the page <head> (#1644).
|
|
347
408
|
importMapInjection = 'html-snippet' as const
|
|
@@ -440,6 +501,10 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
440
501
|
/** Set during type generation when any emit references
|
|
441
502
|
* `template.HTML(...)`; toggles the `"html/template"` import. */
|
|
442
503
|
private usesHtmlTemplate: boolean = false
|
|
504
|
+
/** Component root scope element(s) — each carries `data-key` for a keyed loop
|
|
505
|
+
* item. A plain element root is one node; an `if-statement` (early-return)
|
|
506
|
+
* root contributes the top element of every branch. (#1297) */
|
|
507
|
+
private rootScopeNodes: Set<IRNode> = new Set()
|
|
443
508
|
|
|
444
509
|
/** Set during type generation when any emit references
|
|
445
510
|
* `fmt.Sprint(...)` — e.g. a `Record<staticKeys, scalar>[propKey]`
|
|
@@ -566,6 +631,7 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
566
631
|
const isRootComponent = ir.root.type === 'component'
|
|
567
632
|
const isIfStatement = ir.root.type === 'if-statement'
|
|
568
633
|
|
|
634
|
+
this.rootScopeNodes = collectRootScopeNodes(ir.root)
|
|
569
635
|
const templateBody = isIfStatement
|
|
570
636
|
? this.renderIfStatement(ir.root as IRIfStatement, { isRootOfClientComponent: hasInteractivity })
|
|
571
637
|
: this.renderNode(ir.root, { isRootOfClientComponent: hasInteractivity && isRootComponent })
|
|
@@ -1343,6 +1409,9 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1343
1409
|
// Emitted as bf-h / bf-m HTML attributes by `bfHydrationAttrs`.
|
|
1344
1410
|
lines.push('\tBfParent string `json:"-"`')
|
|
1345
1411
|
lines.push('\tBfMount string `json:"-"`')
|
|
1412
|
+
// (#1297) Keyed-loop reconciliation key, stamped per item by the parent's
|
|
1413
|
+
// loop init and emitted as `data-key` on this component's scope root.
|
|
1414
|
+
lines.push('\tBfDataKey string `json:"-"`')
|
|
1346
1415
|
|
|
1347
1416
|
// Add Scripts field for dynamic script collection
|
|
1348
1417
|
lines.push('\tScripts *bf.ScriptCollector `json:"-"`')
|
|
@@ -1533,6 +1602,13 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1533
1602
|
// mark it as a slot-attached child of this scope.
|
|
1534
1603
|
lines.push(`\t\t${varName}[i].BfParent = scopeID`)
|
|
1535
1604
|
lines.push(`\t\t${varName}[i].BfMount = "${nested.slotId}"`)
|
|
1605
|
+
// (#1297) Stamp the keyed-loop `data-key` per item from the loop's
|
|
1606
|
+
// `key` expression (`item.label` → `item.Label`), matching Hono.
|
|
1607
|
+
const keyField = loopKeyToGoFieldPath(nested.loopKey, nested.loopParam)
|
|
1608
|
+
if (keyField) {
|
|
1609
|
+
lines.push(`\t\t${varName}[i].BfDataKey = fmt.Sprint(${keyField})`)
|
|
1610
|
+
this.usesFmt = true
|
|
1611
|
+
}
|
|
1536
1612
|
lines.push('\t}')
|
|
1537
1613
|
lines.push('')
|
|
1538
1614
|
}
|
|
@@ -1764,6 +1840,11 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1764
1840
|
} else if (child.childrenHtml !== null) {
|
|
1765
1841
|
this.usesHtmlTemplate = true
|
|
1766
1842
|
lines.push(`\t\t\tChildren: template.HTML(${JSON.stringify(child.childrenHtml)}),`)
|
|
1843
|
+
} else if (child.childrenScopedHtmlExpr !== null) {
|
|
1844
|
+
// Hoisted-JSX children with a needsScope root (#1326 / #1335): the
|
|
1845
|
+
// root `bf-s` is the runtime parent scopeID, spliced into the bake.
|
|
1846
|
+
this.usesHtmlTemplate = true
|
|
1847
|
+
lines.push(`\t\t\tChildren: template.HTML(${child.childrenScopedHtmlExpr}),`)
|
|
1767
1848
|
}
|
|
1768
1849
|
lines.push(`\t\t}),`)
|
|
1769
1850
|
}
|
|
@@ -1823,6 +1904,8 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1823
1904
|
...loop.childComponent,
|
|
1824
1905
|
isDynamic: !loop.isStaticArray,
|
|
1825
1906
|
isPropDerived: !!loop.isPropDerivedArray,
|
|
1907
|
+
loopKey: loop.key ?? undefined,
|
|
1908
|
+
loopParam: loop.param ?? undefined,
|
|
1826
1909
|
})
|
|
1827
1910
|
}
|
|
1828
1911
|
}
|
|
@@ -1890,6 +1973,17 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1890
1973
|
* "drop children" fallback. Dynamic / component-bearing children
|
|
1891
1974
|
* stay on the drop path until a re-evaluation hook lands.
|
|
1892
1975
|
*/
|
|
1976
|
+
/**
|
|
1977
|
+
* Pull the IR nodes out of a `children={<…/>}` attribute (a `jsx-children`
|
|
1978
|
+
* prop value). Empty when the component takes no such prop. (#1326 / #1335)
|
|
1979
|
+
*/
|
|
1980
|
+
private jsxChildrenPropNodes(props: IRProp[]): IRNode[] {
|
|
1981
|
+
for (const p of props) {
|
|
1982
|
+
if (p.value.kind === 'jsx-children') return p.value.children
|
|
1983
|
+
}
|
|
1984
|
+
return []
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1893
1987
|
private extractHtmlChildren(children: IRNode[]): string | null {
|
|
1894
1988
|
if (children.length === 0) return null
|
|
1895
1989
|
if (children.every(c => c.type === 'text')) return null
|
|
@@ -1898,6 +1992,38 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1898
1992
|
return html
|
|
1899
1993
|
}
|
|
1900
1994
|
|
|
1995
|
+
/**
|
|
1996
|
+
* Build a Go string-concat expression for hoisted-JSX children whose root
|
|
1997
|
+
* carries `needsScope` (`children={<span/>}` — #1326 / #1335). Such roots
|
|
1998
|
+
* render in the PARENT's scope, so their `bf-s` is the runtime parent
|
|
1999
|
+
* `scopeID`, not a bake-time constant. We render the fragment, swap the
|
|
2000
|
+
* parent-scope hydration marker for a sentinel, and splice `scopeID` back
|
|
2001
|
+
* in. Returns null when the plain static `childrenHtml` path already
|
|
2002
|
+
* applies, or when any other template action survives (genuinely dynamic —
|
|
2003
|
+
* those stay on the drop path).
|
|
2004
|
+
*/
|
|
2005
|
+
private extractScopedHtmlChildren(children: IRNode[]): string | null {
|
|
2006
|
+
if (children.length === 0) return null
|
|
2007
|
+
if (children.every(c => c.type === 'text')) return null
|
|
2008
|
+
const html = this.renderChildren(children)
|
|
2009
|
+
// The needsScope marker renders parent-scope hydration attrs; in a
|
|
2010
|
+
// hoisted fragment every needsScope root resolves to the parent scopeID,
|
|
2011
|
+
// so collapse the whole marker to a bare `bf-s` sentinel (the empty
|
|
2012
|
+
// bf-h / bf-m attrs are dropped — same shape the client emits).
|
|
2013
|
+
const marker = this.renderScopeMarker('.ScopeID')
|
|
2014
|
+
const withSentinel = html
|
|
2015
|
+
.split(marker)
|
|
2016
|
+
.join(`bf-s="${GoTemplateAdapter.SCOPE_SENTINEL}"`)
|
|
2017
|
+
// No sentinel → no needsScope root → the static childrenHtml path covers it.
|
|
2018
|
+
if (!withSentinel.includes(GoTemplateAdapter.SCOPE_SENTINEL)) return null
|
|
2019
|
+
// Any surviving action means the fragment is genuinely dynamic.
|
|
2020
|
+
if (withSentinel.includes('{{')) return null
|
|
2021
|
+
return withSentinel
|
|
2022
|
+
.split(GoTemplateAdapter.SCOPE_SENTINEL)
|
|
2023
|
+
.map(seg => JSON.stringify(seg))
|
|
2024
|
+
.join(' + scopeID + ')
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1901
2027
|
private collectStaticChildInstancesRecursive(
|
|
1902
2028
|
node: IRNode,
|
|
1903
2029
|
result: StaticChildInstance[],
|
|
@@ -1920,13 +2046,21 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
1920
2046
|
// Skip components inside loops (handled by nestedComponents)
|
|
1921
2047
|
if (comp.name !== 'Portal' && !inLoop && comp.slotId) {
|
|
1922
2048
|
const suffix = slotIdToFieldSuffix(comp.slotId)
|
|
2049
|
+
// Children handed in as a `children={<…/>}` attribute (#1326 / #1335)
|
|
2050
|
+
// land as a `jsx-children` prop rather than nested between the tags;
|
|
2051
|
+
// treat them as the child's effective children when no nested ones
|
|
2052
|
+
// exist, so the bake paths below see them.
|
|
2053
|
+
const effectiveChildren = comp.children.length > 0
|
|
2054
|
+
? comp.children
|
|
2055
|
+
: this.jsxChildrenPropNodes(comp.props)
|
|
1923
2056
|
result.push({
|
|
1924
2057
|
name: comp.name,
|
|
1925
2058
|
slotId: comp.slotId,
|
|
1926
2059
|
props: comp.props,
|
|
1927
2060
|
fieldName: `${comp.name}${suffix}`,
|
|
1928
|
-
childrenText: this.extractTextChildren(
|
|
1929
|
-
childrenHtml: this.extractHtmlChildren(
|
|
2061
|
+
childrenText: this.extractTextChildren(effectiveChildren),
|
|
2062
|
+
childrenHtml: this.extractHtmlChildren(effectiveChildren),
|
|
2063
|
+
childrenScopedHtmlExpr: this.extractScopedHtmlChildren(effectiveChildren),
|
|
1930
2064
|
contextBindings: providerCtx.size > 0 ? providerCtx : undefined,
|
|
1931
2065
|
})
|
|
1932
2066
|
}
|
|
@@ -3664,6 +3798,14 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
3664
3798
|
if (element.needsScope) {
|
|
3665
3799
|
hydrationAttrs += ` ${this.renderScopeMarker('.ScopeID')}`
|
|
3666
3800
|
}
|
|
3801
|
+
// (#1297) A root scope element carries `data-key` for a keyed loop item —
|
|
3802
|
+
// the parent's loop init stamped `.BfDataKey`, so a non-keyed render emits
|
|
3803
|
+
// nothing. Mirrors Hono stamping data-key on each loop item's scope root,
|
|
3804
|
+
// including early-return (if-statement) roots where every branch's top
|
|
3805
|
+
// element qualifies.
|
|
3806
|
+
if (this.rootScopeNodes.has(element) && element.needsScope) {
|
|
3807
|
+
hydrationAttrs += `{{if .BfDataKey}} data-key="{{.BfDataKey}}"{{end}}`
|
|
3808
|
+
}
|
|
3667
3809
|
if (element.slotId) {
|
|
3668
3810
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`
|
|
3669
3811
|
}
|
|
@@ -5711,7 +5853,7 @@ export class GoTemplateAdapter extends BaseAdapter implements ParsedExprEmitter,
|
|
|
5711
5853
|
return `{{block "${slotName}" .}}{{end}}`
|
|
5712
5854
|
}
|
|
5713
5855
|
|
|
5714
|
-
renderAsync(node: IRAsync): string {
|
|
5856
|
+
override renderAsync(node: IRAsync): string {
|
|
5715
5857
|
const fallback = this.renderNode(node.fallback)
|
|
5716
5858
|
const children = this.renderChildren(node.children)
|
|
5717
5859
|
// Go templates use the OOS protocol: render a placeholder with fallback,
|
package/src/adapter/index.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Go html/template Adapter Exports
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export { GoTemplateAdapter, goTemplateAdapter } from './go-template-adapter'
|
|
6
|
-
export type { GoTemplateAdapterOptions } from './go-template-adapter'
|
|
5
|
+
export { GoTemplateAdapter, goTemplateAdapter } from './go-template-adapter.ts'
|
|
6
|
+
export type { GoTemplateAdapterOptions } from './go-template-adapter.ts'
|
package/src/build.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Go template build config factory for barefoot.config.ts
|
|
2
2
|
|
|
3
3
|
import type { BuildOptions, PostBuildContext } from '@barefootjs/jsx'
|
|
4
|
-
import { GoTemplateAdapter } from './adapter'
|
|
5
|
-
import type { GoTemplateAdapterOptions } from './adapter'
|
|
4
|
+
import { GoTemplateAdapter } from './adapter/index.ts'
|
|
5
|
+
import type { GoTemplateAdapterOptions } from './adapter/index.ts'
|
|
6
6
|
|
|
7
7
|
export interface GoTemplateBuildOptions extends BuildOptions {
|
|
8
8
|
/** Adapter-specific options passed to GoTemplateAdapter */
|
|
@@ -156,13 +156,26 @@ export function combineGoTypes(options: {
|
|
|
156
156
|
combinedContent = transformTypes(combinedContent)
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
// Conditionally pull in stdlib packages the combined component code uses.
|
|
160
|
+
// Per-component import blocks are stripped above, so the merged file needs
|
|
161
|
+
// its own block — `fmt` (e.g. `fmt.Sprint` for keyed-loop data-key /
|
|
162
|
+
// indexed-map spread) and `html/template` (`template.HTML` for forwarded
|
|
163
|
+
// JSX children) are only imported when actually referenced, so an app that
|
|
164
|
+
// uses neither doesn't get an "imported and not used" error.
|
|
165
|
+
const usageScan = combinedContent + '\n' + (manualTypes ?? '')
|
|
166
|
+
const stdlibImports: string[] = [`\t"math/rand"`]
|
|
167
|
+
if (/\bfmt\./.test(usageScan)) stdlibImports.push(`\t"fmt"`)
|
|
168
|
+
if (/\btemplate\.HTML\b/.test(usageScan)) stdlibImports.push(`\t"html/template"`)
|
|
169
|
+
// gofmt sorts the stdlib group alphabetically by import path.
|
|
170
|
+
stdlibImports.sort()
|
|
171
|
+
|
|
159
172
|
// Build final file
|
|
160
173
|
const parts = [
|
|
161
174
|
`// Code generated by BarefootJS. DO NOT EDIT.`,
|
|
162
175
|
`package ${packageName}`,
|
|
163
176
|
'',
|
|
164
177
|
`import (`,
|
|
165
|
-
|
|
178
|
+
...stdlibImports,
|
|
166
179
|
'',
|
|
167
180
|
`\tbf "github.com/barefootjs/runtime/bf"`,
|
|
168
181
|
`)`,
|
package/src/index.ts
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* Generates Go html/template files from BarefootJS IR.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export { GoTemplateAdapter, goTemplateAdapter } from './adapter'
|
|
8
|
-
export type { GoTemplateAdapterOptions } from './adapter'
|
|
7
|
+
export { GoTemplateAdapter, goTemplateAdapter } from './adapter/index.ts'
|
|
8
|
+
export type { GoTemplateAdapterOptions } from './adapter/index.ts'
|
package/src/test-render.ts
CHANGED
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
import { compileJSX } from '@barefootjs/jsx'
|
|
9
9
|
import type { TemplateAdapter, ComponentIR } from '@barefootjs/jsx'
|
|
10
|
+
import { GoTemplateAdapter } from './adapter/go-template-adapter.ts'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Capitalize a JSON key to its Go struct field name using the same
|
|
14
|
+
* initialism rules as the adapter (`capitalizeFieldName`): a whole-word Go
|
|
15
|
+
* initialism uppercases entirely (`id` → `ID`), otherwise just the first
|
|
16
|
+
* letter. Keeps harness-emitted struct literals (`ItemInput{ID: …}`) matching
|
|
17
|
+
* the generated exported field names. (#1297)
|
|
18
|
+
*/
|
|
19
|
+
function capitalizeGoField(name: string): string {
|
|
20
|
+
if (!name) return name
|
|
21
|
+
if (GoTemplateAdapter.GO_INITIALISMS.has(name.toLowerCase())) return name.toUpperCase()
|
|
22
|
+
return name.charAt(0).toUpperCase() + name.slice(1)
|
|
23
|
+
}
|
|
10
24
|
import { mkdir, rm } from 'node:fs/promises'
|
|
11
25
|
import { resolve } from 'node:path'
|
|
12
26
|
|
|
@@ -259,8 +273,9 @@ export async function renderGoTemplateComponent(options: RenderOptions): Promise
|
|
|
259
273
|
// template content as Go raw string
|
|
260
274
|
const escapedTemplate = template.replace(/`/g, '` + "`" + `')
|
|
261
275
|
|
|
262
|
-
// Build props initialization
|
|
263
|
-
|
|
276
|
+
// Build props initialization (typed against the generated Input struct so
|
|
277
|
+
// an array-of-objects prop emits e.g. `[]ToggleItemInput{…}`, not `[]any`).
|
|
278
|
+
const propsInit = buildGoPropsInit(componentName, props, ir, goTypes)
|
|
264
279
|
|
|
265
280
|
// Honour `__instanceId` from props for the root scope id so
|
|
266
281
|
// shared-component fixtures (which pin `<ComponentName>_test`) match
|
|
@@ -470,9 +485,10 @@ function ensureMergedStdlibImports(goTypes: string): string {
|
|
|
470
485
|
* Build Go struct field initializers from props.
|
|
471
486
|
*/
|
|
472
487
|
function buildGoPropsInit(
|
|
473
|
-
|
|
488
|
+
componentName: string,
|
|
474
489
|
props?: Record<string, unknown>,
|
|
475
490
|
ir?: ComponentIR,
|
|
491
|
+
goTypes?: string,
|
|
476
492
|
): string {
|
|
477
493
|
if (!props) return ''
|
|
478
494
|
|
|
@@ -517,16 +533,25 @@ function buildGoPropsInit(
|
|
|
517
533
|
} else if (typeof value === 'boolean') {
|
|
518
534
|
lines.push(`\t\t${goField}: ${value},`)
|
|
519
535
|
} else if (Array.isArray(value)) {
|
|
520
|
-
// Array → Go
|
|
521
|
-
//
|
|
522
|
-
//
|
|
523
|
-
//
|
|
524
|
-
//
|
|
525
|
-
//
|
|
526
|
-
//
|
|
527
|
-
//
|
|
528
|
-
//
|
|
529
|
-
|
|
536
|
+
// Array → Go slice literal. Fixtures that exercise array-receiver
|
|
537
|
+
// methods (`items.every(...)`, `items.join(' - ')`, etc. — #1448
|
|
538
|
+
// method catalog) need the prop value to reach the rendered template
|
|
539
|
+
// as a real slice so `range .Items` / `bf_join (.Items) ...` see
|
|
540
|
+
// actual elements.
|
|
541
|
+
//
|
|
542
|
+
// When the Input field is a typed slice (`ToggleItems
|
|
543
|
+
// []ToggleItemInput`, a loop-child array prop), emit a matching
|
|
544
|
+
// typed literal (`[]ToggleItemInput{ToggleItemInput{Label: …}, …}`);
|
|
545
|
+
// a bare `[]any{…}` would fail to compile against the typed field.
|
|
546
|
+
// Fall back to `[]any` when the field type is `[]any` / unknown.
|
|
547
|
+
const elemType = goSliceElemType(goTypes, componentName, goField)
|
|
548
|
+
lines.push(
|
|
549
|
+
`\t\t${goField}: ${
|
|
550
|
+
elemType
|
|
551
|
+
? goTypedSliceLiteralFromArray(value, elemType)
|
|
552
|
+
: goArrayLiteralFromArray(value)
|
|
553
|
+
},`,
|
|
554
|
+
)
|
|
530
555
|
} else if (value && typeof value === 'object') {
|
|
531
556
|
// Plain object → Go `map[string]any` literal (#1407 follow-up).
|
|
532
557
|
// Used by `jsx-spread-rest-prop` to populate the input-bag
|
|
@@ -546,6 +571,66 @@ function buildGoPropsInit(
|
|
|
546
571
|
return lines.join('\n')
|
|
547
572
|
}
|
|
548
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Look up the element type of a typed slice field on the entry component's
|
|
576
|
+
* `<Component>Input` struct (e.g. `ToggleItems []ToggleItemInput` →
|
|
577
|
+
* `ToggleItemInput`). Returns null when the field is absent, isn't a slice, or
|
|
578
|
+
* is an untyped `[]any` / `[]interface{}` (those keep the generic `[]any`
|
|
579
|
+
* harness literal). (#1297, toggle-shared)
|
|
580
|
+
*/
|
|
581
|
+
function goSliceElemType(
|
|
582
|
+
goTypes: string | undefined,
|
|
583
|
+
componentName: string,
|
|
584
|
+
goField: string,
|
|
585
|
+
): string | null {
|
|
586
|
+
if (!goTypes) return null
|
|
587
|
+
const struct = goTypes.match(
|
|
588
|
+
new RegExp(`type ${componentName}Input struct \\{([\\s\\S]*?)\\n\\}`),
|
|
589
|
+
)
|
|
590
|
+
if (!struct) return null
|
|
591
|
+
const field = struct[1].match(new RegExp(`\\n\\s*${goField}\\s+\\[\\]([\\w.]+)`))
|
|
592
|
+
if (!field) return null
|
|
593
|
+
const elem = field[1]
|
|
594
|
+
if (elem === 'any' || elem === 'interface{}') return null
|
|
595
|
+
return elem
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Emit a typed Go slice literal (`[]Elem{Elem{…}, …}`). Object elements become
|
|
600
|
+
* keyed struct literals with PascalCase field names; scalar elements (for an
|
|
601
|
+
* `[]string` / `[]int` field) are emitted bare. (#1297, toggle-shared)
|
|
602
|
+
*/
|
|
603
|
+
function goTypedSliceLiteralFromArray(arr: unknown[], elemType: string): string {
|
|
604
|
+
const entries = arr.map(v => {
|
|
605
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
606
|
+
return goStructLiteral(v as Record<string, unknown>, elemType)
|
|
607
|
+
}
|
|
608
|
+
if (typeof v === 'string') return `"${v.replace(/"/g, '\\"')}"`
|
|
609
|
+
if (typeof v === 'number' || typeof v === 'boolean') return String(v)
|
|
610
|
+
if (v === null) return 'nil'
|
|
611
|
+
return goArrayLiteralFromArray(v as unknown[])
|
|
612
|
+
})
|
|
613
|
+
return `[]${elemType}{${entries.join(', ')}}`
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Emit a keyed Go struct literal (`Elem{Field: val, …}`) with PascalCase field
|
|
618
|
+
* names. Only the keys the caller supplied are set, so an omitted optional prop
|
|
619
|
+
* (e.g. `defaultOn` on the third toggle item) takes the Go zero value. (#1297)
|
|
620
|
+
*/
|
|
621
|
+
function goStructLiteral(obj: Record<string, unknown>, typeName: string): string {
|
|
622
|
+
const fields: string[] = []
|
|
623
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
624
|
+
const goField = capitalizeGoField(k)
|
|
625
|
+
if (typeof v === 'string') fields.push(`${goField}: "${v.replace(/"/g, '\\"')}"`)
|
|
626
|
+
else if (typeof v === 'number' || typeof v === 'boolean') fields.push(`${goField}: ${v}`)
|
|
627
|
+
else if (v === null) fields.push(`${goField}: nil`)
|
|
628
|
+
else if (Array.isArray(v)) fields.push(`${goField}: ${goArrayLiteralFromArray(v)}`)
|
|
629
|
+
else if (v && typeof v === 'object') fields.push(`${goField}: ${goMapLiteralFromObject(v as Record<string, unknown>, true)}`)
|
|
630
|
+
}
|
|
631
|
+
return `${typeName}{${fields.join(', ')}}`
|
|
632
|
+
}
|
|
633
|
+
|
|
549
634
|
function goArrayLiteralFromArray(arr: unknown[]): string {
|
|
550
635
|
const entries: string[] = []
|
|
551
636
|
for (const v of arr) {
|