native-document 1.0.90 → 1.0.92

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.
@@ -6,7 +6,6 @@ import PluginsManager from "../../core/utils/plugins-manager";
6
6
  import Validator from "../../core/utils/validator";
7
7
  import {ObservableWhen} from "./ObservableWhen";
8
8
  import {deepClone} from "../utils/helpers";
9
- import {call} from "@babel/traverse/lib/path/context";
10
9
 
11
10
  /**
12
11
  *
@@ -19,7 +18,9 @@ export default function ObservableItem(value, configs = null) {
19
18
 
20
19
  this.$previousValue = null;
21
20
  this.$currentValue = value;
22
- this.$isCleanedUp = false;
21
+ if(process.env.NODE_ENV === 'development') {
22
+ this.$isCleanedUp = false;
23
+ }
23
24
 
24
25
  this.$firstListener = null;
25
26
  this.$listeners = null;
@@ -54,11 +55,12 @@ const noneTrigger = function() {};
54
55
 
55
56
  ObservableItem.prototype.intercept = function(callback) {
56
57
  this.$interceptor = callback;
58
+ this.set = this.$setWithInterceptor;
57
59
  return this;
58
60
  };
59
61
 
60
62
  ObservableItem.prototype.triggerFirstListener = function(operations) {
61
- this.$firstListener(this.$currentValue, this.$previousValue, operations || {});
63
+ this.$firstListener(this.$currentValue, this.$previousValue, operations);
62
64
  };
63
65
 
64
66
  ObservableItem.prototype.triggerListeners = function(operations) {
@@ -66,33 +68,12 @@ ObservableItem.prototype.triggerListeners = function(operations) {
66
68
  const $previousValue = this.$previousValue;
67
69
  const $currentValue = this.$currentValue;
68
70
 
69
- operations = operations || DEFAULT_OPERATIONS;
70
71
  for(let i = 0, length = $listeners.length; i < length; i++) {
71
72
  $listeners[i]($currentValue, $previousValue, operations);
72
73
  }
73
74
  };
74
75
 
75
- const handleWatcherCallback = function(callbacks, value) {
76
- if(typeof callbacks === "function") {
77
- callbacks(value);
78
- return;
79
- }
80
- if (callbacks.set) {
81
- callbacks.set(value);
82
- return;
83
- }
84
- for(let i = 0, length = callbacks.length; i < length; i++) {
85
- const callback = callbacks[i];
86
- callback.set ? callback.set(value) : callback(value);
87
-
88
- }
89
- };
90
-
91
- ObservableItem.prototype.triggerWatchers = function() {
92
- if(!this.$watchers) {
93
- return;
94
- }
95
-
76
+ ObservableItem.prototype.triggerWatchers = function(operations) {
96
77
  const $watchers = this.$watchers;
97
78
  const $previousValue = this.$previousValue;
98
79
  const $currentValue = this.$currentValue;
@@ -100,20 +81,20 @@ ObservableItem.prototype.triggerWatchers = function() {
100
81
  const $currentValueCallbacks = $watchers.get($currentValue);
101
82
  const $previousValueCallbacks = $watchers.get($previousValue);
102
83
  if($currentValueCallbacks) {
103
- handleWatcherCallback($currentValueCallbacks, true);
84
+ $currentValueCallbacks(true, $previousValue, operations);
104
85
  }
105
86
  if($previousValueCallbacks) {
106
- handleWatcherCallback($previousValueCallbacks, false);
87
+ $previousValueCallbacks(false, $currentValue, operations);
107
88
  }
108
89
  };
109
90
 
110
91
  ObservableItem.prototype.triggerAll = function(operations) {
111
- this.triggerWatchers();
92
+ this.triggerWatchers(operations);
112
93
  this.triggerListeners(operations);
113
94
  };
114
95
 
115
96
  ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations) {
116
- this.triggerWatchers();
97
+ this.triggerWatchers(operations);
117
98
  this.triggerFirstListener(operations);
118
99
  };
119
100
 
@@ -141,21 +122,8 @@ ObservableItem.prototype.assocTrigger = function() {
141
122
  };
142
123
  ObservableItem.prototype.trigger = noneTrigger;
143
124
 
144
- /**
145
- * @param {*} data
146
- */
147
- ObservableItem.prototype.set = function(data) {
148
- let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
149
- newValue = Validator.isObservable(newValue) ? newValue.val() : newValue;
150
-
151
- if (this.$interceptor) {
152
- const result = this.$interceptor(newValue, this.$currentValue);
153
-
154
- if (result !== undefined) {
155
- newValue = result;
156
- }
157
- }
158
-
125
+ ObservableItem.prototype.$updateWithNewValue = function(newValue) {
126
+ newValue = newValue?.__$isObservable ? newValue.val() : newValue;
159
127
  if(this.$currentValue === newValue) {
160
128
  return;
161
129
  }
@@ -171,6 +139,30 @@ ObservableItem.prototype.set = function(data) {
171
139
  }
172
140
  };
173
141
 
142
+ /**
143
+ * @param {*} data
144
+ */
145
+ ObservableItem.prototype.$setWithInterceptor = function(data) {
146
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
147
+ const result = this.$interceptor(newValue, this.$currentValue);
148
+
149
+ if (result !== undefined) {
150
+ newValue = result;
151
+ }
152
+
153
+ this.$updateWithNewValue(newValue);
154
+ }
155
+
156
+ /**
157
+ * @param {*} data
158
+ */
159
+ ObservableItem.prototype.$basicSet = function(data) {
160
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
161
+ this.$updateWithNewValue(newValue);
162
+ };
163
+
164
+ ObservableItem.prototype.set = ObservableItem.prototype.$basicSet;
165
+
174
166
  ObservableItem.prototype.val = function() {
175
167
  return this.$currentValue;
176
168
  };
@@ -206,38 +198,34 @@ ObservableItem.prototype.cleanup = function() {
206
198
  }
207
199
  MemoryManager.unregister(this.$memoryId);
208
200
  this.disconnectAll();
209
- this.$isCleanedUp = true;
201
+ if(process.env.NODE_ENV === 'development') {
202
+ this.$isCleanedUp = true;
203
+ }
210
204
  delete this.$value;
211
205
  };
212
206
 
213
207
  /**
214
208
  *
215
209
  * @param {Function} callback
216
- * @param {any} target
217
210
  * @returns {(function(): void)}
218
211
  */
219
- ObservableItem.prototype.subscribe = function(callback, target = null) {
220
- this.$listeners = this.$listeners ?? [];
221
- if (this.$isCleanedUp) {
222
- DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
223
- return () => {};
224
- }
225
- if (typeof callback !== 'function') {
226
- throw new NativeDocumentError('Callback must be a function');
212
+ ObservableItem.prototype.subscribe = function(callback) {
213
+ if(process.env.NODE_ENV === 'development') {
214
+ if (this.$isCleanedUp) {
215
+ DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
216
+ return;
217
+ }
218
+ if (typeof callback !== 'function') {
219
+ throw new NativeDocumentError('Callback must be a function');
220
+ }
227
221
  }
222
+ this.$listeners = this.$listeners ?? [];
228
223
 
229
224
  this.$listeners.push(callback);
230
225
  this.assocTrigger();
231
226
  if(process.env.NODE_ENV === 'development') {
232
- PluginsManager.emit('ObservableSubscribe', this, target);
227
+ PluginsManager.emit('ObservableSubscribe', this);
233
228
  }
234
- return () => {
235
- this.unsubscribe(callback);
236
- this.assocTrigger();
237
- if(process.env.NODE_ENV === 'development') {
238
- PluginsManager.emit('ObservableUnsubscribe', this);
239
- }
240
- };
241
229
  };
242
230
 
243
231
  ObservableItem.prototype.on = function(value, callback) {
@@ -245,40 +233,66 @@ ObservableItem.prototype.on = function(value, callback) {
245
233
 
246
234
  let watchValueList = this.$watchers.get(value);
247
235
 
236
+ if(callback.__$isObservable) {
237
+ callback = callback.set.bind(callback);
238
+ }
239
+
248
240
  if(!watchValueList) {
241
+ watchValueList = callback;
249
242
  this.$watchers.set(value, callback);
250
- } else if(!Validator.isArray(watchValueList)) {
243
+ } else if(!Validator.isArray(watchValueList.list)) {
251
244
  watchValueList = [watchValueList, callback];
252
- this.$watchers.set(value, watchValueList);
245
+ callback = (value) => {
246
+ for(let i = 0, length = watchValueList.length; i < length; i++) {
247
+ watchValueList[i](value);
248
+ }
249
+ }
250
+ callback.list = watchValueList;
251
+ this.$watchers.set(value, callback);
253
252
  } else {
254
- watchValueList.push(callback);
253
+ watchValueList.list.push(callback);
255
254
  }
256
255
 
257
256
  this.assocTrigger();
258
- return () => {
259
- const index = watchValueList.indexOf(callback);
260
- watchValueList?.splice(index, 1);
261
- if(watchValueList.size === 1) {
262
- this.$watchers.set(value, watchValueList[0]);
263
- }
264
- else if(watchValueList.size === 0) {
265
- this.$watchers?.delete(value);
266
- watchValueList = null;
267
- }
257
+ };
258
+
259
+ /**
260
+ * @param {*} value
261
+ * @param {Function} callback - if omitted, removes all watchers for this value
262
+ */
263
+ ObservableItem.prototype.off = function(value, callback) {
264
+ if(!this.$watchers) return;
265
+
266
+ const watchValueList = this.$watchers.get(value);
267
+ if(!watchValueList) return;
268
+
269
+ if(!callback || !Array.isArray(watchValueList.list)) {
270
+ this.$watchers?.delete(value);
268
271
  this.assocTrigger();
269
- };
272
+ return;
273
+ }
274
+ const index = watchValueList.indexOf(callback);
275
+ watchValueList?.splice(index, 1);
276
+ if(watchValueList.length === 1) {
277
+ this.$watchers.set(value, watchValueList[0]);
278
+ }
279
+ else if(watchValueList.length === 0) {
280
+ this.$watchers?.delete(value);
281
+ watchValueList = null;
282
+ }
283
+ this.assocTrigger();
270
284
  };
271
285
 
272
286
  ObservableItem.prototype.once = function(predicate, callback) {
273
287
  const fn = typeof predicate === 'function' ? predicate : (v) => v === predicate;
274
288
 
275
- const unsub = this.subscribe((val) => {
289
+ const handler = (val) => {
276
290
  if (fn(val)) {
277
- unsub();
291
+ this.unsubscribe(handler);
278
292
  callback(val);
279
293
  }
280
- });
281
- return unsub;
294
+ };
295
+ this.subscribe(handler);
282
296
  };
283
297
 
284
298
  /**
@@ -286,11 +300,15 @@ ObservableItem.prototype.once = function(predicate, callback) {
286
300
  * @param {Function} callback
287
301
  */
288
302
  ObservableItem.prototype.unsubscribe = function(callback) {
303
+ if(!this.$listeners) return;
289
304
  const index = this.$listeners.indexOf(callback);
290
305
  if (index > -1) {
291
306
  this.$listeners.splice(index, 1);
292
307
  }
293
308
  this.assocTrigger();
309
+ if(process.env.NODE_ENV === 'development') {
310
+ PluginsManager.emit('ObservableUnsubscribe', this);
311
+ }
294
312
  };
295
313
 
296
314
  /**
@@ -341,4 +359,8 @@ ObservableItem.prototype.reset = function() {
341
359
 
342
360
  ObservableItem.prototype.toString = function() {
343
361
  return String(this.$currentValue);
362
+ };
363
+
364
+ ObservableItem.prototype.valueOf = function() {
365
+ return this.$currentValue;
344
366
  };
@@ -226,7 +226,7 @@ export function ForEachArray(data, callback, configs = {}) {
226
226
  };
227
227
 
228
228
  const buildContent = (items, _, operations) => {
229
- if(operations.action === 'clear' || !items.length) {
229
+ if(operations?.action === 'clear' || !items.length) {
230
230
  if(lastNumberOfItems === 0) {
231
231
  return;
232
232
  }
@@ -9,9 +9,7 @@ import {Observable} from "../data/Observable";
9
9
  * @param {Object} data
10
10
  */
11
11
  export function bindClassAttribute(element, data) {
12
- const classNames = Object.keys(data);
13
- for(let i = 0, length = classNames.length; i < length; i++) {
14
- const className = classNames[i];
12
+ for(const className in data) {
15
13
  const value = data[className];
16
14
  if(value.__$isObservable) {
17
15
  element.classes.toggle(className, value.val());
@@ -38,9 +36,7 @@ export function bindClassAttribute(element, data) {
38
36
  * @param {Object} data
39
37
  */
40
38
  export function bindStyleAttribute(element, data) {
41
- const keys = Object.keys(data);
42
- for(let i = 0, length = keys.length; i < length; i++) {
43
- const styleName = keys[i];
39
+ for(const styleName in data) {
44
40
  const value = data[styleName];
45
41
  if(value.__$isObservable) {
46
42
  element.style[styleName] = value.val();
@@ -108,10 +104,8 @@ export function bindAttributeWithObservable(element, attributeName, value) {
108
104
  export default function AttributesWrapper(element, attributes) {
109
105
 
110
106
  Validator.validateAttributes(attributes);
111
- const attributesKeys = Object.keys(attributes);
112
107
 
113
- for(let i = 0, length = attributesKeys.length; i < length; i++) {
114
- const originalAttributeName = attributesKeys[i];
108
+ for(const originalAttributeName in attributes) {
115
109
  const attributeName = originalAttributeName.toLowerCase();
116
110
  let value = attributes[originalAttributeName];
117
111
  if(value == null) {