native-document 1.0.16 → 1.0.18

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.
@@ -324,6 +324,251 @@ var NativeDocument = (function (exports) {
324
324
  return '{{#ObItem::(' +this.$memoryId+ ')}}';
325
325
  };
326
326
 
327
+ /**
328
+ *
329
+ * @param {*} item
330
+ * @param {string|null} defaultKey
331
+ * @param {?Function} key
332
+ * @returns {*}
333
+ */
334
+ const getKey = (item, defaultKey, key) => {
335
+ if(Validator.isFunction(key)) return key(item, defaultKey);
336
+ if(Validator.isObservable(item)) {
337
+ const val = item.val();
338
+ return (val && key) ? val[key] : defaultKey;
339
+ }
340
+ if(!Validator.isObject(item)) {
341
+ return item;
342
+ }
343
+ return item[key] ?? defaultKey;
344
+ };
345
+
346
+ const trim = function(str, char) {
347
+ return str.replace(new RegExp(`^[${char}]+|[${char}]+$`, 'g'), '');
348
+ };
349
+
350
+ const DocumentObserver = {
351
+ mounted: new WeakMap(),
352
+ mountedSupposedSize: 0,
353
+ unmounted: new WeakMap(),
354
+ unmountedSupposedSize: 0,
355
+ observer: null,
356
+ checkMutation: function(mutationsList) {
357
+ for(const mutation of mutationsList) {
358
+ if(DocumentObserver.mountedSupposedSize > 0 ) {
359
+ for(const node of mutation.addedNodes) {
360
+ const data = DocumentObserver.mounted.get(node);
361
+ if(!data) {
362
+ continue;
363
+ }
364
+ data.inDom = true;
365
+ data.mounted && data.mounted(node);
366
+ }
367
+ }
368
+
369
+ if(DocumentObserver.unmountedSupposedSize > 0 ) {
370
+ for(const node of mutation.removedNodes) {
371
+ const data = DocumentObserver.unmounted.get(node);
372
+ if(!data) {
373
+ continue;
374
+ }
375
+
376
+ data.inDom = false;
377
+ if(data.unmounted && data.unmounted(node) === true) {
378
+ data.disconnect();
379
+ node.nd?.remove();
380
+ }
381
+ }
382
+ }
383
+ }
384
+ },
385
+ /**
386
+ *
387
+ * @param {HTMLElement} element
388
+ * @param {boolean} inDom
389
+ * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
390
+ */
391
+ watch: function(element, inDom = false) {
392
+ let data = {
393
+ inDom,
394
+ mounted: null,
395
+ unmounted: null,
396
+ disconnect: () => {
397
+ DocumentObserver.mounted.delete(element);
398
+ DocumentObserver.unmounted.delete(element);
399
+ DocumentObserver.mountedSupposedSize--;
400
+ DocumentObserver.unmountedSupposedSize--;
401
+ data = null;
402
+ }
403
+ };
404
+
405
+ return {
406
+ disconnect: data.disconnect,
407
+ mounted: (callback) => {
408
+ data.mounted = callback;
409
+ DocumentObserver.mounted.set(element, data);
410
+ DocumentObserver.mountedSupposedSize++;
411
+ },
412
+ unmounted: (callback) => {
413
+ data.unmounted = callback;
414
+ DocumentObserver.unmounted.set(element, data);
415
+ DocumentObserver.unmountedSupposedSize++;
416
+ }
417
+ };
418
+ }
419
+ };
420
+
421
+ DocumentObserver.observer = new MutationObserver(DocumentObserver.checkMutation);
422
+ DocumentObserver.observer.observe(document.body, {
423
+ childList: true,
424
+ subtree: true,
425
+ });
426
+
427
+ const EVENTS = [
428
+ "Click",
429
+ "DblClick",
430
+ "MouseDown",
431
+ "MouseEnter",
432
+ "MouseLeave",
433
+ "MouseMove",
434
+ "MouseOut",
435
+ "MouseOver",
436
+ "MouseUp",
437
+ "Wheel",
438
+ "KeyDown",
439
+ "KeyPress",
440
+ "KeyUp",
441
+ "Blur",
442
+ "Change",
443
+ "Focus",
444
+ "Input",
445
+ "Invalid",
446
+ "Reset",
447
+ "Search",
448
+ "Select",
449
+ "Submit",
450
+ "Drag",
451
+ "DragEnd",
452
+ "DragEnter",
453
+ "DragLeave",
454
+ "DragOver",
455
+ "DragStart",
456
+ "Drop",
457
+ "AfterPrint",
458
+ "BeforePrint",
459
+ "BeforeUnload",
460
+ "Error",
461
+ "HashChange",
462
+ "Load",
463
+ "Offline",
464
+ "Online",
465
+ "PageHide",
466
+ "PageShow",
467
+ "Resize",
468
+ "Scroll",
469
+ "Unload",
470
+ "Abort",
471
+ "CanPlay",
472
+ "CanPlayThrough",
473
+ "DurationChange",
474
+ "Emptied",
475
+ "Ended",
476
+ "LoadedData",
477
+ "LoadedMetadata",
478
+ "LoadStart",
479
+ "Pause",
480
+ "Play",
481
+ "Playing",
482
+ "Progress",
483
+ "RateChange",
484
+ "Seeked",
485
+ "Seeking",
486
+ "Stalled",
487
+ "Suspend",
488
+ "TimeUpdate",
489
+ "VolumeChange",
490
+ "Waiting"
491
+ ];
492
+
493
+ function NDElement(element) {
494
+ this.$element = element;
495
+ this.$observer = null;
496
+ }
497
+
498
+ for(const event of EVENTS) {
499
+ const eventName = event.toLowerCase();
500
+ NDElement.prototype['on'+event] = function(callback) {
501
+ this.$element.addEventListener(eventName, callback);
502
+ return this;
503
+ };
504
+ NDElement.prototype['onPrevent'+event] = function(callback) {
505
+ this.$element.addEventListener(eventName, function(event) {
506
+ event.preventDefault();
507
+ callback(event);
508
+ });
509
+ return this;
510
+ };
511
+ NDElement.prototype['onStop'+event] = function(callback) {
512
+ this.$element.addEventListener(eventName, function(event) {
513
+ event.stopPropagation();
514
+ callback(event);
515
+ });
516
+ return this;
517
+ };
518
+ NDElement.prototype['onPreventStop'+event] = function(callback) {
519
+ this.$element.addEventListener(eventName, function(event) {
520
+ event.stopPropagation();
521
+ event.preventDefault();
522
+ callback(event);
523
+ });
524
+ return this;
525
+ };
526
+ }
527
+
528
+ NDElement.prototype.ref = function(target, name) {
529
+ target[name] = element;
530
+ return this;
531
+ };
532
+
533
+ NDElement.prototype.unmountChildren = function() {
534
+ let element = this.$element;
535
+ for(let i = 0, length = element.children.length; i < length; i++) {
536
+ let elementchildren = element.children[i];
537
+ if(!elementchildren.$ndProx) {
538
+ elementchildren.nd?.remove();
539
+ }
540
+ elementchildren = null;
541
+ }
542
+ element = null;
543
+ return this;
544
+ };
545
+
546
+ NDElement.prototype.remove = function() {
547
+ let element = this.$element;
548
+ element.nd.unmountChildren();
549
+ element.$ndProx = null;
550
+ delete element.nd?.on?.prevent;
551
+ delete element.nd?.on;
552
+ delete element.nd;
553
+ element = null;
554
+ return this;
555
+ };
556
+
557
+ NDElement.prototype.lifecycle = function(states) {
558
+ this.$observer = this.$observer || DocumentObserver.watch(this.$element);
559
+
560
+ states.mounted && this.$observer.mounted(states.mounted);
561
+ states.unmounted && this.$observer.unmounted(states.unmounted);
562
+ return this;
563
+ };
564
+ NDElement.prototype.mounted = function(callback) {
565
+ return this.lifecycle({ mounted: callback });
566
+ };
567
+
568
+ NDElement.prototype.mounted = function(callback) {
569
+ return this.lifecycle({ unmounted: callback });
570
+ };
571
+
327
572
  const Validator = {
328
573
  isObservable(value) {
329
574
  return value instanceof ObservableItem || value instanceof ObservableChecker;
@@ -367,13 +612,16 @@ var NativeDocument = (function (exports) {
367
612
  isStringOrObservable(value) {
368
613
  return this.isString(value) || this.isObservable(value);
369
614
  },
370
-
371
615
  isValidChild(child) {
372
616
  return child === null ||
373
617
  this.isElement(child) ||
374
618
  this.isObservable(child) ||
619
+ this.isNDElement(child) ||
375
620
  ['string', 'number', 'boolean'].includes(typeof child);
376
621
  },
622
+ isNDElement(child) {
623
+ return child instanceof NDElement;
624
+ },
377
625
  isValidChildren(children) {
378
626
  if (!Array.isArray(children)) {
379
627
  children = [children];
@@ -439,16 +687,6 @@ var NativeDocument = (function (exports) {
439
687
  }
440
688
  };
441
689
 
442
- const getChildAsNode = (child) => {
443
- if(Validator.isFunction(child)) {
444
- return getChildAsNode(child());
445
- }
446
- if(Validator.isElement(child)) {
447
- return child;
448
- }
449
- return createTextNode(child)
450
- };
451
-
452
690
  function Anchor(name) {
453
691
  const element = document.createDocumentFragment();
454
692
 
@@ -463,10 +701,10 @@ var NativeDocument = (function (exports) {
463
701
 
464
702
  const insertBefore = function(parent, child, target) {
465
703
  if(parent === element) {
466
- parent.nativeInsertBefore(getChildAsNode(child), target);
704
+ parent.nativeInsertBefore(ElementCreator.getChild(child), target);
467
705
  return;
468
706
  }
469
- parent.insertBefore(getChildAsNode(child), target);
707
+ parent.insertBefore(ElementCreator.getChild(child), target);
470
708
  };
471
709
 
472
710
  element.appendElement = function(child, before = null) {
@@ -487,7 +725,7 @@ var NativeDocument = (function (exports) {
487
725
  if(Validator.isArray(child)) {
488
726
  const fragment = document.createDocumentFragment();
489
727
  for(let i = 0, length = child.length; i < length; i++) {
490
- fragment.appendChild(getChildAsNode(child[i]));
728
+ fragment.appendChild(ElementCreator.getChild(child[i]));
491
729
  }
492
730
  insertBefore(parent, fragment, before);
493
731
  return element;
@@ -566,61 +804,6 @@ var NativeDocument = (function (exports) {
566
804
 
567
805
  const BOOLEAN_ATTRIBUTES = ['checked', 'selected', 'disabled', 'readonly', 'required', 'autofocus', 'multiple', 'autocomplete', 'hidden', 'contenteditable', 'spellcheck', 'translate', 'draggable', 'async', 'defer', 'autoplay', 'controls', 'loop', 'muted', 'download', 'reversed', 'open', 'default', 'formnovalidate', 'novalidate', 'scoped', 'itemscope', 'allowfullscreen', 'allowpaymentrequest', 'playsinline'];
568
806
 
569
- const invoke = function(fn, args, context) {
570
- if(context) {
571
- fn.apply(context, args);
572
- } else {
573
- fn(...args);
574
- }
575
- };
576
- /**
577
- *
578
- * @param {Function} fn
579
- * @param {number} delay
580
- * @param {{leading?:Boolean, trailing?:Boolean, debounce?:Boolean, check: Function}}options
581
- * @returns {(function(...[*]): void)|*}
582
- */
583
- const debounce = function(fn, delay, options = {}) {
584
- let timer = null;
585
- let lastArgs = null;
586
-
587
- return function(...args) {
588
- const context = options.context === true ? this : null;
589
- if(options.check) {
590
- options.check(...args);
591
- }
592
- lastArgs = args;
593
-
594
- // debounce mode: reset the timer for each call
595
- clearTimeout(timer);
596
- timer = setTimeout(() => invoke(fn, lastArgs, context), delay);
597
- }
598
- };
599
-
600
-
601
- /**
602
- *
603
- * @param {*} item
604
- * @param {string|null} defaultKey
605
- * @param {?Function} key
606
- * @returns {*}
607
- */
608
- const getKey = (item, defaultKey, key) => {
609
- if(Validator.isFunction(key)) return key(item, defaultKey);
610
- if(Validator.isObservable(item)) {
611
- const val = item.val();
612
- return (val && key) ? val[key] : defaultKey;
613
- }
614
- if(!Validator.isObject(item)) {
615
- return item;
616
- }
617
- return item[key] ?? defaultKey;
618
- };
619
-
620
- const trim = function(str, char) {
621
- return str.replace(new RegExp(`^[${char}]+|[${char}]+$`, 'g'), '');
622
- };
623
-
624
807
  /**
625
808
  *
626
809
  * @param {*} value
@@ -872,31 +1055,41 @@ var NativeDocument = (function (exports) {
872
1055
  const childrenArray = Array.isArray(children) ? children : [children];
873
1056
 
874
1057
  for(let i = 0, length = childrenArray.length; i < length; i++) {
875
- let child = childrenArray[i];
1058
+ let child = this.getChild(childrenArray[i]);
876
1059
  if (child === null) continue;
877
- if(Validator.isString(child) && Validator.isFunction(child.resolveObservableTemplate)) {
878
- child = child.resolveObservableTemplate();
879
- }
880
- if(Validator.isFunction(child)) {
881
- this.processChildren(child(), parent);
882
- continue;
883
- }
884
- if(Validator.isArray(child)) {
885
- this.processChildren(child, parent);
886
- continue;
887
- }
888
- if (Validator.isElement(child)) {
889
- parent.appendChild(child);
890
- continue;
891
- }
892
- if (Validator.isObservable(child)) {
893
- ElementCreator.createObservableNode(parent, child);
894
- continue;
895
- }
896
- if (child) {
897
- ElementCreator.createStaticTextNode(parent, child);
1060
+ parent.appendChild(child);
1061
+ }
1062
+ },
1063
+ getChild(child) {
1064
+ if(child === null) {
1065
+ return null;
1066
+ }
1067
+ if(Validator.isString(child) && Validator.isFunction(child.resolveObservableTemplate)) {
1068
+ child = child.resolveObservableTemplate();
1069
+ }
1070
+ if(Validator.isString(child)) {
1071
+ return ElementCreator.createStaticTextNode(null, child);
1072
+ }
1073
+ if (Validator.isObservable(child)) {
1074
+ return ElementCreator.createObservableNode(null, child);
1075
+ }
1076
+ if(Validator.isArray(child)) {
1077
+ const fragment = document.createDocumentFragment();
1078
+ for(let i = 0, length = child.length; i < length; i++) {
1079
+ fragment.appendChild(this.getChild(child[i]));
898
1080
  }
1081
+ return fragment;
1082
+ }
1083
+ if(Validator.isFunction(child)) {
1084
+ return this.getChild(child());
1085
+ }
1086
+ if (Validator.isElement(child)) {
1087
+ return child;
899
1088
  }
1089
+ if(Validator.isNDElement(child)) {
1090
+ return child.$element;
1091
+ }
1092
+ return ElementCreator.createStaticTextNode(null, child);
900
1093
  },
901
1094
  /**
902
1095
  *
@@ -921,199 +1114,18 @@ var NativeDocument = (function (exports) {
921
1114
  }
922
1115
  };
923
1116
 
924
- const DocumentObserver = {
925
- mounted: new WeakMap(),
926
- mountedSupposedSize: 0,
927
- unmounted: new WeakMap(),
928
- unmountedSupposedSize: 0,
929
- observer: null,
930
- checkMutation: debounce(function(mutationsList) {
931
- for(const mutation of mutationsList) {
932
- if(DocumentObserver.mountedSupposedSize > 0 ) {
933
- for(const node of mutation.addedNodes) {
934
- const data = DocumentObserver.mounted.get(node);
935
- if(!data) {
936
- continue;
937
- }
938
- data.inDom = true;
939
- data.mounted && data.mounted(node);
940
- }
941
- }
942
-
943
- if(DocumentObserver.unmountedSupposedSize > 0 ) {
944
- for(const node of mutation.removedNodes) {
945
- const data = DocumentObserver.unmounted.get(node);
946
- if(!data) {
947
- continue;
948
- }
949
-
950
- data.inDom = false;
951
- if(data.unmounted && data.unmounted(node) === true) {
952
- data.disconnect();
953
- node.nd?.remove();
954
- }
955
- }
956
- }
957
- }
958
- }, 16),
959
- /**
960
- *
961
- * @param {HTMLElement} element
962
- * @param {boolean} inDom
963
- * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
964
- */
965
- watch: function(element, inDom = false) {
966
- let data = {
967
- inDom,
968
- mounted: null,
969
- unmounted: null,
970
- disconnect: () => {
971
- DocumentObserver.mounted.delete(element);
972
- DocumentObserver.unmounted.delete(element);
973
- DocumentObserver.mountedSupposedSize--;
974
- DocumentObserver.unmountedSupposedSize--;
975
- data = null;
976
- }
977
- };
978
-
979
- return {
980
- disconnect: data.disconnect,
981
- mounted: (callback) => {
982
- data.mounted = callback;
983
- DocumentObserver.mounted.set(element, data);
984
- DocumentObserver.mountedSupposedSize++;
985
- },
986
- unmounted: (callback) => {
987
- data.unmounted = callback;
988
- DocumentObserver.unmounted.set(element, data);
989
- DocumentObserver.unmountedSupposedSize++;
990
- }
991
- };
992
- }
993
- };
994
-
995
- DocumentObserver.observer = new MutationObserver(DocumentObserver.checkMutation);
996
- DocumentObserver.observer.observe(document.body, {
997
- childList: true,
998
- subtree: true,
999
- });
1000
-
1001
1117
  Object.defineProperty(HTMLElement.prototype, 'nd', {
1002
1118
  get() {
1003
- if(this.$ndProx) {
1004
- return this.$ndProx;
1005
- }
1006
- let element = this;
1007
- let lifecycle = null;
1008
-
1009
- this.$ndProx = new Proxy({}, {
1010
- get(target, property) {
1011
- if(/^on[A-Z]/.test(property)) {
1012
- const event = property.replace(/^on/, '').toLowerCase();
1013
- const shouldPrevent = event.toLowerCase().startsWith('prevent');
1014
- let eventName = event.replace(/^prevent/i, '');
1015
- const shouldStop = event.toLowerCase().startsWith('stop');
1016
- eventName = eventName.replace(/^stop/i, '');
1017
-
1018
- return function(callback) {
1019
- if(shouldPrevent && !shouldStop) {
1020
- element.addEventListener(eventName, function(event) {
1021
- event.preventDefault();
1022
- callback(event);
1023
- });
1024
- return element;
1025
- }
1026
- if(!shouldPrevent && shouldStop) {
1027
- element.addEventListener(eventName, function(event) {
1028
- event.stopPropagation();
1029
- callback(event);
1030
- });
1031
- return element;
1032
- }
1033
- if(shouldPrevent && shouldStop) {
1034
- element.addEventListener(eventName, function(event) {
1035
- event.preventDefault();
1036
- event.stopPropagation();
1037
- callback(event);
1038
- });
1039
- return element;
1040
- }
1041
- element.addEventListener(eventName, callback);
1042
- return element;
1043
- };
1044
- }
1045
- if(property === 'ref') {
1046
- return function(target, name) {
1047
- target[name] = element;
1048
- return element;
1049
- };
1050
- }
1051
- if(property === 'unmountChildren') {
1052
- return () => {
1053
- for(let i = 0, length = element.children.length; i < length; i++) {
1054
- let elementchildren = element.children[i];
1055
- if(!elementchildren.$ndProx) {
1056
- elementchildren.nd?.remove();
1057
- }
1058
- elementchildren = null;
1059
- }
1060
- };
1061
- }
1062
- if(property === 'remove') {
1063
- return function() {
1064
- element.nd.unmountChildren();
1065
- lifecycle = null;
1066
- element.$ndProx = null;
1067
- delete element.nd?.on?.prevent;
1068
- delete element.nd?.on;
1069
- delete element.nd;
1070
- };
1071
- }
1072
- if(property === 'hasLifecycle') {
1073
- return lifecycle !== null;
1074
- }
1075
- if(property === 'lifecycle') {
1076
- if(lifecycle) {
1077
- return lifecycle;
1078
- }
1079
- let $observer = null;
1080
- lifecycle = function(states) {
1081
- $observer = $observer || DocumentObserver.watch(element);
1082
-
1083
- states.mounted && $observer.mounted(states.mounted);
1084
- states.unmounted && $observer.unmounted(states.unmounted);
1085
- return element;
1086
- };
1087
- return lifecycle;
1088
- }
1089
- if(property === 'mounted' || property === 'unmounted') {
1090
- return function(callback) {
1091
- element.nd.lifecycle({ [property]: callback});
1092
- return element;
1093
- };
1094
- }
1095
- },
1096
- set(target, p, newValue, receiver) {
1119
+ if(this.$nd) {
1120
+ return this.$nd;
1121
+ }
1097
1122
 
1098
- },
1099
- configurable: true
1100
- });
1101
- return this.$ndProx;
1123
+ this.$nd = new NDElement(this);
1124
+ this.$nd.nd = this.$nd;
1125
+ return this.$nd;
1102
1126
  }
1103
1127
  });
1104
1128
 
1105
- /**
1106
- *
1107
- * @param {*} value
1108
- * @returns {Text}
1109
- */
1110
- const createTextNode = function(value) {
1111
- return (Validator.isObservable(value))
1112
- ? ElementCreator.createObservableNode(null, value)
1113
- : ElementCreator.createStaticTextNode(null, value);
1114
- };
1115
-
1116
-
1117
1129
  /**
1118
1130
  *
1119
1131
  * @param {string} name
@@ -1123,9 +1135,9 @@ var NativeDocument = (function (exports) {
1123
1135
  function HtmlElementWrapper(name, customWrapper) {
1124
1136
  const $tagName = name.toLowerCase();
1125
1137
 
1126
- const builder = function(attributes, children = null) {
1138
+ return function(attributes, children = null) {
1127
1139
  try {
1128
- if(Validator.isValidChildren(attributes)) {
1140
+ if(!Validator.isJson(attributes)) {
1129
1141
  const tempChildren = children;
1130
1142
  children = attributes;
1131
1143
  attributes = tempChildren;
@@ -1141,10 +1153,6 @@ var NativeDocument = (function (exports) {
1141
1153
  DebugManager.error('ElementCreation', `Error creating ${$tagName}`, error);
1142
1154
  }
1143
1155
  };
1144
-
1145
- builder.hold = (children, attributes) => (() => builder(children, attributes));
1146
-
1147
- return builder;
1148
1156
  }
1149
1157
 
1150
1158
  class ArgTypesError extends Error {
@@ -1280,7 +1288,7 @@ var NativeDocument = (function (exports) {
1280
1288
 
1281
1289
  String.prototype.resolveObservableTemplate = function() {
1282
1290
  if(!Validator.containsObservableReference(this)) {
1283
- return this;
1291
+ return this.valueOf();
1284
1292
  }
1285
1293
  return this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map((value) => {
1286
1294
  if(!Validator.containsObservableReference(value)) {
@@ -1318,6 +1326,13 @@ var NativeDocument = (function (exports) {
1318
1326
  return true;
1319
1327
  };
1320
1328
 
1329
+ observer.merge = function(values) {
1330
+ observer.$value = [...observer.$value, ...values];
1331
+ };
1332
+
1333
+ observer.populateAndRender = function(iteration, callback) {
1334
+ observer.trigger({ action: 'populate', args: [observer.$value, iteration, callback] });
1335
+ };
1321
1336
  observer.remove = function(index) {
1322
1337
  const deleted = observer.$value.splice(index, 1);
1323
1338
  if(deleted.length === 0) {
@@ -1640,10 +1655,7 @@ var NativeDocument = (function (exports) {
1640
1655
 
1641
1656
  try {
1642
1657
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1643
- let child = callback(item, indexObserver);
1644
- if(Validator.isStringOrObservable(child)) {
1645
- child = createTextNode(child);
1646
- }
1658
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1647
1659
  cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
1648
1660
  } catch (e) {
1649
1661
  DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
@@ -1810,10 +1822,7 @@ var NativeDocument = (function (exports) {
1810
1822
 
1811
1823
  try {
1812
1824
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1813
- let child = callback(item, indexObserver);
1814
- if(Validator.isStringOrObservable(child)) {
1815
- child = createTextNode(child);
1816
- }
1825
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1817
1826
  cache.set(keyId, {
1818
1827
  keyId,
1819
1828
  isNew: true,
@@ -1901,15 +1910,28 @@ var NativeDocument = (function (exports) {
1901
1910
  child = null;
1902
1911
  },
1903
1912
  clear,
1913
+ merge(items) {
1914
+ Actions.add(items, 0);
1915
+ },
1904
1916
  push(items) {
1905
1917
  let delay = 0;
1906
1918
  if(configs.pushDelay) {
1907
1919
  delay = configs.pushDelay(items) ?? 0;
1908
- } else {
1909
- delay = (items.length >= 1000) ? 10 : 0;
1910
1920
  }
1921
+
1911
1922
  Actions.add(items, delay);
1912
1923
  },
1924
+ populate([target, iteration, callback]) {
1925
+ const fragment = document.createDocumentFragment();
1926
+ for (let i = 0; i < iteration; i++) {
1927
+ const data = callback(i);
1928
+ target.push(data);
1929
+ fragment.append(buildItem(data, i));
1930
+ lastNumberOfItems++;
1931
+ }
1932
+ element.appendChild(fragment);
1933
+ fragment.replaceChildren();
1934
+ },
1913
1935
  unshift(values){
1914
1936
  element.insertBefore(Actions.toFragment(values), blockStart.nextSibling);
1915
1937
  },
@@ -1974,23 +1996,30 @@ var NativeDocument = (function (exports) {
1974
1996
  };
1975
1997
 
1976
1998
  const buildContent = (items, _, operations) => {
1977
- if(operations.action === 'clear' || !items.length) {
1978
- if(lastNumberOfItems === 0) {
1979
- return;
1999
+ if(operations?.action === 'populate') {
2000
+ Actions.populate(operations.args, operations.result);
2001
+ } else {
2002
+ console.log(lastNumberOfItems);
2003
+ if(operations.action === 'clear' || !items.length) {
2004
+ if(lastNumberOfItems === 0) {
2005
+ return;
2006
+ }
2007
+ clear();
1980
2008
  }
1981
- clear();
1982
- }
1983
2009
 
1984
- if(!operations?.action) {
1985
- if(lastNumberOfItems === 0) {
1986
- Actions.add(items);
1987
- return;
2010
+ if(!operations?.action) {
2011
+ if(lastNumberOfItems === 0) {
2012
+ Actions.add(items);
2013
+ return;
2014
+ }
2015
+ Actions.replace(items);
2016
+ }
2017
+ else if(Actions[operations.action]) {
2018
+ Actions[operations.action](operations.args, operations.result);
1988
2019
  }
1989
- Actions.replace(items);
1990
- }
1991
- else if(Actions[operations.action]) {
1992
- Actions[operations.action](operations.args, operations.result);
1993
2020
  }
2021
+
2022
+ console.log(items);
1994
2023
  updateIndexObservers(items, 0);
1995
2024
  };
1996
2025
 
@@ -2021,15 +2050,7 @@ var NativeDocument = (function (exports) {
2021
2050
  if(childElement) {
2022
2051
  return childElement;
2023
2052
  }
2024
- if(typeof child === 'function') {
2025
- childElement = child();
2026
- }
2027
- else {
2028
- childElement = child;
2029
- }
2030
- if(Validator.isStringOrObservable(childElement)) {
2031
- childElement = createTextNode(childElement);
2032
- }
2053
+ childElement = ElementCreator.getChild(child);
2033
2054
  return childElement;
2034
2055
  };
2035
2056
 
@@ -2080,9 +2101,10 @@ var NativeDocument = (function (exports) {
2080
2101
  *
2081
2102
  * @param {ObservableItem|ObservableChecker} $condition
2082
2103
  * @param {{[key]: *}} values
2104
+ * @param {Boolean} shouldKeepInCache
2083
2105
  * @returns {DocumentFragment}
2084
2106
  */
2085
- const Match = function($condition, values) {
2107
+ const Match = function($condition, values, shouldKeepInCache = true) {
2086
2108
 
2087
2109
  if(!Validator.isObservable($condition)) {
2088
2110
  throw new NativeDocumentError("Toggle : condition must be an Observable");
@@ -2092,17 +2114,15 @@ var NativeDocument = (function (exports) {
2092
2114
  const cache = new Map();
2093
2115
 
2094
2116
  const getItem = function(key) {
2095
- if(cache.has(key)) {
2117
+ if(shouldKeepInCache && cache.has(key)) {
2096
2118
  return cache.get(key);
2097
2119
  }
2098
2120
  let item = values[key];
2099
2121
  if(!item) {
2100
2122
  return null;
2101
2123
  }
2102
- if(Validator.isFunction(item)) {
2103
- item = item();
2104
- }
2105
- cache.set(key, item);
2124
+ item = ElementCreator.getChild(item);
2125
+ shouldKeepInCache && cache.set(key, item);
2106
2126
  return item;
2107
2127
  };
2108
2128