native-document 1.0.35 → 1.0.37
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 +455 -211
- 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 +20 -15
- 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 +78 -47
- 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,10 +839,7 @@ var NativeDocument = (function (exports) {
|
|
|
852
839
|
element.nativeInsertBefore = element.insertBefore;
|
|
853
840
|
element.nativeAppendChild = element.appendChild;
|
|
854
841
|
|
|
855
|
-
const isParentUniqueChild = (parent) =>
|
|
856
|
-
console.log('on passwr ici ', isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd));
|
|
857
|
-
return isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd);
|
|
858
|
-
};
|
|
842
|
+
const isParentUniqueChild = (parent) => (isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd));
|
|
859
843
|
|
|
860
844
|
const insertBefore = function(parent, child, target) {
|
|
861
845
|
const element = Validator.isElement(child) ? child : ElementCreator.getChild(child);
|
|
@@ -863,25 +847,21 @@ var NativeDocument = (function (exports) {
|
|
|
863
847
|
parent.nativeInsertBefore(element, target);
|
|
864
848
|
return;
|
|
865
849
|
}
|
|
866
|
-
if(isParentUniqueChild(parent)) {
|
|
867
|
-
parent.append(element,
|
|
850
|
+
if(isParentUniqueChild(parent) || target === anchorEnd) {
|
|
851
|
+
parent.append(element, target);
|
|
868
852
|
return;
|
|
869
853
|
}
|
|
870
854
|
parent.insertBefore(element, target);
|
|
871
855
|
};
|
|
872
856
|
|
|
873
857
|
element.appendElement = function(child, before = null) {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
858
|
+
const parentNode = anchorStart.parentNode;
|
|
859
|
+
const targetBefore = before || anchorEnd;
|
|
860
|
+
if(parentNode === element) {
|
|
861
|
+
parentNode.nativeInsertBefore(child, targetBefore);
|
|
878
862
|
return;
|
|
879
863
|
}
|
|
880
|
-
|
|
881
|
-
anchorEnd.parentNode.nativeInsertBefore(child, before || anchorEnd);
|
|
882
|
-
return;
|
|
883
|
-
}
|
|
884
|
-
anchorEnd.parentNode?.insertBefore(child, before || anchorEnd);
|
|
864
|
+
parentNode?.insertBefore(child, targetBefore);
|
|
885
865
|
};
|
|
886
866
|
|
|
887
867
|
element.appendChild = function(child, before = null) {
|
|
@@ -960,10 +940,22 @@ var NativeDocument = (function (exports) {
|
|
|
960
940
|
element.endElement = function() {
|
|
961
941
|
return anchorEnd;
|
|
962
942
|
};
|
|
943
|
+
|
|
963
944
|
element.startElement = function() {
|
|
964
945
|
return anchorStart;
|
|
965
946
|
};
|
|
966
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
|
+
|
|
967
959
|
return element;
|
|
968
960
|
}
|
|
969
961
|
|
|
@@ -1018,6 +1010,26 @@ var NativeDocument = (function (exports) {
|
|
|
1018
1010
|
setInterval(() => MemoryManager.cleanObservables(threshold), interval);
|
|
1019
1011
|
};
|
|
1020
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
|
+
}
|
|
1021
1033
|
/**
|
|
1022
1034
|
*
|
|
1023
1035
|
* @param {HTMLElement} element
|
|
@@ -1027,23 +1039,22 @@ var NativeDocument = (function (exports) {
|
|
|
1027
1039
|
for(let className in data) {
|
|
1028
1040
|
const value = data[className];
|
|
1029
1041
|
if(Validator.isObservable(value)) {
|
|
1030
|
-
element.
|
|
1031
|
-
value.subscribe(
|
|
1042
|
+
element.classes.toggle(className, value.val());
|
|
1043
|
+
value.subscribe(toggleElementClass.bind(null, element, className));
|
|
1032
1044
|
continue;
|
|
1033
1045
|
}
|
|
1034
1046
|
if(value.$observer) {
|
|
1035
|
-
element.
|
|
1036
|
-
value.$observer.on(value.$target,
|
|
1037
|
-
element.classList.toggle(className, isTargetValue);
|
|
1038
|
-
});
|
|
1047
|
+
element.classes.toggle(className, value.$observer.val() === value.$target);
|
|
1048
|
+
value.$observer.on(value.$target, toggleElementClass.bind(null, element, className));
|
|
1039
1049
|
continue;
|
|
1040
1050
|
}
|
|
1041
1051
|
if(value.$hydrate) {
|
|
1042
1052
|
value.$hydrate(element, className);
|
|
1043
1053
|
continue;
|
|
1044
1054
|
}
|
|
1045
|
-
element.
|
|
1055
|
+
element.classes.toggle(className, value);
|
|
1046
1056
|
}
|
|
1057
|
+
data = null;
|
|
1047
1058
|
}
|
|
1048
1059
|
|
|
1049
1060
|
/**
|
|
@@ -1056,9 +1067,7 @@ var NativeDocument = (function (exports) {
|
|
|
1056
1067
|
const value = data[styleName];
|
|
1057
1068
|
if(Validator.isObservable(value)) {
|
|
1058
1069
|
element.style[styleName] = value.val();
|
|
1059
|
-
value.subscribe(
|
|
1060
|
-
element.style[styleName] = newValue;
|
|
1061
|
-
});
|
|
1070
|
+
value.subscribe(toggleElementStyle.bind(null, element, styleName));
|
|
1062
1071
|
continue;
|
|
1063
1072
|
}
|
|
1064
1073
|
element.style[styleName] = value;
|
|
@@ -1081,21 +1090,9 @@ var NativeDocument = (function (exports) {
|
|
|
1081
1090
|
}
|
|
1082
1091
|
if(Validator.isObservable(value)) {
|
|
1083
1092
|
if(['checked'].includes(attributeName)) {
|
|
1084
|
-
element.addEventListener('input', (
|
|
1085
|
-
if(Validator.isBoolean(defaultValue)) {
|
|
1086
|
-
value.set(element[attributeName]);
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
value.set(element.value);
|
|
1090
|
-
});
|
|
1093
|
+
element.addEventListener('input', updateObserverFromInput.bind(null, element, attributeName, defaultValue));
|
|
1091
1094
|
}
|
|
1092
|
-
value.subscribe(
|
|
1093
|
-
if(Validator.isBoolean(newValue)) {
|
|
1094
|
-
element[attributeName] = newValue;
|
|
1095
|
-
return;
|
|
1096
|
-
}
|
|
1097
|
-
element[attributeName] = newValue === element.value;
|
|
1098
|
-
});
|
|
1095
|
+
value.subscribe(updateInputFromObserver.bind(null, element, attributeName));
|
|
1099
1096
|
}
|
|
1100
1097
|
}
|
|
1101
1098
|
|
|
@@ -1149,11 +1146,11 @@ var NativeDocument = (function (exports) {
|
|
|
1149
1146
|
return value.map(item => Validator.isObservable(item) ? item.val() : item).join(' ') || ' ';
|
|
1150
1147
|
}, observables);
|
|
1151
1148
|
}
|
|
1152
|
-
if(attributeName === 'class' && Validator.
|
|
1149
|
+
if(attributeName === 'class' && Validator.isObject(value)) {
|
|
1153
1150
|
bindClassAttribute(element, value);
|
|
1154
1151
|
continue;
|
|
1155
1152
|
}
|
|
1156
|
-
if(attributeName === 'style' && Validator.
|
|
1153
|
+
if(attributeName === 'style' && Validator.isObject(value)) {
|
|
1157
1154
|
bindStyleAttribute(element, value);
|
|
1158
1155
|
continue;
|
|
1159
1156
|
}
|
|
@@ -1165,6 +1162,10 @@ var NativeDocument = (function (exports) {
|
|
|
1165
1162
|
bindAttributeWithObservable(element, attributeName, value);
|
|
1166
1163
|
continue;
|
|
1167
1164
|
}
|
|
1165
|
+
if(value.$hydrate) {
|
|
1166
|
+
value.$hydrate(element, attributeName);
|
|
1167
|
+
continue;
|
|
1168
|
+
}
|
|
1168
1169
|
element.setAttribute(attributeName, value);
|
|
1169
1170
|
|
|
1170
1171
|
}
|
|
@@ -1241,14 +1242,19 @@ var NativeDocument = (function (exports) {
|
|
|
1241
1242
|
*/
|
|
1242
1243
|
processChildren(children, parent) {
|
|
1243
1244
|
if(children === null) return;
|
|
1244
|
-
const childrenArray = Array.isArray(children) ? children : [children];
|
|
1245
|
-
|
|
1246
1245
|
PluginsManager.emit('BeforeProcessChildren', parent);
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
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
|
+
}
|
|
1252
1258
|
}
|
|
1253
1259
|
|
|
1254
1260
|
PluginsManager.emit('AfterProcessChildren', parent);
|
|
@@ -1315,13 +1321,60 @@ var NativeDocument = (function (exports) {
|
|
|
1315
1321
|
Object.defineProperty(HTMLElement.prototype, 'nd', {
|
|
1316
1322
|
configurable: true,
|
|
1317
1323
|
get() {
|
|
1318
|
-
|
|
1319
|
-
|
|
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;
|
|
1320
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);
|
|
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
|
+
};
|
|
1321
1370
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1371
|
+
Object.defineProperty(HTMLElement.prototype, 'classes', {
|
|
1372
|
+
configurable: true,
|
|
1373
|
+
get() {
|
|
1374
|
+
return {
|
|
1375
|
+
$element: this,
|
|
1376
|
+
...classListMethods
|
|
1377
|
+
};
|
|
1325
1378
|
}
|
|
1326
1379
|
});
|
|
1327
1380
|
|
|
@@ -1457,13 +1510,17 @@ var NativeDocument = (function (exports) {
|
|
|
1457
1510
|
};
|
|
1458
1511
|
|
|
1459
1512
|
|
|
1460
|
-
function createHtmlElement($tagName, _attributes, _children = null
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
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;
|
|
1464
1517
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1518
|
+
if(attributes) {
|
|
1519
|
+
ElementCreator.processAttributes(finalElement, attributes);
|
|
1520
|
+
}
|
|
1521
|
+
if(children) {
|
|
1522
|
+
ElementCreator.processChildren(children, finalElement);
|
|
1523
|
+
}
|
|
1467
1524
|
|
|
1468
1525
|
return ElementCreator.setup(finalElement, attributes, customWrapper);
|
|
1469
1526
|
}
|
|
@@ -1475,24 +1532,23 @@ var NativeDocument = (function (exports) {
|
|
|
1475
1532
|
* @returns {Function}
|
|
1476
1533
|
*/
|
|
1477
1534
|
function HtmlElementWrapper(name, customWrapper) {
|
|
1478
|
-
return (
|
|
1535
|
+
return createHtmlElement.bind(null, name.toLowerCase(), customWrapper);
|
|
1479
1536
|
}
|
|
1480
1537
|
|
|
1481
1538
|
const cloneBindingsDataCache = new WeakMap();
|
|
1482
1539
|
|
|
1483
1540
|
|
|
1484
1541
|
const bindAttributes = (node, bindDingData, data) => {
|
|
1485
|
-
|
|
1486
|
-
return null;
|
|
1487
|
-
}
|
|
1488
|
-
const attributes = { };
|
|
1542
|
+
let attributes = null;
|
|
1489
1543
|
if(bindDingData.attributes) {
|
|
1544
|
+
attributes = attributes || {};
|
|
1490
1545
|
for (const attr in bindDingData.attributes) {
|
|
1491
1546
|
attributes[attr] = bindDingData.attributes[attr](...data);
|
|
1492
1547
|
}
|
|
1493
1548
|
}
|
|
1494
1549
|
|
|
1495
1550
|
if(bindDingData.classes) {
|
|
1551
|
+
attributes = attributes || {};
|
|
1496
1552
|
attributes.class = {};
|
|
1497
1553
|
for (const className in bindDingData.classes) {
|
|
1498
1554
|
attributes.class[className] = bindDingData.classes[className](...data);
|
|
@@ -1500,30 +1556,27 @@ var NativeDocument = (function (exports) {
|
|
|
1500
1556
|
}
|
|
1501
1557
|
|
|
1502
1558
|
if(bindDingData.styles) {
|
|
1559
|
+
attributes = attributes || {};
|
|
1503
1560
|
attributes.style = {};
|
|
1504
1561
|
for (const property in bindDingData.styles) {
|
|
1505
1562
|
attributes.style[property] = bindDingData.styles[property](...data);
|
|
1506
1563
|
}
|
|
1507
1564
|
}
|
|
1508
1565
|
|
|
1509
|
-
if(
|
|
1566
|
+
if(attributes) {
|
|
1510
1567
|
ElementCreator.processAttributes(node, attributes);
|
|
1511
|
-
return
|
|
1568
|
+
return true;
|
|
1512
1569
|
}
|
|
1513
1570
|
|
|
1514
1571
|
return null;
|
|
1515
1572
|
};
|
|
1516
1573
|
|
|
1517
1574
|
|
|
1518
|
-
const
|
|
1519
|
-
if(!bindDingData
|
|
1575
|
+
const bindAttachMethods = function(node, bindDingData, data) {
|
|
1576
|
+
if(!bindDingData.attach) {
|
|
1520
1577
|
return null;
|
|
1521
1578
|
}
|
|
1522
|
-
|
|
1523
|
-
node.nd[methodName](function(...args) {
|
|
1524
|
-
bindDingData.attaches[methodName].call(this, ...[...args, ...data]);
|
|
1525
|
-
});
|
|
1526
|
-
}
|
|
1579
|
+
bindDingData.attach(node, ...data);
|
|
1527
1580
|
};
|
|
1528
1581
|
|
|
1529
1582
|
function TemplateCloner($fn) {
|
|
@@ -1531,18 +1584,20 @@ var NativeDocument = (function (exports) {
|
|
|
1531
1584
|
|
|
1532
1585
|
const clone = (node, data) => {
|
|
1533
1586
|
const bindDingData = cloneBindingsDataCache.get(node);
|
|
1534
|
-
if(node
|
|
1535
|
-
if(bindDingData
|
|
1587
|
+
if(node.nodeType === 3) {
|
|
1588
|
+
if(bindDingData && bindDingData.value) {
|
|
1536
1589
|
return bindDingData.value(data);
|
|
1537
1590
|
}
|
|
1538
1591
|
return node.cloneNode(true);
|
|
1539
1592
|
}
|
|
1540
1593
|
const nodeCloned = node.cloneNode();
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
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];
|
|
1546
1601
|
const childNodeCloned = clone(childNode, data);
|
|
1547
1602
|
nodeCloned.appendChild(childNodeCloned);
|
|
1548
1603
|
}
|
|
@@ -1553,26 +1608,30 @@ var NativeDocument = (function (exports) {
|
|
|
1553
1608
|
if(!$node) {
|
|
1554
1609
|
$node = $fn(this);
|
|
1555
1610
|
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1611
|
+
return clone($node, data);
|
|
1612
|
+
};
|
|
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;
|
|
1559
1630
|
};
|
|
1560
1631
|
|
|
1561
1632
|
const createBinding = (hydrateFunction, target) => {
|
|
1562
1633
|
return {
|
|
1563
|
-
$hydrate :
|
|
1564
|
-
if(!cloneBindingsDataCache.has(element)) {
|
|
1565
|
-
// { classes, styles, attributes, value, attaches }
|
|
1566
|
-
cloneBindingsDataCache.set(element, {});
|
|
1567
|
-
}
|
|
1568
|
-
const hydrationState = cloneBindingsDataCache.get(element);
|
|
1569
|
-
if(target === 'value') {
|
|
1570
|
-
hydrationState.value = hydrateFunction;
|
|
1571
|
-
return;
|
|
1572
|
-
}
|
|
1573
|
-
hydrationState[target] = hydrationState[target] || {};
|
|
1574
|
-
hydrationState[target][property] = hydrateFunction;
|
|
1575
|
-
}
|
|
1634
|
+
$hydrate : (element, property) => $hydrateFn(hydrateFunction, target, element, property),
|
|
1576
1635
|
}
|
|
1577
1636
|
};
|
|
1578
1637
|
|
|
@@ -1582,31 +1641,46 @@ var NativeDocument = (function (exports) {
|
|
|
1582
1641
|
this.class = (fn) => {
|
|
1583
1642
|
return createBinding(fn, 'classes');
|
|
1584
1643
|
};
|
|
1585
|
-
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
|
+
}
|
|
1586
1654
|
return createBinding(function(data) {
|
|
1587
|
-
return createTextNode(
|
|
1655
|
+
return createTextNode(callbackOrProperty(...data));
|
|
1588
1656
|
}, 'value');
|
|
1589
1657
|
};
|
|
1590
1658
|
this.attr = (fn) => {
|
|
1591
1659
|
return createBinding(fn, 'attributes');
|
|
1592
1660
|
};
|
|
1593
1661
|
this.attach = (fn) => {
|
|
1594
|
-
return createBinding(fn, '
|
|
1662
|
+
return createBinding(fn, 'attach');
|
|
1595
1663
|
};
|
|
1596
1664
|
}
|
|
1597
1665
|
|
|
1598
1666
|
function useCache(fn) {
|
|
1599
1667
|
let $cache = null;
|
|
1600
|
-
PluginsManager.emit('NodeTemplateStored', fn);
|
|
1601
1668
|
|
|
1602
|
-
|
|
1669
|
+
const wrapper = function(args) {
|
|
1603
1670
|
if(!$cache) {
|
|
1604
1671
|
$cache = new TemplateCloner(fn);
|
|
1605
|
-
PluginsManager.emit('NodeTemplateCreated', $cache);
|
|
1606
1672
|
}
|
|
1607
|
-
|
|
1608
1673
|
return $cache.clone(args);
|
|
1609
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
|
+
};
|
|
1610
1684
|
}
|
|
1611
1685
|
|
|
1612
1686
|
Function.prototype.args = function(...args) {
|
|
@@ -1666,6 +1740,118 @@ var NativeDocument = (function (exports) {
|
|
|
1666
1740
|
});
|
|
1667
1741
|
};
|
|
1668
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
|
+
|
|
1669
1855
|
const cssPropertyAccumulator = function(initialValue = {}) {
|
|
1670
1856
|
let data = Validator.isString(initialValue) ? initialValue.split(';').filter(Boolean) : initialValue;
|
|
1671
1857
|
const isArray = Validator.isArray(data);
|
|
@@ -1778,9 +1964,9 @@ var NativeDocument = (function (exports) {
|
|
|
1778
1964
|
return observer.val().length;
|
|
1779
1965
|
};
|
|
1780
1966
|
|
|
1781
|
-
const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat'];
|
|
1967
|
+
const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat', 'includes', 'indexOf'];
|
|
1782
1968
|
overrideMethods.forEach((method) => {
|
|
1783
|
-
observer[method] =
|
|
1969
|
+
observer[method] = (...args) => {
|
|
1784
1970
|
return observer.val()[method](...args);
|
|
1785
1971
|
};
|
|
1786
1972
|
});
|
|
@@ -1810,13 +1996,13 @@ var NativeDocument = (function (exports) {
|
|
|
1810
1996
|
|
|
1811
1997
|
/**
|
|
1812
1998
|
*
|
|
1813
|
-
* @param {Object}
|
|
1999
|
+
* @param {Object} initialValue
|
|
1814
2000
|
* @returns {Proxy}
|
|
1815
2001
|
*/
|
|
1816
|
-
Observable.init = function(
|
|
2002
|
+
Observable.init = function(initialValue) {
|
|
1817
2003
|
const data = {};
|
|
1818
|
-
for(const key in
|
|
1819
|
-
const itemValue =
|
|
2004
|
+
for(const key in initialValue) {
|
|
2005
|
+
const itemValue = initialValue[key];
|
|
1820
2006
|
if(Validator.isJson(itemValue)) {
|
|
1821
2007
|
data[key] = Observable.init(itemValue);
|
|
1822
2008
|
continue;
|
|
@@ -1845,8 +2031,11 @@ var NativeDocument = (function (exports) {
|
|
|
1845
2031
|
const $clone = function() {
|
|
1846
2032
|
|
|
1847
2033
|
};
|
|
2034
|
+
const $updateWith = function(values) {
|
|
2035
|
+
Observable.update(proxy, values);
|
|
2036
|
+
};
|
|
1848
2037
|
|
|
1849
|
-
|
|
2038
|
+
const proxy = new Proxy(data, {
|
|
1850
2039
|
get(target, property) {
|
|
1851
2040
|
if(property === '__isProxy__') {
|
|
1852
2041
|
return true;
|
|
@@ -1857,6 +2046,12 @@ var NativeDocument = (function (exports) {
|
|
|
1857
2046
|
if(property === '$clone') {
|
|
1858
2047
|
return $clone;
|
|
1859
2048
|
}
|
|
2049
|
+
if(property === '$observables') {
|
|
2050
|
+
return Object.values(target);
|
|
2051
|
+
}
|
|
2052
|
+
if(property === '$updateWith') {
|
|
2053
|
+
return $updateWith;
|
|
2054
|
+
}
|
|
1860
2055
|
if(target[property] !== undefined) {
|
|
1861
2056
|
return target[property];
|
|
1862
2057
|
}
|
|
@@ -1864,10 +2059,25 @@ var NativeDocument = (function (exports) {
|
|
|
1864
2059
|
},
|
|
1865
2060
|
set(target, prop, newValue) {
|
|
1866
2061
|
if(target[prop] !== undefined) {
|
|
1867
|
-
|
|
2062
|
+
Validator.isObservable(newValue)
|
|
2063
|
+
? target[prop].set(newValue.val())
|
|
2064
|
+
: target[prop].set(newValue);
|
|
2065
|
+
return true;
|
|
1868
2066
|
}
|
|
2067
|
+
return true;
|
|
1869
2068
|
}
|
|
1870
|
-
})
|
|
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));
|
|
1871
2081
|
};
|
|
1872
2082
|
|
|
1873
2083
|
/**
|
|
@@ -1895,13 +2105,16 @@ var NativeDocument = (function (exports) {
|
|
|
1895
2105
|
|
|
1896
2106
|
|
|
1897
2107
|
Observable.update = function($target, data) {
|
|
2108
|
+
if(Validator.isProxy(data)) {
|
|
2109
|
+
data = data.$value;
|
|
2110
|
+
}
|
|
1898
2111
|
for(const key in data) {
|
|
1899
2112
|
const targetItem = $target[key];
|
|
1900
2113
|
const newValue = data[key];
|
|
1901
2114
|
|
|
1902
2115
|
if(Validator.isObservable(targetItem)) {
|
|
1903
2116
|
if(Validator.isArray(newValue)) {
|
|
1904
|
-
|
|
2117
|
+
targetItem.set([...newValue]);
|
|
1905
2118
|
continue;
|
|
1906
2119
|
}
|
|
1907
2120
|
targetItem.set(newValue);
|
|
@@ -1939,7 +2152,15 @@ var NativeDocument = (function (exports) {
|
|
|
1939
2152
|
return observable;
|
|
1940
2153
|
}
|
|
1941
2154
|
|
|
1942
|
-
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
|
+
});
|
|
1943
2164
|
|
|
1944
2165
|
return observable;
|
|
1945
2166
|
};
|
|
@@ -2021,10 +2242,11 @@ var NativeDocument = (function (exports) {
|
|
|
2021
2242
|
*
|
|
2022
2243
|
* @param {Array|Object|ObservableItem} data
|
|
2023
2244
|
* @param {Function} callback
|
|
2024
|
-
* @param {?Function} key
|
|
2245
|
+
* @param {?Function|?string} key
|
|
2246
|
+
* @param {{shouldKeepItemsInCache: boolean}?} configs
|
|
2025
2247
|
* @returns {DocumentFragment}
|
|
2026
2248
|
*/
|
|
2027
|
-
function ForEach(data, callback, key) {
|
|
2249
|
+
function ForEach(data, callback, key, { shouldKeepItemsInCache = false } = {}) {
|
|
2028
2250
|
const element = new Anchor('ForEach');
|
|
2029
2251
|
const blockEnd = element.endElement();
|
|
2030
2252
|
element.startElement();
|
|
@@ -2039,6 +2261,9 @@ var NativeDocument = (function (exports) {
|
|
|
2039
2261
|
};
|
|
2040
2262
|
|
|
2041
2263
|
const cleanCache = (parent) => {
|
|
2264
|
+
if(shouldKeepItemsInCache) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2042
2267
|
for(const [keyId, cacheItem] of cache.entries()) {
|
|
2043
2268
|
if(keyIds.has(keyId)) {
|
|
2044
2269
|
continue;
|
|
@@ -2071,6 +2296,9 @@ var NativeDocument = (function (exports) {
|
|
|
2071
2296
|
try {
|
|
2072
2297
|
const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
|
|
2073
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
|
+
}
|
|
2074
2302
|
cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
|
|
2075
2303
|
} catch (e) {
|
|
2076
2304
|
DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
|
|
@@ -2122,7 +2350,7 @@ var NativeDocument = (function (exports) {
|
|
|
2122
2350
|
keyIds.clear();
|
|
2123
2351
|
if(Array.isArray(items)) {
|
|
2124
2352
|
for(let i = 0, length = items.length; i < length; i++) {
|
|
2125
|
-
const keyId= handleContentItem(items[i], i);
|
|
2353
|
+
const keyId = handleContentItem(items[i], i);
|
|
2126
2354
|
keyIds.add(keyId);
|
|
2127
2355
|
}
|
|
2128
2356
|
} else {
|
|
@@ -2200,14 +2428,12 @@ var NativeDocument = (function (exports) {
|
|
|
2200
2428
|
if(!cacheItem) {
|
|
2201
2429
|
return;
|
|
2202
2430
|
}
|
|
2203
|
-
const child = cacheItem.child;
|
|
2204
|
-
cacheItem.indexObserver?.deref()?.cleanup();
|
|
2205
|
-
cacheItem.child = null;
|
|
2206
|
-
cacheItem.indexObserver = null;
|
|
2207
2431
|
if(removeChild) {
|
|
2432
|
+
const child = cacheItem.child;
|
|
2208
2433
|
child?.remove();
|
|
2209
2434
|
cache.delete(cacheItem.keyId);
|
|
2210
2435
|
}
|
|
2436
|
+
cacheItem.indexObserver?.deref()?.cleanup();
|
|
2211
2437
|
};
|
|
2212
2438
|
|
|
2213
2439
|
const removeCacheItemByKey = (keyId, removeChild = true) => {
|
|
@@ -2215,6 +2441,13 @@ var NativeDocument = (function (exports) {
|
|
|
2215
2441
|
};
|
|
2216
2442
|
|
|
2217
2443
|
const cleanCache = () => {
|
|
2444
|
+
if(configs.shouldKeepItemsInCache) {
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
if(!isIndexRequired) {
|
|
2448
|
+
cache.clear();
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2218
2451
|
for (const [keyId, cacheItem] of cache.entries()) {
|
|
2219
2452
|
removeCacheItem(cacheItem, false);
|
|
2220
2453
|
}
|
|
@@ -2236,6 +2469,9 @@ var NativeDocument = (function (exports) {
|
|
|
2236
2469
|
|
|
2237
2470
|
const indexObserver = isIndexRequired ? Observable(indexKey) : null;
|
|
2238
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
|
+
}
|
|
2239
2475
|
cache.set(keyId, {
|
|
2240
2476
|
keyId,
|
|
2241
2477
|
child: child,
|
|
@@ -2278,12 +2514,12 @@ var NativeDocument = (function (exports) {
|
|
|
2278
2514
|
toFragment(items, startIndexFrom = 0){
|
|
2279
2515
|
const fragment = document.createDocumentFragment();
|
|
2280
2516
|
for(let i = 0, length = items.length; i < length; i++) {
|
|
2281
|
-
fragment.
|
|
2517
|
+
fragment.appendChild(buildItem(items[i], lastNumberOfItems));
|
|
2282
2518
|
lastNumberOfItems++;
|
|
2283
2519
|
}
|
|
2284
2520
|
return fragment;
|
|
2285
2521
|
},
|
|
2286
|
-
add(items, delay =
|
|
2522
|
+
add(items, delay = 2) {
|
|
2287
2523
|
const fragment = Actions.toFragment(items);
|
|
2288
2524
|
setTimeout(() => {
|
|
2289
2525
|
element.appendElement(fragment);
|
|
@@ -2310,7 +2546,7 @@ var NativeDocument = (function (exports) {
|
|
|
2310
2546
|
},
|
|
2311
2547
|
clear,
|
|
2312
2548
|
merge(items) {
|
|
2313
|
-
Actions.add(items
|
|
2549
|
+
Actions.add(items);
|
|
2314
2550
|
},
|
|
2315
2551
|
push(items) {
|
|
2316
2552
|
let delay = 0;
|
|
@@ -2417,7 +2653,9 @@ var NativeDocument = (function (exports) {
|
|
|
2417
2653
|
updateIndexObservers(items, 0);
|
|
2418
2654
|
};
|
|
2419
2655
|
|
|
2420
|
-
|
|
2656
|
+
if(data.val().length) {
|
|
2657
|
+
buildContent(data.val(), null, {action: null});
|
|
2658
|
+
}
|
|
2421
2659
|
if(Validator.isObservable(data)) {
|
|
2422
2660
|
data.subscribe(buildContent);
|
|
2423
2661
|
}
|
|
@@ -2430,10 +2668,10 @@ var NativeDocument = (function (exports) {
|
|
|
2430
2668
|
*
|
|
2431
2669
|
* @param {ObservableItem|ObservableChecker} condition
|
|
2432
2670
|
* @param {*} child
|
|
2433
|
-
* @param {string|null} comment
|
|
2671
|
+
* @param {{comment?: string|null, shouldKeepInCache?: Boolean}} comment
|
|
2434
2672
|
* @returns {DocumentFragment}
|
|
2435
2673
|
*/
|
|
2436
|
-
const ShowIf = function(condition, child, comment = null) {
|
|
2674
|
+
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
2437
2675
|
if(!(Validator.isObservable(condition))) {
|
|
2438
2676
|
return DebugManager$1.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
|
|
2439
2677
|
}
|
|
@@ -2441,10 +2679,13 @@ var NativeDocument = (function (exports) {
|
|
|
2441
2679
|
|
|
2442
2680
|
let childElement = null;
|
|
2443
2681
|
const getChildElement = () => {
|
|
2444
|
-
if(childElement) {
|
|
2682
|
+
if(childElement && shouldKeepInCache) {
|
|
2445
2683
|
return childElement;
|
|
2446
2684
|
}
|
|
2447
2685
|
childElement = ElementCreator.getChild(child);
|
|
2686
|
+
if(Validator.isFragment(childElement)) {
|
|
2687
|
+
childElement = Array.from(childElement.children);
|
|
2688
|
+
}
|
|
2448
2689
|
return childElement;
|
|
2449
2690
|
};
|
|
2450
2691
|
|
|
@@ -2516,6 +2757,9 @@ var NativeDocument = (function (exports) {
|
|
|
2516
2757
|
return null;
|
|
2517
2758
|
}
|
|
2518
2759
|
item = ElementCreator.getChild(item);
|
|
2760
|
+
if(Validator.isFragment(item)) {
|
|
2761
|
+
item = Array.from(item.children);
|
|
2762
|
+
}
|
|
2519
2763
|
shouldKeepInCache && cache.set(key, item);
|
|
2520
2764
|
return item;
|
|
2521
2765
|
};
|