ripple 0.3.67 → 0.3.69
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 +57 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -2
- package/src/runtime/element.js +1 -1
- package/src/runtime/index-client.js +11 -11
- package/src/runtime/index-server.js +7 -4
- package/src/runtime/internal/client/bindings.js +1 -1
- package/src/runtime/internal/client/blocks.js +13 -4
- package/src/runtime/internal/client/component.js +55 -0
- package/src/runtime/internal/client/composite.js +4 -2
- package/src/runtime/internal/client/expression.js +65 -7
- package/src/runtime/internal/client/hmr.js +54 -43
- package/src/runtime/internal/client/index.js +5 -1
- package/src/runtime/internal/client/portal.js +70 -69
- package/src/runtime/internal/client/render.js +3 -0
- package/src/runtime/internal/server/index.js +92 -8
- package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
- package/tests/client/array/array.copy-within.test.tsrx +33 -31
- package/tests/client/array/array.derived.test.tsrx +186 -169
- package/tests/client/array/array.iteration.test.tsrx +40 -37
- package/tests/client/array/array.mutations.test.tsrx +113 -101
- package/tests/client/array/array.static.test.tsrx +119 -101
- package/tests/client/array/array.to-methods.test.tsrx +24 -21
- package/tests/client/async-suspend.test.tsrx +247 -246
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
- package/tests/client/basic/basic.attributes.test.tsrx +428 -423
- package/tests/client/basic/basic.collections.test.tsrx +109 -102
- package/tests/client/basic/basic.components.test.tsrx +323 -205
- package/tests/client/basic/basic.errors.test.tsrx +91 -91
- package/tests/client/basic/basic.events.test.tsrx +114 -115
- package/tests/client/basic/basic.get-set.test.tsrx +97 -87
- package/tests/client/basic/basic.hmr.test.tsrx +19 -16
- package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
- package/tests/client/basic/basic.rendering.test.tsrx +272 -182
- package/tests/client/basic/basic.styling.test.tsrx +23 -22
- package/tests/client/basic/basic.utilities.test.tsrx +10 -8
- package/tests/client/boundaries.test.tsrx +26 -26
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
- package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
- package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
- package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
- package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
- package/tests/client/composite/composite.generics.test.tsrx +168 -192
- package/tests/client/composite/composite.props.test.tsrx +97 -81
- package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
- package/tests/client/composite/composite.render.test.tsrx +122 -105
- package/tests/client/computed-properties.test.tsrx +28 -28
- package/tests/client/context.test.tsrx +21 -21
- package/tests/client/css/global-additional-cases.test.tsrx +58 -58
- package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
- package/tests/client/css/global-at-rules.test.tsrx +10 -10
- package/tests/client/css/global-basic.test.tsrx +14 -14
- package/tests/client/css/global-classes-ids.test.tsrx +14 -14
- package/tests/client/css/global-combinators.test.tsrx +10 -10
- package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
- package/tests/client/css/global-edge-cases.test.tsrx +18 -18
- package/tests/client/css/global-keyframes.test.tsrx +12 -12
- package/tests/client/css/global-nested.test.tsrx +10 -10
- package/tests/client/css/global-pseudo.test.tsrx +12 -12
- package/tests/client/css/global-scoping.test.tsrx +20 -20
- package/tests/client/css/style-identifier.test.tsrx +143 -291
- package/tests/client/date.test.tsrx +146 -133
- package/tests/client/dynamic-elements.test.tsrx +398 -365
- package/tests/client/events.test.tsrx +292 -290
- package/tests/client/for.test.tsrx +156 -153
- package/tests/client/head.test.tsrx +105 -96
- package/tests/client/html.test.tsrx +122 -26
- package/tests/client/input-value.test.tsrx +1361 -1314
- package/tests/client/lazy-array.test.tsrx +16 -13
- package/tests/client/lazy-destructuring.test.tsrx +257 -213
- package/tests/client/map.test.tsrx +65 -60
- package/tests/client/media-query.test.tsrx +22 -20
- package/tests/client/object.test.tsrx +87 -81
- package/tests/client/portal.test.tsrx +57 -51
- package/tests/client/ref.test.tsrx +233 -202
- package/tests/client/return.test.tsrx +71 -2560
- package/tests/client/set.test.tsrx +54 -45
- package/tests/client/svg.test.tsrx +216 -186
- package/tests/client/switch.test.tsrx +194 -193
- package/tests/client/track-async-hydration.test.tsrx +18 -14
- package/tests/client/tracked-index-access.test.tsrx +28 -18
- package/tests/client/try.test.tsrx +675 -548
- package/tests/client/tsx.test.tsrx +373 -311
- package/tests/client/typescript-generics.test.tsrx +145 -145
- package/tests/client/url/url.derived.test.tsrx +33 -28
- package/tests/client/url/url.parsing.test.tsrx +61 -51
- package/tests/client/url/url.partial-removal.test.tsrx +56 -48
- package/tests/client/url/url.reactivity.test.tsrx +142 -125
- package/tests/client/url/url.serialization.test.tsrx +13 -11
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
- package/tests/hydration/basic.test.js +3 -3
- package/tests/hydration/compiled/client/basic.js +586 -651
- package/tests/hydration/compiled/client/composite.js +79 -104
- package/tests/hydration/compiled/client/events.js +140 -148
- package/tests/hydration/compiled/client/for.js +1005 -1018
- package/tests/hydration/compiled/client/head.js +124 -134
- package/tests/hydration/compiled/client/hmr.js +41 -48
- package/tests/hydration/compiled/client/html-in-template.js +38 -41
- package/tests/hydration/compiled/client/html.js +970 -1314
- package/tests/hydration/compiled/client/if-children.js +234 -249
- package/tests/hydration/compiled/client/if.js +182 -189
- package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
- package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
- package/tests/hydration/compiled/client/portal.js +65 -85
- package/tests/hydration/compiled/client/reactivity.js +84 -90
- package/tests/hydration/compiled/client/return.js +38 -1939
- package/tests/hydration/compiled/client/switch.js +218 -224
- package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
- package/tests/hydration/compiled/client/try.js +123 -132
- package/tests/hydration/compiled/server/basic.js +773 -831
- package/tests/hydration/compiled/server/composite.js +166 -191
- package/tests/hydration/compiled/server/events.js +170 -184
- package/tests/hydration/compiled/server/for.js +851 -909
- package/tests/hydration/compiled/server/head.js +206 -216
- package/tests/hydration/compiled/server/hmr.js +64 -72
- package/tests/hydration/compiled/server/html-in-template.js +42 -76
- package/tests/hydration/compiled/server/html.js +1362 -1667
- package/tests/hydration/compiled/server/if-children.js +419 -445
- package/tests/hydration/compiled/server/if.js +194 -208
- package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
- package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
- package/tests/hydration/compiled/server/portal.js +152 -160
- package/tests/hydration/compiled/server/reactivity.js +94 -106
- package/tests/hydration/compiled/server/return.js +28 -2172
- package/tests/hydration/compiled/server/switch.js +274 -286
- package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
- package/tests/hydration/compiled/server/try.js +167 -185
- package/tests/hydration/components/basic.tsrx +320 -272
- package/tests/hydration/components/composite.tsrx +44 -32
- package/tests/hydration/components/events.tsrx +101 -91
- package/tests/hydration/components/for.tsrx +510 -452
- package/tests/hydration/components/head.tsrx +87 -80
- package/tests/hydration/components/hmr.tsrx +22 -17
- package/tests/hydration/components/html-in-template.tsrx +22 -17
- package/tests/hydration/components/html.tsrx +525 -443
- package/tests/hydration/components/if-children.tsrx +158 -148
- package/tests/hydration/components/if.tsrx +109 -95
- package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
- package/tests/hydration/components/nested-control-flow.tsrx +215 -203
- package/tests/hydration/components/portal.tsrx +41 -34
- package/tests/hydration/components/reactivity.tsrx +37 -27
- package/tests/hydration/components/return.tsrx +12 -556
- package/tests/hydration/components/switch.tsrx +120 -114
- package/tests/hydration/components/track-async-serialization.tsrx +107 -91
- package/tests/hydration/components/try.tsrx +55 -40
- package/tests/hydration/html.test.js +4 -4
- package/tests/hydration/return.test.js +13 -532
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +264 -195
- package/tests/server/basic.components.test.tsrx +296 -169
- package/tests/server/basic.test.tsrx +300 -198
- package/tests/server/compiler.test.tsrx +62 -60
- package/tests/server/composite.props.test.tsrx +77 -63
- package/tests/server/composite.test.tsrx +168 -192
- package/tests/server/context.test.tsrx +18 -12
- package/tests/server/dynamic-elements.test.tsrx +197 -180
- package/tests/server/for.test.tsrx +85 -78
- package/tests/server/head.test.tsrx +50 -43
- package/tests/server/html-nesting-validation.test.tsrx +8 -8
- package/tests/server/if.test.tsrx +57 -51
- package/tests/server/lazy-destructuring.test.tsrx +366 -294
- package/tests/server/return.test.tsrx +76 -1355
- package/tests/server/streaming-ssr.test.tsrx +4 -75
- package/tests/server/style-identifier.test.tsrx +169 -148
- package/tests/server/switch.test.tsrx +91 -85
- package/tests/server/track-async-serialization.test.tsrx +105 -85
- package/tests/server/try.test.tsrx +374 -280
- package/tests/utils/compiler-compat-config.test.js +2 -2
- package/tests/utils/runtime-imports.test.js +10 -0
- package/types/index.d.ts +8 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
|
@@ -3,12 +3,13 @@ import { compile } from '@tsrx/ripple';
|
|
|
3
3
|
|
|
4
4
|
describe('for statements', () => {
|
|
5
5
|
it('renders a simple static array', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
function App() {
|
|
7
|
+
return <>
|
|
8
|
+
const items = ['Item 1', 'Item 2', 'Item 3'];
|
|
9
|
+
for (const item of items) {
|
|
10
|
+
<div class={item}>{item}</div>
|
|
11
|
+
}
|
|
12
|
+
</>;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
render(App);
|
|
@@ -17,13 +18,14 @@ describe('for statements', () => {
|
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
it('allows continue to skip an iteration', () => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
function App() {
|
|
22
|
+
return <>
|
|
23
|
+
const items = ['Item 1', '', 'Item 3'];
|
|
24
|
+
for (const item of items) {
|
|
25
|
+
if (!item) continue;
|
|
26
|
+
<div class="item">{item}</div>
|
|
27
|
+
}
|
|
28
|
+
</>;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
render(App);
|
|
@@ -37,16 +39,17 @@ describe('for statements', () => {
|
|
|
37
39
|
it('allows continue after setup statements to skip an iteration', () => {
|
|
38
40
|
const skipped = [];
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
function App() {
|
|
43
|
+
return <>
|
|
44
|
+
const items = ['Item 1', '', 'Item 3'];
|
|
45
|
+
for (const item of items) {
|
|
46
|
+
if (!item) {
|
|
47
|
+
skipped.push('skip');
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
<div class="item">{item}</div>
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
}
|
|
52
|
+
</>;
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
render(App);
|
|
@@ -60,7 +63,7 @@ describe('for statements', () => {
|
|
|
60
63
|
|
|
61
64
|
it('does not emit JavaScript continue in for...of skip callbacks', () => {
|
|
62
65
|
const { code } = compile(
|
|
63
|
-
`
|
|
66
|
+
`function App() { return <>
|
|
64
67
|
const items = ['Item 1', '', 'Item 3'];
|
|
65
68
|
const skipped = [];
|
|
66
69
|
|
|
@@ -71,7 +74,7 @@ describe('for statements', () => {
|
|
|
71
74
|
}
|
|
72
75
|
<div class="item">{item}</div>
|
|
73
76
|
}
|
|
74
|
-
}`,
|
|
77
|
+
</>; }`,
|
|
75
78
|
'App.tsrx',
|
|
76
79
|
{ mode: 'client' },
|
|
77
80
|
);
|
|
@@ -82,14 +85,14 @@ describe('for statements', () => {
|
|
|
82
85
|
});
|
|
83
86
|
|
|
84
87
|
it('renders a simple dynamic array', () => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
function App() {
|
|
89
|
+
return <>
|
|
90
|
+
const items = new RippleArray('Item 1', 'Item 2', 'Item 3');
|
|
91
|
+
for (const item of items) {
|
|
92
|
+
<div class={item}>{item}</div>
|
|
93
|
+
}
|
|
94
|
+
<button onClick={() => items.push(`Item ${items.length + 1}`)}>{'Add Item'}</button>
|
|
95
|
+
</>;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
render(App);
|
|
@@ -104,20 +107,20 @@ describe('for statements', () => {
|
|
|
104
107
|
});
|
|
105
108
|
|
|
106
109
|
it('correctly handles intermediate statements in for block', () => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
110
|
+
function App() {
|
|
111
|
+
return <>
|
|
112
|
+
const items = new RippleArray(1, 2, 3);
|
|
113
|
+
<div>
|
|
114
|
+
for (const item of items) {
|
|
115
|
+
<div>
|
|
116
|
+
<div>{item}</div>
|
|
117
|
+
const some_text = item;
|
|
118
|
+
<div>{some_text}</div>
|
|
119
|
+
</div>
|
|
120
|
+
}
|
|
121
|
+
</div>
|
|
122
|
+
<button onClick={() => items.push(items.length + 1)}>{'Add Item'}</button>
|
|
123
|
+
</>;
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
render(App);
|
|
@@ -133,19 +136,19 @@ describe('for statements', () => {
|
|
|
133
136
|
});
|
|
134
137
|
|
|
135
138
|
it('correctly handles the index in a for...of loop', () => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
function App() {
|
|
140
|
+
return <>
|
|
141
|
+
const items = new RippleArray('a', 'b', 'c');
|
|
142
|
+
<div>
|
|
143
|
+
for (let item of items; index i) {
|
|
144
|
+
<div>{i + ' : ' + item}</div>
|
|
145
|
+
}
|
|
146
|
+
</div>
|
|
147
|
+
<button onClick={() => items.push(String.fromCharCode(97 + items.length))}>
|
|
148
|
+
{'Add Item'}
|
|
149
|
+
</button>
|
|
150
|
+
<button onClick={() => items.reverse()}>{'Reverse'}</button>
|
|
151
|
+
</>;
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
render(App);
|
|
@@ -166,24 +169,24 @@ describe('for statements', () => {
|
|
|
166
169
|
});
|
|
167
170
|
|
|
168
171
|
it('correctly handles keyed for...of loops', () => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
172
|
+
function App() {
|
|
173
|
+
return <>
|
|
174
|
+
let &[items] = track([
|
|
175
|
+
{ id: 1, text: 'Item 1' },
|
|
176
|
+
{ id: 2, text: 'Item 2' },
|
|
177
|
+
{ id: 3, text: 'Item 3' },
|
|
178
|
+
]);
|
|
179
|
+
for (let item of items; index i; key item.id) {
|
|
180
|
+
<div>{i + ':' + item.text}</div>
|
|
181
|
+
}
|
|
182
|
+
<button
|
|
183
|
+
onClick={() => {
|
|
184
|
+
items = items.toReversed();
|
|
185
|
+
}}
|
|
186
|
+
>
|
|
187
|
+
{'Reverse'}
|
|
188
|
+
</button>
|
|
189
|
+
</>;
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
render(App);
|
|
@@ -199,24 +202,24 @@ describe('for statements', () => {
|
|
|
199
202
|
});
|
|
200
203
|
|
|
201
204
|
it('keyed for over derived updates sibling text nodes', () => {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
205
|
+
function App() {
|
|
206
|
+
return <>
|
|
207
|
+
let &[count] = track(0);
|
|
208
|
+
let &[items] = track(
|
|
209
|
+
() => Array.from({ length: count }).map((_, id) => ({ id, label: `Item ${id}` })),
|
|
210
|
+
);
|
|
211
|
+
<button
|
|
212
|
+
onClick={() => {
|
|
213
|
+
count++;
|
|
214
|
+
}}
|
|
215
|
+
>
|
|
216
|
+
{'Add'}
|
|
217
|
+
</button>
|
|
218
|
+
for (const item of items; key item.id) {
|
|
219
|
+
<div class="item">{item.label}</div>
|
|
220
|
+
}
|
|
221
|
+
<p class="count">{count}</p>
|
|
222
|
+
</>;
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
render(App);
|
|
@@ -240,22 +243,22 @@ describe('for statements', () => {
|
|
|
240
243
|
});
|
|
241
244
|
|
|
242
245
|
it('keyed for with 32+ items: full reversal updates values via Map path', () => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
246
|
+
function App() {
|
|
247
|
+
return <>
|
|
248
|
+
let &[items] = track(Array.from({ length: 40 }, (_, i) => ({ id: i, text: `Item ${i}` })));
|
|
249
|
+
<div>
|
|
250
|
+
for (let item of items; index idx; key item.id) {
|
|
251
|
+
<span class="item">{idx + ':' + item.text}</span>
|
|
252
|
+
}
|
|
253
|
+
</div>
|
|
254
|
+
<button
|
|
255
|
+
onClick={() => {
|
|
256
|
+
items = items.toReversed();
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
{'Reverse'}
|
|
260
|
+
</button>
|
|
261
|
+
</>;
|
|
259
262
|
}
|
|
260
263
|
|
|
261
264
|
render(App);
|
|
@@ -273,32 +276,32 @@ describe('for statements', () => {
|
|
|
273
276
|
});
|
|
274
277
|
|
|
275
278
|
it('handles updating with new objects with same key', () => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
279
|
+
function App() {
|
|
280
|
+
return <>
|
|
281
|
+
let &[items] = track([
|
|
282
|
+
{ id: 1, text: 'Item 1' },
|
|
283
|
+
{ id: 2, text: 'Item 2' },
|
|
284
|
+
{ id: 3, text: 'Item 3' },
|
|
285
|
+
]);
|
|
286
|
+
for (let item of items; index i; key item.id) {
|
|
287
|
+
<div>{i + ':' + item.text}</div>
|
|
288
|
+
}
|
|
289
|
+
<button
|
|
290
|
+
onClick={() => {
|
|
291
|
+
items[0].id = 3;
|
|
292
|
+
items[1].id = 2;
|
|
293
|
+
items[2].id = 1;
|
|
294
|
+
|
|
295
|
+
items = [
|
|
296
|
+
{ ...items[0], text: 'Item 1!' },
|
|
297
|
+
{ ...items[1], text: 'Item 2!' },
|
|
298
|
+
{ ...items[2], text: 'Item 3!' },
|
|
299
|
+
];
|
|
300
|
+
}}
|
|
301
|
+
>
|
|
302
|
+
{'Reverse'}
|
|
303
|
+
</button>
|
|
304
|
+
</>;
|
|
302
305
|
}
|
|
303
306
|
|
|
304
307
|
render(App);
|
|
@@ -314,22 +317,22 @@ describe('for statements', () => {
|
|
|
314
317
|
it('ref-based for with 32+ items: remove from start with shared refs via Map path', () => {
|
|
315
318
|
const objects = Array.from({ length: 50 }, (_, i) => ({ id: i, text: `Obj ${i}` }));
|
|
316
319
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
320
|
+
function App() {
|
|
321
|
+
return <>
|
|
322
|
+
let &[items] = track(objects.slice());
|
|
323
|
+
<div>
|
|
324
|
+
for (const item of items) {
|
|
325
|
+
<span class="item">{item.text}</span>
|
|
326
|
+
}
|
|
327
|
+
</div>
|
|
328
|
+
<button
|
|
329
|
+
onClick={() => {
|
|
330
|
+
items = objects.slice(15).reverse();
|
|
331
|
+
}}
|
|
332
|
+
>
|
|
333
|
+
{'Trim and reverse'}
|
|
334
|
+
</button>
|
|
335
|
+
</>;
|
|
333
336
|
}
|
|
334
337
|
|
|
335
338
|
render(App);
|
|
@@ -14,11 +14,13 @@ describe('head elements', () => {
|
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
it('renders static title element', () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
function App() {
|
|
18
|
+
return <>
|
|
19
|
+
<head>
|
|
20
|
+
<title>{'Static Test Title'}</title>
|
|
21
|
+
</head>
|
|
22
|
+
<div>{'Content'}</div>
|
|
23
|
+
</>;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
render(App);
|
|
@@ -28,22 +30,23 @@ describe('head elements', () => {
|
|
|
28
30
|
});
|
|
29
31
|
|
|
30
32
|
it('renders reactive title element', () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
function App() {
|
|
34
|
+
return <>
|
|
35
|
+
let &[title] = track('Initial Title');
|
|
36
|
+
<head>
|
|
37
|
+
<title>{title}</title>
|
|
38
|
+
</head>
|
|
39
|
+
<div>
|
|
40
|
+
<button
|
|
41
|
+
onClick={() => {
|
|
42
|
+
title = 'Updated Title';
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{'Update Title'}
|
|
46
|
+
</button>
|
|
47
|
+
<span>{title}</span>
|
|
48
|
+
</div>
|
|
49
|
+
</>;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
render(App);
|
|
@@ -60,21 +63,22 @@ describe('head elements', () => {
|
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
it('renders title with template literal', () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
function App() {
|
|
67
|
+
return <>
|
|
68
|
+
let &[name] = track('World');
|
|
69
|
+
<head>
|
|
70
|
+
<title>{`Hello ${name}!`}</title>
|
|
71
|
+
</head>
|
|
72
|
+
<div>
|
|
73
|
+
<button
|
|
74
|
+
onClick={() => {
|
|
75
|
+
name = 'Ripple';
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
{'Change Name'}
|
|
79
|
+
</button>
|
|
80
|
+
</div>
|
|
81
|
+
</>;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
render(App);
|
|
@@ -89,23 +93,24 @@ describe('head elements', () => {
|
|
|
89
93
|
});
|
|
90
94
|
|
|
91
95
|
it('renders title with computed value', () => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
96
|
+
function App() {
|
|
97
|
+
return <>
|
|
98
|
+
let &[count] = track(0);
|
|
99
|
+
let prefix = 'Count: ';
|
|
100
|
+
<head>
|
|
101
|
+
<title>{prefix + count}</title>
|
|
102
|
+
</head>
|
|
103
|
+
<div>
|
|
104
|
+
<button
|
|
105
|
+
onClick={() => {
|
|
106
|
+
count++;
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
{'Increment'}
|
|
110
|
+
</button>
|
|
111
|
+
<span>{count}</span>
|
|
112
|
+
</div>
|
|
113
|
+
</>;
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
render(App);
|
|
@@ -121,21 +126,22 @@ describe('head elements', () => {
|
|
|
121
126
|
});
|
|
122
127
|
|
|
123
128
|
it('handles multiple title updates', () => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
129
|
+
function App() {
|
|
130
|
+
return <>
|
|
131
|
+
let &[step] = track(1);
|
|
132
|
+
<head>
|
|
133
|
+
<title>{`Step ${step} of 3`}</title>
|
|
134
|
+
</head>
|
|
135
|
+
<div>
|
|
136
|
+
<button
|
|
137
|
+
onClick={() => {
|
|
138
|
+
step = step % 3 + 1;
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
{'Next Step'}
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
</>;
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
render(App);
|
|
@@ -158,11 +164,13 @@ describe('head elements', () => {
|
|
|
158
164
|
});
|
|
159
165
|
|
|
160
166
|
it('renders empty title', () => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
167
|
+
function App() {
|
|
168
|
+
return <>
|
|
169
|
+
<head>
|
|
170
|
+
<title>{''}</title>
|
|
171
|
+
</head>
|
|
172
|
+
<div>{'Empty title test'}</div>
|
|
173
|
+
</>;
|
|
166
174
|
}
|
|
167
175
|
|
|
168
176
|
render(App);
|
|
@@ -171,29 +179,30 @@ describe('head elements', () => {
|
|
|
171
179
|
});
|
|
172
180
|
|
|
173
181
|
it('renders title with conditional content', () => {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
182
|
+
function App() {
|
|
183
|
+
return <>
|
|
184
|
+
let &[showPrefix] = track(true);
|
|
185
|
+
let &[title] = track('Main Page');
|
|
186
|
+
<head>
|
|
187
|
+
<title>{showPrefix ? 'App - ' + title : title}</title>
|
|
188
|
+
</head>
|
|
189
|
+
<div>
|
|
190
|
+
<button
|
|
191
|
+
onClick={() => {
|
|
192
|
+
showPrefix = !showPrefix;
|
|
193
|
+
}}
|
|
194
|
+
>
|
|
195
|
+
{'Toggle Prefix'}
|
|
196
|
+
</button>
|
|
197
|
+
<button
|
|
198
|
+
onClick={() => {
|
|
199
|
+
title = title === 'Main Page' ? 'Settings' : 'Main Page';
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
{'Change Page'}
|
|
203
|
+
</button>
|
|
204
|
+
</div>
|
|
205
|
+
</>;
|
|
197
206
|
}
|
|
198
207
|
|
|
199
208
|
render(App);
|