@barefootjs/jsx 0.33.0 → 0.33.2
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/analyzer.d.ts.map +1 -1
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/expression-parser.d.ts +14 -0
- package/dist/expression-parser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +268 -79
- package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-inner-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-loop-child-arm.d.ts +8 -0
- package/dist/ir-to-client-js/control-flow/plan/build-loop-child-arm.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/build-reactive-effects.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/plan/inner-loop.d.ts +12 -0
- package/dist/ir-to-client-js/control-flow/plan/inner-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/inner-loop.d.ts +1 -0
- package/dist/ir-to-client-js/control-flow/stringify/inner-loop.d.ts.map +1 -1
- package/dist/ir-to-client-js/control-flow/stringify/lazy-row.d.ts.map +1 -1
- package/dist/ir-to-client-js/element-refs.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/ir-to-client-js/emit-registration.d.ts.map +1 -1
- package/dist/ir-to-client-js/html-template.d.ts +7 -7
- package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
- package/dist/ir-to-client-js/imports.d.ts +2 -2
- package/dist/ir-to-client-js/imports.d.ts.map +1 -1
- package/dist/ir-to-client-js/index.d.ts.map +1 -1
- package/dist/ir-to-client-js/phases/provider-and-child-inits.d.ts.map +1 -1
- package/dist/ir-to-client-js/prop-handling.d.ts +33 -0
- package/dist/ir-to-client-js/prop-handling.d.ts.map +1 -1
- package/dist/ir-to-client-js/reactivity.d.ts +5 -0
- package/dist/ir-to-client-js/reactivity.d.ts.map +1 -1
- package/dist/ir-to-client-js/rewrite-props-object.d.ts +36 -8
- package/dist/ir-to-client-js/rewrite-props-object.d.ts.map +1 -1
- package/dist/ir-to-client-js/types.d.ts +21 -0
- package/dist/ir-to-client-js/types.d.ts.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +23 -6
- package/src/__tests__/binding-scope-ratchet.test.ts +5 -1
- package/src/__tests__/child-components-in-map.test.ts +11 -3
- package/src/__tests__/client-js-generation.test.ts +48 -1
- package/src/__tests__/inline-jsx-callback.test.ts +55 -0
- package/src/__tests__/ir-jsx-props.test.ts +148 -0
- package/src/__tests__/issue-2705-branch-inner-loop-container.test.ts +91 -0
- package/src/__tests__/issue-2723-prop-alias-reactivity.test.ts +124 -0
- package/src/__tests__/markup-prop-brand.test.ts +49 -0
- package/src/__tests__/nested-loop-conditional.test.ts +20 -11
- package/src/__tests__/return-through-local-var.test.ts +269 -0
- package/src/__tests__/rewrite-props-object.test.ts +41 -4
- package/src/analyzer.ts +71 -0
- package/src/errors.ts +17 -1
- package/src/expression-parser.ts +26 -0
- package/src/index.ts +1 -1
- package/src/ir-to-client-js/collect-elements.ts +49 -45
- package/src/ir-to-client-js/control-flow/plan/build-inner-loop.ts +19 -0
- package/src/ir-to-client-js/control-flow/plan/build-loop-child-arm.ts +22 -3
- package/src/ir-to-client-js/control-flow/plan/build-reactive-effects.ts +5 -2
- package/src/ir-to-client-js/control-flow/plan/inner-loop.ts +12 -0
- package/src/ir-to-client-js/control-flow/stringify/inner-loop.ts +9 -0
- package/src/ir-to-client-js/control-flow/stringify/lazy-row.ts +7 -1
- package/src/ir-to-client-js/element-refs.ts +8 -0
- package/src/ir-to-client-js/emit-reactive.ts +91 -23
- package/src/ir-to-client-js/emit-registration.ts +26 -7
- package/src/ir-to-client-js/generate-init.ts +1 -1
- package/src/ir-to-client-js/html-template.ts +8 -8
- package/src/ir-to-client-js/imports.ts +5 -0
- package/src/ir-to-client-js/index.ts +10 -4
- package/src/ir-to-client-js/phases/provider-and-child-inits.ts +5 -1
- package/src/ir-to-client-js/prop-handling.ts +94 -0
- package/src/ir-to-client-js/reactivity.ts +59 -0
- package/src/ir-to-client-js/rewrite-props-object.ts +50 -10
- package/src/ir-to-client-js/types.ts +21 -0
- package/src/jsx-to-ir.ts +204 -9
- package/src/types.ts +14 -0
package/dist/index.js
CHANGED
|
@@ -228,6 +228,9 @@ var ARRAY_METHOD_NAMES = [
|
|
|
228
228
|
"padEnd",
|
|
229
229
|
"flat"
|
|
230
230
|
];
|
|
231
|
+
var SORT_KEY_TYPES = ["numeric", "string", "auto"];
|
|
232
|
+
var SORT_KEY_TARGETS = ["self", "field"];
|
|
233
|
+
var SORT_KEY_DIRECTIONS = ["asc", "desc"];
|
|
231
234
|
var UNSUPPORTED_METHODS = new Set([
|
|
232
235
|
"filter",
|
|
233
236
|
"map",
|
|
@@ -5634,6 +5637,7 @@ var ErrorCodes = {
|
|
|
5634
5637
|
MISSING_KEY_IN_LIST: "BF023",
|
|
5635
5638
|
MISSING_KEY_IN_NESTED_LIST: "BF024",
|
|
5636
5639
|
UNSUPPORTED_DESTRUCTURE_REST: "BF025",
|
|
5640
|
+
RETURN_VALUE_NOT_JSX: "BF027",
|
|
5637
5641
|
PROPS_DESTRUCTURING: "BF043",
|
|
5638
5642
|
SIGNAL_GETTER_NOT_CALLED: "BF044",
|
|
5639
5643
|
JSX_IN_LOCAL_FUNCTION: "BF045",
|
|
@@ -5665,6 +5669,7 @@ var errorMessages = {
|
|
|
5665
5669
|
[ErrorCodes.MISSING_KEY_IN_LIST]: "Missing key attribute in list rendering. Add a key prop for efficient updates",
|
|
5666
5670
|
[ErrorCodes.MISSING_KEY_IN_NESTED_LIST]: "Nested .map() loop requires key attribute for event delegation. Add a key prop to elements in the inner loop",
|
|
5667
5671
|
[ErrorCodes.UNSUPPORTED_DESTRUCTURE_REST]: "Computed property key in .map() callback destructure is not supported. Rewrite the callback to destructure explicit bindings (e.g., `({ a, b }) => ...`) so the compiler can rewrite references to per-item signal accessors.",
|
|
5672
|
+
[ErrorCodes.RETURN_VALUE_NOT_JSX]: "Component's return value is not recognized as JSX — return the JSX expression directly instead of binding it to a local variable first.",
|
|
5668
5673
|
[ErrorCodes.PROPS_DESTRUCTURING]: "Props destructuring in function parameters breaks reactivity. Use props object directly.",
|
|
5669
5674
|
[ErrorCodes.SIGNAL_GETTER_NOT_CALLED]: "Signal/memo getter passed without calling it. Use getter() to read the value.",
|
|
5670
5675
|
[ErrorCodes.JSX_IN_LOCAL_FUNCTION]: "Local function returns JSX but cannot be inlined. Extract it as a top-level PascalCase component or use a single return statement.",
|
|
@@ -6306,6 +6311,14 @@ function visitComponentBody(node, ctx) {
|
|
|
6306
6311
|
}
|
|
6307
6312
|
}
|
|
6308
6313
|
if (isTopLevel && (ts9.isTryStatement(node) || ts9.isSwitchStatement(node) || ts9.isForStatement(node) || ts9.isForInStatement(node) || ts9.isForOfStatement(node) || ts9.isWhileStatement(node) || ts9.isDoStatement(node) || ts9.isThrowStatement(node) || ts9.isBlock(node) && node.parent === ctx.componentBodyBlock)) {
|
|
6314
|
+
if (ts9.isBlock(node)) {
|
|
6315
|
+
const returnedLocal = findBlockBodyReturnedJsxLocalName(node);
|
|
6316
|
+
if (returnedLocal) {
|
|
6317
|
+
ctx.errors.push(createError(ErrorCodes.RETURN_VALUE_NOT_JSX, getSourceLocation(node, ctx.sourceFile, ctx.filePath), {
|
|
6318
|
+
message: `Component '${ctx.componentName ?? "(unknown)"}' return value is not recognized ` + `as JSX — return the JSX expression directly instead of binding it to a local ` + `variable first (\`return ${returnedLocal}\` after \`const ${returnedLocal} = ` + `<jsx/>\` is not resolved at return position).`
|
|
6319
|
+
}));
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
6309
6322
|
collectInitStatement(node, ctx);
|
|
6310
6323
|
return;
|
|
6311
6324
|
}
|
|
@@ -6341,6 +6354,31 @@ function unwrapJsxTransparent(expr) {
|
|
|
6341
6354
|
}
|
|
6342
6355
|
return current;
|
|
6343
6356
|
}
|
|
6357
|
+
function findBlockBodyReturnedJsxLocalName(block) {
|
|
6358
|
+
const stmts = block.statements;
|
|
6359
|
+
const last = stmts[stmts.length - 1];
|
|
6360
|
+
if (!last || !ts9.isReturnStatement(last) || !last.expression)
|
|
6361
|
+
return null;
|
|
6362
|
+
const returned = unwrapJsxTransparent(last.expression);
|
|
6363
|
+
if (!ts9.isIdentifier(returned))
|
|
6364
|
+
return null;
|
|
6365
|
+
const name = returned.text;
|
|
6366
|
+
for (const stmt of stmts) {
|
|
6367
|
+
if (!ts9.isVariableStatement(stmt))
|
|
6368
|
+
continue;
|
|
6369
|
+
for (const decl of stmt.declarationList.declarations) {
|
|
6370
|
+
if (!ts9.isIdentifier(decl.name) || decl.name.text !== name || !decl.initializer)
|
|
6371
|
+
continue;
|
|
6372
|
+
let init = decl.initializer;
|
|
6373
|
+
while (ts9.isParenthesizedExpression(init))
|
|
6374
|
+
init = init.expression;
|
|
6375
|
+
if (ts9.isJsxElement(init) || ts9.isJsxSelfClosingElement(init) || ts9.isJsxFragment(init) || initializerShapeContainsJsx(init) || isMapLikeCallWithJsx(init)) {
|
|
6376
|
+
return name;
|
|
6377
|
+
}
|
|
6378
|
+
}
|
|
6379
|
+
}
|
|
6380
|
+
return null;
|
|
6381
|
+
}
|
|
6344
6382
|
function extractJsxFromExpression(expr) {
|
|
6345
6383
|
const inner = unwrapJsxTransparent(expr);
|
|
6346
6384
|
if (ts9.isJsxElement(inner) || ts9.isJsxFragment(inner) || ts9.isJsxSelfClosingElement(inner)) {
|
|
@@ -10710,8 +10748,14 @@ function buildIRRoot(analyzer) {
|
|
|
10710
10748
|
}
|
|
10711
10749
|
ctx.isRoot = false;
|
|
10712
10750
|
const ir = transformJsxExpression(jsxReturn, ctx);
|
|
10713
|
-
if (ir === null)
|
|
10751
|
+
if (ir === null) {
|
|
10752
|
+
if (ts13.isIdentifier(jsxReturn) && (analyzer.jsxConstants.has(jsxReturn.text) || analyzer.inlineableJsxConsts.has(jsxReturn.text))) {
|
|
10753
|
+
analyzer.errors.push(createError(ErrorCodes.RETURN_VALUE_NOT_JSX, getSourceLocation(jsxReturn, analyzer.sourceFile, analyzer.filePath), {
|
|
10754
|
+
message: `Component '${analyzer.componentName ?? "(unknown)"}' return value is not recognized ` + `as JSX — return the JSX expression directly instead of binding it to a local variable ` + `first (\`return ${jsxReturn.text}\` after \`const ${jsxReturn.text} = <jsx/>\` is not ` + `resolved at return position).`
|
|
10755
|
+
}));
|
|
10756
|
+
}
|
|
10714
10757
|
return null;
|
|
10758
|
+
}
|
|
10715
10759
|
return wrapInScopeElement(ir);
|
|
10716
10760
|
}
|
|
10717
10761
|
function needsScopeWrapper(ir) {
|
|
@@ -11161,6 +11205,31 @@ function unwrapHoistedFragment(node) {
|
|
|
11161
11205
|
return node;
|
|
11162
11206
|
return { ...only, needsScope: true };
|
|
11163
11207
|
}
|
|
11208
|
+
function markDataKeyCarrier(children) {
|
|
11209
|
+
for (let i = 0;i < children.length; i++) {
|
|
11210
|
+
const marked = markCarrierIn(children[i]);
|
|
11211
|
+
if (!marked)
|
|
11212
|
+
continue;
|
|
11213
|
+
const out = children.slice();
|
|
11214
|
+
out[i] = marked;
|
|
11215
|
+
return out;
|
|
11216
|
+
}
|
|
11217
|
+
return children;
|
|
11218
|
+
}
|
|
11219
|
+
function markCarrierIn(node) {
|
|
11220
|
+
if (node.type === "element") {
|
|
11221
|
+
return { ...node, carriesDataKey: true };
|
|
11222
|
+
}
|
|
11223
|
+
if (node.type === "conditional") {
|
|
11224
|
+
const cond = node;
|
|
11225
|
+
const whenTrue = markCarrierIn(cond.whenTrue);
|
|
11226
|
+
const whenFalse = markCarrierIn(cond.whenFalse);
|
|
11227
|
+
if (!whenTrue && !whenFalse)
|
|
11228
|
+
return null;
|
|
11229
|
+
return { ...cond, whenTrue: whenTrue ?? cond.whenTrue, whenFalse: whenFalse ?? cond.whenFalse };
|
|
11230
|
+
}
|
|
11231
|
+
return null;
|
|
11232
|
+
}
|
|
11164
11233
|
function transformFragment(node, ctx) {
|
|
11165
11234
|
const isFragmentRoot = ctx.isRoot;
|
|
11166
11235
|
const isTransparent = isFragmentRoot && isTransparentFragment(node, ctx);
|
|
@@ -11171,7 +11240,7 @@ function transformFragment(node, ctx) {
|
|
|
11171
11240
|
const needsScopeComment = isFragmentRoot && !isTransparent || undefined;
|
|
11172
11241
|
return {
|
|
11173
11242
|
type: "fragment",
|
|
11174
|
-
children,
|
|
11243
|
+
children: needsScopeComment ? markDataKeyCarrier(children) : children,
|
|
11175
11244
|
transparent: isTransparent || undefined,
|
|
11176
11245
|
needsScopeComment,
|
|
11177
11246
|
loc: getSourceLocation(node, ctx.sourceFile, ctx.filePath)
|
|
@@ -13826,6 +13895,35 @@ function getStringValue(node) {
|
|
|
13826
13895
|
}
|
|
13827
13896
|
return null;
|
|
13828
13897
|
}
|
|
13898
|
+
function unwrapTransparentTsWrappers(node) {
|
|
13899
|
+
let n = node;
|
|
13900
|
+
while (ts13.isParenthesizedExpression(n) || ts13.isAsExpression(n) || ts13.isSatisfiesExpression(n) || ts13.isNonNullExpression(n)) {
|
|
13901
|
+
n = n.expression;
|
|
13902
|
+
}
|
|
13903
|
+
return n;
|
|
13904
|
+
}
|
|
13905
|
+
function expressionWrapsJsx(node) {
|
|
13906
|
+
const n = unwrapTransparentTsWrappers(node);
|
|
13907
|
+
if (ts13.isJsxElement(n) || ts13.isJsxSelfClosingElement(n) || ts13.isJsxFragment(n))
|
|
13908
|
+
return true;
|
|
13909
|
+
if (ts13.isConditionalExpression(n)) {
|
|
13910
|
+
return expressionWrapsJsx(n.whenTrue) || expressionWrapsJsx(n.whenFalse);
|
|
13911
|
+
}
|
|
13912
|
+
if (ts13.isArrayLiteralExpression(n)) {
|
|
13913
|
+
return n.elements.some((el) => expressionWrapsJsx(ts13.isSpreadElement(el) ? el.expression : el));
|
|
13914
|
+
}
|
|
13915
|
+
return false;
|
|
13916
|
+
}
|
|
13917
|
+
function reportNakedJsxWrapperProp(ctx, attr, propName, jsxExpr) {
|
|
13918
|
+
const shape = ts13.isConditionalExpression(jsxExpr) ? "a ternary" : "an array literal";
|
|
13919
|
+
ctx.analyzer.errors.push(createError(ErrorCodes.UNSUPPORTED_JSX_PATTERN, getSourceLocation(attr, ctx.sourceFile, ctx.filePath), {
|
|
13920
|
+
message: `Prop '${propName}' is ${shape} wrapping JSX (${jsxExpr.getText(ctx.sourceFile)}). ` + `This shape is not compiled — only a JSX element/fragment given DIRECTLY as the prop value is.`,
|
|
13921
|
+
suggestion: {
|
|
13922
|
+
message: `Move the conditional/array out of the prop position: compute it in a local ` + `const and pass it as the component's children instead of a named prop ` + `(e.g. const ${propName} = ${jsxExpr.getText(ctx.sourceFile)}; <Comp>{${propName}}</Comp>). ` + `Wrapping the ternary/array in a fragment at the prop position ` + `(${propName}={<>{${jsxExpr.getText(ctx.sourceFile)}}</>}) is NOT a safe escape here: it compiles, ` + `but the child's own reactive prop getter receives the branch's HTML unbranded and re-escapes it as ` + `text on the child's very next reactive run, corrupting the DOM (a narrower gap #2651's door ` + `inventory left open — tracked separately).`,
|
|
13923
|
+
escape: [{ kind: "rewrite" }]
|
|
13924
|
+
}
|
|
13925
|
+
}));
|
|
13926
|
+
}
|
|
13829
13927
|
function processComponentProps(attributes, ctx) {
|
|
13830
13928
|
const props = [];
|
|
13831
13929
|
for (const attr of attributes.properties) {
|
|
@@ -13837,10 +13935,7 @@ function processComponentProps(attributes, ctx) {
|
|
|
13837
13935
|
continue;
|
|
13838
13936
|
const name = attr.name.getText(ctx.sourceFile);
|
|
13839
13937
|
if (attr.initializer && ts13.isJsxExpression(attr.initializer) && attr.initializer.expression) {
|
|
13840
|
-
|
|
13841
|
-
while (ts13.isParenthesizedExpression(jsxExpr)) {
|
|
13842
|
-
jsxExpr = jsxExpr.expression;
|
|
13843
|
-
}
|
|
13938
|
+
const jsxExpr = unwrapTransparentTsWrappers(attr.initializer.expression);
|
|
13844
13939
|
if (ts13.isJsxElement(jsxExpr) || ts13.isJsxSelfClosingElement(jsxExpr) || ts13.isJsxFragment(jsxExpr)) {
|
|
13845
13940
|
const prevInsideComponentChildren = ctx.insideComponentChildren;
|
|
13846
13941
|
ctx.insideComponentChildren = true;
|
|
@@ -13855,6 +13950,10 @@ function processComponentProps(attributes, ctx) {
|
|
|
13855
13950
|
continue;
|
|
13856
13951
|
}
|
|
13857
13952
|
}
|
|
13953
|
+
if ((ts13.isConditionalExpression(jsxExpr) || ts13.isArrayLiteralExpression(jsxExpr)) && expressionWrapsJsx(jsxExpr)) {
|
|
13954
|
+
reportNakedJsxWrapperProp(ctx, attr, name, jsxExpr);
|
|
13955
|
+
continue;
|
|
13956
|
+
}
|
|
13858
13957
|
}
|
|
13859
13958
|
let value = getAttributeValue(attr, ctx);
|
|
13860
13959
|
if (value.kind === "template") {
|
|
@@ -14238,6 +14337,50 @@ function buildIfStatementChain(analyzer, ctx, opts) {
|
|
|
14238
14337
|
}
|
|
14239
14338
|
|
|
14240
14339
|
// src/ir-to-client-js/prop-handling.ts
|
|
14340
|
+
function resolveRestSpreadOrigin(ctx, name) {
|
|
14341
|
+
const byName = localConstantValues(ctx);
|
|
14342
|
+
const visited = new Set;
|
|
14343
|
+
let current = name.trim();
|
|
14344
|
+
while (current !== undefined && !visited.has(current)) {
|
|
14345
|
+
if (ctx.restPropsName && current === ctx.restPropsName)
|
|
14346
|
+
return "rest";
|
|
14347
|
+
if (ctx.propsObjectName && current === ctx.propsObjectName)
|
|
14348
|
+
return "props";
|
|
14349
|
+
visited.add(current);
|
|
14350
|
+
current = byName.get(current)?.trim();
|
|
14351
|
+
}
|
|
14352
|
+
return null;
|
|
14353
|
+
}
|
|
14354
|
+
var _localConstantValuesCache = new WeakMap;
|
|
14355
|
+
function localConstantValues(ctx) {
|
|
14356
|
+
const cached = _localConstantValuesCache.get(ctx);
|
|
14357
|
+
if (cached)
|
|
14358
|
+
return cached;
|
|
14359
|
+
const byName = new Map;
|
|
14360
|
+
for (const constant of ctx.localConstants) {
|
|
14361
|
+
if (!byName.has(constant.name))
|
|
14362
|
+
byName.set(constant.name, constant.value);
|
|
14363
|
+
}
|
|
14364
|
+
_localConstantValuesCache.set(ctx, byName);
|
|
14365
|
+
return byName;
|
|
14366
|
+
}
|
|
14367
|
+
var _restSpreadNamesCache = new WeakMap;
|
|
14368
|
+
function resolveRestSpreadNames(ctx) {
|
|
14369
|
+
const cached = _restSpreadNamesCache.get(ctx);
|
|
14370
|
+
if (cached)
|
|
14371
|
+
return cached;
|
|
14372
|
+
const names = new Set;
|
|
14373
|
+
if (ctx.restPropsName)
|
|
14374
|
+
names.add(ctx.restPropsName);
|
|
14375
|
+
if (ctx.propsObjectName)
|
|
14376
|
+
names.add(ctx.propsObjectName);
|
|
14377
|
+
for (const constant of ctx.localConstants) {
|
|
14378
|
+
if (resolveRestSpreadOrigin(ctx, constant.name) !== null)
|
|
14379
|
+
names.add(constant.name);
|
|
14380
|
+
}
|
|
14381
|
+
_restSpreadNamesCache.set(ctx, names);
|
|
14382
|
+
return names;
|
|
14383
|
+
}
|
|
14241
14384
|
function expandDynamicPropValue(value, ctx, scope) {
|
|
14242
14385
|
const trimmedValue = value.trim();
|
|
14243
14386
|
if (scope?.isBound(trimmedValue))
|
|
@@ -14326,6 +14469,9 @@ function decideWrapForChildProp(expandedValue, ctx, prop) {
|
|
|
14326
14469
|
return decideWrapForAttr(expandedValue, ctx, prop);
|
|
14327
14470
|
}
|
|
14328
14471
|
function needsEffectWrapper(expr, ctx, freeIdentifiers2) {
|
|
14472
|
+
return needsEffectWrapperCore(expr, ctx, freeIdentifiers2, new Set);
|
|
14473
|
+
}
|
|
14474
|
+
function needsEffectWrapperCore(expr, ctx, freeIdentifiers2, visitedConstants) {
|
|
14329
14475
|
for (const signal of ctx.signals) {
|
|
14330
14476
|
if (identifierCallPattern(signal.getter).test(expr)) {
|
|
14331
14477
|
return true;
|
|
@@ -14348,6 +14494,19 @@ function needsEffectWrapper(expr, ctx, freeIdentifiers2) {
|
|
|
14348
14494
|
if (propsAccess.test(expr))
|
|
14349
14495
|
return true;
|
|
14350
14496
|
}
|
|
14497
|
+
for (const constant of ctx.localConstants) {
|
|
14498
|
+
if (visitedConstants.has(constant.name))
|
|
14499
|
+
continue;
|
|
14500
|
+
if (constant.value === undefined || constant.containsArrow)
|
|
14501
|
+
continue;
|
|
14502
|
+
const referenced = freeIdentifiers2 ? freeIdentifiers2.has(constant.name) : tokenContainsIdent(expr, constant.name);
|
|
14503
|
+
if (!referenced)
|
|
14504
|
+
continue;
|
|
14505
|
+
visitedConstants.add(constant.name);
|
|
14506
|
+
if (needsEffectWrapperCore(constant.value, ctx, constant.freeIdentifiers, visitedConstants)) {
|
|
14507
|
+
return true;
|
|
14508
|
+
}
|
|
14509
|
+
}
|
|
14351
14510
|
return false;
|
|
14352
14511
|
}
|
|
14353
14512
|
function classifyReactivity(expr, ctx, loopParam, loopParamBindings, freeIdentifiers2) {
|
|
@@ -14936,10 +15095,11 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
14936
15095
|
const innerPreambleNames = preambleNamesOf(n);
|
|
14937
15096
|
if (ctx) {
|
|
14938
15097
|
for (const child of n.children) {
|
|
14939
|
-
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings,
|
|
14940
|
-
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings,
|
|
15098
|
+
bindings.reactiveTexts.push(...collectLoopChildReactiveTexts(child, ctx, n.param, n.paramBindings, true, innerPreambleNames, n.index));
|
|
15099
|
+
bindings.reactiveAttrs.push(...collectLoopChildReactiveAttrs(child, ctx, n.param, n.paramBindings, true, innerPreambleNames, n.index));
|
|
14941
15100
|
bindings.refs.push(...collectLoopChildRefs(child));
|
|
14942
15101
|
}
|
|
15102
|
+
bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings, innerPreambleNames, n.index));
|
|
14943
15103
|
}
|
|
14944
15104
|
let childComponents;
|
|
14945
15105
|
if (collectBindings) {
|
|
@@ -14963,9 +15123,6 @@ function collectInnerLoops(nodes, siblingOffsets, outerLoopParam, ctx, options)
|
|
|
14963
15123
|
for (const child of n.children) {
|
|
14964
15124
|
bindings.events.push(...collectLoopChildEventsWithNesting(child));
|
|
14965
15125
|
}
|
|
14966
|
-
if (ctx) {
|
|
14967
|
-
bindings.conditionals.push(...collectLoopChildConditionals({ type: "fragment", children: n.children, loc: n.loc }, ctx, siblingOffsets, n.param, n.paramBindings, innerPreambleNames, n.index));
|
|
14968
|
-
}
|
|
14969
15126
|
}
|
|
14970
15127
|
result.push({
|
|
14971
15128
|
kind: "nested",
|
|
@@ -15023,24 +15180,14 @@ function jsxChildrenContainComponent(nodes) {
|
|
|
15023
15180
|
function isSingleElementJsxChildren2(nodes) {
|
|
15024
15181
|
return nodes.length === 1 && nodes[0].type === "element";
|
|
15025
15182
|
}
|
|
15026
|
-
function buildRestSpreadNames(ctx) {
|
|
15027
|
-
const names = new Set;
|
|
15028
|
-
if (ctx.restPropsName)
|
|
15029
|
-
names.add(ctx.restPropsName);
|
|
15030
|
-
if (ctx.propsObjectName)
|
|
15031
|
-
names.add(ctx.propsObjectName);
|
|
15032
|
-
return names;
|
|
15033
|
-
}
|
|
15034
15183
|
function buildComponentPropsExpr(props, ctx) {
|
|
15035
|
-
const restName = ctx.restPropsName;
|
|
15036
|
-
const propsObjName = ctx.propsObjectName;
|
|
15037
15184
|
const knownSpreadProp = props.find((p) => {
|
|
15038
15185
|
if (p.name !== "..." && !p.name.startsWith("..."))
|
|
15039
15186
|
return false;
|
|
15040
15187
|
if (p.value.kind !== "spread" && p.value.kind !== "expression")
|
|
15041
15188
|
return false;
|
|
15042
15189
|
const expr = p.value.kind === "spread" ? p.value.expr : p.value.expr;
|
|
15043
|
-
return
|
|
15190
|
+
return resolveRestSpreadOrigin(ctx, expr) !== null;
|
|
15044
15191
|
});
|
|
15045
15192
|
const spreadSource = knownSpreadProp ? PROPS_PARAM : null;
|
|
15046
15193
|
const propsForInit = [];
|
|
@@ -15188,13 +15335,13 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
15188
15335
|
if (l.childComponent) {
|
|
15189
15336
|
template = "";
|
|
15190
15337
|
if (l.isStaticArray && l.children[0]) {
|
|
15191
|
-
staticItemTemplate = irToHtmlTemplate(l.children[0],
|
|
15338
|
+
staticItemTemplate = irToHtmlTemplate(l.children[0], resolveRestSpreadNames(ctx), 0, undefined, undefined);
|
|
15192
15339
|
}
|
|
15193
15340
|
} else if (l.children[0] && !projectionInner) {
|
|
15194
15341
|
const loopParamSpec = [{ param: l.param, bindings: l.paramBindings }];
|
|
15195
|
-
template = useElementReconciliation ? irToPlaceholderTemplate(l.children[0],
|
|
15342
|
+
template = useElementReconciliation ? irToPlaceholderTemplate(l.children[0], resolveRestSpreadNames(ctx), 0, loopParamSpec) : irToHtmlTemplate(l.children[0], resolveRestSpreadNames(ctx), 0, loopParamSpec);
|
|
15196
15343
|
if (l.isStaticArray) {
|
|
15197
|
-
staticItemTemplate = useElementReconciliation ? irToPlaceholderTemplate(l.children[0],
|
|
15344
|
+
staticItemTemplate = useElementReconciliation ? irToPlaceholderTemplate(l.children[0], resolveRestSpreadNames(ctx), 0) : irToHtmlTemplate(l.children[0], resolveRestSpreadNames(ctx), 0);
|
|
15198
15345
|
} else if (!useElementReconciliation && !l.bodyIsMultiRoot && !l.bodyIsItemConditional) {
|
|
15199
15346
|
const skeletonSafeSlots = {
|
|
15200
15347
|
reactiveAttrKeys: new Set(bindings.reactiveAttrs.map((a) => `${a.childSlotId}::${a.attrName}`)),
|
|
@@ -15246,11 +15393,11 @@ function collectElements(node, ctx, siblingOffsets, insideConditional = false) {
|
|
|
15246
15393
|
preambleRegions: l.preambleRegions,
|
|
15247
15394
|
flatMapClient: projectionInner ? {
|
|
15248
15395
|
params: l.index ? `(${l.param}, ${l.index})` : `(${l.param})`,
|
|
15249
|
-
body: renderFlatMapProjectionClientBody(projectionInner,
|
|
15396
|
+
body: renderFlatMapProjectionClientBody(projectionInner, resolveRestSpreadNames(ctx)),
|
|
15250
15397
|
keyed: projectionInner.key !== null
|
|
15251
15398
|
} : l.flatMapCallback ? {
|
|
15252
15399
|
params: l.flatMapCallback.params,
|
|
15253
|
-
body: renderFlatMapClientBody(l.flatMapCallback,
|
|
15400
|
+
body: renderFlatMapClientBody(l.flatMapCallback, resolveRestSpreadNames(ctx)),
|
|
15254
15401
|
keyed: flatMapCallbackHasKeyedLeaf(l.flatMapCallback)
|
|
15255
15402
|
} : undefined
|
|
15256
15403
|
});
|
|
@@ -15317,10 +15464,9 @@ function collectFromElement(element, ctx, insideConditional = false) {
|
|
|
15317
15464
|
for (const attr of element.attrs) {
|
|
15318
15465
|
if (attr.name === "..." && attr.value) {
|
|
15319
15466
|
const spreadVal = attrValueToString(attr.value) ?? "";
|
|
15320
|
-
const
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
const consumedKeys = spreadVal === elemRestName ? ctx.propsParams.map((p) => p.sourceName ?? p.name) : [];
|
|
15467
|
+
const spreadOrigin = spreadVal ? resolveRestSpreadOrigin(ctx, spreadVal) : null;
|
|
15468
|
+
if (spreadOrigin !== null) {
|
|
15469
|
+
const consumedKeys = spreadOrigin === "rest" ? ctx.propsParams.map((p) => p.sourceName ?? p.name) : [];
|
|
15324
15470
|
const staticAttrKeys = element.attrs.filter((a) => a.name !== "...").map((a) => a.name);
|
|
15325
15471
|
const excludeKeys = [...new Set([...consumedKeys, ...staticAttrKeys])];
|
|
15326
15472
|
ctx.restAttrElements.push({
|
|
@@ -15399,7 +15545,7 @@ function collectBranchTextEffects(node) {
|
|
|
15399
15545
|
}
|
|
15400
15546
|
function collectBranchLoops(node, ctx, siblingOffsets) {
|
|
15401
15547
|
const loops = [];
|
|
15402
|
-
const restNames = ctx ?
|
|
15548
|
+
const restNames = ctx ? resolveRestSpreadNames(ctx) : undefined;
|
|
15403
15549
|
walkIR(node, null, {
|
|
15404
15550
|
...stopAt("conditional", "ifStatement"),
|
|
15405
15551
|
element: ({ node: el, scope: parentSlotId, descend }) => {
|
|
@@ -15467,7 +15613,7 @@ function collectBranchLoops(node, ctx, siblingOffsets) {
|
|
|
15467
15613
|
return loops;
|
|
15468
15614
|
}
|
|
15469
15615
|
function buildConditionalMetadata(node, ctx, siblingOffsets) {
|
|
15470
|
-
const restNames =
|
|
15616
|
+
const restNames = resolveRestSpreadNames(ctx);
|
|
15471
15617
|
return {
|
|
15472
15618
|
slotId: node.slotId,
|
|
15473
15619
|
condition: node.condition,
|
|
@@ -16101,6 +16247,7 @@ var RUNTIME_IMPORT_CANDIDATES = [
|
|
|
16101
16247
|
"mapArrayLazy",
|
|
16102
16248
|
"patchLeaf",
|
|
16103
16249
|
"createDisposableEffect",
|
|
16250
|
+
"findCondContainer",
|
|
16104
16251
|
"createComponent",
|
|
16105
16252
|
"renderChild",
|
|
16106
16253
|
"registerComponent",
|
|
@@ -17128,12 +17275,9 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
|
|
|
17128
17275
|
lines.push("");
|
|
17129
17276
|
const propNamesForStaticCheck = new Set(ctx.propsParams.map((p) => p.name));
|
|
17130
17277
|
const { inlinableConstants, unsafeLocalNames } = inlinability ?? buildInlinableConstants(ctx, graph, _ir.root);
|
|
17131
|
-
const restSpreadNames =
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
if (ctx.propsObjectName)
|
|
17135
|
-
restSpreadNames.add(ctx.propsObjectName);
|
|
17136
|
-
const isCommentScope = _ir.root.type === "fragment" && _ir.root.needsScopeComment || _ir.root.type === "component";
|
|
17278
|
+
const restSpreadNames = resolveRestSpreadNames(ctx);
|
|
17279
|
+
const isFragmentRoot = _ir.root.type === "fragment" && !!_ir.root.needsScopeComment;
|
|
17280
|
+
const isCommentScope = isFragmentRoot || _ir.root.type === "component";
|
|
17137
17281
|
const defParts = [`init: init${name}`];
|
|
17138
17282
|
if (canGenerateStaticTemplate(_ir.root, propNamesForStaticCheck, inlinableConstants, unsafeLocalNames)) {
|
|
17139
17283
|
const markupSlotIds = new Set(ctx.dynamicElements.map((e) => e.slotId));
|
|
@@ -17151,6 +17295,9 @@ function emitRegistrationAndHydration(lines, ctx, _ir, graph, inlinability) {
|
|
|
17151
17295
|
if (isCommentScope) {
|
|
17152
17296
|
defParts.push("comment: true");
|
|
17153
17297
|
}
|
|
17298
|
+
if (isFragmentRoot) {
|
|
17299
|
+
defParts.push("fragmentRoot: true");
|
|
17300
|
+
}
|
|
17154
17301
|
const registryKey = nameForRegistryRef(name);
|
|
17155
17302
|
if (registryKey !== name) {
|
|
17156
17303
|
defParts.push(`name: '${name}'`);
|
|
@@ -18000,7 +18147,8 @@ function emitProviderAndChildInits(lines, ctx) {
|
|
|
18000
18147
|
lines.push(` upsertChild(__scope, '${registryName}', '${child.slotId}', ${child.propsExpr})`);
|
|
18001
18148
|
continue;
|
|
18002
18149
|
}
|
|
18003
|
-
const
|
|
18150
|
+
const isCommentRoot = child.slotId !== null && child.slotId === ctx.commentScopeRootSlotId;
|
|
18151
|
+
const scopeRef = !child.slotId || isCommentRoot ? "__scope" : `_${varSlotId(child.slotId)}`;
|
|
18004
18152
|
lines.push(` initChild('${registryName}', ${scopeRef}, ${child.propsExpr})`);
|
|
18005
18153
|
}
|
|
18006
18154
|
}
|
|
@@ -18652,6 +18800,7 @@ function buildBranchInnerLoopsPlan(args) {
|
|
|
18652
18800
|
const {
|
|
18653
18801
|
innerLoops,
|
|
18654
18802
|
scopeVar,
|
|
18803
|
+
condSlotId,
|
|
18655
18804
|
outerLoopParam,
|
|
18656
18805
|
outerLoopParamBindings,
|
|
18657
18806
|
wrapOuter
|
|
@@ -18666,7 +18815,7 @@ function buildBranchInnerLoopsPlan(args) {
|
|
|
18666
18815
|
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings);
|
|
18667
18816
|
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings);
|
|
18668
18817
|
const csl = inner.containerSlotId;
|
|
18669
|
-
const containerExpr = csl ? `(${scopeVar}.querySelector('[bf="${csl}"]') ?? ${scopeVar}.querySelector(\`[${BF_HOST2}="\${__scopeId}"][${BF_AT2}="${csl}"]\`) ?? ${scopeVar})` : scopeVar
|
|
18818
|
+
const containerExpr = csl ? `(${scopeVar}.querySelector('[bf="${csl}"]') ?? ${scopeVar}.querySelector(\`[${BF_HOST2}="\${__scopeId}"][${BF_AT2}="${csl}"]\`) ?? ${scopeVar})` : `findCondContainer(${scopeVar}, '${condSlotId}')`;
|
|
18670
18819
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(inner.param, inner.paramBindings);
|
|
18671
18820
|
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings) : null;
|
|
18672
18821
|
const wrapIRNode = (node) => {
|
|
@@ -18750,13 +18899,15 @@ function buildLoopChildConditionalsPlan(args) {
|
|
|
18750
18899
|
branch: cond.whenTrue,
|
|
18751
18900
|
wrap,
|
|
18752
18901
|
loopParam,
|
|
18753
|
-
loopParamBindings
|
|
18902
|
+
loopParamBindings,
|
|
18903
|
+
condId: cond.slotId
|
|
18754
18904
|
}),
|
|
18755
18905
|
whenFalseArm: buildLoopChildArmPlan({
|
|
18756
18906
|
branch: cond.whenFalse,
|
|
18757
18907
|
wrap,
|
|
18758
18908
|
loopParam,
|
|
18759
|
-
loopParamBindings
|
|
18909
|
+
loopParamBindings,
|
|
18910
|
+
condId: cond.slotId
|
|
18760
18911
|
})
|
|
18761
18912
|
});
|
|
18762
18913
|
}
|
|
@@ -18796,7 +18947,7 @@ function buildArmTextsPlan(texts, wrap) {
|
|
|
18796
18947
|
}));
|
|
18797
18948
|
}
|
|
18798
18949
|
function buildLoopChildArmPlan(args) {
|
|
18799
|
-
const { branch, wrap, loopParam, loopParamBindings } = args;
|
|
18950
|
+
const { branch, wrap, loopParam, loopParamBindings, condId } = args;
|
|
18800
18951
|
return {
|
|
18801
18952
|
events: buildBranchEventBindingsPlan({
|
|
18802
18953
|
events: branch.events,
|
|
@@ -18809,6 +18960,7 @@ function buildLoopChildArmPlan(args) {
|
|
|
18809
18960
|
innerLoops: buildBranchInnerLoopsPlan({
|
|
18810
18961
|
innerLoops: branch.innerLoops,
|
|
18811
18962
|
scopeVar: "__branchScope",
|
|
18963
|
+
condSlotId: condId,
|
|
18812
18964
|
outerLoopParam: loopParam,
|
|
18813
18965
|
outerLoopParamBindings: loopParamBindings,
|
|
18814
18966
|
wrapOuter: wrap
|
|
@@ -18862,8 +19014,8 @@ function buildReactiveEffectsPlan(args) {
|
|
|
18862
19014
|
wrappedCondition: wrap(cond.condition),
|
|
18863
19015
|
whenTrueTemplateHtml: addCondAttrToTemplate(wrap(cond.whenTrueHtml), cond.slotId),
|
|
18864
19016
|
whenFalseTemplateHtml: addCondAttrToTemplate(wrap(cond.whenFalseHtml), cond.slotId),
|
|
18865
|
-
whenTrueArm: buildOuterArm(cond.whenTrue, wrap, loopParam, loopParamBindings, profileComponentName),
|
|
18866
|
-
whenFalseArm: buildOuterArm(cond.whenFalse, wrap, loopParam, loopParamBindings, profileComponentName),
|
|
19017
|
+
whenTrueArm: buildOuterArm(cond.whenTrue, wrap, loopParam, loopParamBindings, cond.slotId, profileComponentName),
|
|
19018
|
+
whenFalseArm: buildOuterArm(cond.whenFalse, wrap, loopParam, loopParamBindings, cond.slotId, profileComponentName),
|
|
18867
19019
|
...cond.readsPreamble && { readsPreamble: true }
|
|
18868
19020
|
});
|
|
18869
19021
|
}
|
|
@@ -18875,7 +19027,7 @@ function buildReactiveEffectsPlan(args) {
|
|
|
18875
19027
|
profileComponentName
|
|
18876
19028
|
};
|
|
18877
19029
|
}
|
|
18878
|
-
function buildOuterArm(branch, wrap, loopParam, loopParamBindings, profileComponentName) {
|
|
19030
|
+
function buildOuterArm(branch, wrap, loopParam, loopParamBindings, condSlotId, profileComponentName) {
|
|
18879
19031
|
return {
|
|
18880
19032
|
events: buildBranchEventBindingsPlan({
|
|
18881
19033
|
events: branch.events,
|
|
@@ -18889,6 +19041,7 @@ function buildOuterArm(branch, wrap, loopParam, loopParamBindings, profileCompon
|
|
|
18889
19041
|
innerLoops: buildBranchInnerLoopsPlan({
|
|
18890
19042
|
innerLoops: branch.innerLoops,
|
|
18891
19043
|
scopeVar: "__branchScope",
|
|
19044
|
+
condSlotId,
|
|
18892
19045
|
outerLoopParam: loopParam,
|
|
18893
19046
|
outerLoopParamBindings: loopParamBindings,
|
|
18894
19047
|
wrapOuter: wrap
|
|
@@ -18990,6 +19143,7 @@ function buildInnerLoopsPlan(args) {
|
|
|
18990
19143
|
}
|
|
18991
19144
|
function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, outerLoopParamBindings) {
|
|
18992
19145
|
const wrapInner = (expr) => wrapLoopParamAsAccessor(expr, inner.param, inner.paramBindings);
|
|
19146
|
+
const wrapBoth = (expr) => wrapLoopParamAsAccessor(wrapOuter(expr), inner.param, inner.paramBindings);
|
|
18993
19147
|
const { head: paramHead, unwrap: paramUnwrap } = destructureLoopParam(inner.param, inner.paramBindings);
|
|
18994
19148
|
const wrappedKey = inner.key ? wrapLoopParamAsAccessor(inner.key, inner.param, inner.paramBindings) : null;
|
|
18995
19149
|
const wrapIRNode = (node) => {
|
|
@@ -19051,6 +19205,13 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
|
|
|
19051
19205
|
}));
|
|
19052
19206
|
}
|
|
19053
19207
|
const childRefs = buildChildRefBindings(inner.bindings.refs, inner.param, inner.paramBindings);
|
|
19208
|
+
const conditionals = buildLoopChildConditionalsPlan({
|
|
19209
|
+
conditionals: inner.bindings.conditionals,
|
|
19210
|
+
scopeVar: `__innerEl${uidSuffix}`,
|
|
19211
|
+
wrap: wrapBoth,
|
|
19212
|
+
loopParam: inner.param,
|
|
19213
|
+
loopParamBindings: inner.paramBindings
|
|
19214
|
+
});
|
|
19054
19215
|
return {
|
|
19055
19216
|
mode: "reactive",
|
|
19056
19217
|
keyFn: loopKeyFn(inner),
|
|
@@ -19063,6 +19224,7 @@ function buildReactiveEmit(inner, level, wrapOuter, uidSuffix, outerLoopParam, o
|
|
|
19063
19224
|
events,
|
|
19064
19225
|
reactiveTexts,
|
|
19065
19226
|
reactiveAttrs,
|
|
19227
|
+
conditionals,
|
|
19066
19228
|
childRefs
|
|
19067
19229
|
};
|
|
19068
19230
|
}
|
|
@@ -20015,6 +20177,17 @@ function bindingIdArg(ctx, slotId) {
|
|
|
20015
20177
|
return "";
|
|
20016
20178
|
return `, ${JSON.stringify(`${ctx.componentName}#binding:${slotId}`)}`;
|
|
20017
20179
|
}
|
|
20180
|
+
function emitValueUpdateStatements(target, expression) {
|
|
20181
|
+
return [
|
|
20182
|
+
`const __val = String(${expression})`,
|
|
20183
|
+
`if ('value' in ${target}) { if (${target}.value !== __val) ${target}.value = __val } else { ${target}.setAttribute('value', __val) }`
|
|
20184
|
+
];
|
|
20185
|
+
}
|
|
20186
|
+
function emitChildValueMirrorStatements(target, expression) {
|
|
20187
|
+
return [
|
|
20188
|
+
`if ('value' in ${target}) { const __val = String(${expression}); if (${target}.value !== __val) ${target}.value = __val }`
|
|
20189
|
+
];
|
|
20190
|
+
}
|
|
20018
20191
|
function emitAttrUpdate(target, attrName, expression, meta) {
|
|
20019
20192
|
const htmlName = toHtmlAttrName(attrName);
|
|
20020
20193
|
if (attrName === "dangerouslySetInnerHTML" || htmlName === "dangerouslySetInnerHTML") {
|
|
@@ -20033,10 +20206,7 @@ function emitAttrUpdate(target, attrName, expression, meta) {
|
|
|
20033
20206
|
];
|
|
20034
20207
|
}
|
|
20035
20208
|
if (htmlName === "value") {
|
|
20036
|
-
return
|
|
20037
|
-
`const __val = String(${expression})`,
|
|
20038
|
-
`if (${target}.value !== __val) ${target}.value = __val`
|
|
20039
|
-
];
|
|
20209
|
+
return emitValueUpdateStatements(target, expression);
|
|
20040
20210
|
}
|
|
20041
20211
|
if (isBooleanAttr(htmlName)) {
|
|
20042
20212
|
return [`${target}.${htmlName} = !!(${expression})`];
|
|
@@ -20284,30 +20454,30 @@ function emitReactivePropBindings(lines, ctx) {
|
|
|
20284
20454
|
propsBySlot.get(prop.slotId).push(prop);
|
|
20285
20455
|
}
|
|
20286
20456
|
for (const [slotId, props] of propsBySlot) {
|
|
20287
|
-
const
|
|
20288
|
-
lines.push(` if (
|
|
20457
|
+
const ref = slotId === ctx.commentScopeRootSlotId ? "__scope" : `_${varSlotId(slotId)}`;
|
|
20458
|
+
lines.push(` if (${ref}) {`);
|
|
20289
20459
|
for (const prop of props) {
|
|
20290
20460
|
const value = `${prop.expression}()`;
|
|
20291
20461
|
if (prop.propName === "selected") {
|
|
20292
20462
|
if (prop.componentName === "TabsContent") {
|
|
20293
|
-
lines.push(`
|
|
20463
|
+
lines.push(` ${ref}.setAttribute('data-state', ${value} ? 'active' : 'inactive')`);
|
|
20294
20464
|
lines.push(` if (${value}) {`);
|
|
20295
|
-
lines.push(`
|
|
20465
|
+
lines.push(` ${ref}.classList.remove('hidden')`);
|
|
20296
20466
|
lines.push(` } else {`);
|
|
20297
|
-
lines.push(`
|
|
20467
|
+
lines.push(` ${ref}.classList.add('hidden')`);
|
|
20298
20468
|
lines.push(` }`);
|
|
20299
20469
|
} else {
|
|
20300
|
-
lines.push(`
|
|
20301
|
-
lines.push(`
|
|
20302
|
-
lines.push(`
|
|
20470
|
+
lines.push(` ${ref}.setAttribute('aria-selected', String(${value}))`);
|
|
20471
|
+
lines.push(` ${ref}.setAttribute('data-state', ${value} ? 'active' : 'inactive')`);
|
|
20472
|
+
lines.push(` ${ref}.setAttribute('tabindex', ${value} ? '0' : '-1')`);
|
|
20303
20473
|
}
|
|
20304
20474
|
} else if (prop.propName === "value") {
|
|
20305
|
-
|
|
20306
|
-
|
|
20475
|
+
for (const stmt of emitChildValueMirrorStatements(ref, value))
|
|
20476
|
+
lines.push(` ${stmt}`);
|
|
20307
20477
|
} else if (isBooleanAttr(prop.propName)) {
|
|
20308
|
-
lines.push(`
|
|
20478
|
+
lines.push(` ${ref}.${prop.propName} = !!(${value})`);
|
|
20309
20479
|
} else {
|
|
20310
|
-
lines.push(`
|
|
20480
|
+
lines.push(` ${ref}.setAttribute('${prop.propName}', String(${value}))`);
|
|
20311
20481
|
}
|
|
20312
20482
|
}
|
|
20313
20483
|
lines.push(` }`);
|
|
@@ -20330,13 +20500,17 @@ function emitReactiveChildProps(lines, ctx) {
|
|
|
20330
20500
|
}
|
|
20331
20501
|
for (const [, props] of propsByComponent) {
|
|
20332
20502
|
const first = props[0];
|
|
20503
|
+
const isCommentRoot = first.slotId !== null && first.slotId === ctx.commentScopeRootSlotId;
|
|
20333
20504
|
const varSuffix = first.slotId ? varSlotId(first.slotId).replace(/-/g, "_") : first.componentName;
|
|
20334
|
-
const varName = `__${first.componentName}_${varSuffix}El`;
|
|
20335
|
-
|
|
20336
|
-
|
|
20505
|
+
const varName = isCommentRoot ? "__scope" : `__${first.componentName}_${varSuffix}El`;
|
|
20506
|
+
if (!isCommentRoot) {
|
|
20507
|
+
const selectorArg = first.slotId ? first.slotId : first.componentName;
|
|
20508
|
+
lines.push(` const [${varName}] = $c(__scope, '${selectorArg}')`);
|
|
20509
|
+
}
|
|
20337
20510
|
lines.push(` if (${varName}) {`);
|
|
20338
20511
|
for (const prop of props) {
|
|
20339
|
-
|
|
20512
|
+
const stmts = toHtmlAttrName(prop.attrName) === "value" ? emitChildValueMirrorStatements(varName, prop.expression) : emitAttrUpdate(varName, prop.attrName, prop.expression, prop);
|
|
20513
|
+
for (const stmt of stmts) {
|
|
20340
20514
|
lines.push(` ${stmt}`);
|
|
20341
20515
|
}
|
|
20342
20516
|
}
|
|
@@ -20897,8 +21071,9 @@ function seedDiffersExpr(target, a) {
|
|
|
20897
21071
|
return `${target}.getAttribute('style') !== styleToCss(__x)`;
|
|
20898
21072
|
if (html === "class")
|
|
20899
21073
|
return `${target}.getAttribute('class') !== (__x != null ? String(__x) : null)`;
|
|
20900
|
-
if (html === "value")
|
|
20901
|
-
return
|
|
21074
|
+
if (html === "value") {
|
|
21075
|
+
return `('value' in ${target} ? ${target}.value !== String(__x) : ${target}.getAttribute('value') !== String(__x))`;
|
|
21076
|
+
}
|
|
20902
21077
|
if (isBooleanAttr(html))
|
|
20903
21078
|
return `${target}.${html} !== !!(__x)`;
|
|
20904
21079
|
if (a.meta.presenceOrUndefined) {
|
|
@@ -21256,6 +21431,9 @@ function emitReactive(lines, inner, indent, pc) {
|
|
|
21256
21431
|
}
|
|
21257
21432
|
lines.push(`${indent} }${profileBindingId(pc, attr.slotId)}) }`);
|
|
21258
21433
|
}
|
|
21434
|
+
if (emit.conditionals.length > 0) {
|
|
21435
|
+
stringifyLoopChildConditionals(lines, emit.conditionals, `${indent} `, pc);
|
|
21436
|
+
}
|
|
21259
21437
|
emitLoopChildRefs(lines, emit.childRefs, {
|
|
21260
21438
|
indent: `${indent} `,
|
|
21261
21439
|
elVar: `__innerEl${uid}`,
|
|
@@ -22019,6 +22197,9 @@ function generateElementRefs(ctx) {
|
|
|
22019
22197
|
for (const slotId of componentSlots) {
|
|
22020
22198
|
regularSlots.delete(slotId);
|
|
22021
22199
|
}
|
|
22200
|
+
if (ctx.commentScopeRootSlotId) {
|
|
22201
|
+
componentSlots.delete(ctx.commentScopeRootSlotId);
|
|
22202
|
+
}
|
|
22022
22203
|
if (regularSlots.size === 0 && componentSlots.size === 0)
|
|
22023
22204
|
return "";
|
|
22024
22205
|
const refLines = [];
|
|
@@ -22170,10 +22351,18 @@ var PHASES = [
|
|
|
22170
22351
|
|
|
22171
22352
|
// src/ir-to-client-js/rewrite-props-object.ts
|
|
22172
22353
|
import ts20 from "typescript";
|
|
22173
|
-
function rewritePropsObjectRef(code, propsObjectName) {
|
|
22174
|
-
|
|
22175
|
-
|
|
22176
|
-
|
|
22354
|
+
function rewritePropsObjectRef(code, propsObjectName, restPropsName = null) {
|
|
22355
|
+
let result = code;
|
|
22356
|
+
const seen = new Set;
|
|
22357
|
+
for (const srcPropsName of [propsObjectName ?? "props", restPropsName]) {
|
|
22358
|
+
if (srcPropsName === null || srcPropsName === PROPS_PARAM || seen.has(srcPropsName))
|
|
22359
|
+
continue;
|
|
22360
|
+
seen.add(srcPropsName);
|
|
22361
|
+
result = rewriteOneName(result, srcPropsName);
|
|
22362
|
+
}
|
|
22363
|
+
return result;
|
|
22364
|
+
}
|
|
22365
|
+
function rewriteOneName(code, srcPropsName) {
|
|
22177
22366
|
if (!identifierPattern(srcPropsName).test(code))
|
|
22178
22367
|
return code;
|
|
22179
22368
|
const sourceFile = ts20.createSourceFile("init-body.ts", code, ts20.ScriptTarget.Latest, true, ts20.ScriptKind.TS);
|
|
@@ -22242,7 +22431,7 @@ function generateInitFunction(ir, ctx, siblingComponents, localImportPrefixes) {
|
|
|
22242
22431
|
runPhases(lines, phaseCtx, PHASES);
|
|
22243
22432
|
const hydrateLine = emitRegistrationAndHydration(lines, ctx, ir, graph, inlinability);
|
|
22244
22433
|
let generatedCode = rewritePropsObjectRef(lines.join(`
|
|
22245
|
-
`), ctx.propsObjectName);
|
|
22434
|
+
`), ctx.propsObjectName, ctx.restPropsName);
|
|
22246
22435
|
generatedCode += `
|
|
22247
22436
|
` + hydrateLine;
|
|
22248
22437
|
const moduleConstantsCode = emitModuleLevelDeclarations(classification.moduleLevelConstants, classification.moduleLevelFunctions, classification.moduleLevelSignals, classification.moduleLevelMemos);
|
|
@@ -22505,6 +22694,7 @@ function createContext(ir, scope, adapterCapabilities, profile) {
|
|
|
22505
22694
|
refElements: [],
|
|
22506
22695
|
childInits: [],
|
|
22507
22696
|
deferredChildSlots: new Set,
|
|
22697
|
+
commentScopeRootSlotId: ir.root.type === "component" ? ir.root.slotId : null,
|
|
22508
22698
|
reactiveProps: [],
|
|
22509
22699
|
reactiveChildProps: [],
|
|
22510
22700
|
reactiveAttrs: [],
|
|
@@ -22541,11 +22731,7 @@ function generateTemplateOnlyMount(ir, ctx) {
|
|
|
22541
22731
|
const propNamesForStaticCheck = new Set(ctx.propsParams.map((p) => p.name));
|
|
22542
22732
|
const graph = buildReferencesGraph(ctx, ir.root);
|
|
22543
22733
|
const { inlinableConstants, unsafeLocalNames } = buildInlinableConstants(ctx, graph, ir.root);
|
|
22544
|
-
const restSpreadNames =
|
|
22545
|
-
if (ctx.restPropsName)
|
|
22546
|
-
restSpreadNames.add(ctx.restPropsName);
|
|
22547
|
-
if (ctx.propsObjectName)
|
|
22548
|
-
restSpreadNames.add(ctx.propsObjectName);
|
|
22734
|
+
const restSpreadNames = resolveRestSpreadNames(ctx);
|
|
22549
22735
|
let templateHtml;
|
|
22550
22736
|
if (canGenerateStaticTemplate(ir.root, propNamesForStaticCheck, inlinableConstants, unsafeLocalNames)) {
|
|
22551
22737
|
const markupSlotIds = new Set(ctx.dynamicElements.map((e) => e.slotId));
|
|
@@ -29121,6 +29307,9 @@ export {
|
|
|
29121
29307
|
__resetLoweringPluginsForTest,
|
|
29122
29308
|
TestAdapter,
|
|
29123
29309
|
SourceMapGenerator,
|
|
29310
|
+
SORT_KEY_TYPES,
|
|
29311
|
+
SORT_KEY_TARGETS,
|
|
29312
|
+
SORT_KEY_DIRECTIONS,
|
|
29124
29313
|
REACTIVE_PRIMITIVES,
|
|
29125
29314
|
PROFILE_SCHEMA_VERSION,
|
|
29126
29315
|
PARSED_EXPR_KINDS,
|