rip-lang 3.13.23 → 3.13.24
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/README.md +1 -1
- package/package.json +1 -1
- package/src/components.js +153 -269
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.
|
|
12
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.24-blue.svg" alt="Version"></a>
|
|
13
13
|
<a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
|
|
14
14
|
<a href="#"><img src="https://img.shields.io/badge/tests-1%2C265%2F1%2C265-brightgreen.svg" alt="Tests"></a>
|
|
15
15
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
|
package/package.json
CHANGED
package/src/components.js
CHANGED
|
@@ -106,23 +106,6 @@ function isPublicProp(target) {
|
|
|
106
106
|
return Array.isArray(target) && target[0] === '.' && target[1] === 'this';
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
/**
|
|
110
|
-
* Detect fragment root and collect direct child variables for proper removal.
|
|
111
|
-
* After insertBefore, a DocumentFragment is empty — .remove() is a no-op.
|
|
112
|
-
* Callers must remove each child element individually.
|
|
113
|
-
*/
|
|
114
|
-
function getFragChildren(rootVar, createLines, localizeVar) {
|
|
115
|
-
const root = localizeVar(rootVar);
|
|
116
|
-
if (!/_frag\d+$/.test(root)) return null;
|
|
117
|
-
const children = [];
|
|
118
|
-
const re = new RegExp(`^${root.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\.appendChild\\(([^)]+)\\);`);
|
|
119
|
-
for (const line of createLines) {
|
|
120
|
-
const m = localizeVar(line).match(re);
|
|
121
|
-
if (m) children.push(m[1]);
|
|
122
|
-
}
|
|
123
|
-
return children.length > 0 ? children : null;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
109
|
// ============================================================================
|
|
127
110
|
// Prototype Installation
|
|
128
111
|
// ============================================================================
|
|
@@ -398,16 +381,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
398
381
|
// Implicit nesting (inject -> before INDENT)
|
|
399
382
|
// ─────────────────────────────────────────────────────────────────────
|
|
400
383
|
if (nextToken && nextToken[0] === 'INDENT') {
|
|
401
|
-
//
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
for (let j = i; j >= 0; j--) {
|
|
405
|
-
let jt = tokens[j][0];
|
|
406
|
-
if (jt === 'INTERPOLATION_END' || jt === 'STRING_END') depth++;
|
|
407
|
-
if (jt === 'INTERPOLATION_START' || jt === 'STRING_START') depth--;
|
|
408
|
-
if (depth < 0) { return 1; }
|
|
409
|
-
}
|
|
410
|
-
}
|
|
384
|
+
// fromThen INDENTs are inline conditional values (if x then y else z),
|
|
385
|
+
// never template nesting — normalizeLines only creates them for single-line then clauses
|
|
386
|
+
if (nextToken.fromThen) return 1;
|
|
411
387
|
if (tag === '->' || tag === '=>' || tag === 'CALL_START' || tag === '(') {
|
|
412
388
|
return 1;
|
|
413
389
|
}
|
|
@@ -437,31 +413,17 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
437
413
|
isTemplateElement = true;
|
|
438
414
|
} else if (tag === 'IDENTIFIER' && isTemplateTag(token[1]) && !isAfterControlFlow) {
|
|
439
415
|
isTemplateElement = true;
|
|
440
|
-
} else if (tag === '
|
|
416
|
+
} else if (tag === 'IDENTIFIER' && !isAfterControlFlow) {
|
|
417
|
+
isTemplateElement = startsWithTag(tokens, i);
|
|
418
|
+
} else if (tag === 'PROPERTY' || tag === 'STRING' || tag === 'STRING_END' || tag === 'NUMBER' || tag === 'BOOL' || tag === 'CALL_END' || tag === ')') {
|
|
441
419
|
isTemplateElement = startsWithTag(tokens, i);
|
|
442
|
-
}
|
|
443
|
-
else if (tag === 'IDENTIFIER' && i > 1 && tokens[i - 1][0] === '...') {
|
|
444
|
-
if (startsWithTag(tokens, i)) {
|
|
445
|
-
let commaToken = gen(',', ',', token);
|
|
446
|
-
let arrowToken = gen('->', '->', token);
|
|
447
|
-
arrowToken.newLine = true;
|
|
448
|
-
tokens.splice(i + 1, 0, commaToken, arrowToken);
|
|
449
|
-
return 3;
|
|
450
|
-
}
|
|
451
420
|
}
|
|
452
421
|
|
|
453
422
|
if (isTemplateElement) {
|
|
454
423
|
let isClassOrIdTail = tag === 'PROPERTY' && i > 0 && (tokens[i - 1][0] === '.' || tokens[i - 1][0] === '#');
|
|
424
|
+
let isBareTag = isClsxCallEnd || (tag === 'IDENTIFIER' && isTemplateTag(token[1])) || isClassOrIdTail;
|
|
455
425
|
|
|
456
|
-
if (
|
|
457
|
-
let callStartToken = gen('CALL_START', '(', token);
|
|
458
|
-
let arrowToken = gen('->', '->', token);
|
|
459
|
-
arrowToken.newLine = true;
|
|
460
|
-
tokens.splice(i + 1, 0, callStartToken, arrowToken);
|
|
461
|
-
pendingCallEnds.push(currentIndent + 1);
|
|
462
|
-
return 3;
|
|
463
|
-
} else if ((tag === 'IDENTIFIER' && isTemplateTag(token[1])) || isClassOrIdTail) {
|
|
464
|
-
// Bare tag or tag.class/tag#id (no other args): inject CALL_START -> and manage CALL_END
|
|
426
|
+
if (isBareTag) {
|
|
465
427
|
let callStartToken = gen('CALL_START', '(', token);
|
|
466
428
|
let arrowToken = gen('->', '->', token);
|
|
467
429
|
arrowToken.newLine = true;
|
|
@@ -469,7 +431,6 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
469
431
|
pendingCallEnds.push(currentIndent + 1);
|
|
470
432
|
return 3;
|
|
471
433
|
} else {
|
|
472
|
-
// Tag with args: inject , -> (call wrapping handled by addImplicitBracesAndParens)
|
|
473
434
|
let commaToken = gen(',', ',', token);
|
|
474
435
|
let arrowToken = gen('->', '->', token);
|
|
475
436
|
arrowToken.newLine = true;
|
|
@@ -503,16 +464,6 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
503
464
|
// Utilities
|
|
504
465
|
// ==========================================================================
|
|
505
466
|
|
|
506
|
-
/**
|
|
507
|
-
* Localize variable references for block factories.
|
|
508
|
-
* Converts this._elN to _elN and this.x to ctx.x.
|
|
509
|
-
*/
|
|
510
|
-
proto.localizeVar = function(line) {
|
|
511
|
-
let result = line.replace(/this\.(_el\d+|_t\d+|_anchor\d+|_frag\d+|_slot\d+|_c\d+|_inst\d+|_empty\d+)/g, '$1');
|
|
512
|
-
result = result.replace(/\bthis\b/g, 'ctx');
|
|
513
|
-
return result;
|
|
514
|
-
};
|
|
515
|
-
|
|
516
467
|
/**
|
|
517
468
|
* Check if name is an HTML/SVG tag
|
|
518
469
|
*/
|
|
@@ -560,12 +511,13 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
560
511
|
* For component context where state variables are signals.
|
|
561
512
|
*/
|
|
562
513
|
proto.transformComponentMembers = function(sexpr) {
|
|
514
|
+
const self = this._self;
|
|
563
515
|
if (!Array.isArray(sexpr)) {
|
|
564
516
|
if (typeof sexpr === 'string' && this.reactiveMembers && this.reactiveMembers.has(sexpr)) {
|
|
565
|
-
return ['.', ['.',
|
|
517
|
+
return ['.', ['.', self, sexpr], 'value'];
|
|
566
518
|
}
|
|
567
519
|
if (typeof sexpr === 'string' && this.componentMembers && this.componentMembers.has(sexpr)) {
|
|
568
|
-
return ['.',
|
|
520
|
+
return ['.', self, sexpr];
|
|
569
521
|
}
|
|
570
522
|
return sexpr;
|
|
571
523
|
}
|
|
@@ -574,9 +526,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
574
526
|
if (sexpr[0] === '.' && sexpr[1] === 'this' && typeof sexpr[2] === 'string') {
|
|
575
527
|
const memberName = sexpr[2];
|
|
576
528
|
if (this.reactiveMembers && this.reactiveMembers.has(memberName)) {
|
|
577
|
-
return ['.',
|
|
529
|
+
return ['.', ['.', self, memberName], 'value'];
|
|
578
530
|
}
|
|
579
|
-
return sexpr;
|
|
531
|
+
return this._factoryMode ? ['.', self, sexpr[2]] : sexpr;
|
|
580
532
|
}
|
|
581
533
|
|
|
582
534
|
// Dot access: transform the object but not the property name
|
|
@@ -819,10 +771,10 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
819
771
|
*/
|
|
820
772
|
proto.generateInComponent = function(sexpr, context) {
|
|
821
773
|
if (typeof sexpr === 'string' && this.reactiveMembers && this.reactiveMembers.has(sexpr)) {
|
|
822
|
-
return
|
|
774
|
+
return `${this._self}.${sexpr}.value`;
|
|
823
775
|
}
|
|
824
776
|
if (typeof sexpr === 'string' && this.componentMembers && this.componentMembers.has(sexpr)) {
|
|
825
|
-
return
|
|
777
|
+
return `${this._self}.${sexpr}`;
|
|
826
778
|
}
|
|
827
779
|
if (Array.isArray(sexpr) && this.reactiveMembers) {
|
|
828
780
|
const transformed = this.transformComponentMembers(sexpr);
|
|
@@ -854,6 +806,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
854
806
|
this._setupLines = [];
|
|
855
807
|
this._blockFactories = [];
|
|
856
808
|
this._loopVarStack = [];
|
|
809
|
+
this._factoryMode = false;
|
|
810
|
+
this._factoryVars = null;
|
|
811
|
+
this._fragChildren = new Map();
|
|
857
812
|
|
|
858
813
|
const statements = this.is(body, 'block') ? body.slice(1) : [body];
|
|
859
814
|
|
|
@@ -865,10 +820,13 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
865
820
|
} else {
|
|
866
821
|
rootVar = this.newElementVar('frag');
|
|
867
822
|
this._createLines.push(`${rootVar} = document.createDocumentFragment();`);
|
|
823
|
+
const children = [];
|
|
868
824
|
for (const stmt of statements) {
|
|
869
825
|
const childVar = this.generateNode(stmt);
|
|
870
826
|
this._createLines.push(`${rootVar}.appendChild(${childVar});`);
|
|
827
|
+
children.push(childVar);
|
|
871
828
|
}
|
|
829
|
+
this._fragChildren.set(rootVar, children);
|
|
872
830
|
}
|
|
873
831
|
|
|
874
832
|
return {
|
|
@@ -886,12 +844,30 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
886
844
|
|
|
887
845
|
/** Generate a unique element variable name */
|
|
888
846
|
proto.newElementVar = function(hint = 'el') {
|
|
889
|
-
|
|
847
|
+
const name = `_${hint}${this._elementCount++}`;
|
|
848
|
+
if (this._factoryVars) this._factoryVars.add(name);
|
|
849
|
+
return this._factoryMode ? name : `this.${name}`;
|
|
890
850
|
};
|
|
891
851
|
|
|
892
852
|
/** Generate a unique text node variable name */
|
|
893
853
|
proto.newTextVar = function() {
|
|
894
|
-
|
|
854
|
+
const name = `_t${this._textCount++}`;
|
|
855
|
+
if (this._factoryVars) this._factoryVars.add(name);
|
|
856
|
+
return this._factoryMode ? name : `this.${name}`;
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
/** Context reference — 'this' in component body, 'ctx' in block factories */
|
|
860
|
+
Object.defineProperty(proto, '_self', {
|
|
861
|
+
get() { return this._factoryMode ? 'ctx' : 'this'; }
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
/** Push an effect line, wrapping with disposer tracking in factory mode */
|
|
865
|
+
proto._pushEffect = function(body) {
|
|
866
|
+
if (this._factoryMode) {
|
|
867
|
+
this._setupLines.push(`disposers.push(__effect(() => { ${body} }));`);
|
|
868
|
+
} else {
|
|
869
|
+
this._setupLines.push(`__effect(() => { ${body} });`);
|
|
870
|
+
}
|
|
895
871
|
};
|
|
896
872
|
|
|
897
873
|
// --------------------------------------------------------------------------
|
|
@@ -911,7 +887,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
911
887
|
if (this.reactiveMembers && this.reactiveMembers.has(str)) {
|
|
912
888
|
const textVar = this.newTextVar();
|
|
913
889
|
this._createLines.push(`${textVar} = document.createTextNode('');`);
|
|
914
|
-
this.
|
|
890
|
+
this._pushEffect(`${textVar}.data = ${this._self}.${str}.value;`);
|
|
915
891
|
return textVar;
|
|
916
892
|
}
|
|
917
893
|
// Static tag without content (possibly with #id)
|
|
@@ -953,15 +929,15 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
953
929
|
|
|
954
930
|
// Property access on this (e.g., @prop, @children)
|
|
955
931
|
if (obj === 'this' && typeof prop === 'string') {
|
|
932
|
+
const s = this._self;
|
|
956
933
|
if (this.reactiveMembers && this.reactiveMembers.has(prop)) {
|
|
957
934
|
const textVar = this.newTextVar();
|
|
958
935
|
this._createLines.push(`${textVar} = document.createTextNode('');`);
|
|
959
|
-
this.
|
|
936
|
+
this._pushEffect(`${textVar}.data = ${s}.${prop}.value;`);
|
|
960
937
|
return textVar;
|
|
961
938
|
}
|
|
962
|
-
// Slot/prop — handle DOM nodes (children) and plain values
|
|
963
939
|
const slotVar = this.newElementVar('slot');
|
|
964
|
-
this._createLines.push(`${slotVar} =
|
|
940
|
+
this._createLines.push(`${slotVar} = ${s}.${prop} instanceof Node ? ${s}.${prop} : (${s}.${prop} != null ? document.createTextNode(String(${s}.${prop})) : document.createComment(''));`);
|
|
965
941
|
return slotVar;
|
|
966
942
|
}
|
|
967
943
|
|
|
@@ -1018,7 +994,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1018
994
|
const exprCode = this.generateInComponent(sexpr, 'value');
|
|
1019
995
|
if (this.hasReactiveDeps(sexpr)) {
|
|
1020
996
|
this._createLines.push(`${textVar} = document.createTextNode('');`);
|
|
1021
|
-
this.
|
|
997
|
+
this._pushEffect(`${textVar}.data = ${exprCode};`);
|
|
1022
998
|
} else {
|
|
1023
999
|
this._createLines.push(`${textVar} = document.createTextNode(String(${exprCode}));`);
|
|
1024
1000
|
}
|
|
@@ -1057,9 +1033,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1057
1033
|
this._createLines.push(`${textVar} = document.createTextNode(${val});`);
|
|
1058
1034
|
} else if (this.reactiveMembers && this.reactiveMembers.has(val)) {
|
|
1059
1035
|
this._createLines.push(`${textVar} = document.createTextNode('');`);
|
|
1060
|
-
this.
|
|
1036
|
+
this._pushEffect(`${textVar}.data = ${this._self}.${val}.value;`);
|
|
1061
1037
|
} else if (this.componentMembers && this.componentMembers.has(val)) {
|
|
1062
|
-
this._createLines.push(`${textVar} = document.createTextNode(String(this.${val}));`);
|
|
1038
|
+
this._createLines.push(`${textVar} = document.createTextNode(String(${this._self}.${val}));`);
|
|
1063
1039
|
} else {
|
|
1064
1040
|
this._createLines.push(`${textVar} = document.createTextNode(${this.generateInComponent(arg, 'value')});`);
|
|
1065
1041
|
}
|
|
@@ -1112,9 +1088,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1112
1088
|
} else {
|
|
1113
1089
|
const combined = this._pendingClassArgs.join(', ');
|
|
1114
1090
|
if (isSvg) {
|
|
1115
|
-
this.
|
|
1091
|
+
this._pushEffect(`${elVar}.setAttribute('class', __clsx(${combined}));`);
|
|
1116
1092
|
} else {
|
|
1117
|
-
this.
|
|
1093
|
+
this._pushEffect(`${elVar}.className = __clsx(${combined});`);
|
|
1118
1094
|
}
|
|
1119
1095
|
}
|
|
1120
1096
|
this._pendingClassArgs = prevClassArgs;
|
|
@@ -1151,9 +1127,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1151
1127
|
const combined = this._pendingClassArgs.join(', ');
|
|
1152
1128
|
const isSvg = SVG_TAGS.has(tag) || this._svgDepth > 0;
|
|
1153
1129
|
if (isSvg) {
|
|
1154
|
-
this.
|
|
1130
|
+
this._pushEffect(`${elVar}.setAttribute('class', __clsx(${combined}));`);
|
|
1155
1131
|
} else {
|
|
1156
|
-
this.
|
|
1132
|
+
this._pushEffect(`${elVar}.className = __clsx(${combined});`);
|
|
1157
1133
|
}
|
|
1158
1134
|
}
|
|
1159
1135
|
this._pendingClassArgs = prevClassArgs;
|
|
@@ -1175,9 +1151,8 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1175
1151
|
// Event handler: @click or (. this eventName)
|
|
1176
1152
|
if (this.is(key, '.') && key[1] === 'this') {
|
|
1177
1153
|
const eventName = key[2];
|
|
1178
|
-
// Bind method references to this
|
|
1179
1154
|
if (typeof value === 'string' && this.componentMembers?.has(value)) {
|
|
1180
|
-
this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => this.${value}(e)));`);
|
|
1155
|
+
this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => ${this._self}.${value}(e)));`);
|
|
1181
1156
|
} else {
|
|
1182
1157
|
const handlerCode = this.generateInComponent(value, 'value');
|
|
1183
1158
|
this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => (${handlerCode})(e)));`);
|
|
@@ -1199,9 +1174,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1199
1174
|
this._pendingClassArgs.push(valueCode);
|
|
1200
1175
|
} else if (this.hasReactiveDeps(value)) {
|
|
1201
1176
|
if (this._svgDepth > 0) {
|
|
1202
|
-
this.
|
|
1177
|
+
this._pushEffect(`${elVar}.setAttribute('class', __clsx(${valueCode}));`);
|
|
1203
1178
|
} else {
|
|
1204
|
-
this.
|
|
1179
|
+
this._pushEffect(`${elVar}.className = __clsx(${valueCode});`);
|
|
1205
1180
|
}
|
|
1206
1181
|
} else {
|
|
1207
1182
|
if (this._svgDepth > 0) {
|
|
@@ -1216,7 +1191,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1216
1191
|
// Element ref: ref: "name" → this.name = element
|
|
1217
1192
|
if (key === 'ref') {
|
|
1218
1193
|
const refName = String(value).replace(/^["']|["']$/g, '');
|
|
1219
|
-
this._createLines.push(
|
|
1194
|
+
this._createLines.push(`${this._self}.${refName} = ${elVar};`);
|
|
1220
1195
|
continue;
|
|
1221
1196
|
}
|
|
1222
1197
|
|
|
@@ -1235,11 +1210,11 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1235
1210
|
? 'e.target.valueAsNumber' : 'e.target.value';
|
|
1236
1211
|
}
|
|
1237
1212
|
|
|
1238
|
-
this.
|
|
1213
|
+
this._pushEffect(`${elVar}.${prop} = ${valueCode};`);
|
|
1239
1214
|
let assignCode = `${valueCode} = ${valueAccessor}`;
|
|
1240
1215
|
const rootMember = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
|
|
1241
1216
|
if (rootMember) {
|
|
1242
|
-
assignCode += `; this.${rootMember}.touch?.()`;
|
|
1217
|
+
assignCode += `; ${this._self}.${rootMember}.touch?.()`;
|
|
1243
1218
|
}
|
|
1244
1219
|
this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
|
|
1245
1220
|
continue;
|
|
@@ -1249,9 +1224,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1249
1224
|
|
|
1250
1225
|
// Smart two-way binding for value/checked when bound to reactive state
|
|
1251
1226
|
if ((key === 'value' || key === 'checked') && this.hasReactiveDeps(value)) {
|
|
1252
|
-
this.
|
|
1253
|
-
// Generate reverse binding for simple assignable targets or nested
|
|
1254
|
-
// reactive paths (with touch() for Svelte-style invalidation)
|
|
1227
|
+
this._pushEffect(`${elVar}.${key} = ${valueCode};`);
|
|
1255
1228
|
const rootMemberImplicit = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
|
|
1256
1229
|
if (this.isSimpleAssignable(value) || rootMemberImplicit) {
|
|
1257
1230
|
const event = key === 'checked' ? 'change' : 'input';
|
|
@@ -1260,7 +1233,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1260
1233
|
: 'e.target.value';
|
|
1261
1234
|
let assignCode = `${valueCode} = ${accessor}`;
|
|
1262
1235
|
if (rootMemberImplicit) {
|
|
1263
|
-
assignCode += `; this.${rootMemberImplicit}.touch?.()`;
|
|
1236
|
+
assignCode += `; ${this._self}.${rootMemberImplicit}.touch?.()`;
|
|
1264
1237
|
}
|
|
1265
1238
|
this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
|
|
1266
1239
|
}
|
|
@@ -1269,18 +1242,18 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1269
1242
|
|
|
1270
1243
|
if (key === 'innerHTML' || key === 'textContent' || key === 'innerText') {
|
|
1271
1244
|
if (this.hasReactiveDeps(value)) {
|
|
1272
|
-
this.
|
|
1245
|
+
this._pushEffect(`${elVar}.${key} = ${valueCode};`);
|
|
1273
1246
|
} else {
|
|
1274
1247
|
this._createLines.push(`${elVar}.${key} = ${valueCode};`);
|
|
1275
1248
|
}
|
|
1276
1249
|
} else if (BOOLEAN_ATTRS.has(key)) {
|
|
1277
1250
|
if (this.hasReactiveDeps(value)) {
|
|
1278
|
-
this.
|
|
1251
|
+
this._pushEffect(`${elVar}.toggleAttribute('${key}', !!${valueCode});`);
|
|
1279
1252
|
} else {
|
|
1280
1253
|
this._createLines.push(`if (${valueCode}) ${elVar}.setAttribute('${key}', '');`);
|
|
1281
1254
|
}
|
|
1282
1255
|
} else if (this.hasReactiveDeps(value)) {
|
|
1283
|
-
this.
|
|
1256
|
+
this._pushEffect(`${elVar}.setAttribute('${key}', ${valueCode});`);
|
|
1284
1257
|
} else {
|
|
1285
1258
|
this._createLines.push(`${elVar}.setAttribute('${key}', ${valueCode});`);
|
|
1286
1259
|
}
|
|
@@ -1309,10 +1282,13 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1309
1282
|
|
|
1310
1283
|
const fragVar = this.newElementVar('frag');
|
|
1311
1284
|
this._createLines.push(`${fragVar} = document.createDocumentFragment();`);
|
|
1285
|
+
const children = [];
|
|
1312
1286
|
for (const stmt of statements) {
|
|
1313
1287
|
const childVar = this.generateNode(stmt);
|
|
1314
1288
|
this._createLines.push(`${fragVar}.appendChild(${childVar});`);
|
|
1289
|
+
children.push(childVar);
|
|
1315
1290
|
}
|
|
1291
|
+
this._fragChildren.set(fragVar, children);
|
|
1316
1292
|
return fragVar;
|
|
1317
1293
|
};
|
|
1318
1294
|
|
|
@@ -1328,9 +1304,8 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1328
1304
|
|
|
1329
1305
|
const condCode = this.generateInComponent(condition, 'value');
|
|
1330
1306
|
|
|
1331
|
-
|
|
1332
|
-
const
|
|
1333
|
-
const extraArgs = loopParams ? `, ${loopParams}` : '';
|
|
1307
|
+
const outerParams = this._loopVarStack.map(v => `${v.itemVar}, ${v.indexVar}`).join(', ');
|
|
1308
|
+
const outerExtra = outerParams ? `, ${outerParams}` : '';
|
|
1334
1309
|
|
|
1335
1310
|
const thenBlockName = this.newBlockVar();
|
|
1336
1311
|
this.generateConditionBranch(thenBlockName, thenBlock);
|
|
@@ -1347,7 +1322,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1347
1322
|
setupLines.push(` const anchor = ${anchorVar};`);
|
|
1348
1323
|
setupLines.push(` let currentBlock = null;`);
|
|
1349
1324
|
setupLines.push(` let showing = null;`);
|
|
1350
|
-
|
|
1325
|
+
const effOpen = this._factoryMode ? 'disposers.push(__effect(() => {' : '__effect(() => {';
|
|
1326
|
+
const effClose = this._factoryMode ? '}));' : '});';
|
|
1327
|
+
setupLines.push(` ${effOpen}`);
|
|
1351
1328
|
setupLines.push(` const show = !!(${condCode});`);
|
|
1352
1329
|
setupLines.push(` const want = show ? 'then' : ${elseBlock ? "'else'" : 'null'};`);
|
|
1353
1330
|
setupLines.push(` if (want === showing) return;`);
|
|
@@ -1359,20 +1336,20 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1359
1336
|
setupLines.push(` showing = want;`);
|
|
1360
1337
|
setupLines.push(``);
|
|
1361
1338
|
setupLines.push(` if (want === 'then') {`);
|
|
1362
|
-
setupLines.push(` currentBlock = ${thenBlockName}(this${
|
|
1339
|
+
setupLines.push(` currentBlock = ${thenBlockName}(${this._self}${outerExtra});`);
|
|
1363
1340
|
setupLines.push(` currentBlock.c();`);
|
|
1364
1341
|
setupLines.push(` if (anchor.parentNode) currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
|
|
1365
|
-
setupLines.push(` currentBlock.p(this${
|
|
1342
|
+
setupLines.push(` currentBlock.p(${this._self}${outerExtra});`);
|
|
1366
1343
|
setupLines.push(` }`);
|
|
1367
1344
|
if (elseBlock) {
|
|
1368
1345
|
setupLines.push(` if (want === 'else') {`);
|
|
1369
|
-
setupLines.push(` currentBlock = ${elseBlockName}(this${
|
|
1346
|
+
setupLines.push(` currentBlock = ${elseBlockName}(${this._self}${outerExtra});`);
|
|
1370
1347
|
setupLines.push(` currentBlock.c();`);
|
|
1371
1348
|
setupLines.push(` if (anchor.parentNode) currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
|
|
1372
|
-
setupLines.push(` currentBlock.p(this${
|
|
1349
|
+
setupLines.push(` currentBlock.p(${this._self}${outerExtra});`);
|
|
1373
1350
|
setupLines.push(` }`);
|
|
1374
1351
|
}
|
|
1375
|
-
setupLines.push(` })
|
|
1352
|
+
setupLines.push(` ${effClose}`);
|
|
1376
1353
|
setupLines.push(`}`);
|
|
1377
1354
|
|
|
1378
1355
|
this._setupLines.push(setupLines.join('\n '));
|
|
@@ -1385,36 +1362,36 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1385
1362
|
// --------------------------------------------------------------------------
|
|
1386
1363
|
|
|
1387
1364
|
proto.generateConditionBranch = function(blockName, block) {
|
|
1388
|
-
const
|
|
1389
|
-
const savedSetupLines = this._setupLines;
|
|
1365
|
+
const saved = [this._createLines, this._setupLines, this._factoryMode, this._factoryVars];
|
|
1390
1366
|
|
|
1391
1367
|
this._createLines = [];
|
|
1392
1368
|
this._setupLines = [];
|
|
1369
|
+
this._factoryMode = true;
|
|
1370
|
+
this._factoryVars = new Set();
|
|
1393
1371
|
|
|
1394
1372
|
const rootVar = this.generateTemplateBlock(block);
|
|
1395
1373
|
const createLines = this._createLines;
|
|
1396
1374
|
const setupLines = this._setupLines;
|
|
1375
|
+
const factoryVars = this._factoryVars;
|
|
1397
1376
|
|
|
1398
|
-
this._createLines =
|
|
1399
|
-
this._setupLines = savedSetupLines;
|
|
1377
|
+
[this._createLines, this._setupLines, this._factoryMode, this._factoryVars] = saved;
|
|
1400
1378
|
|
|
1401
|
-
const
|
|
1379
|
+
const outerParams = this._loopVarStack.map(v => `${v.itemVar}, ${v.indexVar}`).join(', ');
|
|
1380
|
+
const extraParams = outerParams ? `, ${outerParams}` : '';
|
|
1402
1381
|
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
const extraParams = loopParams ? `, ${loopParams}` : '';
|
|
1382
|
+
this.emitBlockFactory(blockName, `ctx${extraParams}`, rootVar, createLines, setupLines, factoryVars);
|
|
1383
|
+
};
|
|
1406
1384
|
|
|
1385
|
+
// --------------------------------------------------------------------------
|
|
1386
|
+
// emitBlockFactory — shared factory generation for conditionals and loops
|
|
1387
|
+
// --------------------------------------------------------------------------
|
|
1388
|
+
|
|
1389
|
+
proto.emitBlockFactory = function(blockName, params, rootVar, createLines, setupLines, factoryVars) {
|
|
1407
1390
|
const factoryLines = [];
|
|
1408
|
-
factoryLines.push(`function ${blockName}(
|
|
1391
|
+
factoryLines.push(`function ${blockName}(${params}) {`);
|
|
1409
1392
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
for (const line of createLines) {
|
|
1413
|
-
const match = line.match(/^this\.(_(?:el|t|anchor|frag|slot|c|inst|empty)\d+)\s*=/);
|
|
1414
|
-
if (match) localVars.add(match[1]);
|
|
1415
|
-
}
|
|
1416
|
-
if (localVars.size > 0) {
|
|
1417
|
-
factoryLines.push(` let ${[...localVars].join(', ')};`);
|
|
1393
|
+
if (factoryVars.size > 0) {
|
|
1394
|
+
factoryLines.push(` let ${[...factoryVars].join(', ')};`);
|
|
1418
1395
|
}
|
|
1419
1396
|
|
|
1420
1397
|
const hasEffects = setupLines.length > 0;
|
|
@@ -1424,49 +1401,43 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1424
1401
|
|
|
1425
1402
|
factoryLines.push(` return {`);
|
|
1426
1403
|
|
|
1427
|
-
// c() - create
|
|
1428
1404
|
factoryLines.push(` c() {`);
|
|
1429
1405
|
for (const line of createLines) {
|
|
1430
|
-
factoryLines.push(` ${
|
|
1406
|
+
factoryLines.push(` ${line}`);
|
|
1431
1407
|
}
|
|
1432
1408
|
factoryLines.push(` },`);
|
|
1433
1409
|
|
|
1434
|
-
|
|
1410
|
+
const fragChildren = this._fragChildren.get(rootVar);
|
|
1435
1411
|
factoryLines.push(` m(target, anchor) {`);
|
|
1436
|
-
|
|
1412
|
+
if (fragChildren) {
|
|
1413
|
+
for (const child of fragChildren) {
|
|
1414
|
+
factoryLines.push(` if (target) target.insertBefore(${child}, anchor);`);
|
|
1415
|
+
}
|
|
1416
|
+
} else {
|
|
1417
|
+
factoryLines.push(` if (target) target.insertBefore(${rootVar}, anchor);`);
|
|
1418
|
+
}
|
|
1437
1419
|
factoryLines.push(` },`);
|
|
1438
1420
|
|
|
1439
|
-
|
|
1440
|
-
factoryLines.push(` p(ctx${extraParams}) {`);
|
|
1421
|
+
factoryLines.push(` p(${params}) {`);
|
|
1441
1422
|
if (hasEffects) {
|
|
1442
1423
|
factoryLines.push(` disposers.forEach(d => d());`);
|
|
1443
1424
|
factoryLines.push(` disposers = [];`);
|
|
1444
1425
|
for (const line of setupLines) {
|
|
1445
|
-
|
|
1446
|
-
const wrappedLine = localizedLine.replace(
|
|
1447
|
-
/__effect\(\(\) => \{/g,
|
|
1448
|
-
'disposers.push(__effect(() => {'
|
|
1449
|
-
).replace(
|
|
1450
|
-
/\}\);$/gm,
|
|
1451
|
-
'}));'
|
|
1452
|
-
);
|
|
1453
|
-
factoryLines.push(` ${wrappedLine}`);
|
|
1426
|
+
factoryLines.push(` ${line}`);
|
|
1454
1427
|
}
|
|
1455
1428
|
}
|
|
1456
1429
|
factoryLines.push(` },`);
|
|
1457
1430
|
|
|
1458
|
-
// d() - destroy
|
|
1459
1431
|
factoryLines.push(` d(detaching) {`);
|
|
1460
1432
|
if (hasEffects) {
|
|
1461
1433
|
factoryLines.push(` disposers.forEach(d => d());`);
|
|
1462
1434
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
for (const child of condFragChildren) {
|
|
1435
|
+
if (fragChildren) {
|
|
1436
|
+
for (const child of fragChildren) {
|
|
1466
1437
|
factoryLines.push(` if (detaching && ${child}) ${child}.remove();`);
|
|
1467
1438
|
}
|
|
1468
1439
|
} else {
|
|
1469
|
-
factoryLines.push(` if (detaching && ${
|
|
1440
|
+
factoryLines.push(` if (detaching && ${rootVar}) ${rootVar}.remove();`);
|
|
1470
1441
|
}
|
|
1471
1442
|
factoryLines.push(` }`);
|
|
1472
1443
|
|
|
@@ -1514,104 +1485,27 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1514
1485
|
}
|
|
1515
1486
|
}
|
|
1516
1487
|
|
|
1517
|
-
|
|
1518
|
-
const savedCreateLines = this._createLines;
|
|
1519
|
-
const savedSetupLines = this._setupLines;
|
|
1488
|
+
const saved = [this._createLines, this._setupLines, this._factoryMode, this._factoryVars];
|
|
1520
1489
|
|
|
1521
1490
|
this._createLines = [];
|
|
1522
1491
|
this._setupLines = [];
|
|
1492
|
+
this._factoryMode = true;
|
|
1493
|
+
this._factoryVars = new Set();
|
|
1523
1494
|
|
|
1524
|
-
|
|
1525
|
-
const
|
|
1526
|
-
const outerExtra = outerLoopParams ? `, ${outerLoopParams}` : '';
|
|
1495
|
+
const outerParams = this._loopVarStack.map(v => `${v.itemVar}, ${v.indexVar}`).join(', ');
|
|
1496
|
+
const outerExtra = outerParams ? `, ${outerParams}` : '';
|
|
1527
1497
|
|
|
1528
1498
|
this._loopVarStack.push({ itemVar, indexVar });
|
|
1529
1499
|
const itemNode = this.generateTemplateBlock(body);
|
|
1530
1500
|
this._loopVarStack.pop();
|
|
1531
1501
|
const itemCreateLines = this._createLines;
|
|
1532
1502
|
const itemSetupLines = this._setupLines;
|
|
1503
|
+
const itemFactoryVars = this._factoryVars;
|
|
1533
1504
|
|
|
1534
|
-
this._createLines =
|
|
1535
|
-
this._setupLines = savedSetupLines;
|
|
1536
|
-
|
|
1537
|
-
const localizeVar = (line) => this.localizeVar(line);
|
|
1538
|
-
|
|
1539
|
-
// Generate block factory
|
|
1540
|
-
const factoryLines = [];
|
|
1541
|
-
factoryLines.push(`function ${blockName}(ctx, ${itemVar}, ${indexVar}${outerExtra}) {`);
|
|
1542
|
-
|
|
1543
|
-
const localVars = new Set();
|
|
1544
|
-
for (const line of itemCreateLines) {
|
|
1545
|
-
const match = line.match(/^this\.(_(?:el|t|anchor|frag|slot|c|inst|empty)\d+)\s*=/);
|
|
1546
|
-
if (match) localVars.add(match[1]);
|
|
1547
|
-
}
|
|
1548
|
-
if (localVars.size > 0) {
|
|
1549
|
-
factoryLines.push(` let ${[...localVars].join(', ')};`);
|
|
1550
|
-
}
|
|
1505
|
+
[this._createLines, this._setupLines, this._factoryMode, this._factoryVars] = saved;
|
|
1551
1506
|
|
|
1552
|
-
const
|
|
1553
|
-
|
|
1554
|
-
factoryLines.push(` let disposers = [];`);
|
|
1555
|
-
}
|
|
1556
|
-
|
|
1557
|
-
factoryLines.push(` return {`);
|
|
1558
|
-
|
|
1559
|
-
// c() - create
|
|
1560
|
-
factoryLines.push(` c() {`);
|
|
1561
|
-
for (const line of itemCreateLines) {
|
|
1562
|
-
factoryLines.push(` ${localizeVar(line)}`);
|
|
1563
|
-
}
|
|
1564
|
-
factoryLines.push(` },`);
|
|
1565
|
-
|
|
1566
|
-
// m() - mount (also repositions already-mounted blocks)
|
|
1567
|
-
const loopFragChildren = getFragChildren(itemNode, itemCreateLines, localizeVar);
|
|
1568
|
-
factoryLines.push(` m(target, anchor) {`);
|
|
1569
|
-
if (loopFragChildren) {
|
|
1570
|
-
for (const child of loopFragChildren) {
|
|
1571
|
-
factoryLines.push(` if (target) target.insertBefore(${child}, anchor);`);
|
|
1572
|
-
}
|
|
1573
|
-
} else {
|
|
1574
|
-
factoryLines.push(` if (target) target.insertBefore(${localizeVar(itemNode)}, anchor);`);
|
|
1575
|
-
}
|
|
1576
|
-
factoryLines.push(` },`);
|
|
1577
|
-
|
|
1578
|
-
// p() - update
|
|
1579
|
-
factoryLines.push(` p(ctx, ${itemVar}, ${indexVar}${outerExtra}) {`);
|
|
1580
|
-
if (hasEffects) {
|
|
1581
|
-
factoryLines.push(` disposers.forEach(d => d());`);
|
|
1582
|
-
factoryLines.push(` disposers = [];`);
|
|
1583
|
-
for (const line of itemSetupLines) {
|
|
1584
|
-
const localizedLine = localizeVar(line);
|
|
1585
|
-
const wrappedLine = localizedLine.replace(
|
|
1586
|
-
/__effect\(\(\) => \{/g,
|
|
1587
|
-
'disposers.push(__effect(() => {'
|
|
1588
|
-
).replace(
|
|
1589
|
-
/\}\);$/gm,
|
|
1590
|
-
'}));'
|
|
1591
|
-
);
|
|
1592
|
-
factoryLines.push(` ${wrappedLine}`);
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
factoryLines.push(` },`);
|
|
1596
|
-
|
|
1597
|
-
// d() - destroy
|
|
1598
|
-
factoryLines.push(` d(detaching) {`);
|
|
1599
|
-
if (hasEffects) {
|
|
1600
|
-
factoryLines.push(` disposers.forEach(d => d());`);
|
|
1601
|
-
}
|
|
1602
|
-
if (loopFragChildren) {
|
|
1603
|
-
for (const child of loopFragChildren) {
|
|
1604
|
-
factoryLines.push(` if (detaching && ${child}) ${child}.remove();`);
|
|
1605
|
-
}
|
|
1606
|
-
} else {
|
|
1607
|
-
factoryLines.push(` if (detaching && ${localizeVar(itemNode)}) ${localizeVar(itemNode)}.remove();`);
|
|
1608
|
-
}
|
|
1609
|
-
factoryLines.push(` }`);
|
|
1610
|
-
|
|
1611
|
-
factoryLines.push(` };`);
|
|
1612
|
-
factoryLines.push(`}`);
|
|
1613
|
-
|
|
1614
|
-
this._blockFactories.push(factoryLines.join('\n'));
|
|
1507
|
+
const loopParams = `ctx, ${itemVar}, ${indexVar}${outerExtra}`;
|
|
1508
|
+
this.emitBlockFactory(blockName, loopParams, itemNode, itemCreateLines, itemSetupLines, itemFactoryVars);
|
|
1615
1509
|
|
|
1616
1510
|
// Generate reconciliation code in _setup()
|
|
1617
1511
|
const setupLines = [];
|
|
@@ -1619,7 +1513,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1619
1513
|
setupLines.push(`{`);
|
|
1620
1514
|
setupLines.push(` const __anchor = ${anchorVar};`);
|
|
1621
1515
|
setupLines.push(` const __map = new Map();`);
|
|
1622
|
-
|
|
1516
|
+
const effOpen = this._factoryMode ? 'disposers.push(__effect(() => {' : '__effect(() => {';
|
|
1517
|
+
const effClose = this._factoryMode ? '}));' : '});';
|
|
1518
|
+
setupLines.push(` ${effOpen}`);
|
|
1623
1519
|
setupLines.push(` const __items = ${collectionCode};`);
|
|
1624
1520
|
setupLines.push(` const __parent = __anchor.parentNode;`);
|
|
1625
1521
|
setupLines.push(` const __newMap = new Map();`);
|
|
@@ -1629,11 +1525,11 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1629
1525
|
setupLines.push(` const __key = ${keyExpr};`);
|
|
1630
1526
|
setupLines.push(` let __block = __map.get(__key);`);
|
|
1631
1527
|
setupLines.push(` if (!__block) {`);
|
|
1632
|
-
setupLines.push(` __block = ${blockName}(this, ${itemVar}, ${indexVar}${outerExtra});`);
|
|
1528
|
+
setupLines.push(` __block = ${blockName}(${this._self}, ${itemVar}, ${indexVar}${outerExtra});`);
|
|
1633
1529
|
setupLines.push(` __block.c();`);
|
|
1634
1530
|
setupLines.push(` }`);
|
|
1635
1531
|
setupLines.push(` __block.m(__parent, __anchor);`);
|
|
1636
|
-
setupLines.push(` __block.p(this, ${itemVar}, ${indexVar}${outerExtra});`);
|
|
1532
|
+
setupLines.push(` __block.p(${this._self}, ${itemVar}, ${indexVar}${outerExtra});`);
|
|
1637
1533
|
setupLines.push(` __newMap.set(__key, __block);`);
|
|
1638
1534
|
setupLines.push(` }`);
|
|
1639
1535
|
setupLines.push(``);
|
|
@@ -1643,7 +1539,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1643
1539
|
setupLines.push(``);
|
|
1644
1540
|
setupLines.push(` __map.clear();`);
|
|
1645
1541
|
setupLines.push(` for (const [__k, __v] of __newMap) __map.set(__k, __v);`);
|
|
1646
|
-
setupLines.push(` })
|
|
1542
|
+
setupLines.push(` ${effClose}`);
|
|
1647
1543
|
setupLines.push(`}`);
|
|
1648
1544
|
|
|
1649
1545
|
this._setupLines.push(setupLines.join('\n '));
|
|
@@ -1660,15 +1556,16 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1660
1556
|
const elVar = this.newElementVar('el');
|
|
1661
1557
|
const { propsCode, reactiveProps, childrenSetupLines } = this.buildComponentProps(args);
|
|
1662
1558
|
|
|
1559
|
+
const s = this._self;
|
|
1663
1560
|
this._createLines.push(`${instVar} = new ${componentName}(${propsCode});`);
|
|
1664
1561
|
this._createLines.push(`${elVar} = ${instVar}._create();`);
|
|
1665
|
-
this._createLines.push(`(
|
|
1562
|
+
this._createLines.push(`(${s}._children || (${s}._children = [])).push(${instVar});`);
|
|
1666
1563
|
|
|
1667
1564
|
this._setupLines.push(`if (${instVar}._setup) ${instVar}._setup();`);
|
|
1668
1565
|
this._setupLines.push(`if (${instVar}.mounted) ${instVar}.mounted();`);
|
|
1669
1566
|
|
|
1670
1567
|
for (const { key, valueCode } of reactiveProps) {
|
|
1671
|
-
this.
|
|
1568
|
+
this._pushEffect(`if (${instVar}.${key}) ${instVar}.${key}.value = ${valueCode};`);
|
|
1672
1569
|
}
|
|
1673
1570
|
|
|
1674
1571
|
for (const line of childrenSetupLines) {
|
|
@@ -1688,56 +1585,43 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1688
1585
|
let childrenVar = null;
|
|
1689
1586
|
const childrenSetupLines = [];
|
|
1690
1587
|
|
|
1588
|
+
// Simple reactive values pass the signal directly for shared reactivity;
|
|
1589
|
+
// complex expressions use normal .value unwrapping to compute the value.
|
|
1590
|
+
const addProp = (key, value) => {
|
|
1591
|
+
const isDirectSignal = this.reactiveMembers && (
|
|
1592
|
+
(typeof value === 'string' && this.reactiveMembers.has(value)) ||
|
|
1593
|
+
(Array.isArray(value) && value[0] === '.' && value[1] === 'this' && typeof value[2] === 'string' && this.reactiveMembers.has(value[2]))
|
|
1594
|
+
);
|
|
1595
|
+
if (isDirectSignal) {
|
|
1596
|
+
const member = typeof value === 'string' ? value : value[2];
|
|
1597
|
+
props.push(`${key}: ${this._self}.${member}`);
|
|
1598
|
+
} else {
|
|
1599
|
+
const valueCode = this.generateInComponent(value, 'value');
|
|
1600
|
+
props.push(`${key}: ${valueCode}`);
|
|
1601
|
+
if (this.hasReactiveDeps(value)) {
|
|
1602
|
+
reactiveProps.push({ key, valueCode });
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
};
|
|
1606
|
+
|
|
1607
|
+
const addObjectProps = (objExpr) => {
|
|
1608
|
+
for (let i = 1; i < objExpr.length; i++) {
|
|
1609
|
+
const [key, value] = objExpr[i];
|
|
1610
|
+
if (typeof key === 'string') addProp(key, value);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
|
|
1691
1614
|
for (const arg of args) {
|
|
1692
1615
|
if (this.is(arg, 'object')) {
|
|
1693
|
-
|
|
1694
|
-
const [key, value] = arg[i];
|
|
1695
|
-
if (typeof key === 'string') {
|
|
1696
|
-
// Simple reactive identifier — pass signal directly for shared reactivity.
|
|
1697
|
-
// Complex expressions — use normal .value unwrapping to compute the value.
|
|
1698
|
-
const isSimpleReactive = this.reactiveMembers && (
|
|
1699
|
-
(typeof value === 'string' && this.reactiveMembers.has(value)) ||
|
|
1700
|
-
(Array.isArray(value) && value[0] === '.' && value[1] === 'this' && typeof value[2] === 'string' && this.reactiveMembers.has(value[2]))
|
|
1701
|
-
);
|
|
1702
|
-
if (isSimpleReactive) {
|
|
1703
|
-
const member = typeof value === 'string' ? value : value[2];
|
|
1704
|
-
props.push(`${key}: this.${member}`);
|
|
1705
|
-
} else {
|
|
1706
|
-
const valueCode = this.generateInComponent(value, 'value');
|
|
1707
|
-
props.push(`${key}: ${valueCode}`);
|
|
1708
|
-
if (this.hasReactiveDeps(value)) {
|
|
1709
|
-
reactiveProps.push({ key, valueCode });
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1616
|
+
addObjectProps(arg);
|
|
1714
1617
|
} else if (Array.isArray(arg) && (arg[0] === '->' || arg[0] === '=>')) {
|
|
1715
1618
|
let block = arg[2];
|
|
1716
1619
|
if (block) {
|
|
1717
|
-
// Indented attributes: extract object nodes from block as props
|
|
1718
1620
|
if (this.is(block, 'block')) {
|
|
1719
1621
|
const domChildren = [];
|
|
1720
1622
|
for (const child of block.slice(1)) {
|
|
1721
1623
|
if (this.is(child, 'object')) {
|
|
1722
|
-
|
|
1723
|
-
const [key, value] = child[i];
|
|
1724
|
-
if (typeof key === 'string') {
|
|
1725
|
-
const isSimpleReactive = this.reactiveMembers && (
|
|
1726
|
-
(typeof value === 'string' && this.reactiveMembers.has(value)) ||
|
|
1727
|
-
(Array.isArray(value) && value[0] === '.' && value[1] === 'this' && typeof value[2] === 'string' && this.reactiveMembers.has(value[2]))
|
|
1728
|
-
);
|
|
1729
|
-
if (isSimpleReactive) {
|
|
1730
|
-
const member = typeof value === 'string' ? value : value[2];
|
|
1731
|
-
props.push(`${key}: this.${member}`);
|
|
1732
|
-
} else {
|
|
1733
|
-
const valueCode = this.generateInComponent(value, 'value');
|
|
1734
|
-
props.push(`${key}: ${valueCode}`);
|
|
1735
|
-
if (this.hasReactiveDeps(value)) {
|
|
1736
|
-
reactiveProps.push({ key, valueCode });
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1624
|
+
addObjectProps(child);
|
|
1741
1625
|
} else {
|
|
1742
1626
|
domChildren.push(child);
|
|
1743
1627
|
}
|