@oscarpalmer/abydon 0.21.0 → 0.23.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 +422 -359
- package/dist/attribute/index.d.mts +7 -0
- package/dist/attribute/index.mjs +47 -0
- package/dist/{node/attribute → attribute}/value.d.mts +2 -2
- package/dist/attribute/value.mjs +53 -0
- package/dist/constants.d.mts +8 -8
- package/dist/constants.mjs +15 -15
- package/dist/fragment.d.mts +30 -13
- package/dist/fragment.mjs +40 -18
- package/dist/fragments.d.mts +3 -7
- package/dist/fragments.mjs +6 -12
- package/dist/helpers/dom.d.mts +2 -3
- package/dist/helpers/dom.mjs +2 -4
- package/dist/helpers/index.d.mts +16 -2
- package/dist/helpers/index.mjs +17 -1
- package/dist/index.d.mts +35 -7
- package/dist/index.mjs +39 -8
- package/dist/models.d.mts +6 -4
- package/dist/node/event.mjs +9 -4
- package/dist/node/index.mjs +26 -32
- package/dist/node/value.mjs +70 -56
- package/dist/parse.mjs +6 -4
- package/package.json +6 -5
- package/src/attribute/index.ts +89 -0
- package/src/attribute/value.ts +107 -0
- package/src/constants.ts +19 -19
- package/src/fragment.ts +43 -21
- package/src/fragments.ts +8 -15
- package/src/helpers/dom.ts +3 -5
- package/src/helpers/index.ts +25 -1
- package/src/index.ts +47 -7
- package/src/models.ts +6 -4
- package/src/node/event.ts +12 -5
- package/src/node/index.ts +36 -56
- package/src/node/value.ts +121 -104
- package/src/parse.ts +15 -5
- package/dist/node/attribute/index.d.mts +0 -6
- package/dist/node/attribute/index.mjs +0 -51
- package/dist/node/attribute/value.mjs +0 -65
- package/src/node/attribute/index.ts +0 -100
- 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(),
|
|
@@ -269,6 +274,44 @@ function setValue$2(instance, state, callback) {
|
|
|
269
274
|
}
|
|
270
275
|
}
|
|
271
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
|
+
}
|
|
314
|
+
//#endregion
|
|
272
315
|
//#region node_modules/@oscarpalmer/mora/dist/helpers/value.mjs
|
|
273
316
|
function emitValue(state) {
|
|
274
317
|
for (const computed of state.computeds) computed.effect.dirty = true;
|
|
@@ -281,7 +324,7 @@ function equalArrays(state, first, second) {
|
|
|
281
324
|
if (length !== second.length) return false;
|
|
282
325
|
let offset = 0;
|
|
283
326
|
if (length >= 100) {
|
|
284
|
-
offset =
|
|
327
|
+
offset = round(length / 10);
|
|
285
328
|
offset = offset > 25 ? 25 : offset;
|
|
286
329
|
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
287
330
|
}
|
|
@@ -575,27 +618,6 @@ function setAtIndex(state, index, value) {
|
|
|
575
618
|
if (actual > -1) state.value[actual] = value;
|
|
576
619
|
}
|
|
577
620
|
//#endregion
|
|
578
|
-
//#region node_modules/@oscarpalmer/mora/node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
579
|
-
/**
|
|
580
|
-
* Is the value a key?
|
|
581
|
-
* @param value Value to check
|
|
582
|
-
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
583
|
-
*/
|
|
584
|
-
function isKey(value) {
|
|
585
|
-
return typeof value === "number" || typeof value === "string";
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Is the value a plain object?
|
|
589
|
-
* @param value Value to check
|
|
590
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
591
|
-
*/
|
|
592
|
-
function isPlainObject$2(value) {
|
|
593
|
-
if (value === null || typeof value !== "object") return false;
|
|
594
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
595
|
-
const prototype = Object.getPrototypeOf(value);
|
|
596
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
597
|
-
}
|
|
598
|
-
//#endregion
|
|
599
621
|
//#region node_modules/@oscarpalmer/mora/dist/value/store.mjs
|
|
600
622
|
var Store = class extends Reactive {
|
|
601
623
|
#keyed = /* @__PURE__ */ new Map();
|
|
@@ -636,11 +658,11 @@ var Store = class extends Reactive {
|
|
|
636
658
|
*/
|
|
637
659
|
update(callback) {
|
|
638
660
|
const updated = callback(this.state.value);
|
|
639
|
-
if (updated == null || isPlainObject$
|
|
661
|
+
if (updated == null || isPlainObject$1(updated)) setObject(this.state, updated);
|
|
640
662
|
}
|
|
641
663
|
};
|
|
642
664
|
function isStoreObject(value) {
|
|
643
|
-
return value == null || isPlainObject$
|
|
665
|
+
return value == null || isPlainObject$1(value);
|
|
644
666
|
}
|
|
645
667
|
function setObject(state, value) {
|
|
646
668
|
startBatch();
|
|
@@ -671,11 +693,19 @@ function store(value, options) {
|
|
|
671
693
|
//#endregion
|
|
672
694
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
673
695
|
/**
|
|
696
|
+
* Is the value a number?
|
|
697
|
+
* @param value Value to check
|
|
698
|
+
* @returns `true` if the value is a `number`, otherwise `false`
|
|
699
|
+
*/
|
|
700
|
+
function isNumber(value) {
|
|
701
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
674
704
|
* Is the value a plain object?
|
|
675
705
|
* @param value Value to check
|
|
676
706
|
* @returns `true` if the value is a plain object, otherwise `false`
|
|
677
707
|
*/
|
|
678
|
-
function isPlainObject
|
|
708
|
+
function isPlainObject(value) {
|
|
679
709
|
if (value === null || typeof value !== "object") return false;
|
|
680
710
|
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
681
711
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -688,14 +718,42 @@ function isPlainObject$1(value) {
|
|
|
688
718
|
* @param value Original value
|
|
689
719
|
* @returns String representation of the value
|
|
690
720
|
*/
|
|
691
|
-
function getString
|
|
721
|
+
function getString(value) {
|
|
692
722
|
if (typeof value === "string") return value;
|
|
693
723
|
if (value == null) return "";
|
|
694
|
-
if (typeof value === "function") return getString
|
|
724
|
+
if (typeof value === "function") return getString(value());
|
|
695
725
|
if (typeof value !== "object") return String(value);
|
|
696
726
|
const asString = String(value.valueOf?.() ?? value);
|
|
697
727
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
698
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;
|
|
699
757
|
//#endregion
|
|
700
758
|
//#region node_modules/@oscarpalmer/atoms/dist/is.mjs
|
|
701
759
|
/**
|
|
@@ -703,10 +761,10 @@ function getString$1(value) {
|
|
|
703
761
|
* @param value Value to check
|
|
704
762
|
* @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
|
|
705
763
|
*/
|
|
706
|
-
function isNullableOrWhitespace
|
|
707
|
-
return value == null || EXPRESSION_WHITESPACE$
|
|
764
|
+
function isNullableOrWhitespace(value) {
|
|
765
|
+
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
708
766
|
}
|
|
709
|
-
const EXPRESSION_WHITESPACE$
|
|
767
|
+
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
710
768
|
//#endregion
|
|
711
769
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
|
|
712
770
|
/**
|
|
@@ -725,6 +783,14 @@ function isEventTarget(value) {
|
|
|
725
783
|
function isHTMLOrSVGElement(value) {
|
|
726
784
|
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
727
785
|
}
|
|
786
|
+
/**
|
|
787
|
+
* Is the value an input element? _(`<input>`, `<select>`, or `<textarea>`)_
|
|
788
|
+
* @param value Value to check
|
|
789
|
+
* @returns `true` if it's an input element, otherwise `false`
|
|
790
|
+
*/
|
|
791
|
+
function isInputElement(value) {
|
|
792
|
+
return value instanceof HTMLInputElement || value instanceof HTMLSelectElement || value instanceof HTMLTextAreaElement;
|
|
793
|
+
}
|
|
728
794
|
//#endregion
|
|
729
795
|
//#region node_modules/@oscarpalmer/toretto/dist/is.mjs
|
|
730
796
|
/**
|
|
@@ -743,85 +809,7 @@ const CHILD_NODE_TYPES = new Set([
|
|
|
743
809
|
Node.DOCUMENT_TYPE_NODE
|
|
744
810
|
]);
|
|
745
811
|
//#endregion
|
|
746
|
-
//#region node_modules/@oscarpalmer/
|
|
747
|
-
/**
|
|
748
|
-
* Is the value a number?
|
|
749
|
-
* @param value Value to check
|
|
750
|
-
* @returns `true` if the value is a `number`, otherwise `false`
|
|
751
|
-
*/
|
|
752
|
-
function isNumber(value) {
|
|
753
|
-
return typeof value === "number" && !Number.isNaN(value);
|
|
754
|
-
}
|
|
755
|
-
/**
|
|
756
|
-
* Is the value a plain object?
|
|
757
|
-
* @param value Value to check
|
|
758
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
759
|
-
*/
|
|
760
|
-
function isPlainObject(value) {
|
|
761
|
-
if (value === null || typeof value !== "object") return false;
|
|
762
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
763
|
-
const prototype = Object.getPrototypeOf(value);
|
|
764
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
765
|
-
}
|
|
766
|
-
//#endregion
|
|
767
|
-
//#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/array/compact.mjs
|
|
768
|
-
function compact(array, strict) {
|
|
769
|
-
if (!Array.isArray(array)) return [];
|
|
770
|
-
if (strict === true) return array.filter(Boolean);
|
|
771
|
-
const { length } = array;
|
|
772
|
-
const compacted = [];
|
|
773
|
-
for (let index = 0; index < length; index += 1) {
|
|
774
|
-
const item = array[index];
|
|
775
|
-
if (item != null) compacted.push(item);
|
|
776
|
-
}
|
|
777
|
-
return compacted;
|
|
778
|
-
}
|
|
779
|
-
//#endregion
|
|
780
|
-
//#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
|
|
781
|
-
/**
|
|
782
|
-
* Get the string value from any value
|
|
783
|
-
* @param value Original value
|
|
784
|
-
* @returns String representation of the value
|
|
785
|
-
*/
|
|
786
|
-
function getString(value) {
|
|
787
|
-
if (typeof value === "string") return value;
|
|
788
|
-
if (value == null) return "";
|
|
789
|
-
if (typeof value === "function") return getString(value());
|
|
790
|
-
if (typeof value !== "object") return String(value);
|
|
791
|
-
const asString = String(value.valueOf?.() ?? value);
|
|
792
|
-
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
793
|
-
}
|
|
794
|
-
/**
|
|
795
|
-
* Join an array of values into a string
|
|
796
|
-
* @param value Array of values
|
|
797
|
-
* @param delimiter Delimiter to use between values
|
|
798
|
-
* @returns Joined string
|
|
799
|
-
*/
|
|
800
|
-
function join(value, delimiter) {
|
|
801
|
-
return compact(value).map(getString).join(typeof delimiter === "string" ? delimiter : "");
|
|
802
|
-
}
|
|
803
|
-
/**
|
|
804
|
-
* Split a string into words _(and other readable parts)_
|
|
805
|
-
* @param value Original string
|
|
806
|
-
* @returns Array of words found in the string
|
|
807
|
-
*/
|
|
808
|
-
function words(value) {
|
|
809
|
-
return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
|
|
810
|
-
}
|
|
811
|
-
const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
812
|
-
//#endregion
|
|
813
|
-
//#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/is.mjs
|
|
814
|
-
/**
|
|
815
|
-
* Is the value `undefined`, `null`, or a whitespace-only string?
|
|
816
|
-
* @param value Value to check
|
|
817
|
-
* @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
|
|
818
|
-
*/
|
|
819
|
-
function isNullableOrWhitespace(value) {
|
|
820
|
-
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
821
|
-
}
|
|
822
|
-
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
823
|
-
//#endregion
|
|
824
|
-
//#region node_modules/@oscarpalmer/toretto/node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
812
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
825
813
|
/**
|
|
826
814
|
* Clamp a number between a minimum and maximum value
|
|
827
815
|
* @param value Value to clamp
|
|
@@ -840,7 +828,7 @@ function clamp(value, minimum, maximum, loop) {
|
|
|
840
828
|
return value > maximum ? loop === true ? minimum : maximum : value;
|
|
841
829
|
}
|
|
842
830
|
//#endregion
|
|
843
|
-
//#region node_modules/@oscarpalmer/
|
|
831
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/sized.mjs
|
|
844
832
|
function getSizedMaximum(first, second) {
|
|
845
833
|
let actual;
|
|
846
834
|
if (typeof first === "number") actual = first;
|
|
@@ -850,7 +838,7 @@ function getSizedMaximum(first, second) {
|
|
|
850
838
|
const MAXIMUM_ABSOLUTE = 16777216;
|
|
851
839
|
const MAXIMUM_DEFAULT = 1048576;
|
|
852
840
|
//#endregion
|
|
853
|
-
//#region node_modules/@oscarpalmer/
|
|
841
|
+
//#region node_modules/@oscarpalmer/atoms/dist/sized/map.mjs
|
|
854
842
|
/**
|
|
855
843
|
* A Map with a maximum size
|
|
856
844
|
*
|
|
@@ -904,7 +892,10 @@ var SizedMap = class extends Map {
|
|
|
904
892
|
}
|
|
905
893
|
};
|
|
906
894
|
//#endregion
|
|
907
|
-
//#region node_modules/@oscarpalmer/
|
|
895
|
+
//#region node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
|
|
896
|
+
/**
|
|
897
|
+
* A memoized function, caching and retrieving results based on the its parameters _(or a custom cache key)_
|
|
898
|
+
*/
|
|
908
899
|
var Memoized = class {
|
|
909
900
|
#state;
|
|
910
901
|
/**
|
|
@@ -1000,7 +991,7 @@ function memoize(callback, options) {
|
|
|
1000
991
|
const DEFAULT_CACHE_SIZE = 1024;
|
|
1001
992
|
const SEPARATOR = "_";
|
|
1002
993
|
//#endregion
|
|
1003
|
-
//#region node_modules/@oscarpalmer/
|
|
994
|
+
//#region node_modules/@oscarpalmer/atoms/dist/string/case.mjs
|
|
1004
995
|
/**
|
|
1005
996
|
* Convert a string to camel case _(thisIsCamelCase)_
|
|
1006
997
|
* @param value String to convert
|
|
@@ -1079,16 +1070,23 @@ const delimiters = {
|
|
|
1079
1070
|
let memoizedCapitalize;
|
|
1080
1071
|
//#endregion
|
|
1081
1072
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
|
|
1082
|
-
function
|
|
1073
|
+
function ignoreSetAttribute(element, name) {
|
|
1074
|
+
if (element instanceof HTMLTextAreaElement && name === "value") return true;
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
function normalizeKey(key, style) {
|
|
1078
|
+
return style && key.startsWith(CSS_VARIABLE_PREFIX) ? key : kebabCase(key);
|
|
1079
|
+
}
|
|
1080
|
+
function setElementValue(element, first, second, third, callback, style) {
|
|
1083
1081
|
if (!isHTMLOrSVGElement(element)) return;
|
|
1084
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
1085
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
1082
|
+
if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
|
|
1083
|
+
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
|
|
1086
1084
|
}
|
|
1087
|
-
function setElementValues(element, first, second, third, callback) {
|
|
1085
|
+
function setElementValues(element, first, second, third, callback, style) {
|
|
1088
1086
|
if (!isHTMLOrSVGElement(element)) return;
|
|
1089
1087
|
const dispatch = third !== false;
|
|
1090
1088
|
if (typeof first === "string") {
|
|
1091
|
-
callback(element,
|
|
1089
|
+
callback(element, normalizeKey(first, style), second, dispatch);
|
|
1092
1090
|
return;
|
|
1093
1091
|
}
|
|
1094
1092
|
const isArray = Array.isArray(first);
|
|
@@ -1100,22 +1098,31 @@ function setElementValues(element, first, second, third, callback) {
|
|
|
1100
1098
|
const { length } = entries;
|
|
1101
1099
|
for (let index = 0; index < length; index += 1) {
|
|
1102
1100
|
const entry = entries[index];
|
|
1103
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element,
|
|
1101
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
1104
1102
|
}
|
|
1105
1103
|
}
|
|
1106
1104
|
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
1107
1105
|
if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
|
|
1108
|
-
else set.call(element, key, json ? JSON.stringify(value) :
|
|
1106
|
+
else if (!ignoreSetAttribute(element, key)) set.call(element, key, json ? JSON.stringify(value) : getString(value));
|
|
1109
1107
|
}
|
|
1108
|
+
const CSS_VARIABLE_PREFIX = "--";
|
|
1110
1109
|
//#endregion
|
|
1111
1110
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/property.mjs
|
|
1112
|
-
function
|
|
1111
|
+
function getPropertyValue(element, name, value) {
|
|
1112
|
+
if (isInputElement(element) && name === "value") return getString(value);
|
|
1113
|
+
return value;
|
|
1114
|
+
}
|
|
1115
|
+
function updateProperty(element, name, value, dispatch) {
|
|
1113
1116
|
let property = name;
|
|
1114
1117
|
if (!(property in element)) property = camelCase(name);
|
|
1115
|
-
|
|
1116
|
-
element[property]
|
|
1118
|
+
const next = getPropertyValue(element, name, value);
|
|
1119
|
+
if (!(property in element) || Object.is(element[property], next)) return;
|
|
1120
|
+
element[property] = next;
|
|
1117
1121
|
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
1118
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
1122
|
+
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
1123
|
+
bubbles: true,
|
|
1124
|
+
cancelable: true
|
|
1125
|
+
}));
|
|
1119
1126
|
}
|
|
1120
1127
|
const elementEvents = {
|
|
1121
1128
|
DETAILS: { open: "toggle" },
|
|
@@ -1151,7 +1158,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
1151
1158
|
let value;
|
|
1152
1159
|
if (isAttribute(first)) {
|
|
1153
1160
|
name = first.name;
|
|
1154
|
-
value =
|
|
1161
|
+
value = getString(first.value);
|
|
1155
1162
|
} else if (typeof first === "string" && typeof second === "string") {
|
|
1156
1163
|
name = first;
|
|
1157
1164
|
value = second;
|
|
@@ -1166,9 +1173,6 @@ function isAttribute(value) {
|
|
|
1166
1173
|
function _isBadAttribute(first, second, decode) {
|
|
1167
1174
|
return handleAttribute(badAttributeHandler, decode, first, second);
|
|
1168
1175
|
}
|
|
1169
|
-
function _isBooleanAttribute(first, decode) {
|
|
1170
|
-
return handleAttribute((name) => booleanAttributesSet.has(name?.toLowerCase()), decode, first, "");
|
|
1171
|
-
}
|
|
1172
1176
|
function _isInvalidBooleanAttribute(first, second, decode) {
|
|
1173
1177
|
return handleAttribute(booleanAttributeHandler, decode, first, second);
|
|
1174
1178
|
}
|
|
@@ -1179,7 +1183,7 @@ function updateAttribute(element, name, value, dispatch) {
|
|
|
1179
1183
|
const lowerCaseName = name.toLowerCase();
|
|
1180
1184
|
const isBoolean = booleanAttributesSet.has(lowerCaseName);
|
|
1181
1185
|
const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === lowerCaseName) : value == null ? "" : value;
|
|
1182
|
-
if (isBoolean || dispatchedAttributes.has(name)) updateProperty
|
|
1186
|
+
if (isBoolean || dispatchedAttributes.has(name)) updateProperty(element, name, next, dispatch);
|
|
1183
1187
|
updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
|
|
1184
1188
|
}
|
|
1185
1189
|
const EXPRESSION_CLOBBERED_NAME = /^(id|name)$/i;
|
|
@@ -1424,8 +1428,9 @@ window.templates = templates;
|
|
|
1424
1428
|
const ARRAY_COMPARISON_ADDED = "added";
|
|
1425
1429
|
const ARRAY_COMPARISON_DISSIMILAR = "dissimilar";
|
|
1426
1430
|
const ARRAY_COMPARISON_REMOVED = "removed";
|
|
1431
|
+
const CHANGE_INPUTS = new Set(["checkbox", "radio"]);
|
|
1427
1432
|
const ERROR_FRAGMENT = "Fragment function must return a Fragment instance";
|
|
1428
|
-
const ERROR_IDENTIFIER_DUPLICATE = "Duplicate identifier found: '
|
|
1433
|
+
const ERROR_IDENTIFIER_DUPLICATE = "Duplicate identifier found: '<>'";
|
|
1429
1434
|
const ERROR_IDENTIFIER_TYPE = "Identifier cannot be null or undefined";
|
|
1430
1435
|
const EVENT_CHANGE = "change";
|
|
1431
1436
|
const EVENT_INPUT = "input";
|
|
@@ -1438,39 +1443,23 @@ const EVENT_DEFAULTS = {
|
|
|
1438
1443
|
SELECT: EVENT_CHANGE,
|
|
1439
1444
|
TEXTAREA: EVENT_INPUT
|
|
1440
1445
|
};
|
|
1441
|
-
const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?[\w-]+)="<!--abydon.(\d+)-->"/g;
|
|
1442
|
-
const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^
|
|
1443
|
-
const EXPRESSION_ABYDON_CONTENT =
|
|
1446
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?[\w-.]+(?::[a-z:]+)?)="<!--abydon.(\d+)-->"/g;
|
|
1447
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^abydon-/;
|
|
1448
|
+
const EXPRESSION_ABYDON_CONTENT = /^abydon\.(\d+)$/;
|
|
1444
1449
|
const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
|
|
1445
1450
|
const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
|
|
1446
1451
|
const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
|
|
1447
|
-
const
|
|
1448
|
-
const
|
|
1449
|
-
const
|
|
1450
|
-
const
|
|
1451
|
-
const
|
|
1452
|
+
const EXPRESSION_ATTRIBUTE_STYLE_VARIABLE = /^style\.--/;
|
|
1453
|
+
const EXPRESSION_EVENT_ATTRIBUTE = /^@([\w-]+)(?::([a-z:]+))?="$/i;
|
|
1454
|
+
const EXPRESSION_EVENT_NAME = /^@?([\w-]+)(?::([a-z:]+))?$/i;
|
|
1455
|
+
const EXPRESSION_EVENT_OPTIONS_ACTIVE = /^a(?:ctive)$/i;
|
|
1456
|
+
const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(?:apture)$/i;
|
|
1457
|
+
const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(?:nce)$/i;
|
|
1452
1458
|
const EXPRESSION_EVENT_PREFIX = /^@/;
|
|
1453
|
-
const
|
|
1454
|
-
const EXPRESSION_TEXTAREA_VALUE = /<!--abydon\.(\d+)-->/;
|
|
1459
|
+
const EXPRESSION_TEXTAREA_VALUE = /(?:<|<)!--abydon\.(\d+)--(?:>|>)/;
|
|
1455
1460
|
const NAME_FRAGMENT = "$fragment";
|
|
1456
1461
|
const NAME_FRAGMENTS = "$fragments";
|
|
1457
|
-
const
|
|
1458
|
-
const PROPERTY_VALUE = "value";
|
|
1459
|
-
//#endregion
|
|
1460
|
-
//#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
|
|
1461
|
-
/**
|
|
1462
|
-
* Parse a JSON string into its proper value _(or `undefined` if it fails)_
|
|
1463
|
-
* @param value JSON string to parse
|
|
1464
|
-
* @param reviver Reviver function to transform the parsed values
|
|
1465
|
-
* @returns Parsed value or `undefined` if parsing fails
|
|
1466
|
-
*/
|
|
1467
|
-
function parse$1(value, reviver) {
|
|
1468
|
-
try {
|
|
1469
|
-
return JSON.parse(value, reviver);
|
|
1470
|
-
} catch {
|
|
1471
|
-
return;
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1462
|
+
const WHITESPACE = /\s+/g;
|
|
1474
1463
|
//#endregion
|
|
1475
1464
|
//#region src/helpers/index.ts
|
|
1476
1465
|
function compareArrays(first, second) {
|
|
@@ -1480,25 +1469,34 @@ function compareArrays(first, second) {
|
|
|
1480
1469
|
if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) return ARRAY_COMPARISON_DISSIMILAR;
|
|
1481
1470
|
return firstIsLarger ? ARRAY_COMPARISON_REMOVED : ARRAY_COMPARISON_ADDED;
|
|
1482
1471
|
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Is the value a _Fragment_?
|
|
1474
|
+
* @param value Value to check
|
|
1475
|
+
* @returns `true` if the value is a _Fragment_, otherwise `false`
|
|
1476
|
+
*/
|
|
1483
1477
|
function isFragment(value) {
|
|
1484
1478
|
return isNamed(value, NAME_FRAGMENT);
|
|
1485
1479
|
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Is the value a _Fragments_ instance?
|
|
1482
|
+
* @param value Value to check
|
|
1483
|
+
* @returns `true` if the value is a _Fragments_ instance, otherwise `false`
|
|
1484
|
+
*/
|
|
1486
1485
|
function isFragments(value) {
|
|
1487
1486
|
return isNamed(value, NAME_FRAGMENTS);
|
|
1488
1487
|
}
|
|
1489
1488
|
function isNamed(value, name) {
|
|
1490
1489
|
return typeof value === "object" && value != null && name in value && value[name] === true;
|
|
1491
1490
|
}
|
|
1491
|
+
function setComputedValue(data, callback, after) {
|
|
1492
|
+
const computation = computed(callback);
|
|
1493
|
+
data.mora.values.add(computation);
|
|
1494
|
+
after(computation);
|
|
1495
|
+
}
|
|
1492
1496
|
//#endregion
|
|
1493
1497
|
//#region src/fragments.ts
|
|
1494
1498
|
var Fragments = class {
|
|
1495
1499
|
#state;
|
|
1496
|
-
/**
|
|
1497
|
-
* Fragment items
|
|
1498
|
-
*/
|
|
1499
|
-
get items() {
|
|
1500
|
-
return this.#state.mapped;
|
|
1501
|
-
}
|
|
1502
1500
|
constructor(items, identify, fragment) {
|
|
1503
1501
|
Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
|
|
1504
1502
|
this.#state = {
|
|
@@ -1509,13 +1507,13 @@ var Fragments = class {
|
|
|
1509
1507
|
mapped: array([]),
|
|
1510
1508
|
subscriber: void 0
|
|
1511
1509
|
};
|
|
1512
|
-
|
|
1510
|
+
fragmentsStates.set(this, this.#state);
|
|
1513
1511
|
initializeFragments(this.#state);
|
|
1514
1512
|
}
|
|
1515
1513
|
};
|
|
1516
1514
|
function handleFragments(item, remove) {
|
|
1517
|
-
const state = isFragments(item) ?
|
|
1518
|
-
|
|
1515
|
+
const state = isFragments(item) ? fragmentsStates.get(item) : item;
|
|
1516
|
+
(remove ? removeFragments : initializeFragments)(state);
|
|
1519
1517
|
}
|
|
1520
1518
|
function handleItems(state, items) {
|
|
1521
1519
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -1525,14 +1523,14 @@ function handleItems(state, items) {
|
|
|
1525
1523
|
const item = items[index];
|
|
1526
1524
|
const identifier = state.identify(item);
|
|
1527
1525
|
if (identifier == null) throw new TypeError(ERROR_IDENTIFIER_TYPE);
|
|
1528
|
-
const key = getString
|
|
1526
|
+
const key = getString(identifier);
|
|
1529
1527
|
if (keys.has(key)) throw new Error(ERROR_IDENTIFIER_DUPLICATE.replace("<>", key));
|
|
1530
1528
|
let instance = state.instances[key];
|
|
1531
1529
|
if (instance == null) {
|
|
1532
1530
|
instance = state.fragment(item);
|
|
1533
1531
|
if (!isFragment(instance)) throw new Error(ERROR_FRAGMENT);
|
|
1534
1532
|
}
|
|
1535
|
-
instance.
|
|
1533
|
+
instance.configure({ identifier: key });
|
|
1536
1534
|
state.instances[key] = instance;
|
|
1537
1535
|
keys.add(key);
|
|
1538
1536
|
mapped.push(instance);
|
|
@@ -1545,7 +1543,7 @@ function initializeFragments(state) {
|
|
|
1545
1543
|
handleItems(state, items);
|
|
1546
1544
|
});
|
|
1547
1545
|
}
|
|
1548
|
-
function removeFragments
|
|
1546
|
+
function removeFragments(state) {
|
|
1549
1547
|
state.subscriber?.();
|
|
1550
1548
|
updateFragments(state);
|
|
1551
1549
|
state.subscriber = void 0;
|
|
@@ -1563,16 +1561,13 @@ function updateFragments(state, active) {
|
|
|
1563
1561
|
state.instances = next;
|
|
1564
1562
|
active?.clear();
|
|
1565
1563
|
}
|
|
1566
|
-
const
|
|
1564
|
+
const fragmentsStates = /* @__PURE__ */ new WeakMap();
|
|
1567
1565
|
//#endregion
|
|
1568
1566
|
//#region src/helpers/dom.ts
|
|
1569
1567
|
function createNodes(value) {
|
|
1570
1568
|
if (isFragment(value)) return value.get();
|
|
1571
1569
|
if (isChildNode(value)) return [value];
|
|
1572
|
-
return [new Text(getString
|
|
1573
|
-
}
|
|
1574
|
-
function isInputElement(node) {
|
|
1575
|
-
return node instanceof HTMLInputElement || node instanceof HTMLSelectElement;
|
|
1570
|
+
return [new Text(getString(value))];
|
|
1576
1571
|
}
|
|
1577
1572
|
function removeNodes(nodes) {
|
|
1578
1573
|
const { length } = nodes;
|
|
@@ -1582,6 +1577,7 @@ function replaceNodes(from, to) {
|
|
|
1582
1577
|
from[0]?.replaceWith(...to);
|
|
1583
1578
|
const { length } = from;
|
|
1584
1579
|
for (let index = 1; index < length; index += 1) from[index].remove();
|
|
1580
|
+
return to;
|
|
1585
1581
|
}
|
|
1586
1582
|
//#endregion
|
|
1587
1583
|
//#region node_modules/@oscarpalmer/toretto/dist/internal/get-value.mjs
|
|
@@ -1679,7 +1675,7 @@ const EVENT_TYPES = new Set([
|
|
|
1679
1675
|
const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
|
|
1680
1676
|
const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
|
|
1681
1677
|
//#endregion
|
|
1682
|
-
//#region node_modules/@oscarpalmer/
|
|
1678
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
1683
1679
|
/**
|
|
1684
1680
|
* A function that does nothing, which can be useful, I guess…
|
|
1685
1681
|
*/
|
|
@@ -1718,130 +1714,134 @@ function getOptions(options) {
|
|
|
1718
1714
|
function getType(element, type) {
|
|
1719
1715
|
if (type !== "on") return type;
|
|
1720
1716
|
if (element instanceof HTMLInputElement) {
|
|
1721
|
-
if (
|
|
1717
|
+
if (CHANGE_INPUTS.has(element.type)) return EVENT_CHANGE;
|
|
1722
1718
|
return element.type === "submit" ? EVENT_SUBMIT : EVENT_INPUT;
|
|
1723
1719
|
}
|
|
1724
1720
|
return EVENT_DEFAULTS[element.tagName] ?? type;
|
|
1725
1721
|
}
|
|
1726
1722
|
function mapEvent(element, name, value) {
|
|
1727
|
-
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name)
|
|
1728
|
-
|
|
1723
|
+
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name);
|
|
1724
|
+
const values = Array.isArray(value) ? value : [value];
|
|
1725
|
+
const { length } = values;
|
|
1726
|
+
for (let index = 0; index < length; index += 1) {
|
|
1727
|
+
const item = values[index];
|
|
1728
|
+
if (typeof item === "function") on(element, getType(element, type), item, getOptions(options ?? ""));
|
|
1729
|
+
}
|
|
1729
1730
|
}
|
|
1730
1731
|
//#endregion
|
|
1731
|
-
//#region node_modules/@oscarpalmer/toretto/dist/
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1732
|
+
//#region node_modules/@oscarpalmer/toretto/dist/style.mjs
|
|
1733
|
+
/**
|
|
1734
|
+
* Set a style on an element
|
|
1735
|
+
* @param element Element to set the style on
|
|
1736
|
+
* @param property Style name
|
|
1737
|
+
* @param value Style value
|
|
1738
|
+
*/
|
|
1739
|
+
function setStyle(element, property, value) {
|
|
1740
|
+
setElementValues(element, property, value, null, updateStyleProperty, true);
|
|
1741
|
+
}
|
|
1742
|
+
function updateStyleProperty(element, key, value) {
|
|
1743
|
+
updateElementValue(element, key, value, function(property, style) {
|
|
1744
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.setProperty(property, getString(style));
|
|
1745
|
+
else this.style[property] = getString(style);
|
|
1746
|
+
}, function(property) {
|
|
1747
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(property);
|
|
1748
|
+
else this.style[property] = "";
|
|
1749
|
+
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
1750
|
+
}, false, false);
|
|
1751
|
+
}
|
|
1752
|
+
const ATTRIBUTE_STYLE = "style";
|
|
1753
|
+
const VARIABLE_PREFIX = "--";
|
|
1735
1754
|
//#endregion
|
|
1736
|
-
//#region src/
|
|
1737
|
-
function
|
|
1738
|
-
if (
|
|
1739
|
-
return
|
|
1755
|
+
//#region src/attribute/value.ts
|
|
1756
|
+
function getStyleValue(value, unit, isVariable) {
|
|
1757
|
+
if (removeStyleValue(value, unit, isVariable)) return;
|
|
1758
|
+
return value === true || value === "true" ? unit : `${getString(value)}${unit ?? ""}`;
|
|
1759
|
+
}
|
|
1760
|
+
function removeStyleValue(value, unit, isVariable) {
|
|
1761
|
+
if (value == null || value === false || isVariable && isNullableOrWhitespace(value)) return true;
|
|
1762
|
+
return unit == null && (value === true || value === "true");
|
|
1740
1763
|
}
|
|
1741
1764
|
function setAttribute(data, element, name, value) {
|
|
1742
1765
|
switch (true) {
|
|
1743
1766
|
case EXPRESSION_ATTRIBUTE_CLASS.test(name):
|
|
1744
|
-
|
|
1767
|
+
setClassValues(data, element, name, value);
|
|
1745
1768
|
return;
|
|
1746
1769
|
case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
|
|
1747
|
-
|
|
1770
|
+
setStyleValues(data, element, name, value);
|
|
1748
1771
|
return;
|
|
1749
1772
|
default:
|
|
1750
1773
|
setValue(data, element, name, value);
|
|
1751
1774
|
break;
|
|
1752
1775
|
}
|
|
1753
1776
|
}
|
|
1754
|
-
function
|
|
1755
|
-
function update(value) {
|
|
1756
|
-
if (value === true) element.classList.add(...classes);
|
|
1757
|
-
else element.classList.remove(...classes);
|
|
1758
|
-
}
|
|
1777
|
+
function setClassValues(data, element, name, value) {
|
|
1759
1778
|
const classes = name.slice(6).split(".");
|
|
1760
|
-
|
|
1761
|
-
|
|
1779
|
+
updateValue(data, value, (value) => {
|
|
1780
|
+
if (value === true || value === "true") element.classList.add(...classes);
|
|
1781
|
+
else element.classList.remove(...classes);
|
|
1782
|
+
});
|
|
1762
1783
|
}
|
|
1763
|
-
function
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
}
|
|
1770
|
-
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
1771
|
-
else update(value);
|
|
1784
|
+
function setStyleValues(data, element, name, value) {
|
|
1785
|
+
let [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name);
|
|
1786
|
+
const isVariable = EXPRESSION_ATTRIBUTE_STYLE_VARIABLE.test(name);
|
|
1787
|
+
updateValue(data, value, (value) => {
|
|
1788
|
+
setStyle(element, property, getStyleValue(value, unit, isVariable));
|
|
1789
|
+
});
|
|
1772
1790
|
}
|
|
1773
1791
|
function setValue(data, element, name, value) {
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}));
|
|
1778
|
-
else callback(element, name, value);
|
|
1779
|
-
}
|
|
1780
|
-
function updateChecked(element, name, value) {
|
|
1781
|
-
updateElement(EVENT_CHANGE, PROPERTY_CHECKED, element, name, value, value === true);
|
|
1782
|
-
}
|
|
1783
|
-
function updateElement(event, property, element, name, value, next) {
|
|
1784
|
-
if (!(property in element) || element[property] === next) return;
|
|
1785
|
-
setAttribute$1(element, name, value);
|
|
1786
|
-
if (element[property] === next) return;
|
|
1787
|
-
element[property] = next;
|
|
1788
|
-
element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
1789
|
-
}
|
|
1790
|
-
function updateProperty(element, name, value) {
|
|
1791
|
-
setAttribute$1(element, name, value === true);
|
|
1792
|
+
updateValue(data, value, (value) => {
|
|
1793
|
+
setAttribute$1(element, name, value);
|
|
1794
|
+
});
|
|
1792
1795
|
}
|
|
1793
|
-
function updateValue(
|
|
1794
|
-
|
|
1796
|
+
function updateValue(data, value, updater) {
|
|
1797
|
+
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(updater));
|
|
1798
|
+
else updater(value);
|
|
1795
1799
|
}
|
|
1796
1800
|
//#endregion
|
|
1797
|
-
//#region src/
|
|
1801
|
+
//#region src/attribute/index.ts
|
|
1802
|
+
function compareAttributes(first, second) {
|
|
1803
|
+
return first.name.localeCompare(second.name);
|
|
1804
|
+
}
|
|
1798
1805
|
function getValue(data, original) {
|
|
1799
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(original
|
|
1806
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(original);
|
|
1800
1807
|
return matches == null ? original : data.values[+matches[1]];
|
|
1801
1808
|
}
|
|
1802
|
-
function
|
|
1803
|
-
|
|
1809
|
+
function mapAttributeValue(data, element, name, value) {
|
|
1810
|
+
if (typeof value === "function") setComputedAttribute(data, element, name, value);
|
|
1811
|
+
else setAttribute(data, element, name, value);
|
|
1812
|
+
if (isInputElement(element) && isSignal(value) && name in element) mapEvent(element, "on", () => {
|
|
1813
|
+
value.set(element[name]);
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
function mapAttributes(data, element, ignoreValue) {
|
|
1817
|
+
const attributes = [...element.attributes].sort(compareAttributes);
|
|
1804
1818
|
const { length } = attributes;
|
|
1805
1819
|
for (let index = 0; index < length; index += 1) {
|
|
1806
1820
|
const { name, value } = attributes[index];
|
|
1807
1821
|
const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, "");
|
|
1808
1822
|
const actualValue = getValue(data, value);
|
|
1809
1823
|
if (actualName !== name) element.removeAttribute(name);
|
|
1824
|
+
if (actualName === "value" && ignoreValue) continue;
|
|
1810
1825
|
switch (true) {
|
|
1811
1826
|
case EXPRESSION_EVENT_PREFIX.test(actualName):
|
|
1812
1827
|
mapEvent(element, actualName, actualValue);
|
|
1813
1828
|
break;
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
case isReactive(actualValue):
|
|
1817
|
-
mapValue$1(data, element, actualName, actualValue);
|
|
1829
|
+
default:
|
|
1830
|
+
mapAttributeValue(data, element, actualName, actualValue);
|
|
1818
1831
|
break;
|
|
1819
|
-
default: break;
|
|
1820
1832
|
}
|
|
1821
1833
|
}
|
|
1822
1834
|
}
|
|
1823
|
-
function mapValue$1(data, element, name, value) {
|
|
1824
|
-
if (typeof value === "function") setComputedAttribute(data, element, name, value);
|
|
1825
|
-
else setAttribute(data, element, name, value);
|
|
1826
|
-
if (!isInputElement(element) || !isSignal(value)) return;
|
|
1827
|
-
let property;
|
|
1828
|
-
if (name === "checked" && element.type === "checkbox") property = PROPERTY_CHECKED;
|
|
1829
|
-
else if (name === "value") property = PROPERTY_VALUE;
|
|
1830
|
-
if (property != null) mapEvent(element, "@on", () => {
|
|
1831
|
-
const next = element[property];
|
|
1832
|
-
value.set(parse$1(String(next)) ?? next);
|
|
1833
|
-
});
|
|
1834
|
-
}
|
|
1835
1835
|
function setComputedAttribute(data, element, name, callback) {
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1836
|
+
setComputedValue(data, callback, (computation) => {
|
|
1837
|
+
setAttribute(data, element, name, computation);
|
|
1838
|
+
});
|
|
1839
1839
|
}
|
|
1840
1840
|
//#endregion
|
|
1841
1841
|
//#region src/node/value.ts
|
|
1842
1842
|
function addToArray(identifiers, items, nodes, added) {
|
|
1843
1843
|
let position = nodes[0];
|
|
1844
|
-
const before = added && !identifiers.previous.has(items.templates[0].identifier);
|
|
1844
|
+
const before = added && !identifiers.previous.set.has(items.templates[0].identifier);
|
|
1845
1845
|
const next = items.next.flatMap((fragment) => fragment.get().flatMap((node) => ({
|
|
1846
1846
|
identifier: fragment.identifier,
|
|
1847
1847
|
value: node
|
|
@@ -1849,19 +1849,48 @@ function addToArray(identifiers, items, nodes, added) {
|
|
|
1849
1849
|
const { length } = next;
|
|
1850
1850
|
for (let index = 0; index < length; index += 1) {
|
|
1851
1851
|
const node = next[index];
|
|
1852
|
-
if (!(added && identifiers.previous.has(node.identifier))) if (index === 0 && before) position.before(node.value);
|
|
1852
|
+
if (!(added && identifiers.previous.set.has(node.identifier))) if (index === 0 && before) position.before(node.value);
|
|
1853
1853
|
else position.after(node.value);
|
|
1854
1854
|
position = node.value;
|
|
1855
1855
|
}
|
|
1856
1856
|
}
|
|
1857
|
+
function getArrayData(item, values) {
|
|
1858
|
+
const { length } = values;
|
|
1859
|
+
const next = [];
|
|
1860
|
+
let templates = [];
|
|
1861
|
+
for (let index = 0; index < length; index += 1) {
|
|
1862
|
+
const value = values[index];
|
|
1863
|
+
if (isFragment(value) && value.identifier != null) {
|
|
1864
|
+
next.push(value.identifier);
|
|
1865
|
+
templates.push(value);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
const previous = item.fragments?.map((fragment) => fragment.identifier) ?? [];
|
|
1869
|
+
const nextSet = new Set(next);
|
|
1870
|
+
if (nextSet.size !== templates.length) templates = [];
|
|
1871
|
+
return {
|
|
1872
|
+
next: {
|
|
1873
|
+
array: next,
|
|
1874
|
+
set: nextSet
|
|
1875
|
+
},
|
|
1876
|
+
previous: {
|
|
1877
|
+
array: previous,
|
|
1878
|
+
set: new Set(previous)
|
|
1879
|
+
},
|
|
1880
|
+
template: {
|
|
1881
|
+
empty: templates.length === 0,
|
|
1882
|
+
items: templates
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1857
1886
|
function handleArray(identifiers, items, nodes) {
|
|
1858
|
-
const next = items.templates.map((template) => items.fragments
|
|
1859
|
-
const comparison = compareArrays(
|
|
1887
|
+
const next = items.templates.map((template) => items.fragments.find((fragment) => fragment.identifier === template.identifier) ?? template);
|
|
1888
|
+
const comparison = compareArrays(identifiers.previous.array, identifiers.next.array);
|
|
1860
1889
|
if (comparison !== "removed") addToArray(identifiers, {
|
|
1861
1890
|
...items,
|
|
1862
1891
|
next
|
|
1863
1892
|
}, nodes, comparison === ARRAY_COMPARISON_ADDED);
|
|
1864
|
-
const toRemove = items.fragments
|
|
1893
|
+
const toRemove = items.fragments.filter((fragment) => !identifiers.next.set.has(fragment.identifier));
|
|
1865
1894
|
const { length } = toRemove;
|
|
1866
1895
|
for (let index = 0; index < length; index += 1) toRemove[index].remove();
|
|
1867
1896
|
return {
|
|
@@ -1869,87 +1898,72 @@ function handleArray(identifiers, items, nodes) {
|
|
|
1869
1898
|
nodes: next.flatMap((fragment) => fragment.get())
|
|
1870
1899
|
};
|
|
1871
1900
|
}
|
|
1872
|
-
function
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1901
|
+
function removeArray(item, comment) {
|
|
1902
|
+
const fragments = (item.fragments ?? []).slice();
|
|
1903
|
+
const result = { nodes: setText(item, comment) };
|
|
1904
|
+
removeFragmentsItems(fragments);
|
|
1905
|
+
return result;
|
|
1877
1906
|
}
|
|
1878
|
-
function
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
else to = item.text == null ? [] : [item.text];
|
|
1882
|
-
replaceNodes(item.nodes ?? [], to);
|
|
1907
|
+
function removeFragmentsItems(fragments) {
|
|
1908
|
+
const { length } = fragments;
|
|
1909
|
+
for (let index = 0; index < length; index += 1) fragments[index].remove();
|
|
1883
1910
|
}
|
|
1884
1911
|
function setArray(item, comment, value) {
|
|
1885
|
-
if (value.length === 0) return
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1912
|
+
if (value.length === 0) return removeArray(item, comment);
|
|
1913
|
+
const { next, previous, template } = getArrayData(item, value);
|
|
1914
|
+
if (template.empty || item.nodes == null || previous.array.some((identifier) => identifier == null)) {
|
|
1915
|
+
const fragments = (item.fragments ?? []).slice();
|
|
1916
|
+
const result = {
|
|
1917
|
+
fragments: template.empty ? void 0 : template.items,
|
|
1918
|
+
nodes: replaceNodes(item.nodes ?? [comment], template.empty ? value.flatMap((item) => createNodes(item)) : template.items.flatMap((template) => template.get()))
|
|
1919
|
+
};
|
|
1920
|
+
removeFragmentsItems(fragments);
|
|
1921
|
+
return result;
|
|
1922
|
+
}
|
|
1895
1923
|
return handleArray({
|
|
1896
|
-
next
|
|
1897
|
-
previous
|
|
1924
|
+
next,
|
|
1925
|
+
previous
|
|
1898
1926
|
}, {
|
|
1899
|
-
|
|
1900
|
-
|
|
1927
|
+
fragments: item.fragments ?? [],
|
|
1928
|
+
templates: template.items
|
|
1901
1929
|
}, item.nodes);
|
|
1902
1930
|
}
|
|
1903
1931
|
function setNodes(item, comment, next) {
|
|
1904
|
-
|
|
1905
|
-
if (comment.parentNode != null) replaceNodes([comment], next);
|
|
1906
|
-
else if (item.text?.parentNode != null) replaceNodes([item.text], next);
|
|
1907
|
-
} else replaceNodes(item.nodes, next);
|
|
1908
|
-
removeFragments(item.fragments);
|
|
1909
|
-
return next;
|
|
1932
|
+
return replaceNodes(item.nodes ?? [comment], next);
|
|
1910
1933
|
}
|
|
1911
1934
|
function setReactiveValue(data, comment, reactive) {
|
|
1912
1935
|
let item = data.items.find((item) => item.nodes?.includes(comment));
|
|
1913
1936
|
item ??= {};
|
|
1914
|
-
item.text = new Text();
|
|
1915
1937
|
data.mora.subscribers.add(reactive.subscribe((value) => {
|
|
1916
1938
|
if (Array.isArray(value)) setReactiveValueForArray(item, comment, value);
|
|
1917
1939
|
else setReactiveValueForSingle(item, comment, value);
|
|
1918
|
-
item.nodes = [...item.nodes ?? [comment]];
|
|
1919
1940
|
}));
|
|
1920
1941
|
}
|
|
1921
1942
|
function setReactiveValueForArray(item, comment, value) {
|
|
1922
|
-
const
|
|
1923
|
-
item.fragments =
|
|
1924
|
-
|
|
1925
|
-
else item.nodes = void 0;
|
|
1926
|
-
else item.nodes = result?.nodes;
|
|
1943
|
+
const { fragments, nodes } = setArray(item, comment, value);
|
|
1944
|
+
item.fragments = fragments;
|
|
1945
|
+
item.nodes = nodes;
|
|
1927
1946
|
}
|
|
1928
1947
|
function setReactiveValueForSingle(item, comment, value) {
|
|
1948
|
+
const fragments = (item.fragments ?? []).slice();
|
|
1929
1949
|
const valueIsFragment = isFragment(value);
|
|
1930
|
-
item.fragments = valueIsFragment ? [value] : void 0;
|
|
1931
1950
|
if (valueIsFragment || isChildNode(value)) item.nodes = setNodes(item, comment, createNodes(value));
|
|
1932
1951
|
else item.nodes = setText(item, comment, value);
|
|
1952
|
+
item.fragments = valueIsFragment ? [value] : void 0;
|
|
1953
|
+
removeFragmentsItems(fragments);
|
|
1933
1954
|
}
|
|
1934
1955
|
function setText(item, comment, value) {
|
|
1935
|
-
const
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
} else if (isNullable && comment.parentNode == null) item.text?.replaceWith(comment);
|
|
1942
|
-
else if (!isNullable && item?.text?.parentNode == null) {
|
|
1943
|
-
if (item.text != null) comment.replaceWith(item.text);
|
|
1944
|
-
result = true;
|
|
1945
|
-
}
|
|
1946
|
-
removeFragments(item.fragments);
|
|
1947
|
-
if (result) return item.text == null ? [] : [item.text];
|
|
1956
|
+
const valueIsNullable = isNullableOrWhitespace(value);
|
|
1957
|
+
item.text ??= new Text();
|
|
1958
|
+
item.text.textContent = valueIsNullable ? "" : getString(value);
|
|
1959
|
+
const result = valueIsNullable ? [comment] : [item.text];
|
|
1960
|
+
replaceNodes(item.nodes ?? [comment], result);
|
|
1961
|
+
return result;
|
|
1948
1962
|
}
|
|
1949
1963
|
//#endregion
|
|
1950
1964
|
//#region src/node/index.ts
|
|
1951
1965
|
function mapNode(data, comment) {
|
|
1952
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent
|
|
1966
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent);
|
|
1953
1967
|
const value = matches == null ? null : data.values[+matches[1]];
|
|
1954
1968
|
if (value != null) mapValue(data, comment, value);
|
|
1955
1969
|
}
|
|
@@ -1961,39 +1975,29 @@ function mapNodes(data, nodes) {
|
|
|
1961
1975
|
mapNode(data, node);
|
|
1962
1976
|
continue;
|
|
1963
1977
|
}
|
|
1964
|
-
if (node
|
|
1965
|
-
|
|
1978
|
+
if (isHTMLOrSVGElement(node)) {
|
|
1979
|
+
let ignoreValueAttribute = false;
|
|
1980
|
+
if (node instanceof HTMLTextAreaElement) ignoreValueAttribute = mapTextarea(data, node);
|
|
1981
|
+
mapAttributes(data, node, ignoreValueAttribute);
|
|
1982
|
+
}
|
|
1966
1983
|
if (node.hasChildNodes()) mapNodes(data, [...node.childNodes]);
|
|
1967
1984
|
}
|
|
1968
1985
|
}
|
|
1969
1986
|
function mapTextarea(data, element) {
|
|
1970
|
-
const [, index] = EXPRESSION_TEXTAREA_VALUE.exec(element.value) ?? [];
|
|
1971
|
-
if (index == null) return;
|
|
1987
|
+
const [, index] = EXPRESSION_TEXTAREA_VALUE.exec(element.textContent) ?? EXPRESSION_TEXTAREA_VALUE.exec(element.value) ?? [];
|
|
1988
|
+
if (index == null) return false;
|
|
1989
|
+
element.textContent = "";
|
|
1972
1990
|
element.value = "";
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
element.value = String(value.peek());
|
|
1976
|
-
mapEvent(element, "@on", () => {
|
|
1977
|
-
value.set(element.value);
|
|
1978
|
-
});
|
|
1979
|
-
return;
|
|
1980
|
-
}
|
|
1981
|
-
let reactive;
|
|
1982
|
-
if (typeof value === "function") reactive = computed(value);
|
|
1983
|
-
else if (isComputed(value)) reactive = value;
|
|
1984
|
-
if (reactive == null) element.value = String(value);
|
|
1985
|
-
else data.mora.subscribers.add(reactive.subscribe((value) => {
|
|
1986
|
-
element.value = String(value);
|
|
1987
|
-
}));
|
|
1991
|
+
mapAttributeValue(data, element, "value", data.values[Number.parseInt(index, 10)]);
|
|
1992
|
+
return true;
|
|
1988
1993
|
}
|
|
1989
1994
|
function mapValue(data, comment, value) {
|
|
1990
1995
|
switch (true) {
|
|
1991
1996
|
case typeof value === "function":
|
|
1992
|
-
|
|
1997
|
+
setComputedNode(data, comment, value);
|
|
1993
1998
|
break;
|
|
1994
1999
|
case isFragments(value):
|
|
1995
|
-
|
|
1996
|
-
setReactiveValue(data, comment, value.items);
|
|
2000
|
+
setFragmentsNode(data, comment, value);
|
|
1997
2001
|
break;
|
|
1998
2002
|
case isReactive(value):
|
|
1999
2003
|
setReactiveValue(data, comment, value);
|
|
@@ -2012,22 +2016,29 @@ function replaceComment(data, comment, value) {
|
|
|
2012
2016
|
}
|
|
2013
2017
|
comment.replaceWith(...nodes);
|
|
2014
2018
|
}
|
|
2015
|
-
function
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
+
function setComputedNode(data, comment, callback) {
|
|
2020
|
+
setComputedValue(data, callback, (computation) => {
|
|
2021
|
+
setReactiveValue(data, comment, computation);
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
function setFragmentsNode(data, comment, fragments) {
|
|
2025
|
+
const state = fragmentsStates.get(fragments);
|
|
2026
|
+
handleFragments(state, false);
|
|
2027
|
+
setReactiveValue(data, comment, state.mapped);
|
|
2019
2028
|
}
|
|
2020
2029
|
//#endregion
|
|
2021
2030
|
//#region src/parse.ts
|
|
2022
2031
|
function handleExpression(data, prefix, expression) {
|
|
2023
2032
|
if (Array.isArray(expression)) {
|
|
2033
|
+
if (EXPRESSION_EVENT_ATTRIBUTE.test(prefix.split(WHITESPACE).at(-1))) return transformExpression(prefix, data.values.push(expression) - 1);
|
|
2024
2034
|
const { length } = expression;
|
|
2025
2035
|
let expressions = "";
|
|
2026
2036
|
for (let index = 0; index < length; index += 1) expressions += handleExpression(data, "", expression[index]);
|
|
2027
2037
|
return `${prefix}${expressions}`;
|
|
2028
2038
|
}
|
|
2029
2039
|
if (typeof expression === "function" || typeof expression === "object" && expression != null) return transformExpression(prefix, data.values.push(expression) - 1);
|
|
2030
|
-
|
|
2040
|
+
const asString = getString(expression);
|
|
2041
|
+
return asString.trim().length === 0 ? prefix : `${prefix}${asString}`;
|
|
2031
2042
|
}
|
|
2032
2043
|
function parse(data) {
|
|
2033
2044
|
if (data.template != null) return data.template;
|
|
@@ -2040,7 +2051,7 @@ function parse(data) {
|
|
|
2040
2051
|
return data.template;
|
|
2041
2052
|
}
|
|
2042
2053
|
function transformAttribute(_, name, index) {
|
|
2043
|
-
return `
|
|
2054
|
+
return `abydon-${name}="abydon.${index}"`;
|
|
2044
2055
|
}
|
|
2045
2056
|
function transformExpression(prefix, index) {
|
|
2046
2057
|
return `${prefix}<!--abydon.${index}-->`;
|
|
@@ -2054,7 +2065,15 @@ var Fragment = class {
|
|
|
2054
2065
|
cache: true
|
|
2055
2066
|
};
|
|
2056
2067
|
/**
|
|
2057
|
-
*
|
|
2068
|
+
* Is template caching enabled?
|
|
2069
|
+
*/
|
|
2070
|
+
get cache() {
|
|
2071
|
+
return this.#configuration.cache;
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* Identifier for the _Fragment_
|
|
2075
|
+
*
|
|
2076
|
+
* _An identifier can be used to uniquely identify a Fragment, which helps prevent re-rendering in reactive arrays and Fragments_
|
|
2058
2077
|
*/
|
|
2059
2078
|
get identifier() {
|
|
2060
2079
|
return this.#configuration.identifier;
|
|
@@ -2073,25 +2092,41 @@ var Fragment = class {
|
|
|
2073
2092
|
};
|
|
2074
2093
|
}
|
|
2075
2094
|
/**
|
|
2076
|
-
*
|
|
2095
|
+
* Insert the _Fragment_ after the given element
|
|
2096
|
+
* @param element Element to insert after
|
|
2097
|
+
*/
|
|
2098
|
+
after(element) {
|
|
2099
|
+
element.after(...this.get());
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Append the _Fragment_ to the given element
|
|
2077
2103
|
* @param element Element to append to
|
|
2078
2104
|
*/
|
|
2079
2105
|
appendTo(element) {
|
|
2080
2106
|
element.append(...this.get());
|
|
2081
2107
|
}
|
|
2082
2108
|
/**
|
|
2083
|
-
*
|
|
2109
|
+
* Insert the _Fragment_ before the given element
|
|
2110
|
+
* @param element Element to insert before
|
|
2111
|
+
*/
|
|
2112
|
+
before(element) {
|
|
2113
|
+
element.before(...this.get());
|
|
2114
|
+
}
|
|
2115
|
+
/**
|
|
2116
|
+
* Configure the _Fragment_
|
|
2117
|
+
*
|
|
2118
|
+
* _Returns the Fragment instance for chaining_
|
|
2084
2119
|
* @param configuration Configuration options
|
|
2085
|
-
* @returns
|
|
2120
|
+
* @returns _Fragment_
|
|
2086
2121
|
*/
|
|
2087
2122
|
configure(configuration) {
|
|
2088
|
-
const actual = isPlainObject
|
|
2123
|
+
const actual = isPlainObject(configuration) ? configuration : {};
|
|
2089
2124
|
if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
|
|
2090
2125
|
if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
|
|
2091
2126
|
return this;
|
|
2092
2127
|
}
|
|
2093
2128
|
/**
|
|
2094
|
-
* Get a list of the
|
|
2129
|
+
* Get a list of the _Fragment_'s nodes
|
|
2095
2130
|
* @returns List of nodes
|
|
2096
2131
|
*/
|
|
2097
2132
|
get() {
|
|
@@ -2099,24 +2134,22 @@ var Fragment = class {
|
|
|
2099
2134
|
if (data.items.length === 0) {
|
|
2100
2135
|
const templated = html$1(parse(data), { cache: this.#configuration.cache });
|
|
2101
2136
|
data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
|
|
2102
|
-
mapNodes(data, data.items.flatMap((item) => item.
|
|
2137
|
+
mapNodes(data, data.items.flatMap((item) => item.nodes));
|
|
2103
2138
|
}
|
|
2104
|
-
return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes
|
|
2139
|
+
return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes);
|
|
2105
2140
|
}
|
|
2106
2141
|
/**
|
|
2107
|
-
*
|
|
2108
|
-
*
|
|
2109
|
-
* _An identifier can be used to uniquely identify a fragment,
|
|
2110
|
-
* which helps prevent re-rendering in certain scenarios._
|
|
2111
|
-
* @param identifier Identifier
|
|
2112
|
-
* @returns Fragment
|
|
2142
|
+
* Prepend the _Fragment_ to the given element
|
|
2143
|
+
* @param element Element to prepend to
|
|
2113
2144
|
*/
|
|
2114
|
-
|
|
2115
|
-
this
|
|
2116
|
-
return this;
|
|
2145
|
+
prependTo(element) {
|
|
2146
|
+
element.prepend(...this.get());
|
|
2117
2147
|
}
|
|
2118
2148
|
/**
|
|
2119
|
-
* Remove the
|
|
2149
|
+
* Remove the _Fragment_ _(and all its descendants)_ from the _DOM_
|
|
2150
|
+
*
|
|
2151
|
+
* - _Any events, reactive values, and Fragments will also be cleaned up and removed_
|
|
2152
|
+
* - _After being removed, the Fragment can be re-inserted into the DOM_
|
|
2120
2153
|
*/
|
|
2121
2154
|
remove() {
|
|
2122
2155
|
removeFragment(this.#data);
|
|
@@ -2129,7 +2162,7 @@ function removeFragment(data) {
|
|
|
2129
2162
|
const { fragments, nodes } = data.items[index];
|
|
2130
2163
|
const fragmentsLength = fragments?.length ?? 0;
|
|
2131
2164
|
for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) fragments?.[fragmentIndex]?.remove();
|
|
2132
|
-
removeNodes(nodes
|
|
2165
|
+
removeNodes(nodes);
|
|
2133
2166
|
}
|
|
2134
2167
|
data.items.length = 0;
|
|
2135
2168
|
length = data.values.length;
|
|
@@ -2147,21 +2180,51 @@ function removeMora(data) {
|
|
|
2147
2180
|
//#endregion
|
|
2148
2181
|
//#region src/index.ts
|
|
2149
2182
|
/**
|
|
2150
|
-
* Create
|
|
2183
|
+
* Create a _Fragments_ instance from a reactive array
|
|
2184
|
+
*
|
|
2185
|
+
* _A Fragments instance can be used to efficiently render a list of items that may change over time, using unique identifiers to track each item, only adding, removing, or updating each related Fragment._
|
|
2186
|
+
*
|
|
2187
|
+
* @example
|
|
2188
|
+
* ```ts
|
|
2189
|
+
* const fruits = array(['Apple', 'Banana', 'Cherry']);
|
|
2190
|
+
* const items = fragments(
|
|
2191
|
+
* fruits,
|
|
2192
|
+
* fruit => fruit, // Identifies a unique item
|
|
2193
|
+
* fruit => html`<p>${fruit}</p>`, // Creates a Fragment from an item
|
|
2194
|
+
* );
|
|
2195
|
+
* html`${items}`.appendTo(document.body) // Renders '<p>Apple</p><p>Banana</p><p>Cherry</p>'
|
|
2196
|
+
* fruits.push(['Date', 'Elderberry', 'Fig']); // Appends '<p>Date</p><p>Elderberry</p><p>Fig</p>'
|
|
2197
|
+
* // without re-rendering the existing Fragments
|
|
2198
|
+
* ```
|
|
2199
|
+
*
|
|
2151
2200
|
* @param array Reactive array
|
|
2152
|
-
* @param identify Function to identify item
|
|
2153
|
-
* @param fragment Function to create
|
|
2154
|
-
* @returns
|
|
2201
|
+
* @param identify Function to identify item uniquely _(non-nullable)_
|
|
2202
|
+
* @param fragment Function to create _Fragment_ from item
|
|
2203
|
+
* @returns _Fragments_
|
|
2155
2204
|
*/
|
|
2156
2205
|
function fragments(array, identify, fragment) {
|
|
2206
|
+
if (!isArray(array)) throw new TypeError("Fragments array must be a reactive array");
|
|
2207
|
+
if (typeof identify !== "function") throw new TypeError("Fragments identify must be a function");
|
|
2208
|
+
if (typeof fragment !== "function") throw new TypeError("Fragments fragment must be a function");
|
|
2157
2209
|
return new Fragments(array, identify, fragment);
|
|
2158
2210
|
}
|
|
2159
2211
|
/**
|
|
2160
|
-
* Create
|
|
2161
|
-
*
|
|
2212
|
+
* Create a _Fragment_ from a template
|
|
2213
|
+
*
|
|
2214
|
+
* _A Fragment can be used to efficiently render a template that may change over time, only updating the necessary parts of the DOM._
|
|
2215
|
+
*
|
|
2216
|
+
* @example
|
|
2217
|
+
* ```ts
|
|
2218
|
+
* const name = signal('World');
|
|
2219
|
+
* const fragment = html`<p>Hello, ${name}!</p>`;
|
|
2220
|
+
* fragment.appendTo(document.body); // Renders '<p>Hello, World!</p>'
|
|
2221
|
+
* name.set('Alice'); // Replaces 'World' with 'Alice'
|
|
2222
|
+
* ```
|
|
2223
|
+
*
|
|
2224
|
+
* @returns _Fragment_
|
|
2162
2225
|
*/
|
|
2163
2226
|
function html(template, ...values) {
|
|
2164
2227
|
return new Fragment(template, values);
|
|
2165
2228
|
}
|
|
2166
2229
|
//#endregion
|
|
2167
|
-
export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|
|
2230
|
+
export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isFragment, isFragments, isReactive, isSignal, signal, startBatch, stopBatch, store };
|