native-document 1.0.15 → 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,202 +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
- if(ref) {
1047
- return ref;
1048
- }
1049
- return function(target, name) {
1050
- target[name] = element;
1051
- return element;
1052
- };
1053
- }
1054
- if(property === 'unmountChildren') {
1055
- return () => {
1056
- for(let i = 0, length = element.children.length; i < length; i++) {
1057
- let elementchildren = element.children[i];
1058
- if(!elementchildren.$ndProx) {
1059
- elementchildren.nd?.remove();
1060
- }
1061
- elementchildren = null;
1062
- }
1063
- };
1064
- }
1065
- if(property === 'remove') {
1066
- return function() {
1067
- element.nd.unmountChildren();
1068
- lifecycle = null;
1069
- element.$ndProx = null;
1070
- delete element.nd?.on?.prevent;
1071
- delete element.nd?.on;
1072
- delete element.nd;
1073
- };
1074
- }
1075
- if(property === 'hasLifecycle') {
1076
- return lifecycle !== null;
1077
- }
1078
- if(property === 'lifecycle') {
1079
- if(lifecycle) {
1080
- return lifecycle;
1081
- }
1082
- let $observer = null;
1083
- lifecycle = function(states) {
1084
- $observer = $observer || DocumentObserver.watch(element);
1085
-
1086
- states.mounted && $observer.mounted(states.mounted);
1087
- states.unmounted && $observer.unmounted(states.unmounted);
1088
- return element;
1089
- };
1090
- return lifecycle;
1091
- }
1092
- if(property === 'mounted' || property === 'unmounted') {
1093
- return function(callback) {
1094
- element.nd.lifecycle({ [property]: callback});
1095
- return element;
1096
- };
1097
- }
1098
- },
1099
- set(target, p, newValue, receiver) {
1151
+ if(this.$nd) {
1152
+ return this.$nd;
1153
+ }
1100
1154
 
1101
- },
1102
- configurable: true
1103
- });
1104
- return this.$ndProx;
1155
+ this.$nd = new NDElement(this);
1156
+ this.$nd.nd = this.$nd;
1157
+ return this.$nd;
1105
1158
  }
1106
1159
  });
1107
1160
 
1108
- /**
1109
- *
1110
- * @param {*} value
1111
- * @returns {Text}
1112
- */
1113
- const createTextNode = function(value) {
1114
- return (Validator.isObservable(value))
1115
- ? ElementCreator.createObservableNode(null, value)
1116
- : ElementCreator.createStaticTextNode(null, value);
1117
- };
1118
-
1119
-
1120
1161
  /**
1121
1162
  *
1122
1163
  * @param {string} name
@@ -1126,9 +1167,9 @@ var NativeDocument = (function (exports) {
1126
1167
  function HtmlElementWrapper(name, customWrapper) {
1127
1168
  const $tagName = name.toLowerCase();
1128
1169
 
1129
- const builder = function(attributes, children = null) {
1170
+ return function(attributes, children = null) {
1130
1171
  try {
1131
- if(Validator.isValidChildren(attributes)) {
1172
+ if(!Validator.isJson(attributes)) {
1132
1173
  const tempChildren = children;
1133
1174
  children = attributes;
1134
1175
  attributes = tempChildren;
@@ -1144,10 +1185,6 @@ var NativeDocument = (function (exports) {
1144
1185
  DebugManager.error('ElementCreation', `Error creating ${$tagName}`, error);
1145
1186
  }
1146
1187
  };
1147
-
1148
- builder.hold = (children, attributes) => (() => builder(children, attributes));
1149
-
1150
- return builder;
1151
1188
  }
1152
1189
 
1153
1190
  class ArgTypesError extends Error {
@@ -1283,7 +1320,7 @@ var NativeDocument = (function (exports) {
1283
1320
 
1284
1321
  String.prototype.resolveObservableTemplate = function() {
1285
1322
  if(!Validator.containsObservableReference(this)) {
1286
- return this;
1323
+ return this.valueOf();
1287
1324
  }
1288
1325
  return this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map((value) => {
1289
1326
  if(!Validator.containsObservableReference(value)) {
@@ -1321,6 +1358,13 @@ var NativeDocument = (function (exports) {
1321
1358
  return true;
1322
1359
  };
1323
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
+ };
1324
1368
  observer.remove = function(index) {
1325
1369
  const deleted = observer.$value.splice(index, 1);
1326
1370
  if(deleted.length === 0) {
@@ -1643,10 +1687,7 @@ var NativeDocument = (function (exports) {
1643
1687
 
1644
1688
  try {
1645
1689
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1646
- let child = callback(item, indexObserver);
1647
- if(Validator.isStringOrObservable(child)) {
1648
- child = createTextNode(child);
1649
- }
1690
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1650
1691
  cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
1651
1692
  } catch (e) {
1652
1693
  DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
@@ -1813,10 +1854,7 @@ var NativeDocument = (function (exports) {
1813
1854
 
1814
1855
  try {
1815
1856
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
1816
- let child = callback(item, indexObserver);
1817
- if(Validator.isStringOrObservable(child)) {
1818
- child = createTextNode(child);
1819
- }
1857
+ let child = ElementCreator.getChild(callback(item, indexObserver));
1820
1858
  cache.set(keyId, {
1821
1859
  keyId,
1822
1860
  isNew: true,
@@ -1904,15 +1942,28 @@ var NativeDocument = (function (exports) {
1904
1942
  child = null;
1905
1943
  },
1906
1944
  clear,
1945
+ merge(items) {
1946
+ Actions.add(items, 0);
1947
+ },
1907
1948
  push(items) {
1908
1949
  let delay = 0;
1909
1950
  if(configs.pushDelay) {
1910
1951
  delay = configs.pushDelay(items) ?? 0;
1911
- } else {
1912
- delay = (items.length >= 1000) ? 10 : 0;
1913
1952
  }
1953
+
1914
1954
  Actions.add(items, delay);
1915
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
+ },
1916
1967
  unshift(values){
1917
1968
  element.insertBefore(Actions.toFragment(values), blockStart.nextSibling);
1918
1969
  },
@@ -1977,23 +2028,30 @@ var NativeDocument = (function (exports) {
1977
2028
  };
1978
2029
 
1979
2030
  const buildContent = (items, _, operations) => {
1980
- if(operations.action === 'clear' || !items.length) {
1981
- if(lastNumberOfItems === 0) {
1982
- 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();
1983
2040
  }
1984
- clear();
1985
- }
1986
2041
 
1987
- if(!operations?.action) {
1988
- if(lastNumberOfItems === 0) {
1989
- Actions.add(items);
1990
- 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);
1991
2051
  }
1992
- Actions.replace(items);
1993
- }
1994
- else if(Actions[operations.action]) {
1995
- Actions[operations.action](operations.args, operations.result);
1996
2052
  }
2053
+
2054
+ console.log(items);
1997
2055
  updateIndexObservers(items, 0);
1998
2056
  };
1999
2057
 
@@ -2024,15 +2082,7 @@ var NativeDocument = (function (exports) {
2024
2082
  if(childElement) {
2025
2083
  return childElement;
2026
2084
  }
2027
- if(typeof child === 'function') {
2028
- childElement = child();
2029
- }
2030
- else {
2031
- childElement = child;
2032
- }
2033
- if(Validator.isStringOrObservable(childElement)) {
2034
- childElement = createTextNode(childElement);
2035
- }
2085
+ childElement = ElementCreator.getChild(child);
2036
2086
  return childElement;
2037
2087
  };
2038
2088
 
@@ -2083,9 +2133,10 @@ var NativeDocument = (function (exports) {
2083
2133
  *
2084
2134
  * @param {ObservableItem|ObservableChecker} $condition
2085
2135
  * @param {{[key]: *}} values
2136
+ * @param {Boolean} shouldKeepInCache
2086
2137
  * @returns {DocumentFragment}
2087
2138
  */
2088
- const Match = function($condition, values) {
2139
+ const Match = function($condition, values, shouldKeepInCache = true) {
2089
2140
 
2090
2141
  if(!Validator.isObservable($condition)) {
2091
2142
  throw new NativeDocumentError("Toggle : condition must be an Observable");
@@ -2095,17 +2146,15 @@ var NativeDocument = (function (exports) {
2095
2146
  const cache = new Map();
2096
2147
 
2097
2148
  const getItem = function(key) {
2098
- if(cache.has(key)) {
2149
+ if(shouldKeepInCache && cache.has(key)) {
2099
2150
  return cache.get(key);
2100
2151
  }
2101
2152
  let item = values[key];
2102
2153
  if(!item) {
2103
2154
  return null;
2104
2155
  }
2105
- if(Validator.isFunction(item)) {
2106
- item = item();
2107
- }
2108
- cache.set(key, item);
2156
+ item = ElementCreator.getChild(item);
2157
+ shouldKeepInCache && cache.set(key, item);
2109
2158
  return item;
2110
2159
  };
2111
2160
 
@@ -2210,7 +2259,7 @@ var NativeDocument = (function (exports) {
2210
2259
 
2211
2260
  el.submit = function(action) {
2212
2261
  if(typeof action === 'function') {
2213
- el.on.submit((e) => {
2262
+ el.onSubmit((e) => {
2214
2263
  e.preventDefault();
2215
2264
  action(e);
2216
2265
  });
@@ -3155,7 +3204,7 @@ var NativeDocument = (function (exports) {
3155
3204
  const target = to || href;
3156
3205
  if(Validator.isString(target)) {
3157
3206
  const router = Router.get();
3158
- return Link$1({ ...attributes, href: target}, children).nd.on.prevent.click(() => {
3207
+ return Link$1({ ...attributes, href: target}, children).nd.onPreventClick(() => {
3159
3208
  router.push(target);
3160
3209
  });
3161
3210
  }
@@ -3166,7 +3215,7 @@ var NativeDocument = (function (exports) {
3166
3215
  throw new RouterError('Router not found "'+routerName+'" for link "'+target.name+'"');
3167
3216
  }
3168
3217
  const url = router.generateUrl(target.name, target.params, target.query);
3169
- return Link$1({ ...attributes, href: url }, children).nd.on.prevent.click(() => {
3218
+ return Link$1({ ...attributes, href: url }, children).nd.onPreventClick(() => {
3170
3219
  router.push(url);
3171
3220
  });
3172
3221
  }