neo.mjs 5.14.0 → 5.14.1
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/apps/ServiceWorker.mjs +2 -2
- package/examples/ServiceWorker.mjs +2 -2
- package/package.json +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/button/Base.mjs +6 -1
- package/src/controller/Application.mjs +1 -8
- package/src/model/Component.mjs +160 -86
- package/src/util/Logger.mjs +10 -5
- package/src/worker/App.mjs +97 -0
package/apps/ServiceWorker.mjs
CHANGED
package/package.json
CHANGED
package/src/DefaultConfig.mjs
CHANGED
@@ -245,12 +245,12 @@ const DefaultConfig = {
|
|
245
245
|
useVdomWorker: true,
|
246
246
|
/**
|
247
247
|
* buildScripts/injectPackageVersion.mjs will update this value
|
248
|
-
* @default '5.14.
|
248
|
+
* @default '5.14.1'
|
249
249
|
* @memberOf! module:Neo
|
250
250
|
* @name config.version
|
251
251
|
* @type String
|
252
252
|
*/
|
253
|
-
version: '5.14.
|
253
|
+
version: '5.14.1'
|
254
254
|
};
|
255
255
|
|
256
256
|
Object.assign(DefaultConfig, {
|
package/src/button/Base.mjs
CHANGED
@@ -82,6 +82,10 @@ class Base extends Component {
|
|
82
82
|
* @member {Object[]|null} menu_=null
|
83
83
|
*/
|
84
84
|
menu_: null,
|
85
|
+
/**
|
86
|
+
* @member {Object} menuListConfig=null
|
87
|
+
*/
|
88
|
+
menuListConfig: null,
|
85
89
|
/**
|
86
90
|
* The pressed state of the Button
|
87
91
|
* @member {Boolean} pressed_=false
|
@@ -258,7 +262,8 @@ class Base extends Component {
|
|
258
262
|
hidden : true,
|
259
263
|
items : value,
|
260
264
|
parentComponent: me,
|
261
|
-
style : {left: '-5000px', top: '-5000px'}
|
265
|
+
style : {left: '-5000px', top: '-5000px'},
|
266
|
+
...me.menuListConfig
|
262
267
|
})
|
263
268
|
})
|
264
269
|
}
|
@@ -90,7 +90,7 @@ class Application extends Base {
|
|
90
90
|
// short delay to ensure changes from onHashChange() got applied
|
91
91
|
await Neo.timeout(Neo.config.hash ? 200 : 10);
|
92
92
|
|
93
|
-
|
93
|
+
Logger.addContextMenuListener(me.mainView);
|
94
94
|
|
95
95
|
value.render(true)
|
96
96
|
}
|
@@ -122,13 +122,6 @@ class Application extends Base {
|
|
122
122
|
Neo.currentWorker.removeAppFromThemeMap(this.name);
|
123
123
|
super.destroy(...args)
|
124
124
|
}
|
125
|
-
|
126
|
-
/**
|
127
|
-
* @protected
|
128
|
-
*/
|
129
|
-
registerLoggerClickEvent() {
|
130
|
-
Logger.addContextMenuListener(this.mainView)
|
131
|
-
}
|
132
125
|
}
|
133
126
|
|
134
127
|
Neo.applyClassConfig(Application);
|
package/src/model/Component.mjs
CHANGED
@@ -44,6 +44,27 @@ class Component extends Base {
|
|
44
44
|
* @member {Object|null} data_=null
|
45
45
|
*/
|
46
46
|
data_: null,
|
47
|
+
/**
|
48
|
+
* @member {Object|null} formulas_=null
|
49
|
+
*
|
50
|
+
* @example
|
51
|
+
* data: {
|
52
|
+
* a: 1,
|
53
|
+
* b: 2
|
54
|
+
* }
|
55
|
+
* formulas: {
|
56
|
+
* aPlusB: {
|
57
|
+
* bind: {
|
58
|
+
* foo: 'a',
|
59
|
+
* bar: 'b'
|
60
|
+
* },
|
61
|
+
* get(data) {
|
62
|
+
* return data.foo + data.bar
|
63
|
+
* }
|
64
|
+
* }
|
65
|
+
* }
|
66
|
+
*/
|
67
|
+
formulas_: null,
|
47
68
|
/**
|
48
69
|
* @member {Neo.model.Component|null} parent_=null
|
49
70
|
*/
|
@@ -60,7 +81,7 @@ class Component extends Base {
|
|
60
81
|
construct(config) {
|
61
82
|
Neo.currentWorker.isUsingViewModels = true;
|
62
83
|
super.construct(config);
|
63
|
-
this.bindings = {}
|
84
|
+
this.bindings = {}
|
64
85
|
}
|
65
86
|
|
66
87
|
/**
|
@@ -77,12 +98,12 @@ class Component extends Base {
|
|
77
98
|
|
78
99
|
Neo.ns(key, true, me.data);
|
79
100
|
|
80
|
-
data
|
101
|
+
data = me.getDataScope(key);
|
81
102
|
scope = data.scope;
|
82
103
|
|
83
104
|
scope[data.key] = value;
|
84
105
|
|
85
|
-
me.createDataProperties(me.data, 'data')
|
106
|
+
me.createDataProperties(me.data, 'data')
|
86
107
|
}
|
87
108
|
|
88
109
|
/**
|
@@ -92,7 +113,17 @@ class Component extends Base {
|
|
92
113
|
* @protected
|
93
114
|
*/
|
94
115
|
afterSetData(value, oldValue) {
|
95
|
-
value && this.createDataProperties(value, 'data')
|
116
|
+
value && this.createDataProperties(value, 'data')
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Triggered after the formulas config got changed
|
121
|
+
* @param {Object|null} value
|
122
|
+
* @param {Object|null} oldValue
|
123
|
+
* @protected
|
124
|
+
*/
|
125
|
+
afterSetFormulas(value, oldValue) {
|
126
|
+
value && this.resolveFormulas(null)
|
96
127
|
}
|
97
128
|
|
98
129
|
/**
|
@@ -101,7 +132,7 @@ class Component extends Base {
|
|
101
132
|
* @protected
|
102
133
|
*/
|
103
134
|
beforeGetData(value) {
|
104
|
-
return value || {}
|
135
|
+
return value || {}
|
105
136
|
}
|
106
137
|
|
107
138
|
/**
|
@@ -111,7 +142,7 @@ class Component extends Base {
|
|
111
142
|
* @protected
|
112
143
|
*/
|
113
144
|
beforeSetParent(value, oldValue) {
|
114
|
-
return value ? value : this.getParent()
|
145
|
+
return value ? value : this.getParent()
|
115
146
|
}
|
116
147
|
|
117
148
|
/**
|
@@ -126,23 +157,23 @@ class Component extends Base {
|
|
126
157
|
|
127
158
|
value && Object.entries(value).forEach(([key, storeValue]) => {
|
128
159
|
controller?.parseConfig(storeValue);
|
129
|
-
value[key] = ClassSystemUtil.beforeSetInstance(storeValue)
|
160
|
+
value[key] = ClassSystemUtil.beforeSetInstance(storeValue)
|
130
161
|
});
|
131
162
|
|
132
|
-
return value
|
163
|
+
return value
|
133
164
|
}
|
134
165
|
|
135
166
|
/**
|
136
167
|
* @param {Function} formatter
|
137
|
-
* @param {Object}
|
168
|
+
* @param {Object} data=null optionally pass this.getHierarchyData() for performance reasons
|
138
169
|
* @returns {String}
|
139
170
|
*/
|
140
171
|
callFormatter(formatter, data=null) {
|
141
172
|
if (!data) {
|
142
|
-
data = this.getHierarchyData()
|
173
|
+
data = this.getHierarchyData()
|
143
174
|
}
|
144
175
|
|
145
|
-
return formatter.call(this, data)
|
176
|
+
return formatter.call(this, data)
|
146
177
|
}
|
147
178
|
|
148
179
|
/**
|
@@ -162,21 +193,21 @@ class Component extends Base {
|
|
162
193
|
|
163
194
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
164
195
|
bindingScope = Neo.ns(`${key}.${componentId}`, true, me.bindings);
|
165
|
-
bindingScope[value] = formatter
|
196
|
+
bindingScope[value] = formatter
|
166
197
|
} else {
|
167
198
|
parentModel = me.getParent();
|
168
199
|
|
169
200
|
if (parentModel) {
|
170
|
-
parentModel.createBinding(componentId, key, value, formatter)
|
201
|
+
parentModel.createBinding(componentId, key, value, formatter)
|
171
202
|
} else {
|
172
|
-
console.error('No model.Component found with the specified data property', componentId, keyLeaf, value)
|
203
|
+
console.error('No model.Component found with the specified data property', componentId, keyLeaf, value)
|
173
204
|
}
|
174
205
|
}
|
175
206
|
}
|
176
207
|
|
177
208
|
/**
|
178
209
|
* Registers a new binding in case a matching data property does exist.
|
179
|
-
* Otherwise it will use the closest model with a match.
|
210
|
+
* Otherwise, it will use the closest model with a match.
|
180
211
|
* @param {String} componentId
|
181
212
|
* @param {String} formatter
|
182
213
|
* @param {String} value
|
@@ -186,8 +217,8 @@ class Component extends Base {
|
|
186
217
|
formatterVars = me.getFormatterVariables(formatter);
|
187
218
|
|
188
219
|
formatterVars.forEach(key => {
|
189
|
-
me.createBinding(componentId, key, value, formatter)
|
190
|
-
})
|
220
|
+
me.createBinding(componentId, key, value, formatter)
|
221
|
+
})
|
191
222
|
}
|
192
223
|
|
193
224
|
/**
|
@@ -196,13 +227,13 @@ class Component extends Base {
|
|
196
227
|
createBindings(component) {
|
197
228
|
Object.entries(component.bind).forEach(([key, value]) => {
|
198
229
|
if (Neo.isObject(value)) {
|
199
|
-
value = value.value
|
230
|
+
value = value.value
|
200
231
|
}
|
201
232
|
|
202
233
|
if (!this.isStoreValue(value)) {
|
203
|
-
this.createBindingByFormatter(component.id, value, key)
|
234
|
+
this.createBindingByFormatter(component.id, value, key)
|
204
235
|
}
|
205
|
-
})
|
236
|
+
})
|
206
237
|
}
|
207
238
|
|
208
239
|
/**
|
@@ -222,31 +253,31 @@ class Component extends Base {
|
|
222
253
|
if (!(typeof descriptor === 'object' && typeof descriptor.set === 'function')) {
|
223
254
|
keyValue = config[key];
|
224
255
|
me.createDataProperty(key, newPath, root);
|
225
|
-
root[key] = keyValue
|
256
|
+
root[key] = keyValue
|
226
257
|
}
|
227
258
|
|
228
259
|
if (Neo.isObject(value)) {
|
229
|
-
me.createDataProperties(config[key], newPath)
|
260
|
+
me.createDataProperties(config[key], newPath)
|
230
261
|
}
|
231
262
|
}
|
232
|
-
})
|
263
|
+
})
|
233
264
|
}
|
234
265
|
|
235
266
|
/**
|
236
267
|
* @param {String} key
|
237
268
|
* @param {String} path
|
238
|
-
* @param {Object}
|
269
|
+
* @param {Object} root=this.data
|
239
270
|
*/
|
240
271
|
createDataProperty(key, path, root=this.data) {
|
241
272
|
let me = this;
|
242
273
|
|
243
274
|
if (path?.startsWith('data.')) {
|
244
|
-
path = path.substring(5)
|
275
|
+
path = path.substring(5)
|
245
276
|
}
|
246
277
|
|
247
278
|
Object.defineProperty(root, key, {
|
248
279
|
get() {
|
249
|
-
return root['_' + key]
|
280
|
+
return root['_' + key]
|
250
281
|
},
|
251
282
|
|
252
283
|
set(value) {
|
@@ -258,16 +289,16 @@ class Component extends Base {
|
|
258
289
|
enumerable: false,
|
259
290
|
value,
|
260
291
|
writable : true
|
261
|
-
})
|
292
|
+
})
|
262
293
|
} else {
|
263
|
-
root[_key] = value
|
294
|
+
root[_key] = value
|
264
295
|
}
|
265
296
|
|
266
297
|
if (!Neo.isEqual(value, oldValue)) {
|
267
|
-
me.onDataPropertyChange(path ? path : key, value, oldValue)
|
298
|
+
me.onDataPropertyChange(path ? path : key, value, oldValue)
|
268
299
|
}
|
269
300
|
}
|
270
|
-
})
|
301
|
+
})
|
271
302
|
}
|
272
303
|
|
273
304
|
/**
|
@@ -276,13 +307,13 @@ class Component extends Base {
|
|
276
307
|
* @returns {Neo.controller.Component|null}
|
277
308
|
*/
|
278
309
|
getController(ntype) {
|
279
|
-
return this.component.getController(ntype)
|
310
|
+
return this.component.getController(ntype)
|
280
311
|
}
|
281
312
|
|
282
313
|
/**
|
283
314
|
* Access the closest data property inside the VM parent chain.
|
284
315
|
* @param {String} key
|
285
|
-
* @param {Neo.model.Component}
|
316
|
+
* @param {Neo.model.Component} originModel=this for internal usage only
|
286
317
|
* @returns {*} value
|
287
318
|
*/
|
288
319
|
getData(key, originModel=this) {
|
@@ -293,16 +324,16 @@ class Component extends Base {
|
|
293
324
|
parentModel;
|
294
325
|
|
295
326
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
296
|
-
return scope[keyLeaf]
|
327
|
+
return scope[keyLeaf]
|
297
328
|
}
|
298
329
|
|
299
330
|
parentModel = me.getParent();
|
300
331
|
|
301
332
|
if (!parentModel) {
|
302
|
-
console.error(`data property '${key}' does not exist.`, originModel)
|
333
|
+
console.error(`data property '${key}' does not exist.`, originModel)
|
303
334
|
}
|
304
335
|
|
305
|
-
return parentModel.getData(key, originModel)
|
336
|
+
return parentModel.getData(key, originModel)
|
306
337
|
}
|
307
338
|
|
308
339
|
/**
|
@@ -321,13 +352,13 @@ class Component extends Base {
|
|
321
352
|
if (key.includes('.')) {
|
322
353
|
key = key.split('.');
|
323
354
|
keyLeaf = key.pop();
|
324
|
-
data = Neo.ns(key.join('.'), false, data)
|
355
|
+
data = Neo.ns(key.join('.'), false, data)
|
325
356
|
}
|
326
357
|
|
327
358
|
return {
|
328
359
|
key : keyLeaf,
|
329
360
|
scope: data
|
330
|
-
}
|
361
|
+
}
|
331
362
|
}
|
332
363
|
|
333
364
|
/**
|
@@ -336,7 +367,7 @@ class Component extends Base {
|
|
336
367
|
*/
|
337
368
|
getFormatterVariables(value) {
|
338
369
|
if (Neo.isFunction(value)) {
|
339
|
-
value = value.toString()
|
370
|
+
value = value.toString()
|
340
371
|
}
|
341
372
|
|
342
373
|
if (Neo.config.environment === 'dist/production') {
|
@@ -353,7 +384,7 @@ class Component extends Base {
|
|
353
384
|
let dataName = value.match(variableNameRegex)[0],
|
354
385
|
variableRegExp = new RegExp(`(^|[^\\w.])(${dataName})(?!\\w)`, 'g');
|
355
386
|
|
356
|
-
value = value.replace(variableRegExp, '$1data')
|
387
|
+
value = value.replace(variableRegExp, '$1data')
|
357
388
|
}
|
358
389
|
|
359
390
|
let dataVars = value.match(dataVariableRegex) || [],
|
@@ -362,12 +393,12 @@ class Component extends Base {
|
|
362
393
|
dataVars.forEach(variable => {
|
363
394
|
// remove the "data." at the start
|
364
395
|
variable = variable.substr(5);
|
365
|
-
NeoArray.add(result, variable)
|
396
|
+
NeoArray.add(result, variable)
|
366
397
|
});
|
367
398
|
|
368
399
|
result.sort();
|
369
400
|
|
370
|
-
return result
|
401
|
+
return result
|
371
402
|
}
|
372
403
|
|
373
404
|
/**
|
@@ -383,16 +414,16 @@ class Component extends Base {
|
|
383
414
|
return {
|
384
415
|
...parent.getHierarchyData(data),
|
385
416
|
...me.getPlainData()
|
386
|
-
}
|
417
|
+
}
|
387
418
|
}
|
388
419
|
|
389
|
-
return me.getPlainData()
|
420
|
+
return me.getPlainData()
|
390
421
|
}
|
391
422
|
|
392
423
|
/**
|
393
424
|
* Returns a plain version of this.data.
|
394
425
|
* This excludes the property getters & setters.
|
395
|
-
* @param {Object}
|
426
|
+
* @param {Object} data=this.data
|
396
427
|
* @returns {Object}
|
397
428
|
*/
|
398
429
|
getPlainData(data=this.data) {
|
@@ -400,13 +431,13 @@ class Component extends Base {
|
|
400
431
|
|
401
432
|
Object.entries(data).forEach(([key, value]) => {
|
402
433
|
if (Neo.typeOf(value) === 'Object') {
|
403
|
-
plainData[key] = this.getPlainData(value)
|
434
|
+
plainData[key] = this.getPlainData(value)
|
404
435
|
} else {
|
405
|
-
plainData[key] = value
|
436
|
+
plainData[key] = value
|
406
437
|
}
|
407
438
|
});
|
408
439
|
|
409
|
-
return plainData
|
440
|
+
return plainData
|
410
441
|
}
|
411
442
|
|
412
443
|
/**
|
@@ -418,19 +449,19 @@ class Component extends Base {
|
|
418
449
|
parentComponent, parentId;
|
419
450
|
|
420
451
|
if (me.parent) {
|
421
|
-
return me.parent
|
452
|
+
return me.parent
|
422
453
|
}
|
423
454
|
|
424
|
-
parentId
|
455
|
+
parentId = me.component.parentId;
|
425
456
|
parentComponent = parentId && Neo.getComponent(parentId);
|
426
457
|
|
427
|
-
return parentComponent?.getModel() || null
|
458
|
+
return parentComponent?.getModel() || null
|
428
459
|
}
|
429
460
|
|
430
461
|
/**
|
431
462
|
* Access the closest store inside the VM parent chain.
|
432
463
|
* @param {String} key
|
433
|
-
* @param {Neo.model.Component}
|
464
|
+
* @param {Neo.model.Component} originModel=this for internal usage only
|
434
465
|
* @returns {*} value
|
435
466
|
*/
|
436
467
|
getStore(key, originModel=this) {
|
@@ -439,16 +470,16 @@ class Component extends Base {
|
|
439
470
|
parentModel;
|
440
471
|
|
441
472
|
if (stores?.hasOwnProperty(key)) {
|
442
|
-
return stores[key]
|
473
|
+
return stores[key]
|
443
474
|
}
|
444
475
|
|
445
476
|
parentModel = me.getParent();
|
446
477
|
|
447
478
|
if (!parentModel) {
|
448
|
-
console.error(`store '${key}' not found inside this model or parents.`, originModel)
|
479
|
+
console.error(`store '${key}' not found inside this model or parents.`, originModel)
|
449
480
|
}
|
450
481
|
|
451
|
-
return parentModel.getStore(key, originModel)
|
482
|
+
return parentModel.getStore(key, originModel)
|
452
483
|
}
|
453
484
|
|
454
485
|
/**
|
@@ -469,26 +500,26 @@ class Component extends Base {
|
|
469
500
|
|
470
501
|
if (Neo.isObject(key)) {
|
471
502
|
Object.entries(key).forEach(([dataKey, dataValue]) => {
|
472
|
-
me.internalSetData(dataKey, dataValue, originModel)
|
473
|
-
})
|
503
|
+
me.internalSetData(dataKey, dataValue, originModel)
|
504
|
+
})
|
474
505
|
} else {
|
475
506
|
data = me.getDataScope(key);
|
476
|
-
scope = data.scope;
|
477
507
|
keyLeaf = data.key;
|
508
|
+
scope = data.scope;
|
478
509
|
|
479
510
|
if (scope?.hasOwnProperty(keyLeaf)) {
|
480
|
-
scope[keyLeaf] = value
|
511
|
+
scope[keyLeaf] = value
|
481
512
|
} else {
|
482
513
|
if (originModel) {
|
483
514
|
parentModel = me.getParent();
|
484
515
|
|
485
516
|
if (parentModel) {
|
486
|
-
parentModel.internalSetData(key, value, originModel)
|
517
|
+
parentModel.internalSetData(key, value, originModel)
|
487
518
|
} else {
|
488
|
-
originModel.addDataProperty(key, value)
|
519
|
+
originModel.addDataProperty(key, value)
|
489
520
|
}
|
490
521
|
} else {
|
491
|
-
me.addDataProperty(key, value)
|
522
|
+
me.addDataProperty(key, value)
|
492
523
|
}
|
493
524
|
}
|
494
525
|
}
|
@@ -500,7 +531,7 @@ class Component extends Base {
|
|
500
531
|
* @returns {Boolean}
|
501
532
|
*/
|
502
533
|
isStoreValue(value) {
|
503
|
-
return Neo.isString(value) && value.startsWith('stores.')
|
534
|
+
return Neo.isString(value) && value.startsWith('stores.')
|
504
535
|
}
|
505
536
|
|
506
537
|
/**
|
@@ -511,10 +542,10 @@ class Component extends Base {
|
|
511
542
|
*/
|
512
543
|
mergeConfig(config, preventOriginalConfig) {
|
513
544
|
if (config.data) {
|
514
|
-
config.data = Neo.merge(Neo.clone(this.constructor.config.data, true) || {}, config.data)
|
545
|
+
config.data = Neo.merge(Neo.clone(this.constructor.config.data, true) || {}, config.data)
|
515
546
|
}
|
516
547
|
|
517
|
-
return super.mergeConfig(config, preventOriginalConfig)
|
548
|
+
return super.mergeConfig(config, preventOriginalConfig)
|
518
549
|
}
|
519
550
|
|
520
551
|
/**
|
@@ -532,35 +563,32 @@ class Component extends Base {
|
|
532
563
|
|
533
564
|
Object.entries(binding).forEach(([componentId, configObject]) => {
|
534
565
|
component = Neo.getComponent(componentId) || Neo.get(componentId); // timing issue: the cmp might not be registered inside manager.Component yet
|
535
|
-
config
|
536
|
-
model
|
566
|
+
config = {};
|
567
|
+
model = component.getModel();
|
537
568
|
|
538
569
|
if (!hierarchyData[model.id]) {
|
539
|
-
hierarchyData[model.id] = model.getHierarchyData()
|
570
|
+
hierarchyData[model.id] = model.getHierarchyData()
|
540
571
|
}
|
541
572
|
|
542
573
|
Object.entries(configObject).forEach(([configField, formatter]) => {
|
543
574
|
// we can not call me.callFormatter(), since a data property inside a parent model
|
544
575
|
// could have changed which is relying on data properties inside a closer model
|
545
|
-
config[configField] = model.callFormatter(formatter, hierarchyData[model.id])
|
576
|
+
config[configField] = model.callFormatter(formatter, hierarchyData[model.id])
|
546
577
|
});
|
547
578
|
|
548
|
-
component?.set(config)
|
549
|
-
})
|
579
|
+
component?.set(config)
|
580
|
+
})
|
550
581
|
}
|
551
582
|
|
552
|
-
me.
|
553
|
-
|
554
|
-
|
555
|
-
oldValue,
|
556
|
-
value
|
557
|
-
});
|
583
|
+
me.resolveFormulas({key, id: me.id, oldValue, value});
|
584
|
+
|
585
|
+
me.fire('dataPropertyChange', {key, id: me.id, oldValue, value})
|
558
586
|
}
|
559
587
|
|
560
588
|
/**
|
561
589
|
* This method will assign binding values at the earliest possible point inside the component lifecycle.
|
562
590
|
* It can not store bindings though, since child component ids most likely do not exist yet.
|
563
|
-
* @param {Neo.component.Base}
|
591
|
+
* @param {Neo.component.Base} component=this.component
|
564
592
|
*/
|
565
593
|
parseConfig(component=this.component) {
|
566
594
|
let me = this,
|
@@ -572,17 +600,17 @@ class Component extends Base {
|
|
572
600
|
Object.entries(component.bind).forEach(([key, value]) => {
|
573
601
|
if (Neo.isObject(value)) {
|
574
602
|
value.key = me.getFormatterVariables(value.value)[0];
|
575
|
-
value = value.value
|
603
|
+
value = value.value
|
576
604
|
}
|
577
605
|
|
578
606
|
if (me.isStoreValue(value)) {
|
579
|
-
me.resolveStore(component, key, value.substring(7))
|
607
|
+
me.resolveStore(component, key, value.substring(7)) // remove the "stores." at the start
|
580
608
|
} else {
|
581
|
-
config[key] = me.callFormatter(value)
|
609
|
+
config[key] = me.callFormatter(value)
|
582
610
|
}
|
583
611
|
});
|
584
612
|
|
585
|
-
component.set(config)
|
613
|
+
component.set(config)
|
586
614
|
}
|
587
615
|
}
|
588
616
|
|
@@ -596,10 +624,56 @@ class Component extends Base {
|
|
596
624
|
parentModel = me.getParent();
|
597
625
|
|
598
626
|
Object.entries(me.bindings).forEach(([dataProperty, binding]) => {
|
599
|
-
delete binding[componentId]
|
627
|
+
delete binding[componentId]
|
600
628
|
});
|
601
629
|
|
602
|
-
parentModel?.removeBindings(componentId)
|
630
|
+
parentModel?.removeBindings(componentId)
|
631
|
+
}
|
632
|
+
|
633
|
+
/**
|
634
|
+
* Resolve the formulas initially and update, when data change
|
635
|
+
* @param {Object} data data from event or null on initial call
|
636
|
+
*/
|
637
|
+
resolveFormulas(data) {
|
638
|
+
let me = this,
|
639
|
+
formulas = me.formulas,
|
640
|
+
initialRun = !data,
|
641
|
+
affectFormula, bindObject, fn, key, result, value;
|
642
|
+
|
643
|
+
if (formulas) {
|
644
|
+
if (!initialRun && (!data.key || !data.value)) {
|
645
|
+
console.warn('[ViewModel:formulas] missing key or value', data.key, data.value)
|
646
|
+
}
|
647
|
+
|
648
|
+
for ([key, value] of Object.entries(formulas)) {
|
649
|
+
affectFormula = true;
|
650
|
+
|
651
|
+
// Check if the change affects a formula
|
652
|
+
if (!initialRun) {
|
653
|
+
affectFormula = Object.values(value.bind).includes(data.key)
|
654
|
+
}
|
655
|
+
|
656
|
+
if (affectFormula) {
|
657
|
+
// Create Bind-Object and fill with new values
|
658
|
+
bindObject = Neo.clone(value.bind);
|
659
|
+
fn = value.get;
|
660
|
+
|
661
|
+
Object.keys(bindObject).forEach((key, index) => {
|
662
|
+
bindObject[key] = me.getData(bindObject[key])
|
663
|
+
});
|
664
|
+
|
665
|
+
// Calc the formula
|
666
|
+
result = fn(bindObject);
|
667
|
+
|
668
|
+
// Assign if no error or null
|
669
|
+
if (isNaN(result)) {
|
670
|
+
me.setData(key, null)
|
671
|
+
} else {
|
672
|
+
me.setData(key, result)
|
673
|
+
}
|
674
|
+
}
|
675
|
+
}
|
676
|
+
}
|
603
677
|
}
|
604
678
|
|
605
679
|
/**
|
@@ -608,7 +682,7 @@ class Component extends Base {
|
|
608
682
|
* @param {String} storeName
|
609
683
|
*/
|
610
684
|
resolveStore(component, configName, storeName) {
|
611
|
-
component[configName] = this.getStore(storeName)
|
685
|
+
component[configName] = this.getStore(storeName)
|
612
686
|
}
|
613
687
|
|
614
688
|
/**
|
@@ -618,7 +692,7 @@ class Component extends Base {
|
|
618
692
|
* @param {*} value
|
619
693
|
*/
|
620
694
|
setData(key, value) {
|
621
|
-
this.internalSetData(key, value, this)
|
695
|
+
this.internalSetData(key, value, this)
|
622
696
|
}
|
623
697
|
|
624
698
|
/**
|
@@ -628,7 +702,7 @@ class Component extends Base {
|
|
628
702
|
* @param {*} value
|
629
703
|
*/
|
630
704
|
setDataAtSameLevel(key, value) {
|
631
|
-
this.internalSetData(key, value)
|
705
|
+
this.internalSetData(key, value)
|
632
706
|
}
|
633
707
|
}
|
634
708
|
|
package/src/util/Logger.mjs
CHANGED
@@ -18,7 +18,7 @@ class Logger extends Base {
|
|
18
18
|
*
|
19
19
|
* Neo.util.Logger.enableLogsInProduction = true;
|
20
20
|
*
|
21
|
-
* @member {
|
21
|
+
* @member {Boolean} enableLogsInProduction=true
|
22
22
|
*/
|
23
23
|
enableLogsInProduction: false,
|
24
24
|
/**
|
@@ -27,9 +27,9 @@ class Logger extends Base {
|
|
27
27
|
*
|
28
28
|
* Neo.util.Logger.enableComponentLogger = true;
|
29
29
|
*
|
30
|
-
* @member {
|
30
|
+
* @member {Boolean} enableComponentLogger=true
|
31
31
|
*/
|
32
|
-
|
32
|
+
enableComponentLogger: true,
|
33
33
|
/**
|
34
34
|
* Set the minimum level, which you want to output.
|
35
35
|
* Change this at any time using a value of logLevels: ['info', 'log', 'warn', 'error']
|
@@ -101,7 +101,8 @@ class Logger extends Base {
|
|
101
101
|
*/
|
102
102
|
addContextMenuListener(view) {
|
103
103
|
view.addDomListeners({
|
104
|
-
contextmenu: this.onContextMenu
|
104
|
+
contextmenu: this.onContextMenu,
|
105
|
+
scope : this
|
105
106
|
})
|
106
107
|
}
|
107
108
|
|
@@ -184,7 +185,11 @@ class Logger extends Base {
|
|
184
185
|
* @param {Object} data
|
185
186
|
*/
|
186
187
|
onContextMenu(data) {
|
187
|
-
if (
|
188
|
+
if (
|
189
|
+
data.ctrlKey
|
190
|
+
&& this.enableComponentLogger
|
191
|
+
&& !(Neo.config.env === 'dist/production' && this.enableLogsInProduction)
|
192
|
+
) {
|
188
193
|
let isGroupSet = false,
|
189
194
|
component;
|
190
195
|
|
package/src/worker/App.mjs
CHANGED
@@ -20,6 +20,17 @@ class App extends Base {
|
|
20
20
|
* @protected
|
21
21
|
*/
|
22
22
|
className: 'Neo.worker.App',
|
23
|
+
/**
|
24
|
+
* Remote method access for other workers
|
25
|
+
* @member {Object} remote
|
26
|
+
* @protected
|
27
|
+
*/
|
28
|
+
remote: {
|
29
|
+
main: [
|
30
|
+
'createNeoInstance',
|
31
|
+
'destroyNeoInstance'
|
32
|
+
]
|
33
|
+
},
|
23
34
|
/**
|
24
35
|
* @member {Boolean} singleton=true
|
25
36
|
* @protected
|
@@ -72,6 +83,62 @@ class App extends Base {
|
|
72
83
|
return this.promiseMessage('main', {action: 'updateDom', appName, deltas})
|
73
84
|
}
|
74
85
|
|
86
|
+
/**
|
87
|
+
* Remote method to use inside main threads for creating neo based class instances.
|
88
|
+
* Be aware that you can only pass configs which can get converted into pure JSON.
|
89
|
+
*
|
90
|
+
* Rendering a component into the document.body
|
91
|
+
* @example:
|
92
|
+
* Neo.worker.App.createNeoInstance({
|
93
|
+
* ntype : 'button',
|
94
|
+
* autoMount : true,
|
95
|
+
* autoRender: true
|
96
|
+
* text : 'Hi Nige!'
|
97
|
+
* }).then(id => console.log(id))
|
98
|
+
*
|
99
|
+
* Inserting a component into a container
|
100
|
+
* @example:
|
101
|
+
* Neo.worker.App.createNeoInstance({
|
102
|
+
* ntype : 'button',
|
103
|
+
* parentId : 'neo-container-3',
|
104
|
+
* parentIndex: 0
|
105
|
+
* text : 'Hi Nige!'
|
106
|
+
* }).then(id => console.log(id))
|
107
|
+
*
|
108
|
+
* @param {Object} config
|
109
|
+
* @param {String} [config.parentId] passing a parentId will put your instance into a container
|
110
|
+
* @param {Number} [config.parentIndex] if a parentId is passed, but no index, neo will use add()
|
111
|
+
* @returns {String} the instance id
|
112
|
+
*/
|
113
|
+
createNeoInstance(config) {
|
114
|
+
let appName = Object.keys(Neo.apps)[0], // fallback in case no appName was provided
|
115
|
+
Container = Neo.container?.Base,
|
116
|
+
index, instance, parent;
|
117
|
+
|
118
|
+
config = {appName: appName, ...config};
|
119
|
+
|
120
|
+
if (config.parentId) {
|
121
|
+
parent = Neo.getComponent(config.parentId);
|
122
|
+
|
123
|
+
if (Container && parent && parent instanceof Container) {
|
124
|
+
index = config.parentIndex;
|
125
|
+
|
126
|
+
delete config.parentId;
|
127
|
+
delete config.parentIndex;
|
128
|
+
|
129
|
+
if (Neo.isNumber(index)) {
|
130
|
+
instance = parent.insert(index, config)
|
131
|
+
} else {
|
132
|
+
instance = parent.add(config)
|
133
|
+
}
|
134
|
+
}
|
135
|
+
} else {
|
136
|
+
instance = Neo[config.ntype ? 'ntype' : 'create'](config)
|
137
|
+
}
|
138
|
+
|
139
|
+
return instance.id
|
140
|
+
}
|
141
|
+
|
75
142
|
/**
|
76
143
|
* @param {Object} data
|
77
144
|
*/
|
@@ -81,6 +148,36 @@ class App extends Base {
|
|
81
148
|
this.resolveThemeFilesCache()
|
82
149
|
}
|
83
150
|
|
151
|
+
/**
|
152
|
+
* Remote method to use inside main threads for destroying neo based class instances.
|
153
|
+
*
|
154
|
+
* @example:
|
155
|
+
* Neo.worker.App.destroyNeoInstance('neo-button-3').then(success => console.log(success))
|
156
|
+
*
|
157
|
+
* @param {String} id
|
158
|
+
* @returns {Boolean} returns true, in case the instance was found
|
159
|
+
*/
|
160
|
+
destroyNeoInstance(id) {
|
161
|
+
let instance = Neo.get(id),
|
162
|
+
parent;
|
163
|
+
|
164
|
+
if (instance) {
|
165
|
+
if (instance.parentId) {
|
166
|
+
parent = Neo.getComponent(instance.parentId);
|
167
|
+
|
168
|
+
if (parent) {
|
169
|
+
parent.remove(instance);
|
170
|
+
return true
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
instance.destroy(true, true);
|
175
|
+
return true
|
176
|
+
}
|
177
|
+
|
178
|
+
return false
|
179
|
+
}
|
180
|
+
|
84
181
|
/**
|
85
182
|
* Only needed for the SharedWorkers context
|
86
183
|
* @param {String} eventName
|