@oscarpalmer/abydon 0.14.0 → 0.16.0

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.
@@ -20,18 +20,18 @@ const METHODS_UPDATE = new Set([
20
20
  const NAME_ARRAY = "array";
21
21
  const NAME_COMPUTED = "computed";
22
22
  const NAME_EFFECT = "effect";
23
+ const NAME_MORA = "$mora";
23
24
  const NAME_SIGNAL = "signal";
24
25
  const NAME_STORE = "store";
25
- const NAMES = new Set([
26
+ const NAME_ALL = new Set([
26
27
  NAME_ARRAY,
27
28
  NAME_COMPUTED,
28
29
  NAME_SIGNAL,
29
30
  NAME_STORE
30
31
  ]);
31
-
32
32
  var Effect = class {
33
33
  constructor(callback) {
34
- Object.defineProperty(this, "$mora", { value: NAME_EFFECT });
34
+ Object.defineProperty(this, NAME_MORA, { value: NAME_EFFECT });
35
35
  this.state = { callback };
36
36
  runEffect(this);
37
37
  }
@@ -48,7 +48,6 @@ function runEffect(effect$1) {
48
48
  function effect(callback) {
49
49
  return typeof callback === "function" ? new Effect(callback) : void 0;
50
50
  }
51
-
52
51
  function isArray(value) {
53
52
  return isMora(value, NAME_ARRAY);
54
53
  }
@@ -59,15 +58,14 @@ function isEffect(value) {
59
58
  return isMora(value, NAME_EFFECT);
60
59
  }
61
60
  function isMora(value, name) {
62
- return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value.$mora === name : name.has(value.$mora));
61
+ return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
63
62
  }
64
63
  function isReactive(value) {
65
- return isMora(value, NAMES);
64
+ return isMora(value, NAME_ALL);
66
65
  }
67
66
  function isSignal(value) {
68
67
  return isMora(value, NAME_SIGNAL);
69
68
  }
70
-
71
69
  function flushHandlers() {
72
70
  while (BATCH.depth === 0 && BATCH.handlers.size > 0) {
73
71
  const handlers = [...BATCH.handlers];
@@ -83,7 +81,6 @@ function stopBatch() {
83
81
  if (BATCH.depth > 0) BATCH.depth -= 1;
84
82
  flushHandlers();
85
83
  }
86
-
87
84
  var Subscription = class {
88
85
  callback;
89
86
  state;
@@ -93,13 +90,13 @@ var Subscription = class {
93
90
  callback(state.value);
94
91
  }
95
92
  destroy() {
96
- this.callback = noop;
93
+ this.callback = noop$1;
97
94
  this.state = void 0;
98
95
  }
99
96
  };
100
- function noop() {}
97
+ function noop$1() {}
101
98
  function subscribe(state, callback) {
102
- if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
99
+ if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop$1;
103
100
  state.subscriptions.set(callback, new Subscription(state, callback));
104
101
  return () => {
105
102
  unsubscribe(state, callback);
@@ -109,7 +106,6 @@ function unsubscribe(state, callback) {
109
106
  state.subscriptions.get(callback)?.destroy();
110
107
  state.subscriptions.delete(callback);
111
108
  }
112
-
113
109
  var Reactive = class {
114
110
  state = {
115
111
  computeds: /* @__PURE__ */ new Set(),
@@ -121,7 +117,7 @@ var Reactive = class {
121
117
  constructor(name, value, options) {
122
118
  this.state.value = value;
123
119
  if (typeof options === "object" && typeof options.equal === "function") this.state.equal = options.equal;
124
- Object.defineProperty(this, "$mora", { value: name });
120
+ Object.defineProperty(this, NAME_MORA, { value: name });
125
121
  }
126
122
  peek() {
127
123
  return this.state.value;
@@ -139,7 +135,6 @@ var Reactive = class {
139
135
  unsubscribe(this.state, callback);
140
136
  }
141
137
  };
142
-
143
138
  var Computed = class extends Reactive {
144
139
  effect = {
145
140
  dirty: true,
@@ -172,10 +167,9 @@ var Computed = class extends Reactive {
172
167
  function computed(callback, options) {
173
168
  return new Computed(callback, options);
174
169
  }
175
-
176
170
  function emitValue(state) {
177
- for (const computed of state.computeds) computed.effect.dirty = true;
178
- for (const effect of state.effects) BATCH.handlers.add(effect);
171
+ for (const computed$1 of state.computeds) computed$1.effect.dirty = true;
172
+ for (const effect$1 of state.effects) BATCH.handlers.add(effect$1);
179
173
  for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
180
174
  if (BATCH.depth === 0) flushHandlers();
181
175
  }
@@ -197,7 +191,6 @@ function getValue$1(state) {
197
191
  if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
198
192
  return state.value;
199
193
  }
200
-
201
194
  var Signal = class extends Reactive {
202
195
  constructor(value, options) {
203
196
  super(NAME_SIGNAL, value, options);
@@ -218,14 +211,16 @@ var Signal = class extends Reactive {
218
211
  function signal(value, options) {
219
212
  return new Signal(value, options);
220
213
  }
221
-
222
- function getReactiveValueInProxy(reactive, mapped, key, isArray) {
214
+ function emityProxyValues(state, mapped) {
215
+ const values = [...mapped.values()];
216
+ const { length } = values;
217
+ for (let index = 0; index < length; index += 1) values[index].effect.dirty = true;
218
+ emitValue(state);
219
+ }
220
+ function getReactiveValueInProxy(reactive, mapped, key, isArray$1) {
223
221
  let item = mapped.get(key);
224
222
  if (item == null) {
225
- item = computed(() => {
226
- const value = reactive.get();
227
- return isArray ? value.at(key) : value[key];
228
- });
223
+ item = computed(() => isArray$1 ? reactive.get().at(key) : reactive.get()[key]);
229
224
  mapped.set(key, item);
230
225
  }
231
226
  return item;
@@ -247,19 +242,18 @@ function setProxyValue(proxy, value) {
247
242
  stopBatch();
248
243
  }
249
244
  function setValueInProxy(parameters) {
250
- const { isArray, length, property, state, target, value } = parameters;
251
- if (isArray) {
245
+ const { isArray: isArray$1, length, property, state, target, value } = parameters;
246
+ if (isArray$1) {
252
247
  if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
253
248
  }
254
249
  const previous = Reflect.get(target, property);
255
250
  if (!state.equal(previous, value)) {
256
251
  Reflect.set(target, property, value);
257
252
  emitValue(state);
258
- if (isArray) length?.set(target.length);
253
+ if (isArray$1) length?.set(target.length);
259
254
  }
260
255
  return true;
261
256
  }
262
-
263
257
  var ReactiveArray = class extends Reactive {
264
258
  #indiced = /* @__PURE__ */ new Map();
265
259
  #size = signal(0);
@@ -291,19 +285,17 @@ var ReactiveArray = class extends Reactive {
291
285
  }
292
286
  get(first) {
293
287
  if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
294
- if (first === "length") return this.length;
295
- return getValue$1(this.state);
288
+ return first === "length" ? this.length : getValue$1(this.state);
296
289
  }
297
290
  map(callback) {
298
291
  return computed(() => this.get().map(callback));
299
292
  }
300
293
  notify() {
301
- emitValue(this.state);
294
+ emityProxyValues(this.state, this.#indiced);
302
295
  }
303
296
  peek(value) {
304
297
  if (value === "length") return this.#size.peek();
305
- if (typeof value === "number") return this.state.value.at(value);
306
- return [...this.state.value];
298
+ return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
307
299
  }
308
300
  pop() {
309
301
  return this.state.value.pop();
@@ -324,7 +316,7 @@ var ReactiveArray = class extends Reactive {
324
316
  }
325
317
  subscribe(first, second) {
326
318
  if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
327
- return typeof first === "function" ? subscribe(this.state, first) : noop;
319
+ return typeof first === "function" ? subscribe(this.state, first) : noop$1;
328
320
  }
329
321
  unshift(...items) {
330
322
  return this.state.value.unshift(...items);
@@ -354,30 +346,28 @@ function setAtIndex(array$1, index, value) {
354
346
  const actual = index < 0 ? array$1.length + index : index;
355
347
  if (actual > -1) array$1[actual] = value;
356
348
  }
357
-
358
349
  function isKey(value) {
359
350
  return typeof value === "number" || typeof value === "string";
360
351
  }
361
- function isPlainObject$1(value) {
352
+ function isPlainObject$2(value) {
362
353
  if (value === null || typeof value !== "object") return false;
363
354
  if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
364
355
  const prototype = Object.getPrototypeOf(value);
365
356
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
366
357
  }
367
-
368
- function getString$1(value) {
369
- if (typeof value === "string") return value;
370
- if (value == null) return "";
371
- if (typeof value !== "object") return String(value);
372
- const asString = String(value.valueOf?.() ?? value);
373
- return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
374
- }
375
-
376
- function isNullableOrWhitespace(value) {
377
- return value == null || EXPRESSION_WHITESPACE.test(getString$1(value));
378
- }
379
- var EXPRESSION_WHITESPACE = /^\s*$/;
380
-
358
+ new Set([
359
+ Int8Array,
360
+ Uint8Array,
361
+ Uint8ClampedArray,
362
+ Int16Array,
363
+ Uint16Array,
364
+ Int32Array,
365
+ Uint32Array,
366
+ Float32Array,
367
+ Float64Array,
368
+ BigInt64Array,
369
+ BigUint64Array
370
+ ]);
381
371
  var Store = class extends Reactive {
382
372
  #keyed = /* @__PURE__ */ new Map();
383
373
  constructor(value, options) {
@@ -392,111 +382,166 @@ var Store = class extends Reactive {
392
382
  get(key) {
393
383
  return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue$1(this.state);
394
384
  }
385
+ notify() {
386
+ emityProxyValues(this.state, this.#keyed);
387
+ }
395
388
  peek(key) {
396
389
  return isKey(key) ? this.state.value[key] : { ...this.state.value };
397
390
  }
398
391
  set(first, second) {
399
392
  if (isKey(first)) this.state.value[first] = second;
400
- else if (first == null || isPlainObject$1(first)) setProxyValue(this.state.value, first ?? {});
393
+ else if (first == null || isPlainObject$2(first)) setProxyValue(this.state.value, first ?? {});
401
394
  }
402
395
  subscribe(first, second) {
403
396
  if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
404
- return typeof first === "function" ? subscribe(this.state, first) : noop;
397
+ return typeof first === "function" ? subscribe(this.state, first) : noop$1;
405
398
  }
406
399
  update(callback) {
407
400
  const updated = callback({ ...this.state.value });
408
- if (updated == null || isPlainObject$1(updated)) setProxyValue(this.state.value, updated ?? {});
401
+ if (updated == null || isPlainObject$2(updated)) setProxyValue(this.state.value, updated ?? {});
409
402
  }
410
403
  };
411
404
  function store(value, options) {
412
- return new Store(isPlainObject$1(value) ? value : {}, options);
405
+ return new Store(isPlainObject$2(value) ? value : {}, options);
413
406
  }
414
-
415
- function isChildNode(value) {
416
- return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
407
+ function isPlainObject$1(value) {
408
+ if (value === null || typeof value !== "object") return false;
409
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
410
+ const prototype = Object.getPrototypeOf(value);
411
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
412
+ }
413
+ new Set([
414
+ Int8Array,
415
+ Uint8Array,
416
+ Uint8ClampedArray,
417
+ Int16Array,
418
+ Uint16Array,
419
+ Int32Array,
420
+ Uint32Array,
421
+ Float32Array,
422
+ Float64Array,
423
+ BigInt64Array,
424
+ BigUint64Array
425
+ ]);
426
+ function getString$1(value) {
427
+ if (typeof value === "string") return value;
428
+ if (value == null) return "";
429
+ if (typeof value === "function") return getString$1(value());
430
+ if (typeof value !== "object") return String(value);
431
+ const asString = String(value.valueOf?.() ?? value);
432
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
433
+ }
434
+ function isNullableOrWhitespace(value) {
435
+ return value == null || EXPRESSION_WHITESPACE$1.test(getString$1(value));
436
+ }
437
+ var EXPRESSION_WHITESPACE$1 = /^\s*$/;
438
+ function isEventTarget(value) {
439
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
417
440
  }
418
441
  function isHTMLOrSVGElement(value) {
419
442
  return value instanceof HTMLElement || value instanceof SVGElement;
420
443
  }
421
- var CHILD_NODE_TYPES = new Set([
422
- Node.ELEMENT_NODE,
423
- Node.TEXT_NODE,
424
- Node.PROCESSING_INSTRUCTION_NODE,
425
- Node.COMMENT_NODE,
426
- Node.DOCUMENT_TYPE_NODE
427
- ]);
428
-
429
444
  function getString(value) {
430
445
  if (typeof value === "string") return value;
431
446
  if (value == null) return "";
447
+ if (typeof value === "function") return getString(value());
432
448
  if (typeof value !== "object") return String(value);
433
449
  const asString = String(value.valueOf?.() ?? value);
434
450
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
435
451
  }
436
-
437
452
  function isPlainObject(value) {
438
453
  if (value === null || typeof value !== "object") return false;
439
454
  if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
440
455
  const prototype = Object.getPrototypeOf(value);
441
456
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
442
457
  }
443
-
458
+ new Set([
459
+ Int8Array,
460
+ Uint8Array,
461
+ Uint8ClampedArray,
462
+ Int16Array,
463
+ Uint16Array,
464
+ Int32Array,
465
+ Uint32Array,
466
+ Float32Array,
467
+ Float64Array,
468
+ BigInt64Array,
469
+ BigUint64Array
470
+ ]);
471
+ function badAttributeHandler(name, value) {
472
+ if (name == null || value == null) return true;
473
+ if (EXPRESSION_CLOBBERED_NAME.test(name) && (value in document || value in formElement) || EXPRESSION_EVENT_NAME$1.test(name)) return true;
474
+ if (EXPRESSION_SKIP_NAME.test(name) || EXPRESSION_URI_VALUE.test(value) || isValidSourceAttribute(name, value)) return false;
475
+ return EXPRESSION_DATA_OR_SCRIPT.test(value);
476
+ }
477
+ function booleanAttributeHandler(name, value) {
478
+ if (name == null || value == null) return true;
479
+ if (!booleanAttributesSet.has(name)) return false;
480
+ const normalized = value.toLowerCase().trim();
481
+ return !(normalized.length === 0 || normalized === name);
482
+ }
483
+ function decodeAttribute(value) {
484
+ textArea ??= document.createElement("textarea");
485
+ textArea.innerHTML = value;
486
+ return decodeURIComponent(textArea.value);
487
+ }
488
+ function handleAttribute(callback, decode, first, second) {
489
+ let name;
490
+ let value;
491
+ if (isAttribute(first)) {
492
+ name = first.name;
493
+ value = String(first.value);
494
+ } else if (typeof first === "string" && typeof second === "string") {
495
+ name = first;
496
+ value = second;
497
+ }
498
+ if (decode && value != null) value = decodeAttribute(value);
499
+ return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
500
+ }
444
501
  function isAttribute(value) {
445
502
  return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
446
503
  }
447
- function isBadAttribute(first, second) {
448
- return validateAttribute((attribute) => attribute == null || EXPRESSION_ON_PREFIX.test(attribute.name) || EXPRESSION_SOURCE_PREFIX.test(attribute.name) && EXPRESSION_VALUE_PREFIX.test(String(attribute.value)), first, second);
504
+ function _isBadAttribute(first, second, decode) {
505
+ return handleAttribute(badAttributeHandler, decode, first, second);
449
506
  }
450
- function isBooleanAttribute(value) {
451
- return validateAttribute((attribute) => attribute != null && booleanAttributes.includes(attribute.name.toLowerCase()), value, "");
507
+ function _isBooleanAttribute(first, decode) {
508
+ return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
452
509
  }
453
- function isEmptyNonBooleanAttribute(first, second) {
454
- return validateAttribute((attribute) => attribute != null && !booleanAttributes.includes(attribute.name) && String(attribute.value).trim().length === 0, first, second);
510
+ function _isEmptyNonBooleanAttribute(first, second, decode) {
511
+ return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
455
512
  }
456
- function isInvalidBooleanAttribute(first, second) {
457
- return validateAttribute((attribute) => {
458
- if (attribute == null) return true;
459
- if (!booleanAttributes.includes(attribute.name)) return false;
460
- const normalized = String(attribute.value).toLowerCase().trim();
461
- return !(normalized.length === 0 || normalized === attribute.name);
462
- }, first, second);
513
+ function _isInvalidBooleanAttribute(first, second, decode) {
514
+ return handleAttribute(booleanAttributeHandler, decode, first, second);
463
515
  }
464
516
  function isProperty(value) {
465
517
  return isPlainObject(value) && typeof value.name === "string";
466
518
  }
467
- function setAttribute$1(element, first, second) {
468
- updateValue(element, first, second, updateAttribute);
469
- }
470
- function setProperty(element, first, second) {
471
- updateValue(element, first, second, updateProperty$1);
519
+ function isValidSourceAttribute(name, value) {
520
+ return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
472
521
  }
473
522
  function updateAttribute(element, name, value) {
474
- if (booleanAttributes.includes(name.toLowerCase())) updateProperty$1(element, name, value, false);
475
- else if (value == null) element.removeAttribute(name);
476
- else element.setAttribute(name, typeof value === "string" ? value : getString(value));
523
+ const isBoolean = booleanAttributesSet.has(name.toLowerCase());
524
+ if (isBoolean) updateProperty$1(element, name, value);
525
+ if (isBoolean ? value !== true : value == null) element.removeAttribute(name);
526
+ else element.setAttribute(name, isBoolean ? "" : getString(value));
477
527
  }
478
- function updateProperty$1(element, name, value, validate) {
479
- const actual = validate ?? true ? name.toLowerCase() : name;
480
- if (actual === "hidden") element.hidden = value === "" || value === true;
481
- else element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
528
+ function updateProperty$1(element, name, value) {
529
+ const actual = name.toLowerCase();
530
+ element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
482
531
  }
483
- function updateValue(element, first, second, callback) {
532
+ function updateValue$1(element, first, second) {
484
533
  if (!isHTMLOrSVGElement(element)) return;
485
- if (isProperty(first)) callback(element, first.name, first.value);
486
- else if (typeof first === "string") callback(element, first, second);
487
- }
488
- function validateAttribute(callback, first, second) {
489
- let attribute;
490
- if (isAttribute(first)) attribute = first;
491
- else if (typeof first === "string" && typeof second === "string") attribute = {
492
- name: first,
493
- value: second
494
- };
495
- return callback(attribute);
496
- }
497
- var EXPRESSION_ON_PREFIX = /^on/i;
498
- var EXPRESSION_SOURCE_PREFIX = /^(href|src|xlink:href)$/i;
499
- var EXPRESSION_VALUE_PREFIX = /(data:text\/html|javascript:)/i;
534
+ if (isProperty(first)) updateAttribute(element, first.name, first.value);
535
+ else if (typeof first === "string") updateAttribute(element, first, second);
536
+ }
537
+ var EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
538
+ var EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
539
+ var EXPRESSION_EVENT_NAME$1 = /^on/i;
540
+ var EXPRESSION_SKIP_NAME = /^(aria-[-\w]+|data-[-\w.\u00B7-\uFFFF]+)$/i;
541
+ var EXPRESSION_SOURCE_NAME = /^src$/i;
542
+ var EXPRESSION_SOURCE_VALUE = /^data:/i;
543
+ var EXPRESSION_URI_VALUE = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
544
+ var EXPRESSION_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
500
545
  const booleanAttributes = Object.freeze([
501
546
  "async",
502
547
  "autofocus",
@@ -523,631 +568,755 @@ const booleanAttributes = Object.freeze([
523
568
  "reversed",
524
569
  "selected"
525
570
  ]);
526
-
527
- function getOptions$1(input) {
528
- const options = isPlainObject(input) ? input : {};
529
- options.sanitizeBooleanAttributes = typeof options.sanitizeBooleanAttributes === "boolean" ? options.sanitizeBooleanAttributes : true;
530
- return options;
571
+ var booleanAttributesSet = new Set(booleanAttributes);
572
+ var formElement = document.createElement("form");
573
+ var textArea;
574
+ function setAttribute$1(element, first, second) {
575
+ updateValue$1(element, first, second);
576
+ }
577
+ function setProperty(element, first, second) {
578
+ updateValue$1(element, first, second);
579
+ }
580
+ function handleElement(element, depth) {
581
+ if (depth === 0) {
582
+ const removable = element.querySelectorAll(REMOVE_SELECTOR);
583
+ for (const item of removable) item.remove();
584
+ }
585
+ sanitizeAttributes(element, [...element.attributes]);
531
586
  }
532
- function sanitize(value, options) {
533
- return sanitizeNodes$1(Array.isArray(value) ? value : [value], getOptions$1(options));
587
+ function isClobbered(value) {
588
+ return value instanceof HTMLFormElement && (typeof value.nodeName !== "string" || typeof value.textContent !== "string" || typeof value.removeChild !== "function" || !(value.attributes instanceof NamedNodeMap) || typeof value.removeAttribute !== "function" || typeof value.setAttribute !== "function" || typeof value.namespaceURI !== "string" || typeof value.insertBefore !== "function" || typeof value.hasChildNodes !== "function");
534
589
  }
535
- function sanitizeAttributes(element, attributes, options) {
590
+ function removeNode(node) {
591
+ if (typeof node.remove === "function") node.remove();
592
+ }
593
+ function sanitizeAttributes(element, attributes) {
536
594
  const { length } = attributes;
537
595
  for (let index = 0; index < length; index += 1) {
538
- const attribute = attributes[index];
539
- if (isBadAttribute(attribute) || isEmptyNonBooleanAttribute(attribute)) element.removeAttribute(attribute.name);
540
- else if (options.sanitizeBooleanAttributes && isInvalidBooleanAttribute(attribute)) element.setAttribute(attribute.name, "");
596
+ const { name, value } = attributes[index];
597
+ if (_isBadAttribute(name, value, false) || _isEmptyNonBooleanAttribute(name, value, false)) element.removeAttribute(name);
598
+ else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute$1(element, name, true);
541
599
  }
542
600
  }
543
- function sanitizeNodes$1(nodes, options) {
601
+ function sanitizeNodes(nodes, depth) {
544
602
  const actual = nodes.filter((node) => node instanceof Node);
545
- const { length } = nodes;
603
+ let { length } = nodes;
546
604
  for (let index = 0; index < length; index += 1) {
547
605
  const node = actual[index];
548
- if (node instanceof Element) sanitizeAttributes(node, [...node.attributes], options);
549
- if (node.hasChildNodes()) sanitizeNodes$1([...node.childNodes], options);
606
+ let remove = isClobbered(node);
607
+ if (!remove) switch (node.nodeType) {
608
+ case Node.ELEMENT_NODE:
609
+ handleElement(node, depth);
610
+ break;
611
+ case Node.COMMENT_NODE:
612
+ remove = COMMENT_HARMFUL.test(node.data);
613
+ break;
614
+ case Node.DOCUMENT_TYPE_NODE:
615
+ case Node.PROCESSING_INSTRUCTION_NODE:
616
+ remove = true;
617
+ break;
618
+ }
619
+ if (remove) {
620
+ removeNode(node);
621
+ actual.splice(index, 1);
622
+ index -= 1;
623
+ length -= 1;
624
+ continue;
625
+ }
626
+ if (node.hasChildNodes()) sanitizeNodes([...node.childNodes], depth + 1);
550
627
  }
551
628
  return nodes;
552
629
  }
553
-
554
- function createTemplate(html$1) {
555
- const template = document.createElement("template");
556
- template.innerHTML = html$1;
557
- templates[html$1] = template;
630
+ var COMMENT_HARMFUL = /<[/\w]/g;
631
+ var REMOVE_SELECTOR = "script, toretto-temporary";
632
+ function createHtml(value) {
633
+ const parsed = getParser().parseFromString(getHtml(value), PARSE_TYPE_HTML);
634
+ parsed.body.normalize();
635
+ sanitizeNodes([parsed.body], 0);
636
+ return parsed.body.innerHTML;
637
+ }
638
+ function createTemplate(value, options) {
639
+ const template = document.createElement(TEMPLATE_TAG);
640
+ template.innerHTML = createHtml(value);
641
+ if (typeof value === "string" && options.cache) templates[value] = template;
558
642
  return template;
559
643
  }
560
- function getTemplate(value) {
561
- if (typeof value !== "string" || value.trim().length === 0) return;
644
+ function getHtml(value) {
645
+ return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
646
+ }
647
+ function getNodes(value, options) {
648
+ if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
649
+ const template = getTemplate(value, options);
650
+ return template == null ? [] : [...template.content.cloneNode(true).childNodes];
651
+ }
652
+ function getOptions$1(input) {
653
+ const options = isPlainObject(input) ? input : {};
654
+ options.cache = typeof options.cache === "boolean" ? options.cache : true;
655
+ return options;
656
+ }
657
+ function getParser() {
658
+ parser ??= new DOMParser();
659
+ return parser;
660
+ }
661
+ function getTemplate(value, options) {
662
+ if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
663
+ if (value.trim().length === 0) return;
562
664
  let template = templates[value];
563
665
  if (template != null) return template;
564
666
  const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
565
- template = element instanceof HTMLTemplateElement ? element : createTemplate(value);
566
- templates[value] = template;
567
- return template;
667
+ return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
568
668
  }
569
- var html$1 = ((value, sanitization) => {
570
- if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
571
- let options;
572
- if (sanitization == null || sanitization === true) options = {};
573
- else options = sanitization === false ? void 0 : sanitization;
574
- const template = value instanceof HTMLTemplateElement ? value : getTemplate(value);
575
- if (template == null) return [];
576
- const cloned = template.content.cloneNode(true);
577
- const scripts = cloned.querySelectorAll("script");
578
- const { length } = scripts;
579
- for (let index = 0; index < length; index += 1) scripts[index].remove();
580
- cloned.normalize();
581
- return options != null ? sanitize([...cloned.childNodes], options) : [...cloned.childNodes];
669
+ var html$1 = ((value, options) => {
670
+ return getNodes(value, getOptions$1(options));
582
671
  });
583
672
  html$1.clear = () => {
584
673
  templates = {};
585
674
  };
586
675
  html$1.remove = (template) => {
587
- if (typeof template === "string") templates[template] = void 0;
676
+ if (typeof template !== "string" || templates[template] == null) return;
677
+ const keys = Object.keys(templates);
678
+ const { length } = keys;
679
+ const updated = {};
680
+ for (let index = 0; index < length; index += 1) {
681
+ const key = keys[index];
682
+ if (key !== template) updated[key] = templates[key];
683
+ }
684
+ templates = updated;
588
685
  };
589
686
  var EXPRESSION_ID = /^[a-z][\w-]*$/i;
687
+ var PARSE_TYPE_HTML = "text/html";
688
+ var TEMPLATE_TAG = "template";
689
+ var TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
690
+ var parser;
590
691
  var templates = {};
591
-
592
- const ABORT_CONTROLLERS = new WeakMap();
593
692
  const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
693
+ const EVENT_DEFAULTS = {
694
+ A: "click",
695
+ BUTTON: "click",
696
+ DETAILS: "toggle",
697
+ FORM: "submit",
698
+ SELECT: "change",
699
+ TEXTAREA: "input"
700
+ };
701
+ const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?\w+)="<!--abydon.(\d+)-->"/g;
702
+ const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^_/;
703
+ const EXPRESSION_ABYDON_CONTENT = /^@?abydon\.(\d+)@?$/;
594
704
  const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
595
705
  const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
596
706
  const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
597
- const EXPRESSION_COMMENT_FULL = /^<!--abydon\.(\d+)-->$/;
598
- const EXPRESSION_COMMENT_CONTENT = /^abydon\.(\d+)$/;
707
+ const EXPRESSION_EVENT_CHANGE_TYPES = /^(checkbox|radio)$/;
599
708
  const EXPRESSION_EVENT_NAME = /^@([\w-]+)(?::([a-z:]+))?$/i;
600
- const REASON_EVENT_REMOVED = 'Event removed as element was removed from document by Abydon';
601
-
602
- function getController(element) {
603
- let controller = ABORT_CONTROLLERS.get(element);
604
- if (controller == null) {
605
- controller = new AbortController();
606
- ABORT_CONTROLLERS.set(element, controller);
607
- }
608
- return controller;
609
- }
610
- function getOptions(options) {
611
- const parts = options.split(':');
612
- return {
613
- capture: parts.includes('c') || parts.includes('capture'),
614
- once: parts.includes('o') || parts.includes('once'),
615
- passive: !(parts.includes('a') || parts.includes('active')),
616
- };
617
- }
618
- function mapEvent(element, name, value) {
619
- element.removeAttribute(name);
620
- const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
621
- if (typeof value === 'function' && type != null) {
622
- element.addEventListener(type, value, {
623
- ...getOptions(options ?? ''),
624
- signal: getController(element).signal,
625
- });
626
- }
627
- }
628
- function removeEvents(element) {
629
- ABORT_CONTROLLERS.get(element)?.abort(REASON_EVENT_REMOVED);
630
- ABORT_CONTROLLERS.delete(element);
631
- }
632
-
709
+ const EXPRESSION_EVENT_OPTIONS_ACTIVE = /^a(ctive)$/i;
710
+ const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(apture)$/i;
711
+ const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(nce)$/i;
712
+ const EXPRESSION_EVENT_PREFIX = /^@/;
713
+ const EXPRESSION_PERIOD = /\./;
714
+ const NAME_FRAGMENT = "$fragment";
715
+ const NAME_FRAGMENTS = "$fragments";
633
716
  function compareArrays(first, second) {
634
- const firstIsLarger = first.length > second.length;
635
- const from = firstIsLarger ? first : second;
636
- const to = firstIsLarger ? second : first;
637
- if (!from
638
- .filter(key => to.includes(key))
639
- .every((key, index) => to[index] === key)) {
640
- return 'dissimilar';
641
- }
642
- return firstIsLarger ? 'removed' : 'added';
717
+ const firstIsLarger = first.length > second.length;
718
+ const from = firstIsLarger ? first : second;
719
+ const to = firstIsLarger ? second : first;
720
+ if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) return COMPARISON_DISSIMILAR;
721
+ return firstIsLarger ? COMPARISON_REMOVED : COMPARISON_ADDED;
643
722
  }
644
723
  function isFragment(value) {
645
- return (typeof value === 'object' &&
646
- value != null &&
647
- '$fragment' in value &&
648
- value.$fragment === true);
724
+ return isNamed(value, NAME_FRAGMENT);
725
+ }
726
+ function isFragments(value) {
727
+ return isNamed(value, NAME_FRAGMENTS);
728
+ }
729
+ function isNamed(value, name) {
730
+ return typeof value === "object" && value != null && name in value && value[name] === true;
731
+ }
732
+ const COMPARISON_ADDED = "added";
733
+ const COMPARISON_DISSIMILAR = "dissimilar";
734
+ const COMPARISON_REMOVED = "removed";
735
+ var Fragments = class {
736
+ #state;
737
+ get items() {
738
+ return this.#state.mapped;
739
+ }
740
+ constructor(items, identify, fragment) {
741
+ Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
742
+ this.#state = {
743
+ fragment,
744
+ identify,
745
+ array: items,
746
+ instances: {},
747
+ mapped: array([]),
748
+ subscriber: void 0
749
+ };
750
+ states.set(this, this.#state);
751
+ initializeFragments(this.#state);
752
+ }
753
+ };
754
+ function handleFragments(item, remove) {
755
+ const state = isFragments(item) ? states.get(item) : item;
756
+ if (state != null) (remove ? removeFragments$1 : initializeFragments)(state);
757
+ }
758
+ function handleItems(state, items) {
759
+ const keys = /* @__PURE__ */ new Set();
760
+ const mapped = [];
761
+ const { length } = items;
762
+ for (let index = 0; index < length; index += 1) {
763
+ const item = items[index];
764
+ const identifier = state.identify(item);
765
+ if (identifier == null) throw new Error("Identifier cannot be null or undefined");
766
+ const key = getString$1(identifier);
767
+ if (keys.has(key)) throw new Error(`Duplicate identifier found: "${key}"`);
768
+ let instance = state.instances[key];
769
+ if (instance == null) {
770
+ instance = state.fragment(item);
771
+ if (!isFragment(instance)) throw new Error("Fragment function must return a Fragment instance");
772
+ }
773
+ instance.identify(key);
774
+ state.instances[key] = instance;
775
+ keys.add(key);
776
+ mapped.push(instance);
777
+ }
778
+ state.mapped.set(mapped);
779
+ updateFragments(state, keys);
780
+ }
781
+ function initializeFragments(state) {
782
+ state.subscriber ??= state.array.subscribe((items) => {
783
+ handleItems(state, items);
784
+ });
649
785
  }
650
-
786
+ function removeFragments$1(state) {
787
+ state.subscriber?.();
788
+ updateFragments(state);
789
+ state.subscriber = void 0;
790
+ }
791
+ function updateFragments(state, active) {
792
+ const next = {};
793
+ const previous = { ...state.instances };
794
+ const keys = Object.keys(previous);
795
+ const { length } = keys;
796
+ for (let index = 0; index < length; index += 1) {
797
+ const key = keys[index];
798
+ if (active?.has(key)) next[key] = previous[key];
799
+ else previous[key].remove();
800
+ }
801
+ state.instances = next;
802
+ active?.clear();
803
+ }
804
+ const states = /* @__PURE__ */ new WeakMap();
805
+ function isChildNode(value) {
806
+ return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
807
+ }
808
+ var CHILD_NODE_TYPES = new Set([
809
+ Node.ELEMENT_NODE,
810
+ Node.TEXT_NODE,
811
+ Node.PROCESSING_INSTRUCTION_NODE,
812
+ Node.COMMENT_NODE,
813
+ Node.DOCUMENT_TYPE_NODE
814
+ ]);
651
815
  function createNodes(value) {
652
- if (isFragment(value)) {
653
- return value.get();
654
- }
655
- if (isChildNode(value)) {
656
- return [value];
657
- }
658
- return [new Text(getString$1(value))];
816
+ if (isFragment(value)) return value.get();
817
+ if (isChildNode(value)) return [value];
818
+ return [new Text(getString$1(value))];
659
819
  }
660
820
  function removeNodes(nodes) {
661
- sanitizeNodes(nodes);
662
- const { length } = nodes;
663
- for (let index = 0; index < length; index += 1) {
664
- nodes[index].remove();
665
- }
821
+ const { length } = nodes;
822
+ for (let index = 0; index < length; index += 1) nodes[index].remove();
666
823
  }
667
824
  function replaceNodes(from, to) {
668
- from[0]?.replaceWith(...to);
669
- const { length } = from;
670
- for (let index = 1; index < length; index += 1) {
671
- from[index].remove();
672
- }
673
- }
674
- function sanitizeNodes(nodes) {
675
- const { length } = nodes;
676
- for (let index = 0; index < length; index += 1) {
677
- const node = nodes[index];
678
- if (isHTMLOrSVGElement(node)) {
679
- removeEvents(node);
680
- }
681
- if (node.hasChildNodes()) {
682
- sanitizeNodes([...node.childNodes]);
683
- }
684
- }
685
- }
686
-
825
+ from[0]?.replaceWith(...to);
826
+ const { length } = from;
827
+ for (let index = 1; index < length; index += 1) from[index].remove();
828
+ }
829
+ function getBoolean(value, defaultValue) {
830
+ return typeof value === "boolean" ? value : defaultValue ?? false;
831
+ }
832
+ function addDelegatedHandler(doc, type, name, passive) {
833
+ if (DELEGATED.has(name)) return;
834
+ DELEGATED.add(name);
835
+ doc.addEventListener(type, passive ? HANDLER_PASSIVE : HANDLER_ACTIVE, { passive });
836
+ }
837
+ function addDelegatedListener(target, type, name, listener, passive) {
838
+ target[name] ??= /* @__PURE__ */ new Set();
839
+ target[name].add(listener);
840
+ addDelegatedHandler(document, type, name, passive);
841
+ return () => {
842
+ removeDelegatedListener(target, name, listener);
843
+ };
844
+ }
845
+ function delegatedEventHandler(event) {
846
+ const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
847
+ const items = event.composedPath();
848
+ const { length } = items;
849
+ let target = items[0];
850
+ Object.defineProperties(event, {
851
+ currentTarget: {
852
+ configurable: true,
853
+ get() {
854
+ return target;
855
+ }
856
+ },
857
+ target: {
858
+ configurable: true,
859
+ value: target
860
+ }
861
+ });
862
+ for (let index = 0; index < length; index += 1) {
863
+ const item = items[index];
864
+ const listeners = item[key];
865
+ if (item.disabled || listeners == null) continue;
866
+ target = item;
867
+ for (const listener of listeners) {
868
+ listener.call(item, event);
869
+ if (event.cancelBubble) return;
870
+ }
871
+ }
872
+ }
873
+ function getDelegatedName(target, type, options) {
874
+ if (isEventTarget(target) && EVENT_TYPES.has(type) && !options.capture && !options.once && options.signal == null) return `${EVENT_PREFIX}${type}${options.passive ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
875
+ }
876
+ function removeDelegatedListener(target, name, listener) {
877
+ const handlers = target[name];
878
+ if (handlers == null || !handlers.has(listener)) return false;
879
+ handlers.delete(listener);
880
+ if (handlers.size === 0) target[name] = void 0;
881
+ return true;
882
+ }
883
+ var DELEGATED = /* @__PURE__ */ new Set();
884
+ var EVENT_PREFIX = "@";
885
+ var EVENT_SUFFIX_ACTIVE = ":active";
886
+ var EVENT_SUFFIX_PASSIVE = ":passive";
887
+ var EVENT_TYPES = new Set([
888
+ "beforeinput",
889
+ "click",
890
+ "dblclick",
891
+ "contextmenu",
892
+ "focusin",
893
+ "focusout",
894
+ "input",
895
+ "keydown",
896
+ "keyup",
897
+ "mousedown",
898
+ "mousemove",
899
+ "mouseout",
900
+ "mouseover",
901
+ "mouseup",
902
+ "pointerdown",
903
+ "pointermove",
904
+ "pointerout",
905
+ "pointerover",
906
+ "pointerup",
907
+ "touchend",
908
+ "touchmove",
909
+ "touchstart"
910
+ ]);
911
+ var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
912
+ var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
913
+ function noop() {}
914
+ function calculate() {
915
+ return new Promise((resolve) => {
916
+ const values = [];
917
+ let last;
918
+ function step(now) {
919
+ if (last != null) values.push(now - last);
920
+ last = now;
921
+ if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(CALCULATION_TRIM_PART, -CALCULATION_TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM_TOTAL));
922
+ else requestAnimationFrame(step);
923
+ }
924
+ requestAnimationFrame(step);
925
+ });
926
+ }
927
+ var CALCULATION_TOTAL = 10;
928
+ var CALCULATION_TRIM_PART = 2;
929
+ var CALCULATION_TRIM_TOTAL = 4;
930
+ calculate().then((value) => {});
931
+ function createEventOptions(options) {
932
+ return {
933
+ capture: getBoolean(options?.capture),
934
+ once: getBoolean(options?.once),
935
+ passive: getBoolean(options?.passive, true),
936
+ signal: options?.signal instanceof AbortSignal ? options.signal : void 0
937
+ };
938
+ }
939
+ function on(target, type, listener, options) {
940
+ if (!isEventTarget(target) || typeof type !== "string" || typeof listener !== "function") return noop;
941
+ const extended = createEventOptions(options);
942
+ const delegated = getDelegatedName(target, type, extended);
943
+ if (delegated != null) return addDelegatedListener(target, type, delegated, listener, extended.passive);
944
+ target.addEventListener(type, listener, extended);
945
+ if (extended.once) return noop;
946
+ return () => {
947
+ target.removeEventListener(type, listener, extended);
948
+ };
949
+ }
950
+ function getOptions(options) {
951
+ const parts = options.split(":");
952
+ return {
953
+ capture: parts.some((part) => EXPRESSION_EVENT_OPTIONS_CAPTURE.test(part)),
954
+ once: parts.some((part) => EXPRESSION_EVENT_OPTIONS_ONCE.test(part)),
955
+ passive: !parts.some((part) => EXPRESSION_EVENT_OPTIONS_ACTIVE.test(part))
956
+ };
957
+ }
958
+ function getType(element, type) {
959
+ if (type !== "on") return type;
960
+ if (element instanceof HTMLInputElement) {
961
+ if (EXPRESSION_EVENT_CHANGE_TYPES.test(element.type)) return "change";
962
+ return element.type === "submit" ? "submit" : "input";
963
+ }
964
+ return EVENT_DEFAULTS[element.tagName] ?? type;
965
+ }
966
+ function mapEvent(element, name, value) {
967
+ const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
968
+ if (type != null && typeof value === "function") on(element, getType(element, type), value, getOptions(options ?? ""));
969
+ }
970
+ function isBooleanAttribute(first) {
971
+ return _isBooleanAttribute(first, true);
972
+ }
973
+ function getCallback(element, name) {
974
+ if (isBooleanAttribute(name) && name in element) return name === "checked" ? updateChecked : updateProperty;
975
+ return name === "value" ? updateValue : setAttribute$1;
976
+ }
687
977
  function setAttribute(data, element, name, value) {
688
- element.removeAttribute(name);
689
- switch (true) {
690
- case EXPRESSION_ATTRIBUTE_CLASS.test(name):
691
- setClasses(data, element, name, value);
692
- return;
693
- case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
694
- setStyle(data, element, name, value);
695
- return;
696
- default:
697
- setValue(data, element, name, value);
698
- break;
699
- }
978
+ switch (true) {
979
+ case EXPRESSION_ATTRIBUTE_CLASS.test(name):
980
+ setClasses(data, element, name, value);
981
+ return;
982
+ case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
983
+ setStyle(data, element, name, value);
984
+ return;
985
+ default:
986
+ setValue(data, element, name, value);
987
+ break;
988
+ }
700
989
  }
701
990
  function setClasses(data, element, name, value) {
702
- function update(value) {
703
- if (value === true) {
704
- element.classList.add(...classes);
705
- }
706
- else {
707
- element.classList.remove(...classes);
708
- }
709
- }
710
- const classes = name.slice(ATTRIBUTE_CLASS_PREFIX_LENGTH).split('.');
711
- if (isReactive(value)) {
712
- data.mora.subscribers.add(value.subscribe(update));
713
- }
714
- else {
715
- update(value);
716
- }
991
+ function update(value$1) {
992
+ if (value$1 === true) element.classList.add(...classes);
993
+ else element.classList.remove(...classes);
994
+ }
995
+ const classes = name.slice(ATTRIBUTE_CLASS_PREFIX_LENGTH).split(".");
996
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
997
+ else update(value);
717
998
  }
718
999
  function setStyle(data, element, name, value) {
719
- const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
720
- if (property == null) {
721
- return;
722
- }
723
- function update(value) {
724
- if (value == null || value === false || (value === true && unit == null)) {
725
- element.style.removeProperty(property);
726
- }
727
- else {
728
- element.style.setProperty(property, value === true ? unit : getString$1(value));
729
- }
730
- }
731
- if (isReactive(value)) {
732
- data.mora.subscribers.add(value.subscribe(update));
733
- }
734
- else {
735
- update(value);
736
- }
1000
+ const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
1001
+ if (property == null) return;
1002
+ function update(value$1) {
1003
+ if (value$1 == null || value$1 === false || value$1 === true && unit == null) element.style.removeProperty(property);
1004
+ else element.style.setProperty(property, value$1 === true ? unit : String(value$1));
1005
+ }
1006
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
1007
+ else update(value);
737
1008
  }
738
1009
  function setValue(data, element, name, value) {
739
- let callback;
740
- if (isBooleanAttribute(name) && name in element) {
741
- callback = name === 'selected' ? updateSelected : updateProperty;
742
- }
743
- else {
744
- callback = setAttribute$1;
745
- }
746
- if (isReactive(value)) {
747
- data.mora.subscribers.add(value.subscribe(next => {
748
- callback(element, name, next);
749
- }));
750
- }
751
- else {
752
- callback(element, name, value);
753
- }
1010
+ const callback = getCallback(element, name);
1011
+ if (isReactive(value)) data.mora.subscribers.add(value.subscribe((next) => {
1012
+ callback(element, name, next);
1013
+ }));
1014
+ else callback(element, name, value);
1015
+ }
1016
+ function updateChecked(element, name, value) {
1017
+ updateElement("change", "checked", element, name, value, value === true);
1018
+ }
1019
+ function updateElement(event, property, element, name, value, next) {
1020
+ if (!(property in element) || element[property] === next) return;
1021
+ setAttribute$1(element, name, value);
1022
+ element[property] = next;
1023
+ element.dispatchEvent(new Event(event, { bubbles: true }));
754
1024
  }
755
1025
  function updateProperty(element, name, value) {
756
- element[name] = value === true;
1026
+ setProperty(element, name, value === true);
757
1027
  }
758
- function updateSelected(element, name, value) {
759
- const select = element.closest('select');
760
- const options = [...(select?.options ?? [])];
761
- if (select != null && options.includes(element)) {
762
- select.dispatchEvent(new Event('change', { bubbles: true }));
763
- }
764
- updateProperty(element, name, value);
1028
+ function updateValue(element, name, value) {
1029
+ updateElement(element instanceof HTMLSelectElement ? "change" : "input", "value", element, name, value, String(value));
765
1030
  }
766
-
767
1031
  function getValue(data, original) {
768
- const matches = EXPRESSION_COMMENT_FULL.exec(original ?? '');
769
- return matches == null ? original : data.values[+matches[1]];
1032
+ const matches = EXPRESSION_ABYDON_CONTENT.exec(original ?? "");
1033
+ return matches == null ? original : data.values[+matches[1]];
770
1034
  }
771
1035
  function mapAttributes(data, element) {
772
- const attributes = [...element.attributes];
773
- const { length } = attributes;
774
- for (let index = 0; index < length; index += 1) {
775
- const { name, value } = attributes[index];
776
- const actual = getValue(data, value);
777
- switch (true) {
778
- case name.startsWith('@'):
779
- mapEvent(element, name, actual);
780
- break;
781
- case name.includes('.') ||
782
- typeof actual === 'function' ||
783
- isReactive(actual):
784
- mapValue$1(data, element, name, actual);
785
- break;
786
- case isBooleanAttribute(name):
787
- setProperty(element, name, value);
788
- break;
789
- }
790
- }
1036
+ const attributes = [...element.attributes];
1037
+ const { length } = attributes;
1038
+ for (let index = 0; index < length; index += 1) {
1039
+ const { name, value } = attributes[index];
1040
+ const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, "");
1041
+ const actualValue = getValue(data, value);
1042
+ if (actualName !== name) element.removeAttribute(name);
1043
+ switch (true) {
1044
+ case EXPRESSION_EVENT_PREFIX.test(actualName):
1045
+ mapEvent(element, actualName, actualValue);
1046
+ break;
1047
+ case EXPRESSION_PERIOD.test(actualName):
1048
+ case typeof actualValue === "function":
1049
+ case isReactive(actualValue):
1050
+ mapValue$1(data, element, actualName, actualValue);
1051
+ break;
1052
+ default: break;
1053
+ }
1054
+ }
791
1055
  }
792
1056
  function mapValue$1(data, element, name, value) {
793
- if (typeof value === 'function') {
794
- setComputedAttribute(data, element, name, value);
795
- }
796
- else {
797
- setAttribute(data, element, name, value);
798
- }
1057
+ if (typeof value === "function") setComputedAttribute(data, element, name, value);
1058
+ else setAttribute(data, element, name, value);
799
1059
  }
800
1060
  function setComputedAttribute(data, element, name, callback) {
801
- const value = computed(callback);
802
- data.mora.values.add(value);
803
- setAttribute(data, element, name, value);
1061
+ const value = computed(callback);
1062
+ data.mora.values.add(value);
1063
+ setAttribute(data, element, name, value);
804
1064
  }
805
-
806
- //
807
1065
  function addToArray(identifiers, items, nodes, added) {
808
- let position = nodes[0];
809
- const before = added && !identifiers.previous.includes(items.templates[0].identifier);
810
- const next = items.next.flatMap(fragment => fragment.get().flatMap(node => ({
811
- identifier: fragment.identifier,
812
- value: node,
813
- })));
814
- const { length } = next;
815
- for (let index = 0; index < length; index += 1) {
816
- const node = next[index];
817
- if (!(added && identifiers.previous.includes(node.identifier))) {
818
- if (index === 0 && before) {
819
- position.before(node.value);
820
- }
821
- else {
822
- position.after(node.value);
823
- }
824
- }
825
- position = node.value;
826
- }
1066
+ let position = nodes[0];
1067
+ const before = added && !identifiers.previous.has(items.templates[0].identifier);
1068
+ const next = items.next.flatMap((fragment) => fragment.get().flatMap((node) => ({
1069
+ identifier: fragment.identifier,
1070
+ value: node
1071
+ })));
1072
+ const { length } = next;
1073
+ for (let index = 0; index < length; index += 1) {
1074
+ const node = next[index];
1075
+ if (!(added && identifiers.previous.has(node.identifier))) if (index === 0 && before) position.before(node.value);
1076
+ else position.after(node.value);
1077
+ position = node.value;
1078
+ }
827
1079
  }
828
1080
  function handleArray(identifiers, items, nodes) {
829
- const next = items.templates.map(template => items.fragments?.find(fragment => fragment.identifier === template.identifier) ?? template);
830
- const comparison = compareArrays(items.fragments ?? [], items.templates);
831
- if (comparison !== 'removed') {
832
- addToArray(identifiers, { ...items, next }, nodes, comparison === 'added');
833
- }
834
- const toRemove = items.fragments?.filter(fragment => !identifiers.next.includes(fragment.identifier)) ?? [];
835
- const { length } = toRemove;
836
- for (let index = 0; index < length; index += 1) {
837
- toRemove[index].remove();
838
- }
839
- return {
840
- fragments: next,
841
- nodes: next.flatMap(fragment => fragment.get()),
842
- };
843
- }
844
- function removeFragments(fragments) {
845
- if (fragments != null) {
846
- const { length } = fragments;
847
- for (let index = 0; index < length; index += 1) {
848
- fragments[index].remove();
849
- }
850
- }
1081
+ const next = items.templates.map((template) => items.fragments?.find((fragment) => fragment.identifier === template.identifier) ?? template);
1082
+ const comparison = compareArrays(items.fragments ?? [], items.templates);
1083
+ if (comparison !== "removed") addToArray(identifiers, {
1084
+ ...items,
1085
+ next
1086
+ }, nodes, comparison === "added");
1087
+ const toRemove = items.fragments?.filter((fragment) => !identifiers.next.has(fragment.identifier)) ?? [];
1088
+ const { length } = toRemove;
1089
+ for (let index = 0; index < length; index += 1) toRemove[index].remove();
1090
+ return {
1091
+ fragments: next,
1092
+ nodes: next.flatMap((fragment) => fragment.get())
1093
+ };
1094
+ }
1095
+ function removeFragments(fragments$1) {
1096
+ if (fragments$1 != null) {
1097
+ const { length } = fragments$1;
1098
+ for (let index = 0; index < length; index += 1) fragments$1[index].remove();
1099
+ }
1100
+ }
1101
+ function replaceText(item, comment, isNullable) {
1102
+ let to;
1103
+ if (isNullable) to = [comment];
1104
+ else to = item.text == null ? [] : [item.text];
1105
+ replaceNodes(item.nodes ?? [], to);
851
1106
  }
852
1107
  function setArray(item, comment, value) {
853
- if (value.length === 0) {
854
- return {
855
- nodes: setText(item, comment, value),
856
- };
857
- }
858
- let templates = value.filter(item => isFragment(item) && item.identifier != null);
859
- const next = templates.map(fragment => fragment.identifier);
860
- const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
861
- if (new Set(next).size !== templates.length) {
862
- templates = [];
863
- }
864
- const noTemplates = templates.length === 0;
865
- if (noTemplates ||
866
- item.nodes == null ||
867
- previous.some(identifier => identifier == null)) {
868
- return {
869
- fragments: noTemplates ? undefined : templates,
870
- nodes: setNodes(item, comment, noTemplates
871
- ? value.flatMap(item => createNodes(item))
872
- : templates.flatMap(template => template.get())),
873
- };
874
- }
875
- return handleArray({
876
- next,
877
- previous,
878
- }, {
879
- templates,
880
- fragments: item.fragments ?? [],
881
- }, item.nodes);
1108
+ if (value.length === 0) return { nodes: setText(item, comment, value) };
1109
+ let templates$1 = value.filter((item$1) => isFragment(item$1) && item$1.identifier != null);
1110
+ const next = templates$1.map((fragment) => fragment.identifier);
1111
+ const previous = item.fragments?.map((fragment) => fragment.identifier) ?? [];
1112
+ if (new Set(next).size !== templates$1.length) templates$1 = [];
1113
+ const noTemplates = templates$1.length === 0;
1114
+ if (noTemplates || item.nodes == null || previous.some((identifier) => identifier == null)) return {
1115
+ fragments: noTemplates ? void 0 : templates$1,
1116
+ nodes: setNodes(item, comment, noTemplates ? value.flatMap((item$1) => createNodes(item$1)) : templates$1.flatMap((template) => template.get()))
1117
+ };
1118
+ return handleArray({
1119
+ next: new Set(next),
1120
+ previous: new Set(previous)
1121
+ }, {
1122
+ templates: templates$1,
1123
+ fragments: item.fragments ?? []
1124
+ }, item.nodes);
882
1125
  }
883
1126
  function setNodes(item, comment, next) {
884
- if (item.nodes == null) {
885
- if (comment.parentNode != null) {
886
- replaceNodes([comment], next);
887
- }
888
- else if (item.text?.parentNode != null) {
889
- replaceNodes([item.text], next);
890
- }
891
- }
892
- else {
893
- replaceNodes(item.nodes, next);
894
- }
895
- removeFragments(item.fragments);
896
- return next;
1127
+ if (item.nodes == null) {
1128
+ if (comment.parentNode != null) replaceNodes([comment], next);
1129
+ else if (item.text?.parentNode != null) replaceNodes([item.text], next);
1130
+ } else replaceNodes(item.nodes, next);
1131
+ removeFragments(item.fragments);
1132
+ return next;
897
1133
  }
898
1134
  function setReactiveValue(data, comment, reactive) {
899
- let item = data.items.find(item => item.nodes?.includes(comment));
900
- item ??= {};
901
- item.text = new Text();
902
- data.mora.subscribers.add(reactive.subscribe(value => {
903
- if (Array.isArray(value)) {
904
- setReactiveValueForArray(item, comment, value);
905
- }
906
- else {
907
- setReactiveValueForSingle(item, comment, value);
908
- }
909
- item.nodes = [...(item.nodes ?? [comment])];
910
- }));
1135
+ let item = data.items.find((item$1) => item$1.nodes?.includes(comment));
1136
+ item ??= {};
1137
+ item.text = new Text();
1138
+ data.mora.subscribers.add(reactive.subscribe((value) => {
1139
+ if (Array.isArray(value)) setReactiveValueForArray(item, comment, value);
1140
+ else setReactiveValueForSingle(item, comment, value);
1141
+ item.nodes = [...item.nodes ?? [comment]];
1142
+ }));
911
1143
  }
912
1144
  function setReactiveValueForArray(item, comment, value) {
913
- const result = setArray(item, comment, value);
914
- item.fragments = typeof result === 'boolean' ? undefined : result?.fragments;
915
- if (typeof result === 'boolean') {
916
- item.nodes = result ? item.text == null ? [] : [item.text] : undefined;
917
- }
918
- else {
919
- item.nodes = result?.nodes;
920
- }
1145
+ const result = setArray(item, comment, value);
1146
+ item.fragments = typeof result === "boolean" ? void 0 : result?.fragments;
1147
+ if (typeof result === "boolean") if (result) item.nodes = item.text == null ? [] : [item.text];
1148
+ else item.nodes = void 0;
1149
+ else item.nodes = result?.nodes;
921
1150
  }
922
1151
  function setReactiveValueForSingle(item, comment, value) {
923
- const valueIsFragment = isFragment(value);
924
- item.fragments = valueIsFragment ? [value] : undefined;
925
- if (valueIsFragment || isChildNode(value)) {
926
- item.nodes = setNodes(item, comment, createNodes(value));
927
- }
928
- else {
929
- item.nodes = setText(item, comment, value);
930
- }
1152
+ const valueIsFragment = isFragment(value);
1153
+ item.fragments = valueIsFragment ? [value] : void 0;
1154
+ if (valueIsFragment || isChildNode(value)) item.nodes = setNodes(item, comment, createNodes(value));
1155
+ else item.nodes = setText(item, comment, value);
931
1156
  }
932
1157
  function setText(item, comment, value) {
933
- const isNullable = isNullableOrWhitespace(value);
934
- if (item.text != null) {
935
- item.text.textContent = isNullable ? '' : getString$1(value);
936
- }
937
- let result = false;
938
- if (item.nodes != null) {
939
- replaceNodes(item.nodes, isNullable ? [comment] : item.text == null ? [] : [item.text]);
940
- result = !isNullable;
941
- }
942
- else if (isNullable && comment.parentNode == null) {
943
- item.text?.replaceWith(comment);
944
- }
945
- else if (!isNullable && item?.text?.parentNode == null) {
946
- if (item.text != null) {
947
- comment.replaceWith(item.text);
948
- }
949
- result = true;
950
- }
951
- removeFragments(item.fragments);
952
- return result ? item.text == null ? [] : [item.text] : undefined;
953
- }
954
-
1158
+ const isNullable = isNullableOrWhitespace(value);
1159
+ if (item.text != null) item.text.textContent = isNullable ? "" : getString$1(value);
1160
+ let result = false;
1161
+ if (item.nodes != null) {
1162
+ replaceText(item, comment, isNullable);
1163
+ result = !isNullable;
1164
+ } else if (isNullable && comment.parentNode == null) item.text?.replaceWith(comment);
1165
+ else if (!isNullable && item?.text?.parentNode == null) {
1166
+ if (item.text != null) comment.replaceWith(item.text);
1167
+ result = true;
1168
+ }
1169
+ removeFragments(item.fragments);
1170
+ if (result) return item.text == null ? [] : [item.text];
1171
+ }
955
1172
  function mapNode(data, comment) {
956
- const matches = EXPRESSION_COMMENT_CONTENT.exec(comment.textContent ?? '');
957
- const value = matches == null ? null : data.values[+matches[1]];
958
- if (value != null) {
959
- mapValue(data, comment, value);
960
- }
1173
+ const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent ?? "");
1174
+ const value = matches == null ? null : data.values[+matches[1]];
1175
+ if (value != null) mapValue(data, comment, value);
961
1176
  }
962
1177
  function mapNodes(data, nodes) {
963
- const { length } = nodes;
964
- for (let index = 0; index < length; index += 1) {
965
- const node = nodes[index];
966
- if (node instanceof Comment) {
967
- mapNode(data, node);
968
- continue;
969
- }
970
- if (isHTMLOrSVGElement(node)) {
971
- mapAttributes(data, node);
972
- }
973
- if (node.hasChildNodes()) {
974
- mapNodes(data, [...node.childNodes]);
975
- }
976
- }
1178
+ const { length } = nodes;
1179
+ for (let index = 0; index < length; index += 1) {
1180
+ const node = nodes[index];
1181
+ if (node instanceof Comment) {
1182
+ mapNode(data, node);
1183
+ continue;
1184
+ }
1185
+ if (isHTMLOrSVGElement(node)) mapAttributes(data, node);
1186
+ if (node.hasChildNodes()) mapNodes(data, [...node.childNodes]);
1187
+ }
977
1188
  }
978
1189
  function mapValue(data, comment, value) {
979
- switch (true) {
980
- case typeof value === 'function':
981
- setComputedValue(data, comment, value);
982
- break;
983
- case isReactive(value):
984
- setReactiveValue(data, comment, value);
985
- break;
986
- default:
987
- replaceComment(data, comment, value);
988
- break;
989
- }
1190
+ switch (true) {
1191
+ case typeof value === "function":
1192
+ setComputedValue(data, comment, value);
1193
+ break;
1194
+ case isFragments(value):
1195
+ handleFragments(value, false);
1196
+ setReactiveValue(data, comment, value.items);
1197
+ break;
1198
+ case isReactive(value):
1199
+ setReactiveValue(data, comment, value);
1200
+ break;
1201
+ default:
1202
+ replaceComment(data, comment, value);
1203
+ break;
1204
+ }
990
1205
  }
991
1206
  function replaceComment(data, comment, value) {
992
- const item = data.items.find(item => item.nodes?.includes(comment));
993
- const nodes = createNodes(value);
994
- if (item != null) {
995
- item.fragments = isFragment(value) ? [value] : undefined;
996
- item.nodes = nodes;
997
- }
998
- comment.replaceWith(...nodes);
1207
+ const item = data.items.find((item$1) => item$1.nodes?.includes(comment));
1208
+ const nodes = createNodes(value);
1209
+ if (item != null) {
1210
+ item.fragments = isFragment(value) ? [value] : void 0;
1211
+ item.nodes = nodes;
1212
+ }
1213
+ comment.replaceWith(...nodes);
999
1214
  }
1000
1215
  function setComputedValue(data, comment, callback) {
1001
- const value = computed(callback);
1002
- data.mora.values.add(value);
1003
- setReactiveValue(data, comment, value);
1216
+ const value = computed(callback);
1217
+ data.mora.values.add(value);
1218
+ setReactiveValue(data, comment, value);
1004
1219
  }
1005
-
1006
1220
  function handleExpression(data, prefix, expression) {
1007
- if (Array.isArray(expression)) {
1008
- const { length } = expression;
1009
- let expressions = '';
1010
- for (let index = 0; index < length; index += 1) {
1011
- expressions += handleExpression(data, '', expression[index]);
1012
- }
1013
- return `${prefix}${expressions}`;
1014
- }
1015
- if (typeof expression === 'function' ||
1016
- (typeof expression === 'object' && expression != null)) {
1017
- const index = data.values.push(expression) - 1;
1018
- return `${prefix}<!--abydon.${index}-->`;
1019
- }
1020
- return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
1221
+ if (Array.isArray(expression)) {
1222
+ const { length } = expression;
1223
+ let expressions = "";
1224
+ for (let index = 0; index < length; index += 1) expressions += handleExpression(data, "", expression[index]);
1225
+ return `${prefix}${expressions}`;
1226
+ }
1227
+ if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
1228
+ return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
1021
1229
  }
1022
1230
  function parse(data) {
1023
- if (data.template != null) {
1024
- return data.template;
1025
- }
1026
- const { length } = data.strings;
1027
- data.template = '';
1028
- for (let index = 0; index < length; index += 1) {
1029
- data.template += handleExpression(data, data.strings[index], data.expressions[index]);
1030
- }
1031
- data.expressions = [];
1032
- data.strings = [];
1033
- return data.template;
1034
- }
1035
-
1036
- function calculate() {
1037
- return new Promise((resolve) => {
1038
- const values = [];
1039
- let last;
1040
- function step(now) {
1041
- if (last != null) values.push(now - last);
1042
- last = now;
1043
- if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM));
1044
- else requestAnimationFrame(step);
1231
+ if (data.template != null) return data.template;
1232
+ const { length } = data.strings;
1233
+ data.template = "";
1234
+ for (let index = 0; index < length; index += 1) data.template += handleExpression(data, data.strings[index], data.expressions[index]);
1235
+ data.template = data.template.replaceAll(EXPRESSION_ABYDON_ATTRIBUTE_FULL, transformAttribute);
1236
+ data.expressions = [];
1237
+ data.strings = [];
1238
+ return data.template;
1239
+ }
1240
+ function transformAttribute(_, name, index) {
1241
+ return `_${name}="@abydon.${index}@"`;
1242
+ }
1243
+ function transformExpression(prefix, index) {
1244
+ return `${prefix}<!--abydon.${index}-->`;
1245
+ }
1246
+ var Fragment = class {
1247
+ #data;
1248
+ #configuration = {
1249
+ identifier: void 0,
1250
+ cache: true
1251
+ };
1252
+ get identifier() {
1253
+ return this.#configuration.identifier;
1254
+ }
1255
+ constructor(strings, expressions) {
1256
+ Object.defineProperty(this, NAME_FRAGMENT, { value: true });
1257
+ this.#data = {
1258
+ expressions,
1259
+ strings,
1260
+ items: [],
1261
+ mora: {
1262
+ subscribers: /* @__PURE__ */ new Set(),
1263
+ values: /* @__PURE__ */ new Set()
1264
+ },
1265
+ values: []
1266
+ };
1267
+ }
1268
+ appendTo(element) {
1269
+ element.append(...this.get());
1270
+ }
1271
+ configure(configuration) {
1272
+ const actual = isPlainObject$1(configuration) ? configuration : {};
1273
+ if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
1274
+ if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
1275
+ return this;
1276
+ }
1277
+ get() {
1278
+ const data = this.#data;
1279
+ if (data.items.length === 0) {
1280
+ const templated = html$1(parse(data), { cache: this.#configuration.cache });
1281
+ data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
1282
+ mapNodes(data, data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []));
1045
1283
  }
1046
- requestAnimationFrame(step);
1047
- });
1048
- }
1049
- var CALCULATION_TOTAL = 10;
1050
- var CALCULATION_TRIM = 4;
1051
- calculate().then((value) => {
1052
- });
1053
-
1054
- class Fragment {
1055
- #data;
1056
- #configuration = {
1057
- identifier: undefined,
1058
- ignoreCache: false,
1059
- };
1060
- get identifier() {
1061
- return this.#configuration.identifier;
1062
- }
1063
- constructor(strings, expressions) {
1064
- this.#data = {
1065
- expressions,
1066
- strings,
1067
- items: [],
1068
- mora: {
1069
- subscribers: new Set(),
1070
- values: new Set(),
1071
- },
1072
- values: [],
1073
- };
1074
- Object.defineProperty(this, '$fragment', {
1075
- value: true,
1076
- });
1077
- }
1078
- /**
1079
- * Appends the fragment to the given element
1080
- */
1081
- appendTo(element) {
1082
- element.append(...this.get());
1083
- }
1084
- configure(configuration) {
1085
- const actual = isPlainObject$1(configuration) ? configuration : {};
1086
- if (actual.identifier !== undefined) {
1087
- this.#configuration.identifier = actual.identifier;
1088
- }
1089
- if (typeof actual.ignoreCache === 'boolean') {
1090
- this.#configuration.ignoreCache = actual.ignoreCache;
1091
- }
1092
- return this;
1093
- }
1094
- /**
1095
- * Gets a list of the fragment's nodes
1096
- */
1097
- get() {
1098
- const data = this.#data;
1099
- if (data.items.length === 0) {
1100
- const parsed = parse(data);
1101
- const templated = html$1(parsed, {
1102
- sanitizeBooleanAttributes: false,
1103
- });
1104
- if (this.#configuration.ignoreCache) {
1105
- html$1.remove(parsed);
1106
- }
1107
- data.items.splice(0, data.items.length, ...templated.map(node => ({
1108
- nodes: [node],
1109
- })));
1110
- mapNodes(data, data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes ?? []));
1111
- }
1112
- return [
1113
- ...data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes ?? []),
1114
- ];
1115
- }
1116
- identify(identifier) {
1117
- this.#configuration.identifier = identifier;
1118
- return this;
1119
- }
1120
- /**
1121
- * Removes the fragment from the DOM
1122
- */
1123
- remove() {
1124
- removeFragment(this.#data);
1125
- }
1126
- }
1284
+ return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []);
1285
+ }
1286
+ identify(identifier) {
1287
+ this.#configuration.identifier = identifier;
1288
+ return this;
1289
+ }
1290
+ remove() {
1291
+ removeFragment(this.#data);
1292
+ }
1293
+ };
1127
1294
  function removeFragment(data) {
1128
- removeMora(data);
1129
- const { length } = data.items;
1130
- for (let index = 0; index < length; index += 1) {
1131
- const { fragments, nodes } = data.items[index];
1132
- const length = fragments?.length ?? 0;
1133
- for (let index = 0; index < length; index += 1) {
1134
- fragments?.[index]?.remove();
1135
- }
1136
- removeNodes(nodes ?? []);
1137
- }
1138
- data.items.length = 0;
1295
+ removeMora(data);
1296
+ let { length } = data.items;
1297
+ for (let index = 0; index < length; index += 1) {
1298
+ const { fragments: fragments$1, nodes } = data.items[index];
1299
+ const fragmentsLength = fragments$1?.length ?? 0;
1300
+ for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) fragments$1?.[fragmentIndex]?.remove();
1301
+ removeNodes(nodes ?? []);
1302
+ }
1303
+ data.items.length = 0;
1304
+ length = data.values.length;
1305
+ for (let index = 0; index < length; index += 1) {
1306
+ const value = data.values[index];
1307
+ if (isFragments(value)) handleFragments(value, true);
1308
+ }
1139
1309
  }
1140
1310
  function removeMora(data) {
1141
- const unsubscribers = [...data.mora.subscribers];
1142
- data.mora.subscribers.clear();
1143
- data.mora.values.clear();
1144
- for (const unsubscribe of unsubscribers) {
1145
- unsubscribe();
1146
- }
1147
- }
1148
-
1149
- function html(strings, ...values) {
1150
- return new Fragment(strings, values);
1151
- }
1152
-
1153
- export { array, computed, effect, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
1311
+ const unsubscribers = [...data.mora.subscribers];
1312
+ data.mora.subscribers.clear();
1313
+ data.mora.values.clear();
1314
+ for (const unsubscribe$1 of unsubscribers) unsubscribe$1();
1315
+ }
1316
+ function fragments(array$1, identify, fragment) {
1317
+ return new Fragments(array$1, identify, fragment);
1318
+ }
1319
+ function html(template, ...values) {
1320
+ return new Fragment(template, values);
1321
+ }
1322
+ export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };