ripple 0.2.214 → 0.2.216
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/CHANGELOG.md +85 -0
- package/package.json +2 -2
- package/src/compiler/errors.js +33 -1
- package/src/compiler/index.d.ts +2 -2
- package/src/compiler/index.js +8 -1
- package/src/compiler/phases/2-analyze/index.js +75 -8
- package/src/compiler/phases/2-analyze/prune.js +25 -12
- package/src/compiler/phases/2-analyze/validation.js +1 -0
- package/src/compiler/phases/3-transform/client/index.js +302 -54
- package/src/compiler/phases/3-transform/segments.js +5 -3
- package/src/compiler/phases/3-transform/server/index.js +81 -18
- package/src/compiler/types/index.d.ts +125 -90
- package/src/compiler/utils.js +20 -0
- package/src/runtime/internal/client/blocks.js +13 -2
- package/src/runtime/internal/client/constants.js +2 -0
- package/src/runtime/internal/client/hmr.js +112 -1
- package/src/runtime/internal/client/hydration.js +29 -2
- package/src/runtime/internal/client/index.js +3 -1
- package/src/runtime/internal/client/runtime.js +5 -1
- package/src/runtime/internal/client/template.js +30 -68
- package/src/runtime/internal/client/try.js +73 -2
- package/src/runtime/internal/server/index.js +1 -1
- package/tests/client/basic/basic.errors.test.ripple +66 -0
- package/tests/client/basic/basic.hmr.test.ripple +19 -0
- package/tests/client/compiler/compiler.basic.test.ripple +16 -0
- package/tests/client/css/style-identifier.test.ripple +396 -0
- package/tests/client/for.test.ripple +41 -0
- package/tests/client/switch.test.ripple +50 -0
- package/tests/client/try.test.ripple +98 -0
- package/tests/hydration/compiled/client/basic.js +10 -10
- package/tests/hydration/compiled/client/composite.js +8 -8
- package/tests/hydration/compiled/client/for.js +18 -18
- package/tests/hydration/compiled/client/head.js +1 -1
- package/tests/hydration/compiled/client/hmr.js +86 -0
- package/tests/hydration/compiled/client/html-in-template.js +64 -0
- package/tests/hydration/compiled/client/html.js +1418 -13
- package/tests/hydration/compiled/client/if-children.js +7 -7
- package/tests/hydration/compiled/client/if.js +7 -7
- package/tests/hydration/compiled/client/mixed-control-flow.js +483 -0
- package/tests/hydration/compiled/client/nested-control-flow.js +1457 -0
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +2 -2
- package/tests/hydration/compiled/client/return.js +103 -103
- package/tests/hydration/compiled/client/switch.js +205 -30
- package/tests/hydration/compiled/client/try.js +130 -0
- package/tests/hydration/compiled/server/composite.js +2 -0
- package/tests/hydration/compiled/server/hmr.js +110 -0
- package/tests/hydration/compiled/server/html-in-template.js +96 -0
- package/tests/hydration/compiled/server/html.js +1704 -0
- package/tests/hydration/compiled/server/if-children.js +4 -0
- package/tests/hydration/compiled/server/mixed-control-flow.js +303 -0
- package/tests/hydration/compiled/server/nested-control-flow.js +733 -0
- package/tests/hydration/compiled/server/portal.js +9 -1
- package/tests/hydration/compiled/server/switch.js +153 -0
- package/tests/hydration/compiled/server/try.js +140 -0
- package/tests/hydration/components/hmr.ripple +35 -0
- package/tests/hydration/components/html-in-template.ripple +24 -0
- package/tests/hydration/components/html.ripple +390 -1
- package/tests/hydration/components/mixed-control-flow.ripple +114 -0
- package/tests/hydration/components/nested-control-flow.ripple +269 -0
- package/tests/hydration/components/switch.ripple +78 -0
- package/tests/hydration/components/try.ripple +31 -0
- package/tests/hydration/hmr.test.js +74 -0
- package/tests/hydration/html-in-template.test.js +45 -0
- package/tests/hydration/html.test.js +116 -20
- package/tests/hydration/mixed-control-flow.test.js +70 -0
- package/tests/hydration/nested-control-flow.test.js +203 -0
- package/tests/hydration/switch.test.js +67 -0
- package/tests/hydration/try.test.js +37 -0
- package/tests/server/__snapshots__/compiler.test.ripple.snap +3 -1
- package/tests/server/await.test.ripple +0 -2
- package/tests/server/basic.components.test.ripple +1 -1
- package/tests/server/basic.test.ripple +0 -2
- package/tests/server/compiler.test.ripple +0 -2
- package/tests/server/composite.test.ripple +0 -2
- package/tests/server/context.test.ripple +0 -2
- package/tests/server/dynamic-elements.test.ripple +2 -2
- package/tests/server/for.test.ripple +0 -3
- package/tests/server/html-nesting-validation.test.ripple +2 -4
- package/tests/server/if.test.ripple +0 -3
- package/tests/server/return.test.ripple +0 -3
- package/tests/server/streaming-ssr.test.ripple +1 -3
- package/tests/server/style-identifier.test.ripple +236 -0
- package/tests/server/switch.test.ripple +0 -3
- package/tests/server/try.test.ripple +82 -0
- package/tests/server/tsconfig.json +1 -0
- package/tests/setup-server.js +2 -0
- package/tsconfig.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,90 @@
|
|
|
1
1
|
# ripple
|
|
2
2
|
|
|
3
|
+
## 0.2.216
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#757](https://github.com/Ripple-TS/ripple/pull/757)
|
|
8
|
+
[`9fb507d`](https://github.com/Ripple-TS/ripple/commit/9fb507d76af6fd6a5c636af1976d1e03d3e869ac)
|
|
9
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - fixes compiler error that was
|
|
10
|
+
generating async functions for call expressions inside if conditions when inside
|
|
11
|
+
async context
|
|
12
|
+
|
|
13
|
+
- [#751](https://github.com/Ripple-TS/ripple/pull/751)
|
|
14
|
+
[`e1de4bb`](https://github.com/Ripple-TS/ripple/commit/e1de4bb9df75342a693cda24d0999a423db05ec4)
|
|
15
|
+
Thanks [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Fix
|
|
16
|
+
HMR "zoom" issue when a Ripple file is changed in the dev server.
|
|
17
|
+
|
|
18
|
+
When a layout component contained children with nested `if`/`for` blocks,
|
|
19
|
+
hydration would leave `hydrate_node` pointing deep inside the layout's root
|
|
20
|
+
element (e.g. a HYDRATION_END comment inside `<main>`). The `append()`
|
|
21
|
+
function's `parentNode === dom` check only handled direct children, so it missed
|
|
22
|
+
grandchild/deeper positions and incorrectly updated the branch block's `s.end`
|
|
23
|
+
to that deep internal node.
|
|
24
|
+
|
|
25
|
+
This caused two problems on HMR re-render:
|
|
26
|
+
1. `remove_block_dom(s.start, s.end)` removed wrong elements (the deep node was
|
|
27
|
+
treated as a sibling boundary, causing removal of unrelated content including
|
|
28
|
+
the root HYDRATION_END comment).
|
|
29
|
+
2. `target = hydrate_node` (set after the initial render) became `null` or
|
|
30
|
+
pointed outside the component's region, so new content was inserted at the
|
|
31
|
+
wrong DOM location — producing a layout that appeared "zoomed" because it
|
|
32
|
+
rendered outside its CSS container context.
|
|
33
|
+
|
|
34
|
+
The fix changes the `parentNode === dom` check to `dom.contains(hydrate_node)`,
|
|
35
|
+
consistent with the `anchor === dom` branch that already used `dom.contains()`.
|
|
36
|
+
This correctly resets `hydrate_node` to `dom`'s sibling level regardless of how
|
|
37
|
+
deeply nested it was inside `dom`.
|
|
38
|
+
|
|
39
|
+
- [#764](https://github.com/Ripple-TS/ripple/pull/764)
|
|
40
|
+
[`95ea864`](https://github.com/Ripple-TS/ripple/commit/95ea8645b2cb27e2610a4ace4c8fb238c92d441a)
|
|
41
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Fixes syntax color
|
|
42
|
+
highlighting for `pending`
|
|
43
|
+
|
|
44
|
+
- Updated dependencies
|
|
45
|
+
[[`9fb507d`](https://github.com/Ripple-TS/ripple/commit/9fb507d76af6fd6a5c636af1976d1e03d3e869ac),
|
|
46
|
+
[`e1de4bb`](https://github.com/Ripple-TS/ripple/commit/e1de4bb9df75342a693cda24d0999a423db05ec4),
|
|
47
|
+
[`95ea864`](https://github.com/Ripple-TS/ripple/commit/95ea8645b2cb27e2610a4ace4c8fb238c92d441a)]:
|
|
48
|
+
- ripple@0.2.216
|
|
49
|
+
|
|
50
|
+
## 0.2.215
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- [#742](https://github.com/Ripple-TS/ripple/pull/742)
|
|
55
|
+
[`a9ecda4`](https://github.com/Ripple-TS/ripple/commit/a9ecda4e3f29e3b934d9f5ee80d55c059ba36ebe)
|
|
56
|
+
Thanks [@copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Fix
|
|
57
|
+
catch block not executing when used with pending block in try statements.
|
|
58
|
+
Previously, errors thrown inside async components within
|
|
59
|
+
`try { ... } pending { ... } catch { ... }` blocks were lost as unhandled
|
|
60
|
+
promise rejections. Now errors are properly caught and the catch block is
|
|
61
|
+
rendered. Also fixes the server-side rendering to not include pending content in
|
|
62
|
+
the final output when the async operation resolves or errors.
|
|
63
|
+
|
|
64
|
+
- [#744](https://github.com/Ripple-TS/ripple/pull/744)
|
|
65
|
+
[`6653c5c`](https://github.com/Ripple-TS/ripple/commit/6653c5cebfbd4dce129906a25686ef9c63dc592a)
|
|
66
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Fix compiler analysis
|
|
67
|
+
incorrectly marking untrackable nodes as tracked. `MemberExpression` now only
|
|
68
|
+
enables tracking when the member or its property is actually marked as
|
|
69
|
+
`tracked`, and unconditional tracking side-effects were removed from
|
|
70
|
+
`CallExpression` and `NewExpression` visitors.
|
|
71
|
+
|
|
72
|
+
Also fixes the client transform for `TrackedExpression` in TypeScript mode to
|
|
73
|
+
emit a `['#v']` member access (marked as `tracked`) instead of the runtime
|
|
74
|
+
`_$_.get(...)` call, aligning TSX output with tracked-access semantics.
|
|
75
|
+
|
|
76
|
+
- [#733](https://github.com/Ripple-TS/ripple/pull/733)
|
|
77
|
+
[`307dcf3`](https://github.com/Ripple-TS/ripple/commit/307dcf30f27dae987a19a59508cc2593c839eda3)
|
|
78
|
+
Thanks [@trueadm](https://github.com/trueadm)! - Fix client HMR updates when a
|
|
79
|
+
wrapped component has not mounted yet. The runtime now avoids calling `set()` on
|
|
80
|
+
an undefined tracked source and keeps wrapper HMR state synchronized across
|
|
81
|
+
update chains.
|
|
82
|
+
- Updated dependencies
|
|
83
|
+
[[`a9ecda4`](https://github.com/Ripple-TS/ripple/commit/a9ecda4e3f29e3b934d9f5ee80d55c059ba36ebe),
|
|
84
|
+
[`6653c5c`](https://github.com/Ripple-TS/ripple/commit/6653c5cebfbd4dce129906a25686ef9c63dc592a),
|
|
85
|
+
[`307dcf3`](https://github.com/Ripple-TS/ripple/commit/307dcf30f27dae987a19a59508cc2593c839eda3)]:
|
|
86
|
+
- ripple@0.2.215
|
|
87
|
+
|
|
3
88
|
## 0.2.214
|
|
4
89
|
|
|
5
90
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.216",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -96,6 +96,6 @@
|
|
|
96
96
|
"vscode-languageserver-types": "^3.17.5"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
|
-
"ripple": "0.2.
|
|
99
|
+
"ripple": "0.2.216"
|
|
100
100
|
}
|
|
101
101
|
}
|
package/src/compiler/errors.js
CHANGED
|
@@ -9,9 +9,14 @@
|
|
|
9
9
|
* @param {string | null} filename
|
|
10
10
|
* @param {AST.Node} node
|
|
11
11
|
* @param {RippleCompileError[]} [errors]
|
|
12
|
+
* @param {AST.CommentWithLocation[]} [comments]
|
|
12
13
|
* @returns {void}
|
|
13
14
|
*/
|
|
14
|
-
export function error(message, filename, node, errors) {
|
|
15
|
+
export function error(message, filename, node, errors, comments) {
|
|
16
|
+
if (errors && comments && is_ripple_error_suppressed(node, comments)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
const error = /** @type {RippleCompileError} */ (new Error(message));
|
|
16
21
|
|
|
17
22
|
// same as the acorn compiler error
|
|
@@ -43,3 +48,30 @@ export function error(message, filename, node, errors) {
|
|
|
43
48
|
error.type = 'fatal';
|
|
44
49
|
throw error;
|
|
45
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {AST.CommentWithLocation} comment
|
|
54
|
+
* @return {boolean}
|
|
55
|
+
*/
|
|
56
|
+
function is_ripple_error_suppress_comment(comment) {
|
|
57
|
+
const text = comment.value.trim();
|
|
58
|
+
return text.startsWith('@ripple-ignore') || text.startsWith('@ripple-expect-error');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {AST.Node} node
|
|
63
|
+
* @param {AST.CommentWithLocation[]} comments
|
|
64
|
+
*/
|
|
65
|
+
function is_ripple_error_suppressed(node, comments) {
|
|
66
|
+
if (node.loc) {
|
|
67
|
+
const node_start_line = node.loc.start.line;
|
|
68
|
+
for (const comment of comments) {
|
|
69
|
+
if (comment.type === 'Line' && comment.loc.start.line === node_start_line - 1) {
|
|
70
|
+
if (is_ripple_error_suppress_comment(comment)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
package/src/compiler/index.d.ts
CHANGED
|
@@ -101,6 +101,7 @@ interface SharedCompileOptions {
|
|
|
101
101
|
}
|
|
102
102
|
export interface CompileOptions extends SharedCompileOptions {
|
|
103
103
|
mode?: 'client' | 'server';
|
|
104
|
+
hmr?: boolean;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
export interface ParseOptions {
|
|
@@ -115,8 +116,7 @@ export interface AnalyzeOptions extends ParseOptions, Pick<CompileOptions, 'mode
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
export interface VolarCompileOptions
|
|
118
|
-
extends Omit<ParseOptions, 'errors' | 'comments'>,
|
|
119
|
-
SharedCompileOptions {}
|
|
119
|
+
extends Omit<ParseOptions, 'errors' | 'comments'>, SharedCompileOptions {}
|
|
120
120
|
|
|
121
121
|
export function parse(source: string, options?: ParseOptions): AST.Program;
|
|
122
122
|
|
package/src/compiler/index.js
CHANGED
|
@@ -34,7 +34,14 @@ export function compile(source, filename, options = {}) {
|
|
|
34
34
|
options?.minify_css ?? false,
|
|
35
35
|
options?.dev ?? false,
|
|
36
36
|
)
|
|
37
|
-
: transform_client(
|
|
37
|
+
: transform_client(
|
|
38
|
+
filename,
|
|
39
|
+
source,
|
|
40
|
+
analysis,
|
|
41
|
+
false,
|
|
42
|
+
options?.minify_css ?? false,
|
|
43
|
+
options?.hmr ?? false,
|
|
44
|
+
);
|
|
38
45
|
|
|
39
46
|
return result;
|
|
40
47
|
}
|
|
@@ -141,6 +141,7 @@ function error_return_keyword(node, context, message) {
|
|
|
141
141
|
context.state.analysis.module.filename,
|
|
142
142
|
return_keyword_node,
|
|
143
143
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
144
|
+
context.state.analysis.comments,
|
|
144
145
|
);
|
|
145
146
|
}
|
|
146
147
|
|
|
@@ -281,6 +282,7 @@ const visitors = {
|
|
|
281
282
|
context.state.analysis.module.filename,
|
|
282
283
|
node,
|
|
283
284
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
285
|
+
context.state.analysis.comments,
|
|
284
286
|
);
|
|
285
287
|
}
|
|
286
288
|
}
|
|
@@ -307,7 +309,13 @@ const visitors = {
|
|
|
307
309
|
MemberExpression(node, context) {
|
|
308
310
|
const parent = context.path.at(-1);
|
|
309
311
|
|
|
310
|
-
if (
|
|
312
|
+
if (
|
|
313
|
+
context.state.metadata?.tracking === false &&
|
|
314
|
+
parent?.type !== 'AssignmentExpression' &&
|
|
315
|
+
(node.tracked ||
|
|
316
|
+
((node.property.type === 'Identifier' || node.property.type === 'Literal') &&
|
|
317
|
+
/** @type {AST.TrackedNode} */ (node.property).tracked))
|
|
318
|
+
) {
|
|
311
319
|
context.state.metadata.tracking = true;
|
|
312
320
|
}
|
|
313
321
|
|
|
@@ -321,6 +329,7 @@ const visitors = {
|
|
|
321
329
|
context.state.analysis.module.filename,
|
|
322
330
|
node,
|
|
323
331
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
332
|
+
context.state.analysis.comments,
|
|
324
333
|
);
|
|
325
334
|
} else {
|
|
326
335
|
component.metadata.styleIdentifierPresent = true;
|
|
@@ -346,6 +355,7 @@ const visitors = {
|
|
|
346
355
|
context.state.analysis.module.filename,
|
|
347
356
|
node.property,
|
|
348
357
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
358
|
+
context.state.analysis.comments,
|
|
349
359
|
);
|
|
350
360
|
}
|
|
351
361
|
|
|
@@ -377,6 +387,7 @@ const visitors = {
|
|
|
377
387
|
context.state.analysis.module.filename,
|
|
378
388
|
node.property,
|
|
379
389
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
390
|
+
context.state.analysis.comments,
|
|
380
391
|
);
|
|
381
392
|
}
|
|
382
393
|
}
|
|
@@ -391,6 +402,7 @@ const visitors = {
|
|
|
391
402
|
context.state.analysis.module.filename,
|
|
392
403
|
node.object,
|
|
393
404
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
405
|
+
context.state.analysis.comments,
|
|
394
406
|
);
|
|
395
407
|
}
|
|
396
408
|
}
|
|
@@ -416,13 +428,10 @@ const visitors = {
|
|
|
416
428
|
context.state.analysis.module.filename,
|
|
417
429
|
node.callee,
|
|
418
430
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
431
|
+
context.state.analysis.comments,
|
|
419
432
|
);
|
|
420
433
|
}
|
|
421
434
|
|
|
422
|
-
if (context.state.metadata?.tracking === false) {
|
|
423
|
-
context.state.metadata.tracking = true;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
435
|
if (!is_inside_component(context, true)) {
|
|
427
436
|
mark_as_tracked(context.path);
|
|
428
437
|
}
|
|
@@ -431,9 +440,6 @@ const visitors = {
|
|
|
431
440
|
},
|
|
432
441
|
|
|
433
442
|
NewExpression(node, context) {
|
|
434
|
-
if (context.state.metadata?.tracking === false) {
|
|
435
|
-
context.state.metadata.tracking = true;
|
|
436
|
-
}
|
|
437
443
|
context.next();
|
|
438
444
|
},
|
|
439
445
|
|
|
@@ -447,6 +453,7 @@ const visitors = {
|
|
|
447
453
|
state.analysis.module.filename,
|
|
448
454
|
declarator.id,
|
|
449
455
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
456
|
+
context.state.analysis.comments,
|
|
450
457
|
);
|
|
451
458
|
}
|
|
452
459
|
const metadata = { tracking: false, await: false };
|
|
@@ -477,6 +484,7 @@ const visitors = {
|
|
|
477
484
|
state.analysis.module.filename,
|
|
478
485
|
path.node,
|
|
479
486
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
487
|
+
context.state.analysis.comments,
|
|
480
488
|
);
|
|
481
489
|
}
|
|
482
490
|
}
|
|
@@ -536,6 +544,7 @@ const visitors = {
|
|
|
536
544
|
context.state.analysis.module.filename,
|
|
537
545
|
props,
|
|
538
546
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
547
|
+
context.state.analysis.comments,
|
|
539
548
|
);
|
|
540
549
|
}
|
|
541
550
|
}
|
|
@@ -582,6 +591,7 @@ const visitors = {
|
|
|
582
591
|
context.state.analysis.module.filename,
|
|
583
592
|
property,
|
|
584
593
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
594
|
+
context.state.analysis.comments,
|
|
585
595
|
);
|
|
586
596
|
}
|
|
587
597
|
}
|
|
@@ -639,6 +649,7 @@ const visitors = {
|
|
|
639
649
|
context.state.analysis.module.filename,
|
|
640
650
|
switch_case,
|
|
641
651
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
652
|
+
context.state.analysis.comments,
|
|
642
653
|
);
|
|
643
654
|
}
|
|
644
655
|
}
|
|
@@ -712,6 +723,7 @@ const visitors = {
|
|
|
712
723
|
context.state.analysis.module.filename,
|
|
713
724
|
node.body,
|
|
714
725
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
726
|
+
context.state.analysis.comments,
|
|
715
727
|
);
|
|
716
728
|
}
|
|
717
729
|
},
|
|
@@ -734,6 +746,7 @@ const visitors = {
|
|
|
734
746
|
context.state.analysis.module.filename,
|
|
735
747
|
/** @type {AST.Identifier} */ (declaration.id),
|
|
736
748
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
749
|
+
context.state.analysis.comments,
|
|
737
750
|
);
|
|
738
751
|
// TODO: the client and server rendering doesn't currently support components
|
|
739
752
|
// If we're going to support this, we need to account also for anonymous object declaration
|
|
@@ -762,6 +775,7 @@ const visitors = {
|
|
|
762
775
|
context.state.analysis.module.filename,
|
|
763
776
|
decl.init,
|
|
764
777
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
778
|
+
context.state.analysis.comments,
|
|
765
779
|
);
|
|
766
780
|
continue;
|
|
767
781
|
}
|
|
@@ -773,6 +787,7 @@ const visitors = {
|
|
|
773
787
|
context.state.analysis.module.filename,
|
|
774
788
|
path.node,
|
|
775
789
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
790
|
+
context.state.analysis.comments,
|
|
776
791
|
);
|
|
777
792
|
}
|
|
778
793
|
}
|
|
@@ -783,6 +798,7 @@ const visitors = {
|
|
|
783
798
|
context.state.analysis.module.filename,
|
|
784
799
|
decl,
|
|
785
800
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
801
|
+
context.state.analysis.comments,
|
|
786
802
|
);
|
|
787
803
|
}
|
|
788
804
|
} else if (node.specifiers) {
|
|
@@ -801,6 +817,7 @@ const visitors = {
|
|
|
801
817
|
context.state.analysis.module.filename,
|
|
802
818
|
specifier,
|
|
803
819
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
820
|
+
context.state.analysis.comments,
|
|
804
821
|
);
|
|
805
822
|
}
|
|
806
823
|
} else {
|
|
@@ -809,6 +826,7 @@ const visitors = {
|
|
|
809
826
|
context.state.analysis.module.filename,
|
|
810
827
|
node,
|
|
811
828
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
829
|
+
context.state.analysis.comments,
|
|
812
830
|
);
|
|
813
831
|
}
|
|
814
832
|
|
|
@@ -863,6 +881,7 @@ const visitors = {
|
|
|
863
881
|
context.state.analysis.module.filename,
|
|
864
882
|
node.consequent,
|
|
865
883
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
884
|
+
context.state.analysis.comments,
|
|
866
885
|
);
|
|
867
886
|
}
|
|
868
887
|
|
|
@@ -879,6 +898,7 @@ const visitors = {
|
|
|
879
898
|
context.state.analysis.module.filename,
|
|
880
899
|
node.alternate,
|
|
881
900
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
901
|
+
context.state.analysis.comments,
|
|
882
902
|
);
|
|
883
903
|
}
|
|
884
904
|
|
|
@@ -966,6 +986,7 @@ const visitors = {
|
|
|
966
986
|
state.analysis.module.filename,
|
|
967
987
|
node.block,
|
|
968
988
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
989
|
+
context.state.analysis.comments,
|
|
969
990
|
);
|
|
970
991
|
}
|
|
971
992
|
|
|
@@ -982,6 +1003,7 @@ const visitors = {
|
|
|
982
1003
|
state.analysis.module.filename,
|
|
983
1004
|
node.pending,
|
|
984
1005
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1006
|
+
context.state.analysis.comments,
|
|
985
1007
|
);
|
|
986
1008
|
}
|
|
987
1009
|
}
|
|
@@ -1009,6 +1031,30 @@ const visitors = {
|
|
|
1009
1031
|
context.next();
|
|
1010
1032
|
},
|
|
1011
1033
|
|
|
1034
|
+
WhileStatement(node, context) {
|
|
1035
|
+
if (is_inside_component(context)) {
|
|
1036
|
+
error(
|
|
1037
|
+
'While loops are not supported in components. Move the while loop into a function.',
|
|
1038
|
+
context.state.analysis.module.filename,
|
|
1039
|
+
node,
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
context.next();
|
|
1044
|
+
},
|
|
1045
|
+
|
|
1046
|
+
DoWhileStatement(node, context) {
|
|
1047
|
+
if (is_inside_component(context)) {
|
|
1048
|
+
error(
|
|
1049
|
+
'Do...while loops are not supported in components. Move the do...while loop into a function.',
|
|
1050
|
+
context.state.analysis.module.filename,
|
|
1051
|
+
node,
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
context.next();
|
|
1056
|
+
},
|
|
1057
|
+
|
|
1012
1058
|
JSXElement(node, context) {
|
|
1013
1059
|
const inside_tsx_compat = context.path.some((n) => n.type === 'TsxCompat');
|
|
1014
1060
|
|
|
@@ -1167,6 +1213,7 @@ const visitors = {
|
|
|
1167
1213
|
},
|
|
1168
1214
|
},
|
|
1169
1215
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1216
|
+
context.state.analysis.comments,
|
|
1170
1217
|
);
|
|
1171
1218
|
}
|
|
1172
1219
|
if (attr.name.type === 'Identifier') {
|
|
@@ -1178,6 +1225,21 @@ const visitors = {
|
|
|
1178
1225
|
state.analysis.module.filename,
|
|
1179
1226
|
attr,
|
|
1180
1227
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1228
|
+
context.state.analysis.comments,
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
if (
|
|
1233
|
+
attr.value &&
|
|
1234
|
+
attr.value.type === 'MemberExpression' &&
|
|
1235
|
+
attr.value.object.type === 'StyleIdentifier'
|
|
1236
|
+
) {
|
|
1237
|
+
error(
|
|
1238
|
+
'`#style` cannot be used directly on DOM elements. Pass the class to a child component instead.',
|
|
1239
|
+
state.analysis.module.filename,
|
|
1240
|
+
attr.value.object,
|
|
1241
|
+
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1242
|
+
context.state.analysis.comments,
|
|
1181
1243
|
);
|
|
1182
1244
|
}
|
|
1183
1245
|
|
|
@@ -1205,6 +1267,7 @@ const visitors = {
|
|
|
1205
1267
|
state.analysis.module.filename,
|
|
1206
1268
|
node,
|
|
1207
1269
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1270
|
+
context.state.analysis.comments,
|
|
1208
1271
|
);
|
|
1209
1272
|
}
|
|
1210
1273
|
} else {
|
|
@@ -1246,6 +1309,7 @@ const visitors = {
|
|
|
1246
1309
|
state.analysis.module.filename,
|
|
1247
1310
|
item,
|
|
1248
1311
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1312
|
+
context.state.analysis.comments,
|
|
1249
1313
|
);
|
|
1250
1314
|
}
|
|
1251
1315
|
}
|
|
@@ -1261,6 +1325,7 @@ const visitors = {
|
|
|
1261
1325
|
state.analysis.module.filename,
|
|
1262
1326
|
attribute,
|
|
1263
1327
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1328
|
+
context.state.analysis.comments,
|
|
1264
1329
|
);
|
|
1265
1330
|
}
|
|
1266
1331
|
}
|
|
@@ -1286,6 +1351,7 @@ const visitors = {
|
|
|
1286
1351
|
context.state.analysis.module.filename,
|
|
1287
1352
|
node.expression,
|
|
1288
1353
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1354
|
+
context.state.analysis.comments,
|
|
1289
1355
|
);
|
|
1290
1356
|
}
|
|
1291
1357
|
|
|
@@ -1320,6 +1386,7 @@ const visitors = {
|
|
|
1320
1386
|
context.state.analysis.module.filename,
|
|
1321
1387
|
adjusted_node,
|
|
1322
1388
|
context.state.loose ? context.state.analysis.errors : undefined,
|
|
1389
|
+
context.state.analysis.comments,
|
|
1323
1390
|
);
|
|
1324
1391
|
}
|
|
1325
1392
|
}
|
|
@@ -236,18 +236,6 @@ function apply_selector(relative_selectors, rule, element, direction) {
|
|
|
236
236
|
selector: selector,
|
|
237
237
|
});
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
// Also store in top_scoped_classes if standalone selector
|
|
241
|
-
if (
|
|
242
|
-
is_standalone_class_selector(relative_selector, selector) &&
|
|
243
|
-
!top_scoped_classes.has(name)
|
|
244
|
-
) {
|
|
245
|
-
top_scoped_classes.set(name, {
|
|
246
|
-
start: selector.start,
|
|
247
|
-
end: selector.end,
|
|
248
|
-
selector: selector,
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
239
|
}
|
|
252
240
|
}
|
|
253
241
|
}
|
|
@@ -1090,6 +1078,31 @@ export function prune_css(css, element, styleClasses, topScopedClasses) {
|
|
|
1090
1078
|
node.metadata.used = true;
|
|
1091
1079
|
}
|
|
1092
1080
|
|
|
1081
|
+
// Populate top_scoped_classes for truly standalone class selectors (for #style support).
|
|
1082
|
+
// A class is standalone only when the entire effective selector chain (after resolving
|
|
1083
|
+
// nesting and stripping :global) is a single RelativeSelector with a single ClassSelector.
|
|
1084
|
+
// This prevents classes from compound selectors like `.wrapper .nested` or selectors
|
|
1085
|
+
// inside :global() from being treated as valid #style targets.
|
|
1086
|
+
if (selectors.length === 1) {
|
|
1087
|
+
const sole_selector = selectors[0];
|
|
1088
|
+
if (
|
|
1089
|
+
!sole_selector.metadata.is_global &&
|
|
1090
|
+
!sole_selector.metadata.is_global_like &&
|
|
1091
|
+
sole_selector.selectors.length === 1 &&
|
|
1092
|
+
sole_selector.selectors[0].type === 'ClassSelector'
|
|
1093
|
+
) {
|
|
1094
|
+
const class_selector = sole_selector.selectors[0];
|
|
1095
|
+
const name = class_selector.name.replace(regex_backslash_and_following_character, '$1');
|
|
1096
|
+
if (!top_scoped_classes.has(name)) {
|
|
1097
|
+
top_scoped_classes.set(name, {
|
|
1098
|
+
start: class_selector.start,
|
|
1099
|
+
end: class_selector.end,
|
|
1100
|
+
selector: class_selector,
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1093
1106
|
context.next();
|
|
1094
1107
|
},
|
|
1095
1108
|
PseudoClassSelector(node, context) {
|