ripple 0.2.86 → 0.2.87

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.
@@ -1,11 +1,11 @@
1
1
  import { is_passive_event } from '../../../utils/events.js';
2
2
  import {
3
- active_block,
4
- active_reaction,
5
- set_active_block,
6
- set_active_reaction,
7
- set_tracking,
8
- tracking,
3
+ active_block,
4
+ active_reaction,
5
+ set_active_block,
6
+ set_active_reaction,
7
+ set_tracking,
8
+ tracking,
9
9
  } from './runtime.js';
10
10
  import { array_from, define_property, is_array } from './utils.js';
11
11
 
@@ -35,136 +35,136 @@ export function on(element, type, handler, options = {}) {
35
35
  * @returns {void}
36
36
  */
37
37
  export function handle_event_propagation(event) {
38
- var handler_element = this;
39
- var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
40
- var event_name = event.type;
41
- var path = event.composedPath?.() || [];
42
- var current_target = /** @type {null | Element} */ (path[0] || event.target);
43
-
44
- // composedPath contains list of nodes the event has propagated through.
45
- // We check __root to skip all nodes below it in case this is a
46
- // parent of the __root node, which indicates that there's nested
47
- // mounted apps. In this case we don't want to trigger events multiple times.
48
- var path_idx = 0;
49
-
50
- // @ts-expect-error is added below
51
- var handled_at = event.__root;
52
-
53
- if (handled_at) {
54
- var at_idx = path.indexOf(handled_at);
55
- if (
56
- at_idx !== -1 &&
57
- (handler_element === document || handler_element === /** @type {any} */ (window))
58
- ) {
59
- // This is the fallback document listener or a window listener, but the event was already handled
60
- // -> ignore, but set handle_at to document/window so that we're resetting the event
61
- // chain in case someone manually dispatches the same event object again.
62
- // @ts-expect-error
63
- event.__root = handler_element;
64
- return;
65
- }
66
-
67
- // We're deliberately not skipping if the index is higher, because
68
- // someone could create an event programmatically and emit it multiple times,
69
- // in which case we want to handle the whole propagation chain properly each time.
70
- // (this will only be a false negative if the event is dispatched multiple times and
71
- // the fallback document listener isn't reached in between, but that's super rare)
72
- var handler_idx = path.indexOf(handler_element);
73
- if (handler_idx === -1) {
74
- // handle_idx can theoretically be -1 (happened in some JSDOM testing scenarios with an event listener on the window object)
75
- // so guard against that, too, and assume that everything was handled at this point.
76
- return;
77
- }
78
-
79
- if (at_idx <= handler_idx) {
80
- path_idx = at_idx;
81
- }
82
- }
83
-
84
- current_target = /** @type {Element} */ (path[path_idx] || event.target);
85
- // there can only be one delegated event per element, and we either already handled the current target,
86
- // or this is the very first target in the chain which has a non-delegated listener, in which case it's safe
87
- // to handle a possible delegated event on it later (through the root delegation listener for example).
88
- if (current_target === handler_element) return;
89
-
90
- // Proxy currentTarget to correct target
91
- define_property(event, 'currentTarget', {
92
- configurable: true,
93
- get() {
94
- return current_target || owner_document;
95
- },
96
- });
97
-
98
- var previous_block = active_block;
99
- var previous_reaction = active_reaction;
100
- var previous_tracking = tracking;
101
-
102
- set_active_block(null);
103
- set_active_reaction(null);
104
- set_tracking(false);
105
-
106
- try {
107
- /**
108
- * @type {unknown}
109
- */
110
- var throw_error;
111
- /**
112
- * @type {unknown[]}
113
- */
114
- var other_errors = [];
115
-
116
- while (current_target !== null) {
117
- /** @type {null | Element} */
118
- var parent_element =
119
- current_target.assignedSlot ||
120
- current_target.parentNode ||
121
- /** @type {any} */ (current_target).host ||
122
- null;
123
-
124
- try {
125
- // @ts-expect-error
126
- var delegated = current_target['__' + event_name];
127
-
128
- if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
129
- if (is_array(delegated)) {
130
- var [fn, block, ...data] = delegated;
131
- fn.apply(current_target, [event, ...data, block]);
132
- } else {
133
- delegated.call(current_target, event);
134
- }
135
- }
136
- } catch (error) {
137
- if (throw_error) {
138
- other_errors.push(error);
139
- } else {
140
- throw_error = error;
141
- }
142
- }
143
- if (event.cancelBubble || parent_element === handler_element || parent_element === null) {
144
- break;
145
- }
146
- current_target = parent_element;
147
- }
148
-
149
- if (throw_error) {
150
- for (let error of other_errors) {
151
- // Throw the rest of the errors, one-by-one on a microtask
152
- queueMicrotask(() => {
153
- throw error;
154
- });
155
- }
156
- throw throw_error;
157
- }
158
- } finally {
159
- set_active_block(previous_block);
160
- // @ts-expect-error is used above
161
- event.__root = handler_element;
162
- // @ts-ignore remove proxy on currentTarget
163
- delete event.currentTarget;
164
- set_active_block(previous_block);
165
- set_active_reaction(previous_reaction);
166
- set_tracking(previous_tracking);
167
- }
38
+ var handler_element = this;
39
+ var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
40
+ var event_name = event.type;
41
+ var path = event.composedPath?.() || [];
42
+ var current_target = /** @type {null | Element} */ (path[0] || event.target);
43
+
44
+ // composedPath contains list of nodes the event has propagated through.
45
+ // We check __root to skip all nodes below it in case this is a
46
+ // parent of the __root node, which indicates that there's nested
47
+ // mounted apps. In this case we don't want to trigger events multiple times.
48
+ var path_idx = 0;
49
+
50
+ // @ts-expect-error is added below
51
+ var handled_at = event.__root;
52
+
53
+ if (handled_at) {
54
+ var at_idx = path.indexOf(handled_at);
55
+ if (
56
+ at_idx !== -1 &&
57
+ (handler_element === document || handler_element === /** @type {any} */ (window))
58
+ ) {
59
+ // This is the fallback document listener or a window listener, but the event was already handled
60
+ // -> ignore, but set handle_at to document/window so that we're resetting the event
61
+ // chain in case someone manually dispatches the same event object again.
62
+ // @ts-expect-error
63
+ event.__root = handler_element;
64
+ return;
65
+ }
66
+
67
+ // We're deliberately not skipping if the index is higher, because
68
+ // someone could create an event programmatically and emit it multiple times,
69
+ // in which case we want to handle the whole propagation chain properly each time.
70
+ // (this will only be a false negative if the event is dispatched multiple times and
71
+ // the fallback document listener isn't reached in between, but that's super rare)
72
+ var handler_idx = path.indexOf(handler_element);
73
+ if (handler_idx === -1) {
74
+ // handle_idx can theoretically be -1 (happened in some JSDOM testing scenarios with an event listener on the window object)
75
+ // so guard against that, too, and assume that everything was handled at this point.
76
+ return;
77
+ }
78
+
79
+ if (at_idx <= handler_idx) {
80
+ path_idx = at_idx;
81
+ }
82
+ }
83
+
84
+ current_target = /** @type {Element} */ (path[path_idx] || event.target);
85
+ // there can only be one delegated event per element, and we either already handled the current target,
86
+ // or this is the very first target in the chain which has a non-delegated listener, in which case it's safe
87
+ // to handle a possible delegated event on it later (through the root delegation listener for example).
88
+ if (current_target === handler_element) return;
89
+
90
+ // Proxy currentTarget to correct target
91
+ define_property(event, 'currentTarget', {
92
+ configurable: true,
93
+ get() {
94
+ return current_target || owner_document;
95
+ },
96
+ });
97
+
98
+ var previous_block = active_block;
99
+ var previous_reaction = active_reaction;
100
+ var previous_tracking = tracking;
101
+
102
+ set_active_block(null);
103
+ set_active_reaction(null);
104
+ set_tracking(false);
105
+
106
+ try {
107
+ /**
108
+ * @type {unknown}
109
+ */
110
+ var throw_error;
111
+ /**
112
+ * @type {unknown[]}
113
+ */
114
+ var other_errors = [];
115
+
116
+ while (current_target !== null) {
117
+ /** @type {null | Element} */
118
+ var parent_element =
119
+ current_target.assignedSlot ||
120
+ current_target.parentNode ||
121
+ /** @type {any} */ (current_target).host ||
122
+ null;
123
+
124
+ try {
125
+ // @ts-expect-error
126
+ var delegated = current_target['__' + event_name];
127
+
128
+ if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
129
+ if (is_array(delegated)) {
130
+ var [fn, block, ...data] = delegated;
131
+ fn.apply(current_target, [event, ...data, block]);
132
+ } else {
133
+ delegated.call(current_target, event);
134
+ }
135
+ }
136
+ } catch (error) {
137
+ if (throw_error) {
138
+ other_errors.push(error);
139
+ } else {
140
+ throw_error = error;
141
+ }
142
+ }
143
+ if (event.cancelBubble || parent_element === handler_element || parent_element === null) {
144
+ break;
145
+ }
146
+ current_target = parent_element;
147
+ }
148
+
149
+ if (throw_error) {
150
+ for (let error of other_errors) {
151
+ // Throw the rest of the errors, one-by-one on a microtask
152
+ queueMicrotask(() => {
153
+ throw error;
154
+ });
155
+ }
156
+ throw throw_error;
157
+ }
158
+ } finally {
159
+ set_active_block(previous_block);
160
+ // @ts-expect-error is used above
161
+ event.__root = handler_element;
162
+ // @ts-ignore remove proxy on currentTarget
163
+ delete event.currentTarget;
164
+ set_active_block(previous_block);
165
+ set_active_reaction(previous_reaction);
166
+ set_tracking(previous_tracking);
167
+ }
168
168
  }
169
169
 
170
170
  /**
@@ -174,73 +174,103 @@ export function handle_event_propagation(event) {
174
174
  * @param {AddEventListenerOptions} [options]
175
175
  */
176
176
  function create_event(event_name, dom, handler, options = {}) {
177
- function target_handler(/** @type {Event} */ event) {
178
- var previous_block = active_block;
179
- var previous_reaction = active_reaction;
180
- var previous_tracking = tracking;
181
-
182
- try {
183
- set_active_block(null);
184
- set_active_reaction(null);
185
- set_tracking(false);
186
-
187
- if (!options.capture) {
188
- // Only call in the bubble phase, else delegated events would be called before the capturing events
189
- handle_event_propagation.call(dom, event);
190
- }
191
- if (!event.cancelBubble) {
192
- return handler?.call(this, event);
193
- }
194
- } finally {
195
- set_active_block(previous_block);
196
- set_active_reaction(previous_reaction);
197
- set_tracking(previous_tracking);
198
- }
199
- }
200
-
201
- dom.addEventListener(event_name, target_handler, options);
202
-
203
- return target_handler;
177
+ /** @this {any} */
178
+ function target_handler(/** @type {Event} */ event) {
179
+ var previous_block = active_block;
180
+ var previous_reaction = active_reaction;
181
+ var previous_tracking = tracking;
182
+
183
+ try {
184
+ set_active_block(null);
185
+ set_active_reaction(null);
186
+ set_tracking(false);
187
+
188
+ if (!options.capture) {
189
+ // Only call in the bubble phase, else delegated events would be called before the capturing events
190
+ handle_event_propagation.call(dom, event);
191
+ }
192
+ if (!event.cancelBubble) {
193
+ return handler?.call(this, event);
194
+ }
195
+ } finally {
196
+ set_active_block(previous_block);
197
+ set_active_reaction(previous_reaction);
198
+ set_tracking(previous_tracking);
199
+ }
200
+ }
201
+
202
+ dom.addEventListener(event_name, target_handler, options);
203
+
204
+ return target_handler;
204
205
  }
205
206
 
207
+ /**
208
+ * @param {string} event_name
209
+ * @param {Element} dom
210
+ * @param {EventListener} [handler]
211
+ * @param {boolean} [capture]
212
+ * @param {boolean} [passive]
213
+ * @returns {void}
214
+ */
206
215
  export function event(event_name, dom, handler, capture, passive) {
207
- var options = { capture, passive };
208
- create_event(event_name, dom, handler, options);
216
+ var options = { capture, passive };
217
+ create_event(event_name, dom, handler, options);
209
218
  }
210
219
 
220
+ /**
221
+ * @param {Array<string>} events
222
+ * @returns {void}
223
+ */
211
224
  export function delegate(events) {
212
- for (var i = 0; i < events.length; i++) {
213
- all_registered_events.add(events[i]);
214
- }
225
+ for (var i = 0; i < events.length; i++) {
226
+ all_registered_events.add(events[i]);
227
+ }
215
228
 
216
- for (var fn of root_event_handles) {
217
- fn(events);
218
- }
229
+ for (var fn of root_event_handles) {
230
+ fn(events);
231
+ }
219
232
  }
220
233
 
234
+ /** @param {Element} target */
221
235
  export function handle_root_events(target) {
222
- var registered_events = new Set();
236
+ var registered_events = new Set();
237
+
238
+ /**
239
+ * @typedef {Object} EventHandleOptions
240
+ * @property {boolean} [passive]
241
+ */
223
242
 
224
- var event_handle = (events) => {
225
- for (var i = 0; i < events.length; i++) {
226
- var event_name = events[i];
243
+ /**
244
+ * @typedef {(
245
+ * events: Array<string>
246
+ * ) => void} EventHandle
247
+ */
227
248
 
228
- if (registered_events.has(event_name)) continue;
229
- registered_events.add(event_name);
249
+ /** @type {EventHandle} */
250
+ var event_handle = (/** @type {Array<string>} */ events) => {
251
+ for (var i = 0; i < events.length; i++) {
252
+ var event_name = events[i];
230
253
 
231
- var passive = is_passive_event(event_name);
254
+ if (registered_events.has(event_name)) continue;
255
+ registered_events.add(event_name);
232
256
 
233
- target.addEventListener(event_name, handle_event_propagation, { passive });
234
- }
235
- };
257
+ /** @type {boolean} */
258
+ var passive = is_passive_event(event_name);
236
259
 
237
- event_handle(array_from(all_registered_events));
238
- root_event_handles.add(event_handle);
260
+ /** @type {EventHandleOptions} */
261
+ var options = { passive };
262
+
263
+ target.addEventListener(event_name, handle_event_propagation, options);
264
+ }
265
+ };
239
266
 
240
- return () => {
241
- for (var event_name of registered_events) {
242
- target.removeEventListener(event_name, handle_event_propagation);
243
- }
244
- root_event_handles.delete(event_handle);
245
- };
267
+ event_handle(array_from(all_registered_events));
268
+ root_event_handles.add(event_handle);
269
+
270
+ return () => {
271
+ for (var event_name of registered_events) {
272
+ target.removeEventListener(event_name, handle_event_propagation);
273
+ }
274
+ root_event_handles.delete(event_handle);
275
+ };
246
276
  }
@@ -1,3 +1,5 @@
1
+ /** @import { Block } from '#client' */
2
+
1
3
  import { IS_CONTROLLED, IS_INDEXED } from '../../../constants.js';
2
4
  import { branch, destroy_block, destroy_block_children, render } from './blocks.js';
3
5
  import { FOR_BLOCK, TRACKED_ARRAY } from './constants.js';
@@ -5,6 +7,15 @@ import { create_text, next_sibling } from './operations.js';
5
7
  import { active_block, set, tracked, untrack } from './runtime.js';
6
8
  import { array_from, is_array } from './utils.js';
7
9
 
10
+ /**
11
+ * @template V
12
+ * @param {Node} anchor
13
+ * @param {V} value
14
+ * @param {number} index
15
+ * @param {(anchor: Node, value: V, index?: any) => Block} render_fn
16
+ * @param {boolean} is_indexed
17
+ * @returns {Block}
18
+ */
8
19
  function create_item(anchor, value, index, render_fn, is_indexed) {
9
20
  var b = branch(() => {
10
21
  var tracked_index;
@@ -31,6 +42,11 @@ function create_item(anchor, value, index, render_fn, is_indexed) {
31
42
  return b;
32
43
  }
33
44
 
45
+ /**
46
+ * @param {Block} block
47
+ * @param {Element} anchor
48
+ * @returns {void}
49
+ */
34
50
  function move(block, anchor) {
35
51
  var node = block.s.start;
36
52
  var end = block.s.end;
@@ -40,7 +56,7 @@ function move(block, anchor) {
40
56
  return;
41
57
  }
42
58
  while (node !== null) {
43
- var next_node = /** @type {TemplateNode} */ (next_sibling(node));
59
+ var next_node = /** @type {Node} */ (next_sibling(node));
44
60
  anchor.before(node);
45
61
  node = next_node;
46
62
  if (node === end) {
@@ -50,6 +66,11 @@ function move(block, anchor) {
50
66
  }
51
67
  }
52
68
 
69
+ /**
70
+ * @template V
71
+ * @param {V[] | Iterable<V>} collection
72
+ * @returns {V[]}
73
+ */
53
74
  function collection_to_array(collection) {
54
75
  var array = is_array(collection) ? collection : collection == null ? [] : array_from(collection);
55
76
 
@@ -62,10 +83,18 @@ function collection_to_array(collection) {
62
83
  return array;
63
84
  }
64
85
 
86
+ /**
87
+ * @template V
88
+ * @param {Element} node
89
+ * @param {() => V[] | Iterable<V>} get_collection
90
+ * @param {(anchor: Node, value: V, index?: any) => Block} render_fn
91
+ * @param {number} flags
92
+ * @returns {void}
93
+ */
65
94
  export function for_block(node, get_collection, render_fn, flags) {
66
95
  var is_controlled = (flags & IS_CONTROLLED) !== 0;
67
96
  var is_indexed = (flags & IS_INDEXED) !== 0;
68
- var anchor = node;
97
+ var anchor = /** @type {Element | Text} */ (node);
69
98
 
70
99
  if (is_controlled) {
71
100
  anchor = node.appendChild(create_text());
@@ -82,9 +111,16 @@ export function for_block(node, get_collection, render_fn, flags) {
82
111
  }, FOR_BLOCK);
83
112
  }
84
113
 
114
+ /**
115
+ * @template V
116
+ * @param {Element | Text} anchor
117
+ * @param {Block} block
118
+ * @param {V[]} array
119
+ * @returns {void}
120
+ */
85
121
  function reconcile_fast_clear(anchor, block, array) {
86
122
  var state = block.s;
87
- var parent_node = anchor.parentNode;
123
+ var parent_node = /** @type {Element} */ (anchor.parentNode);
88
124
  parent_node.textContent = '';
89
125
  destroy_block_children(block);
90
126
  parent_node.append(anchor);
@@ -92,13 +128,48 @@ function reconcile_fast_clear(anchor, block, array) {
92
128
  state.blocks = [];
93
129
  }
94
130
 
131
+ /**
132
+ * @param {Block} block
133
+ * @param {number} index
134
+ * @returns {void}
135
+ */
95
136
  function update_index(block, index) {
96
137
  set(block.s.i, index, block);
97
138
  }
98
139
 
140
+ /**
141
+ * @template V
142
+ * @param {Element | Text} anchor
143
+ * @param {Block} block
144
+ * @param {V[]} b
145
+ * @param {(anchor: Node, value: V, index?: any) => Block} render_fn
146
+ * @param {boolean} is_controlled
147
+ * @param {boolean} is_indexed
148
+ * @returns {void}
149
+ */
99
150
  function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
100
151
  var state = block.s;
101
152
 
153
+ // Variables used in conditional branches - declare with initial values
154
+ /** @type {number} */
155
+ var a_start = 0;
156
+ /** @type {number} */
157
+ var b_start = 0;
158
+ /** @type {number} */
159
+ var a_left = 0;
160
+ /** @type {number} */
161
+ var b_left = 0;
162
+ /** @type {Int32Array} */
163
+ var sources = new Int32Array(0);
164
+ /** @type {boolean} */
165
+ var moved = false;
166
+ /** @type {number} */
167
+ var pos = 0;
168
+ /** @type {number} */
169
+ var patched = 0;
170
+ /** @type {number} */
171
+ var i = 0;
172
+
102
173
  if (state === null) {
103
174
  state = block.s = {
104
175
  array: [],
@@ -187,15 +258,15 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
187
258
  destroy_block(a_blocks[j++]);
188
259
  }
189
260
  } else {
190
- var a_start = j;
191
- var b_start = j;
192
- var a_left = a_end - j + 1;
193
- var b_left = b_end - j + 1;
194
- var sources = new Int32Array(b_left + 1);
195
- var moved = false;
196
- var pos = 0;
197
- var patched = 0;
198
- var i = 0;
261
+ a_start = j;
262
+ b_start = j;
263
+ a_left = a_end - j + 1;
264
+ b_left = b_end - j + 1;
265
+ sources = new Int32Array(b_left + 1);
266
+ moved = false;
267
+ pos = 0;
268
+ patched = 0;
269
+ i = 0;
199
270
 
200
271
  fast_path_removal = is_controlled && a_left === a_length;
201
272
 
@@ -321,10 +392,16 @@ function reconcile(anchor, block, b, render_fn, is_controlled, is_indexed) {
321
392
  state.blocks = b_blocks;
322
393
  }
323
394
 
395
+ /** @type {Int32Array} */
324
396
  let result;
397
+ /** @type {Int32Array} */
325
398
  let p;
326
399
  let maxLen = 0;
327
400
  // https://en.wikipedia.org/wiki/Longest_increasing_subsequence
401
+ /**
402
+ * @param {Int32Array} arr
403
+ * @returns {Int32Array}
404
+ */
328
405
  function lis_algorithm(arr) {
329
406
  let arrI = 0;
330
407
  let i = 0;
@@ -386,6 +463,13 @@ function lis_algorithm(arr) {
386
463
  return seq;
387
464
  }
388
465
 
466
+ /**
467
+ * @template V
468
+ * @template K
469
+ * @param {V[] | Iterable<V>} collection
470
+ * @param {(item: V) => K} key_fn
471
+ * @returns {V[]}
472
+ */
389
473
  export function keyed(collection, key_fn) {
390
474
  var block = active_block;
391
475
  if (block === null || (block.f & FOR_BLOCK) === 0) {
@@ -404,7 +488,7 @@ export function keyed(collection, key_fn) {
404
488
  var state = block.s;
405
489
 
406
490
  if (state === null) {
407
- return collection;
491
+ return b_array;
408
492
  }
409
493
 
410
494
  var a_array = state.array;
@@ -1,17 +1,28 @@
1
+ /** @import { Block } from '#client' */
2
+
1
3
  import { branch, destroy_block, render } from './blocks.js';
2
4
  import { IF_BLOCK, UNINITIALIZED } from './constants.js';
3
5
 
6
+ /**
7
+ * @param {Node} node
8
+ * @param {(set_branch: (fn: (anchor: Node) => void, flag?: boolean) => void) => void} fn
9
+ * @returns {void}
10
+ */
4
11
  export function if_block(node, fn) {
5
12
  var anchor = node;
6
13
  var has_branch = false;
14
+ /** @type {any} */
7
15
  var condition = UNINITIALIZED;
16
+ /** @type {Block | null} */
8
17
  var b = null;
9
18
 
19
+ /** @type {(fn: (anchor: Node) => void, flag?: boolean) => void} */
10
20
  var set_branch = (fn, flag = true) => {
11
21
  has_branch = true;
12
22
  update_branch(flag, fn);
13
23
  };
14
24
 
25
+ /** @type {(new_condition: any, fn: ((anchor: Node) => void) | null) => void} */
15
26
  var update_branch = (new_condition, fn) => {
16
27
  if (condition === (condition = new_condition)) return;
17
28