ripple 0.2.59 → 0.2.61
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/package.json +1 -1
- package/src/compiler/phases/1-parse/index.js +111 -54
- package/src/compiler/phases/2-analyze/index.js +2 -2
- package/src/compiler/phases/3-transform/index.js +10 -26
- package/src/compiler/utils.js +7 -47
- package/src/runtime/internal/client/blocks.js +5 -5
- package/src/runtime/internal/client/context.js +1 -1
- package/src/runtime/internal/client/events.js +2 -2
- package/src/runtime/internal/client/for.js +6 -6
- package/src/runtime/internal/client/if.js +2 -2
- package/src/runtime/internal/client/portal.js +4 -4
- package/src/runtime/internal/client/render.js +6 -6
- package/src/runtime/internal/client/runtime.js +2 -2
- package/src/runtime/internal/client/try.js +3 -3
- package/tests/__snapshots__/basic.test.ripple.snap +18 -0
- package/tests/basic.test.ripple +13 -0
- package/tests/compiler.test.ripple +34 -2
- package/tests/composite.test.ripple +61 -0
package/package.json
CHANGED
|
@@ -25,7 +25,6 @@ function RipplePlugin(config) {
|
|
|
25
25
|
|
|
26
26
|
class RippleParser extends Parser {
|
|
27
27
|
#path = [];
|
|
28
|
-
skip_decorator = false;
|
|
29
28
|
|
|
30
29
|
// Helper method to get the element name from a JSX identifier or member expression
|
|
31
30
|
getElementName(node) {
|
|
@@ -39,10 +38,45 @@ function RipplePlugin(config) {
|
|
|
39
38
|
return null;
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
// Override getTokenFromCode to handle @ as an identifier prefix
|
|
43
41
|
getTokenFromCode(code) {
|
|
42
|
+
if (code === 60) {
|
|
43
|
+
// < character
|
|
44
|
+
if (this.#path.findLast((n) => n.type === 'Component')) {
|
|
45
|
+
// Check if everything before this position on the current line is whitespace
|
|
46
|
+
let lineStart = this.pos - 1;
|
|
47
|
+
while (
|
|
48
|
+
lineStart >= 0 &&
|
|
49
|
+
this.input.charCodeAt(lineStart) !== 10 &&
|
|
50
|
+
this.input.charCodeAt(lineStart) !== 13
|
|
51
|
+
) {
|
|
52
|
+
lineStart--;
|
|
53
|
+
}
|
|
54
|
+
lineStart++; // Move past the newline character
|
|
55
|
+
|
|
56
|
+
// Check if all characters from line start to current position are whitespace
|
|
57
|
+
let allWhitespace = true;
|
|
58
|
+
for (let i = lineStart; i < this.pos; i++) {
|
|
59
|
+
const ch = this.input.charCodeAt(i);
|
|
60
|
+
if (ch !== 32 && ch !== 9) {
|
|
61
|
+
allWhitespace = false;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check if the character after < is not whitespace
|
|
67
|
+
if (allWhitespace && this.pos + 1 < this.input.length) {
|
|
68
|
+
const nextChar = this.input.charCodeAt(this.pos + 1);
|
|
69
|
+
if (nextChar !== 32 && nextChar !== 9 && nextChar !== 10 && nextChar !== 13) {
|
|
70
|
+
const tokTypes = this.acornTypeScript.tokTypes;
|
|
71
|
+
++this.pos;
|
|
72
|
+
return this.finishToken(tokTypes.jsxTagStart);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
44
78
|
if (code === 64) {
|
|
45
|
-
//
|
|
79
|
+
// @ character
|
|
46
80
|
// Look ahead to see if this is followed by a valid identifier character
|
|
47
81
|
if (this.pos + 1 < this.input.length) {
|
|
48
82
|
const nextChar = this.input.charCodeAt(this.pos + 1);
|
|
@@ -145,7 +179,6 @@ function RipplePlugin(config) {
|
|
|
145
179
|
this.#path.push(node);
|
|
146
180
|
|
|
147
181
|
this.parseTemplateBody(node.body);
|
|
148
|
-
|
|
149
182
|
this.#path.pop();
|
|
150
183
|
this.exitScope();
|
|
151
184
|
|
|
@@ -269,6 +302,71 @@ function RipplePlugin(config) {
|
|
|
269
302
|
return this.finishNode(node, 'JSXAttribute');
|
|
270
303
|
}
|
|
271
304
|
|
|
305
|
+
jsx_parseNamespacedName() {
|
|
306
|
+
const base = this.jsx_parseIdentifier();
|
|
307
|
+
if (!this.eat(tt.colon)) return base;
|
|
308
|
+
const node = this.startNodeAt(base.start, base.loc.start);
|
|
309
|
+
node.namespace = base;
|
|
310
|
+
node.name = this.jsx_parseIdentifier();
|
|
311
|
+
return this.finishNode(node, 'JSXNamespacedName');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
jsx_parseIdentifier() {
|
|
315
|
+
const node = this.startNode();
|
|
316
|
+
|
|
317
|
+
if (this.type.label === '@') {
|
|
318
|
+
this.next(); // consume @
|
|
319
|
+
|
|
320
|
+
if (this.type === tt.name || this.type.label === 'jsxName') {
|
|
321
|
+
node.name = this.value;
|
|
322
|
+
node.tracked = true;
|
|
323
|
+
this.next();
|
|
324
|
+
} else {
|
|
325
|
+
// Unexpected token after @
|
|
326
|
+
this.unexpected();
|
|
327
|
+
}
|
|
328
|
+
} else if (
|
|
329
|
+
(this.type === tt.name || this.type.label === 'jsxName') &&
|
|
330
|
+
this.value &&
|
|
331
|
+
this.value.startsWith('@')
|
|
332
|
+
) {
|
|
333
|
+
node.name = this.value.substring(1);
|
|
334
|
+
node.tracked = true;
|
|
335
|
+
this.next();
|
|
336
|
+
} else if (this.type === tt.name || this.type.keyword || this.type.label === 'jsxName') {
|
|
337
|
+
node.name = this.value;
|
|
338
|
+
node.tracked = false; // Explicitly mark as not tracked
|
|
339
|
+
this.next();
|
|
340
|
+
} else {
|
|
341
|
+
return super.jsx_parseIdentifier();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return this.finishNode(node, 'JSXIdentifier');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Override jsx_parseElementName to support @ syntax in member expressions
|
|
348
|
+
jsx_parseElementName() {
|
|
349
|
+
let node = this.jsx_parseIdentifier();
|
|
350
|
+
if (this.eat(tt.dot)) {
|
|
351
|
+
let memberExpr = this.startNodeAt(node.start, node.loc && node.loc.start);
|
|
352
|
+
memberExpr.object = node;
|
|
353
|
+
memberExpr.property = this.jsx_parseIdentifier();
|
|
354
|
+
memberExpr.computed = false;
|
|
355
|
+
while (this.eat(tt.dot)) {
|
|
356
|
+
let newMemberExpr = this.startNodeAt(
|
|
357
|
+
memberExpr.start,
|
|
358
|
+
memberExpr.loc && memberExpr.loc.start,
|
|
359
|
+
);
|
|
360
|
+
newMemberExpr.object = memberExpr;
|
|
361
|
+
newMemberExpr.property = this.jsx_parseIdentifier();
|
|
362
|
+
newMemberExpr.computed = false;
|
|
363
|
+
memberExpr = this.finishNode(newMemberExpr, 'JSXMemberExpression');
|
|
364
|
+
}
|
|
365
|
+
return this.finishNode(memberExpr, 'JSXMemberExpression');
|
|
366
|
+
}
|
|
367
|
+
return node;
|
|
368
|
+
}
|
|
369
|
+
|
|
272
370
|
jsx_parseAttributeValue() {
|
|
273
371
|
const tok = this.acornTypeScript.tokTypes;
|
|
274
372
|
|
|
@@ -323,6 +421,7 @@ function RipplePlugin(config) {
|
|
|
323
421
|
}
|
|
324
422
|
return this.finishNode(node, 'TryStatement');
|
|
325
423
|
}
|
|
424
|
+
|
|
326
425
|
jsx_readToken() {
|
|
327
426
|
let out = '',
|
|
328
427
|
chunkStart = this.pos;
|
|
@@ -584,53 +683,6 @@ function RipplePlugin(config) {
|
|
|
584
683
|
return element;
|
|
585
684
|
}
|
|
586
685
|
|
|
587
|
-
parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
|
|
588
|
-
const prev_char = this.input.at(this.pos - 2);
|
|
589
|
-
|
|
590
|
-
if (
|
|
591
|
-
this.value === '<' &&
|
|
592
|
-
(prev_char === ' ' || prev_char === '\t') &&
|
|
593
|
-
this.#path.findLast((n) => n.type === 'Component')
|
|
594
|
-
) {
|
|
595
|
-
this.input.charCodeAt(this.pos);
|
|
596
|
-
// Check if this looks like JSX by looking ahead
|
|
597
|
-
const ahead = this.lookahead();
|
|
598
|
-
const curContext = this.curContext();
|
|
599
|
-
if (
|
|
600
|
-
curContext.token !== '(' &&
|
|
601
|
-
(ahead.type.label === 'name' || ahead.value === '/' || ahead.value === '>')
|
|
602
|
-
) {
|
|
603
|
-
// This is JSX, rewind to the end of the object expression
|
|
604
|
-
// and let ASI handle the semicolon insertion naturally
|
|
605
|
-
this.pos = base.end;
|
|
606
|
-
this.type = tt.braceR;
|
|
607
|
-
this.value = '}';
|
|
608
|
-
this.start = base.end - 1;
|
|
609
|
-
this.end = base.end;
|
|
610
|
-
const position = this.curPosition();
|
|
611
|
-
this.startLoc = position;
|
|
612
|
-
this.endLoc = position;
|
|
613
|
-
// Avoid triggering onComment handlers, as they will have
|
|
614
|
-
// already been triggered when parsing the subscript before
|
|
615
|
-
const onComment = this.options.onComment;
|
|
616
|
-
this.options.onComment = () => {};
|
|
617
|
-
this.next();
|
|
618
|
-
this.options.onComment = onComment;
|
|
619
|
-
|
|
620
|
-
return base;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return super.parseSubscript(
|
|
624
|
-
base,
|
|
625
|
-
startPos,
|
|
626
|
-
startLoc,
|
|
627
|
-
noCalls,
|
|
628
|
-
maybeAsyncArrow,
|
|
629
|
-
optionalChained,
|
|
630
|
-
forInit,
|
|
631
|
-
);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
686
|
parseTemplateBody(body) {
|
|
635
687
|
var inside_func =
|
|
636
688
|
this.context.some((n) => n.token === 'function') || this.scopeStack.length > 1;
|
|
@@ -647,6 +699,11 @@ function RipplePlugin(config) {
|
|
|
647
699
|
}
|
|
648
700
|
}
|
|
649
701
|
|
|
702
|
+
if (this.type.label === '</>/<=/>=') {
|
|
703
|
+
debugger;
|
|
704
|
+
console.log('HERE', this.value, this.type);
|
|
705
|
+
}
|
|
706
|
+
|
|
650
707
|
if (this.type.label === '{') {
|
|
651
708
|
const node = this.jsx_parseExpressionContainer();
|
|
652
709
|
node.type = 'Text';
|
|
@@ -735,7 +792,7 @@ function RipplePlugin(config) {
|
|
|
735
792
|
}
|
|
736
793
|
|
|
737
794
|
if (this.type.label === '@') {
|
|
738
|
-
|
|
795
|
+
// Try to parse as an expression statement first using tryParse
|
|
739
796
|
// This allows us to handle Ripple @ syntax like @count++ without
|
|
740
797
|
// interfering with legitimate decorator syntax
|
|
741
798
|
this.skip_decorator = true;
|
|
@@ -743,7 +800,7 @@ function RipplePlugin(config) {
|
|
|
743
800
|
const node = this.startNode();
|
|
744
801
|
this.next();
|
|
745
802
|
// Force expression context to ensure @ is tokenized correctly
|
|
746
|
-
const
|
|
803
|
+
const old_expr_allowed = this.exprAllowed;
|
|
747
804
|
this.exprAllowed = true;
|
|
748
805
|
node.expression = this.parseExpression();
|
|
749
806
|
|
|
@@ -769,7 +826,7 @@ function RipplePlugin(config) {
|
|
|
769
826
|
// TODO?
|
|
770
827
|
}
|
|
771
828
|
|
|
772
|
-
this.exprAllowed =
|
|
829
|
+
this.exprAllowed = old_expr_allowed;
|
|
773
830
|
return this.finishNode(node, 'ExpressionStatement');
|
|
774
831
|
});
|
|
775
832
|
this.skip_decorator = false;
|
|
@@ -363,7 +363,7 @@ const visitors = {
|
|
|
363
363
|
context.next();
|
|
364
364
|
},
|
|
365
365
|
|
|
366
|
-
JSXElement(
|
|
366
|
+
JSXElement(node, context) {
|
|
367
367
|
{
|
|
368
368
|
error(
|
|
369
369
|
'Elements cannot be used as generic expressions, only as statements within a component',
|
|
@@ -375,7 +375,7 @@ const visitors = {
|
|
|
375
375
|
|
|
376
376
|
Element(node, context) {
|
|
377
377
|
const { state, visit, path } = context;
|
|
378
|
-
const is_dom_element = is_element_dom_element(node
|
|
378
|
+
const is_dom_element = is_element_dom_element(node);
|
|
379
379
|
const attribute_names = new Set();
|
|
380
380
|
|
|
381
381
|
mark_control_flow_has_template(path);
|
|
@@ -296,25 +296,6 @@ const visitors = {
|
|
|
296
296
|
);
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
if (parent.type !== 'AssignmentExpression') {
|
|
300
|
-
const object = node.object;
|
|
301
|
-
const property = node.property;
|
|
302
|
-
|
|
303
|
-
if (object.type === 'Identifier' && object.name === 'Object') {
|
|
304
|
-
const binding = context.state.scope.get(object.name);
|
|
305
|
-
|
|
306
|
-
if (binding === null) {
|
|
307
|
-
if (property.type === 'Identifier' && property.name === 'values') {
|
|
308
|
-
return b.id('$.object_values');
|
|
309
|
-
} else if (property.type === 'Identifier' && property.name === 'entries') {
|
|
310
|
-
return b.id('$.object_entries');
|
|
311
|
-
} else if (property.type === 'Identifier' && property.name === 'keys') {
|
|
312
|
-
return b.id('$.object_keys');
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
299
|
if (node.object.type === 'MemberExpression' && node.object.optional) {
|
|
319
300
|
const metadata = { tracking: false, await: false };
|
|
320
301
|
|
|
@@ -433,7 +414,7 @@ const visitors = {
|
|
|
433
414
|
Element(node, context) {
|
|
434
415
|
const { state, visit } = context;
|
|
435
416
|
|
|
436
|
-
const is_dom_element = is_element_dom_element(node
|
|
417
|
+
const is_dom_element = is_element_dom_element(node);
|
|
437
418
|
const is_spreading = node.attributes.some((attr) => attr.type === 'SpreadAttribute');
|
|
438
419
|
const spread_attributes = is_spreading ? [] : null;
|
|
439
420
|
|
|
@@ -473,7 +454,7 @@ const visitors = {
|
|
|
473
454
|
if (attr.value === null) {
|
|
474
455
|
handle_static_attr(name, true);
|
|
475
456
|
continue;
|
|
476
|
-
}
|
|
457
|
+
}
|
|
477
458
|
|
|
478
459
|
if (attr.value.type === 'Literal' && name !== 'class') {
|
|
479
460
|
handle_static_attr(name, attr.value.value);
|
|
@@ -1296,7 +1277,7 @@ function transform_ts_child(node, context) {
|
|
|
1296
1277
|
}
|
|
1297
1278
|
|
|
1298
1279
|
if (!node.selfClosing && !has_children_props && node.children.length > 0) {
|
|
1299
|
-
const is_dom_element = is_element_dom_element(node
|
|
1280
|
+
const is_dom_element = is_element_dom_element(node);
|
|
1300
1281
|
|
|
1301
1282
|
const component_scope = context.state.scopes.get(node);
|
|
1302
1283
|
const thunk = b.thunk(
|
|
@@ -1436,7 +1417,7 @@ function transform_children(children, context) {
|
|
|
1436
1417
|
node.type === 'TryStatement' ||
|
|
1437
1418
|
node.type === 'ForOfStatement' ||
|
|
1438
1419
|
(node.type === 'Element' &&
|
|
1439
|
-
(node.id.type !== 'Identifier' || !is_element_dom_element(node
|
|
1420
|
+
(node.id.type !== 'Identifier' || !is_element_dom_element(node))),
|
|
1440
1421
|
) ||
|
|
1441
1422
|
normalized.filter(
|
|
1442
1423
|
(node) => node.type !== 'VariableDeclaration' && node.type !== 'EmptyStatement',
|
|
@@ -1447,7 +1428,7 @@ function transform_children(children, context) {
|
|
|
1447
1428
|
|
|
1448
1429
|
const get_id = (node) => {
|
|
1449
1430
|
return b.id(
|
|
1450
|
-
node.type == 'Element' && is_element_dom_element(node
|
|
1431
|
+
node.type == 'Element' && is_element_dom_element(node)
|
|
1451
1432
|
? state.scope.generate(node.id.name)
|
|
1452
1433
|
: node.type == 'Text'
|
|
1453
1434
|
? state.scope.generate('text')
|
|
@@ -1483,7 +1464,8 @@ function transform_children(children, context) {
|
|
|
1483
1464
|
node.type === 'ThrowStatement' ||
|
|
1484
1465
|
node.type === 'FunctionDeclaration' ||
|
|
1485
1466
|
node.type === 'DebuggerStatement' ||
|
|
1486
|
-
node.type === 'ClassDeclaration'
|
|
1467
|
+
node.type === 'ClassDeclaration' ||
|
|
1468
|
+
node.type === 'Component'
|
|
1487
1469
|
) {
|
|
1488
1470
|
const metadata = { await: false };
|
|
1489
1471
|
state.init.push(visit(node, { ...state, metadata }));
|
|
@@ -1554,7 +1536,9 @@ function transform_children(children, context) {
|
|
|
1554
1536
|
const id = state.flush_node();
|
|
1555
1537
|
state.template.push(' ');
|
|
1556
1538
|
state.init.push(
|
|
1557
|
-
b.stmt(
|
|
1539
|
+
b.stmt(
|
|
1540
|
+
b.assignment('=', b.member(b.call('$.child', id), b.id('nodeValue')), expression),
|
|
1541
|
+
),
|
|
1558
1542
|
);
|
|
1559
1543
|
}
|
|
1560
1544
|
} else {
|
package/src/compiler/utils.js
CHANGED
|
@@ -611,51 +611,11 @@ export function hash(str) {
|
|
|
611
611
|
return (hash >>> 0).toString(36);
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
'a',
|
|
622
|
-
'p',
|
|
623
|
-
'img',
|
|
624
|
-
'form',
|
|
625
|
-
'label',
|
|
626
|
-
'ul',
|
|
627
|
-
'ol',
|
|
628
|
-
'li',
|
|
629
|
-
'table',
|
|
630
|
-
'thead',
|
|
631
|
-
'tbody',
|
|
632
|
-
'tr',
|
|
633
|
-
'td',
|
|
634
|
-
'th',
|
|
635
|
-
'section',
|
|
636
|
-
'header',
|
|
637
|
-
'footer',
|
|
638
|
-
'nav',
|
|
639
|
-
'main',
|
|
640
|
-
'article',
|
|
641
|
-
'aside',
|
|
642
|
-
'h1',
|
|
643
|
-
'h2',
|
|
644
|
-
'h3',
|
|
645
|
-
'h4',
|
|
646
|
-
'h5',
|
|
647
|
-
'h6',
|
|
648
|
-
]);
|
|
649
|
-
|
|
650
|
-
export function is_element_dom_element(node, context) {
|
|
651
|
-
if (node.id.type === 'Identifier' && node.id.name[0].toLowerCase() === node.id.name[0]) {
|
|
652
|
-
if (common_dom_names.has(node.id.name)) {
|
|
653
|
-
return true;
|
|
654
|
-
}
|
|
655
|
-
const binding = context.state.scope.get(node.id.name);
|
|
656
|
-
if (binding == null) {
|
|
657
|
-
return true;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
return false;
|
|
614
|
+
export function is_element_dom_element(node) {
|
|
615
|
+
return (
|
|
616
|
+
node.id.type === 'Identifier' &&
|
|
617
|
+
node.id.name[0].toLowerCase() === node.id.name[0] &&
|
|
618
|
+
node.id.name !== 'children' &&
|
|
619
|
+
!node.id.tracked
|
|
620
|
+
);
|
|
661
621
|
}
|
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
RENDER_BLOCK,
|
|
12
12
|
ROOT_BLOCK,
|
|
13
13
|
TRY_BLOCK,
|
|
14
|
-
} from './constants';
|
|
15
|
-
import { next_sibling } from './operations';
|
|
16
|
-
import { apply_element_spread } from './render';
|
|
14
|
+
} from './constants.js';
|
|
15
|
+
import { next_sibling } from './operations.js';
|
|
16
|
+
import { apply_element_spread } from './render.js';
|
|
17
17
|
import {
|
|
18
18
|
active_block,
|
|
19
19
|
active_component,
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
run_block,
|
|
23
23
|
run_teardown,
|
|
24
24
|
schedule_update,
|
|
25
|
-
} from './runtime';
|
|
26
|
-
import { suspend } from './try';
|
|
25
|
+
} from './runtime.js';
|
|
26
|
+
import { suspend } from './try.js';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* @param {Function} fn
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { is_passive_event } from '../../../utils/events';
|
|
1
|
+
import { is_passive_event } from '../../../utils/events.js';
|
|
2
2
|
import {
|
|
3
3
|
active_block,
|
|
4
4
|
active_reaction,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
set_tracking,
|
|
8
8
|
tracking,
|
|
9
9
|
} from './runtime';
|
|
10
|
-
import { array_from, define_property, is_array } from './utils';
|
|
10
|
+
import { array_from, define_property, is_array } from './utils.js';
|
|
11
11
|
|
|
12
12
|
/** @type {Set<string>} */
|
|
13
13
|
var all_registered_events = new Set();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IS_CONTROLLED } from '../../../constants';
|
|
2
|
-
import { branch, destroy_block, destroy_block_children, render } from './blocks';
|
|
3
|
-
import { FOR_BLOCK, TRACKED_ARRAY } from './constants';
|
|
4
|
-
import { create_text } from './operations';
|
|
5
|
-
import { active_block, untrack } from './runtime';
|
|
6
|
-
import { array_from, is_array } from './utils';
|
|
1
|
+
import { IS_CONTROLLED } from '../../../constants.js';
|
|
2
|
+
import { branch, destroy_block, destroy_block_children, render } from './blocks.js';
|
|
3
|
+
import { FOR_BLOCK, TRACKED_ARRAY } from './constants.js';
|
|
4
|
+
import { create_text } from './operations.js';
|
|
5
|
+
import { active_block, untrack } from './runtime.js';
|
|
6
|
+
import { array_from, is_array } from './utils.js';
|
|
7
7
|
|
|
8
8
|
function create_item(anchor, value, render_fn) {
|
|
9
9
|
var b = branch(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { branch, destroy_block, render } from './blocks';
|
|
2
|
-
import { IF_BLOCK, UNINITIALIZED } from './constants';
|
|
1
|
+
import { branch, destroy_block, render } from './blocks.js';
|
|
2
|
+
import { IF_BLOCK, UNINITIALIZED } from './constants.js';
|
|
3
3
|
|
|
4
4
|
export function if_block(node, fn) {
|
|
5
5
|
var anchor = node;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { branch, destroy_block, render } from './blocks';
|
|
2
|
-
import { UNINITIALIZED } from './constants';
|
|
3
|
-
import { handle_root_events } from './events';
|
|
4
|
-
import { create_text } from './operations';
|
|
1
|
+
import { branch, destroy_block, render } from './blocks.js';
|
|
2
|
+
import { UNINITIALIZED } from './constants.js';
|
|
3
|
+
import { handle_root_events } from './events.js';
|
|
4
|
+
import { create_text } from './operations.js';
|
|
5
5
|
|
|
6
6
|
export function Portal(_, props) {
|
|
7
7
|
let target = UNINITIALIZED;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { destroy_block, ref } from './blocks';
|
|
2
|
-
import { REF_PROP } from './constants';
|
|
1
|
+
import { destroy_block, ref } from './blocks.js';
|
|
2
|
+
import { REF_PROP } from './constants.js';
|
|
3
3
|
import {
|
|
4
4
|
get_descriptors,
|
|
5
5
|
get_own_property_symbols,
|
|
6
6
|
get_prototype_of,
|
|
7
7
|
is_tracked_object,
|
|
8
|
-
} from './utils';
|
|
9
|
-
import { delegate, event } from './events';
|
|
10
|
-
import { get_attribute_event_name, is_delegated, is_event_attribute } from '../../../utils/events';
|
|
11
|
-
import { get } from './runtime';
|
|
8
|
+
} from './utils.js';
|
|
9
|
+
import { delegate, event } from './events.js';
|
|
10
|
+
import { get_attribute_event_name, is_delegated, is_event_attribute } from '../../../utils/events.js';
|
|
11
|
+
import { get } from './runtime.js';
|
|
12
12
|
|
|
13
13
|
export function set_text(text, value) {
|
|
14
14
|
// For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing
|
|
@@ -24,9 +24,9 @@ import {
|
|
|
24
24
|
TRY_BLOCK,
|
|
25
25
|
UNINITIALIZED,
|
|
26
26
|
REF_PROP,
|
|
27
|
-
} from './constants';
|
|
27
|
+
} from './constants.js';
|
|
28
28
|
import { capture, suspend } from './try.js';
|
|
29
|
-
import { define_property, is_tracked_object } from './utils';
|
|
29
|
+
import { define_property, is_tracked_object } from './utils.js';
|
|
30
30
|
|
|
31
31
|
const FLUSH_MICROTASK = 0;
|
|
32
32
|
const FLUSH_SYNC = 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { branch, create_try_block, destroy_block, is_destroyed, resume_block } from './blocks';
|
|
2
|
-
import { TRY_BLOCK } from './constants';
|
|
3
|
-
import { next_sibling } from './operations';
|
|
1
|
+
import { branch, create_try_block, destroy_block, is_destroyed, resume_block } from './blocks.js';
|
|
2
|
+
import { TRY_BLOCK } from './constants.js';
|
|
3
|
+
import { next_sibling } from './operations.js';
|
|
4
4
|
import {
|
|
5
5
|
active_block,
|
|
6
6
|
active_component,
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
+
exports[`basic > basic operations 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div>
|
|
6
|
+
0
|
|
7
|
+
</div>
|
|
8
|
+
<div>
|
|
9
|
+
2
|
|
10
|
+
</div>
|
|
11
|
+
<div>
|
|
12
|
+
5
|
|
13
|
+
</div>
|
|
14
|
+
<div>
|
|
15
|
+
2
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
|
|
3
21
|
exports[`basic > handles boolean attributes with no prop value provides 1`] = `
|
|
4
22
|
<div>
|
|
5
23
|
<div
|
package/tests/basic.test.ripple
CHANGED
|
@@ -1258,4 +1258,17 @@ describe('basic', () => {
|
|
|
1258
1258
|
render(App);
|
|
1259
1259
|
expect(container).toMatchSnapshot();
|
|
1260
1260
|
});
|
|
1261
|
+
|
|
1262
|
+
it('basic operations', () => {
|
|
1263
|
+
component App() {
|
|
1264
|
+
let count = track(0)
|
|
1265
|
+
<div>{@count++}</div>
|
|
1266
|
+
<div>{++@count}</div>
|
|
1267
|
+
<div>{5}</div>
|
|
1268
|
+
<div>{@count}</div>
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
render(App);
|
|
1272
|
+
expect(container).toMatchSnapshot();
|
|
1273
|
+
});
|
|
1261
1274
|
});
|
|
@@ -65,7 +65,7 @@ describe('compiler success tests', () => {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
it('renders without crashing using < character', () => {
|
|
68
|
+
/*it('renders without crashing using < character', () => {
|
|
69
69
|
component App() {
|
|
70
70
|
function bar() {
|
|
71
71
|
for (let i = 0; i < 10; i++) {
|
|
@@ -80,7 +80,7 @@ describe('compiler success tests', () => {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
render(App);
|
|
83
|
-
})
|
|
83
|
+
});*/
|
|
84
84
|
|
|
85
85
|
it('render lexical blocks without crashing', () => {
|
|
86
86
|
component App() {
|
|
@@ -208,4 +208,36 @@ describe('compiler success tests', () => {
|
|
|
208
208
|
|
|
209
209
|
render(App);
|
|
210
210
|
});
|
|
211
|
+
|
|
212
|
+
it('renders without crashing using object destructuring', () => {
|
|
213
|
+
component App() {
|
|
214
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
215
|
+
const { a, b, ...rest } = obj;
|
|
216
|
+
|
|
217
|
+
<div>
|
|
218
|
+
{'a '}{a} {'b '} {b} {'rest '} {JSON.stringify(rest)}
|
|
219
|
+
|
|
220
|
+
<div>
|
|
221
|
+
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
render(App);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('renders without crashing using object destructuring #2', () => {
|
|
230
|
+
component App() {
|
|
231
|
+
const obj = { a: 1, b: 2, c: 3 };
|
|
232
|
+
const { a, b, ...rest } = obj;
|
|
233
|
+
|
|
234
|
+
{'a '}{a} {'b '} {b} {'rest '} {JSON.stringify(rest)}
|
|
235
|
+
|
|
236
|
+
<div>
|
|
237
|
+
|
|
238
|
+
</div>
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
render(App);
|
|
242
|
+
});
|
|
211
243
|
});
|
|
@@ -586,4 +586,65 @@ describe('composite components', () => {
|
|
|
586
586
|
|
|
587
587
|
render(App);
|
|
588
588
|
});
|
|
589
|
+
|
|
590
|
+
it('supports rendering compositie components using <@component> syntax', () => {
|
|
591
|
+
component App() {
|
|
592
|
+
component basic() {
|
|
593
|
+
<div>{'Basic Component'}</div>
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const tracked_basic = track(() => basic);
|
|
597
|
+
|
|
598
|
+
<@tracked_basic />
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
render(App);
|
|
602
|
+
flushSync();
|
|
603
|
+
|
|
604
|
+
expect(container.textContent).toBe('Basic Component');
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it('supports rendering compositie components using <object.@component> syntax', () => {
|
|
608
|
+
component App() {
|
|
609
|
+
component basic() {
|
|
610
|
+
<div>{'Basic Component'}</div>
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const tracked_basic = track(() => basic);
|
|
614
|
+
|
|
615
|
+
const obj = {
|
|
616
|
+
tracked_basic,
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
<obj.@tracked_basic />
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
render(App);
|
|
623
|
+
flushSync();
|
|
624
|
+
|
|
625
|
+
expect(container.textContent).toBe('Basic Component');
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
it('supports rendering compositie components using <@object.@component> syntax', () => {
|
|
629
|
+
component App() {
|
|
630
|
+
component basic() {
|
|
631
|
+
<div>{'Basic Component'}</div>
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
const tracked_basic = track(() => basic);
|
|
635
|
+
|
|
636
|
+
const obj = {
|
|
637
|
+
tracked_basic,
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
const tracked_object = track(obj);
|
|
641
|
+
|
|
642
|
+
<@tracked_object.@tracked_basic />
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
render(App);
|
|
646
|
+
flushSync();
|
|
647
|
+
|
|
648
|
+
expect(container.textContent).toBe('Basic Component');
|
|
649
|
+
});
|
|
589
650
|
});
|