native-document 1.0.34 → 1.0.36
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 +457 -204
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.min.js +1 -1
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/data/ObservableItem.js +29 -27
- package/src/data/observable-helpers/array.js +2 -2
- package/src/data/observable-helpers/computed.js +9 -1
- package/src/data/observable-helpers/object.js +35 -8
- package/src/elements/anchor.js +23 -13
- package/src/elements/control/for-each-array.js +19 -9
- package/src/elements/control/for-each.js +12 -5
- package/src/elements/control/show-if.js +6 -3
- package/src/elements/control/switch.js +3 -0
- package/src/utils/helpers.js +1 -1
- package/src/utils/plugins-manager.js +9 -9
- package/src/utils/validator.js +30 -15
- package/src/wrappers/AttributesWrapper.js +36 -26
- package/src/wrappers/ElementCreator.js +12 -7
- package/src/wrappers/HtmlElementWrapper.js +11 -7
- package/src/wrappers/NDElement.js +3 -31
- package/src/wrappers/NDElementEventPrototypes.js +116 -0
- package/src/wrappers/NdPrototype.js +52 -5
- package/src/wrappers/TemplateCloner.js +60 -39
- package/types/control-flow.d.ts +3 -2
- package/types/elements.d.ts +201 -1
- package/types/observable.d.ts +2 -1
- package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
|
@@ -165,10 +165,11 @@ var NativeDocument = (function (exports) {
|
|
|
165
165
|
}
|
|
166
166
|
for(const methodName in plugin) {
|
|
167
167
|
if(/^on[A-Z]/.test(methodName)) {
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
const eventName = methodName.replace(/^on/, '');
|
|
169
|
+
if(!$pluginByEvents.has(eventName)) {
|
|
170
|
+
$pluginByEvents.set(eventName, new Set());
|
|
170
171
|
}
|
|
171
|
-
$pluginByEvents.get(
|
|
172
|
+
$pluginByEvents.get(eventName).add(plugin);
|
|
172
173
|
}
|
|
173
174
|
}
|
|
174
175
|
},
|
|
@@ -190,20 +191,19 @@ var NativeDocument = (function (exports) {
|
|
|
190
191
|
}
|
|
191
192
|
$plugins.delete(pluginName);
|
|
192
193
|
},
|
|
193
|
-
emit(
|
|
194
|
-
|
|
195
|
-
if(!$pluginByEvents.has(eventMethodName)) {
|
|
194
|
+
emit(eventName, ...data) {
|
|
195
|
+
if(!$pluginByEvents.has(eventName)) {
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
|
-
const plugins = $pluginByEvents.get(
|
|
198
|
+
const plugins = $pluginByEvents.get(eventName);
|
|
199
199
|
|
|
200
200
|
for(const plugin of plugins) {
|
|
201
|
-
const callback = plugin[
|
|
201
|
+
const callback = plugin[eventName];
|
|
202
202
|
if(typeof callback === 'function') {
|
|
203
203
|
try{
|
|
204
204
|
callback.call(plugin, ...data);
|
|
205
205
|
} catch (error) {
|
|
206
|
-
DebugManager$1.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${
|
|
206
|
+
DebugManager$1.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${eventName}`, error);
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
}
|
|
@@ -217,7 +217,7 @@ var NativeDocument = (function (exports) {
|
|
|
217
217
|
* @class ObservableItem
|
|
218
218
|
*/
|
|
219
219
|
function ObservableItem(value) {
|
|
220
|
-
this.$previousValue =
|
|
220
|
+
this.$previousValue = null;
|
|
221
221
|
this.$currentValue = value;
|
|
222
222
|
this.$isCleanedUp = false;
|
|
223
223
|
|
|
@@ -241,19 +241,33 @@ var NativeDocument = (function (exports) {
|
|
|
241
241
|
ObservableItem.prototype.__$isObservable = true;
|
|
242
242
|
|
|
243
243
|
const noneTrigger = function() {};
|
|
244
|
+
ObservableItem.prototype.triggerFirstListener = function(operations) {
|
|
245
|
+
this.$listeners[0](this.$currentValue, this.$previousValue, operations || {});
|
|
246
|
+
};
|
|
244
247
|
ObservableItem.prototype.triggerListeners = function(operations) {
|
|
245
248
|
const $listeners = this.$listeners;
|
|
246
249
|
const $previousValue = this.$previousValue;
|
|
247
250
|
const $currentValue = this.$currentValue;
|
|
248
251
|
|
|
249
|
-
operations = operations ||
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
$listeners[i]($currentValue, $previousValue, operations);
|
|
253
|
-
}
|
|
252
|
+
operations = operations || DEFAULT_OPERATIONS;
|
|
253
|
+
for(let i = 0, length = $listeners.length; i < length; i++) {
|
|
254
|
+
$listeners[i]($currentValue, $previousValue, operations);
|
|
254
255
|
}
|
|
255
256
|
};
|
|
256
257
|
|
|
258
|
+
const handleWatcherCallback = function(callbacks, value) {
|
|
259
|
+
if(typeof callbacks === "function") {
|
|
260
|
+
callbacks(value);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (callbacks.set) {
|
|
264
|
+
callbacks.set(value);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
callbacks.forEach(callback => {
|
|
268
|
+
callback.set ? callback.set(value) : callback(value);
|
|
269
|
+
});
|
|
270
|
+
};
|
|
257
271
|
ObservableItem.prototype.triggerWatchers = function() {
|
|
258
272
|
if(!this.$watchers) {
|
|
259
273
|
return;
|
|
@@ -265,28 +279,11 @@ var NativeDocument = (function (exports) {
|
|
|
265
279
|
|
|
266
280
|
if($watchers.has($currentValue)) {
|
|
267
281
|
const $currentValueCallbacks = $watchers.get($currentValue);
|
|
268
|
-
|
|
269
|
-
$currentValueCallbacks(true);
|
|
270
|
-
} else if ($currentValueCallbacks.set) {
|
|
271
|
-
$currentValueCallbacks.set(true);
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
$currentValueCallbacks.forEach(callback => {
|
|
275
|
-
callback.set ? callback.set(true) : callback(true);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
282
|
+
handleWatcherCallback($currentValueCallbacks, true);
|
|
278
283
|
}
|
|
279
284
|
if($watchers.has($previousValue)) {
|
|
280
285
|
const $previousValueCallbacks = $watchers.get($previousValue);
|
|
281
|
-
|
|
282
|
-
$previousValueCallbacks(false);
|
|
283
|
-
} else if($previousValueCallbacks.set) {
|
|
284
|
-
$previousValueCallbacks.set(false);
|
|
285
|
-
} else {
|
|
286
|
-
$previousValueCallbacks.forEach(callback => {
|
|
287
|
-
callback.set ? callback.set(false) : callback(false);
|
|
288
|
-
});
|
|
289
|
-
}
|
|
286
|
+
handleWatcherCallback($previousValueCallbacks, false);
|
|
290
287
|
}
|
|
291
288
|
};
|
|
292
289
|
|
|
@@ -295,13 +292,18 @@ var NativeDocument = (function (exports) {
|
|
|
295
292
|
this.triggerWatchers();
|
|
296
293
|
};
|
|
297
294
|
|
|
295
|
+
ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations) {
|
|
296
|
+
this.triggerListeners(operations);
|
|
297
|
+
this.triggerWatchers();
|
|
298
|
+
};
|
|
299
|
+
|
|
298
300
|
ObservableItem.prototype.assocTrigger = function() {
|
|
299
301
|
if(this.$watchers?.size && this.$listeners?.length) {
|
|
300
|
-
this.trigger = this.triggerAll;
|
|
302
|
+
this.trigger = (this.$listeners.length === 1) ? this.triggerWatchersAndFirstListener : this.triggerAll;
|
|
301
303
|
return;
|
|
302
304
|
}
|
|
303
305
|
if(this.$listeners?.length) {
|
|
304
|
-
this.trigger = this.triggerListeners;
|
|
306
|
+
this.trigger = (this.$listeners.length === 1) ? this.triggerFirstListener : this.triggerListeners;
|
|
305
307
|
return;
|
|
306
308
|
}
|
|
307
309
|
if(this.$watchers?.size) {
|
|
@@ -461,7 +463,7 @@ var NativeDocument = (function (exports) {
|
|
|
461
463
|
if(!Validator.isObject(item)) {
|
|
462
464
|
return item;
|
|
463
465
|
}
|
|
464
|
-
return item[key] ?? defaultKey;
|
|
466
|
+
return item[key]?.val?.() ?? item[key] ?? defaultKey;
|
|
465
467
|
};
|
|
466
468
|
|
|
467
469
|
const trim = function(str, char) {
|
|
@@ -633,35 +635,7 @@ var NativeDocument = (function (exports) {
|
|
|
633
635
|
}
|
|
634
636
|
NDElement.prototype.__$isNDElement = true;
|
|
635
637
|
|
|
636
|
-
|
|
637
|
-
const eventName = event.toLowerCase();
|
|
638
|
-
NDElement.prototype['on'+event] = function(callback) {
|
|
639
|
-
this.$element.addEventListener(eventName, callback);
|
|
640
|
-
return this;
|
|
641
|
-
};
|
|
642
|
-
NDElement.prototype['onPrevent'+event] = function(callback) {
|
|
643
|
-
this.$element.addEventListener(eventName, function(event) {
|
|
644
|
-
event.preventDefault();
|
|
645
|
-
callback && callback(event);
|
|
646
|
-
});
|
|
647
|
-
return this;
|
|
648
|
-
};
|
|
649
|
-
NDElement.prototype['onStop'+event] = function(callback) {
|
|
650
|
-
this.$element.addEventListener(eventName, function(event) {
|
|
651
|
-
event.stopPropagation();
|
|
652
|
-
callback && callback(event);
|
|
653
|
-
});
|
|
654
|
-
return this;
|
|
655
|
-
};
|
|
656
|
-
NDElement.prototype['onPreventStop'+event] = function(callback) {
|
|
657
|
-
this.$element.addEventListener(eventName, function(event) {
|
|
658
|
-
event.stopPropagation();
|
|
659
|
-
event.preventDefault();
|
|
660
|
-
callback && callback(event);
|
|
661
|
-
});
|
|
662
|
-
return this;
|
|
663
|
-
};
|
|
664
|
-
}
|
|
638
|
+
|
|
665
639
|
|
|
666
640
|
NDElement.prototype.valueOf = function() {
|
|
667
641
|
return this.$element;
|
|
@@ -717,20 +691,26 @@ var NativeDocument = (function (exports) {
|
|
|
717
691
|
|
|
718
692
|
NDElement.prototype.node = NDElement.prototype.htmlElement;
|
|
719
693
|
|
|
720
|
-
NDElement.prototype.attach = function(
|
|
721
|
-
bindingHydrator.$hydrate(this.$element
|
|
694
|
+
NDElement.prototype.attach = function(bindingHydrator) {
|
|
695
|
+
bindingHydrator.$hydrate(this.$element);
|
|
722
696
|
return this.$element;
|
|
723
697
|
};
|
|
724
698
|
|
|
699
|
+
const COMMON_NODE_TYPES = {
|
|
700
|
+
ELEMENT: 1,
|
|
701
|
+
TEXT: 3,
|
|
702
|
+
DOCUMENT_FRAGMENT: 11
|
|
703
|
+
};
|
|
704
|
+
|
|
725
705
|
const Validator = {
|
|
726
706
|
isObservable(value) {
|
|
727
|
-
return value instanceof ObservableItem || value instanceof ObservableChecker
|
|
707
|
+
return value?.__$isObservable || value instanceof ObservableItem || value instanceof ObservableChecker;
|
|
728
708
|
},
|
|
729
709
|
isProxy(value) {
|
|
730
710
|
return value?.__isProxy__
|
|
731
711
|
},
|
|
732
712
|
isObservableChecker(value) {
|
|
733
|
-
return value instanceof ObservableChecker
|
|
713
|
+
return value?.__$isObservableChecker || value instanceof ObservableChecker;
|
|
734
714
|
},
|
|
735
715
|
isArray(value) {
|
|
736
716
|
return Array.isArray(value);
|
|
@@ -754,13 +734,17 @@ var NativeDocument = (function (exports) {
|
|
|
754
734
|
return typeof value === 'object';
|
|
755
735
|
},
|
|
756
736
|
isJson(value) {
|
|
757
|
-
return typeof value === 'object' && value !== null && value.constructor.name === 'Object'
|
|
737
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) && value.constructor.name === 'Object';
|
|
758
738
|
},
|
|
759
739
|
isElement(value) {
|
|
760
|
-
return value
|
|
740
|
+
return value && (
|
|
741
|
+
value.nodeType === COMMON_NODE_TYPES.ELEMENT ||
|
|
742
|
+
value.nodeType === COMMON_NODE_TYPES.TEXT ||
|
|
743
|
+
value.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT
|
|
744
|
+
);
|
|
761
745
|
},
|
|
762
746
|
isFragment(value) {
|
|
763
|
-
return value
|
|
747
|
+
return value?.nodeType === COMMON_NODE_TYPES.DOCUMENT_FRAGMENT;
|
|
764
748
|
},
|
|
765
749
|
isStringOrObservable(value) {
|
|
766
750
|
return this.isString(value) || this.isObservable(value);
|
|
@@ -773,7 +757,7 @@ var NativeDocument = (function (exports) {
|
|
|
773
757
|
['string', 'number', 'boolean'].includes(typeof child);
|
|
774
758
|
},
|
|
775
759
|
isNDElement(child) {
|
|
776
|
-
return child instanceof NDElement
|
|
760
|
+
return child?.__$isNDElement || child instanceof NDElement;
|
|
777
761
|
},
|
|
778
762
|
isValidChildren(children) {
|
|
779
763
|
if (!Array.isArray(children)) {
|
|
@@ -818,7 +802,16 @@ var NativeDocument = (function (exports) {
|
|
|
818
802
|
}
|
|
819
803
|
return /\{\{#ObItem::\([0-9]+\)\}\}/.test(data);
|
|
820
804
|
},
|
|
821
|
-
validateAttributes(attributes) {
|
|
805
|
+
validateAttributes(attributes) {},
|
|
806
|
+
|
|
807
|
+
validateEventCallback(callback) {
|
|
808
|
+
if (typeof callback !== 'function') {
|
|
809
|
+
throw new NativeDocumentError('Event callback must be a function');
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
{
|
|
814
|
+
Validator.validateAttributes = function(attributes) {
|
|
822
815
|
if (!attributes || typeof attributes !== 'object') {
|
|
823
816
|
return attributes;
|
|
824
817
|
}
|
|
@@ -831,14 +824,8 @@ var NativeDocument = (function (exports) {
|
|
|
831
824
|
}
|
|
832
825
|
|
|
833
826
|
return attributes;
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
validateEventCallback(callback) {
|
|
837
|
-
if (typeof callback !== 'function') {
|
|
838
|
-
throw new NativeDocumentError('Event callback must be a function');
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
};
|
|
827
|
+
};
|
|
828
|
+
}
|
|
842
829
|
|
|
843
830
|
function Anchor(name, isUniqueChild = false) {
|
|
844
831
|
const element = document.createDocumentFragment();
|
|
@@ -852,13 +839,15 @@ var NativeDocument = (function (exports) {
|
|
|
852
839
|
element.nativeInsertBefore = element.insertBefore;
|
|
853
840
|
element.nativeAppendChild = element.appendChild;
|
|
854
841
|
|
|
842
|
+
const isParentUniqueChild = (parent) => (isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd));
|
|
843
|
+
|
|
855
844
|
const insertBefore = function(parent, child, target) {
|
|
856
845
|
const element = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
857
846
|
if(parent === element) {
|
|
858
847
|
parent.nativeInsertBefore(element, target);
|
|
859
848
|
return;
|
|
860
849
|
}
|
|
861
|
-
if(
|
|
850
|
+
if(isParentUniqueChild(parent) || target === anchorEnd) {
|
|
862
851
|
parent.append(element, target);
|
|
863
852
|
return;
|
|
864
853
|
}
|
|
@@ -866,17 +855,13 @@ var NativeDocument = (function (exports) {
|
|
|
866
855
|
};
|
|
867
856
|
|
|
868
857
|
element.appendElement = function(child, before = null) {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
if(anchorEnd.parentNode === element) {
|
|
876
|
-
anchorEnd.parentNode.nativeInsertBefore(child, before || anchorEnd);
|
|
858
|
+
const parentNode = anchorStart.parentNode;
|
|
859
|
+
const targetBefore = before || anchorEnd;
|
|
860
|
+
if(parentNode === element) {
|
|
861
|
+
parentNode.nativeInsertBefore(child, targetBefore);
|
|
877
862
|
return;
|
|
878
863
|
}
|
|
879
|
-
|
|
864
|
+
parentNode?.insertBefore(child, targetBefore);
|
|
880
865
|
};
|
|
881
866
|
|
|
882
867
|
element.appendChild = function(child, before = null) {
|
|
@@ -894,7 +879,7 @@ var NativeDocument = (function (exports) {
|
|
|
894
879
|
if(parent === element) {
|
|
895
880
|
return;
|
|
896
881
|
}
|
|
897
|
-
if(
|
|
882
|
+
if(isParentUniqueChild(parent)) {
|
|
898
883
|
parent.replaceChildren(anchorStart, anchorEnd);
|
|
899
884
|
return;
|
|
900
885
|
}
|
|
@@ -913,7 +898,7 @@ var NativeDocument = (function (exports) {
|
|
|
913
898
|
if(parent === element) {
|
|
914
899
|
return;
|
|
915
900
|
}
|
|
916
|
-
if(
|
|
901
|
+
if(isParentUniqueChild(parent)) {
|
|
917
902
|
parent.replaceChildren(anchorEnd, anchorEnd);
|
|
918
903
|
return;
|
|
919
904
|
}
|
|
@@ -936,7 +921,7 @@ var NativeDocument = (function (exports) {
|
|
|
936
921
|
if(!parent) {
|
|
937
922
|
return;
|
|
938
923
|
}
|
|
939
|
-
if(
|
|
924
|
+
if(isParentUniqueChild(parent)) {
|
|
940
925
|
parent.replaceChildren(anchorStart, child, anchorEnd);
|
|
941
926
|
return;
|
|
942
927
|
}
|
|
@@ -955,10 +940,22 @@ var NativeDocument = (function (exports) {
|
|
|
955
940
|
element.endElement = function() {
|
|
956
941
|
return anchorEnd;
|
|
957
942
|
};
|
|
943
|
+
|
|
958
944
|
element.startElement = function() {
|
|
959
945
|
return anchorStart;
|
|
960
946
|
};
|
|
961
947
|
|
|
948
|
+
element.getByIndex = function(index) {
|
|
949
|
+
let currentNode = anchorStart;
|
|
950
|
+
for(let i = 0; i <= index; i++) {
|
|
951
|
+
if(!currentNode.nextSibling) {
|
|
952
|
+
return null;
|
|
953
|
+
}
|
|
954
|
+
currentNode = currentNode.nextSibling;
|
|
955
|
+
}
|
|
956
|
+
return currentNode !== anchorStart ? currentNode : null;
|
|
957
|
+
};
|
|
958
|
+
|
|
962
959
|
return element;
|
|
963
960
|
}
|
|
964
961
|
|
|
@@ -1013,6 +1010,26 @@ var NativeDocument = (function (exports) {
|
|
|
1013
1010
|
setInterval(() => MemoryManager.cleanObservables(threshold), interval);
|
|
1014
1011
|
};
|
|
1015
1012
|
|
|
1013
|
+
function toggleElementClass(element, className, shouldAdd) {
|
|
1014
|
+
element.classes.toggle(className, shouldAdd);
|
|
1015
|
+
}
|
|
1016
|
+
function toggleElementStyle(element, styleName, newValue) {
|
|
1017
|
+
element.style[styleName] = newValue;
|
|
1018
|
+
}
|
|
1019
|
+
function updateInputFromObserver(element, attributeName, newValue) {
|
|
1020
|
+
if(Validator.isBoolean(newValue)) {
|
|
1021
|
+
element[attributeName] = newValue;
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
element[attributeName] = newValue === element.value;
|
|
1025
|
+
}
|
|
1026
|
+
function updateObserverFromInput(element, attributeName, defaultValue, value) {
|
|
1027
|
+
if(Validator.isBoolean(defaultValue)) {
|
|
1028
|
+
value.set(element[attributeName]);
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
value.set(element.value);
|
|
1032
|
+
}
|
|
1016
1033
|
/**
|
|
1017
1034
|
*
|
|
1018
1035
|
* @param {HTMLElement} element
|
|
@@ -1022,23 +1039,22 @@ var NativeDocument = (function (exports) {
|
|
|
1022
1039
|
for(let className in data) {
|
|
1023
1040
|
const value = data[className];
|
|
1024
1041
|
if(Validator.isObservable(value)) {
|
|
1025
|
-
element.
|
|
1026
|
-
value.subscribe(
|
|
1042
|
+
element.classes.toggle(className, value.val());
|
|
1043
|
+
value.subscribe(toggleElementClass.bind(null, element, className));
|
|
1027
1044
|
continue;
|
|
1028
1045
|
}
|
|
1029
1046
|
if(value.$observer) {
|
|
1030
|
-
element.
|
|
1031
|
-
value.$observer.on(value.$target,
|
|
1032
|
-
element.classList.toggle(className, isTargetValue);
|
|
1033
|
-
});
|
|
1047
|
+
element.classes.toggle(className, value.$observer.val() === value.$target);
|
|
1048
|
+
value.$observer.on(value.$target, toggleElementClass.bind(null, element, className));
|
|
1034
1049
|
continue;
|
|
1035
1050
|
}
|
|
1036
1051
|
if(value.$hydrate) {
|
|
1037
1052
|
value.$hydrate(element, className);
|
|
1038
1053
|
continue;
|
|
1039
1054
|
}
|
|
1040
|
-
element.
|
|
1055
|
+
element.classes.toggle(className, value);
|
|
1041
1056
|
}
|
|
1057
|
+
data = null;
|
|
1042
1058
|
}
|
|
1043
1059
|
|
|
1044
1060
|
/**
|
|
@@ -1051,9 +1067,7 @@ var NativeDocument = (function (exports) {
|
|
|
1051
1067
|
const value = data[styleName];
|
|
1052
1068
|
if(Validator.isObservable(value)) {
|
|
1053
1069
|
element.style[styleName] = value.val();
|
|
1054
|
-
value.subscribe(
|
|
1055
|
-
element.style[styleName] = newValue;
|
|
1056
|
-
});
|
|
1070
|
+
value.subscribe(toggleElementStyle.bind(null, element, styleName));
|
|
1057
1071
|
continue;
|
|
1058
1072
|
}
|
|
1059
1073
|
element.style[styleName] = value;
|
|
@@ -1076,21 +1090,9 @@ var NativeDocument = (function (exports) {
|
|
|
1076
1090
|
}
|
|
1077
1091
|
if(Validator.isObservable(value)) {
|
|
1078
1092
|
if(['checked'].includes(attributeName)) {
|
|
1079
|
-
element.addEventListener('input', (
|
|
1080
|
-
if(Validator.isBoolean(defaultValue)) {
|
|
1081
|
-
value.set(element[attributeName]);
|
|
1082
|
-
return;
|
|
1083
|
-
}
|
|
1084
|
-
value.set(element.value);
|
|
1085
|
-
});
|
|
1093
|
+
element.addEventListener('input', updateObserverFromInput.bind(null, element, attributeName, defaultValue));
|
|
1086
1094
|
}
|
|
1087
|
-
value.subscribe(
|
|
1088
|
-
if(Validator.isBoolean(newValue)) {
|
|
1089
|
-
element[attributeName] = newValue;
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
|
-
element[attributeName] = newValue === element.value;
|
|
1093
|
-
});
|
|
1095
|
+
value.subscribe(updateInputFromObserver.bind(null, element, attributeName));
|
|
1094
1096
|
}
|
|
1095
1097
|
}
|
|
1096
1098
|
|
|
@@ -1144,11 +1146,11 @@ var NativeDocument = (function (exports) {
|
|
|
1144
1146
|
return value.map(item => Validator.isObservable(item) ? item.val() : item).join(' ') || ' ';
|
|
1145
1147
|
}, observables);
|
|
1146
1148
|
}
|
|
1147
|
-
if(attributeName === 'class' && Validator.
|
|
1149
|
+
if(attributeName === 'class' && Validator.isObject(value)) {
|
|
1148
1150
|
bindClassAttribute(element, value);
|
|
1149
1151
|
continue;
|
|
1150
1152
|
}
|
|
1151
|
-
if(attributeName === 'style' && Validator.
|
|
1153
|
+
if(attributeName === 'style' && Validator.isObject(value)) {
|
|
1152
1154
|
bindStyleAttribute(element, value);
|
|
1153
1155
|
continue;
|
|
1154
1156
|
}
|
|
@@ -1160,6 +1162,10 @@ var NativeDocument = (function (exports) {
|
|
|
1160
1162
|
bindAttributeWithObservable(element, attributeName, value);
|
|
1161
1163
|
continue;
|
|
1162
1164
|
}
|
|
1165
|
+
if(value.$hydrate) {
|
|
1166
|
+
value.$hydrate(element, attributeName);
|
|
1167
|
+
continue;
|
|
1168
|
+
}
|
|
1163
1169
|
element.setAttribute(attributeName, value);
|
|
1164
1170
|
|
|
1165
1171
|
}
|
|
@@ -1236,14 +1242,19 @@ var NativeDocument = (function (exports) {
|
|
|
1236
1242
|
*/
|
|
1237
1243
|
processChildren(children, parent) {
|
|
1238
1244
|
if(children === null) return;
|
|
1239
|
-
const childrenArray = Array.isArray(children) ? children : [children];
|
|
1240
|
-
|
|
1241
1245
|
PluginsManager.emit('BeforeProcessChildren', parent);
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1246
|
+
if(!Array.isArray(children)) {
|
|
1247
|
+
let child = this.getChild(children);
|
|
1248
|
+
if(child) {
|
|
1249
|
+
parent.appendChild(child);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
for(let i = 0, length = children.length; i < length; i++) {
|
|
1254
|
+
let child = this.getChild(children[i]);
|
|
1255
|
+
if (child === null) continue;
|
|
1256
|
+
parent.appendChild(child);
|
|
1257
|
+
}
|
|
1247
1258
|
}
|
|
1248
1259
|
|
|
1249
1260
|
PluginsManager.emit('AfterProcessChildren', parent);
|
|
@@ -1310,13 +1321,60 @@ var NativeDocument = (function (exports) {
|
|
|
1310
1321
|
Object.defineProperty(HTMLElement.prototype, 'nd', {
|
|
1311
1322
|
configurable: true,
|
|
1312
1323
|
get() {
|
|
1313
|
-
|
|
1314
|
-
|
|
1324
|
+
return new NDElement(this);
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1328
|
+
const classListMethods = {
|
|
1329
|
+
getClasses() {
|
|
1330
|
+
return this.$element.className?.split(' ').filter(Boolean);
|
|
1331
|
+
},
|
|
1332
|
+
add(value) {
|
|
1333
|
+
const classes = this.getClasses();
|
|
1334
|
+
if(classes.indexOf(value) >= 0) {
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
classes.push(value);
|
|
1338
|
+
this.$element.className = classes.join(' ');
|
|
1339
|
+
},
|
|
1340
|
+
remove(value) {
|
|
1341
|
+
const classes = this.getClasses();
|
|
1342
|
+
const index = classes.indexOf(value);
|
|
1343
|
+
if(index < 0) {
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
classes.splice(index, 1);
|
|
1347
|
+
this.$element.className = classes.join(' ');
|
|
1348
|
+
},
|
|
1349
|
+
toggle(value, force = undefined) {
|
|
1350
|
+
const classes = this.getClasses();
|
|
1351
|
+
const index = classes.indexOf(value);
|
|
1352
|
+
if(index >= 0) {
|
|
1353
|
+
if(force === true) {
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
classes.splice(index, 1);
|
|
1315
1357
|
}
|
|
1358
|
+
else {
|
|
1359
|
+
if(force === false) {
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
classes.push(value);
|
|
1363
|
+
}
|
|
1364
|
+
this.$element.className = classes.join(' ');
|
|
1365
|
+
},
|
|
1366
|
+
contains(value) {
|
|
1367
|
+
return this.getClasses().indexOf(value) >= 0;
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1316
1370
|
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1371
|
+
Object.defineProperty(HTMLElement.prototype, 'classes', {
|
|
1372
|
+
configurable: true,
|
|
1373
|
+
get() {
|
|
1374
|
+
return {
|
|
1375
|
+
$element: this,
|
|
1376
|
+
...classListMethods
|
|
1377
|
+
};
|
|
1320
1378
|
}
|
|
1321
1379
|
});
|
|
1322
1380
|
|
|
@@ -1452,13 +1510,17 @@ var NativeDocument = (function (exports) {
|
|
|
1452
1510
|
};
|
|
1453
1511
|
|
|
1454
1512
|
|
|
1455
|
-
function createHtmlElement($tagName, _attributes, _children = null
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1513
|
+
function createHtmlElement($tagName, customWrapper, _attributes, _children = null) {
|
|
1514
|
+
let { props: attributes, children = null } = normalizeComponentArgs(_attributes, _children);
|
|
1515
|
+
let element = ElementCreator.createElement($tagName);
|
|
1516
|
+
let finalElement = (customWrapper && typeof customWrapper === 'function') ? customWrapper(element) : element;
|
|
1459
1517
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1518
|
+
if(attributes) {
|
|
1519
|
+
ElementCreator.processAttributes(finalElement, attributes);
|
|
1520
|
+
}
|
|
1521
|
+
if(children) {
|
|
1522
|
+
ElementCreator.processChildren(children, finalElement);
|
|
1523
|
+
}
|
|
1462
1524
|
|
|
1463
1525
|
return ElementCreator.setup(finalElement, attributes, customWrapper);
|
|
1464
1526
|
}
|
|
@@ -1470,24 +1532,23 @@ var NativeDocument = (function (exports) {
|
|
|
1470
1532
|
* @returns {Function}
|
|
1471
1533
|
*/
|
|
1472
1534
|
function HtmlElementWrapper(name, customWrapper) {
|
|
1473
|
-
return (
|
|
1535
|
+
return createHtmlElement.bind(null, name.toLowerCase(), customWrapper);
|
|
1474
1536
|
}
|
|
1475
1537
|
|
|
1476
1538
|
const cloneBindingsDataCache = new WeakMap();
|
|
1477
1539
|
|
|
1478
1540
|
|
|
1479
1541
|
const bindAttributes = (node, bindDingData, data) => {
|
|
1480
|
-
|
|
1481
|
-
return null;
|
|
1482
|
-
}
|
|
1483
|
-
const attributes = { };
|
|
1542
|
+
let attributes = null;
|
|
1484
1543
|
if(bindDingData.attributes) {
|
|
1544
|
+
attributes = attributes || {};
|
|
1485
1545
|
for (const attr in bindDingData.attributes) {
|
|
1486
1546
|
attributes[attr] = bindDingData.attributes[attr](...data);
|
|
1487
1547
|
}
|
|
1488
1548
|
}
|
|
1489
1549
|
|
|
1490
1550
|
if(bindDingData.classes) {
|
|
1551
|
+
attributes = attributes || {};
|
|
1491
1552
|
attributes.class = {};
|
|
1492
1553
|
for (const className in bindDingData.classes) {
|
|
1493
1554
|
attributes.class[className] = bindDingData.classes[className](...data);
|
|
@@ -1495,30 +1556,27 @@ var NativeDocument = (function (exports) {
|
|
|
1495
1556
|
}
|
|
1496
1557
|
|
|
1497
1558
|
if(bindDingData.styles) {
|
|
1559
|
+
attributes = attributes || {};
|
|
1498
1560
|
attributes.style = {};
|
|
1499
1561
|
for (const property in bindDingData.styles) {
|
|
1500
1562
|
attributes.style[property] = bindDingData.styles[property](...data);
|
|
1501
1563
|
}
|
|
1502
1564
|
}
|
|
1503
1565
|
|
|
1504
|
-
if(
|
|
1566
|
+
if(attributes) {
|
|
1505
1567
|
ElementCreator.processAttributes(node, attributes);
|
|
1506
|
-
return
|
|
1568
|
+
return true;
|
|
1507
1569
|
}
|
|
1508
1570
|
|
|
1509
1571
|
return null;
|
|
1510
1572
|
};
|
|
1511
1573
|
|
|
1512
1574
|
|
|
1513
|
-
const
|
|
1514
|
-
if(!bindDingData
|
|
1575
|
+
const bindAttachMethods = function(node, bindDingData, data) {
|
|
1576
|
+
if(!bindDingData.attach) {
|
|
1515
1577
|
return null;
|
|
1516
1578
|
}
|
|
1517
|
-
|
|
1518
|
-
node.nd[methodName](function(...args) {
|
|
1519
|
-
bindDingData.attaches[methodName].call(this, ...[...args, ...data]);
|
|
1520
|
-
});
|
|
1521
|
-
}
|
|
1579
|
+
bindDingData.attach(node, ...data);
|
|
1522
1580
|
};
|
|
1523
1581
|
|
|
1524
1582
|
function TemplateCloner($fn) {
|
|
@@ -1526,18 +1584,20 @@ var NativeDocument = (function (exports) {
|
|
|
1526
1584
|
|
|
1527
1585
|
const clone = (node, data) => {
|
|
1528
1586
|
const bindDingData = cloneBindingsDataCache.get(node);
|
|
1529
|
-
if(node
|
|
1530
|
-
if(bindDingData
|
|
1587
|
+
if(node.nodeType === 3) {
|
|
1588
|
+
if(bindDingData && bindDingData.value) {
|
|
1531
1589
|
return bindDingData.value(data);
|
|
1532
1590
|
}
|
|
1533
1591
|
return node.cloneNode(true);
|
|
1534
1592
|
}
|
|
1535
1593
|
const nodeCloned = node.cloneNode();
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1594
|
+
if(bindDingData) {
|
|
1595
|
+
bindAttributes(nodeCloned, bindDingData, data);
|
|
1596
|
+
bindAttachMethods(nodeCloned, bindDingData, data);
|
|
1597
|
+
}
|
|
1598
|
+
const childNodes = node.childNodes;
|
|
1599
|
+
for(let i = 0, length = childNodes.length; i < length; i++) {
|
|
1600
|
+
const childNode = childNodes[i];
|
|
1541
1601
|
const childNodeCloned = clone(childNode, data);
|
|
1542
1602
|
nodeCloned.appendChild(childNodeCloned);
|
|
1543
1603
|
}
|
|
@@ -1551,21 +1611,27 @@ var NativeDocument = (function (exports) {
|
|
|
1551
1611
|
return clone($node, data);
|
|
1552
1612
|
};
|
|
1553
1613
|
|
|
1614
|
+
const $hydrateFn = function(hydrateFunction, target, element, property) {
|
|
1615
|
+
if(!cloneBindingsDataCache.has(element)) {
|
|
1616
|
+
// { classes, styles, attributes, value, attach }
|
|
1617
|
+
cloneBindingsDataCache.set(element, {});
|
|
1618
|
+
}
|
|
1619
|
+
const hydrationState = cloneBindingsDataCache.get(element);
|
|
1620
|
+
if(target === 'value') {
|
|
1621
|
+
hydrationState.value = hydrateFunction;
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
if(target === 'attach') {
|
|
1625
|
+
hydrationState.attach = hydrateFunction;
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
hydrationState[target] = hydrationState[target] || {};
|
|
1629
|
+
hydrationState[target][property] = hydrateFunction;
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1554
1632
|
const createBinding = (hydrateFunction, target) => {
|
|
1555
1633
|
return {
|
|
1556
|
-
$hydrate :
|
|
1557
|
-
if(!cloneBindingsDataCache.has(element)) {
|
|
1558
|
-
// { classes, styles, attributes, value, attaches }
|
|
1559
|
-
cloneBindingsDataCache.set(element, {});
|
|
1560
|
-
}
|
|
1561
|
-
const hydrationState = cloneBindingsDataCache.get(element);
|
|
1562
|
-
if(target === 'value') {
|
|
1563
|
-
hydrationState.value = hydrateFunction;
|
|
1564
|
-
return;
|
|
1565
|
-
}
|
|
1566
|
-
hydrationState[target] = hydrationState[target] || {};
|
|
1567
|
-
hydrationState[target][property] = hydrateFunction;
|
|
1568
|
-
}
|
|
1634
|
+
$hydrate : (element, property) => $hydrateFn(hydrateFunction, target, element, property),
|
|
1569
1635
|
}
|
|
1570
1636
|
};
|
|
1571
1637
|
|
|
@@ -1575,29 +1641,46 @@ var NativeDocument = (function (exports) {
|
|
|
1575
1641
|
this.class = (fn) => {
|
|
1576
1642
|
return createBinding(fn, 'classes');
|
|
1577
1643
|
};
|
|
1578
|
-
this.
|
|
1644
|
+
this.property = (propertyName) => {
|
|
1645
|
+
return this.value(propertyName);
|
|
1646
|
+
};
|
|
1647
|
+
this.value = (callbackOrProperty) => {
|
|
1648
|
+
if(typeof callbackOrProperty !== 'function') {
|
|
1649
|
+
return createBinding(function(data) {
|
|
1650
|
+
const firstArgument = data[0];
|
|
1651
|
+
return createTextNode(firstArgument[callbackOrProperty]);
|
|
1652
|
+
}, 'value');
|
|
1653
|
+
}
|
|
1579
1654
|
return createBinding(function(data) {
|
|
1580
|
-
return createTextNode(
|
|
1655
|
+
return createTextNode(callbackOrProperty(...data));
|
|
1581
1656
|
}, 'value');
|
|
1582
1657
|
};
|
|
1583
1658
|
this.attr = (fn) => {
|
|
1584
1659
|
return createBinding(fn, 'attributes');
|
|
1585
1660
|
};
|
|
1586
1661
|
this.attach = (fn) => {
|
|
1587
|
-
return createBinding(fn, '
|
|
1662
|
+
return createBinding(fn, 'attach');
|
|
1588
1663
|
};
|
|
1589
1664
|
}
|
|
1590
1665
|
|
|
1591
1666
|
function useCache(fn) {
|
|
1592
1667
|
let $cache = null;
|
|
1593
1668
|
|
|
1594
|
-
|
|
1669
|
+
const wrapper = function(args) {
|
|
1595
1670
|
if(!$cache) {
|
|
1596
1671
|
$cache = new TemplateCloner(fn);
|
|
1597
1672
|
}
|
|
1598
|
-
|
|
1599
1673
|
return $cache.clone(args);
|
|
1600
1674
|
};
|
|
1675
|
+
|
|
1676
|
+
if(fn.length < 2) {
|
|
1677
|
+
return function(...args) {
|
|
1678
|
+
return wrapper(args);
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
return function(_, __, ...args) {
|
|
1682
|
+
return wrapper([_, __, ...args]);
|
|
1683
|
+
};
|
|
1601
1684
|
}
|
|
1602
1685
|
|
|
1603
1686
|
Function.prototype.args = function(...args) {
|
|
@@ -1657,6 +1740,118 @@ var NativeDocument = (function (exports) {
|
|
|
1657
1740
|
});
|
|
1658
1741
|
};
|
|
1659
1742
|
|
|
1743
|
+
(function() {
|
|
1744
|
+
const DelegatedEventsCallbackStore = {};
|
|
1745
|
+
|
|
1746
|
+
const addCallbackToCallbacksStore = function(element, eventName, callback) {
|
|
1747
|
+
if(!element) return;
|
|
1748
|
+
if(!DelegatedEventsCallbackStore[eventName]) {
|
|
1749
|
+
const eventStore = new WeakMap();
|
|
1750
|
+
DelegatedEventsCallbackStore[eventName] = eventStore;
|
|
1751
|
+
eventStore.set(element, callback);
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
const eventStore = DelegatedEventsCallbackStore[eventName];
|
|
1755
|
+
|
|
1756
|
+
if(!eventStore.has(element)) {
|
|
1757
|
+
eventStore.set(element, callback);
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
const existingCallbacks = eventStore.get(element);
|
|
1761
|
+
if(!Validator.isArray(existingCallbacks)) {
|
|
1762
|
+
eventStore.set(element, [store[eventName], callback]);
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
existingCallbacks.push(callback);
|
|
1766
|
+
};
|
|
1767
|
+
|
|
1768
|
+
const handleDelegatedCallbacks = function(container, eventName) {
|
|
1769
|
+
container.addEventListener(eventName, (event) => {
|
|
1770
|
+
const eventStore = DelegatedEventsCallbackStore[eventName];
|
|
1771
|
+
if(!eventStore) {
|
|
1772
|
+
return;
|
|
1773
|
+
}
|
|
1774
|
+
let target = event.target;
|
|
1775
|
+
while(target && target !== container) {
|
|
1776
|
+
const callback = eventStore.get(target);
|
|
1777
|
+
if(!callback) {
|
|
1778
|
+
target = target.parentElement;
|
|
1779
|
+
continue;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
if(Validator.isFunction(callback)) {
|
|
1783
|
+
callback.call(target, event);
|
|
1784
|
+
}
|
|
1785
|
+
else {
|
|
1786
|
+
for(let i = 0; i < callback.length; i++) {
|
|
1787
|
+
callback[i].call(target, event);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
return;
|
|
1791
|
+
}
|
|
1792
|
+
});
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
const preventDefaultWrapper = function(element, eventName, callback) {
|
|
1797
|
+
element.addEventListener(eventName, (event) => {
|
|
1798
|
+
event.preventDefault();
|
|
1799
|
+
callback && callback.call(element, event);
|
|
1800
|
+
});
|
|
1801
|
+
return this;
|
|
1802
|
+
};
|
|
1803
|
+
const stopPropagationWrapper = function(element, eventName, callback) {
|
|
1804
|
+
element.addEventListener(eventName, (event) => {
|
|
1805
|
+
event.stopPropagation();
|
|
1806
|
+
callback && callback.call(element, event);
|
|
1807
|
+
});
|
|
1808
|
+
return this;
|
|
1809
|
+
};
|
|
1810
|
+
const preventDefaultAndStopPropagationWrapper = function(element, eventName, callback) {
|
|
1811
|
+
element.addEventListener(eventName, (event) => {
|
|
1812
|
+
event.stopPropagation();
|
|
1813
|
+
event.preventDefault();
|
|
1814
|
+
callback && callback.call(element, event);
|
|
1815
|
+
});
|
|
1816
|
+
return this;
|
|
1817
|
+
};
|
|
1818
|
+
const captureEventWrapper = function(element, eventName, directHandler) {
|
|
1819
|
+
if(directHandler) {
|
|
1820
|
+
element.addEventListener(eventName, directHandler);
|
|
1821
|
+
return this;
|
|
1822
|
+
}
|
|
1823
|
+
handleDelegatedCallbacks(element, eventName);
|
|
1824
|
+
return this;
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
for(const event of EVENTS) {
|
|
1828
|
+
const eventName = event.toLowerCase();
|
|
1829
|
+
NDElement.prototype['on'+event] = function(callback) {
|
|
1830
|
+
this.$element.addEventListener(eventName, callback);
|
|
1831
|
+
return this;
|
|
1832
|
+
};
|
|
1833
|
+
NDElement.prototype['onPrevent'+event] = function(callback) {
|
|
1834
|
+
return preventDefaultWrapper(this.$element, eventName, callback);
|
|
1835
|
+
};
|
|
1836
|
+
NDElement.prototype['onStop'+event] = function(callback) {
|
|
1837
|
+
return stopPropagationWrapper(this.$element, eventName, callback);
|
|
1838
|
+
};
|
|
1839
|
+
NDElement.prototype['onPreventStop'+event] = function(callback) {
|
|
1840
|
+
return preventDefaultAndStopPropagationWrapper(this.$element, eventName, callback);
|
|
1841
|
+
};
|
|
1842
|
+
|
|
1843
|
+
NDElement.prototype['when'+event] = function(callback) {
|
|
1844
|
+
addCallbackToCallbacksStore(this.$element, eventName, callback);
|
|
1845
|
+
return this;
|
|
1846
|
+
};
|
|
1847
|
+
|
|
1848
|
+
NDElement.prototype['capture'+event] = function(directHandler) {
|
|
1849
|
+
captureEventWrapper(this.$element, eventName, directHandler);
|
|
1850
|
+
return this;
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
}());
|
|
1854
|
+
|
|
1660
1855
|
const cssPropertyAccumulator = function(initialValue = {}) {
|
|
1661
1856
|
let data = Validator.isString(initialValue) ? initialValue.split(';').filter(Boolean) : initialValue;
|
|
1662
1857
|
const isArray = Validator.isArray(data);
|
|
@@ -1769,9 +1964,9 @@ var NativeDocument = (function (exports) {
|
|
|
1769
1964
|
return observer.val().length;
|
|
1770
1965
|
};
|
|
1771
1966
|
|
|
1772
|
-
const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat'];
|
|
1967
|
+
const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat', 'includes', 'indexOf'];
|
|
1773
1968
|
overrideMethods.forEach((method) => {
|
|
1774
|
-
observer[method] =
|
|
1969
|
+
observer[method] = (...args) => {
|
|
1775
1970
|
return observer.val()[method](...args);
|
|
1776
1971
|
};
|
|
1777
1972
|
});
|
|
@@ -1801,13 +1996,13 @@ var NativeDocument = (function (exports) {
|
|
|
1801
1996
|
|
|
1802
1997
|
/**
|
|
1803
1998
|
*
|
|
1804
|
-
* @param {Object}
|
|
1999
|
+
* @param {Object} initialValue
|
|
1805
2000
|
* @returns {Proxy}
|
|
1806
2001
|
*/
|
|
1807
|
-
Observable.init = function(
|
|
2002
|
+
Observable.init = function(initialValue) {
|
|
1808
2003
|
const data = {};
|
|
1809
|
-
for(const key in
|
|
1810
|
-
const itemValue =
|
|
2004
|
+
for(const key in initialValue) {
|
|
2005
|
+
const itemValue = initialValue[key];
|
|
1811
2006
|
if(Validator.isJson(itemValue)) {
|
|
1812
2007
|
data[key] = Observable.init(itemValue);
|
|
1813
2008
|
continue;
|
|
@@ -1836,8 +2031,11 @@ var NativeDocument = (function (exports) {
|
|
|
1836
2031
|
const $clone = function() {
|
|
1837
2032
|
|
|
1838
2033
|
};
|
|
2034
|
+
const $updateWith = function(values) {
|
|
2035
|
+
Observable.update(proxy, values);
|
|
2036
|
+
};
|
|
1839
2037
|
|
|
1840
|
-
|
|
2038
|
+
const proxy = new Proxy(data, {
|
|
1841
2039
|
get(target, property) {
|
|
1842
2040
|
if(property === '__isProxy__') {
|
|
1843
2041
|
return true;
|
|
@@ -1848,6 +2046,12 @@ var NativeDocument = (function (exports) {
|
|
|
1848
2046
|
if(property === '$clone') {
|
|
1849
2047
|
return $clone;
|
|
1850
2048
|
}
|
|
2049
|
+
if(property === '$observables') {
|
|
2050
|
+
return Object.values(target);
|
|
2051
|
+
}
|
|
2052
|
+
if(property === '$updateWith') {
|
|
2053
|
+
return $updateWith;
|
|
2054
|
+
}
|
|
1851
2055
|
if(target[property] !== undefined) {
|
|
1852
2056
|
return target[property];
|
|
1853
2057
|
}
|
|
@@ -1855,10 +2059,25 @@ var NativeDocument = (function (exports) {
|
|
|
1855
2059
|
},
|
|
1856
2060
|
set(target, prop, newValue) {
|
|
1857
2061
|
if(target[prop] !== undefined) {
|
|
1858
|
-
|
|
2062
|
+
Validator.isObservable(newValue)
|
|
2063
|
+
? target[prop].set(newValue.val())
|
|
2064
|
+
: target[prop].set(newValue);
|
|
2065
|
+
return true;
|
|
1859
2066
|
}
|
|
2067
|
+
return true;
|
|
1860
2068
|
}
|
|
1861
|
-
})
|
|
2069
|
+
});
|
|
2070
|
+
|
|
2071
|
+
return proxy;
|
|
2072
|
+
};
|
|
2073
|
+
|
|
2074
|
+
/**
|
|
2075
|
+
*
|
|
2076
|
+
* @param {any[]} data
|
|
2077
|
+
* @return Proxy[]
|
|
2078
|
+
*/
|
|
2079
|
+
Observable.arrayOfObject = function(data) {
|
|
2080
|
+
return data.map(item => Observable.object(item));
|
|
1862
2081
|
};
|
|
1863
2082
|
|
|
1864
2083
|
/**
|
|
@@ -1886,13 +2105,16 @@ var NativeDocument = (function (exports) {
|
|
|
1886
2105
|
|
|
1887
2106
|
|
|
1888
2107
|
Observable.update = function($target, data) {
|
|
2108
|
+
if(Validator.isProxy(data)) {
|
|
2109
|
+
data = data.$value;
|
|
2110
|
+
}
|
|
1889
2111
|
for(const key in data) {
|
|
1890
2112
|
const targetItem = $target[key];
|
|
1891
2113
|
const newValue = data[key];
|
|
1892
2114
|
|
|
1893
2115
|
if(Validator.isObservable(targetItem)) {
|
|
1894
2116
|
if(Validator.isArray(newValue)) {
|
|
1895
|
-
|
|
2117
|
+
targetItem.set([...newValue]);
|
|
1896
2118
|
continue;
|
|
1897
2119
|
}
|
|
1898
2120
|
targetItem.set(newValue);
|
|
@@ -1930,7 +2152,15 @@ var NativeDocument = (function (exports) {
|
|
|
1930
2152
|
return observable;
|
|
1931
2153
|
}
|
|
1932
2154
|
|
|
1933
|
-
dependencies.forEach(dependency =>
|
|
2155
|
+
dependencies.forEach(dependency => {
|
|
2156
|
+
if(Validator.isProxy(dependency)) {
|
|
2157
|
+
dependency.$observables.forEach((observable) => {
|
|
2158
|
+
observable.subscribe(updatedValue);
|
|
2159
|
+
});
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
dependency.subscribe(updatedValue);
|
|
2163
|
+
});
|
|
1934
2164
|
|
|
1935
2165
|
return observable;
|
|
1936
2166
|
};
|
|
@@ -2012,10 +2242,11 @@ var NativeDocument = (function (exports) {
|
|
|
2012
2242
|
*
|
|
2013
2243
|
* @param {Array|Object|ObservableItem} data
|
|
2014
2244
|
* @param {Function} callback
|
|
2015
|
-
* @param {?Function} key
|
|
2245
|
+
* @param {?Function|?string} key
|
|
2246
|
+
* @param {{shouldKeepItemsInCache: boolean}?} configs
|
|
2016
2247
|
* @returns {DocumentFragment}
|
|
2017
2248
|
*/
|
|
2018
|
-
function ForEach(data, callback, key) {
|
|
2249
|
+
function ForEach(data, callback, key, { shouldKeepItemsInCache = false } = {}) {
|
|
2019
2250
|
const element = new Anchor('ForEach');
|
|
2020
2251
|
const blockEnd = element.endElement();
|
|
2021
2252
|
element.startElement();
|
|
@@ -2030,6 +2261,9 @@ var NativeDocument = (function (exports) {
|
|
|
2030
2261
|
};
|
|
2031
2262
|
|
|
2032
2263
|
const cleanCache = (parent) => {
|
|
2264
|
+
if(shouldKeepItemsInCache) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2033
2267
|
for(const [keyId, cacheItem] of cache.entries()) {
|
|
2034
2268
|
if(keyIds.has(keyId)) {
|
|
2035
2269
|
continue;
|
|
@@ -2062,6 +2296,9 @@ var NativeDocument = (function (exports) {
|
|
|
2062
2296
|
try {
|
|
2063
2297
|
const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
|
|
2064
2298
|
let child = ElementCreator.getChild(callback(item, indexObserver));
|
|
2299
|
+
if(!child || Validator.isFragment(child)) {
|
|
2300
|
+
throw new NativeDocumentError("ForEachArray child can't be null or undefined!");
|
|
2301
|
+
}
|
|
2065
2302
|
cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
|
|
2066
2303
|
} catch (e) {
|
|
2067
2304
|
DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
|
|
@@ -2113,7 +2350,7 @@ var NativeDocument = (function (exports) {
|
|
|
2113
2350
|
keyIds.clear();
|
|
2114
2351
|
if(Array.isArray(items)) {
|
|
2115
2352
|
for(let i = 0, length = items.length; i < length; i++) {
|
|
2116
|
-
const keyId= handleContentItem(items[i], i);
|
|
2353
|
+
const keyId = handleContentItem(items[i], i);
|
|
2117
2354
|
keyIds.add(keyId);
|
|
2118
2355
|
}
|
|
2119
2356
|
} else {
|
|
@@ -2191,14 +2428,12 @@ var NativeDocument = (function (exports) {
|
|
|
2191
2428
|
if(!cacheItem) {
|
|
2192
2429
|
return;
|
|
2193
2430
|
}
|
|
2194
|
-
const child = cacheItem.child;
|
|
2195
|
-
cacheItem.indexObserver?.deref()?.cleanup();
|
|
2196
|
-
cacheItem.child = null;
|
|
2197
|
-
cacheItem.indexObserver = null;
|
|
2198
2431
|
if(removeChild) {
|
|
2432
|
+
const child = cacheItem.child;
|
|
2199
2433
|
child?.remove();
|
|
2200
2434
|
cache.delete(cacheItem.keyId);
|
|
2201
2435
|
}
|
|
2436
|
+
cacheItem.indexObserver?.deref()?.cleanup();
|
|
2202
2437
|
};
|
|
2203
2438
|
|
|
2204
2439
|
const removeCacheItemByKey = (keyId, removeChild = true) => {
|
|
@@ -2206,6 +2441,13 @@ var NativeDocument = (function (exports) {
|
|
|
2206
2441
|
};
|
|
2207
2442
|
|
|
2208
2443
|
const cleanCache = () => {
|
|
2444
|
+
if(configs.shouldKeepItemsInCache) {
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
if(!isIndexRequired) {
|
|
2448
|
+
cache.clear();
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2209
2451
|
for (const [keyId, cacheItem] of cache.entries()) {
|
|
2210
2452
|
removeCacheItem(cacheItem, false);
|
|
2211
2453
|
}
|
|
@@ -2227,6 +2469,9 @@ var NativeDocument = (function (exports) {
|
|
|
2227
2469
|
|
|
2228
2470
|
const indexObserver = isIndexRequired ? Observable(indexKey) : null;
|
|
2229
2471
|
let child = ElementCreator.getChild(callback(item, indexObserver));
|
|
2472
|
+
if(!child || Validator.isFragment(child)) {
|
|
2473
|
+
throw new NativeDocumentError("ForEachArray child can't be null or undefined!");
|
|
2474
|
+
}
|
|
2230
2475
|
cache.set(keyId, {
|
|
2231
2476
|
keyId,
|
|
2232
2477
|
child: child,
|
|
@@ -2269,12 +2514,12 @@ var NativeDocument = (function (exports) {
|
|
|
2269
2514
|
toFragment(items, startIndexFrom = 0){
|
|
2270
2515
|
const fragment = document.createDocumentFragment();
|
|
2271
2516
|
for(let i = 0, length = items.length; i < length; i++) {
|
|
2272
|
-
fragment.
|
|
2517
|
+
fragment.appendChild(buildItem(items[i], lastNumberOfItems));
|
|
2273
2518
|
lastNumberOfItems++;
|
|
2274
2519
|
}
|
|
2275
2520
|
return fragment;
|
|
2276
2521
|
},
|
|
2277
|
-
add(items, delay =
|
|
2522
|
+
add(items, delay = 2) {
|
|
2278
2523
|
const fragment = Actions.toFragment(items);
|
|
2279
2524
|
setTimeout(() => {
|
|
2280
2525
|
element.appendElement(fragment);
|
|
@@ -2301,7 +2546,7 @@ var NativeDocument = (function (exports) {
|
|
|
2301
2546
|
},
|
|
2302
2547
|
clear,
|
|
2303
2548
|
merge(items) {
|
|
2304
|
-
Actions.add(items
|
|
2549
|
+
Actions.add(items);
|
|
2305
2550
|
},
|
|
2306
2551
|
push(items) {
|
|
2307
2552
|
let delay = 0;
|
|
@@ -2408,7 +2653,9 @@ var NativeDocument = (function (exports) {
|
|
|
2408
2653
|
updateIndexObservers(items, 0);
|
|
2409
2654
|
};
|
|
2410
2655
|
|
|
2411
|
-
|
|
2656
|
+
if(data.val().length) {
|
|
2657
|
+
buildContent(data.val(), null, {action: null});
|
|
2658
|
+
}
|
|
2412
2659
|
if(Validator.isObservable(data)) {
|
|
2413
2660
|
data.subscribe(buildContent);
|
|
2414
2661
|
}
|
|
@@ -2421,10 +2668,10 @@ var NativeDocument = (function (exports) {
|
|
|
2421
2668
|
*
|
|
2422
2669
|
* @param {ObservableItem|ObservableChecker} condition
|
|
2423
2670
|
* @param {*} child
|
|
2424
|
-
* @param {string|null} comment
|
|
2671
|
+
* @param {{comment?: string|null, shouldKeepInCache?: Boolean}} comment
|
|
2425
2672
|
* @returns {DocumentFragment}
|
|
2426
2673
|
*/
|
|
2427
|
-
const ShowIf = function(condition, child, comment = null) {
|
|
2674
|
+
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
2428
2675
|
if(!(Validator.isObservable(condition))) {
|
|
2429
2676
|
return DebugManager$1.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
|
|
2430
2677
|
}
|
|
@@ -2432,10 +2679,13 @@ var NativeDocument = (function (exports) {
|
|
|
2432
2679
|
|
|
2433
2680
|
let childElement = null;
|
|
2434
2681
|
const getChildElement = () => {
|
|
2435
|
-
if(childElement) {
|
|
2682
|
+
if(childElement && shouldKeepInCache) {
|
|
2436
2683
|
return childElement;
|
|
2437
2684
|
}
|
|
2438
2685
|
childElement = ElementCreator.getChild(child);
|
|
2686
|
+
if(Validator.isFragment(childElement)) {
|
|
2687
|
+
childElement = Array.from(childElement.children);
|
|
2688
|
+
}
|
|
2439
2689
|
return childElement;
|
|
2440
2690
|
};
|
|
2441
2691
|
|
|
@@ -2507,6 +2757,9 @@ var NativeDocument = (function (exports) {
|
|
|
2507
2757
|
return null;
|
|
2508
2758
|
}
|
|
2509
2759
|
item = ElementCreator.getChild(item);
|
|
2760
|
+
if(Validator.isFragment(item)) {
|
|
2761
|
+
item = Array.from(item.children);
|
|
2762
|
+
}
|
|
2510
2763
|
shouldKeepInCache && cache.set(key, item);
|
|
2511
2764
|
return item;
|
|
2512
2765
|
};
|