@barefootjs/mojolicious 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/index.js +9 -12
- package/dist/adapter/mojo-adapter.d.ts +0 -1
- package/dist/adapter/mojo-adapter.d.ts.map +1 -1
- package/dist/build.js +9 -12
- package/dist/conformance-pins.d.ts.map +1 -1
- package/dist/index.js +13 -14
- package/dist/render-divergences.d.ts.map +1 -1
- package/lib/BarefootJS/Backend/Mojo.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS/DevReload.pm +1 -1
- package/lib/Mojolicious/Plugin/BarefootJS.pm +1 -1
- package/package.json +3 -3
- package/src/__tests__/mojo-adapter.test.ts +6 -6
- package/src/adapter/mojo-adapter.ts +22 -13
- package/src/conformance-pins.ts +0 -5
- package/src/render-divergences.ts +13 -0
package/dist/adapter/index.js
CHANGED
|
@@ -24,7 +24,8 @@ import {
|
|
|
24
24
|
resolveDangerousInnerHtml,
|
|
25
25
|
dangerousInnerHtmlMetacharViolation,
|
|
26
26
|
dangerousInnerHtmlDiagnostic,
|
|
27
|
-
resolveStaticLoopSource
|
|
27
|
+
resolveStaticLoopSource,
|
|
28
|
+
derivesScopeFromSlot
|
|
28
29
|
} from "@barefootjs/jsx";
|
|
29
30
|
|
|
30
31
|
// src/adapter/boolean-result.ts
|
|
@@ -1046,7 +1047,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1046
1047
|
rootScopeNodes = new Set;
|
|
1047
1048
|
options;
|
|
1048
1049
|
errors = [];
|
|
1049
|
-
inLoop = false;
|
|
1050
1050
|
currentLoopKeyDepth = 0;
|
|
1051
1051
|
propsObjectName = null;
|
|
1052
1052
|
propsParams = [];
|
|
@@ -1436,16 +1436,16 @@ ${whenTrue}
|
|
|
1436
1436
|
const param = loop.param;
|
|
1437
1437
|
const indexVar = loop.iterationShape === "keys" ? `$${param}` : loop.index ? `$${loop.index}` : "$_i";
|
|
1438
1438
|
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"];
|
|
1439
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
1440
|
+
for (const d of preambleDecls)
|
|
1441
|
+
loopBound.push(d.name);
|
|
1439
1442
|
for (const n of loopBound) {
|
|
1440
1443
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
1441
1444
|
}
|
|
1442
|
-
const prevInLoop = this.inLoop;
|
|
1443
|
-
this.inLoop = true;
|
|
1444
1445
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
1445
1446
|
this.currentLoopKeyDepth = loop.depth;
|
|
1446
1447
|
const renderedChildren = this.renderChildren(loop.children);
|
|
1447
1448
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
1448
|
-
this.inLoop = prevInLoop;
|
|
1449
1449
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
1450
1450
|
${renderedChildren}` : renderedChildren;
|
|
1451
1451
|
const lines = [];
|
|
@@ -1505,6 +1505,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1505
1505
|
}
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
|
+
const preambleLines = preambleDecls.map((d) => `% my $${d.name} = ${this.convertExpressionToPerl(d.raw, d.valueParsed)};`);
|
|
1508
1509
|
if (loop.filterPredicate) {
|
|
1509
1510
|
let filterCond;
|
|
1510
1511
|
if (loop.filterPredicate.predicate) {
|
|
@@ -1516,9 +1517,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1516
1517
|
filterCond = filterCond.replace(new RegExp(`\\$${loop.filterPredicate.param}\\b`, "g"), `$${param}`);
|
|
1517
1518
|
}
|
|
1518
1519
|
lines.push(`% if (${filterCond}) {`);
|
|
1520
|
+
lines.push(...preambleLines);
|
|
1519
1521
|
lines.push(children);
|
|
1520
1522
|
lines.push(`% }`);
|
|
1521
1523
|
} else {
|
|
1524
|
+
lines.push(...preambleLines);
|
|
1522
1525
|
lines.push(children);
|
|
1523
1526
|
}
|
|
1524
1527
|
for (const n of loopBound) {
|
|
@@ -1562,10 +1565,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1562
1565
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
1563
1566
|
continue;
|
|
1564
1567
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
1565
|
-
const prevInLoop = this.inLoop;
|
|
1566
|
-
this.inLoop = false;
|
|
1567
1568
|
const slotBody = this.renderChildren(p.value.children);
|
|
1568
|
-
this.inLoop = prevInLoop;
|
|
1569
1569
|
const varName = `$bf_prop_${this.childrenCaptureCounter++}`;
|
|
1570
1570
|
namedSlotCaptures.push(`<% my ${varName} = begin %>${slotBody}<% end %>`);
|
|
1571
1571
|
propParts.push(`${perlHashKey(p.name)} => ${varName}`);
|
|
@@ -1575,17 +1575,14 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1575
1575
|
if (lowered)
|
|
1576
1576
|
propParts.push(lowered);
|
|
1577
1577
|
}
|
|
1578
|
-
if (comp
|
|
1578
|
+
if (derivesScopeFromSlot(comp)) {
|
|
1579
1579
|
propParts.push(`_bf_slot => '${comp.slotId}'`);
|
|
1580
1580
|
}
|
|
1581
1581
|
const propsStr = propParts.length > 0 ? ", " + propParts.join(", ") : "";
|
|
1582
1582
|
const tplName = this.toTemplateName(comp.name);
|
|
1583
1583
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
1584
1584
|
if (effectiveChildren.length > 0) {
|
|
1585
|
-
const prevInLoop = this.inLoop;
|
|
1586
|
-
this.inLoop = false;
|
|
1587
1585
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
1588
|
-
this.inLoop = prevInLoop;
|
|
1589
1586
|
const varName = `$bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
|
|
1590
1587
|
return `${namedSlotCaptures.join("")}<% my ${varName} = begin %>${childrenBody}<% end %><%== bf->render_child('${tplName}'${propsStr}, children => ${varName}) %>`;
|
|
1591
1588
|
}
|
|
@@ -35,7 +35,6 @@ export declare class MojoAdapter extends BaseAdapter implements IRNodeEmitter<Mo
|
|
|
35
35
|
private rootScopeNodes;
|
|
36
36
|
private options;
|
|
37
37
|
private errors;
|
|
38
|
-
private inLoop;
|
|
39
38
|
/**
|
|
40
39
|
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
41
40
|
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mojo-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/mojo-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,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,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAE3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"mojo-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/mojo-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/build.js
CHANGED
|
@@ -24,7 +24,8 @@ import {
|
|
|
24
24
|
resolveDangerousInnerHtml,
|
|
25
25
|
dangerousInnerHtmlMetacharViolation,
|
|
26
26
|
dangerousInnerHtmlDiagnostic,
|
|
27
|
-
resolveStaticLoopSource
|
|
27
|
+
resolveStaticLoopSource,
|
|
28
|
+
derivesScopeFromSlot
|
|
28
29
|
} from "@barefootjs/jsx";
|
|
29
30
|
|
|
30
31
|
// src/adapter/boolean-result.ts
|
|
@@ -1046,7 +1047,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1046
1047
|
rootScopeNodes = new Set;
|
|
1047
1048
|
options;
|
|
1048
1049
|
errors = [];
|
|
1049
|
-
inLoop = false;
|
|
1050
1050
|
currentLoopKeyDepth = 0;
|
|
1051
1051
|
propsObjectName = null;
|
|
1052
1052
|
propsParams = [];
|
|
@@ -1436,16 +1436,16 @@ ${whenTrue}
|
|
|
1436
1436
|
const param = loop.param;
|
|
1437
1437
|
const indexVar = loop.iterationShape === "keys" ? `$${param}` : loop.index ? `$${loop.index}` : "$_i";
|
|
1438
1438
|
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"];
|
|
1439
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
1440
|
+
for (const d of preambleDecls)
|
|
1441
|
+
loopBound.push(d.name);
|
|
1439
1442
|
for (const n of loopBound) {
|
|
1440
1443
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
1441
1444
|
}
|
|
1442
|
-
const prevInLoop = this.inLoop;
|
|
1443
|
-
this.inLoop = true;
|
|
1444
1445
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
1445
1446
|
this.currentLoopKeyDepth = loop.depth;
|
|
1446
1447
|
const renderedChildren = this.renderChildren(loop.children);
|
|
1447
1448
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
1448
|
-
this.inLoop = prevInLoop;
|
|
1449
1449
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
1450
1450
|
${renderedChildren}` : renderedChildren;
|
|
1451
1451
|
const lines = [];
|
|
@@ -1505,6 +1505,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1505
1505
|
}
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
|
+
const preambleLines = preambleDecls.map((d) => `% my $${d.name} = ${this.convertExpressionToPerl(d.raw, d.valueParsed)};`);
|
|
1508
1509
|
if (loop.filterPredicate) {
|
|
1509
1510
|
let filterCond;
|
|
1510
1511
|
if (loop.filterPredicate.predicate) {
|
|
@@ -1516,9 +1517,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1516
1517
|
filterCond = filterCond.replace(new RegExp(`\\$${loop.filterPredicate.param}\\b`, "g"), `$${param}`);
|
|
1517
1518
|
}
|
|
1518
1519
|
lines.push(`% if (${filterCond}) {`);
|
|
1520
|
+
lines.push(...preambleLines);
|
|
1519
1521
|
lines.push(children);
|
|
1520
1522
|
lines.push(`% }`);
|
|
1521
1523
|
} else {
|
|
1524
|
+
lines.push(...preambleLines);
|
|
1522
1525
|
lines.push(children);
|
|
1523
1526
|
}
|
|
1524
1527
|
for (const n of loopBound) {
|
|
@@ -1562,10 +1565,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1562
1565
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
1563
1566
|
continue;
|
|
1564
1567
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
1565
|
-
const prevInLoop = this.inLoop;
|
|
1566
|
-
this.inLoop = false;
|
|
1567
1568
|
const slotBody = this.renderChildren(p.value.children);
|
|
1568
|
-
this.inLoop = prevInLoop;
|
|
1569
1569
|
const varName = `$bf_prop_${this.childrenCaptureCounter++}`;
|
|
1570
1570
|
namedSlotCaptures.push(`<% my ${varName} = begin %>${slotBody}<% end %>`);
|
|
1571
1571
|
propParts.push(`${perlHashKey(p.name)} => ${varName}`);
|
|
@@ -1575,17 +1575,14 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1575
1575
|
if (lowered)
|
|
1576
1576
|
propParts.push(lowered);
|
|
1577
1577
|
}
|
|
1578
|
-
if (comp
|
|
1578
|
+
if (derivesScopeFromSlot(comp)) {
|
|
1579
1579
|
propParts.push(`_bf_slot => '${comp.slotId}'`);
|
|
1580
1580
|
}
|
|
1581
1581
|
const propsStr = propParts.length > 0 ? ", " + propParts.join(", ") : "";
|
|
1582
1582
|
const tplName = this.toTemplateName(comp.name);
|
|
1583
1583
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
1584
1584
|
if (effectiveChildren.length > 0) {
|
|
1585
|
-
const prevInLoop = this.inLoop;
|
|
1586
|
-
this.inLoop = false;
|
|
1587
1585
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
1588
|
-
this.inLoop = prevInLoop;
|
|
1589
1586
|
const varName = `$bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
|
|
1590
1587
|
return `${namedSlotCaptures.join("")}<% my ${varName} = begin %>${childrenBody}<% end %><%== bf->render_child('${tplName}'${propsStr}, children => ${varName}) %>`;
|
|
1591
1588
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"conformance-pins.d.ts","sourceRoot":"","sources":["../src/conformance-pins.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,eAAO,MAAM,eAAe,EAAE,eAmL7B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,8 @@ import {
|
|
|
24
24
|
resolveDangerousInnerHtml,
|
|
25
25
|
dangerousInnerHtmlMetacharViolation,
|
|
26
26
|
dangerousInnerHtmlDiagnostic,
|
|
27
|
-
resolveStaticLoopSource
|
|
27
|
+
resolveStaticLoopSource,
|
|
28
|
+
derivesScopeFromSlot
|
|
28
29
|
} from "@barefootjs/jsx";
|
|
29
30
|
|
|
30
31
|
// src/adapter/boolean-result.ts
|
|
@@ -1046,7 +1047,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1046
1047
|
rootScopeNodes = new Set;
|
|
1047
1048
|
options;
|
|
1048
1049
|
errors = [];
|
|
1049
|
-
inLoop = false;
|
|
1050
1050
|
currentLoopKeyDepth = 0;
|
|
1051
1051
|
propsObjectName = null;
|
|
1052
1052
|
propsParams = [];
|
|
@@ -1436,16 +1436,16 @@ ${whenTrue}
|
|
|
1436
1436
|
const param = loop.param;
|
|
1437
1437
|
const indexVar = loop.iterationShape === "keys" ? `$${param}` : loop.index ? `$${loop.index}` : "$_i";
|
|
1438
1438
|
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"];
|
|
1439
|
+
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
1440
|
+
for (const d of preambleDecls)
|
|
1441
|
+
loopBound.push(d.name);
|
|
1439
1442
|
for (const n of loopBound) {
|
|
1440
1443
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1);
|
|
1441
1444
|
}
|
|
1442
|
-
const prevInLoop = this.inLoop;
|
|
1443
|
-
this.inLoop = true;
|
|
1444
1445
|
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
1445
1446
|
this.currentLoopKeyDepth = loop.depth;
|
|
1446
1447
|
const renderedChildren = this.renderChildren(loop.children);
|
|
1447
1448
|
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
1448
|
-
this.inLoop = prevInLoop;
|
|
1449
1449
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
1450
1450
|
${renderedChildren}` : renderedChildren;
|
|
1451
1451
|
const lines = [];
|
|
@@ -1505,6 +1505,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1505
1505
|
}
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
|
+
const preambleLines = preambleDecls.map((d) => `% my $${d.name} = ${this.convertExpressionToPerl(d.raw, d.valueParsed)};`);
|
|
1508
1509
|
if (loop.filterPredicate) {
|
|
1509
1510
|
let filterCond;
|
|
1510
1511
|
if (loop.filterPredicate.predicate) {
|
|
@@ -1516,9 +1517,11 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1516
1517
|
filterCond = filterCond.replace(new RegExp(`\\$${loop.filterPredicate.param}\\b`, "g"), `$${param}`);
|
|
1517
1518
|
}
|
|
1518
1519
|
lines.push(`% if (${filterCond}) {`);
|
|
1520
|
+
lines.push(...preambleLines);
|
|
1519
1521
|
lines.push(children);
|
|
1520
1522
|
lines.push(`% }`);
|
|
1521
1523
|
} else {
|
|
1524
|
+
lines.push(...preambleLines);
|
|
1522
1525
|
lines.push(children);
|
|
1523
1526
|
}
|
|
1524
1527
|
for (const n of loopBound) {
|
|
@@ -1562,10 +1565,7 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1562
1565
|
if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
|
|
1563
1566
|
continue;
|
|
1564
1567
|
if (p.value.kind === "jsx-children" && p.name !== "children") {
|
|
1565
|
-
const prevInLoop = this.inLoop;
|
|
1566
|
-
this.inLoop = false;
|
|
1567
1568
|
const slotBody = this.renderChildren(p.value.children);
|
|
1568
|
-
this.inLoop = prevInLoop;
|
|
1569
1569
|
const varName = `$bf_prop_${this.childrenCaptureCounter++}`;
|
|
1570
1570
|
namedSlotCaptures.push(`<% my ${varName} = begin %>${slotBody}<% end %>`);
|
|
1571
1571
|
propParts.push(`${perlHashKey(p.name)} => ${varName}`);
|
|
@@ -1575,17 +1575,14 @@ ${renderedChildren}` : renderedChildren;
|
|
|
1575
1575
|
if (lowered)
|
|
1576
1576
|
propParts.push(lowered);
|
|
1577
1577
|
}
|
|
1578
|
-
if (comp
|
|
1578
|
+
if (derivesScopeFromSlot(comp)) {
|
|
1579
1579
|
propParts.push(`_bf_slot => '${comp.slotId}'`);
|
|
1580
1580
|
}
|
|
1581
1581
|
const propsStr = propParts.length > 0 ? ", " + propParts.join(", ") : "";
|
|
1582
1582
|
const tplName = this.toTemplateName(comp.name);
|
|
1583
1583
|
const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
|
|
1584
1584
|
if (effectiveChildren.length > 0) {
|
|
1585
|
-
const prevInLoop = this.inLoop;
|
|
1586
|
-
this.inLoop = false;
|
|
1587
1585
|
const childrenBody = this.renderChildren(effectiveChildren);
|
|
1588
|
-
this.inLoop = prevInLoop;
|
|
1589
1586
|
const varName = `$bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
|
|
1590
1587
|
return `${namedSlotCaptures.join("")}<% my ${varName} = begin %>${childrenBody}<% end %><%== bf->render_child('${tplName}'${propsStr}, children => ${varName}) %>`;
|
|
1591
1588
|
}
|
|
@@ -1913,7 +1910,6 @@ var mojoAdapter = new MojoAdapter;
|
|
|
1913
1910
|
// src/conformance-pins.ts
|
|
1914
1911
|
var conformancePins = {
|
|
1915
1912
|
"filter-typeof-predicate": [{ code: "BF021", severity: "error" }],
|
|
1916
|
-
"map-preamble-branch-body": [{ code: "BF021", severity: "error" }],
|
|
1917
1913
|
"map-array-builder-body": [{ code: "BF021", severity: "error" }],
|
|
1918
1914
|
"map-array-builder-escaping": [{ code: "BF021", severity: "error" }],
|
|
1919
1915
|
"fill-unsupported": [{ code: "BF101", severity: "error" }],
|
|
@@ -1937,7 +1933,10 @@ var conformancePins = {
|
|
|
1937
1933
|
"date-method-uncatalogued": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2356" }]
|
|
1938
1934
|
};
|
|
1939
1935
|
// src/render-divergences.ts
|
|
1940
|
-
var renderDivergences = {
|
|
1936
|
+
var renderDivergences = {
|
|
1937
|
+
"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)",
|
|
1938
|
+
"composite-row-child-aliased-prop": "same #2460 defect as `aliased-destructured-prop`, inside a keyed `.map()` loop row: the nested child's renamed prop (`{ n: count }`) is always undefined, so both rows render an empty count (https://github.com/piconic-ai/barefootjs/issues/2460)"
|
|
1939
|
+
};
|
|
1941
1940
|
export {
|
|
1942
1941
|
renderDivergences,
|
|
1943
1942
|
mojoAdapter,
|
|
@@ -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,iBAkB/B,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/mojolicious",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Mojolicious EP template adapter for BarefootJS - generates .html.ep files from IR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"directory": "packages/adapter-mojolicious"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@barefootjs/shared": "0.
|
|
55
|
+
"@barefootjs/shared": "0.30.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -60,6 +60,6 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
63
|
-
"@barefootjs/jsx": "0.
|
|
63
|
+
"@barefootjs/jsx": "0.30.0"
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -488,14 +488,14 @@ function C({ rows }: { rows?: number }) {
|
|
|
488
488
|
|
|
489
489
|
test('leaves a defaulted attr unconditional (scope did not widen)', () => {
|
|
490
490
|
const { template } = compileAndGenerate(`
|
|
491
|
-
function C({
|
|
492
|
-
return <textarea
|
|
491
|
+
function C({ placeholder = '' }: { placeholder?: string }) {
|
|
492
|
+
return <textarea placeholder={placeholder} />
|
|
493
493
|
}
|
|
494
494
|
`)
|
|
495
|
-
// `
|
|
496
|
-
// exactly like Hono's
|
|
497
|
-
expect(template).toContain('
|
|
498
|
-
expect(template).not.toContain('defined $
|
|
495
|
+
// `placeholder` has a destructure default → never undef → unconditional,
|
|
496
|
+
// exactly like Hono's placeholder="".
|
|
497
|
+
expect(template).toContain('placeholder="<%= $placeholder %>"')
|
|
498
|
+
expect(template).not.toContain('defined $placeholder')
|
|
499
499
|
})
|
|
500
500
|
})
|
|
501
501
|
|
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
dangerousInnerHtmlMetacharViolation,
|
|
65
65
|
dangerousInnerHtmlDiagnostic,
|
|
66
66
|
resolveStaticLoopSource,
|
|
67
|
+
derivesScopeFromSlot,
|
|
67
68
|
} from '@barefootjs/jsx'
|
|
68
69
|
import { isAriaBooleanAttr, isBooleanResultExpr } from './boolean-result.ts'
|
|
69
70
|
import type { ParsedExpr, LoweringMatcher } from '@barefootjs/jsx'
|
|
@@ -170,7 +171,6 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
170
171
|
private rootScopeNodes: Set<IRNode> = new Set()
|
|
171
172
|
private options: Required<MojoAdapterOptions>
|
|
172
173
|
private errors: CompilerError[] = []
|
|
173
|
-
private inLoop: boolean = false
|
|
174
174
|
/**
|
|
175
175
|
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
176
176
|
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
@@ -936,16 +936,19 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
936
936
|
: supportableDestructure
|
|
937
937
|
? ['__bf_item', ...(loop.paramBindings ?? []).map(b => b.name), loop.index ?? '_i']
|
|
938
938
|
: [param, loop.index ?? '_i']
|
|
939
|
+
// A `.map()` callback preamble lowers to one per-row `my` local per
|
|
940
|
+
// declaration (#2447). Loop-binding the names keeps a same-named module
|
|
941
|
+
// const from inlining over the local the loop just declared — the same
|
|
942
|
+
// hazard class `resolveModuleStringConst` already consults this map for.
|
|
943
|
+
const preambleDecls = loop.preamble?.declarations ?? []
|
|
944
|
+
for (const d of preambleDecls) loopBound.push(d.name)
|
|
939
945
|
for (const n of loopBound) {
|
|
940
946
|
this.loopBoundNames.set(n, (this.loopBoundNames.get(n) ?? 0) + 1)
|
|
941
947
|
}
|
|
942
|
-
const prevInLoop = this.inLoop
|
|
943
|
-
this.inLoop = true
|
|
944
948
|
const prevLoopKeyDepth = this.currentLoopKeyDepth
|
|
945
949
|
this.currentLoopKeyDepth = loop.depth
|
|
946
950
|
const renderedChildren = this.renderChildren(loop.children)
|
|
947
951
|
this.currentLoopKeyDepth = prevLoopKeyDepth
|
|
948
|
-
this.inLoop = prevInLoop
|
|
949
952
|
|
|
950
953
|
// Whole-item conditional (#1665): prepend an always-present
|
|
951
954
|
// `<!--bf-loop-i:KEY-->` anchor before each item's (possibly empty)
|
|
@@ -1056,6 +1059,15 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1056
1059
|
}
|
|
1057
1060
|
}
|
|
1058
1061
|
|
|
1062
|
+
// Per-row preamble locals (#2447), in source order so a later
|
|
1063
|
+
// initializer sees an earlier local — same as the source block. Emitted
|
|
1064
|
+
// INSIDE the filter guard below, matching JS evaluation order: a
|
|
1065
|
+
// `.filter(p).map(cb)` chain never runs `cb`'s body for a filtered-out
|
|
1066
|
+
// item.
|
|
1067
|
+
const preambleLines = preambleDecls.map(
|
|
1068
|
+
d => `% my $${d.name} = ${this.convertExpressionToPerl(d.raw, d.valueParsed)};`,
|
|
1069
|
+
)
|
|
1070
|
+
|
|
1059
1071
|
// Handle filter().map() pattern by wrapping children in if-condition
|
|
1060
1072
|
if (loop.filterPredicate) {
|
|
1061
1073
|
let filterCond: string
|
|
@@ -1075,9 +1087,11 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1075
1087
|
)
|
|
1076
1088
|
}
|
|
1077
1089
|
lines.push(`% if (${filterCond}) {`)
|
|
1090
|
+
lines.push(...preambleLines)
|
|
1078
1091
|
lines.push(children)
|
|
1079
1092
|
lines.push(`% }`)
|
|
1080
1093
|
} else {
|
|
1094
|
+
lines.push(...preambleLines)
|
|
1081
1095
|
lines.push(children)
|
|
1082
1096
|
}
|
|
1083
1097
|
|
|
@@ -1168,10 +1182,7 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1168
1182
|
// SSR (Hono renders neither; the client JS wires them at hydration).
|
|
1169
1183
|
if ((p.name.match(/^on[A-Z]/) || p.name === 'ref') && p.value.kind === 'expression') continue
|
|
1170
1184
|
if (p.value.kind === 'jsx-children' && p.name !== 'children') {
|
|
1171
|
-
const prevInLoop = this.inLoop
|
|
1172
|
-
this.inLoop = false
|
|
1173
1185
|
const slotBody = this.renderChildren(p.value.children)
|
|
1174
|
-
this.inLoop = prevInLoop
|
|
1175
1186
|
// Purely counter-based — NOT derived from `p.name` or `comp.slotId`.
|
|
1176
1187
|
// A JSX prop name can contain characters (`data-slot`) that aren't a
|
|
1177
1188
|
// valid Perl variable token, and `comp.slotId` alone would collide
|
|
@@ -1186,9 +1197,10 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1186
1197
|
const lowered = emitAttrValue(p.value, this.componentPropEmitter, p.name)
|
|
1187
1198
|
if (lowered) propParts.push(lowered)
|
|
1188
1199
|
}
|
|
1189
|
-
// Pass slot ID so the child renderer can set correct scope ID for
|
|
1190
|
-
//
|
|
1191
|
-
|
|
1200
|
+
// Pass slot ID so the child renderer can set correct scope ID for
|
|
1201
|
+
// hydration. Skipped for a loop item root — it uses ComponentName_random
|
|
1202
|
+
// instead (#2444).
|
|
1203
|
+
if (derivesScopeFromSlot(comp)) {
|
|
1192
1204
|
propParts.push(`_bf_slot => '${comp.slotId}'`)
|
|
1193
1205
|
}
|
|
1194
1206
|
const propsStr = propParts.length > 0 ? ', ' + propParts.join(', ') : ''
|
|
@@ -1215,10 +1227,7 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1215
1227
|
// `render_child` would let the inner `%>` close the outer tag.
|
|
1216
1228
|
// `render_child` materializes the resulting CODE ref into the
|
|
1217
1229
|
// captured Mojo::ByteStream.
|
|
1218
|
-
const prevInLoop = this.inLoop
|
|
1219
|
-
this.inLoop = false
|
|
1220
1230
|
const childrenBody = this.renderChildren(effectiveChildren)
|
|
1221
|
-
this.inLoop = prevInLoop
|
|
1222
1231
|
const varName = `$bf_children_${comp.slotId ?? 'c' + this.childrenCaptureCounter++}`
|
|
1223
1232
|
return `${namedSlotCaptures.join('')}<% my ${varName} = begin %>${childrenBody}<% end %><%== bf->render_child('${tplName}'${propsStr}, children => ${varName}) %>`
|
|
1224
1233
|
}
|
package/src/conformance-pins.ts
CHANGED
|
@@ -13,11 +13,6 @@ export const conformancePins: ConformancePins = {
|
|
|
13
13
|
// JS-runtime target runs it, a DSL adapter surfaces BF021 + `/* @client */`.
|
|
14
14
|
// See spec/callback-fidelity.md.
|
|
15
15
|
'filter-typeof-predicate': [{ code: 'BF021', severity: 'error' }],
|
|
16
|
-
// A `.map()` body with a `const`/`let` preamble before its branches:
|
|
17
|
-
// a JS runtime folds it, a DSL adapter can't carry the loop-local into a
|
|
18
|
-
// conditional branch template, so it refuses with BF021 + `/* @client */`.
|
|
19
|
-
// See spec/callback-fidelity.md.
|
|
20
|
-
'map-preamble-branch-body': [{ code: 'BF021', severity: 'error' }],
|
|
21
16
|
'map-array-builder-body': [{ code: 'BF021', severity: 'error' }],
|
|
22
17
|
'map-array-builder-escaping': [{ code: 'BF021', severity: 'error' }],
|
|
23
18
|
// `.fill(value)` mutates the receiver in place — no template lowering
|
|
@@ -19,4 +19,17 @@ 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)',
|
|
33
|
+
'composite-row-child-aliased-prop':
|
|
34
|
+
'same #2460 defect as `aliased-destructured-prop`, inside a keyed `.map()` loop row: the nested child\'s renamed prop (`{ n: count }`) is always undefined, so both rows render an empty count (https://github.com/piconic-ai/barefootjs/issues/2460)',
|
|
22
35
|
}
|