ripple 0.3.72 → 0.3.76
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 +116 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +4 -10
- package/src/runtime/dynamic-client.js +33 -0
- package/src/runtime/dynamic-server.js +80 -0
- package/src/runtime/index-client.js +5 -13
- package/src/runtime/index-server.js +2 -0
- package/src/runtime/internal/client/blocks.js +6 -27
- package/src/runtime/internal/client/composite.js +11 -6
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/render.js +5 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/src/runtime/internal/server/index.js +8 -1
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +55 -61
- package/tests/client/basic/basic.components.test.tsrx +198 -220
- package/tests/client/basic/basic.errors.test.tsrx +70 -76
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.styling.test.tsrx +16 -14
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +62 -47
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +493 -439
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +65 -72
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +318 -299
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +74 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +197 -216
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +286 -292
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +390 -319
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -258
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +117 -162
- package/tests/server/basic.components.test.tsrx +164 -194
- package/tests/server/basic.test.tsrx +299 -199
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +147 -148
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +54 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +61 -69
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +29 -4
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -3,21 +3,19 @@ import { effect, flushSync, on, track } from 'ripple';
|
|
|
3
3
|
|
|
4
4
|
describe('on() event handler', () => {
|
|
5
5
|
it('should attach multiple handlers via onClick attribute (delegated)', () => {
|
|
6
|
-
function Basic() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
function Basic() @{
|
|
7
|
+
let &[count1] = track(0);
|
|
8
|
+
let &[count2] = track(0);
|
|
9
|
+
<>
|
|
10
10
|
<button
|
|
11
11
|
onClick={() => {
|
|
12
12
|
count1++;
|
|
13
13
|
count2++;
|
|
14
14
|
}}
|
|
15
|
-
>
|
|
16
|
-
{'Click me'}
|
|
17
|
-
</button>
|
|
15
|
+
>{'Click me'}</button>
|
|
18
16
|
<div class="count1">{count1}</div>
|
|
19
17
|
<div class="count2">{count2}</div>
|
|
20
|
-
|
|
18
|
+
</>
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
render(Basic);
|
|
@@ -36,18 +34,18 @@ describe('on() event handler', () => {
|
|
|
36
34
|
});
|
|
37
35
|
|
|
38
36
|
it('should attach and remove a single event handler', () => {
|
|
39
|
-
function Basic() {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
function Basic() @{
|
|
38
|
+
let &[count] = track(0);
|
|
39
|
+
const setupListener = (node: HTMLButtonElement) => {
|
|
40
|
+
const remove = on(node, 'click', () => {
|
|
41
|
+
count++;
|
|
42
|
+
});
|
|
43
|
+
return remove;
|
|
44
|
+
};
|
|
45
|
+
<>
|
|
48
46
|
<button ref={setupListener}>{'Click me'}</button>
|
|
49
47
|
<div class="count">{count}</div>
|
|
50
|
-
|
|
48
|
+
</>
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
render(Basic);
|
|
@@ -68,26 +66,26 @@ describe('on() event handler', () => {
|
|
|
68
66
|
});
|
|
69
67
|
|
|
70
68
|
it('should handle multiple different event types on same element', () => {
|
|
71
|
-
function Basic() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
remove2();
|
|
85
|
-
};
|
|
69
|
+
function Basic() @{
|
|
70
|
+
let &[clickCount] = track(0);
|
|
71
|
+
let &[mousedownCount] = track(0);
|
|
72
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
73
|
+
const remove1 = on(node, 'click', () => {
|
|
74
|
+
clickCount++;
|
|
75
|
+
});
|
|
76
|
+
const remove2 = on(node, 'mousedown', () => {
|
|
77
|
+
mousedownCount++;
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
remove1();
|
|
81
|
+
remove2();
|
|
86
82
|
};
|
|
83
|
+
};
|
|
84
|
+
<>
|
|
87
85
|
<button ref={setupListeners}>{'Test'}</button>
|
|
88
86
|
<div class="click-count">{clickCount}</div>
|
|
89
87
|
<div class="mousedown-count">{mousedownCount}</div>
|
|
90
|
-
|
|
88
|
+
</>
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
render(Basic);
|
|
@@ -118,28 +116,28 @@ describe('on() event handler', () => {
|
|
|
118
116
|
});
|
|
119
117
|
|
|
120
118
|
it('should handle multiple handlers for same event type on same element', () => {
|
|
121
|
-
function Basic() {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
remove3();
|
|
138
|
-
};
|
|
119
|
+
function Basic() @{
|
|
120
|
+
let &[callOrder] = track<number[]>([]);
|
|
121
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
122
|
+
const remove1 = on(node, 'click', () => {
|
|
123
|
+
callOrder = [...callOrder, 1];
|
|
124
|
+
});
|
|
125
|
+
const remove2 = on(node, 'click', () => {
|
|
126
|
+
callOrder = [...callOrder, 2];
|
|
127
|
+
});
|
|
128
|
+
const remove3 = on(node, 'click', () => {
|
|
129
|
+
callOrder = [...callOrder, 3];
|
|
130
|
+
});
|
|
131
|
+
return () => {
|
|
132
|
+
remove1();
|
|
133
|
+
remove2();
|
|
134
|
+
remove3();
|
|
139
135
|
};
|
|
136
|
+
};
|
|
137
|
+
<>
|
|
140
138
|
<button ref={setupListeners}>{'Click me'}</button>
|
|
141
139
|
<div class="order">{callOrder.join(',')}</div>
|
|
142
|
-
|
|
140
|
+
</>
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
render(Basic);
|
|
@@ -161,44 +159,40 @@ describe('on() event handler', () => {
|
|
|
161
159
|
});
|
|
162
160
|
|
|
163
161
|
it('should remove specific handler without affecting others', () => {
|
|
164
|
-
function Basic() {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
remove3();
|
|
184
|
-
};
|
|
162
|
+
function Basic() @{
|
|
163
|
+
let &[handler1Called] = track(0);
|
|
164
|
+
let &[handler2Called] = track(0);
|
|
165
|
+
let &[handler3Called] = track(0);
|
|
166
|
+
let removeHandler2: OnEventListenerRemover | undefined;
|
|
167
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
168
|
+
const remove1 = on(node, 'click', () => {
|
|
169
|
+
handler1Called++;
|
|
170
|
+
});
|
|
171
|
+
removeHandler2 = on(node, 'click', () => {
|
|
172
|
+
handler2Called++;
|
|
173
|
+
});
|
|
174
|
+
const remove3 = on(node, 'click', () => {
|
|
175
|
+
handler3Called++;
|
|
176
|
+
});
|
|
177
|
+
return () => {
|
|
178
|
+
remove1();
|
|
179
|
+
removeHandler2?.();
|
|
180
|
+
remove3();
|
|
185
181
|
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
</div>
|
|
201
|
-
</>;
|
|
182
|
+
};
|
|
183
|
+
<div>
|
|
184
|
+
<button class="test-btn" ref={setupListeners}>{'Click me'}</button>
|
|
185
|
+
<button
|
|
186
|
+
class="remove-btn"
|
|
187
|
+
onClick={() => {
|
|
188
|
+
removeHandler2?.();
|
|
189
|
+
removeHandler2 = undefined;
|
|
190
|
+
}}
|
|
191
|
+
>{'Remove handler 2'}</button>
|
|
192
|
+
<div class="h1">{handler1Called}</div>
|
|
193
|
+
<div class="h2">{handler2Called}</div>
|
|
194
|
+
<div class="h3">{handler3Called}</div>
|
|
195
|
+
</div>
|
|
202
196
|
}
|
|
203
197
|
|
|
204
198
|
render(Basic);
|
|
@@ -239,31 +233,33 @@ describe('on() event handler', () => {
|
|
|
239
233
|
it(
|
|
240
234
|
'should handle change event with multiple handlers (like bindChecked and bindIndeterminate)',
|
|
241
235
|
() => {
|
|
242
|
-
function Basic() {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
remove2();
|
|
259
|
-
};
|
|
236
|
+
function Basic() @{
|
|
237
|
+
let &[checked] = track(false);
|
|
238
|
+
let &[indeterminate] = track(true);
|
|
239
|
+
const setupListeners = (node: HTMLInputElement) => {
|
|
240
|
+
node.indeterminate = indeterminate;
|
|
241
|
+
node.checked = checked;
|
|
242
|
+
|
|
243
|
+
const remove1 = on(node, 'change', () => {
|
|
244
|
+
checked = node.checked;
|
|
245
|
+
});
|
|
246
|
+
const remove2 = on(node, 'change', () => {
|
|
247
|
+
indeterminate = node.indeterminate;
|
|
248
|
+
});
|
|
249
|
+
return () => {
|
|
250
|
+
remove1();
|
|
251
|
+
remove2();
|
|
260
252
|
};
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
253
|
+
};
|
|
254
|
+
<div>
|
|
255
|
+
<input type="checkbox" ref={setupListeners} />
|
|
256
|
+
<div class="checked">
|
|
257
|
+
{checked ? 'true' : 'false'}
|
|
265
258
|
</div>
|
|
266
|
-
|
|
259
|
+
<div class="indeterminate">
|
|
260
|
+
{indeterminate ? 'true' : 'false'}
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
267
263
|
}
|
|
268
264
|
|
|
269
265
|
render(Basic);
|
|
@@ -288,18 +284,18 @@ describe('on() event handler', () => {
|
|
|
288
284
|
);
|
|
289
285
|
|
|
290
286
|
it('should support non-delegated events', () => {
|
|
291
|
-
function Basic() {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
287
|
+
function Basic() @{
|
|
288
|
+
let &[focusCount] = track(0);
|
|
289
|
+
const setupListener = (node: HTMLInputElement) => {
|
|
290
|
+
const remove = on(node, 'focus', () => {
|
|
291
|
+
focusCount++;
|
|
292
|
+
});
|
|
293
|
+
return remove;
|
|
294
|
+
};
|
|
295
|
+
<>
|
|
300
296
|
<input ref={setupListener} />
|
|
301
297
|
<div class="focus-count">{focusCount}</div>
|
|
302
|
-
|
|
298
|
+
</>
|
|
303
299
|
}
|
|
304
300
|
|
|
305
301
|
render(Basic);
|
|
@@ -320,44 +316,40 @@ describe('on() event handler', () => {
|
|
|
320
316
|
});
|
|
321
317
|
|
|
322
318
|
it('should handle removal of all handlers for same event type', () => {
|
|
323
|
-
function Basic() {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
319
|
+
function Basic() @{
|
|
320
|
+
let &[count] = track(0);
|
|
321
|
+
let remove1: OnEventListenerRemover | undefined;
|
|
322
|
+
let remove2: OnEventListenerRemover | undefined;
|
|
323
|
+
let remove3: OnEventListenerRemover | undefined;
|
|
324
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
325
|
+
remove1 = on(node, 'click', () => {
|
|
326
|
+
count++;
|
|
327
|
+
});
|
|
328
|
+
remove2 = on(node, 'click', () => {
|
|
329
|
+
count += 10;
|
|
330
|
+
});
|
|
331
|
+
remove3 = on(node, 'click', () => {
|
|
332
|
+
count += 100;
|
|
333
|
+
});
|
|
334
|
+
return () => {
|
|
335
|
+
remove1?.();
|
|
336
|
+
remove2?.();
|
|
337
|
+
remove3?.();
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
<div>
|
|
341
|
+
<button class="test-btn" ref={setupListeners}>{'Click me'}</button>
|
|
342
|
+
<button
|
|
343
|
+
class="remove-all"
|
|
344
|
+
onClick={() => {
|
|
340
345
|
remove1?.();
|
|
341
346
|
remove2?.();
|
|
342
347
|
remove3?.();
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
class="remove-all"
|
|
349
|
-
onClick={() => {
|
|
350
|
-
remove1?.();
|
|
351
|
-
remove2?.();
|
|
352
|
-
remove3?.();
|
|
353
|
-
remove1 = remove2 = remove3 = undefined;
|
|
354
|
-
}}
|
|
355
|
-
>
|
|
356
|
-
{'Remove all'}
|
|
357
|
-
</button>
|
|
358
|
-
<div class="count">{count}</div>
|
|
359
|
-
</div>
|
|
360
|
-
</>;
|
|
348
|
+
remove1 = remove2 = remove3 = undefined;
|
|
349
|
+
}}
|
|
350
|
+
>{'Remove all'}</button>
|
|
351
|
+
<div class="count">{count}</div>
|
|
352
|
+
</div>
|
|
361
353
|
}
|
|
362
354
|
|
|
363
355
|
render(Basic);
|
|
@@ -385,27 +377,27 @@ describe('on() event handler', () => {
|
|
|
385
377
|
});
|
|
386
378
|
|
|
387
379
|
it('should not add duplicate handlers when same handler is attached multiple times', () => {
|
|
388
|
-
function Basic() {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
remove3?.();
|
|
404
|
-
};
|
|
380
|
+
function Basic() @{
|
|
381
|
+
let &[count] = track(0);
|
|
382
|
+
const sharedHandler = () => {
|
|
383
|
+
count++;
|
|
384
|
+
};
|
|
385
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
386
|
+
// Attach the same handler multiple times
|
|
387
|
+
const remove1 = on(node, 'click', sharedHandler);
|
|
388
|
+
const remove2 = on(node, 'click', sharedHandler);
|
|
389
|
+
const remove3 = on(node, 'click', sharedHandler);
|
|
390
|
+
|
|
391
|
+
return () => {
|
|
392
|
+
remove1?.();
|
|
393
|
+
remove2?.();
|
|
394
|
+
remove3?.();
|
|
405
395
|
};
|
|
396
|
+
};
|
|
397
|
+
<>
|
|
406
398
|
<button ref={setupListeners}>{'Click me'}</button>
|
|
407
399
|
<div class="count">{count}</div>
|
|
408
|
-
|
|
400
|
+
</>
|
|
409
401
|
}
|
|
410
402
|
|
|
411
403
|
render(Basic);
|
|
@@ -427,27 +419,27 @@ describe('on() event handler', () => {
|
|
|
427
419
|
});
|
|
428
420
|
|
|
429
421
|
it('should allow duplicate handlers when delegated is false (no deduplication)', () => {
|
|
430
|
-
function Basic() {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
remove3?.();
|
|
446
|
-
};
|
|
422
|
+
function Basic() @{
|
|
423
|
+
let &[count] = track(0);
|
|
424
|
+
const sharedHandler = () => {
|
|
425
|
+
count++;
|
|
426
|
+
};
|
|
427
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
428
|
+
// Attach the same handler multiple times with delegated: false
|
|
429
|
+
const remove1 = on(node, 'click', sharedHandler, { delegated: false });
|
|
430
|
+
const remove2 = on(node, 'click', sharedHandler, { delegated: false });
|
|
431
|
+
const remove3 = on(node, 'click', sharedHandler, { delegated: false });
|
|
432
|
+
|
|
433
|
+
return () => {
|
|
434
|
+
remove1?.();
|
|
435
|
+
remove2?.();
|
|
436
|
+
remove3?.();
|
|
447
437
|
};
|
|
438
|
+
};
|
|
439
|
+
<>
|
|
448
440
|
<button ref={setupListeners}>{'Click me'}</button>
|
|
449
441
|
<div class="count">{count}</div>
|
|
450
|
-
|
|
442
|
+
</>
|
|
451
443
|
}
|
|
452
444
|
|
|
453
445
|
render(Basic);
|
|
@@ -470,26 +462,26 @@ describe('on() event handler', () => {
|
|
|
470
462
|
});
|
|
471
463
|
|
|
472
464
|
it('should fire capture event on parent before bubbling event on child', () => {
|
|
473
|
-
function Basic() {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
465
|
+
function Basic() @{
|
|
466
|
+
let &[callOrder] = track<string[]>([]);
|
|
467
|
+
const parentCaptureHandler = () => {
|
|
468
|
+
callOrder = [...callOrder, 'parent-capture'];
|
|
469
|
+
};
|
|
470
|
+
const childBubbleHandler = () => {
|
|
471
|
+
callOrder = [...callOrder, 'child-bubble'];
|
|
472
|
+
};
|
|
473
|
+
const setupParent = (node: HTMLDivElement) => {
|
|
474
|
+
return on(node, 'clickCapture', parentCaptureHandler);
|
|
475
|
+
};
|
|
476
|
+
const setupChild = (node: HTMLButtonElement) => {
|
|
477
|
+
return on(node, 'click', childBubbleHandler);
|
|
478
|
+
};
|
|
479
|
+
<>
|
|
488
480
|
<div ref={setupParent} class="parent">
|
|
489
481
|
<button ref={setupChild} class="child">{'Click me'}</button>
|
|
490
482
|
</div>
|
|
491
483
|
<div class="order">{callOrder.join(',')}</div>
|
|
492
|
-
|
|
484
|
+
</>
|
|
493
485
|
}
|
|
494
486
|
|
|
495
487
|
render(Basic);
|
|
@@ -512,28 +504,28 @@ describe('on() event handler', () => {
|
|
|
512
504
|
});
|
|
513
505
|
|
|
514
506
|
it('should fire handler only once when once option is true', () => {
|
|
515
|
-
function Basic() {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
}, { once: true });
|
|
523
|
-
|
|
524
|
-
const permanentHandler = on(node, 'click', () => {
|
|
525
|
-
permanentCount++;
|
|
526
|
-
});
|
|
507
|
+
function Basic() @{
|
|
508
|
+
let &[count] = track(0);
|
|
509
|
+
let &[permanentCount] = track(0);
|
|
510
|
+
const setupListeners = (node: HTMLButtonElement) => {
|
|
511
|
+
const onceHandler = on(node, 'click', () => {
|
|
512
|
+
count++;
|
|
513
|
+
}, { once: true });
|
|
527
514
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
515
|
+
const permanentHandler = on(node, 'click', () => {
|
|
516
|
+
permanentCount++;
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
return () => {
|
|
520
|
+
onceHandler?.();
|
|
521
|
+
permanentHandler?.();
|
|
532
522
|
};
|
|
523
|
+
};
|
|
524
|
+
<>
|
|
533
525
|
<button ref={setupListeners}>{'Click me'}</button>
|
|
534
526
|
<div class="once-count">{count}</div>
|
|
535
527
|
<div class="permanent-count">{permanentCount}</div>
|
|
536
|
-
|
|
528
|
+
</>
|
|
537
529
|
}
|
|
538
530
|
|
|
539
531
|
render(Basic);
|
|
@@ -566,20 +558,18 @@ describe('on() event handler', () => {
|
|
|
566
558
|
});
|
|
567
559
|
|
|
568
560
|
it('should handle click events on window', () => {
|
|
569
|
-
function Basic() {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
windowClickCount++;
|
|
575
|
-
});
|
|
576
|
-
return removeWindowListener;
|
|
561
|
+
function Basic() @{
|
|
562
|
+
let &[windowClickCount] = track(0);
|
|
563
|
+
effect(() => {
|
|
564
|
+
const removeWindowListener = on(window, 'click', () => {
|
|
565
|
+
windowClickCount++;
|
|
577
566
|
});
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
</
|
|
582
|
-
|
|
567
|
+
return removeWindowListener;
|
|
568
|
+
});
|
|
569
|
+
<div>
|
|
570
|
+
<button class="test-btn">{'Click me'}</button>
|
|
571
|
+
<div class="window-count">{windowClickCount}</div>
|
|
572
|
+
</div>
|
|
583
573
|
}
|
|
584
574
|
|
|
585
575
|
render(Basic);
|
|
@@ -602,20 +592,18 @@ describe('on() event handler', () => {
|
|
|
602
592
|
});
|
|
603
593
|
|
|
604
594
|
it('should handle click events on document', () => {
|
|
605
|
-
function Basic() {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
documentClickCount++;
|
|
611
|
-
});
|
|
612
|
-
return removeDocumentListener;
|
|
595
|
+
function Basic() @{
|
|
596
|
+
let &[documentClickCount] = track(0);
|
|
597
|
+
effect(() => {
|
|
598
|
+
const removeDocumentListener = on(document, 'click', () => {
|
|
599
|
+
documentClickCount++;
|
|
613
600
|
});
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
</
|
|
618
|
-
|
|
601
|
+
return removeDocumentListener;
|
|
602
|
+
});
|
|
603
|
+
<div>
|
|
604
|
+
<button class="test-btn">{'Click me'}</button>
|
|
605
|
+
<div class="document-count">{documentClickCount}</div>
|
|
606
|
+
</div>
|
|
619
607
|
}
|
|
620
608
|
|
|
621
609
|
render(Basic);
|
|
@@ -638,20 +626,18 @@ describe('on() event handler', () => {
|
|
|
638
626
|
});
|
|
639
627
|
|
|
640
628
|
it('should handle click events on body', () => {
|
|
641
|
-
function Basic() {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
bodyClickCount++;
|
|
647
|
-
});
|
|
648
|
-
return removeBodyListener;
|
|
629
|
+
function Basic() @{
|
|
630
|
+
let &[bodyClickCount] = track(0);
|
|
631
|
+
effect(() => {
|
|
632
|
+
const removeBodyListener = on(document.body, 'click', () => {
|
|
633
|
+
bodyClickCount++;
|
|
649
634
|
});
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
</
|
|
654
|
-
|
|
635
|
+
return removeBodyListener;
|
|
636
|
+
});
|
|
637
|
+
<div>
|
|
638
|
+
<button class="test-btn">{'Click me'}</button>
|
|
639
|
+
<div class="body-count">{bodyClickCount}</div>
|
|
640
|
+
</div>
|
|
655
641
|
}
|
|
656
642
|
|
|
657
643
|
render(Basic);
|