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.
- package/dist/native-document.dev.js +378 -329
- 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/elements/form.js +1 -1
- package/src/router/link.js +2 -2
- 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 -102
|
@@ -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,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.$
|
|
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
|
-
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
|
-
|
|
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
|
-
|
|
1170
|
+
return function(attributes, children = null) {
|
|
1130
1171
|
try {
|
|
1131
|
-
if(Validator.
|
|
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
|
|
1981
|
-
|
|
1982
|
-
|
|
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
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2106
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
3218
|
+
return Link$1({ ...attributes, href: url }, children).nd.onPreventClick(() => {
|
|
3170
3219
|
router.push(url);
|
|
3171
3220
|
});
|
|
3172
3221
|
}
|