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