@barefootjs/mojolicious 0.33.1 → 0.33.3
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 +12 -50
- package/dist/adapter/mojo-adapter.d.ts +0 -14
- package/dist/adapter/mojo-adapter.d.ts.map +1 -1
- package/dist/index.js +15 -51
- package/dist/render-divergences.d.ts.map +1 -1
- package/dist/vite.js +103 -125
- 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 +5 -5
- package/src/adapter/mojo-adapter.ts +34 -44
- package/src/render-divergences.ts +14 -1
- package/dist/adapter/lib/ir-scope.d.ts +0 -33
- package/dist/adapter/lib/ir-scope.d.ts.map +0 -1
- package/src/adapter/lib/ir-scope.ts +0 -57
package/dist/adapter/index.js
CHANGED
|
@@ -84,7 +84,7 @@ function isAriaBooleanAttr(name) {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
// src/adapter/mojo-adapter.ts
|
|
87
|
-
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from "@barefootjs/shared";
|
|
87
|
+
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
|
|
88
88
|
|
|
89
89
|
// src/adapter/lib/constants.ts
|
|
90
90
|
var MOJO_TEMPLATE_PRIMITIVES = {
|
|
@@ -112,39 +112,6 @@ function perlIdentifierFromMarkerId(markerId) {
|
|
|
112
112
|
return markerId.replace(/[^a-zA-Z0-9]/g, (ch) => ch === "_" ? "__" : `_x${ch.charCodeAt(0).toString(16)}`);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// src/adapter/lib/ir-scope.ts
|
|
116
|
-
function resolveJsxChildrenProp(props) {
|
|
117
|
-
const prop = props.find((p) => p.name === "children");
|
|
118
|
-
if (!prop)
|
|
119
|
-
return [];
|
|
120
|
-
if (prop.value.kind !== "jsx-children")
|
|
121
|
-
return [];
|
|
122
|
-
return prop.value.children;
|
|
123
|
-
}
|
|
124
|
-
function collectRootScopeNodes(node) {
|
|
125
|
-
const out = new Set;
|
|
126
|
-
const visit = (n) => {
|
|
127
|
-
if (!n)
|
|
128
|
-
return;
|
|
129
|
-
if (n.type === "element") {
|
|
130
|
-
out.add(n);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
if (n.type === "if-statement") {
|
|
134
|
-
const s = n;
|
|
135
|
-
visit(s.consequent);
|
|
136
|
-
visit(s.alternate);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (n.type === "fragment") {
|
|
140
|
-
for (const c of n.children)
|
|
141
|
-
visit(c);
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
visit(node);
|
|
145
|
-
return out;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
115
|
// src/adapter/expr/array-method.ts
|
|
149
116
|
import {
|
|
150
117
|
serializeParsedExpr,
|
|
@@ -1051,10 +1018,8 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1051
1018
|
templatesPerComponent = true;
|
|
1052
1019
|
templatePrimitives = MOJO_PRIMITIVE_EMIT_MAP;
|
|
1053
1020
|
componentName = "";
|
|
1054
|
-
rootScopeNodes = new Set;
|
|
1055
1021
|
options;
|
|
1056
1022
|
errors = [];
|
|
1057
|
-
currentLoopKeyDepth = 0;
|
|
1058
1023
|
propsObjectName = null;
|
|
1059
1024
|
propsParams = [];
|
|
1060
1025
|
booleanTypedProps = new Set;
|
|
@@ -1092,7 +1057,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1092
1057
|
if (!options?.siblingTemplatesRegistered) {
|
|
1093
1058
|
this.errors.push(...collectImportedLoopChildComponentErrors(ir, this.componentName));
|
|
1094
1059
|
}
|
|
1095
|
-
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
1096
1060
|
const templateBody = ir.root.type === "if-statement" ? this.renderIfStatement(ir.root) : this.renderNode(ir.root);
|
|
1097
1061
|
const scriptReg = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName, options?.scriptAssets, options?.preloadAssets);
|
|
1098
1062
|
const ctxSeed = generateContextConsumerSeed(ir);
|
|
@@ -1273,8 +1237,14 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1273
1237
|
if (element.needsScope) {
|
|
1274
1238
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
1275
1239
|
}
|
|
1276
|
-
if (
|
|
1277
|
-
|
|
1240
|
+
if (element.keyAttr) {
|
|
1241
|
+
if (element.keyAttr.value !== undefined) {
|
|
1242
|
+
const lowered = emitAttrValue({ kind: "expression", expr: element.keyAttr.value }, this.elementAttrEmitter, element.keyAttr.name);
|
|
1243
|
+
if (lowered)
|
|
1244
|
+
hydrationAttrs += ` ${lowered}`;
|
|
1245
|
+
} else {
|
|
1246
|
+
hydrationAttrs += ` <%== bf->data_key_attr %>`;
|
|
1247
|
+
}
|
|
1278
1248
|
}
|
|
1279
1249
|
if (element.slotId) {
|
|
1280
1250
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
@@ -1455,10 +1425,7 @@ ${whenTrue}
|
|
|
1455
1425
|
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
1456
1426
|
const prevScope = this.scope;
|
|
1457
1427
|
this.scope = prevScope.enterLoopRow(loop);
|
|
1458
|
-
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
1459
|
-
this.currentLoopKeyDepth = loop.depth;
|
|
1460
1428
|
const renderedChildren = this.renderChildren(loop.children);
|
|
1461
|
-
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
1462
1429
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
1463
1430
|
${renderedChildren}` : renderedChildren;
|
|
1464
1431
|
const lines = [];
|
|
@@ -1724,14 +1691,9 @@ ${children}`;
|
|
|
1724
1691
|
continue;
|
|
1725
1692
|
if (isDangerousInnerHtmlAttr(attr))
|
|
1726
1693
|
continue;
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
else if (attr.name === "key") {
|
|
1731
|
-
const depth = this.currentLoopKeyDepth;
|
|
1732
|
-
attrName = depth > 0 ? `data-key-${depth}` : "data-key";
|
|
1733
|
-
} else
|
|
1734
|
-
attrName = attr.name;
|
|
1694
|
+
if (attr.name === "key")
|
|
1695
|
+
continue;
|
|
1696
|
+
const attrName = attr.name === "className" ? "class" : attr.name;
|
|
1735
1697
|
const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
|
|
1736
1698
|
if (lowered)
|
|
1737
1699
|
parts.push(lowered);
|
|
@@ -26,22 +26,8 @@ export declare class MojoAdapter extends BaseAdapter implements IRNodeEmitter<Mo
|
|
|
26
26
|
*/
|
|
27
27
|
templatePrimitives: TemplatePrimitiveRegistry;
|
|
28
28
|
private componentName;
|
|
29
|
-
/** The component's root scope element(s) — each carries `data-key` for a
|
|
30
|
-
* keyed loop item (set by the child renderer from the JSX `key` prop). A
|
|
31
|
-
* plain element root is a single node; an `if-statement` (early-return) root
|
|
32
|
-
* contributes the top element of every branch, since any one of them can be
|
|
33
|
-
* the rendered root at runtime. */
|
|
34
|
-
private rootScopeNodes;
|
|
35
29
|
private options;
|
|
36
30
|
private errors;
|
|
37
|
-
/**
|
|
38
|
-
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
39
|
-
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
40
|
-
* `renderAttributes` reads this to derive the `key` → `data-key`/
|
|
41
|
-
* `data-key-N` suffix — the depth is IR-computed (jsx-to-ir.ts), not
|
|
42
|
-
* re-derived here (#2168 nested-loop-outer-binding).
|
|
43
|
-
*/
|
|
44
|
-
private currentLoopKeyDepth;
|
|
45
31
|
/**
|
|
46
32
|
* SolidJS-style props identifier (`function(props: P)`) and the
|
|
47
33
|
* analyzer-extracted prop names. Stashed at `generate()` entry so
|
|
@@ -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,EAiChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"mojo-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/mojo-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -84,7 +84,7 @@ function isAriaBooleanAttr(name) {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
// src/adapter/mojo-adapter.ts
|
|
87
|
-
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from "@barefootjs/shared";
|
|
87
|
+
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml, resolveJsxChildrenProp } from "@barefootjs/shared";
|
|
88
88
|
|
|
89
89
|
// src/adapter/lib/constants.ts
|
|
90
90
|
var MOJO_TEMPLATE_PRIMITIVES = {
|
|
@@ -112,39 +112,6 @@ function perlIdentifierFromMarkerId(markerId) {
|
|
|
112
112
|
return markerId.replace(/[^a-zA-Z0-9]/g, (ch) => ch === "_" ? "__" : `_x${ch.charCodeAt(0).toString(16)}`);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// src/adapter/lib/ir-scope.ts
|
|
116
|
-
function resolveJsxChildrenProp(props) {
|
|
117
|
-
const prop = props.find((p) => p.name === "children");
|
|
118
|
-
if (!prop)
|
|
119
|
-
return [];
|
|
120
|
-
if (prop.value.kind !== "jsx-children")
|
|
121
|
-
return [];
|
|
122
|
-
return prop.value.children;
|
|
123
|
-
}
|
|
124
|
-
function collectRootScopeNodes(node) {
|
|
125
|
-
const out = new Set;
|
|
126
|
-
const visit = (n) => {
|
|
127
|
-
if (!n)
|
|
128
|
-
return;
|
|
129
|
-
if (n.type === "element") {
|
|
130
|
-
out.add(n);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
if (n.type === "if-statement") {
|
|
134
|
-
const s = n;
|
|
135
|
-
visit(s.consequent);
|
|
136
|
-
visit(s.alternate);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (n.type === "fragment") {
|
|
140
|
-
for (const c of n.children)
|
|
141
|
-
visit(c);
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
visit(node);
|
|
145
|
-
return out;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
115
|
// src/adapter/expr/array-method.ts
|
|
149
116
|
import {
|
|
150
117
|
serializeParsedExpr,
|
|
@@ -1051,10 +1018,8 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1051
1018
|
templatesPerComponent = true;
|
|
1052
1019
|
templatePrimitives = MOJO_PRIMITIVE_EMIT_MAP;
|
|
1053
1020
|
componentName = "";
|
|
1054
|
-
rootScopeNodes = new Set;
|
|
1055
1021
|
options;
|
|
1056
1022
|
errors = [];
|
|
1057
|
-
currentLoopKeyDepth = 0;
|
|
1058
1023
|
propsObjectName = null;
|
|
1059
1024
|
propsParams = [];
|
|
1060
1025
|
booleanTypedProps = new Set;
|
|
@@ -1092,7 +1057,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1092
1057
|
if (!options?.siblingTemplatesRegistered) {
|
|
1093
1058
|
this.errors.push(...collectImportedLoopChildComponentErrors(ir, this.componentName));
|
|
1094
1059
|
}
|
|
1095
|
-
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
1096
1060
|
const templateBody = ir.root.type === "if-statement" ? this.renderIfStatement(ir.root) : this.renderNode(ir.root);
|
|
1097
1061
|
const scriptReg = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName, options?.scriptAssets, options?.preloadAssets);
|
|
1098
1062
|
const ctxSeed = generateContextConsumerSeed(ir);
|
|
@@ -1273,8 +1237,14 @@ class MojoAdapter extends BaseAdapter {
|
|
|
1273
1237
|
if (element.needsScope) {
|
|
1274
1238
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
1275
1239
|
}
|
|
1276
|
-
if (
|
|
1277
|
-
|
|
1240
|
+
if (element.keyAttr) {
|
|
1241
|
+
if (element.keyAttr.value !== undefined) {
|
|
1242
|
+
const lowered = emitAttrValue({ kind: "expression", expr: element.keyAttr.value }, this.elementAttrEmitter, element.keyAttr.name);
|
|
1243
|
+
if (lowered)
|
|
1244
|
+
hydrationAttrs += ` ${lowered}`;
|
|
1245
|
+
} else {
|
|
1246
|
+
hydrationAttrs += ` <%== bf->data_key_attr %>`;
|
|
1247
|
+
}
|
|
1278
1248
|
}
|
|
1279
1249
|
if (element.slotId) {
|
|
1280
1250
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
@@ -1455,10 +1425,7 @@ ${whenTrue}
|
|
|
1455
1425
|
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
1456
1426
|
const prevScope = this.scope;
|
|
1457
1427
|
this.scope = prevScope.enterLoopRow(loop);
|
|
1458
|
-
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
1459
|
-
this.currentLoopKeyDepth = loop.depth;
|
|
1460
1428
|
const renderedChildren = this.renderChildren(loop.children);
|
|
1461
|
-
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
1462
1429
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
1463
1430
|
${renderedChildren}` : renderedChildren;
|
|
1464
1431
|
const lines = [];
|
|
@@ -1724,14 +1691,9 @@ ${children}`;
|
|
|
1724
1691
|
continue;
|
|
1725
1692
|
if (isDangerousInnerHtmlAttr(attr))
|
|
1726
1693
|
continue;
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
else if (attr.name === "key") {
|
|
1731
|
-
const depth = this.currentLoopKeyDepth;
|
|
1732
|
-
attrName = depth > 0 ? `data-key-${depth}` : "data-key";
|
|
1733
|
-
} else
|
|
1734
|
-
attrName = attr.name;
|
|
1694
|
+
if (attr.name === "key")
|
|
1695
|
+
continue;
|
|
1696
|
+
const attrName = attr.name === "className" ? "class" : attr.name;
|
|
1735
1697
|
const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
|
|
1736
1698
|
if (lowered)
|
|
1737
1699
|
parts.push(lowered);
|
|
@@ -1941,7 +1903,9 @@ var conformancePins = {
|
|
|
1941
1903
|
"jsx-element-prop-array": [{ code: "BF021", severity: "error", issue: "https://github.com/piconic-ai/barefootjs/issues/2667" }]
|
|
1942
1904
|
};
|
|
1943
1905
|
// src/render-divergences.ts
|
|
1944
|
-
var renderDivergences = {
|
|
1906
|
+
var renderDivergences = {
|
|
1907
|
+
"children-passthrough-renamed": "A renamed `children` destructure emits the local alias as a template variable; the stash defines only `children`, so the Perl render dies (#2788)."
|
|
1908
|
+
};
|
|
1945
1909
|
export {
|
|
1946
1910
|
renderDivergences,
|
|
1947
1911
|
mojoAdapter,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAkBxD,eAAO,MAAM,iBAAiB,EAAE,iBAG/B,CAAA"}
|
package/dist/vite.js
CHANGED
|
@@ -5,7 +5,7 @@ import { barefoot as coreBarefoot } from "@barefootjs/vite";
|
|
|
5
5
|
import { devModuleUrl, loadManifest, resolveDevOrigin, resolveScriptAssets, toPosixRelative } from "@barefootjs/vite";
|
|
6
6
|
|
|
7
7
|
// ../jsx/src/compiler.ts
|
|
8
|
-
import
|
|
8
|
+
import ts25 from "typescript";
|
|
9
9
|
|
|
10
10
|
// ../jsx/src/analyzer.ts
|
|
11
11
|
import ts9 from "typescript";
|
|
@@ -2082,6 +2082,15 @@ function isBooleanAttr(name) {
|
|
|
2082
2082
|
function escapeHtml(text) {
|
|
2083
2083
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2084
2084
|
}
|
|
2085
|
+
// ../shared/src/jsx-children-prop.ts
|
|
2086
|
+
function resolveJsxChildrenProp(props) {
|
|
2087
|
+
const prop = props.find((p) => p.name === "children");
|
|
2088
|
+
if (!prop)
|
|
2089
|
+
return [];
|
|
2090
|
+
if (prop.value.kind !== "jsx-children")
|
|
2091
|
+
return [];
|
|
2092
|
+
return prop.value.children ?? [];
|
|
2093
|
+
}
|
|
2085
2094
|
// ../jsx/src/ir-to-client-js/csr-substitute.ts
|
|
2086
2095
|
import ts4 from "typescript";
|
|
2087
2096
|
function extractFreeIdentifiersFromText(text) {
|
|
@@ -3008,6 +3017,10 @@ var EMPTY_BOUND = new Set;
|
|
|
3008
3017
|
var constInitializerCache = new WeakMap;
|
|
3009
3018
|
var functionInfoExprCache = new WeakMap;
|
|
3010
3019
|
|
|
3020
|
+
// ../jsx/src/ir-to-client-js/prop-handling.ts
|
|
3021
|
+
var _localConstantValuesCache = new WeakMap;
|
|
3022
|
+
var _restSpreadNamesCache = new WeakMap;
|
|
3023
|
+
|
|
3011
3024
|
// ../jsx/src/ir-to-client-js/control-flow/stringify/template-parse.ts
|
|
3012
3025
|
var SVG_ROOT_TAGS = new Set([
|
|
3013
3026
|
"svg",
|
|
@@ -3129,11 +3142,14 @@ var KEYWORDS_AND_GLOBALS = new Set([
|
|
|
3129
3142
|
// ../jsx/src/ir-to-client-js/walk-prop-accesses.ts
|
|
3130
3143
|
import ts14 from "typescript";
|
|
3131
3144
|
|
|
3145
|
+
// ../jsx/src/ir-to-client-js/imports.ts
|
|
3146
|
+
import ts16 from "typescript";
|
|
3147
|
+
|
|
3132
3148
|
// ../jsx/src/value-references.ts
|
|
3133
3149
|
import ts15 from "typescript";
|
|
3134
3150
|
|
|
3135
3151
|
// ../jsx/src/relocate.ts
|
|
3136
|
-
import
|
|
3152
|
+
import ts17 from "typescript";
|
|
3137
3153
|
|
|
3138
3154
|
// ../jsx/src/lowering-registry.ts
|
|
3139
3155
|
var plugins = [];
|
|
@@ -3350,10 +3366,10 @@ function matchSearchParamsMethodCall(callee, args, localNames) {
|
|
|
3350
3366
|
}
|
|
3351
3367
|
|
|
3352
3368
|
// ../jsx/src/ir-to-client-js/prune-unused-prop-extractions.ts
|
|
3353
|
-
import
|
|
3369
|
+
import ts18 from "typescript";
|
|
3354
3370
|
|
|
3355
3371
|
// ../jsx/src/ir-to-client-js/control-flow/plan/lazy-preamble.ts
|
|
3356
|
-
import
|
|
3372
|
+
import ts19 from "typescript";
|
|
3357
3373
|
var NO_PREAMBLE = {
|
|
3358
3374
|
lazySafe: true,
|
|
3359
3375
|
facts: { declaredNames: new Set, freeNames: new Set }
|
|
@@ -3403,7 +3419,7 @@ var INERT_BINDING_GLOBALS = new Set([
|
|
|
3403
3419
|
]);
|
|
3404
3420
|
|
|
3405
3421
|
// ../jsx/src/ir-to-client-js/emit-reactive.ts
|
|
3406
|
-
import
|
|
3422
|
+
import ts20 from "typescript";
|
|
3407
3423
|
|
|
3408
3424
|
// ../jsx/src/ir-to-client-js/control-flow/stringify/event-delegation.ts
|
|
3409
3425
|
var NON_BUBBLING_EVENTS = new Set([
|
|
@@ -3418,7 +3434,7 @@ var NON_BUBBLING_EVENTS = new Set([
|
|
|
3418
3434
|
]);
|
|
3419
3435
|
|
|
3420
3436
|
// ../jsx/src/ir-to-client-js/rewrite-props-object.ts
|
|
3421
|
-
import
|
|
3437
|
+
import ts21 from "typescript";
|
|
3422
3438
|
|
|
3423
3439
|
// ../jsx/src/ir-to-client-js/source-map.ts
|
|
3424
3440
|
var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
@@ -3509,15 +3525,15 @@ class SourceMapGenerator {
|
|
|
3509
3525
|
}
|
|
3510
3526
|
|
|
3511
3527
|
// ../jsx/src/preprocess-inline-jsx-callbacks.ts
|
|
3512
|
-
import
|
|
3528
|
+
import ts22 from "typescript";
|
|
3513
3529
|
|
|
3514
3530
|
// ../jsx/src/ssr-defaults.ts
|
|
3515
|
-
import
|
|
3531
|
+
import ts23 from "typescript";
|
|
3516
3532
|
var UNRESOLVED = Symbol("unresolved");
|
|
3517
3533
|
var NO_RETURN = Symbol("no-return");
|
|
3518
3534
|
|
|
3519
3535
|
// ../jsx/src/augment-inherited-props.ts
|
|
3520
|
-
import
|
|
3536
|
+
import ts24 from "typescript";
|
|
3521
3537
|
function collectContextConsumers(metadata) {
|
|
3522
3538
|
const constants = metadata.localConstants ?? [];
|
|
3523
3539
|
const contextDefaults = new Map;
|
|
@@ -3549,47 +3565,47 @@ function collectContextConsumers(metadata) {
|
|
|
3549
3565
|
}
|
|
3550
3566
|
function parseUseContextArg(source) {
|
|
3551
3567
|
const expr = parseSingleExpression(source);
|
|
3552
|
-
if (!expr || !
|
|
3568
|
+
if (!expr || !ts24.isCallExpression(expr))
|
|
3553
3569
|
return null;
|
|
3554
|
-
if (!
|
|
3570
|
+
if (!ts24.isIdentifier(expr.expression) || expr.expression.text !== "useContext")
|
|
3555
3571
|
return null;
|
|
3556
3572
|
if (expr.arguments.length !== 1)
|
|
3557
3573
|
return null;
|
|
3558
3574
|
const arg = expr.arguments[0];
|
|
3559
|
-
return
|
|
3575
|
+
return ts24.isIdentifier(arg) ? arg.text : null;
|
|
3560
3576
|
}
|
|
3561
3577
|
function parseCreateContextDefault(source) {
|
|
3562
3578
|
const expr = parseSingleExpression(source);
|
|
3563
|
-
if (!expr || !
|
|
3579
|
+
if (!expr || !ts24.isCallExpression(expr))
|
|
3564
3580
|
return null;
|
|
3565
3581
|
if (expr.arguments.length === 0)
|
|
3566
3582
|
return null;
|
|
3567
3583
|
const arg = expr.arguments[0];
|
|
3568
|
-
if (
|
|
3584
|
+
if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
|
|
3569
3585
|
return arg.text;
|
|
3570
|
-
if (
|
|
3586
|
+
if (ts24.isNumericLiteral(arg))
|
|
3571
3587
|
return Number(arg.text);
|
|
3572
|
-
if (arg.kind ===
|
|
3588
|
+
if (arg.kind === ts24.SyntaxKind.TrueKeyword)
|
|
3573
3589
|
return true;
|
|
3574
|
-
if (arg.kind ===
|
|
3590
|
+
if (arg.kind === ts24.SyntaxKind.FalseKeyword)
|
|
3575
3591
|
return false;
|
|
3576
3592
|
return null;
|
|
3577
3593
|
}
|
|
3578
3594
|
function isObjectLiteralCreateContextDefault(source) {
|
|
3579
3595
|
const expr = parseSingleExpression(source);
|
|
3580
|
-
if (!expr || !
|
|
3596
|
+
if (!expr || !ts24.isCallExpression(expr))
|
|
3581
3597
|
return false;
|
|
3582
3598
|
if (expr.arguments.length === 0)
|
|
3583
3599
|
return false;
|
|
3584
|
-
return
|
|
3600
|
+
return ts24.isObjectLiteralExpression(expr.arguments[0]);
|
|
3585
3601
|
}
|
|
3586
3602
|
function parseSingleExpression(source) {
|
|
3587
|
-
const sf =
|
|
3603
|
+
const sf = ts24.createSourceFile("__ctx.ts", `(${source})`, ts24.ScriptTarget.Latest, false);
|
|
3588
3604
|
const stmt = sf.statements[0];
|
|
3589
|
-
if (!stmt || !
|
|
3605
|
+
if (!stmt || !ts24.isExpressionStatement(stmt))
|
|
3590
3606
|
return null;
|
|
3591
3607
|
let e = stmt.expression;
|
|
3592
|
-
while (
|
|
3608
|
+
while (ts24.isParenthesizedExpression(e))
|
|
3593
3609
|
e = e.expression;
|
|
3594
3610
|
return e;
|
|
3595
3611
|
}
|
|
@@ -3614,25 +3630,25 @@ function augmentInheritedPropAccesses(ir) {
|
|
|
3614
3630
|
const pinCoalesceLiterals = (s) => {
|
|
3615
3631
|
if (!s || !s.includes(propsObj))
|
|
3616
3632
|
return;
|
|
3617
|
-
const sf =
|
|
3633
|
+
const sf = ts24.createSourceFile("__aug.ts", `(${s})`, ts24.ScriptTarget.Latest, false);
|
|
3618
3634
|
const visit = (n) => {
|
|
3619
|
-
if (
|
|
3635
|
+
if (ts24.isBinaryExpression(n) && (n.operatorToken.kind === ts24.SyntaxKind.QuestionQuestionToken || n.operatorToken.kind === ts24.SyntaxKind.BarBarToken)) {
|
|
3620
3636
|
let left = n.left;
|
|
3621
|
-
while (
|
|
3637
|
+
while (ts24.isParenthesizedExpression(left))
|
|
3622
3638
|
left = left.expression;
|
|
3623
|
-
if (
|
|
3639
|
+
if (ts24.isPropertyAccessExpression(left) && ts24.isIdentifier(left.expression) && left.expression.text === propsObj) {
|
|
3624
3640
|
const name = left.name.text;
|
|
3625
3641
|
let right = n.right;
|
|
3626
|
-
while (
|
|
3642
|
+
while (ts24.isParenthesizedExpression(right))
|
|
3627
3643
|
right = right.expression;
|
|
3628
|
-
if (
|
|
3644
|
+
if (ts24.isPrefixUnaryExpression(right))
|
|
3629
3645
|
right = right.operand;
|
|
3630
|
-
const kind =
|
|
3646
|
+
const kind = ts24.isNumericLiteral(right) ? "number" : right.kind === ts24.SyntaxKind.TrueKeyword || right.kind === ts24.SyntaxKind.FalseKeyword ? "boolean" : ts24.isStringLiteralLike(right) ? "string" : null;
|
|
3631
3647
|
if (kind && !coalesceLiteralTypes.has(name))
|
|
3632
3648
|
coalesceLiteralTypes.set(name, kind);
|
|
3633
3649
|
}
|
|
3634
3650
|
}
|
|
3635
|
-
|
|
3651
|
+
ts24.forEachChild(n, visit);
|
|
3636
3652
|
};
|
|
3637
3653
|
visit(sf);
|
|
3638
3654
|
};
|
|
@@ -3743,33 +3759,33 @@ function augmentInheritedPropAccesses(ir) {
|
|
|
3743
3759
|
}
|
|
3744
3760
|
}
|
|
3745
3761
|
function parseStaticStringConst(source) {
|
|
3746
|
-
const sf =
|
|
3762
|
+
const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
|
|
3747
3763
|
const stmt = sf.statements[0];
|
|
3748
|
-
if (!stmt || !
|
|
3764
|
+
if (!stmt || !ts24.isVariableStatement(stmt))
|
|
3749
3765
|
return null;
|
|
3750
3766
|
let init = stmt.declarationList.declarations[0]?.initializer;
|
|
3751
|
-
while (init &&
|
|
3767
|
+
while (init && ts24.isParenthesizedExpression(init))
|
|
3752
3768
|
init = init.expression;
|
|
3753
3769
|
if (!init)
|
|
3754
3770
|
return null;
|
|
3755
|
-
if (
|
|
3771
|
+
if (ts24.isStringLiteral(init) || ts24.isNoSubstitutionTemplateLiteral(init)) {
|
|
3756
3772
|
return init.text;
|
|
3757
3773
|
}
|
|
3758
3774
|
return evalStringArrayJoin(source);
|
|
3759
3775
|
}
|
|
3760
3776
|
function evalTemplateOfStringConsts(source, resolved) {
|
|
3761
|
-
const sf =
|
|
3777
|
+
const sf = ts24.createSourceFile("__const.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
|
|
3762
3778
|
const stmt = sf.statements[0];
|
|
3763
|
-
if (!stmt || !
|
|
3779
|
+
if (!stmt || !ts24.isVariableStatement(stmt))
|
|
3764
3780
|
return null;
|
|
3765
3781
|
let init = stmt.declarationList.declarations[0]?.initializer;
|
|
3766
|
-
while (init &&
|
|
3782
|
+
while (init && ts24.isParenthesizedExpression(init))
|
|
3767
3783
|
init = init.expression;
|
|
3768
|
-
if (!init || !
|
|
3784
|
+
if (!init || !ts24.isTemplateExpression(init))
|
|
3769
3785
|
return null;
|
|
3770
3786
|
let out = init.head.text;
|
|
3771
3787
|
for (const span of init.templateSpans) {
|
|
3772
|
-
if (!
|
|
3788
|
+
if (!ts24.isIdentifier(span.expression))
|
|
3773
3789
|
return null;
|
|
3774
3790
|
const value = resolved.get(span.expression.text);
|
|
3775
3791
|
if (value === undefined)
|
|
@@ -3802,30 +3818,30 @@ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
|
|
|
3802
3818
|
const constInfo = (constants ?? []).find((c) => c.name === objectName && c.isModule);
|
|
3803
3819
|
if (constInfo?.value === undefined)
|
|
3804
3820
|
return null;
|
|
3805
|
-
const sf =
|
|
3821
|
+
const sf = ts24.createSourceFile("__rec.ts", `(${constInfo.value})`, ts24.ScriptTarget.Latest, true);
|
|
3806
3822
|
if (sf.statements.length !== 1)
|
|
3807
3823
|
return null;
|
|
3808
3824
|
const stmt = sf.statements[0];
|
|
3809
|
-
if (!
|
|
3825
|
+
if (!ts24.isExpressionStatement(stmt))
|
|
3810
3826
|
return null;
|
|
3811
3827
|
let parsed = stmt.expression;
|
|
3812
|
-
while (
|
|
3828
|
+
while (ts24.isParenthesizedExpression(parsed))
|
|
3813
3829
|
parsed = parsed.expression;
|
|
3814
|
-
if (!
|
|
3830
|
+
if (!ts24.isObjectLiteralExpression(parsed))
|
|
3815
3831
|
return null;
|
|
3816
3832
|
for (const prop of parsed.properties) {
|
|
3817
|
-
if (!
|
|
3833
|
+
if (!ts24.isPropertyAssignment(prop))
|
|
3818
3834
|
continue;
|
|
3819
3835
|
const name = prop.name;
|
|
3820
|
-
const propKey =
|
|
3836
|
+
const propKey = ts24.isIdentifier(name) || ts24.isStringLiteral(name) || ts24.isNoSubstitutionTemplateLiteral(name) ? name.text : null;
|
|
3821
3837
|
if (propKey !== key)
|
|
3822
3838
|
continue;
|
|
3823
3839
|
let v = prop.initializer;
|
|
3824
|
-
while (
|
|
3840
|
+
while (ts24.isParenthesizedExpression(v))
|
|
3825
3841
|
v = v.expression;
|
|
3826
|
-
if (
|
|
3842
|
+
if (ts24.isNumericLiteral(v))
|
|
3827
3843
|
return { kind: "number", text: v.text };
|
|
3828
|
-
if (
|
|
3844
|
+
if (ts24.isStringLiteral(v) || ts24.isNoSubstitutionTemplateLiteral(v)) {
|
|
3829
3845
|
return { kind: "string", text: v.text };
|
|
3830
3846
|
}
|
|
3831
3847
|
return null;
|
|
@@ -3833,28 +3849,28 @@ function lookupStaticRecordLiteral(objectName, key, constants, isShadowed) {
|
|
|
3833
3849
|
return null;
|
|
3834
3850
|
}
|
|
3835
3851
|
function evalStringArrayJoin(source) {
|
|
3836
|
-
const sf =
|
|
3852
|
+
const sf = ts24.createSourceFile("__join.ts", `const __x = (${source});`, ts24.ScriptTarget.Latest, false);
|
|
3837
3853
|
const stmt = sf.statements[0];
|
|
3838
|
-
if (!stmt || !
|
|
3854
|
+
if (!stmt || !ts24.isVariableStatement(stmt))
|
|
3839
3855
|
return null;
|
|
3840
3856
|
let node = stmt.declarationList.declarations[0]?.initializer;
|
|
3841
|
-
while (node &&
|
|
3857
|
+
while (node && ts24.isParenthesizedExpression(node))
|
|
3842
3858
|
node = node.expression;
|
|
3843
|
-
if (!node || !
|
|
3859
|
+
if (!node || !ts24.isCallExpression(node))
|
|
3844
3860
|
return null;
|
|
3845
3861
|
const callee = node.expression;
|
|
3846
|
-
if (!
|
|
3862
|
+
if (!ts24.isPropertyAccessExpression(callee))
|
|
3847
3863
|
return null;
|
|
3848
3864
|
if (callee.name.text !== "join")
|
|
3849
3865
|
return null;
|
|
3850
3866
|
let recv = callee.expression;
|
|
3851
|
-
while (
|
|
3867
|
+
while (ts24.isParenthesizedExpression(recv))
|
|
3852
3868
|
recv = recv.expression;
|
|
3853
|
-
if (!
|
|
3869
|
+
if (!ts24.isArrayLiteralExpression(recv))
|
|
3854
3870
|
return null;
|
|
3855
3871
|
const parts = [];
|
|
3856
3872
|
for (const el of recv.elements) {
|
|
3857
|
-
if (
|
|
3873
|
+
if (ts24.isStringLiteral(el) || ts24.isNoSubstitutionTemplateLiteral(el)) {
|
|
3858
3874
|
parts.push(el.text);
|
|
3859
3875
|
} else {
|
|
3860
3876
|
return null;
|
|
@@ -3863,7 +3879,7 @@ function evalStringArrayJoin(source) {
|
|
|
3863
3879
|
let sep = ",";
|
|
3864
3880
|
if (node.arguments.length >= 1) {
|
|
3865
3881
|
const arg = node.arguments[0];
|
|
3866
|
-
if (
|
|
3882
|
+
if (ts24.isStringLiteral(arg) || ts24.isNoSubstitutionTemplateLiteral(arg))
|
|
3867
3883
|
sep = arg.text;
|
|
3868
3884
|
else
|
|
3869
3885
|
return null;
|
|
@@ -3871,11 +3887,11 @@ function evalStringArrayJoin(source) {
|
|
|
3871
3887
|
return parts.join(sep);
|
|
3872
3888
|
}
|
|
3873
3889
|
function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
3874
|
-
if (!
|
|
3890
|
+
if (!ts24.isElementAccessExpression(val))
|
|
3875
3891
|
return null;
|
|
3876
3892
|
const obj = val.expression;
|
|
3877
3893
|
const arg = val.argumentExpression;
|
|
3878
|
-
if (!
|
|
3894
|
+
if (!ts24.isIdentifier(obj) || !ts24.isIdentifier(arg))
|
|
3879
3895
|
return null;
|
|
3880
3896
|
let indexPropName;
|
|
3881
3897
|
let defaultKey;
|
|
@@ -3891,35 +3907,35 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
|
|
|
3891
3907
|
const constInfo = localConstants.find((c) => c.name === obj.text && c.isModule);
|
|
3892
3908
|
if (constInfo?.value === undefined)
|
|
3893
3909
|
return null;
|
|
3894
|
-
const sf =
|
|
3910
|
+
const sf = ts24.createSourceFile("__rec.ts", `(${constInfo.value})`, ts24.ScriptTarget.Latest, true);
|
|
3895
3911
|
if (sf.statements.length !== 1)
|
|
3896
3912
|
return null;
|
|
3897
3913
|
const stmt = sf.statements[0];
|
|
3898
|
-
if (!
|
|
3914
|
+
if (!ts24.isExpressionStatement(stmt))
|
|
3899
3915
|
return null;
|
|
3900
3916
|
let parsed = stmt.expression;
|
|
3901
|
-
while (
|
|
3917
|
+
while (ts24.isParenthesizedExpression(parsed))
|
|
3902
3918
|
parsed = parsed.expression;
|
|
3903
|
-
if (!
|
|
3919
|
+
if (!ts24.isObjectLiteralExpression(parsed))
|
|
3904
3920
|
return null;
|
|
3905
3921
|
const entries = [];
|
|
3906
3922
|
for (const prop of parsed.properties) {
|
|
3907
|
-
if (!
|
|
3923
|
+
if (!ts24.isPropertyAssignment(prop))
|
|
3908
3924
|
return null;
|
|
3909
3925
|
let key;
|
|
3910
|
-
if (
|
|
3926
|
+
if (ts24.isIdentifier(prop.name)) {
|
|
3911
3927
|
key = prop.name.text;
|
|
3912
|
-
} else if (
|
|
3928
|
+
} else if (ts24.isStringLiteral(prop.name) || ts24.isNoSubstitutionTemplateLiteral(prop.name)) {
|
|
3913
3929
|
key = prop.name.text;
|
|
3914
3930
|
} else {
|
|
3915
3931
|
return null;
|
|
3916
3932
|
}
|
|
3917
3933
|
let v = prop.initializer;
|
|
3918
|
-
while (
|
|
3934
|
+
while (ts24.isParenthesizedExpression(v))
|
|
3919
3935
|
v = v.expression;
|
|
3920
|
-
if (
|
|
3936
|
+
if (ts24.isNumericLiteral(v)) {
|
|
3921
3937
|
entries.push({ key, value: { kind: "number", text: v.text } });
|
|
3922
|
-
} else if (
|
|
3938
|
+
} else if (ts24.isStringLiteral(v) || ts24.isNoSubstitutionTemplateLiteral(v)) {
|
|
3923
3939
|
entries.push({ key, value: { kind: "string", text: v.text } });
|
|
3924
3940
|
} else {
|
|
3925
3941
|
return null;
|
|
@@ -4008,7 +4024,7 @@ function computeSsrSeedPlan(metadata) {
|
|
|
4008
4024
|
// ../jsx/src/rich-type-refusal.ts
|
|
4009
4025
|
var EMPTY_BINDINGS2 = new Map;
|
|
4010
4026
|
// ../jsx/src/shared-program.ts
|
|
4011
|
-
import
|
|
4027
|
+
import ts26 from "typescript";
|
|
4012
4028
|
// ../jsx/src/adapters/interface.ts
|
|
4013
4029
|
class BaseAdapter {
|
|
4014
4030
|
renderChildren(children) {
|
|
@@ -4290,7 +4306,7 @@ class JsxAdapter extends BaseAdapter {
|
|
|
4290
4306
|
}
|
|
4291
4307
|
|
|
4292
4308
|
// ../jsx/src/adapters/template-imports.ts
|
|
4293
|
-
import
|
|
4309
|
+
import ts27 from "typescript";
|
|
4294
4310
|
var CLIENT_PACKAGE_SOURCES = new Set([
|
|
4295
4311
|
"@barefootjs/client",
|
|
4296
4312
|
"@barefootjs/client/runtime"
|
|
@@ -5070,7 +5086,7 @@ function dangerousInnerHtmlDiagnostic(expr, loc, reason) {
|
|
|
5070
5086
|
};
|
|
5071
5087
|
}
|
|
5072
5088
|
// ../jsx/src/combine-client-js.ts
|
|
5073
|
-
import
|
|
5089
|
+
import ts28 from "typescript";
|
|
5074
5090
|
// ../jsx/src/loop-destructure.ts
|
|
5075
5091
|
function isLowerableLoopDestructure(loop) {
|
|
5076
5092
|
const bindings = loop.paramBindings;
|
|
@@ -5210,9 +5226,9 @@ function escapeRe(s) {
|
|
|
5210
5226
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5211
5227
|
}
|
|
5212
5228
|
// ../jsx/src/debug.ts
|
|
5213
|
-
import ts28 from "typescript";
|
|
5214
|
-
// ../jsx/src/profiler.ts
|
|
5215
5229
|
import ts29 from "typescript";
|
|
5230
|
+
// ../jsx/src/profiler.ts
|
|
5231
|
+
import ts30 from "typescript";
|
|
5216
5232
|
|
|
5217
5233
|
// ../jsx/src/index.ts
|
|
5218
5234
|
registerBuiltinLoweringPlugins();
|
|
@@ -5295,39 +5311,6 @@ function perlIdentifierFromMarkerId(markerId) {
|
|
|
5295
5311
|
return markerId.replace(/[^a-zA-Z0-9]/g, (ch) => ch === "_" ? "__" : `_x${ch.charCodeAt(0).toString(16)}`);
|
|
5296
5312
|
}
|
|
5297
5313
|
|
|
5298
|
-
// src/adapter/lib/ir-scope.ts
|
|
5299
|
-
function resolveJsxChildrenProp(props) {
|
|
5300
|
-
const prop = props.find((p) => p.name === "children");
|
|
5301
|
-
if (!prop)
|
|
5302
|
-
return [];
|
|
5303
|
-
if (prop.value.kind !== "jsx-children")
|
|
5304
|
-
return [];
|
|
5305
|
-
return prop.value.children;
|
|
5306
|
-
}
|
|
5307
|
-
function collectRootScopeNodes(node) {
|
|
5308
|
-
const out = new Set;
|
|
5309
|
-
const visit = (n) => {
|
|
5310
|
-
if (!n)
|
|
5311
|
-
return;
|
|
5312
|
-
if (n.type === "element") {
|
|
5313
|
-
out.add(n);
|
|
5314
|
-
return;
|
|
5315
|
-
}
|
|
5316
|
-
if (n.type === "if-statement") {
|
|
5317
|
-
const s = n;
|
|
5318
|
-
visit(s.consequent);
|
|
5319
|
-
visit(s.alternate);
|
|
5320
|
-
return;
|
|
5321
|
-
}
|
|
5322
|
-
if (n.type === "fragment") {
|
|
5323
|
-
for (const c of n.children)
|
|
5324
|
-
visit(c);
|
|
5325
|
-
}
|
|
5326
|
-
};
|
|
5327
|
-
visit(node);
|
|
5328
|
-
return out;
|
|
5329
|
-
}
|
|
5330
|
-
|
|
5331
5314
|
// src/adapter/expr/array-method.ts
|
|
5332
5315
|
function renderArrayMethod(method, object, args, emit) {
|
|
5333
5316
|
switch (method) {
|
|
@@ -6044,7 +6027,7 @@ function collectImportedLoopChildComponentErrors(ir, componentName) {
|
|
|
6044
6027
|
}
|
|
6045
6028
|
|
|
6046
6029
|
// src/adapter/spread/spread-codegen.ts
|
|
6047
|
-
import
|
|
6030
|
+
import ts31 from "typescript";
|
|
6048
6031
|
function conditionalSpreadToPerl(ctx, expr) {
|
|
6049
6032
|
if (!expr || expr.kind !== "conditional")
|
|
6050
6033
|
return null;
|
|
@@ -6101,7 +6084,7 @@ function recordIndexAccessToPerl(ctx, val) {
|
|
|
6101
6084
|
if (val.kind !== "index-access" || val.object.kind !== "identifier" || val.index.kind !== "identifier") {
|
|
6102
6085
|
return null;
|
|
6103
6086
|
}
|
|
6104
|
-
const tsVal =
|
|
6087
|
+
const tsVal = ts31.factory.createElementAccessExpression(ts31.factory.createIdentifier(val.object.name), ts31.factory.createIdentifier(val.index.name));
|
|
6105
6088
|
const parsed = parseRecordIndexAccess(tsVal, ctx.localConstants, ctx.propsParams);
|
|
6106
6089
|
if (!parsed)
|
|
6107
6090
|
return null;
|
|
@@ -6210,10 +6193,8 @@ class MojoAdapter extends BaseAdapter {
|
|
|
6210
6193
|
templatesPerComponent = true;
|
|
6211
6194
|
templatePrimitives = MOJO_PRIMITIVE_EMIT_MAP;
|
|
6212
6195
|
componentName = "";
|
|
6213
|
-
rootScopeNodes = new Set;
|
|
6214
6196
|
options;
|
|
6215
6197
|
errors = [];
|
|
6216
|
-
currentLoopKeyDepth = 0;
|
|
6217
6198
|
propsObjectName = null;
|
|
6218
6199
|
propsParams = [];
|
|
6219
6200
|
booleanTypedProps = new Set;
|
|
@@ -6251,7 +6232,6 @@ class MojoAdapter extends BaseAdapter {
|
|
|
6251
6232
|
if (!options?.siblingTemplatesRegistered) {
|
|
6252
6233
|
this.errors.push(...collectImportedLoopChildComponentErrors(ir, this.componentName));
|
|
6253
6234
|
}
|
|
6254
|
-
this.rootScopeNodes = collectRootScopeNodes(ir.root);
|
|
6255
6235
|
const templateBody = ir.root.type === "if-statement" ? this.renderIfStatement(ir.root) : this.renderNode(ir.root);
|
|
6256
6236
|
const scriptReg = options?.skipScriptRegistration ? "" : this.generateScriptRegistrations(ir, options?.scriptBaseName, options?.scriptAssets, options?.preloadAssets);
|
|
6257
6237
|
const ctxSeed = generateContextConsumerSeed(ir);
|
|
@@ -6432,8 +6412,14 @@ class MojoAdapter extends BaseAdapter {
|
|
|
6432
6412
|
if (element.needsScope) {
|
|
6433
6413
|
hydrationAttrs += ` ${this.renderScopeMarker("")}`;
|
|
6434
6414
|
}
|
|
6435
|
-
if (
|
|
6436
|
-
|
|
6415
|
+
if (element.keyAttr) {
|
|
6416
|
+
if (element.keyAttr.value !== undefined) {
|
|
6417
|
+
const lowered = emitAttrValue({ kind: "expression", expr: element.keyAttr.value }, this.elementAttrEmitter, element.keyAttr.name);
|
|
6418
|
+
if (lowered)
|
|
6419
|
+
hydrationAttrs += ` ${lowered}`;
|
|
6420
|
+
} else {
|
|
6421
|
+
hydrationAttrs += ` <%== bf->data_key_attr %>`;
|
|
6422
|
+
}
|
|
6437
6423
|
}
|
|
6438
6424
|
if (element.slotId) {
|
|
6439
6425
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`;
|
|
@@ -6614,10 +6600,7 @@ ${whenTrue}
|
|
|
6614
6600
|
const preambleDecls = loop.preamble?.declarations ?? [];
|
|
6615
6601
|
const prevScope = this.scope;
|
|
6616
6602
|
this.scope = prevScope.enterLoopRow(loop);
|
|
6617
|
-
const prevLoopKeyDepth = this.currentLoopKeyDepth;
|
|
6618
|
-
this.currentLoopKeyDepth = loop.depth;
|
|
6619
6603
|
const renderedChildren = this.renderChildren(loop.children);
|
|
6620
|
-
this.currentLoopKeyDepth = prevLoopKeyDepth;
|
|
6621
6604
|
const children = loop.bodyIsItemConditional && loop.key ? `<%== bf->comment("loop-i:" . ${this.convertExpressionToPerl(loop.key)}) %>
|
|
6622
6605
|
${renderedChildren}` : renderedChildren;
|
|
6623
6606
|
const lines = [];
|
|
@@ -6883,14 +6866,9 @@ ${children}`;
|
|
|
6883
6866
|
continue;
|
|
6884
6867
|
if (isDangerousInnerHtmlAttr(attr))
|
|
6885
6868
|
continue;
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
else if (attr.name === "key") {
|
|
6890
|
-
const depth = this.currentLoopKeyDepth;
|
|
6891
|
-
attrName = depth > 0 ? `data-key-${depth}` : "data-key";
|
|
6892
|
-
} else
|
|
6893
|
-
attrName = attr.name;
|
|
6869
|
+
if (attr.name === "key")
|
|
6870
|
+
continue;
|
|
6871
|
+
const attrName = attr.name === "className" ? "class" : attr.name;
|
|
6894
6872
|
const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName);
|
|
6895
6873
|
if (lowered)
|
|
6896
6874
|
parts.push(lowered);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/mojolicious",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.3",
|
|
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.33.
|
|
55
|
+
"@barefootjs/shared": "0.33.3"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@barefootjs/jsx": ">=0.2.0",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
73
|
-
"@barefootjs/jsx": "0.33.
|
|
74
|
-
"@barefootjs/vite": "0.33.
|
|
75
|
-
"@barefootjs/client": "0.33.
|
|
73
|
+
"@barefootjs/jsx": "0.33.3",
|
|
74
|
+
"@barefootjs/vite": "0.33.3",
|
|
75
|
+
"@barefootjs/client": "0.33.3",
|
|
76
76
|
"vite": "^6.0.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -70,15 +70,11 @@ import {
|
|
|
70
70
|
} from '@barefootjs/jsx'
|
|
71
71
|
import { isAriaBooleanAttr, isBooleanResultExpr } from './boolean-result.ts'
|
|
72
72
|
import type { ParsedExpr, LoweringMatcher } from '@barefootjs/jsx'
|
|
73
|
-
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml } from '@barefootjs/shared'
|
|
73
|
+
import { BF_SLOT, BF_COND, BF_REGION, escapeHtml, resolveJsxChildrenProp } from '@barefootjs/shared'
|
|
74
74
|
|
|
75
75
|
import type { MojoRenderCtx } from './lib/types.ts'
|
|
76
76
|
import { MOJO_PRIMITIVE_EMIT_MAP } from './lib/constants.ts'
|
|
77
77
|
import { perlHashKey, perlIdentifierFromMarkerId } from './lib/perl-naming.ts'
|
|
78
|
-
import {
|
|
79
|
-
resolveJsxChildrenProp,
|
|
80
|
-
collectRootScopeNodes,
|
|
81
|
-
} from './lib/ir-scope.ts'
|
|
82
78
|
import { renderSortMethod, renderSortEval } from './expr/array-method.ts'
|
|
83
79
|
import { staticValueToPerl } from './lib/static-value.ts'
|
|
84
80
|
import { MojoFilterEmitter, MojoTopLevelEmitter } from './expr/emitters.ts'
|
|
@@ -162,22 +158,8 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
162
158
|
templatePrimitives: TemplatePrimitiveRegistry = MOJO_PRIMITIVE_EMIT_MAP
|
|
163
159
|
|
|
164
160
|
private componentName: string = ''
|
|
165
|
-
/** The component's root scope element(s) — each carries `data-key` for a
|
|
166
|
-
* keyed loop item (set by the child renderer from the JSX `key` prop). A
|
|
167
|
-
* plain element root is a single node; an `if-statement` (early-return) root
|
|
168
|
-
* contributes the top element of every branch, since any one of them can be
|
|
169
|
-
* the rendered root at runtime. */
|
|
170
|
-
private rootScopeNodes: Set<IRNode> = new Set()
|
|
171
161
|
private options: Required<MojoAdapterOptions>
|
|
172
162
|
private errors: CompilerError[] = []
|
|
173
|
-
/**
|
|
174
|
-
* `IRLoop.depth` of the loop currently being rendered (save/restore
|
|
175
|
-
* around `renderChildren(loop.children)`, mirroring `inLoop` above).
|
|
176
|
-
* `renderAttributes` reads this to derive the `key` → `data-key`/
|
|
177
|
-
* `data-key-N` suffix — the depth is IR-computed (jsx-to-ir.ts), not
|
|
178
|
-
* re-derived here (#2168 nested-loop-outer-binding).
|
|
179
|
-
*/
|
|
180
|
-
private currentLoopKeyDepth = 0
|
|
181
163
|
/**
|
|
182
164
|
* SolidJS-style props identifier (`function(props: P)`) and the
|
|
183
165
|
* analyzer-extracted prop names. Stashed at `generate()` entry so
|
|
@@ -322,7 +304,6 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
322
304
|
this.errors.push(...collectImportedLoopChildComponentErrors(ir, this.componentName))
|
|
323
305
|
}
|
|
324
306
|
|
|
325
|
-
this.rootScopeNodes = collectRootScopeNodes(ir.root)
|
|
326
307
|
const templateBody = ir.root.type === 'if-statement'
|
|
327
308
|
? this.renderIfStatement(ir.root as IRIfStatement)
|
|
328
309
|
: this.renderNode(ir.root)
|
|
@@ -672,13 +653,30 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
672
653
|
if (element.needsScope) {
|
|
673
654
|
hydrationAttrs += ` ${this.renderScopeMarker('')}`
|
|
674
655
|
}
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
//
|
|
680
|
-
|
|
681
|
-
|
|
656
|
+
// #2753: `element.keyAttr` is the ONE IR-resolved decision for this
|
|
657
|
+
// element's row-key attribute — replacing both the `carriesDataKey`
|
|
658
|
+
// boolean and this adapter's own `rootScopeNodes`/`needsScope` check
|
|
659
|
+
// (mechanism 2: a render-root relay, including the #2732 fragment-root
|
|
660
|
+
// case) and the separate `currentLoopKeyDepth`-driven rewrite of a
|
|
661
|
+
// literal `key` attribute this adapter used to do in `renderAttributes`
|
|
662
|
+
// (mechanism 1: a `.map()` row root compiled inline here).
|
|
663
|
+
if (element.keyAttr) {
|
|
664
|
+
if (element.keyAttr.value !== undefined) {
|
|
665
|
+
const lowered = emitAttrValue(
|
|
666
|
+
{ kind: 'expression', expr: element.keyAttr.value },
|
|
667
|
+
this.elementAttrEmitter,
|
|
668
|
+
element.keyAttr.name,
|
|
669
|
+
)
|
|
670
|
+
if (lowered) hydrationAttrs += ` ${lowered}`
|
|
671
|
+
} else {
|
|
672
|
+
// Relay: this element is one of THIS component's own render roots,
|
|
673
|
+
// carrying whatever key its OWN caller supplies at runtime (the `bf`
|
|
674
|
+
// instance's `data_key` field) when this component is itself
|
|
675
|
+
// invoked as a caller's keyed loop row. Mirrors Hono stamping
|
|
676
|
+
// data-key on each loop item's root, including early-return
|
|
677
|
+
// (if-statement) roots (#1297), and #2732's fragment-root case.
|
|
678
|
+
hydrationAttrs += ` <%== bf->data_key_attr %>`
|
|
679
|
+
}
|
|
682
680
|
}
|
|
683
681
|
if (element.slotId) {
|
|
684
682
|
hydrationAttrs += ` ${this.renderSlotMarker(element.slotId)}`
|
|
@@ -975,10 +973,7 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
975
973
|
const preambleDecls = loop.preamble?.declarations ?? []
|
|
976
974
|
const prevScope = this.scope
|
|
977
975
|
this.scope = prevScope.enterLoopRow(loop)
|
|
978
|
-
const prevLoopKeyDepth = this.currentLoopKeyDepth
|
|
979
|
-
this.currentLoopKeyDepth = loop.depth
|
|
980
976
|
const renderedChildren = this.renderChildren(loop.children)
|
|
981
|
-
this.currentLoopKeyDepth = prevLoopKeyDepth
|
|
982
977
|
|
|
983
978
|
// Whole-item conditional (#1665): prepend an always-present
|
|
984
979
|
// `<!--bf-loop-i:KEY-->` anchor before each item's (possibly empty)
|
|
@@ -1601,20 +1596,15 @@ export class MojoAdapter extends BaseAdapter implements IRNodeEmitter<MojoRender
|
|
|
1601
1596
|
// literal never reaches the generic object-literal BF101 refusal
|
|
1602
1597
|
// (which would double-report alongside the purpose-built one).
|
|
1603
1598
|
if (isDangerousInnerHtmlAttr(attr)) continue
|
|
1604
|
-
//
|
|
1605
|
-
//
|
|
1606
|
-
//
|
|
1607
|
-
//
|
|
1608
|
-
//
|
|
1609
|
-
//
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
else if (attr.name === 'key') {
|
|
1614
|
-
const depth = this.currentLoopKeyDepth
|
|
1615
|
-
attrName = depth > 0 ? `data-key-${depth}` : 'data-key'
|
|
1616
|
-
}
|
|
1617
|
-
else attrName = attr.name
|
|
1599
|
+
// `key` never renders as a literal HTML attribute — #2753 resolves it
|
|
1600
|
+
// onto `element.keyAttr` (name AND value) at IR-build time, emitted
|
|
1601
|
+
// separately in `renderElement`. A stray `key` that jsx-to-ir.ts did
|
|
1602
|
+
// NOT recognize as a loop row root (so `keyAttr` was never set) has no
|
|
1603
|
+
// defined rendering outside a `.map()` anyway; drop it rather than
|
|
1604
|
+
// leak an invalid `key="..."` HTML attribute.
|
|
1605
|
+
if (attr.name === 'key') continue
|
|
1606
|
+
// Rewrite JSX special-prop names to their HTML-attribute counterparts (#1475).
|
|
1607
|
+
const attrName = attr.name === 'className' ? 'class' : attr.name
|
|
1618
1608
|
const lowered = emitAttrValue(attr.value, this.elementAttrEmitter, attrName)
|
|
1619
1609
|
if (lowered) parts.push(lowered)
|
|
1620
1610
|
}
|
|
@@ -15,4 +15,17 @@ import type { RenderDivergences } from '@barefootjs/jsx'
|
|
|
15
15
|
// at value position and the runtime evaluator's `object-literal` case
|
|
16
16
|
// now merges it, so the seed classifies `derived` and SSRs identically
|
|
17
17
|
// to Hono.
|
|
18
|
-
|
|
18
|
+
// https://github.com/piconic-ai/barefootjs/issues/2788 — a renamed
|
|
19
|
+
// `children` destructure (`const { children: kids } = props`) interpolates
|
|
20
|
+
// the LOCAL alias into the `.html.ep`, and the stash only carries the
|
|
21
|
+
// caller-facing `children`, so Perl dies inside `Mojo::Template::process`
|
|
22
|
+
// at render time rather than at build. Seven adapters resolve the alias;
|
|
23
|
+
// only Mojo does not. Same family as `aliased-destructured-prop`'s
|
|
24
|
+
// `{ n: count }` shape, one level in — the reserved children slot.
|
|
25
|
+
// Delete this entry when #2788 is fixed: `children-passthrough-renamed`
|
|
26
|
+
// already asserts the correct (Hono-generated) output, so it becomes the
|
|
27
|
+
// regression test the moment the skip comes off.
|
|
28
|
+
export const renderDivergences: RenderDivergences = {
|
|
29
|
+
'children-passthrough-renamed':
|
|
30
|
+
'A renamed `children` destructure emits the local alias as a template variable; the stash defines only `children`, so the Perl render dies (#2788).',
|
|
31
|
+
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IR traversal helpers for the Mojolicious EP template adapter.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
|
|
5
|
-
* track D). Pure functions over the IR tree — no adapter instance state.
|
|
6
|
-
*
|
|
7
|
-
* SHARED CANDIDATE: the bodies here are byte-identical to the Xslate
|
|
8
|
-
* adapter's `lib/ir-scope.ts`. They are adapter-agnostic (no Perl/Kolon
|
|
9
|
-
* specifics), so they are the obvious first extraction into a shared
|
|
10
|
-
* Perl-family codegen module once one exists — the groundwork for the
|
|
11
|
-
* future Perl evaluator integration (issue #2018 track D). Kept per-adapter
|
|
12
|
-
* for now, matching the repo convention (the Go adapter keeps its own copy).
|
|
13
|
-
*/
|
|
14
|
-
import type { IRNode, IRProp } from '@barefootjs/jsx';
|
|
15
|
-
/**
|
|
16
|
-
* Find the `children` prop's `jsx-children` payload (#1326). Narrowed
|
|
17
|
-
* via the AttrValue `kind` discriminator so adapter code stays type-
|
|
18
|
-
* safe if the IR shape evolves — adding a new AttrValue variant or
|
|
19
|
-
* renaming `children` to `jsxChildren` becomes a TS compile error
|
|
20
|
-
* here instead of silently dropping the children at runtime.
|
|
21
|
-
*/
|
|
22
|
-
export declare function resolveJsxChildrenProp(props: readonly IRProp[]): IRNode[];
|
|
23
|
-
/**
|
|
24
|
-
* Collect the component's root scope element node(s) — the elements that
|
|
25
|
-
* become the rendered root and so carry `data-key` for a keyed loop item. A
|
|
26
|
-
* plain element root is itself; an `if-statement` (early-return) root
|
|
27
|
-
* contributes the top element of each branch (`consequent` + the `alternate`
|
|
28
|
-
* chain), since exactly one branch renders at runtime. Non-element branch
|
|
29
|
-
* tops (fragments / nested shapes) are walked one level so an
|
|
30
|
-
* `if (…) return <A/>` still resolves to `<A>`. (#1297)
|
|
31
|
-
*/
|
|
32
|
-
export declare function collectRootScopeNodes(node: IRNode): Set<IRNode>;
|
|
33
|
-
//# sourceMappingURL=ir-scope.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ir-scope.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/ir-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAA6B,MAAM,iBAAiB,CAAA;AAEhF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB/D"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IR traversal helpers for the Mojolicious EP template adapter.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from `mojo-adapter.ts` (domain-module refactor, issue #2018
|
|
5
|
-
* track D). Pure functions over the IR tree — no adapter instance state.
|
|
6
|
-
*
|
|
7
|
-
* SHARED CANDIDATE: the bodies here are byte-identical to the Xslate
|
|
8
|
-
* adapter's `lib/ir-scope.ts`. They are adapter-agnostic (no Perl/Kolon
|
|
9
|
-
* specifics), so they are the obvious first extraction into a shared
|
|
10
|
-
* Perl-family codegen module once one exists — the groundwork for the
|
|
11
|
-
* future Perl evaluator integration (issue #2018 track D). Kept per-adapter
|
|
12
|
-
* for now, matching the repo convention (the Go adapter keeps its own copy).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { IRNode, IRProp, IRIfStatement, IRFragment } from '@barefootjs/jsx'
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Find the `children` prop's `jsx-children` payload (#1326). Narrowed
|
|
19
|
-
* via the AttrValue `kind` discriminator so adapter code stays type-
|
|
20
|
-
* safe if the IR shape evolves — adding a new AttrValue variant or
|
|
21
|
-
* renaming `children` to `jsxChildren` becomes a TS compile error
|
|
22
|
-
* here instead of silently dropping the children at runtime.
|
|
23
|
-
*/
|
|
24
|
-
export function resolveJsxChildrenProp(props: readonly IRProp[]): IRNode[] {
|
|
25
|
-
const prop = props.find(p => p.name === 'children')
|
|
26
|
-
if (!prop) return []
|
|
27
|
-
if (prop.value.kind !== 'jsx-children') return []
|
|
28
|
-
return prop.value.children
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Collect the component's root scope element node(s) — the elements that
|
|
33
|
-
* become the rendered root and so carry `data-key` for a keyed loop item. A
|
|
34
|
-
* plain element root is itself; an `if-statement` (early-return) root
|
|
35
|
-
* contributes the top element of each branch (`consequent` + the `alternate`
|
|
36
|
-
* chain), since exactly one branch renders at runtime. Non-element branch
|
|
37
|
-
* tops (fragments / nested shapes) are walked one level so an
|
|
38
|
-
* `if (…) return <A/>` still resolves to `<A>`. (#1297)
|
|
39
|
-
*/
|
|
40
|
-
export function collectRootScopeNodes(node: IRNode): Set<IRNode> {
|
|
41
|
-
const out = new Set<IRNode>()
|
|
42
|
-
const visit = (n: IRNode | null): void => {
|
|
43
|
-
if (!n) return
|
|
44
|
-
if (n.type === 'element') { out.add(n); return }
|
|
45
|
-
if (n.type === 'if-statement') {
|
|
46
|
-
const s = n as IRIfStatement
|
|
47
|
-
visit(s.consequent)
|
|
48
|
-
visit(s.alternate)
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
if (n.type === 'fragment') {
|
|
52
|
-
for (const c of (n as IRFragment).children) visit(c)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
visit(node)
|
|
56
|
-
return out
|
|
57
|
-
}
|