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.
- package/dist/native-document.dev.js +375 -323
- package/dist/native-document.min.js +1 -1
- package/package.json +1 -1
- package/src/data/observable-helpers/array.js +7 -1
- package/src/elements/anchor.js +4 -14
- package/src/elements/control/for-each-array.js +37 -20
- package/src/elements/control/for-each.js +2 -5
- package/src/elements/control/show-if.js +2 -10
- package/src/elements/control/switch.js +6 -7
- package/src/utils/events.js +65 -0
- package/src/utils/prototypes.js +1 -1
- package/src/utils/validator.js +5 -1
- package/src/wrappers/ElementCreator.js +32 -22
- package/src/wrappers/HtmlElementWrapper.js +2 -6
- package/src/wrappers/NDElement.js +81 -0
- package/src/wrappers/NdPrototype.js +6 -99
|
@@ -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(
|
|
736
|
+
parent.nativeInsertBefore(ElementCreator.getChild(child), target);
|
|
467
737
|
return;
|
|
468
738
|
}
|
|
469
|
-
parent.insertBefore(
|
|
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(
|
|
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
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
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.$
|
|
1004
|
-
return this.$
|
|
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
|
-
|
|
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
|
-
|
|
1170
|
+
return function(attributes, children = null) {
|
|
1127
1171
|
try {
|
|
1128
|
-
if(Validator.
|
|
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
|
|
1978
|
-
|
|
1979
|
-
|
|
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
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2103
|
-
|
|
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
|
|