@oscarpalmer/abydon 0.20.0 → 0.22.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.
- package/README.md +2 -0
- package/dist/abydon.full.mjs +787 -276
- package/dist/attribute/index.d.mts +6 -0
- package/dist/{node/attribute → attribute}/index.mjs +10 -19
- package/dist/{node/attribute → attribute}/value.d.mts +2 -2
- package/dist/attribute/value.mjs +63 -0
- package/dist/constants.d.mts +7 -3
- package/dist/constants.mjs +12 -8
- package/dist/fragment.d.mts +45 -1
- package/dist/fragment.mjs +9 -3
- package/dist/fragments.d.mts +4 -6
- package/dist/fragments.mjs +5 -11
- package/dist/helpers/index.d.mts +11 -1
- package/dist/helpers/index.mjs +10 -0
- package/dist/index.d.mts +5 -4
- package/dist/index.mjs +8 -4
- package/dist/models.d.mts +43 -1
- package/dist/node/event.mjs +9 -4
- package/dist/node/index.d.mts +1 -1
- package/dist/node/index.mjs +19 -10
- package/dist/node/value.d.mts +1 -1
- package/dist/node/value.mjs +9 -12
- package/dist/parse.d.mts +1 -1
- package/dist/parse.mjs +6 -4
- package/package.json +8 -7
- package/src/{node/attribute → attribute}/index.ts +16 -33
- package/src/attribute/value.ts +140 -0
- package/src/constants.ts +16 -8
- package/src/fragment.ts +10 -5
- package/src/fragments.ts +4 -13
- package/src/helpers/index.ts +10 -0
- package/src/index.ts +16 -3
- package/src/node/event.ts +12 -5
- package/src/node/index.ts +31 -13
- package/src/node/value.ts +10 -25
- package/src/parse.ts +14 -4
- package/dist/fragment-9qTBAvtR.d.mts +0 -82
- package/dist/node/attribute/index.d.mts +0 -6
- package/dist/node/attribute/value.mjs +0 -65
- package/src/node/attribute/value.ts +0 -158
package/dist/abydon.full.mjs
CHANGED
|
@@ -156,6 +156,11 @@ function unsubscribe(state, callback) {
|
|
|
156
156
|
//#endregion
|
|
157
157
|
//#region node_modules/@oscarpalmer/mora/dist/value/reactive.mjs
|
|
158
158
|
var Reactive = class {
|
|
159
|
+
/**
|
|
160
|
+
* Internal state of the reactive value
|
|
161
|
+
*
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
159
164
|
state = {
|
|
160
165
|
computeds: /* @__PURE__ */ new Set(),
|
|
161
166
|
effects: /* @__PURE__ */ new Set(),
|
|
@@ -215,18 +220,10 @@ var Computed = class extends Reactive {
|
|
|
215
220
|
constructor(callback, options) {
|
|
216
221
|
super(NAME_COMPUTED, void 0, options);
|
|
217
222
|
this.effect.instance = effect(() => {
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const value = callback();
|
|
222
|
-
ACTIVE.computed = previousComputed;
|
|
223
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
224
|
-
this.state.value = value;
|
|
225
|
-
for (const computed of this.state.computeds) computed.effect.dirty = true;
|
|
226
|
-
for (const effect of this.state.effects) BATCH.handlers.add(effect);
|
|
227
|
-
for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
|
|
223
|
+
if (this.effect.dirty) {
|
|
224
|
+
setValue$2(this, this.state, callback);
|
|
225
|
+
this.effect.dirty = false;
|
|
228
226
|
}
|
|
229
|
-
this.effect.dirty = false;
|
|
230
227
|
});
|
|
231
228
|
}
|
|
232
229
|
/**
|
|
@@ -248,6 +245,72 @@ var Computed = class extends Reactive {
|
|
|
248
245
|
function computed(callback, options) {
|
|
249
246
|
return new Computed(callback, options);
|
|
250
247
|
}
|
|
248
|
+
function setAndEmit$1(state, value) {
|
|
249
|
+
if (state.equal(state.value, value)) return;
|
|
250
|
+
state.value = value;
|
|
251
|
+
for (const computed of state.computeds) computed.effect.dirty = true;
|
|
252
|
+
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
253
|
+
for (const [, subscription] of state.subscriptions) subscription.callback(value);
|
|
254
|
+
flushHandlers();
|
|
255
|
+
}
|
|
256
|
+
function setValue$2(instance, state, callback) {
|
|
257
|
+
const previousComputed = ACTIVE.computed;
|
|
258
|
+
ACTIVE.computed = instance;
|
|
259
|
+
try {
|
|
260
|
+
const value = callback();
|
|
261
|
+
if (value instanceof Promise) {
|
|
262
|
+
state.promise = value;
|
|
263
|
+
value.then((resolvedValue) => {
|
|
264
|
+
if (state.promise === value) {
|
|
265
|
+
state.promise = void 0;
|
|
266
|
+
setAndEmit$1(state, resolvedValue);
|
|
267
|
+
}
|
|
268
|
+
}).catch(() => {
|
|
269
|
+
if (state.promise === value) state.promise = void 0;
|
|
270
|
+
});
|
|
271
|
+
} else setAndEmit$1(state, value);
|
|
272
|
+
} finally {
|
|
273
|
+
ACTIVE.computed = previousComputed;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region node_modules/@oscarpalmer/mora/node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
278
|
+
/**
|
|
279
|
+
* Is the value a key?
|
|
280
|
+
* @param value Value to check
|
|
281
|
+
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
282
|
+
*/
|
|
283
|
+
function isKey(value) {
|
|
284
|
+
return typeof value === "number" || typeof value === "string";
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Is the value a plain object?
|
|
288
|
+
* @param value Value to check
|
|
289
|
+
* @returns `true` if the value is a plain object, otherwise `false`
|
|
290
|
+
*/
|
|
291
|
+
function isPlainObject$1(value) {
|
|
292
|
+
if (value === null || typeof value !== "object") return false;
|
|
293
|
+
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
294
|
+
const prototype = Object.getPrototypeOf(value);
|
|
295
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region node_modules/@oscarpalmer/mora/node_modules/@oscarpalmer/atoms/dist/math.mjs
|
|
299
|
+
/**
|
|
300
|
+
* Round a number
|
|
301
|
+
* @param value Number to round
|
|
302
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
303
|
+
* @returns Rounded number, or `NaN` if the value if unable to be rounded
|
|
304
|
+
*/
|
|
305
|
+
function round(value, decimals) {
|
|
306
|
+
return roundNumber(Math.round, value, decimals);
|
|
307
|
+
}
|
|
308
|
+
function roundNumber(callback, value, decimals) {
|
|
309
|
+
if (typeof value !== "number") return NaN;
|
|
310
|
+
if (typeof decimals !== "number" || decimals < 1) return callback(value);
|
|
311
|
+
const mod = 10 ** decimals;
|
|
312
|
+
return callback((value + Number.EPSILON) * mod) / mod;
|
|
313
|
+
}
|
|
251
314
|
//#endregion
|
|
252
315
|
//#region node_modules/@oscarpalmer/mora/dist/helpers/value.mjs
|
|
253
316
|
function emitValue(state) {
|
|
@@ -261,7 +324,7 @@ function equalArrays(state, first, second) {
|
|
|
261
324
|
if (length !== second.length) return false;
|
|
262
325
|
let offset = 0;
|
|
263
326
|
if (length >= 100) {
|
|
264
|
-
offset =
|
|
327
|
+
offset = round(length / 10);
|
|
265
328
|
offset = offset > 25 ? 25 : offset;
|
|
266
329
|
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
267
330
|
}
|
|
@@ -291,10 +354,7 @@ var Signal = class extends Reactive {
|
|
|
291
354
|
* @param value New value
|
|
292
355
|
*/
|
|
293
356
|
set(value) {
|
|
294
|
-
|
|
295
|
-
this.state.value = value;
|
|
296
|
-
emitValue(this.state);
|
|
297
|
-
}
|
|
357
|
+
setValue$1(this.state, value);
|
|
298
358
|
}
|
|
299
359
|
/**
|
|
300
360
|
* Update the value _(based on the current value)_
|
|
@@ -304,14 +364,33 @@ var Signal = class extends Reactive {
|
|
|
304
364
|
this.set(callback(this.state.value));
|
|
305
365
|
}
|
|
306
366
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
367
|
+
function setAndEmit(state, value) {
|
|
368
|
+
if (!state.equal(state.value, value)) {
|
|
369
|
+
state.value = value;
|
|
370
|
+
emitValue(state);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function setValue$1(state, value) {
|
|
374
|
+
try {
|
|
375
|
+
let actual = value;
|
|
376
|
+
if (typeof value === "function") actual = value();
|
|
377
|
+
if (actual instanceof Promise) {
|
|
378
|
+
state.promise = actual;
|
|
379
|
+
actual.then((value) => {
|
|
380
|
+
if (actual === state.promise) {
|
|
381
|
+
state.promise = void 0;
|
|
382
|
+
setAndEmit(state, value);
|
|
383
|
+
}
|
|
384
|
+
}).catch(() => {
|
|
385
|
+
if (actual === state.promise) state.promise = void 0;
|
|
386
|
+
});
|
|
387
|
+
} else setAndEmit(state, actual);
|
|
388
|
+
} catch {}
|
|
389
|
+
}
|
|
313
390
|
function signal(value, options) {
|
|
314
|
-
|
|
391
|
+
const instance = new Signal(void 0, options);
|
|
392
|
+
instance.set(value);
|
|
393
|
+
return instance;
|
|
315
394
|
}
|
|
316
395
|
//#endregion
|
|
317
396
|
//#region node_modules/@oscarpalmer/mora/dist/helpers/proxy.mjs
|
|
@@ -329,21 +408,44 @@ function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
|
329
408
|
}
|
|
330
409
|
return item;
|
|
331
410
|
}
|
|
332
|
-
function setProxyValue(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
let { length } = proxyKeys;
|
|
337
|
-
for (let index = 0; index < length; index += 1) {
|
|
338
|
-
const key = proxyKeys[index];
|
|
339
|
-
proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
|
|
411
|
+
function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
|
|
412
|
+
if (array && first === "length") {
|
|
413
|
+
state.value.length = second;
|
|
414
|
+
return;
|
|
340
415
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
if (!proxyKeys.includes(key)) proxy[key] = value[key];
|
|
416
|
+
if (isObject(first)) {
|
|
417
|
+
setObject(state, first);
|
|
418
|
+
return;
|
|
345
419
|
}
|
|
346
|
-
|
|
420
|
+
const property = isProperty(first);
|
|
421
|
+
if (array && property && Number.isNaN(first)) return;
|
|
422
|
+
let actual = property ? second : first;
|
|
423
|
+
if (typeof actual === "function") try {
|
|
424
|
+
actual = actual();
|
|
425
|
+
} catch {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (actual instanceof Promise) {
|
|
429
|
+
if (property) {
|
|
430
|
+
state.promises ??= /* @__PURE__ */ new Map();
|
|
431
|
+
state.promises.set(first, actual);
|
|
432
|
+
} else state.promise = actual;
|
|
433
|
+
actual.then((value) => {
|
|
434
|
+
if (property && state.promises.get(first) === actual) {
|
|
435
|
+
state.promises.delete(first);
|
|
436
|
+
setProperty(state, first, value);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
if (!property && isObject(value) && state.promise === actual) {
|
|
440
|
+
state.promise = void 0;
|
|
441
|
+
setObject(state, value);
|
|
442
|
+
}
|
|
443
|
+
}).catch(() => {
|
|
444
|
+
if (property && state.promises.get(first) === actual) state.promises.delete(first);
|
|
445
|
+
else if (!property && state.promise === actual) state.promise = void 0;
|
|
446
|
+
});
|
|
447
|
+
} else if (property) setProperty(state, first, actual);
|
|
448
|
+
else if (isObject(actual)) setObject(state, actual);
|
|
347
449
|
}
|
|
348
450
|
function setValueInProxy(parameters) {
|
|
349
451
|
const { isArray, length, property, state, target, value } = parameters;
|
|
@@ -426,7 +528,7 @@ var ReactiveArray = class extends Reactive {
|
|
|
426
528
|
}
|
|
427
529
|
peek(value) {
|
|
428
530
|
if (value === "length") return this.#size.peek();
|
|
429
|
-
return typeof value === "number" ? this.state.value.at(value) :
|
|
531
|
+
return typeof value === "number" ? this.state.value.at(value) : this.state.value.slice();
|
|
430
532
|
}
|
|
431
533
|
/**
|
|
432
534
|
* Remove and return the last item of the array
|
|
@@ -444,9 +546,7 @@ var ReactiveArray = class extends Reactive {
|
|
|
444
546
|
return this.state.value.push(...items);
|
|
445
547
|
}
|
|
446
548
|
set(first, second) {
|
|
447
|
-
|
|
448
|
-
else if (first === "length") this.length = second;
|
|
449
|
-
else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
|
|
549
|
+
setProxyValue(true, this.state, isArrayValue, isArrayIndex, setArray$1, setAtIndex, first, second);
|
|
450
550
|
}
|
|
451
551
|
/**
|
|
452
552
|
* Remove and return the first item of the array
|
|
@@ -486,18 +586,20 @@ var ReactiveArray = class extends Reactive {
|
|
|
486
586
|
if (updated == null || Array.isArray(updated)) this.set(updated);
|
|
487
587
|
}
|
|
488
588
|
};
|
|
489
|
-
/**
|
|
490
|
-
* Create a reactive array
|
|
491
|
-
* @param value Initial array of items
|
|
492
|
-
* @param options Reactivity options
|
|
493
|
-
* @returns Reactive array
|
|
494
|
-
*/
|
|
495
589
|
function array(value, options) {
|
|
496
|
-
|
|
590
|
+
const instance = new ReactiveArray([], options);
|
|
591
|
+
instance.set(value);
|
|
592
|
+
return instance;
|
|
593
|
+
}
|
|
594
|
+
function isArrayIndex(value) {
|
|
595
|
+
return typeof value === "number";
|
|
596
|
+
}
|
|
597
|
+
function isArrayValue(value) {
|
|
598
|
+
return value == null || Array.isArray(value);
|
|
497
599
|
}
|
|
498
600
|
function updateArray(type, array, state, length) {
|
|
499
601
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
500
|
-
const previousArray = affectsLength ? [] :
|
|
602
|
+
const previousArray = affectsLength ? [] : array.slice();
|
|
501
603
|
const previousLength = array.length;
|
|
502
604
|
return (...args) => {
|
|
503
605
|
const result = array[type](...args);
|
|
@@ -508,57 +610,13 @@ function updateArray(type, array, state, length) {
|
|
|
508
610
|
return result;
|
|
509
611
|
};
|
|
510
612
|
}
|
|
511
|
-
function
|
|
512
|
-
|
|
513
|
-
if (actual > -1) array[actual] = value;
|
|
514
|
-
}
|
|
515
|
-
//#endregion
|
|
516
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
517
|
-
/**
|
|
518
|
-
* Is the value a key?
|
|
519
|
-
* @param value Value to check
|
|
520
|
-
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
521
|
-
*/
|
|
522
|
-
function isKey(value) {
|
|
523
|
-
return typeof value === "number" || typeof value === "string";
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Is the value a plain object?
|
|
527
|
-
* @param value Value to check
|
|
528
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
529
|
-
*/
|
|
530
|
-
function isPlainObject(value) {
|
|
531
|
-
if (value === null || typeof value !== "object") return false;
|
|
532
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
533
|
-
const prototype = Object.getPrototypeOf(value);
|
|
534
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
535
|
-
}
|
|
536
|
-
//#endregion
|
|
537
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
|
|
538
|
-
/**
|
|
539
|
-
* Get the string value from any value
|
|
540
|
-
* @param value Original value
|
|
541
|
-
* @returns String representation of the value
|
|
542
|
-
*/
|
|
543
|
-
function getString(value) {
|
|
544
|
-
if (typeof value === "string") return value;
|
|
545
|
-
if (value == null) return "";
|
|
546
|
-
if (typeof value === "function") return getString(value());
|
|
547
|
-
if (typeof value !== "object") return String(value);
|
|
548
|
-
const asString = String(value.valueOf?.() ?? value);
|
|
549
|
-
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
613
|
+
function setArray$1(state, value) {
|
|
614
|
+
state.value.splice(0, state.value.length, ...value ?? []);
|
|
550
615
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
* Is the value `undefined`, `null`, or a whitespace-only string?
|
|
555
|
-
* @param value Value to check
|
|
556
|
-
* @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
|
|
557
|
-
*/
|
|
558
|
-
function isNullableOrWhitespace(value) {
|
|
559
|
-
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
616
|
+
function setAtIndex(state, index, value) {
|
|
617
|
+
const actual = index < 0 ? state.value.length + index : index;
|
|
618
|
+
if (actual > -1) state.value[actual] = value;
|
|
560
619
|
}
|
|
561
|
-
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
562
620
|
//#endregion
|
|
563
621
|
//#region node_modules/@oscarpalmer/mora/dist/value/store.mjs
|
|
564
622
|
var Store = class extends Reactive {
|
|
@@ -588,8 +646,7 @@ var Store = class extends Reactive {
|
|
|
588
646
|
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
589
647
|
}
|
|
590
648
|
set(first, second) {
|
|
591
|
-
|
|
592
|
-
else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
|
|
649
|
+
setProxyValue(false, this.state, isStoreObject, isKey, setObject, setProperty, first, second);
|
|
593
650
|
}
|
|
594
651
|
subscribe(first, second) {
|
|
595
652
|
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
@@ -600,19 +657,114 @@ var Store = class extends Reactive {
|
|
|
600
657
|
* @param callback Callback to update the value
|
|
601
658
|
*/
|
|
602
659
|
update(callback) {
|
|
603
|
-
const updated = callback(
|
|
604
|
-
if (updated == null || isPlainObject(updated))
|
|
660
|
+
const updated = callback(this.state.value);
|
|
661
|
+
if (updated == null || isPlainObject$1(updated)) setObject(this.state, updated);
|
|
605
662
|
}
|
|
606
663
|
};
|
|
664
|
+
function isStoreObject(value) {
|
|
665
|
+
return value == null || isPlainObject$1(value);
|
|
666
|
+
}
|
|
667
|
+
function setObject(state, value) {
|
|
668
|
+
startBatch();
|
|
669
|
+
const actual = value ?? {};
|
|
670
|
+
const proxy = state.value;
|
|
671
|
+
const proxyKeys = Object.keys(proxy);
|
|
672
|
+
const actualKeys = Object.keys(actual);
|
|
673
|
+
let { length } = proxyKeys;
|
|
674
|
+
for (let index = 0; index < length; index += 1) {
|
|
675
|
+
const key = proxyKeys[index];
|
|
676
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
|
|
677
|
+
}
|
|
678
|
+
length = actualKeys.length;
|
|
679
|
+
for (let index = 0; index < length; index += 1) {
|
|
680
|
+
const key = actualKeys[index];
|
|
681
|
+
if (!proxyKeys.includes(key)) proxy[key] = actual[key];
|
|
682
|
+
}
|
|
683
|
+
stopBatch();
|
|
684
|
+
}
|
|
685
|
+
function setProperty(state, key, value) {
|
|
686
|
+
state.value[key] = value;
|
|
687
|
+
}
|
|
688
|
+
function store(value, options) {
|
|
689
|
+
const instance = new Store({}, options);
|
|
690
|
+
instance.set(value);
|
|
691
|
+
return instance;
|
|
692
|
+
}
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
607
695
|
/**
|
|
608
|
-
*
|
|
609
|
-
* @param value
|
|
610
|
-
* @
|
|
611
|
-
* @returns Reactive store
|
|
696
|
+
* Is the value a number?
|
|
697
|
+
* @param value Value to check
|
|
698
|
+
* @returns `true` if the value is a `number`, otherwise `false`
|
|
612
699
|
*/
|
|
613
|
-
function
|
|
614
|
-
return
|
|
700
|
+
function isNumber(value) {
|
|
701
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
615
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* Is the value a plain object?
|
|
705
|
+
* @param value Value to check
|
|
706
|
+
* @returns `true` if the value is a plain object, otherwise `false`
|
|
707
|
+
*/
|
|
708
|
+
function isPlainObject(value) {
|
|
709
|
+
if (value === null || typeof value !== "object") return false;
|
|
710
|
+
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
711
|
+
const prototype = Object.getPrototypeOf(value);
|
|
712
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
713
|
+
}
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
|
|
716
|
+
/**
|
|
717
|
+
* Get the string value from any value
|
|
718
|
+
* @param value Original value
|
|
719
|
+
* @returns String representation of the value
|
|
720
|
+
*/
|
|
721
|
+
function getString(value) {
|
|
722
|
+
if (typeof value === "string") return value;
|
|
723
|
+
if (value == null) return "";
|
|
724
|
+
if (typeof value === "function") return getString(value());
|
|
725
|
+
if (typeof value !== "object") return String(value);
|
|
726
|
+
const asString = String(value.valueOf?.() ?? value);
|
|
727
|
+
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Join an array of values into a string _(while ignoring empty values)_
|
|
731
|
+
*
|
|
732
|
+
* _(`null`, `undefined`, and any values that become whitespace-only strings are considered empty)_
|
|
733
|
+
* @param array Array of values
|
|
734
|
+
* @param delimiter Delimiter to use between values
|
|
735
|
+
* @returns Joined string
|
|
736
|
+
*/
|
|
737
|
+
function join(array, delimiter) {
|
|
738
|
+
if (!Array.isArray(array)) return "";
|
|
739
|
+
const { length } = array;
|
|
740
|
+
if (length === 0) return "";
|
|
741
|
+
const values = [];
|
|
742
|
+
for (let index = 0; index < length; index += 1) {
|
|
743
|
+
const item = getString(array[index]);
|
|
744
|
+
if (item.trim().length > 0) values.push(item);
|
|
745
|
+
}
|
|
746
|
+
return values.join(typeof delimiter === "string" ? delimiter : "");
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Split a string into words _(and other readable parts)_
|
|
750
|
+
* @param value Original string
|
|
751
|
+
* @returns Array of words found in the string
|
|
752
|
+
*/
|
|
753
|
+
function words(value) {
|
|
754
|
+
return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
|
|
755
|
+
}
|
|
756
|
+
const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region node_modules/@oscarpalmer/atoms/dist/is.mjs
|
|
759
|
+
/**
|
|
760
|
+
* Is the value `undefined`, `null`, or stringified as a whitespace-only string?
|
|
761
|
+
* @param value Value to check
|
|
762
|
+
* @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
|
|
763
|
+
*/
|
|
764
|
+
function isNullableOrWhitespace(value) {
|
|
765
|
+
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
766
|
+
}
|
|
767
|
+
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
616
768
|
//#endregion
|
|
617
769
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
|
|
618
770
|
/**
|
|
@@ -649,16 +801,280 @@ const CHILD_NODE_TYPES = new Set([
|
|
|
649
801
|
Node.DOCUMENT_TYPE_NODE
|
|
650
802
|
]);
|
|
651
803
|
//#endregion
|
|
804
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
805
|
+
/**
|
|
806
|
+
* Clamp a number between a minimum and maximum value
|
|
807
|
+
* @param value Value to clamp
|
|
808
|
+
* @param minimum Minimum value
|
|
809
|
+
* @param maximum Maximum value
|
|
810
|
+
* @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
|
|
811
|
+
* @returns Clamped value
|
|
812
|
+
*/
|
|
813
|
+
function clamp(value, minimum, maximum, loop) {
|
|
814
|
+
if (![
|
|
815
|
+
value,
|
|
816
|
+
minimum,
|
|
817
|
+
maximum
|
|
818
|
+
].every(isNumber)) return NaN;
|
|
819
|
+
if (value < minimum) return loop === true ? maximum : minimum;
|
|
820
|
+
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
821
|
+
}
|
|
822
|
+
//#endregion
|
|
823
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/sized.mjs
|
|
824
|
+
function getSizedMaximum(first, second) {
|
|
825
|
+
let actual;
|
|
826
|
+
if (typeof first === "number") actual = first;
|
|
827
|
+
else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
|
|
828
|
+
return clamp(actual, 1, MAXIMUM_ABSOLUTE);
|
|
829
|
+
}
|
|
830
|
+
const MAXIMUM_ABSOLUTE = 16777216;
|
|
831
|
+
const MAXIMUM_DEFAULT = 1048576;
|
|
832
|
+
//#endregion
|
|
833
|
+
//#region node_modules/@oscarpalmer/atoms/dist/sized/map.mjs
|
|
834
|
+
/**
|
|
835
|
+
* A Map with a maximum size
|
|
836
|
+
*
|
|
837
|
+
* Behavior is similar to a _LRU_-cache, where the least recently used entries are removed
|
|
838
|
+
*/
|
|
839
|
+
var SizedMap = class extends Map {
|
|
840
|
+
/**
|
|
841
|
+
* The maximum size of the Map
|
|
842
|
+
*/
|
|
843
|
+
#maximumSize;
|
|
844
|
+
/**
|
|
845
|
+
* Is the Map full?
|
|
846
|
+
*/
|
|
847
|
+
get full() {
|
|
848
|
+
return super.size >= this.#maximumSize;
|
|
849
|
+
}
|
|
850
|
+
get maximum() {
|
|
851
|
+
return this.#maximumSize;
|
|
852
|
+
}
|
|
853
|
+
constructor(first, second) {
|
|
854
|
+
const maximum = getSizedMaximum(first, second);
|
|
855
|
+
super();
|
|
856
|
+
this.#maximumSize = maximum;
|
|
857
|
+
if (Array.isArray(first)) {
|
|
858
|
+
const { length } = first;
|
|
859
|
+
if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
|
|
860
|
+
else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* @inheritdoc
|
|
865
|
+
*/
|
|
866
|
+
get(key) {
|
|
867
|
+
if (super.has(key)) {
|
|
868
|
+
const value = super.get(key);
|
|
869
|
+
this.#setValue(key, value, true);
|
|
870
|
+
return value;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* @inheritdoc
|
|
875
|
+
*/
|
|
876
|
+
set(key, value) {
|
|
877
|
+
return this.#setValue(key, value, super.has(key));
|
|
878
|
+
}
|
|
879
|
+
#setValue(key, value, has) {
|
|
880
|
+
if (has) super.delete(key);
|
|
881
|
+
else if (super.size >= this.#maximumSize) super.delete(super.keys().next().value);
|
|
882
|
+
super.set(key, value);
|
|
883
|
+
return this;
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
//#endregion
|
|
887
|
+
//#region node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
|
|
888
|
+
/**
|
|
889
|
+
* A memoized function, caching and retrieving results based on the its parameters _(or a custom cache key)_
|
|
890
|
+
*/
|
|
891
|
+
var Memoized = class {
|
|
892
|
+
#state;
|
|
893
|
+
/**
|
|
894
|
+
* Maximum cache size
|
|
895
|
+
*/
|
|
896
|
+
get maximum() {
|
|
897
|
+
return this.#state.cache?.maximum ?? NaN;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Current cache size
|
|
901
|
+
*/
|
|
902
|
+
get size() {
|
|
903
|
+
return this.#state.cache?.size ?? NaN;
|
|
904
|
+
}
|
|
905
|
+
constructor(callback, options) {
|
|
906
|
+
const cache = new SizedMap(options.cacheSize);
|
|
907
|
+
const getter = (...parameters) => {
|
|
908
|
+
const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), SEPARATOR));
|
|
909
|
+
if (cache.has(key)) return cache.get(key);
|
|
910
|
+
const value = callback(...parameters);
|
|
911
|
+
cache.set(key, value);
|
|
912
|
+
return value;
|
|
913
|
+
};
|
|
914
|
+
this.#state = {
|
|
915
|
+
cache,
|
|
916
|
+
getter
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Clear the cache
|
|
921
|
+
*/
|
|
922
|
+
clear() {
|
|
923
|
+
this.#state.cache?.clear();
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Delete a result from the cache
|
|
927
|
+
* @param key Key to delete
|
|
928
|
+
* @returns `true` if the key existed and was removed, otherwise `false`
|
|
929
|
+
*/
|
|
930
|
+
delete(key) {
|
|
931
|
+
return this.#state.cache?.delete(key) ?? false;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Destroy the instance _(clearing its cache and removing its callback)_
|
|
935
|
+
*/
|
|
936
|
+
destroy() {
|
|
937
|
+
this.#state.cache?.clear();
|
|
938
|
+
this.#state.cache = void 0;
|
|
939
|
+
this.#state.getter = void 0;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Get a result from the cache
|
|
943
|
+
* @param key Key to get
|
|
944
|
+
* @returns Cached result or `undefined` if it does not exist
|
|
945
|
+
*/
|
|
946
|
+
get(key) {
|
|
947
|
+
return this.#state.cache?.get(key);
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Does the result exist?
|
|
951
|
+
* @param key Key to check
|
|
952
|
+
* @returns `true` if the result exists, otherwise `false`
|
|
953
|
+
*/
|
|
954
|
+
has(key) {
|
|
955
|
+
return this.#state.cache?.has(key) ?? false;
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Run the callback with the provided parameters
|
|
959
|
+
* @param parameters Parameters to pass to the callback
|
|
960
|
+
* @returns Cached or computed _(then cached)_ result
|
|
961
|
+
*/
|
|
962
|
+
run(...parameters) {
|
|
963
|
+
if (this.#state.cache == null || this.#state.getter == null) throw new Error("The Memoized instance has been destroyed");
|
|
964
|
+
return this.#state.getter(...parameters);
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
function getMemoizationOptions(input) {
|
|
968
|
+
const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
|
|
969
|
+
return {
|
|
970
|
+
cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
|
|
971
|
+
cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Memoize a function, caching and retrieving results based on the first parameter
|
|
976
|
+
* @param callback Callback to memoize
|
|
977
|
+
* @param options Memoization options
|
|
978
|
+
* @returns Memoized instance
|
|
979
|
+
*/
|
|
980
|
+
function memoize(callback, options) {
|
|
981
|
+
return new Memoized(callback, getMemoizationOptions(options));
|
|
982
|
+
}
|
|
983
|
+
const DEFAULT_CACHE_SIZE = 1024;
|
|
984
|
+
const SEPARATOR = "_";
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region node_modules/@oscarpalmer/atoms/dist/string/case.mjs
|
|
987
|
+
/**
|
|
988
|
+
* Convert a string to camel case _(thisIsCamelCase)_
|
|
989
|
+
* @param value String to convert
|
|
990
|
+
* @returns Camel-cased string
|
|
991
|
+
*/
|
|
992
|
+
function camelCase(value) {
|
|
993
|
+
return toCase(CASE_CAMEL, value, true, false);
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Capitalize the first letter of a string _(and lowercase the rest)_
|
|
997
|
+
* @param value String to capitalize
|
|
998
|
+
* @returns Capitalized string
|
|
999
|
+
*/
|
|
1000
|
+
function capitalize(value) {
|
|
1001
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
1002
|
+
memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
|
|
1003
|
+
return memoizedCapitalize.run(value);
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Convert a string to kebab case _(this-is-kebab-case)_
|
|
1007
|
+
* @param value String to convert
|
|
1008
|
+
* @returns Kebab-cased string
|
|
1009
|
+
*/
|
|
1010
|
+
function kebabCase(value) {
|
|
1011
|
+
return toCase(CASE_KEBAB, value, false, false);
|
|
1012
|
+
}
|
|
1013
|
+
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
1014
|
+
caseMemoizers[type] ??= memoize(toCaseCallback.bind({
|
|
1015
|
+
type,
|
|
1016
|
+
capitalizeAny,
|
|
1017
|
+
capitalizeFirst
|
|
1018
|
+
}));
|
|
1019
|
+
return caseMemoizers[type].run(value);
|
|
1020
|
+
}
|
|
1021
|
+
function toCaseCallback(value) {
|
|
1022
|
+
if (typeof value !== "string") return "";
|
|
1023
|
+
if (value.length < 1) return value;
|
|
1024
|
+
const { capitalizeAny, capitalizeFirst, type } = this;
|
|
1025
|
+
const parts = words(value);
|
|
1026
|
+
const partsLength = parts.length;
|
|
1027
|
+
const cased = [];
|
|
1028
|
+
for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
|
|
1029
|
+
const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === S ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
|
|
1030
|
+
const itemsLength = items.length;
|
|
1031
|
+
const partResult = [];
|
|
1032
|
+
let itemCount = 0;
|
|
1033
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
1034
|
+
const item = items[itemIndex];
|
|
1035
|
+
if (item.length === 0) continue;
|
|
1036
|
+
if (!capitalizeAny || itemCount === 0 && partIndex === 0 && !capitalizeFirst) partResult.push(item.toLocaleLowerCase());
|
|
1037
|
+
else partResult.push(capitalize(item));
|
|
1038
|
+
itemCount += 1;
|
|
1039
|
+
}
|
|
1040
|
+
cased.push(join(partResult, delimiters[type]));
|
|
1041
|
+
}
|
|
1042
|
+
return join(cased, delimiters[type]);
|
|
1043
|
+
}
|
|
1044
|
+
const CASE_CAMEL = "camel";
|
|
1045
|
+
const CASE_KEBAB = "kebab";
|
|
1046
|
+
const CASE_PASCAL = "pascal";
|
|
1047
|
+
const CASE_SNAKE = "snake";
|
|
1048
|
+
const DELIMTER_EMPTY = "";
|
|
1049
|
+
const DELIMITER_HYPHEN = "-";
|
|
1050
|
+
const DELIMITER_UNDERSCORE = "_";
|
|
1051
|
+
const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
|
|
1052
|
+
const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
|
|
1053
|
+
const REPLACEMENT_CAMEL_CASE = "$1-$2";
|
|
1054
|
+
const S = "s";
|
|
1055
|
+
const caseMemoizers = {};
|
|
1056
|
+
const delimiters = {
|
|
1057
|
+
[CASE_CAMEL]: DELIMTER_EMPTY,
|
|
1058
|
+
[CASE_KEBAB]: DELIMITER_HYPHEN,
|
|
1059
|
+
[CASE_PASCAL]: DELIMTER_EMPTY,
|
|
1060
|
+
[CASE_SNAKE]: DELIMITER_UNDERSCORE
|
|
1061
|
+
};
|
|
1062
|
+
let memoizedCapitalize;
|
|
1063
|
+
//#endregion
|
|
652
1064
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
|
|
653
|
-
function
|
|
1065
|
+
function normalizeKey(key, style) {
|
|
1066
|
+
return style && key.startsWith(CSS_VARIABLE_PREFIX) ? key : kebabCase(key);
|
|
1067
|
+
}
|
|
1068
|
+
function setElementValue(element, first, second, third, callback, style) {
|
|
654
1069
|
if (!isHTMLOrSVGElement(element)) return;
|
|
655
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
656
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
1070
|
+
if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
|
|
1071
|
+
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
|
|
657
1072
|
}
|
|
658
|
-
function setElementValues(element, first, second, third, callback) {
|
|
1073
|
+
function setElementValues(element, first, second, third, callback, style) {
|
|
659
1074
|
if (!isHTMLOrSVGElement(element)) return;
|
|
1075
|
+
const dispatch = third !== false;
|
|
660
1076
|
if (typeof first === "string") {
|
|
661
|
-
callback(element, first, second,
|
|
1077
|
+
callback(element, normalizeKey(first, style), second, dispatch);
|
|
662
1078
|
return;
|
|
663
1079
|
}
|
|
664
1080
|
const isArray = Array.isArray(first);
|
|
@@ -670,13 +1086,36 @@ function setElementValues(element, first, second, third, callback) {
|
|
|
670
1086
|
const { length } = entries;
|
|
671
1087
|
for (let index = 0; index < length; index += 1) {
|
|
672
1088
|
const entry = entries[index];
|
|
673
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value,
|
|
1089
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
674
1090
|
}
|
|
675
1091
|
}
|
|
676
1092
|
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
677
1093
|
if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
|
|
678
1094
|
else set.call(element, key, json ? JSON.stringify(value) : String(value));
|
|
679
1095
|
}
|
|
1096
|
+
const CSS_VARIABLE_PREFIX = "--";
|
|
1097
|
+
//#endregion
|
|
1098
|
+
//#region node_modules/@oscarpalmer/toretto/dist/internal/property.mjs
|
|
1099
|
+
function updateProperty(element, name, value, dispatch) {
|
|
1100
|
+
let property = name;
|
|
1101
|
+
if (!(property in element)) property = camelCase(name);
|
|
1102
|
+
if (!(property in element) || Object.is(element[property], value)) return;
|
|
1103
|
+
element[property] = value;
|
|
1104
|
+
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
1105
|
+
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
1106
|
+
bubbles: true,
|
|
1107
|
+
cancelable: true
|
|
1108
|
+
}));
|
|
1109
|
+
}
|
|
1110
|
+
const elementEvents = {
|
|
1111
|
+
DETAILS: { open: "toggle" },
|
|
1112
|
+
INPUT: {
|
|
1113
|
+
checked: "change",
|
|
1114
|
+
value: "input"
|
|
1115
|
+
},
|
|
1116
|
+
SELECT: { value: "change" },
|
|
1117
|
+
TEXTAREA: { value: "input" }
|
|
1118
|
+
};
|
|
680
1119
|
//#endregion
|
|
681
1120
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/attribute.mjs
|
|
682
1121
|
function badAttributeHandler(name, value) {
|
|
@@ -707,6 +1146,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
707
1146
|
name = first;
|
|
708
1147
|
value = second;
|
|
709
1148
|
}
|
|
1149
|
+
if (name != null) name = kebabCase(name);
|
|
710
1150
|
if (decode && value != null) value = decodeAttribute(value);
|
|
711
1151
|
return callback(name, value?.replace(EXPRESSION_WHITESPACE, ""));
|
|
712
1152
|
}
|
|
@@ -716,12 +1156,6 @@ function isAttribute(value) {
|
|
|
716
1156
|
function _isBadAttribute(first, second, decode) {
|
|
717
1157
|
return handleAttribute(badAttributeHandler, decode, first, second);
|
|
718
1158
|
}
|
|
719
|
-
function _isBooleanAttribute(first, decode) {
|
|
720
|
-
return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
|
|
721
|
-
}
|
|
722
|
-
function _isEmptyNonBooleanAttribute(first, second, decode) {
|
|
723
|
-
return handleAttribute((name, value) => name != null && value != null && !booleanAttributesSet.has(name) && value.trim().length === 0, decode, first, second);
|
|
724
|
-
}
|
|
725
1159
|
function _isInvalidBooleanAttribute(first, second, decode) {
|
|
726
1160
|
return handleAttribute(booleanAttributeHandler, decode, first, second);
|
|
727
1161
|
}
|
|
@@ -729,18 +1163,12 @@ function isValidSourceAttribute(name, value) {
|
|
|
729
1163
|
return EXPRESSION_SOURCE_NAME.test(name) && EXPRESSION_SOURCE_VALUE.test(value);
|
|
730
1164
|
}
|
|
731
1165
|
function updateAttribute(element, name, value, dispatch) {
|
|
732
|
-
const
|
|
733
|
-
const isBoolean = booleanAttributesSet.has(
|
|
734
|
-
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() ===
|
|
735
|
-
if (
|
|
1166
|
+
const lowerCaseName = name.toLowerCase();
|
|
1167
|
+
const isBoolean = booleanAttributesSet.has(lowerCaseName);
|
|
1168
|
+
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
|
|
1169
|
+
if (isBoolean || dispatchedAttributes.has(name)) updateProperty(element, name, next, dispatch);
|
|
736
1170
|
updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
|
|
737
1171
|
}
|
|
738
|
-
function updateProperty$1(element, name, value, dispatch) {
|
|
739
|
-
if (Object.is(element[name], value)) return;
|
|
740
|
-
element[name] = value;
|
|
741
|
-
const event = dispatch !== false && elementEvents[element.tagName]?.[name];
|
|
742
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
743
|
-
}
|
|
744
1172
|
const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
|
|
745
1173
|
const EXPRESSION_DATA_OR_SCRIPT = /^(?:data|\w+script):/i;
|
|
746
1174
|
const EXPRESSION_EVENT_NAME$1 = /^on/i;
|
|
@@ -779,19 +1207,15 @@ const booleanAttributes = Object.freeze([
|
|
|
779
1207
|
"selected"
|
|
780
1208
|
]);
|
|
781
1209
|
const booleanAttributesSet = new Set(booleanAttributes);
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
},
|
|
788
|
-
SELECT: { value: "change" },
|
|
789
|
-
TEXTAREA: { value: "input" }
|
|
790
|
-
};
|
|
1210
|
+
const dispatchedAttributes = new Set([
|
|
1211
|
+
"checked",
|
|
1212
|
+
"open",
|
|
1213
|
+
"value"
|
|
1214
|
+
]);
|
|
791
1215
|
const formElement = document.createElement("form");
|
|
792
1216
|
let textArea;
|
|
793
1217
|
//#endregion
|
|
794
|
-
//#region node_modules/@oscarpalmer/toretto/dist/attribute/set.mjs
|
|
1218
|
+
//#region node_modules/@oscarpalmer/toretto/dist/attribute/set.attribute.mjs
|
|
795
1219
|
function setAttribute$1(element, first, second, third) {
|
|
796
1220
|
setElementValue(element, first, second, third, updateAttribute);
|
|
797
1221
|
}
|
|
@@ -799,8 +1223,9 @@ function setAttribute$1(element, first, second, third) {
|
|
|
799
1223
|
//#region node_modules/@oscarpalmer/toretto/dist/html/sanitize.mjs
|
|
800
1224
|
function handleElement(element, depth) {
|
|
801
1225
|
if (depth === 0) {
|
|
802
|
-
const removable = element.querySelectorAll(REMOVE_SELECTOR);
|
|
803
|
-
|
|
1226
|
+
const removable = [...element.querySelectorAll(REMOVE_SELECTOR)];
|
|
1227
|
+
const { length } = removable;
|
|
1228
|
+
for (let index = 0; index < length; index += 1) removable[index].remove();
|
|
804
1229
|
}
|
|
805
1230
|
sanitizeAttributes(element, [...element.attributes]);
|
|
806
1231
|
}
|
|
@@ -819,7 +1244,7 @@ function sanitizeAttributes(element, attributes) {
|
|
|
819
1244
|
const { length } = attributes;
|
|
820
1245
|
for (let index = 0; index < length; index += 1) {
|
|
821
1246
|
const { name, value } = attributes[index];
|
|
822
|
-
if (_isBadAttribute(name, value, false)
|
|
1247
|
+
if (_isBadAttribute(name, value, false)) element.removeAttribute(name);
|
|
823
1248
|
else if (_isInvalidBooleanAttribute(name, value, false)) setAttribute$1(element, name, true);
|
|
824
1249
|
}
|
|
825
1250
|
}
|
|
@@ -865,16 +1290,22 @@ function createHtml(value) {
|
|
|
865
1290
|
function createTemplate(value, options) {
|
|
866
1291
|
const template = document.createElement(TEMPLATE_TAG);
|
|
867
1292
|
template.innerHTML = createHtml(value);
|
|
868
|
-
if (typeof value === "string" && options.cache) templates
|
|
1293
|
+
if (typeof value === "string" && options.cache) templates.set(value, template);
|
|
869
1294
|
return template;
|
|
870
1295
|
}
|
|
1296
|
+
function getComment(index) {
|
|
1297
|
+
return COMMENT_TEMPLATE.replace(COMMENT_INDEX, String(index));
|
|
1298
|
+
}
|
|
871
1299
|
function getHtml(value) {
|
|
872
1300
|
return `${TEMPORARY_ELEMENT}${typeof value === "string" ? value : value.innerHTML}${TEMPORARY_ELEMENT}`;
|
|
873
1301
|
}
|
|
874
|
-
function getNodes(value, options) {
|
|
1302
|
+
function getNodes(value, options, nodes) {
|
|
875
1303
|
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
876
1304
|
const template = getTemplate(value, options);
|
|
877
|
-
|
|
1305
|
+
if (template == null) return [];
|
|
1306
|
+
const cloned = [...template.content.cloneNode(true).childNodes];
|
|
1307
|
+
if (nodes != null) replaceComments(cloned, nodes);
|
|
1308
|
+
return cloned;
|
|
878
1309
|
}
|
|
879
1310
|
function getOptions$1(input) {
|
|
880
1311
|
const options = isPlainObject(input) ? input : {};
|
|
@@ -885,42 +1316,102 @@ function getParser() {
|
|
|
885
1316
|
parser ??= new DOMParser();
|
|
886
1317
|
return parser;
|
|
887
1318
|
}
|
|
1319
|
+
function getTagged(strings, values) {
|
|
1320
|
+
const tagged = {
|
|
1321
|
+
nodes: [],
|
|
1322
|
+
template: ""
|
|
1323
|
+
};
|
|
1324
|
+
const stringsLength = strings.length;
|
|
1325
|
+
let nodeIndex = 0;
|
|
1326
|
+
for (let stringIndex = 0; stringIndex < stringsLength; stringIndex += 1) {
|
|
1327
|
+
const value = values[stringIndex];
|
|
1328
|
+
tagged.template += strings[stringIndex];
|
|
1329
|
+
if (value instanceof Node) {
|
|
1330
|
+
tagged.nodes.push(value);
|
|
1331
|
+
tagged.template += getComment(nodeIndex);
|
|
1332
|
+
nodeIndex += 1;
|
|
1333
|
+
} else if (hasNodes(value)) {
|
|
1334
|
+
const items = [...value];
|
|
1335
|
+
const itemsLength = items.length;
|
|
1336
|
+
for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
|
|
1337
|
+
const item = items[itemIndex];
|
|
1338
|
+
if (item instanceof Node) {
|
|
1339
|
+
tagged.nodes.push(item);
|
|
1340
|
+
tagged.template += getComment(nodeIndex);
|
|
1341
|
+
nodeIndex += 1;
|
|
1342
|
+
} else tagged.template += getString(item);
|
|
1343
|
+
}
|
|
1344
|
+
} else if (Array.isArray(value)) {
|
|
1345
|
+
const valueLength = value.length;
|
|
1346
|
+
for (let valueIndex = 0; valueIndex < valueLength; valueIndex += 1) tagged.template += getString(value[valueIndex]);
|
|
1347
|
+
} else tagged.template += getString(value);
|
|
1348
|
+
}
|
|
1349
|
+
return tagged;
|
|
1350
|
+
}
|
|
888
1351
|
function getTemplate(value, options) {
|
|
889
1352
|
if (value instanceof HTMLTemplateElement) return createTemplate(value, options);
|
|
890
1353
|
if (value.trim().length === 0) return;
|
|
891
|
-
let template = templates
|
|
1354
|
+
let template = templates.get(value);
|
|
892
1355
|
if (template != null) return template;
|
|
893
1356
|
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
894
1357
|
return createTemplate(element instanceof HTMLTemplateElement ? element : value, options);
|
|
895
1358
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1359
|
+
function hasNodes(value) {
|
|
1360
|
+
if (value instanceof HTMLCollection || value instanceof NodeList) return true;
|
|
1361
|
+
return Array.isArray(value) && value.some((item) => item instanceof Node);
|
|
1362
|
+
}
|
|
1363
|
+
function html$1(first, ...second) {
|
|
1364
|
+
if (isTagged(first)) {
|
|
1365
|
+
const tagged = getTagged(first, second);
|
|
1366
|
+
return getNodes(tagged.template, getOptions$1(), tagged.nodes);
|
|
1367
|
+
}
|
|
1368
|
+
return getNodes(first, getOptions$1(second[0]));
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Clear cache of template elements
|
|
1372
|
+
*/
|
|
899
1373
|
html$1.clear = () => {
|
|
900
|
-
templates
|
|
1374
|
+
templates.clear();
|
|
901
1375
|
};
|
|
1376
|
+
/**
|
|
1377
|
+
* Remove cached template element for an HTML string or id
|
|
1378
|
+
* @param template HTML string or id for a template element
|
|
1379
|
+
*/
|
|
902
1380
|
html$1.remove = (template) => {
|
|
903
|
-
|
|
904
|
-
const keys = Object.keys(templates);
|
|
905
|
-
const { length } = keys;
|
|
906
|
-
const updated = {};
|
|
907
|
-
for (let index = 0; index < length; index += 1) {
|
|
908
|
-
const key = keys[index];
|
|
909
|
-
if (key !== template) updated[key] = templates[key];
|
|
910
|
-
}
|
|
911
|
-
templates = updated;
|
|
1381
|
+
templates.delete(template);
|
|
912
1382
|
};
|
|
1383
|
+
function isTagged(value) {
|
|
1384
|
+
return Array.isArray(value) && Array.isArray(value.raw);
|
|
1385
|
+
}
|
|
1386
|
+
function replaceComments(origin, replacements) {
|
|
1387
|
+
const nodes = [...origin];
|
|
1388
|
+
const { length } = nodes;
|
|
1389
|
+
for (let nodeIndex = 0; nodeIndex < length; nodeIndex += 1) {
|
|
1390
|
+
const node = nodes[nodeIndex];
|
|
1391
|
+
if (node instanceof Comment) {
|
|
1392
|
+
const [, index] = EXPRESSION_COMMENT.exec(node.textContent) ?? [];
|
|
1393
|
+
if (index != null) node.replaceWith(replacements[Number(index)]);
|
|
1394
|
+
continue;
|
|
1395
|
+
}
|
|
1396
|
+
if (node.hasChildNodes()) replaceComments(node.childNodes, replacements);
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
const COMMENT_INDEX = "<index>";
|
|
1400
|
+
const COMMENT_TEMPLATE = `<!--toretto.node:${COMMENT_INDEX}-->`;
|
|
1401
|
+
const EXPRESSION_COMMENT = /^toretto\.node:(\d+)$/;
|
|
913
1402
|
const EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
914
1403
|
const PARSE_TYPE_HTML = "text/html";
|
|
915
1404
|
const TEMPLATE_TAG = "template";
|
|
916
1405
|
const TEMPORARY_ELEMENT = "<toretto-temporary></toretto-temporary>";
|
|
1406
|
+
const templates = new SizedMap(128);
|
|
917
1407
|
let parser;
|
|
918
|
-
|
|
1408
|
+
window.templates = templates;
|
|
919
1409
|
//#endregion
|
|
920
1410
|
//#region src/constants.ts
|
|
921
1411
|
const ARRAY_COMPARISON_ADDED = "added";
|
|
922
1412
|
const ARRAY_COMPARISON_DISSIMILAR = "dissimilar";
|
|
923
1413
|
const ARRAY_COMPARISON_REMOVED = "removed";
|
|
1414
|
+
const CHANGE_INPUTS = new Set(["checkbox", "radio"]);
|
|
924
1415
|
const ERROR_FRAGMENT = "Fragment function must return a Fragment instance";
|
|
925
1416
|
const ERROR_IDENTIFIER_DUPLICATE = "Duplicate identifier found: '<id>'";
|
|
926
1417
|
const ERROR_IDENTIFIER_TYPE = "Identifier cannot be null or undefined";
|
|
@@ -935,39 +1426,23 @@ const EVENT_DEFAULTS = {
|
|
|
935
1426
|
SELECT: EVENT_CHANGE,
|
|
936
1427
|
TEXTAREA: EVENT_INPUT
|
|
937
1428
|
};
|
|
938
|
-
const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?[\w-]+)="<!--abydon.(\d+)-->"/g;
|
|
939
|
-
const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^
|
|
940
|
-
const EXPRESSION_ABYDON_CONTENT =
|
|
1429
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?[\w-.]+(?::[a-z:]+)?)="<!--abydon.(\d+)-->"/g;
|
|
1430
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^abydon-/;
|
|
1431
|
+
const EXPRESSION_ABYDON_CONTENT = /^abydon\.(\d+)$/;
|
|
941
1432
|
const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
|
|
942
1433
|
const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
|
|
943
1434
|
const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
|
|
944
|
-
const
|
|
945
|
-
const
|
|
1435
|
+
const EXPRESSION_ATTRIBUTE_STYLE_PROPERTY = /^style\.--/;
|
|
1436
|
+
const EXPRESSION_EVENT_ATTRIBUTE = /^@([\w-]+)(?::([a-z:]+))?="$/i;
|
|
1437
|
+
const EXPRESSION_EVENT_NAME = /^@?([\w-]+)(?::([a-z:]+))?$/i;
|
|
946
1438
|
const EXPRESSION_EVENT_OPTIONS_ACTIVE = /^a(ctive)$/i;
|
|
947
1439
|
const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(apture)$/i;
|
|
948
1440
|
const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(nce)$/i;
|
|
949
1441
|
const EXPRESSION_EVENT_PREFIX = /^@/;
|
|
950
|
-
const
|
|
951
|
-
const EXPRESSION_TEXTAREA_VALUE = /<!--abydon\.(\d+)-->/;
|
|
1442
|
+
const EXPRESSION_TEXTAREA_VALUE = /(?:<|<)!--abydon\.(\d+)--(?:>|>)/;
|
|
952
1443
|
const NAME_FRAGMENT = "$fragment";
|
|
953
1444
|
const NAME_FRAGMENTS = "$fragments";
|
|
954
|
-
const
|
|
955
|
-
const PROPERTY_VALUE = "value";
|
|
956
|
-
//#endregion
|
|
957
|
-
//#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
|
|
958
|
-
/**
|
|
959
|
-
* Parse a JSON string into its proper value _(or `undefined` if it fails)_
|
|
960
|
-
* @param value JSON string to parse
|
|
961
|
-
* @param reviver Reviver function to transform the parsed values
|
|
962
|
-
* @returns Parsed value or `undefined` if parsing fails
|
|
963
|
-
*/
|
|
964
|
-
function parse$1(value, reviver) {
|
|
965
|
-
try {
|
|
966
|
-
return JSON.parse(value, reviver);
|
|
967
|
-
} catch {
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
1445
|
+
const WHITESPACE = /\s+/g;
|
|
971
1446
|
//#endregion
|
|
972
1447
|
//#region src/helpers/index.ts
|
|
973
1448
|
function compareArrays(first, second) {
|
|
@@ -977,9 +1452,19 @@ function compareArrays(first, second) {
|
|
|
977
1452
|
if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) return ARRAY_COMPARISON_DISSIMILAR;
|
|
978
1453
|
return firstIsLarger ? ARRAY_COMPARISON_REMOVED : ARRAY_COMPARISON_ADDED;
|
|
979
1454
|
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Is the value a Fragment?
|
|
1457
|
+
* @param value Value to check
|
|
1458
|
+
* @returns `true` if the value is a Fragment, otherwise `false`
|
|
1459
|
+
*/
|
|
980
1460
|
function isFragment(value) {
|
|
981
1461
|
return isNamed(value, NAME_FRAGMENT);
|
|
982
1462
|
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Is the value a Fragments?
|
|
1465
|
+
* @param value Value to check
|
|
1466
|
+
* @returns `true` if the value is a Fragments, otherwise `false`
|
|
1467
|
+
*/
|
|
983
1468
|
function isFragments(value) {
|
|
984
1469
|
return isNamed(value, NAME_FRAGMENTS);
|
|
985
1470
|
}
|
|
@@ -990,12 +1475,6 @@ function isNamed(value, name) {
|
|
|
990
1475
|
//#region src/fragments.ts
|
|
991
1476
|
var Fragments = class {
|
|
992
1477
|
#state;
|
|
993
|
-
/**
|
|
994
|
-
* Fragment items
|
|
995
|
-
*/
|
|
996
|
-
get items() {
|
|
997
|
-
return this.#state.mapped;
|
|
998
|
-
}
|
|
999
1478
|
constructor(items, identify, fragment) {
|
|
1000
1479
|
Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
|
|
1001
1480
|
this.#state = {
|
|
@@ -1006,13 +1485,13 @@ var Fragments = class {
|
|
|
1006
1485
|
mapped: array([]),
|
|
1007
1486
|
subscriber: void 0
|
|
1008
1487
|
};
|
|
1009
|
-
|
|
1488
|
+
fragmentsStates.set(this, this.#state);
|
|
1010
1489
|
initializeFragments(this.#state);
|
|
1011
1490
|
}
|
|
1012
1491
|
};
|
|
1013
1492
|
function handleFragments(item, remove) {
|
|
1014
|
-
const state = isFragments(item) ?
|
|
1015
|
-
|
|
1493
|
+
const state = isFragments(item) ? fragmentsStates.get(item) : item;
|
|
1494
|
+
(remove ? removeFragments$1 : initializeFragments)(state);
|
|
1016
1495
|
}
|
|
1017
1496
|
function handleItems(state, items) {
|
|
1018
1497
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -1060,7 +1539,7 @@ function updateFragments(state, active) {
|
|
|
1060
1539
|
state.instances = next;
|
|
1061
1540
|
active?.clear();
|
|
1062
1541
|
}
|
|
1063
|
-
const
|
|
1542
|
+
const fragmentsStates = /* @__PURE__ */ new WeakMap();
|
|
1064
1543
|
//#endregion
|
|
1065
1544
|
//#region src/helpers/dom.ts
|
|
1066
1545
|
function createNodes(value) {
|
|
@@ -1104,7 +1583,14 @@ function delegatedEventHandler(event) {
|
|
|
1104
1583
|
const key = `${EVENT_PREFIX}${event.type}${this ? EVENT_SUFFIX_PASSIVE : EVENT_SUFFIX_ACTIVE}`;
|
|
1105
1584
|
const items = event.composedPath();
|
|
1106
1585
|
const { length } = items;
|
|
1586
|
+
let cancelled = false;
|
|
1107
1587
|
let target = items[0];
|
|
1588
|
+
const originalStopPropagation = event.stopPropagation;
|
|
1589
|
+
event.stopPropagation = function() {
|
|
1590
|
+
cancelled = true;
|
|
1591
|
+
originalStopPropagation.call(event);
|
|
1592
|
+
};
|
|
1593
|
+
event.stopImmediatePropagation = event.stopPropagation.bind(event);
|
|
1108
1594
|
Object.defineProperties(event, {
|
|
1109
1595
|
currentTarget: {
|
|
1110
1596
|
configurable: true,
|
|
@@ -1124,7 +1610,7 @@ function delegatedEventHandler(event) {
|
|
|
1124
1610
|
target = item;
|
|
1125
1611
|
for (const listener of listeners) {
|
|
1126
1612
|
listener.call(item, event);
|
|
1127
|
-
if (
|
|
1613
|
+
if (cancelled) return;
|
|
1128
1614
|
}
|
|
1129
1615
|
}
|
|
1130
1616
|
}
|
|
@@ -1208,89 +1694,106 @@ function getOptions(options) {
|
|
|
1208
1694
|
function getType(element, type) {
|
|
1209
1695
|
if (type !== "on") return type;
|
|
1210
1696
|
if (element instanceof HTMLInputElement) {
|
|
1211
|
-
if (
|
|
1697
|
+
if (CHANGE_INPUTS.has(element.type)) return EVENT_CHANGE;
|
|
1212
1698
|
return element.type === "submit" ? EVENT_SUBMIT : EVENT_INPUT;
|
|
1213
1699
|
}
|
|
1214
1700
|
return EVENT_DEFAULTS[element.tagName] ?? type;
|
|
1215
1701
|
}
|
|
1216
1702
|
function mapEvent(element, name, value) {
|
|
1217
|
-
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name)
|
|
1218
|
-
|
|
1703
|
+
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name);
|
|
1704
|
+
const values = Array.isArray(value) ? value : [value];
|
|
1705
|
+
const { length } = values;
|
|
1706
|
+
for (let index = 0; index < length; index += 1) {
|
|
1707
|
+
const item = values[index];
|
|
1708
|
+
if (typeof item === "function") on(element, getType(element, type), item, getOptions(options ?? ""));
|
|
1709
|
+
}
|
|
1219
1710
|
}
|
|
1220
1711
|
//#endregion
|
|
1221
|
-
//#region node_modules/@oscarpalmer/toretto/dist/
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1712
|
+
//#region node_modules/@oscarpalmer/toretto/dist/style.mjs
|
|
1713
|
+
/**
|
|
1714
|
+
* Set a style on an element
|
|
1715
|
+
* @param element Element to set the style on
|
|
1716
|
+
* @param property Style name
|
|
1717
|
+
* @param value Style value
|
|
1718
|
+
*/
|
|
1719
|
+
function setStyle(element, property, value) {
|
|
1720
|
+
setElementValues(element, property, value, null, updateStyleProperty, true);
|
|
1721
|
+
}
|
|
1722
|
+
function updateStyleProperty(element, key, value) {
|
|
1723
|
+
updateElementValue(element, key, value, function(property, style) {
|
|
1724
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.setProperty(property, String(style));
|
|
1725
|
+
else this.style[property] = String(style);
|
|
1726
|
+
}, function(property) {
|
|
1727
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(property);
|
|
1728
|
+
else this.style[property] = "";
|
|
1729
|
+
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
1730
|
+
}, false, false);
|
|
1731
|
+
}
|
|
1732
|
+
const ATTRIBUTE_STYLE = "style";
|
|
1733
|
+
const VARIABLE_PREFIX = "--";
|
|
1225
1734
|
//#endregion
|
|
1226
|
-
//#region src/
|
|
1227
|
-
function
|
|
1228
|
-
if (
|
|
1229
|
-
return
|
|
1735
|
+
//#region src/attribute/value.ts
|
|
1736
|
+
function getStyleValue(value, unit, isProperty) {
|
|
1737
|
+
if (removeStyleValue(value, unit, isProperty)) return;
|
|
1738
|
+
return value === true || value === "true" ? unit : `${getString(value)}${unit ?? ""}`;
|
|
1739
|
+
}
|
|
1740
|
+
function removeStyleValue(value, unit, isProperty) {
|
|
1741
|
+
if (value == null || value === false || isProperty && isNullableOrWhitespace(value)) return true;
|
|
1742
|
+
return unit == null && (value === true || value === "true");
|
|
1230
1743
|
}
|
|
1231
1744
|
function setAttribute(data, element, name, value) {
|
|
1232
1745
|
switch (true) {
|
|
1233
1746
|
case EXPRESSION_ATTRIBUTE_CLASS.test(name):
|
|
1234
|
-
|
|
1747
|
+
setClassValues(data, element, name, value);
|
|
1235
1748
|
return;
|
|
1236
1749
|
case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
|
|
1237
|
-
|
|
1750
|
+
setStyleValues(data, element, name, value);
|
|
1238
1751
|
return;
|
|
1239
1752
|
default:
|
|
1240
1753
|
setValue(data, element, name, value);
|
|
1241
1754
|
break;
|
|
1242
1755
|
}
|
|
1243
1756
|
}
|
|
1244
|
-
function
|
|
1757
|
+
function setClassValues(data, element, name, value) {
|
|
1245
1758
|
function update(value) {
|
|
1246
|
-
if (value === true) element.classList.add(...classes);
|
|
1759
|
+
if (value === true || value === "true") element.classList.add(...classes);
|
|
1247
1760
|
else element.classList.remove(...classes);
|
|
1248
1761
|
}
|
|
1249
1762
|
const classes = name.slice(6).split(".");
|
|
1250
1763
|
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
1251
1764
|
else update(value);
|
|
1252
1765
|
}
|
|
1253
|
-
function
|
|
1254
|
-
|
|
1255
|
-
|
|
1766
|
+
function setStyleValues(data, element, name, value) {
|
|
1767
|
+
let [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name);
|
|
1768
|
+
const isProperty = EXPRESSION_ATTRIBUTE_STYLE_PROPERTY.test(name);
|
|
1769
|
+
property = camelCase(property);
|
|
1770
|
+
if (isProperty) property = `--${property}`;
|
|
1256
1771
|
function update(value) {
|
|
1257
|
-
|
|
1258
|
-
else element.style.setProperty(property, value === true ? unit : String(value));
|
|
1772
|
+
setStyle(element, property, getStyleValue(value, unit, isProperty));
|
|
1259
1773
|
}
|
|
1260
1774
|
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
1261
1775
|
else update(value);
|
|
1262
1776
|
}
|
|
1263
1777
|
function setValue(data, element, name, value) {
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
|
|
1778
|
+
const isReactiveValue = isReactive(value);
|
|
1779
|
+
unsetValue(element, name, isReactiveValue ? value.peek() : value);
|
|
1780
|
+
if (isReactiveValue) data.mora.subscribers.add(value.subscribe((next) => {
|
|
1781
|
+
setAttribute$1(element, name, next);
|
|
1267
1782
|
}));
|
|
1268
|
-
else
|
|
1269
|
-
}
|
|
1270
|
-
function updateChecked(element, name, value) {
|
|
1271
|
-
updateElement(EVENT_CHANGE, PROPERTY_CHECKED, element, name, value, value === true);
|
|
1272
|
-
}
|
|
1273
|
-
function updateElement(event, property, element, name, value, next) {
|
|
1274
|
-
if (!(property in element) || element[property] === next) return;
|
|
1275
|
-
setAttribute$1(element, name, value);
|
|
1276
|
-
if (element[property] === next) return;
|
|
1277
|
-
element[property] = next;
|
|
1278
|
-
element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
1783
|
+
else setAttribute$1(element, name, value);
|
|
1279
1784
|
}
|
|
1280
|
-
function
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
function updateValue(element, name, value) {
|
|
1284
|
-
updateElement(element instanceof HTMLSelectElement ? EVENT_CHANGE : EVENT_INPUT, PROPERTY_VALUE, element, name, value, String(value));
|
|
1785
|
+
function unsetValue(element, name, value) {
|
|
1786
|
+
if (name === "checked") element.checked = !(value === true || value === "true");
|
|
1787
|
+
if (name === "value") element.value = element.value === "" ? "_" : "";
|
|
1285
1788
|
}
|
|
1286
1789
|
//#endregion
|
|
1287
|
-
//#region src/
|
|
1790
|
+
//#region src/attribute/index.ts
|
|
1288
1791
|
function getValue(data, original) {
|
|
1289
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(original
|
|
1792
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(original);
|
|
1290
1793
|
return matches == null ? original : data.values[+matches[1]];
|
|
1291
1794
|
}
|
|
1292
1795
|
function mapAttributes(data, element) {
|
|
1293
|
-
const attributes = [...element.attributes];
|
|
1796
|
+
const attributes = [...element.attributes].sort((first, second) => first.name.localeCompare(second.name));
|
|
1294
1797
|
const { length } = attributes;
|
|
1295
1798
|
for (let index = 0; index < length; index += 1) {
|
|
1296
1799
|
const { name, value } = attributes[index];
|
|
@@ -1301,25 +1804,17 @@ function mapAttributes(data, element) {
|
|
|
1301
1804
|
case EXPRESSION_EVENT_PREFIX.test(actualName):
|
|
1302
1805
|
mapEvent(element, actualName, actualValue);
|
|
1303
1806
|
break;
|
|
1304
|
-
|
|
1305
|
-
case typeof actualValue === "function":
|
|
1306
|
-
case isReactive(actualValue):
|
|
1807
|
+
default:
|
|
1307
1808
|
mapValue$1(data, element, actualName, actualValue);
|
|
1308
1809
|
break;
|
|
1309
|
-
default: break;
|
|
1310
1810
|
}
|
|
1311
1811
|
}
|
|
1312
1812
|
}
|
|
1313
1813
|
function mapValue$1(data, element, name, value) {
|
|
1314
1814
|
if (typeof value === "function") setComputedAttribute(data, element, name, value);
|
|
1315
1815
|
else setAttribute(data, element, name, value);
|
|
1316
|
-
if (
|
|
1317
|
-
|
|
1318
|
-
if (name === "checked" && element.type === "checkbox") property = PROPERTY_CHECKED;
|
|
1319
|
-
else if (name === "value") property = PROPERTY_VALUE;
|
|
1320
|
-
if (property != null) mapEvent(element, "@on", () => {
|
|
1321
|
-
const next = element[property];
|
|
1322
|
-
value.set(parse$1(String(next)) ?? next);
|
|
1816
|
+
if (isInputElement(element) && isSignal(value) && name in element) mapEvent(element, "on", () => {
|
|
1817
|
+
value.set(element[name]);
|
|
1323
1818
|
});
|
|
1324
1819
|
}
|
|
1325
1820
|
function setComputedAttribute(data, element, name, callback) {
|
|
@@ -1376,14 +1871,15 @@ function setArray(item, comment, value) {
|
|
|
1376
1871
|
let templates = value.filter((item) => isFragment(item) && item.identifier != null);
|
|
1377
1872
|
const next = templates.map((fragment) => fragment.identifier);
|
|
1378
1873
|
const previous = item.fragments?.map((fragment) => fragment.identifier) ?? [];
|
|
1379
|
-
|
|
1874
|
+
const nextSet = new Set(next);
|
|
1875
|
+
if (nextSet.size !== templates.length) templates = [];
|
|
1380
1876
|
const noTemplates = templates.length === 0;
|
|
1381
1877
|
if (noTemplates || item.nodes == null || previous.some((identifier) => identifier == null)) return {
|
|
1382
1878
|
fragments: noTemplates ? void 0 : templates,
|
|
1383
1879
|
nodes: setNodes(item, comment, noTemplates ? value.flatMap((item) => createNodes(item)) : templates.flatMap((template) => template.get()))
|
|
1384
1880
|
};
|
|
1385
1881
|
return handleArray({
|
|
1386
|
-
next:
|
|
1882
|
+
next: nextSet,
|
|
1387
1883
|
previous: new Set(previous)
|
|
1388
1884
|
}, {
|
|
1389
1885
|
templates,
|
|
@@ -1391,10 +1887,8 @@ function setArray(item, comment, value) {
|
|
|
1391
1887
|
}, item.nodes);
|
|
1392
1888
|
}
|
|
1393
1889
|
function setNodes(item, comment, next) {
|
|
1394
|
-
if (item.nodes == null)
|
|
1395
|
-
|
|
1396
|
-
else if (item.text?.parentNode != null) replaceNodes([item.text], next);
|
|
1397
|
-
} else replaceNodes(item.nodes, next);
|
|
1890
|
+
if (item.nodes == null) replaceNodes([comment], next);
|
|
1891
|
+
else replaceNodes(item.nodes, next);
|
|
1398
1892
|
removeFragments(item.fragments);
|
|
1399
1893
|
return next;
|
|
1400
1894
|
}
|
|
@@ -1405,15 +1899,13 @@ function setReactiveValue(data, comment, reactive) {
|
|
|
1405
1899
|
data.mora.subscribers.add(reactive.subscribe((value) => {
|
|
1406
1900
|
if (Array.isArray(value)) setReactiveValueForArray(item, comment, value);
|
|
1407
1901
|
else setReactiveValueForSingle(item, comment, value);
|
|
1408
|
-
item.nodes
|
|
1902
|
+
item.nodes ??= [comment];
|
|
1409
1903
|
}));
|
|
1410
1904
|
}
|
|
1411
1905
|
function setReactiveValueForArray(item, comment, value) {
|
|
1412
|
-
const
|
|
1413
|
-
item.fragments =
|
|
1414
|
-
|
|
1415
|
-
else item.nodes = void 0;
|
|
1416
|
-
else item.nodes = result?.nodes;
|
|
1906
|
+
const { fragments, nodes } = setArray(item, comment, value);
|
|
1907
|
+
item.fragments = fragments;
|
|
1908
|
+
item.nodes = nodes;
|
|
1417
1909
|
}
|
|
1418
1910
|
function setReactiveValueForSingle(item, comment, value) {
|
|
1419
1911
|
const valueIsFragment = isFragment(value);
|
|
@@ -1439,7 +1931,7 @@ function setText(item, comment, value) {
|
|
|
1439
1931
|
//#endregion
|
|
1440
1932
|
//#region src/node/index.ts
|
|
1441
1933
|
function mapNode(data, comment) {
|
|
1442
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent
|
|
1934
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent);
|
|
1443
1935
|
const value = matches == null ? null : data.values[+matches[1]];
|
|
1444
1936
|
if (value != null) mapValue(data, comment, value);
|
|
1445
1937
|
}
|
|
@@ -1457,23 +1949,27 @@ function mapNodes(data, nodes) {
|
|
|
1457
1949
|
}
|
|
1458
1950
|
}
|
|
1459
1951
|
function mapTextarea(data, element) {
|
|
1460
|
-
const [, index] = EXPRESSION_TEXTAREA_VALUE.exec(element.value) ?? [];
|
|
1952
|
+
const [, index] = EXPRESSION_TEXTAREA_VALUE.exec(element.textContent) ?? EXPRESSION_TEXTAREA_VALUE.exec(element.value) ?? [];
|
|
1461
1953
|
if (index == null) return;
|
|
1954
|
+
element.textContent = "";
|
|
1462
1955
|
element.value = "";
|
|
1463
1956
|
const value = data.values[Number.parseInt(index, 10)];
|
|
1464
1957
|
if (isSignal(value)) {
|
|
1465
|
-
element.value =
|
|
1466
|
-
mapEvent(element, "
|
|
1958
|
+
element.value = getString(value.peek());
|
|
1959
|
+
mapEvent(element, "on", () => {
|
|
1467
1960
|
value.set(element.value);
|
|
1468
1961
|
});
|
|
1962
|
+
data.mora.subscribers.add(value.subscribe((value) => {
|
|
1963
|
+
element.value = getString(value);
|
|
1964
|
+
}));
|
|
1469
1965
|
return;
|
|
1470
1966
|
}
|
|
1471
1967
|
let reactive;
|
|
1472
1968
|
if (typeof value === "function") reactive = computed(value);
|
|
1473
1969
|
else if (isComputed(value)) reactive = value;
|
|
1474
|
-
if (reactive == null) element.value =
|
|
1970
|
+
if (reactive == null) element.value = "";
|
|
1475
1971
|
else data.mora.subscribers.add(reactive.subscribe((value) => {
|
|
1476
|
-
element.value =
|
|
1972
|
+
element.value = getString(value);
|
|
1477
1973
|
}));
|
|
1478
1974
|
}
|
|
1479
1975
|
function mapValue(data, comment, value) {
|
|
@@ -1482,8 +1978,7 @@ function mapValue(data, comment, value) {
|
|
|
1482
1978
|
setComputedValue(data, comment, value);
|
|
1483
1979
|
break;
|
|
1484
1980
|
case isFragments(value):
|
|
1485
|
-
|
|
1486
|
-
setReactiveValue(data, comment, value.items);
|
|
1981
|
+
setFragmentsValue(data, comment, value);
|
|
1487
1982
|
break;
|
|
1488
1983
|
case isReactive(value):
|
|
1489
1984
|
setReactiveValue(data, comment, value);
|
|
@@ -1507,17 +2002,24 @@ function setComputedValue(data, comment, callback) {
|
|
|
1507
2002
|
data.mora.values.add(value);
|
|
1508
2003
|
setReactiveValue(data, comment, value);
|
|
1509
2004
|
}
|
|
2005
|
+
function setFragmentsValue(data, comment, fragments) {
|
|
2006
|
+
const state = fragmentsStates.get(fragments);
|
|
2007
|
+
handleFragments(state, false);
|
|
2008
|
+
setReactiveValue(data, comment, state.mapped);
|
|
2009
|
+
}
|
|
1510
2010
|
//#endregion
|
|
1511
2011
|
//#region src/parse.ts
|
|
1512
2012
|
function handleExpression(data, prefix, expression) {
|
|
1513
2013
|
if (Array.isArray(expression)) {
|
|
2014
|
+
if (EXPRESSION_EVENT_ATTRIBUTE.test(prefix.split(WHITESPACE).at(-1))) return transformExpression(prefix, data.values.push(expression) - 1);
|
|
1514
2015
|
const { length } = expression;
|
|
1515
2016
|
let expressions = "";
|
|
1516
2017
|
for (let index = 0; index < length; index += 1) expressions += handleExpression(data, "", expression[index]);
|
|
1517
2018
|
return `${prefix}${expressions}`;
|
|
1518
2019
|
}
|
|
1519
2020
|
if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
|
|
1520
|
-
|
|
2021
|
+
const asString = getString(expression);
|
|
2022
|
+
return asString.trim().length === 0 ? prefix : `${prefix}${asString}`;
|
|
1521
2023
|
}
|
|
1522
2024
|
function parse(data) {
|
|
1523
2025
|
if (data.template != null) return data.template;
|
|
@@ -1530,7 +2032,7 @@ function parse(data) {
|
|
|
1530
2032
|
return data.template;
|
|
1531
2033
|
}
|
|
1532
2034
|
function transformAttribute(_, name, index) {
|
|
1533
|
-
return `
|
|
2035
|
+
return `abydon-${name}="abydon.${index}"`;
|
|
1534
2036
|
}
|
|
1535
2037
|
function transformExpression(prefix, index) {
|
|
1536
2038
|
return `${prefix}<!--abydon.${index}-->`;
|
|
@@ -1544,6 +2046,12 @@ var Fragment = class {
|
|
|
1544
2046
|
cache: true
|
|
1545
2047
|
};
|
|
1546
2048
|
/**
|
|
2049
|
+
* Is template caching enabled?
|
|
2050
|
+
*/
|
|
2051
|
+
get caching() {
|
|
2052
|
+
return this.#configuration.cache;
|
|
2053
|
+
}
|
|
2054
|
+
/**
|
|
1547
2055
|
* Fragment identifier
|
|
1548
2056
|
*/
|
|
1549
2057
|
get identifier() {
|
|
@@ -1589,9 +2097,9 @@ var Fragment = class {
|
|
|
1589
2097
|
if (data.items.length === 0) {
|
|
1590
2098
|
const templated = html$1(parse(data), { cache: this.#configuration.cache });
|
|
1591
2099
|
data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
|
|
1592
|
-
mapNodes(data, data.items.flatMap((item) => item.
|
|
2100
|
+
mapNodes(data, data.items.flatMap((item) => item.nodes));
|
|
1593
2101
|
}
|
|
1594
|
-
return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes
|
|
2102
|
+
return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes);
|
|
1595
2103
|
}
|
|
1596
2104
|
/**
|
|
1597
2105
|
* Set an identifier for the fragment
|
|
@@ -1619,7 +2127,7 @@ function removeFragment(data) {
|
|
|
1619
2127
|
const { fragments, nodes } = data.items[index];
|
|
1620
2128
|
const fragmentsLength = fragments?.length ?? 0;
|
|
1621
2129
|
for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) fragments?.[fragmentIndex]?.remove();
|
|
1622
|
-
removeNodes(nodes
|
|
2130
|
+
removeNodes(nodes);
|
|
1623
2131
|
}
|
|
1624
2132
|
data.items.length = 0;
|
|
1625
2133
|
length = data.values.length;
|
|
@@ -1637,21 +2145,24 @@ function removeMora(data) {
|
|
|
1637
2145
|
//#endregion
|
|
1638
2146
|
//#region src/index.ts
|
|
1639
2147
|
/**
|
|
1640
|
-
* Create Fragments from a reactive array
|
|
2148
|
+
* Create a Fragments from a reactive array
|
|
1641
2149
|
* @param array Reactive array
|
|
1642
2150
|
* @param identify Function to identify item
|
|
1643
2151
|
* @param fragment Function to create fragment from item
|
|
1644
2152
|
* @returns Fragments
|
|
1645
2153
|
*/
|
|
1646
2154
|
function fragments(array, identify, fragment) {
|
|
2155
|
+
if (!isArray(array)) throw new TypeError("Fragments array must be a reactive array");
|
|
2156
|
+
if (typeof identify !== "function") throw new TypeError("Fragments identify must be a function");
|
|
2157
|
+
if (typeof fragment !== "function") throw new TypeError("Fragments fragment must be a function");
|
|
1647
2158
|
return new Fragments(array, identify, fragment);
|
|
1648
2159
|
}
|
|
1649
2160
|
/**
|
|
1650
|
-
* Create Fragment from a template
|
|
2161
|
+
* Create a Fragment from a template
|
|
1651
2162
|
* @returns Fragment
|
|
1652
2163
|
*/
|
|
1653
2164
|
function html(template, ...values) {
|
|
1654
2165
|
return new Fragment(template, values);
|
|
1655
2166
|
}
|
|
1656
2167
|
//#endregion
|
|
1657
|
-
export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|
|
2168
|
+
export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isFragment, isFragments, isReactive, isSignal, signal, startBatch, stopBatch, store };
|