@barefootjs/xslate 0.10.1 → 0.12.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 +29 -2
- package/dist/adapter/xslate-adapter.d.ts +9 -0
- package/dist/adapter/xslate-adapter.d.ts.map +1 -1
- package/dist/build.js +29 -2
- package/dist/index.js +29 -2
- package/lib/BarefootJS/Backend/Xslate.pm +1 -1
- package/package.json +3 -3
- package/src/__tests__/xslate-adapter.test.ts +9 -12
- package/src/adapter/xslate-adapter.ts +68 -5
package/dist/adapter/index.js
CHANGED
|
@@ -187292,6 +187292,7 @@ import {
|
|
|
187292
187292
|
BaseAdapter,
|
|
187293
187293
|
isBooleanAttr,
|
|
187294
187294
|
parseExpression as parseExpression2,
|
|
187295
|
+
parseStyleObjectEntries,
|
|
187295
187296
|
isSupported,
|
|
187296
187297
|
identifierPath,
|
|
187297
187298
|
emitParsedExpr,
|
|
@@ -187302,6 +187303,7 @@ import {
|
|
|
187302
187303
|
evalStringArrayJoin,
|
|
187303
187304
|
extractArrowBodyExpression,
|
|
187304
187305
|
collectContextConsumers,
|
|
187306
|
+
isLowerableObjectRestDestructure,
|
|
187305
187307
|
extractSsrDefaults
|
|
187306
187308
|
} from "@barefootjs/jsx";
|
|
187307
187309
|
|
|
@@ -187805,7 +187807,9 @@ ${whenTrue}
|
|
|
187805
187807
|
renderLoop(loop) {
|
|
187806
187808
|
if (loop.clientOnly)
|
|
187807
187809
|
return "";
|
|
187808
|
-
|
|
187810
|
+
const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
|
|
187811
|
+
const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
|
|
187812
|
+
if (destructure && !supportableDestructure) {
|
|
187809
187813
|
this.errors.push({
|
|
187810
187814
|
code: "BF104",
|
|
187811
187815
|
severity: "error",
|
|
@@ -187826,13 +187830,18 @@ ${whenTrue}
|
|
|
187826
187830
|
}
|
|
187827
187831
|
const param = loop.param;
|
|
187828
187832
|
const renderedChildren = this.renderChildren(loop.children);
|
|
187829
|
-
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : param;
|
|
187833
|
+
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
|
|
187830
187834
|
const indexLocalLines = [];
|
|
187831
187835
|
if (loop.iterationShape === "keys") {
|
|
187832
187836
|
indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
|
|
187833
187837
|
} else if (loop.index) {
|
|
187834
187838
|
indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
|
|
187835
187839
|
}
|
|
187840
|
+
if (supportableDestructure) {
|
|
187841
|
+
for (const b of loop.paramBindings ?? []) {
|
|
187842
|
+
indexLocalLines.push(b.rest ? `: my $${b.name} = $${loopVar};` : `: my $${b.name} = $${loopVar}${b.path};`);
|
|
187843
|
+
}
|
|
187844
|
+
}
|
|
187836
187845
|
const prevInLoop = this.inLoop;
|
|
187837
187846
|
this.inLoop = true;
|
|
187838
187847
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
@@ -187970,6 +187979,11 @@ ${children}`;
|
|
|
187970
187979
|
elementAttrEmitter = {
|
|
187971
187980
|
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
187972
187981
|
emitExpression: (value, name) => {
|
|
187982
|
+
if (name === "style") {
|
|
187983
|
+
const css = this.tryLowerStyleObject(value.expr);
|
|
187984
|
+
if (css !== null)
|
|
187985
|
+
return `style="${css}"`;
|
|
187986
|
+
}
|
|
187973
187987
|
if (this.refuseUnsupportedAttrExpression(value.expr, name)) {
|
|
187974
187988
|
return "";
|
|
187975
187989
|
}
|
|
@@ -188026,6 +188040,19 @@ ${body}
|
|
|
188026
188040
|
emitBooleanShorthand: () => "",
|
|
188027
188041
|
emitJsxChildren: () => ""
|
|
188028
188042
|
};
|
|
188043
|
+
tryLowerStyleObject(expr) {
|
|
188044
|
+
const entries = parseStyleObjectEntries(expr);
|
|
188045
|
+
if (!entries)
|
|
188046
|
+
return null;
|
|
188047
|
+
for (const e of entries) {
|
|
188048
|
+
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188049
|
+
return null;
|
|
188050
|
+
}
|
|
188051
|
+
return entries.map((e) => e.kind === "literal" ? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}` : `${this.escapeAttrText(e.cssKey)}:<: ${this.convertExpressionToKolon(e.expr)} :>`).join(";");
|
|
188052
|
+
}
|
|
188053
|
+
escapeAttrText(s) {
|
|
188054
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
188055
|
+
}
|
|
188029
188056
|
renderAttributes(element) {
|
|
188030
188057
|
const parts = [];
|
|
188031
188058
|
for (const attr of element.attrs) {
|
|
@@ -181,6 +181,15 @@ export declare class XslateAdapter extends BaseAdapter implements IRNodeEmitter<
|
|
|
181
181
|
* AttrValue lowering for intrinsic-element attributes (Kolon).
|
|
182
182
|
*/
|
|
183
183
|
private readonly elementAttrEmitter;
|
|
184
|
+
/**
|
|
185
|
+
* Lower a `style={{ … }}` object literal to a CSS string with dynamic values
|
|
186
|
+
* interpolated as Kolon actions, e.g. `{ backgroundColor: color }` →
|
|
187
|
+
* `background-color:<: $color :>`. Returns null when the shape is unsupported
|
|
188
|
+
* or any value can't be lowered (caller falls through to BF101). (#1322)
|
|
189
|
+
*/
|
|
190
|
+
private tryLowerStyleObject;
|
|
191
|
+
/** HTML-attribute escape for static text inlined into a `"..."` attribute. */
|
|
192
|
+
private escapeAttrText;
|
|
184
193
|
private renderAttributes;
|
|
185
194
|
renderScopeMarker(_instanceIdExpr: string): string;
|
|
186
195
|
renderSlotMarker(slotId: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,OAAO,EAKP,yBAAyB,EAE1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAM3B,KAAK,aAAa,EAClB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"xslate-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/xslate-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/build.js
CHANGED
|
@@ -187292,6 +187292,7 @@ import {
|
|
|
187292
187292
|
BaseAdapter,
|
|
187293
187293
|
isBooleanAttr,
|
|
187294
187294
|
parseExpression as parseExpression2,
|
|
187295
|
+
parseStyleObjectEntries,
|
|
187295
187296
|
isSupported,
|
|
187296
187297
|
identifierPath,
|
|
187297
187298
|
emitParsedExpr,
|
|
@@ -187302,6 +187303,7 @@ import {
|
|
|
187302
187303
|
evalStringArrayJoin,
|
|
187303
187304
|
extractArrowBodyExpression,
|
|
187304
187305
|
collectContextConsumers,
|
|
187306
|
+
isLowerableObjectRestDestructure,
|
|
187305
187307
|
extractSsrDefaults
|
|
187306
187308
|
} from "@barefootjs/jsx";
|
|
187307
187309
|
|
|
@@ -187805,7 +187807,9 @@ ${whenTrue}
|
|
|
187805
187807
|
renderLoop(loop) {
|
|
187806
187808
|
if (loop.clientOnly)
|
|
187807
187809
|
return "";
|
|
187808
|
-
|
|
187810
|
+
const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
|
|
187811
|
+
const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
|
|
187812
|
+
if (destructure && !supportableDestructure) {
|
|
187809
187813
|
this.errors.push({
|
|
187810
187814
|
code: "BF104",
|
|
187811
187815
|
severity: "error",
|
|
@@ -187826,13 +187830,18 @@ ${whenTrue}
|
|
|
187826
187830
|
}
|
|
187827
187831
|
const param = loop.param;
|
|
187828
187832
|
const renderedChildren = this.renderChildren(loop.children);
|
|
187829
|
-
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : param;
|
|
187833
|
+
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
|
|
187830
187834
|
const indexLocalLines = [];
|
|
187831
187835
|
if (loop.iterationShape === "keys") {
|
|
187832
187836
|
indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
|
|
187833
187837
|
} else if (loop.index) {
|
|
187834
187838
|
indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
|
|
187835
187839
|
}
|
|
187840
|
+
if (supportableDestructure) {
|
|
187841
|
+
for (const b of loop.paramBindings ?? []) {
|
|
187842
|
+
indexLocalLines.push(b.rest ? `: my $${b.name} = $${loopVar};` : `: my $${b.name} = $${loopVar}${b.path};`);
|
|
187843
|
+
}
|
|
187844
|
+
}
|
|
187836
187845
|
const prevInLoop = this.inLoop;
|
|
187837
187846
|
this.inLoop = true;
|
|
187838
187847
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
@@ -187970,6 +187979,11 @@ ${children}`;
|
|
|
187970
187979
|
elementAttrEmitter = {
|
|
187971
187980
|
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
187972
187981
|
emitExpression: (value, name) => {
|
|
187982
|
+
if (name === "style") {
|
|
187983
|
+
const css = this.tryLowerStyleObject(value.expr);
|
|
187984
|
+
if (css !== null)
|
|
187985
|
+
return `style="${css}"`;
|
|
187986
|
+
}
|
|
187973
187987
|
if (this.refuseUnsupportedAttrExpression(value.expr, name)) {
|
|
187974
187988
|
return "";
|
|
187975
187989
|
}
|
|
@@ -188026,6 +188040,19 @@ ${body}
|
|
|
188026
188040
|
emitBooleanShorthand: () => "",
|
|
188027
188041
|
emitJsxChildren: () => ""
|
|
188028
188042
|
};
|
|
188043
|
+
tryLowerStyleObject(expr) {
|
|
188044
|
+
const entries = parseStyleObjectEntries(expr);
|
|
188045
|
+
if (!entries)
|
|
188046
|
+
return null;
|
|
188047
|
+
for (const e of entries) {
|
|
188048
|
+
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188049
|
+
return null;
|
|
188050
|
+
}
|
|
188051
|
+
return entries.map((e) => e.kind === "literal" ? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}` : `${this.escapeAttrText(e.cssKey)}:<: ${this.convertExpressionToKolon(e.expr)} :>`).join(";");
|
|
188052
|
+
}
|
|
188053
|
+
escapeAttrText(s) {
|
|
188054
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
188055
|
+
}
|
|
188029
188056
|
renderAttributes(element) {
|
|
188030
188057
|
const parts = [];
|
|
188031
188058
|
for (const attr of element.attrs) {
|
package/dist/index.js
CHANGED
|
@@ -187292,6 +187292,7 @@ import {
|
|
|
187292
187292
|
BaseAdapter,
|
|
187293
187293
|
isBooleanAttr,
|
|
187294
187294
|
parseExpression as parseExpression2,
|
|
187295
|
+
parseStyleObjectEntries,
|
|
187295
187296
|
isSupported,
|
|
187296
187297
|
identifierPath,
|
|
187297
187298
|
emitParsedExpr,
|
|
@@ -187302,6 +187303,7 @@ import {
|
|
|
187302
187303
|
evalStringArrayJoin,
|
|
187303
187304
|
extractArrowBodyExpression,
|
|
187304
187305
|
collectContextConsumers,
|
|
187306
|
+
isLowerableObjectRestDestructure,
|
|
187305
187307
|
extractSsrDefaults
|
|
187306
187308
|
} from "@barefootjs/jsx";
|
|
187307
187309
|
|
|
@@ -187805,7 +187807,9 @@ ${whenTrue}
|
|
|
187805
187807
|
renderLoop(loop) {
|
|
187806
187808
|
if (loop.clientOnly)
|
|
187807
187809
|
return "";
|
|
187808
|
-
|
|
187810
|
+
const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
|
|
187811
|
+
const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
|
|
187812
|
+
if (destructure && !supportableDestructure) {
|
|
187809
187813
|
this.errors.push({
|
|
187810
187814
|
code: "BF104",
|
|
187811
187815
|
severity: "error",
|
|
@@ -187826,13 +187830,18 @@ ${whenTrue}
|
|
|
187826
187830
|
}
|
|
187827
187831
|
const param = loop.param;
|
|
187828
187832
|
const renderedChildren = this.renderChildren(loop.children);
|
|
187829
|
-
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : param;
|
|
187833
|
+
const loopVar = loop.iterationShape === "keys" ? "__bf_item" : supportableDestructure ? "__bf_item" : param;
|
|
187830
187834
|
const indexLocalLines = [];
|
|
187831
187835
|
if (loop.iterationShape === "keys") {
|
|
187832
187836
|
indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`);
|
|
187833
187837
|
} else if (loop.index) {
|
|
187834
187838
|
indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`);
|
|
187835
187839
|
}
|
|
187840
|
+
if (supportableDestructure) {
|
|
187841
|
+
for (const b of loop.paramBindings ?? []) {
|
|
187842
|
+
indexLocalLines.push(b.rest ? `: my $${b.name} = $${loopVar};` : `: my $${b.name} = $${loopVar}${b.path};`);
|
|
187843
|
+
}
|
|
187844
|
+
}
|
|
187836
187845
|
const prevInLoop = this.inLoop;
|
|
187837
187846
|
this.inLoop = true;
|
|
187838
187847
|
const childrenUnderLoop = this.renderChildren(loop.children);
|
|
@@ -187970,6 +187979,11 @@ ${children}`;
|
|
|
187970
187979
|
elementAttrEmitter = {
|
|
187971
187980
|
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
187972
187981
|
emitExpression: (value, name) => {
|
|
187982
|
+
if (name === "style") {
|
|
187983
|
+
const css = this.tryLowerStyleObject(value.expr);
|
|
187984
|
+
if (css !== null)
|
|
187985
|
+
return `style="${css}"`;
|
|
187986
|
+
}
|
|
187973
187987
|
if (this.refuseUnsupportedAttrExpression(value.expr, name)) {
|
|
187974
187988
|
return "";
|
|
187975
187989
|
}
|
|
@@ -188026,6 +188040,19 @@ ${body}
|
|
|
188026
188040
|
emitBooleanShorthand: () => "",
|
|
188027
188041
|
emitJsxChildren: () => ""
|
|
188028
188042
|
};
|
|
188043
|
+
tryLowerStyleObject(expr) {
|
|
188044
|
+
const entries = parseStyleObjectEntries(expr);
|
|
188045
|
+
if (!entries)
|
|
188046
|
+
return null;
|
|
188047
|
+
for (const e of entries) {
|
|
188048
|
+
if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
|
|
188049
|
+
return null;
|
|
188050
|
+
}
|
|
188051
|
+
return entries.map((e) => e.kind === "literal" ? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}` : `${this.escapeAttrText(e.cssKey)}:<: ${this.convertExpressionToKolon(e.expr)} :>`).join(";");
|
|
188052
|
+
}
|
|
188053
|
+
escapeAttrText(s) {
|
|
188054
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
188055
|
+
}
|
|
188029
188056
|
renderAttributes(element) {
|
|
188030
188057
|
const parts = [];
|
|
188031
188058
|
for (const attr of element.attrs) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/xslate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Text::Xslate (Kolon) adapter for BarefootJS — compiles IR to .tx templates and ships the Xslate rendering backend; runs under any PSGI/Plack app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
"directory": "packages/adapter-xslate"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@barefootjs/shared": "0.
|
|
58
|
+
"@barefootjs/shared": "0.12.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@barefootjs/jsx": ">=0.2.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@barefootjs/adapter-tests": "0.1.0",
|
|
65
|
-
"@barefootjs/jsx": "0.
|
|
65
|
+
"@barefootjs/jsx": "0.12.0",
|
|
66
66
|
"typescript": "^5.0.0"
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -52,10 +52,11 @@ runAdapterConformanceTests({
|
|
|
52
52
|
{ code: 'BF103', severity: 'error' },
|
|
53
53
|
{ code: 'BF104', severity: 'error' },
|
|
54
54
|
],
|
|
55
|
-
// Rest-destructure `.map()` callbacks — the
|
|
56
|
-
//
|
|
57
|
-
// (
|
|
58
|
-
|
|
55
|
+
// Rest-destructure `.map()` callbacks — the object-rest shape read via
|
|
56
|
+
// member access (`rest-destructure-object-in-map`) now lowers via Kolon
|
|
57
|
+
// `: my` binding locals (`$rest` aliases the item). The other three stay
|
|
58
|
+
// refused: rest SPREAD needs a residual object, array-index / nested paths
|
|
59
|
+
// can't unpack a tuple (same surface as mojo).
|
|
59
60
|
'rest-destructure-object-spread-in-map': [{ code: 'BF104', severity: 'error' }],
|
|
60
61
|
'rest-destructure-array-in-map': [{ code: 'BF104', severity: 'error' }],
|
|
61
62
|
'rest-destructure-nested-in-map': [{ code: 'BF104', severity: 'error' }],
|
|
@@ -72,14 +73,10 @@ runAdapterConformanceTests({
|
|
|
72
73
|
// above — refused with BF101 for the identical Kolon engine reason, not a
|
|
73
74
|
// render-mismatch (so it's pinned here, not in `skipJsx`).
|
|
74
75
|
'kbd': [{ code: 'BF101', severity: 'error' }],
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
// with BF101 (no idiomatic Kolon form). mojo *skips* this fixture because
|
|
80
|
-
// its EP path emits invalid Perl silently — Xslate's build-time diagnostic
|
|
81
|
-
// is the stronger contract, so it's pinned here rather than skipped.
|
|
82
|
-
'style-object-dynamic': [{ code: 'BF101', severity: 'error' }],
|
|
76
|
+
// `style-3-signals` / `style-object-dynamic` no longer pinned — a
|
|
77
|
+
// `style={{ … }}` object literal now lowers to a CSS string with dynamic
|
|
78
|
+
// values interpolated (`background-color:<: $color :>;padding:8px`) via
|
|
79
|
+
// `tryLowerStyleObject` (#1322).
|
|
83
80
|
// Tagged-template-literal call in a className — same family, same
|
|
84
81
|
// refusal (BF101).
|
|
85
82
|
'tagged-template-classname': [{ code: 'BF101', severity: 'error' }],
|
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
type AttrValueEmitter,
|
|
56
56
|
isBooleanAttr,
|
|
57
57
|
parseExpression,
|
|
58
|
+
parseStyleObjectEntries,
|
|
58
59
|
isSupported,
|
|
59
60
|
identifierPath,
|
|
60
61
|
emitParsedExpr,
|
|
@@ -65,6 +66,7 @@ import {
|
|
|
65
66
|
evalStringArrayJoin,
|
|
66
67
|
extractArrowBodyExpression,
|
|
67
68
|
collectContextConsumers,
|
|
69
|
+
isLowerableObjectRestDestructure,
|
|
68
70
|
type ContextConsumer,
|
|
69
71
|
extractSsrDefaults,
|
|
70
72
|
} from '@barefootjs/jsx'
|
|
@@ -789,7 +791,14 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
789
791
|
// `({ name, age }) => ...`) lowers to invalid Kolon — Kolon's `for LIST
|
|
790
792
|
// -> $item` binds a single scalar and can't unpack a tuple. Surface this
|
|
791
793
|
// at build time instead of shipping a broken template line.
|
|
792
|
-
|
|
794
|
+
// A destructure loop param is lowerable for the object-rest / simple-field
|
|
795
|
+
// shape (`.map(({ id, title, ...rest }) => …)`, `rest` read via member
|
|
796
|
+
// access): each binding becomes a Kolon `: my` local off the per-item var,
|
|
797
|
+
// so the body's `$id` / `$rest.flag` resolve. Array-index / nested /
|
|
798
|
+
// rest-spread shapes still can't unpack a tuple → BF104. (#1310)
|
|
799
|
+
const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0)
|
|
800
|
+
const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop)
|
|
801
|
+
if (destructure && !supportableDestructure) {
|
|
793
802
|
this.errors.push({
|
|
794
803
|
code: 'BF104',
|
|
795
804
|
severity: 'error',
|
|
@@ -822,17 +831,30 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
822
831
|
// For `keys`-shape iterations the callback param IS the index. We iterate
|
|
823
832
|
// the array but bind the loop var to a throwaway and expose the index as
|
|
824
833
|
// `$param`. Kolon's `$~loopvar.index` provides the 0-based index.
|
|
825
|
-
const loopVar = loop.iterationShape === 'keys'
|
|
834
|
+
const loopVar = loop.iterationShape === 'keys'
|
|
835
|
+
? '__bf_item'
|
|
836
|
+
: supportableDestructure ? '__bf_item' : param
|
|
826
837
|
|
|
827
838
|
// Index alias: when an explicit `index` param is present (`.map((x, i) =>
|
|
828
839
|
// ...)`) or the iteration is `keys`-shaped, expose it via a `: my` Kolon
|
|
829
|
-
// local bound to the loop variable's `.index` accessor.
|
|
840
|
+
// local bound to the loop variable's `.index` accessor. A supported
|
|
841
|
+
// destructure param adds one `: my` local per binding (`rest` aliases the
|
|
842
|
+
// item so `$rest.flag` resolves).
|
|
830
843
|
const indexLocalLines: string[] = []
|
|
831
844
|
if (loop.iterationShape === 'keys') {
|
|
832
845
|
indexLocalLines.push(`: my $${param} = $~${loopVar}.index;`)
|
|
833
846
|
} else if (loop.index) {
|
|
834
847
|
indexLocalLines.push(`: my $${loop.index} = $~${loopVar}.index;`)
|
|
835
848
|
}
|
|
849
|
+
if (supportableDestructure) {
|
|
850
|
+
for (const b of loop.paramBindings ?? []) {
|
|
851
|
+
indexLocalLines.push(
|
|
852
|
+
b.rest
|
|
853
|
+
? `: my $${b.name} = $${loopVar};`
|
|
854
|
+
: `: my $${b.name} = $${loopVar}${b.path};`,
|
|
855
|
+
)
|
|
856
|
+
}
|
|
857
|
+
}
|
|
836
858
|
|
|
837
859
|
const prevInLoop = this.inLoop
|
|
838
860
|
this.inLoop = true
|
|
@@ -1074,9 +1096,15 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1074
1096
|
private readonly elementAttrEmitter: AttrValueEmitter = {
|
|
1075
1097
|
emitLiteral: (value, name) => `${name}="${value.value}"`,
|
|
1076
1098
|
emitExpression: (value, name) => {
|
|
1099
|
+
// `style={{ … }}` object literal → a CSS string with dynamic values
|
|
1100
|
+
// interpolated, instead of refusing the bare object with BF101 (#1322).
|
|
1101
|
+
if (name === 'style') {
|
|
1102
|
+
const css = this.tryLowerStyleObject(value.expr)
|
|
1103
|
+
if (css !== null) return `style="${css}"`
|
|
1104
|
+
}
|
|
1077
1105
|
// Refuse shapes that the lowering pipeline can't represent in Kolon —
|
|
1078
|
-
//
|
|
1079
|
-
//
|
|
1106
|
+
// tagged-template-literal call expressions (`cn\`base \${tone()}\``).
|
|
1107
|
+
// Same gate as the Mojo adapter.
|
|
1080
1108
|
if (this.refuseUnsupportedAttrExpression(value.expr, name)) {
|
|
1081
1109
|
return ''
|
|
1082
1110
|
}
|
|
@@ -1177,6 +1205,41 @@ export class XslateAdapter extends BaseAdapter implements IRNodeEmitter<XslateRe
|
|
|
1177
1205
|
emitJsxChildren: () => '',
|
|
1178
1206
|
}
|
|
1179
1207
|
|
|
1208
|
+
/**
|
|
1209
|
+
* Lower a `style={{ … }}` object literal to a CSS string with dynamic values
|
|
1210
|
+
* interpolated as Kolon actions, e.g. `{ backgroundColor: color }` →
|
|
1211
|
+
* `background-color:<: $color :>`. Returns null when the shape is unsupported
|
|
1212
|
+
* or any value can't be lowered (caller falls through to BF101). (#1322)
|
|
1213
|
+
*/
|
|
1214
|
+
private tryLowerStyleObject(expr: string): string | null {
|
|
1215
|
+
const entries = parseStyleObjectEntries(expr)
|
|
1216
|
+
if (!entries) return null
|
|
1217
|
+
for (const e of entries) {
|
|
1218
|
+
if (e.kind === 'expr' && !isSupported(parseExpression(e.expr)).supported) return null
|
|
1219
|
+
}
|
|
1220
|
+
// The static CSS key + literal value are inlined into a double-quoted
|
|
1221
|
+
// `style="..."` attribute as raw template text, so HTML-attr escape them
|
|
1222
|
+
// (a value like `'"'` would otherwise break the attribute / inject
|
|
1223
|
+
// markup). The dynamic arm's `<: … :>` is HTML-escaped by Kolon.
|
|
1224
|
+
return entries
|
|
1225
|
+
.map(e =>
|
|
1226
|
+
e.kind === 'literal'
|
|
1227
|
+
? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}`
|
|
1228
|
+
: `${this.escapeAttrText(e.cssKey)}:<: ${this.convertExpressionToKolon(e.expr)} :>`,
|
|
1229
|
+
)
|
|
1230
|
+
.join(';')
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
/** HTML-attribute escape for static text inlined into a `"..."` attribute. */
|
|
1234
|
+
private escapeAttrText(s: string): string {
|
|
1235
|
+
return s
|
|
1236
|
+
.replace(/&/g, '&')
|
|
1237
|
+
.replace(/"/g, '"')
|
|
1238
|
+
.replace(/'/g, ''')
|
|
1239
|
+
.replace(/</g, '<')
|
|
1240
|
+
.replace(/>/g, '>')
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1180
1243
|
private renderAttributes(element: IRElement): string {
|
|
1181
1244
|
const parts: string[] = []
|
|
1182
1245
|
|