@barefootjs/erb 0.28.1 → 0.30.0
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/erb-adapter.d.ts +0 -1
- package/dist/adapter/erb-adapter.d.ts.map +1 -1
- package/dist/adapter/index.js +9 -12
- package/dist/build.js +9 -12
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +12 -14
- package/dist/render-divergences.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/adapter/erb-adapter.ts +23 -13
- package/src/conformance-pins.ts +0 -5
- package/src/render-divergences.ts +11 -0
|
@@ -61,7 +61,6 @@ export declare class ErbAdapter extends BaseAdapter implements IRNodeEmitter<Erb
|
|
|
61
61
|
private rootScopeNodes;
|
|
62
62
|
private options;
|
|
63
63
|
private errors;
|
|
64
|
-
private inLoop;
|
|
65
64
|
/**
|
|
66
65
|
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
67
66
|
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EACV,WAAW,EAEX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAMP,yBAAyB,EAC1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"erb-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/erb-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/index.js
CHANGED
|
@@ -187313,7 +187313,8 @@ import {
|
|
|
187313
187313
|
resolveDangerousInnerHtml,
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
|
-
resolveStaticLoopSource
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
derivesScopeFromSlot
|
|
187317
187318
|
} from "@barefootjs/jsx";
|
|
187318
187319
|
|
|
187319
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -188374,7 +188375,6 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188374
188375
|
rootScopeNodes = new Set;
|
|
188375
188376
|
options;
|
|
188376
188377
|
errors = [];
|
|
188377
|
-
inLoop = false;
|
|
188378
188378
|
currentLoopKeyDepth = 0;
|
|
188379
188379
|
propsObjectName = null;
|
|
188380
188380
|
propsParams = [];
|
|
@@ -188784,16 +188784,16 @@ ${whenTrue}
|
|
|
188784
188784
|
const param = loop.param;
|
|
188785
188785
|
const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
|
|
188786
188786
|
const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
|
|
188787
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
188788
|
+
for (const d of preambleDecls)
|
|
188789
|
+
loopBound.push(d.name);
|
|
188787
188790
|
for (const n of loopBound) {
|
|
188788
188791
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188789
188792
|
}
|
|
188790
|
-
const prevInLoop = this.inLoop;
|
|
188791
|
-
this.inLoop = true;
|
|
188792
188793
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188793
188794
|
this.currentLoopKeyDepth = loop.depth;
|
|
188794
188795
|
const renderedChildren = this.renderChildren(loop.children);
|
|
188795
188796
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
188796
|
-
this.inLoop = prevInLoop;
|
|
188797
188797
|
const children = loop.bodyIsItemConditional && loop.key ? `<%= bf.comment("loop-i:" + bf.string(${this.convertExpressionToRuby(loop.key)})) %>
|
|
188798
188798
|
${renderedChildren}` : renderedChildren;
|
|
188799
188799
|
const lines = [];
|
|
@@ -188851,6 +188851,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188851
188851
|
}
|
|
188852
188852
|
}
|
|
188853
188853
|
}
|
|
188854
|
+
const preambleLines = preambleDecls.map((d) => `<%- ${rubyLocal(d.name)} = ${this.convertExpressionToRuby(d.raw, d.valueParsed)} -%>`);
|
|
188854
188855
|
if (loop.filterPredicate) {
|
|
188855
188856
|
let filterCond;
|
|
188856
188857
|
if (loop.filterPredicate.predicate) {
|
|
@@ -188861,9 +188862,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188861
188862
|
filterCond = "true";
|
|
188862
188863
|
}
|
|
188863
188864
|
lines.push(`<%- if bf.truthy?(${filterCond}) -%>`);
|
|
188865
|
+
lines.push(...preambleLines);
|
|
188864
188866
|
lines.push(children);
|
|
188865
188867
|
lines.push(`<%- end -%>`);
|
|
188866
188868
|
} else {
|
|
188869
|
+
lines.push(...preambleLines);
|
|
188867
188870
|
lines.push(children);
|
|
188868
188871
|
}
|
|
188869
188872
|
for (const n of loopBound) {
|
|
@@ -188907,10 +188910,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188907
188910
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
188908
188911
|
continue;
|
|
188909
188912
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
188910
|
-
const prevInLoop = this.inLoop;
|
|
188911
|
-
this.inLoop = false;
|
|
188912
188913
|
const slotBody = this.renderChildren(p.value.children);
|
|
188913
|
-
this.inLoop = prevInLoop;
|
|
188914
188914
|
const suffix = `${this.childrenCaptureCounter++}`;
|
|
188915
188915
|
const lenVar = `__bf_len_${suffix}`;
|
|
188916
188916
|
const rawVar = `__bf_praw_${suffix}`;
|
|
@@ -188923,16 +188923,13 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188923
188923
|
if (lowered)
|
|
188924
188924
|
propParts.push(lowered);
|
|
188925
188925
|
}
|
|
188926
|
-
if (comp
|
|
188926
|
+
if (derivesScopeFromSlot(comp)) {
|
|
188927
188927
|
propParts.push(`${rubySymbolKey("_bf_slot")} '${comp.slotId}'`);
|
|
188928
188928
|
}
|
|
188929
188929
|
const tplName = this.toTemplateName(comp.name);
|
|
188930
188930
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
188931
188931
|
if (effectiveChildren.length > 0) {
|
|
188932
|
-
const prevInLoop = this.inLoop;
|
|
188933
|
-
this.inLoop = false;
|
|
188934
188932
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
188935
|
-
this.inLoop = prevInLoop;
|
|
188936
188933
|
const suffix = comp.slotId ?? `c${this.childrenCaptureCounter++}`;
|
|
188937
188934
|
const lenVar = `__bf_len_${suffix}`;
|
|
188938
188935
|
const capVar = `__bf_children_${suffix}`;
|
package/dist/build.js
CHANGED
|
@@ -187313,7 +187313,8 @@ import {
|
|
|
187313
187313
|
resolveDangerousInnerHtml,
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
|
-
resolveStaticLoopSource
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
derivesScopeFromSlot
|
|
187317
187318
|
} from "@barefootjs/jsx";
|
|
187318
187319
|
|
|
187319
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -188374,7 +188375,6 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188374
188375
|
rootScopeNodes = new Set;
|
|
188375
188376
|
options;
|
|
188376
188377
|
errors = [];
|
|
188377
|
-
inLoop = false;
|
|
188378
188378
|
currentLoopKeyDepth = 0;
|
|
188379
188379
|
propsObjectName = null;
|
|
188380
188380
|
propsParams = [];
|
|
@@ -188784,16 +188784,16 @@ ${whenTrue}
|
|
|
188784
188784
|
const param = loop.param;
|
|
188785
188785
|
const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
|
|
188786
188786
|
const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
|
|
188787
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
188788
|
+
for (const d of preambleDecls)
|
|
188789
|
+
loopBound.push(d.name);
|
|
188787
188790
|
for (const n of loopBound) {
|
|
188788
188791
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188789
188792
|
}
|
|
188790
|
-
const prevInLoop = this.inLoop;
|
|
188791
|
-
this.inLoop = true;
|
|
188792
188793
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188793
188794
|
this.currentLoopKeyDepth = loop.depth;
|
|
188794
188795
|
const renderedChildren = this.renderChildren(loop.children);
|
|
188795
188796
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
188796
|
-
this.inLoop = prevInLoop;
|
|
188797
188797
|
const children = loop.bodyIsItemConditional && loop.key ? `<%= bf.comment("loop-i:" + bf.string(${this.convertExpressionToRuby(loop.key)})) %>
|
|
188798
188798
|
${renderedChildren}` : renderedChildren;
|
|
188799
188799
|
const lines = [];
|
|
@@ -188851,6 +188851,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188851
188851
|
}
|
|
188852
188852
|
}
|
|
188853
188853
|
}
|
|
188854
|
+
const preambleLines = preambleDecls.map((d) => `<%- ${rubyLocal(d.name)} = ${this.convertExpressionToRuby(d.raw, d.valueParsed)} -%>`);
|
|
188854
188855
|
if (loop.filterPredicate) {
|
|
188855
188856
|
let filterCond;
|
|
188856
188857
|
if (loop.filterPredicate.predicate) {
|
|
@@ -188861,9 +188862,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188861
188862
|
filterCond = "true";
|
|
188862
188863
|
}
|
|
188863
188864
|
lines.push(`<%- if bf.truthy?(${filterCond}) -%>`);
|
|
188865
|
+
lines.push(...preambleLines);
|
|
188864
188866
|
lines.push(children);
|
|
188865
188867
|
lines.push(`<%- end -%>`);
|
|
188866
188868
|
} else {
|
|
188869
|
+
lines.push(...preambleLines);
|
|
188867
188870
|
lines.push(children);
|
|
188868
188871
|
}
|
|
188869
188872
|
for (const n of loopBound) {
|
|
@@ -188907,10 +188910,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188907
188910
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
188908
188911
|
continue;
|
|
188909
188912
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
188910
|
-
const prevInLoop = this.inLoop;
|
|
188911
|
-
this.inLoop = false;
|
|
188912
188913
|
const slotBody = this.renderChildren(p.value.children);
|
|
188913
|
-
this.inLoop = prevInLoop;
|
|
188914
188914
|
const suffix = `${this.childrenCaptureCounter++}`;
|
|
188915
188915
|
const lenVar = `__bf_len_${suffix}`;
|
|
188916
188916
|
const rawVar = `__bf_praw_${suffix}`;
|
|
@@ -188923,16 +188923,13 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188923
188923
|
if (lowered)
|
|
188924
188924
|
propParts.push(lowered);
|
|
188925
188925
|
}
|
|
188926
|
-
if (comp
|
|
188926
|
+
if (derivesScopeFromSlot(comp)) {
|
|
188927
188927
|
propParts.push(`${rubySymbolKey("_bf_slot")} '${comp.slotId}'`);
|
|
188928
188928
|
}
|
|
188929
188929
|
const tplName = this.toTemplateName(comp.name);
|
|
188930
188930
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
188931
188931
|
if (effectiveChildren.length > 0) {
|
|
188932
|
-
const prevInLoop = this.inLoop;
|
|
188933
|
-
this.inLoop = false;
|
|
188934
188932
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
188935
|
-
this.inLoop = prevInLoop;
|
|
188936
188933
|
const suffix = comp.slotId ?? `c${this.childrenCaptureCounter++}`;
|
|
188937
188934
|
const lenVar = `__bf_len_${suffix}`;
|
|
188938
188935
|
const capVar = `__bf_children_${suffix}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAyI7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -187313,7 +187313,8 @@ import {
|
|
|
187313
187313
|
resolveDangerousInnerHtml,
|
|
187314
187314
|
dangerousInnerHtmlMetacharViolation,
|
|
187315
187315
|
dangerousInnerHtmlDiagnostic,
|
|
187316
|
-
resolveStaticLoopSource
|
|
187316
|
+
resolveStaticLoopSource,
|
|
187317
|
+
derivesScopeFromSlot
|
|
187317
187318
|
} from "@barefootjs/jsx";
|
|
187318
187319
|
|
|
187319
187320
|
// src/adapter/boolean-result.ts
|
|
@@ -188374,7 +188375,6 @@ class ErbAdapter extends BaseAdapter {
|
|
|
188374
188375
|
rootScopeNodes = new Set;
|
|
188375
188376
|
options;
|
|
188376
188377
|
errors = [];
|
|
188377
|
-
inLoop = false;
|
|
188378
188378
|
currentLoopKeyDepth = 0;
|
|
188379
188379
|
propsObjectName = null;
|
|
188380
188380
|
propsParams = [];
|
|
@@ -188784,16 +188784,16 @@ ${whenTrue}
|
|
|
188784
188784
|
const param = loop.param;
|
|
188785
188785
|
const indexVar = loop.iterationShape === "keys" ? rubyLocal(param) : rubyLocal(loop.index ?? "_i");
|
|
188786
188786
|
const loopBound = loop.objectIteration === "entries" ? [param, loop.index ?? "_k"] : loop.objectIteration === "keys" || loop.objectIteration === "values" || loop.iterationShape === "keys" ? [param] : supportableDestructure ? ["__bf_item", ...(loop.paramBindings ?? []).map((b) => b.name), loop.index ?? "_i"] : [param, loop.index ?? "_i"];
|
|
188787
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
188788
|
+
for (const d of preambleDecls)
|
|
188789
|
+
loopBound.push(d.name);
|
|
188787
188790
|
for (const n of loopBound) {
|
|
188788
188791
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
188789
188792
|
}
|
|
188790
|
-
const prevInLoop = this.inLoop;
|
|
188791
|
-
this.inLoop = true;
|
|
188792
188793
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
188793
188794
|
this.currentLoopKeyDepth = loop.depth;
|
|
188794
188795
|
const renderedChildren = this.renderChildren(loop.children);
|
|
188795
188796
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
188796
|
-
this.inLoop = prevInLoop;
|
|
188797
188797
|
const children = loop.bodyIsItemConditional && loop.key ? `<%= bf.comment("loop-i:" + bf.string(${this.convertExpressionToRuby(loop.key)})) %>
|
|
188798
188798
|
${renderedChildren}` : renderedChildren;
|
|
188799
188799
|
const lines = [];
|
|
@@ -188851,6 +188851,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188851
188851
|
}
|
|
188852
188852
|
}
|
|
188853
188853
|
}
|
|
188854
|
+
const preambleLines = preambleDecls.map((d) => `<%- ${rubyLocal(d.name)} = ${this.convertExpressionToRuby(d.raw, d.valueParsed)} -%>`);
|
|
188854
188855
|
if (loop.filterPredicate) {
|
|
188855
188856
|
let filterCond;
|
|
188856
188857
|
if (loop.filterPredicate.predicate) {
|
|
@@ -188861,9 +188862,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188861
188862
|
filterCond = "true";
|
|
188862
188863
|
}
|
|
188863
188864
|
lines.push(`<%- if bf.truthy?(${filterCond}) -%>`);
|
|
188865
|
+
lines.push(...preambleLines);
|
|
188864
188866
|
lines.push(children);
|
|
188865
188867
|
lines.push(`<%- end -%>`);
|
|
188866
188868
|
} else {
|
|
188869
|
+
lines.push(...preambleLines);
|
|
188867
188870
|
lines.push(children);
|
|
188868
188871
|
}
|
|
188869
188872
|
for (const n of loopBound) {
|
|
@@ -188907,10 +188910,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188907
188910
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
188908
188911
|
continue;
|
|
188909
188912
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
188910
|
-
const prevInLoop = this.inLoop;
|
|
188911
|
-
this.inLoop = false;
|
|
188912
188913
|
const slotBody = this.renderChildren(p.value.children);
|
|
188913
|
-
this.inLoop = prevInLoop;
|
|
188914
188914
|
const suffix = `${this.childrenCaptureCounter++}`;
|
|
188915
188915
|
const lenVar = `__bf_len_${suffix}`;
|
|
188916
188916
|
const rawVar = `__bf_praw_${suffix}`;
|
|
@@ -188923,16 +188923,13 @@ ${renderedChildren}` : renderedChildren;
|
|
|
188923
188923
|
if (lowered)
|
|
188924
188924
|
propParts.push(lowered);
|
|
188925
188925
|
}
|
|
188926
|
-
if (comp
|
|
188926
|
+
if (derivesScopeFromSlot(comp)) {
|
|
188927
188927
|
propParts.push(`${rubySymbolKey("_bf_slot")} '${comp.slotId}'`);
|
|
188928
188928
|
}
|
|
188929
188929
|
const tplName = this.toTemplateName(comp.name);
|
|
188930
188930
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
188931
188931
|
if (effectiveChildren.length > 0) {
|
|
188932
|
-
const prevInLoop = this.inLoop;
|
|
188933
|
-
this.inLoop = false;
|
|
188934
188932
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
188935
|
-
this.inLoop = prevInLoop;
|
|
188936
188933
|
const suffix = comp.slotId ?? `c${this.childrenCaptureCounter++}`;
|
|
188937
188934
|
const lenVar = `__bf_len_${suffix}`;
|
|
188938
188935
|
const capVar = `__bf_children_${suffix}`;
|
|
@@ -189266,7 +189263,6 @@ var erbAdapter = new ErbAdapter;
|
|
|
189266
189263
|
// src/conformance-pins.ts
|
|
189267
189264
|
var conformancePins = {
|
|
189268
189265
|
"filter-typeof-predicate": [{ code: "BF021", severity: "error" }],
|
|
189269
|
-
"map-preamble-branch-body": [{ code: "BF021", severity: "error" }],
|
|
189270
189266
|
"map-array-builder-body": [{ code: "BF021", severity: "error" }],
|
|
189271
189267
|
"map-array-builder-escaping": [{ code: "BF021", severity: "error" }],
|
|
189272
189268
|
"fill-unsupported": [{ code: "BF101", severity: "error" }],
|
|
@@ -189290,7 +189286,9 @@ var conformancePins = {
|
|
|
189290
189286
|
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
|
|
189291
189287
|
};
|
|
189292
189288
|
// src/render-divergences.ts
|
|
189293
|
-
var renderDivergences = {
|
|
189289
|
+
var renderDivergences = {
|
|
189290
|
+
"aliased-destructured-prop": "aliased destructured prop `{ n: count }` loses its rename — template vars, ssr-defaults, and the props bridge all key off the local name, so the prop is always undefined (https://github.com/piconic-ai/barefootjs/issues/2460)"
|
|
189291
|
+
};
|
|
189294
189292
|
export {
|
|
189295
189293
|
renderDivergences,
|
|
189296
189294
|
erbAdapter,
|
|
@@ -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,
|
|
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,iBAgB/B,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/erb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "ERB (Embedded Ruby) adapter for BarefootJS — compiles IR to .erb templates and ships the Ruby rendering backend; runs under any Rack app (Sinatra, Rails)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
"directory": "packages/adapter-erb"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@barefootjs/shared": "0.
|
|
57
|
+
"@barefootjs/shared": "0.30.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@barefootjs/jsx": ">=0.2.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
64
|
-
"@barefootjs/jsx": "0.
|
|
64
|
+
"@barefootjs/jsx": "0.30.0",
|
|
65
65
|
"typescript": "^5.0.0"
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
dangerousInnerHtmlMetacharViolation,
|
|
94
94
|
dangerousInnerHtmlDiagnostic,
|
|
95
95
|
resolveStaticLoopSource,
|
|
96
|
+
derivesScopeFromSlot,
|
|
96
97
|
} from '@barefootjs/jsx'
|
|
97
98
|
import { isAriaBooleanAttr, isBooleanResultExpr, isExplicitStringCall } from './boolean-result.ts'
|
|
98
99
|
import type { ParsedExpr, LoweringMatcher, LoopBindingPathSegment } from '@barefootjs/jsx'
|
|
@@ -182,7 +183,6 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
182
183
|
private rootScopeNodes: Set<IRNode> = new Set()
|
|
183
184
|
private options: Required<ErbAdapterOptions>
|
|
184
185
|
private errors: CompilerError[] = []
|
|
185
|
-
private inLoop: boolean = false
|
|
186
186
|
/**
|
|
187
187
|
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
188
188
|
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
@@ -981,16 +981,21 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
981
981
|
: supportableDestructure
|
|
982
982
|
? ['__bf_item', ...(loop.paramBindings ?? []).map(b => b.name), loop.index ?? '_i']
|
|
983
983
|
: [param, loop.index ?? '_i']
|
|
984
|
+
// A `.map()` callback preamble lowers to one per-row Ruby local per
|
|
985
|
+
// declaration (#2447). The names must be loop-bound for the whole body,
|
|
986
|
+
// or `ErbTopLevelEmitter.identifier` renders each read as `v[:cls]` —
|
|
987
|
+
// a vars-Hash key nothing ever seeds, i.e. the empty attribute this
|
|
988
|
+
// fixes. Phase 1 guarantees `declarations` is present or the loop was
|
|
989
|
+
// already refused, so there is no partial-lowering case here.
|
|
990
|
+
const preambleDecls = loop.preamble?.declarations ?? []
|
|
991
|
+
for (const d of preambleDecls) loopBound.push(d.name)
|
|
984
992
|
for (const n of loopBound) {
|
|
985
993
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1)
|
|
986
994
|
}
|
|
987
|
-
const prevInLoop = this.inLoop
|
|
988
|
-
this.inLoop = true
|
|
989
995
|
const prevLoopKeyDepth = this.currentLoopKeyDepth
|
|
990
996
|
this.currentLoopKeyDepth = loop.depth
|
|
991
997
|
const renderedChildren = this.renderChildren(loop.children)
|
|
992
998
|
this.currentLoopKeyDepth = prevLoopKeyDepth
|
|
993
|
-
this.inLoop = prevInLoop
|
|
994
999
|
|
|
995
1000
|
// Whole-item conditional: prepend an always-present
|
|
996
1001
|
// `<!--bf-loop-i:KEY-->` anchor before each item's (possibly empty)
|
|
@@ -1104,6 +1109,15 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
1104
1109
|
}
|
|
1105
1110
|
}
|
|
1106
1111
|
|
|
1112
|
+
// Per-row preamble locals (#2447), in source order so a later
|
|
1113
|
+
// initializer sees an earlier local — same as the source block. Emitted
|
|
1114
|
+
// INSIDE the filter guard below, matching JS evaluation order: a
|
|
1115
|
+
// `.filter(p).map(cb)` chain never runs `cb`'s body for a filtered-out
|
|
1116
|
+
// item.
|
|
1117
|
+
const preambleLines = preambleDecls.map(
|
|
1118
|
+
d => `<%- ${rubyLocal(d.name)} = ${this.convertExpressionToRuby(d.raw, d.valueParsed)} -%>`,
|
|
1119
|
+
)
|
|
1120
|
+
|
|
1107
1121
|
// Handle filter().map() pattern by wrapping children in if-condition
|
|
1108
1122
|
if (loop.filterPredicate) {
|
|
1109
1123
|
let filterCond: string
|
|
@@ -1137,9 +1151,11 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
1137
1151
|
filterCond = 'true'
|
|
1138
1152
|
}
|
|
1139
1153
|
lines.push(`<%- if bf.truthy?(${filterCond}) -%>`)
|
|
1154
|
+
lines.push(...preambleLines)
|
|
1140
1155
|
lines.push(children)
|
|
1141
1156
|
lines.push(`<%- end -%>`)
|
|
1142
1157
|
} else {
|
|
1158
|
+
lines.push(...preambleLines)
|
|
1143
1159
|
lines.push(children)
|
|
1144
1160
|
}
|
|
1145
1161
|
|
|
@@ -1231,10 +1247,7 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
1231
1247
|
// SSR (Hono renders neither; the client JS wires them at hydration).
|
|
1232
1248
|
if ((p.name.match(/^on[A-Z]/) || p.name === 'ref') && p.value.kind === 'expression') continue
|
|
1233
1249
|
if (p.value.kind === 'jsx-children' && p.name !== 'children') {
|
|
1234
|
-
const prevInLoop = this.inLoop
|
|
1235
|
-
this.inLoop = false
|
|
1236
1250
|
const slotBody = this.renderChildren(p.value.children)
|
|
1237
|
-
this.inLoop = prevInLoop
|
|
1238
1251
|
// Purely counter-based — NOT derived from `p.name` or `comp.slotId`.
|
|
1239
1252
|
// A JSX prop name can contain characters (`data-slot`) that aren't
|
|
1240
1253
|
// valid in a Ruby local variable name, and `comp.slotId` alone
|
|
@@ -1255,9 +1268,9 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
1255
1268
|
if (lowered) propParts.push(lowered)
|
|
1256
1269
|
}
|
|
1257
1270
|
// Pass slot ID so the child renderer can set correct scope ID for
|
|
1258
|
-
// hydration.
|
|
1259
|
-
// pattern instead.
|
|
1260
|
-
if (comp
|
|
1271
|
+
// hydration. Skipped for a loop item root — it uses the
|
|
1272
|
+
// ComponentName_random pattern instead (#2444).
|
|
1273
|
+
if (derivesScopeFromSlot(comp)) {
|
|
1261
1274
|
propParts.push(`${rubySymbolKey('_bf_slot')} '${comp.slotId}'`)
|
|
1262
1275
|
}
|
|
1263
1276
|
const tplName = this.toTemplateName(comp.name)
|
|
@@ -1282,10 +1295,7 @@ export class ErbAdapter extends BaseAdapter implements IRNodeEmitter<ErbRenderCt
|
|
|
1282
1295
|
// tags and the children — the slice captures byte-for-byte whatever
|
|
1283
1296
|
// `_erbout` gained in between, so any interposed template text would
|
|
1284
1297
|
// leak into (or out of) the capture.
|
|
1285
|
-
const prevInLoop = this.inLoop
|
|
1286
|
-
this.inLoop = false
|
|
1287
1298
|
const childrenBody = this.renderChildren(effectiveChildren)
|
|
1288
|
-
this.inLoop = prevInLoop
|
|
1289
1299
|
const suffix = comp.slotId ?? `c${this.childrenCaptureCounter++}`
|
|
1290
1300
|
const lenVar = `__bf_len_${suffix}`
|
|
1291
1301
|
const capVar = `__bf_children_${suffix}`
|
package/src/conformance-pins.ts
CHANGED
|
@@ -16,11 +16,6 @@ export const conformancePins: ConformancePins = {
|
|
|
16
16
|
// JS-runtime target runs it, a DSL adapter surfaces BF021 + `/* @client */`.
|
|
17
17
|
// See spec/callback-fidelity.md.
|
|
18
18
|
'filter-typeof-predicate': [{ code: 'BF021', severity: 'error' }],
|
|
19
|
-
// A `.map()` body with a `const`/`let` preamble before its branches:
|
|
20
|
-
// a JS runtime folds it, a DSL adapter can't carry the loop-local into a
|
|
21
|
-
// conditional branch template, so it refuses with BF021 + `/* @client */`.
|
|
22
|
-
// See spec/callback-fidelity.md.
|
|
23
|
-
'map-preamble-branch-body': [{ code: 'BF021', severity: 'error' }],
|
|
24
19
|
'map-array-builder-body': [{ code: 'BF021', severity: 'error' }],
|
|
25
20
|
'map-array-builder-escaping': [{ code: 'BF021', severity: 'error' }],
|
|
26
21
|
// `.fill(value)` mutates the receiver in place — no template lowering
|
|
@@ -19,4 +19,15 @@ export const renderDivergences: RenderDivergences = {
|
|
|
19
19
|
// `evaluateSignalInit` (`@barefootjs/jsx`, sandboxed real-JS evaluation
|
|
20
20
|
// instead of a fixed regex-shape catalogue) now correctly seeds `todos`
|
|
21
21
|
// from `(props.initialTodos ?? []).map(t => ({ ...t, editing: false }))`.
|
|
22
|
+
|
|
23
|
+
// Onboarding TSX-fidelity fixtures (PR #2461): `expectedHtml` is
|
|
24
|
+
// hand-authored to the CORRECT output because the emission bug lives in
|
|
25
|
+
// the shared compiler layer — every adapter, including the Hono
|
|
26
|
+
// reference, currently emits the broken form (verified against this
|
|
27
|
+
// adapter's emitted template; see each fixture's docstring). Graduate
|
|
28
|
+
// by fixing the shared emission, regenerating `expectedHtml` from the
|
|
29
|
+
// fixed reference, and deleting these lines (and the matching hono
|
|
30
|
+
// `skipJsx` entries).
|
|
31
|
+
'aliased-destructured-prop':
|
|
32
|
+
'aliased destructured prop `{ n: count }` loses its rename — template vars, ssr-defaults, and the props bridge all key off the local name, so the prop is always undefined (https://github.com/piconic-ai/barefootjs/issues/2460)',
|
|
22
33
|
}
|