native-document 1.0.16 → 1.0.17

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,283 @@ var NativeDocument = (function (exports) {
324
324
  return '{{#ObItem::(' +this.$memoryId+ ')}}';
325
325
  };
326
326
 
327
+ const invoke = function(fn, args, context) {
328
+ if(context) {
329
+ fn.apply(context, args);
330
+ } else {
331
+ fn(...args);
332
+ }
333
+ };
334
+ /**
335
+ *
336
+ * @param {Function} fn
337
+ * @param {number} delay
338
+ * @param {{leading?:Boolean, trailing?:Boolean, debounce?:Boolean, check: Function}}options
339
+ * @returns {(function(...[*]): void)|*}
340
+ */
341
+ const debounce = function(fn, delay, options = {}) {
342
+ let timer = null;
343
+ let lastArgs = null;
344
+
345
+ return function(...args) {
346
+ const context = options.context === true ? this : null;
347
+ if(options.check) {
348
+ options.check(...args);
349
+ }
350
+ lastArgs = args;
351
+
352
+ // debounce mode: reset the timer for each call
353
+ clearTimeout(timer);
354
+ timer = setTimeout(() => invoke(fn, lastArgs, context), delay);
355
+ }
356
+ };
357
+
358
+
359
+ /**
360
+ *
361
+ * @param {*} item
362
+ * @param {string|null} defaultKey
363
+ * @param {?Function} key
364
+ * @returns {*}
365
+ */
366
+ const getKey = (item, defaultKey, key) => {
367
+ if(Validator.isFunction(key)) return key(item, defaultKey);
368
+ if(Validator.isObservable(item)) {
369
+ const val = item.val();
370
+ return (val && key) ? val[key] : defaultKey;
371
+ }
372
+ if(!Validator.isObject(item)) {
373
+ return item;
374
+ }
375
+ return item[key] ?? defaultKey;
376
+ };
377
+
378
+ const trim = function(str, char) {
379
+ return str.replace(new RegExp(`^[${char}]+|[${char}]+$`, 'g'), '');
380
+ };
381
+
382
+ const DocumentObserver = {
383
+ mounted: new WeakMap(),
384
+ mountedSupposedSize: 0,
385
+ unmounted: new WeakMap(),
386
+ unmountedSupposedSize: 0,
387
+ observer: null,
388
+ checkMutation: debounce(function(mutationsList) {
389
+ for(const mutation of mutationsList) {
390
+ if(DocumentObserver.mountedSupposedSize > 0 ) {
391
+ for(const node of mutation.addedNodes) {
392
+ const data = DocumentObserver.mounted.get(node);
393
+ if(!data) {
394
+ continue;
395
+ }
396
+ data.inDom = true;
397
+ data.mounted && data.mounted(node);
398
+ }
399
+ }
400
+
401
+ if(DocumentObserver.unmountedSupposedSize > 0 ) {
402
+ for(const node of mutation.removedNodes) {
403
+ const data = DocumentObserver.unmounted.get(node);
404
+ if(!data) {
405
+ continue;
406
+ }
407
+
408
+ data.inDom = false;
409
+ if(data.unmounted && data.unmounted(node) === true) {
410
+ data.disconnect();
411
+ node.nd?.remove();
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }, 16),
417
+ /**
418
+ *
419
+ * @param {HTMLElement} element
420
+ * @param {boolean} inDom
421
+ * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
422
+ */
423
+ watch: function(element, inDom = false) {
424
+ let data = {
425
+ inDom,
426
+ mounted: null,
427
+ unmounted: null,
428
+ disconnect: () => {
429
+ DocumentObserver.mounted.delete(element);
430
+ DocumentObserver.unmounted.delete(element);
431
+ DocumentObserver.mountedSupposedSize--;
432
+ DocumentObserver.unmountedSupposedSize--;
433
+ data = null;
434
+ }
435
+ };
436
+
437
+ return {
438
+ disconnect: data.disconnect,
439
+ mounted: (callback) => {
440
+ data.mounted = callback;
441
+ DocumentObserver.mounted.set(element, data);
442
+ DocumentObserver.mountedSupposedSize++;
443
+ },
444
+ unmounted: (callback) => {
445
+ data.unmounted = callback;
446
+ DocumentObserver.unmounted.set(element, data);
447
+ DocumentObserver.unmountedSupposedSize++;
448
+ }
449
+ };
450
+ }
451
+ };
452
+
453
+ DocumentObserver.observer = new MutationObserver(DocumentObserver.checkMutation);
454
+ DocumentObserver.observer.observe(document.body, {
455
+ childList: true,
456
+ subtree: true,
457
+ });
458
+
459
+ const EVENTS = [
460
+ "Click",
461
+ "DblClick",
462
+ "MouseDown",
463
+ "MouseEnter",
464
+ "MouseLeave",
465
+ "MouseMove",
466
+ "MouseOut",
467
+ "MouseOver",
468
+ "MouseUp",
469
+ "Wheel",
470
+ "KeyDown",
471
+ "KeyPress",
472
+ "KeyUp",
473
+ "Blur",
474
+ "Change",
475
+ "Focus",
476
+ "Input",
477
+ "Invalid",
478
+ "Reset",
479
+ "Search",
480
+ "Select",
481
+ "Submit",
482
+ "Drag",
483
+ "DragEnd",
484
+ "DragEnter",
485
+ "DragLeave",
486
+ "DragOver",
487
+ "DragStart",
488
+ "Drop",
489
+ "AfterPrint",
490
+ "BeforePrint",
491
+ "BeforeUnload",
492
+ "Error",
493
+ "HashChange",
494
+ "Load",
495
+ "Offline",
496
+ "Online",
497
+ "PageHide",
498
+ "PageShow",
499
+ "Resize",
500
+ "Scroll",
501
+ "Unload",
502
+ "Abort",
503
+ "CanPlay",
504
+ "CanPlayThrough",
505
+ "DurationChange",
506
+ "Emptied",
507
+ "Ended",
508
+ "LoadedData",
509
+ "LoadedMetadata",
510
+ "LoadStart",
511
+ "Pause",
512
+ "Play",
513
+ "Playing",
514
+ "Progress",
515
+ "RateChange",
516
+ "Seeked",
517
+ "Seeking",
518
+ "Stalled",
519
+ "Suspend",
520
+ "TimeUpdate",
521
+ "VolumeChange",
522
+ "Waiting"
523
+ ];
524
+
525
+ function NDElement(element) {
526
+ this.$element = element;
527
+ this.$observer = null;
528
+ }
529
+
530
+ for(const event of EVENTS) {
531
+ const eventName = event.toLowerCase();
532
+ NDElement.prototype['on'+event] = function(callback) {
533
+ this.$element.addEventListener(eventName, callback);
534
+ return this;
535
+ };
536
+ NDElement.prototype['onPrevent'+event] = function(callback) {
537
+ this.$element.addEventListener(eventName, function(event) {
538
+ event.preventDefault();
539
+ callback(event);
540
+ });
541
+ return this;
542
+ };
543
+ NDElement.prototype['onStop'+event] = function(callback) {
544
+ this.$element.addEventListener(eventName, function(event) {
545
+ event.stopPropagation();
546
+ callback(event);
547
+ });
548
+ return this;
549
+ };
550
+ NDElement.prototype['onPreventStop'+event] = function(callback) {
551
+ this.$element.addEventListener(eventName, function(event) {
552
+ event.stopPropagation();
553
+ event.preventDefault();
554
+ callback(event);
555
+ });
556
+ return this;
557
+ };
558
+ }
559
+
560
+ NDElement.prototype.ref = function(target, name) {
561
+ target[name] = element;
562
+ return this;
563
+ };
564
+
565
+ NDElement.prototype.unmountChildren = function() {
566
+ let element = this.$element;
567
+ for(let i = 0, length = element.children.length; i < length; i++) {
568
+ let elementchildren = element.children[i];
569
+ if(!elementchildren.$ndProx) {
570
+ elementchildren.nd?.remove();
571
+ }
572
+ elementchildren = null;
573
+ }
574
+ element = null;
575
+ return this;
576
+ };
577
+
578
+ NDElement.prototype.remove = function() {
579
+ let element = this.$element;
580
+ element.nd.unmountChildren();
581
+ element.$ndProx = null;
582
+ delete element.nd?.on?.prevent;
583
+ delete element.nd?.on;
584
+ delete element.nd;
585
+ element = null;
586
+ return this;
587
+ };
588
+
589
+ NDElement.prototype.lifecycle = function(states) {
590
+ this.$observer = this.$observer || DocumentObserver.watch(this.$element);
591
+
592
+ states.mounted && this.$observer.mounted(states.mounted);
593
+ states.unmounted && this.$observer.unmounted(states.unmounted);
594
+ return this;
595
+ };
596
+ NDElement.prototype.mounted = function(callback) {
597
+ return this.lifecycle({ mounted: callback });
598
+ };
599
+
600
+ NDElement.prototype.mounted = function(callback) {
601
+ return this.lifecycle({ unmounted: callback });
602
+ };
603
+
327
604
  const Validator = {
328
605
  isObservable(value) {
329
606
  return value instanceof ObservableItem || value instanceof ObservableChecker;
@@ -367,13 +644,16 @@ var NativeDocument = (function (exports) {
367
644
  isStringOrObservable(value) {
368
645
  return this.isString(value) || this.isObservable(value);
369
646
  },
370
-
371
647
  isValidChild(child) {
372
648
  return child === null ||
373
649
  this.isElement(child) ||
374
650
  this.isObservable(child) ||
651
+ this.isNDElement(child) ||
375
652
  ['string', 'number', 'boolean'].includes(typeof child);
376
653
  },
654
+ isNDElement(child) {
655
+ return child instanceof NDElement;
656
+ },
377
657
  isValidChildren(children) {
378
658
  if (!Array.isArray(children)) {
379
659
  children = [children];
@@ -439,16 +719,6 @@ var NativeDocument = (function (exports) {
439
719
  }
440
720
  };
441
721
 
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
722
  function Anchor(name) {
453
723
  const element = document.createDocumentFragment();
454
724
 
@@ -463,10 +733,10 @@ var NativeDocument = (function (exports) {
463
733
 
464
734
  const insertBefore = function(parent, child, target) {
465
735
  if(parent === element) {
466
- parent.nativeInsertBefore(getChildAsNode(child), target);
736
+ parent.nativeInsertBefore(ElementCreator.getChild(child), target);
467
737
  return;
468
738
  }
469
- parent.insertBefore(getChildAsNode(child), target);
739
+ parent.insertBefore(ElementCreator.getChild(child), target);
470
740
  };
471
741
 
472
742
  element.appendElement = function(child, before = null) {
@@ -487,7 +757,7 @@ var NativeDocument = (function (exports) {
487
757
  if(Validator.isArray(child)) {
488
758
  const fragment = document.createDocumentFragment();
489
759
  for(let i = 0, length = child.length; i < length; i++) {
490
- fragment.appendChild(getChildAsNode(child[i]));
760
+ fragment.appendChild(ElementCreator.getChild(child[i]));
491
761
  }
492
762
  insertBefore(parent, fragment, before);
493
763
  return element;
@@ -566,61 +836,6 @@ var NativeDocument = (function (exports) {
566
836
 
567
837
  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
838
 
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
839
  /**
625
840
  *
626
841
  * @param {*} value
@@ -872,31 +1087,41 @@ var NativeDocument = (function (exports) {
872
1087
  const childrenArray = Array.isArray(children) ? children : [children];
873
1088
 
874
1089
  for(let i = 0, length = childrenArray.length; i < length; i++) {
875
- let child = childrenArray[i];
1090
+ let child = this.getChild(childrenArray[i]);
876
1091
  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);
1092
+ parent.appendChild(child);
1093
+ }
1094
+ },
1095
+ getChild(child) {
1096
+ if(child === null) {
1097
+ return null;
1098
+ }
1099
+ if(Validator.isString(child) && Validator.isFunction(child.resolveObservableTemplate)) {
1100
+ child = child.resolveObservableTemplate();
1101
+ }
1102
+ if(Validator.isString(child)) {
1103
+ return ElementCreator.createStaticTextNode(null, child);
1104
+ }
1105
+ if (Validator.isObservable(child)) {
1106
+ return ElementCreator.createObservableNode(null, child);
1107
+ }
1108
+ if(Validator.isArray(child)) {
1109
+ const fragment = document.createDocumentFragment();
1110
+ for(let i = 0, length = child.length; i < length; i++) {
1111
+ fragment.appendChild(this.getChild(child[i]));
898
1112
  }
1113
+ return fragment;
1114
+ }
1115
+ if(Validator.isFunction(child)) {
1116
+ return this.getChild(child());
1117
+ }
1118
+ if (Validator.isElement(child)) {
1119
+ return child;
899
1120
  }
1121
+ if(Validator.isNDElement(child)) {
1122
+ return child.$element;
1123
+ }
1124
+ return ElementCreator.createStaticTextNode(null, child);
900
1125
  },
901
1126
  /**
902
1127
  *
@@ -921,199 +1146,18 @@ var NativeDocument = (function (exports) {
921
1146
  }
922
1147
  };
923
1148
 
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
1149
  Object.defineProperty(HTMLElement.prototype, 'nd', {
1002
1150
  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) {
1151
+ if(this.$nd) {
1152
+ return this.$nd;
1153
+ }
1097
1154
 
1098
- },
1099
- configurable: true
1100
- });
1101
- return this.$ndProx;
1155
+ this.$nd = new NDElement(this);
1156
+ this.$nd.nd = this.$nd;
1157
+ return this.$nd;
1102
1158
  }
1103
1159
  });
1104
1160
 
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
1161
  /**
1118
1162
  *
1119
1163
  * @param {string} name
@@ -1123,9 +1167,9 @@ var NativeDocument = (function (exports) {
1123
1167
  function HtmlElementWrapper(name, customWrapper) {
1124
1168
  const $tagName = name.toLowerCase();
1125
1169
 
1126
- const builder = function(attributes, children = null) {
1170
+ return function(attributes, children = null) {
1127
1171
  try {
1128
- if(Validator.isValidChildren(attributes)) {
1172
+ if(!Validator.isJson(attributes)) {
1129
1173
  const tempChildren = children;
1130
1174
  children = attributes;
1131
1175
  attributes = tempChildren;
@@ -1141,10 +1185,6 @@ var NativeDocument = (function (exports) {
1141
1185
  DebugManager.error('ElementCreation', `Error creating ${$tagName}`, error);
1142
1186
  }
1143
1187
  };
1144
-
1145
- builder.hold = (children, attributes) => (() => builder(children, attributes));
1146
-
1147
- return builder;
1148
1188
  }
1149
1189
 
1150
1190
  class ArgTypesError extends Error {
@@ -1280,7 +1320,7 @@ var NativeDocument = (function (exports) {
1280
1320
 
1281
1321
  String.prototype.resolveObservableTemplate = function() {
1282
1322
  if(!Validator.containsObservableReference(this)) {
1283
- return this;
1323
+ return this.valueOf();
1284
1324
  }
1285
1325
  return this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map((value) => {
1286
1326
  if(!Validator.containsObservableReference(value)) {
@@ -1318,6 +1358,13 @@ var NativeDocument = (function (exports) {
1318
1358
  return true;
1319
1359
  };
1320
1360
 
1361
+ observer.merge = function(values) {
1362
+ observer.$value = [...observer.$value, ...values];
1363
+ };
1364
+
1365
+ observer.populateAndRender = function(iteration, callback) {
1366
+ observer.trigger({ action: 'populate', args: [observer.$value, iteration, callback] });
1367
+ };
1321
1368
  observer.remove = function(index) {
1322
1369
  const deleted = observer.$value.splice(index, 1);
1323
1370
  if(deleted.length === 0) {
@@ -1640,10 +1687,7 @@ var NativeDocument = (function (exports) {
1640
1687
 
1641
1688
  try {
1642
1689
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1643
- let child = callback(item, indexObserver);
1644
- if(Validator.isStringOrObservable(child)) {
1645
- child = createTextNode(child);
1646
- }
1690
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1647
1691
  cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
1648
1692
  } catch (e) {
1649
1693
  DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
@@ -1810,10 +1854,7 @@ var NativeDocument = (function (exports) {
1810
1854
 
1811
1855
  try {
1812
1856
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1813
- let child = callback(item, indexObserver);
1814
- if(Validator.isStringOrObservable(child)) {
1815
- child = createTextNode(child);
1816
- }
1857
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1817
1858
  cache.set(keyId, {
1818
1859
  keyId,
1819
1860
  isNew: true,
@@ -1901,15 +1942,28 @@ var NativeDocument = (function (exports) {
1901
1942
  child = null;
1902
1943
  },
1903
1944
  clear,
1945
+ merge(items) {
1946
+ Actions.add(items, 0);
1947
+ },
1904
1948
  push(items) {
1905
1949
  let delay = 0;
1906
1950
  if(configs.pushDelay) {
1907
1951
  delay = configs.pushDelay(items) ?? 0;
1908
- } else {
1909
- delay = (items.length >= 1000) ? 10 : 0;
1910
1952
  }
1953
+
1911
1954
  Actions.add(items, delay);
1912
1955
  },
1956
+ populate([target, iteration, callback]) {
1957
+ const fragment = document.createDocumentFragment();
1958
+ for (let i = 0; i < iteration; i++) {
1959
+ const data = callback(i);
1960
+ target.push(data);
1961
+ fragment.append(buildItem(data, i));
1962
+ lastNumberOfItems++;
1963
+ }
1964
+ element.appendChild(fragment);
1965
+ fragment.replaceChildren();
1966
+ },
1913
1967
  unshift(values){
1914
1968
  element.insertBefore(Actions.toFragment(values), blockStart.nextSibling);
1915
1969
  },
@@ -1974,23 +2028,30 @@ var NativeDocument = (function (exports) {
1974
2028
  };
1975
2029
 
1976
2030
  const buildContent = (items, _, operations) => {
1977
- if(operations.action === 'clear' || !items.length) {
1978
- if(lastNumberOfItems === 0) {
1979
- return;
2031
+ if(operations?.action === 'populate') {
2032
+ Actions.populate(operations.args, operations.result);
2033
+ } else {
2034
+ console.log(lastNumberOfItems);
2035
+ if(operations.action === 'clear' || !items.length) {
2036
+ if(lastNumberOfItems === 0) {
2037
+ return;
2038
+ }
2039
+ clear();
1980
2040
  }
1981
- clear();
1982
- }
1983
2041
 
1984
- if(!operations?.action) {
1985
- if(lastNumberOfItems === 0) {
1986
- Actions.add(items);
1987
- return;
2042
+ if(!operations?.action) {
2043
+ if(lastNumberOfItems === 0) {
2044
+ Actions.add(items);
2045
+ return;
2046
+ }
2047
+ Actions.replace(items);
2048
+ }
2049
+ else if(Actions[operations.action]) {
2050
+ Actions[operations.action](operations.args, operations.result);
1988
2051
  }
1989
- Actions.replace(items);
1990
- }
1991
- else if(Actions[operations.action]) {
1992
- Actions[operations.action](operations.args, operations.result);
1993
2052
  }
2053
+
2054
+ console.log(items);
1994
2055
  updateIndexObservers(items, 0);
1995
2056
  };
1996
2057
 
@@ -2021,15 +2082,7 @@ var NativeDocument = (function (exports) {
2021
2082
  if(childElement) {
2022
2083
  return childElement;
2023
2084
  }
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
- }
2085
+ childElement = ElementCreator.getChild(child);
2033
2086
  return childElement;
2034
2087
  };
2035
2088
 
@@ -2080,9 +2133,10 @@ var NativeDocument = (function (exports) {
2080
2133
  *
2081
2134
  * @param {ObservableItem|ObservableChecker} $condition
2082
2135
  * @param {{[key]: *}} values
2136
+ * @param {Boolean} shouldKeepInCache
2083
2137
  * @returns {DocumentFragment}
2084
2138
  */
2085
- const Match = function($condition, values) {
2139
+ const Match = function($condition, values, shouldKeepInCache = true) {
2086
2140
 
2087
2141
  if(!Validator.isObservable($condition)) {
2088
2142
  throw new NativeDocumentError("Toggle : condition must be an Observable");
@@ -2092,17 +2146,15 @@ var NativeDocument = (function (exports) {
2092
2146
  const cache = new Map();
2093
2147
 
2094
2148
  const getItem = function(key) {
2095
- if(cache.has(key)) {
2149
+ if(shouldKeepInCache && cache.has(key)) {
2096
2150
  return cache.get(key);
2097
2151
  }
2098
2152
  let item = values[key];
2099
2153
  if(!item) {
2100
2154
  return null;
2101
2155
  }
2102
- if(Validator.isFunction(item)) {
2103
- item = item();
2104
- }
2105
- cache.set(key, item);
2156
+ item = ElementCreator.getChild(item);
2157
+ shouldKeepInCache && cache.set(key, item);
2106
2158
  return item;
2107
2159
  };
2108
2160