neo.mjs 5.15.2 → 5.15.3

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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.15.2'
23
+ * @member {String} version='5.15.3'
24
24
  */
25
- version: '5.15.2'
25
+ version: '5.15.3'
26
26
  }
27
27
 
28
28
  /**
@@ -45,7 +45,7 @@ class PreviewList extends List {
45
45
  });
46
46
 
47
47
  if (!silent) {
48
- me.promiseVdomUpdate().then(() => {
48
+ me.promiseUpdate().then(() => {
49
49
  me.fire('createItems');
50
50
  });
51
51
  }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.15.2'
23
+ * @member {String} version='5.15.3'
24
24
  */
25
- version: '5.15.2'
25
+ version: '5.15.3'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.15.2",
3
+ "version": "5.15.3",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -245,12 +245,12 @@ const DefaultConfig = {
245
245
  useVdomWorker: true,
246
246
  /**
247
247
  * buildScripts/injectPackageVersion.mjs will update this value
248
- * @default '5.15.2'
248
+ * @default '5.15.3'
249
249
  * @memberOf! module:Neo
250
250
  * @name config.version
251
251
  * @type String
252
252
  */
253
- version: '5.15.2'
253
+ version: '5.15.3'
254
254
  };
255
255
 
256
256
  Object.assign(DefaultConfig, {
package/src/Neo.mjs CHANGED
@@ -645,7 +645,10 @@ function autoGenerateGetSet(proto, key) {
645
645
  me[_key] = value;
646
646
  }
647
647
 
648
- if (!Neo.isEqual(value, oldValue)) {
648
+ if (
649
+ (key === 'vnode' && value !== oldValue) || // vnode trees can be huge, avoid a deep comparison
650
+ !Neo.isEqual(value, oldValue)
651
+ ) {
649
652
  me[afterSet]?.(value, oldValue);
650
653
  me.afterSetConfig?.(key, value, oldValue);
651
654
  }
@@ -261,7 +261,7 @@ class MainContainer extends Container {
261
261
  if (value) {
262
262
  delete sideBar.vdom.removeDom;
263
263
 
264
- me.promiseVdomUpdate().then(() => {
264
+ me.promiseUpdate().then(() => {
265
265
  sideBar.mounted = true;
266
266
 
267
267
  setTimeout(() => {
@@ -274,7 +274,7 @@ class MainContainer extends Container {
274
274
  sideBar._style = style; // silent update
275
275
  sideBar._vdom.style = style; // silent update
276
276
 
277
- me.promiseVdomUpdate().then(() => {
277
+ me.promiseUpdate().then(() => {
278
278
  setTimeout(() => {
279
279
  sideBar.vdom.removeDom = true;
280
280
  sideBar.update();
@@ -57,7 +57,7 @@ class SettingsContainer extends Container {
57
57
  me._style = style; // silent update
58
58
  me._vdom.style = style; // silent update
59
59
 
60
- Neo.getComponent(me.parentId).promiseVdomUpdate().then(() => {
60
+ Neo.getComponent(me.parentId).promiseUpdate().then(() => {
61
61
  setTimeout(() => {
62
62
  me.collapsed = true;
63
63
 
@@ -145,7 +145,7 @@ class SettingsContainer extends Container {
145
145
 
146
146
  delete me.vdom.removeDom;
147
147
 
148
- Neo.getComponent(me.parentId).promiseVdomUpdate().then(() => {
148
+ Neo.getComponent(me.parentId).promiseUpdate().then(() => {
149
149
  me.collapsed = false;
150
150
  me.mounted = true;
151
151
 
@@ -512,7 +512,7 @@ class YearComponent extends Component {
512
512
  vdom.cn[1].cn[0].cn[scrollFromTop ? 'unshift' : 'push'](vdom.cn[0]);
513
513
  vdom.cn.splice(0, 1);
514
514
 
515
- me.promiseVdomUpdate(vdom).then(() => {
515
+ me.promiseUpdate(vdom).then(() => {
516
516
  y = scrollFromTop ? -data.height : 0;
517
517
  vdom.cn[0].cn[0].style.transform = `translateY(${y}px)`;
518
518
  me.update();
@@ -783,7 +783,7 @@ class YearComponent extends Component {
783
783
 
784
784
  me.isUpdating = true;
785
785
 
786
- me.promiseVdomUpdate(me.vdom).then(() => {
786
+ me.promiseUpdate(me.vdom).then(() => {
787
787
  me.isUpdating = false;
788
788
  });
789
789
  }
@@ -689,7 +689,7 @@ class Component extends BaseComponent {
689
689
  week.header && container.cn.unshift(week.header);
690
690
  }
691
691
 
692
- me.promiseVdomUpdate(me.vdom).then(() => {
692
+ me.promiseUpdate(me.vdom).then(() => {
693
693
  Neo.main.DomAccess.scrollTo({
694
694
  direction: 'top',
695
695
  id : me.vdom.cn[1].id,
@@ -805,7 +805,7 @@ class Component extends BaseComponent {
805
805
  if (scrollValue) {
806
806
  me.isUpdating = true;
807
807
 
808
- me.promiseVdomUpdate().then(() => {
808
+ me.promiseUpdate().then(() => {
809
809
  Neo.main.DomAccess.scrollBy({
810
810
  direction: 'left',
811
811
  id : me.getScrollContainer().id,
@@ -313,6 +313,11 @@ class Base extends CoreBase {
313
313
  */
314
314
  childUpdateCache = []
315
315
 
316
+ /**
317
+ * @member {Function[]} resolveUpdateCache=[]
318
+ */
319
+ resolveUpdateCache = []
320
+
316
321
  /**
317
322
  * Apply component based listeners
318
323
  * @member {Object} listeners={}
@@ -635,6 +640,8 @@ class Base extends CoreBase {
635
640
  }, 100)
636
641
  }
637
642
 
643
+ me.doResolveUpdateCache();
644
+
638
645
  me.fire('mounted', me.id)
639
646
  }
640
647
  }
@@ -1059,6 +1066,14 @@ class Base extends CoreBase {
1059
1066
  super.destroy()
1060
1067
  }
1061
1068
 
1069
+ /**
1070
+ * Triggers all stored resolve() callbacks
1071
+ */
1072
+ doResolveUpdateCache() {
1073
+ this.resolveUpdateCache.forEach(item => item());
1074
+ this.resolveUpdateCache = [];
1075
+ }
1076
+
1062
1077
  /**
1063
1078
  * Convenience shortcut for Neo.manager.Component.down
1064
1079
  * @param {Object|String} config
@@ -1073,8 +1088,8 @@ class Base extends CoreBase {
1073
1088
  * Internal method to send update requests to the vdom worker
1074
1089
  * @param {Object} vdom
1075
1090
  * @param {Neo.vdom.VNode} vnode
1076
- * @param {function} [resolve] used by promiseVdomUpdate()
1077
- * @param {function} [reject] used by promiseVdomUpdate()
1091
+ * @param {function} [resolve] used by promiseUpdate()
1092
+ * @param {function} [reject] used by promiseUpdate()
1078
1093
  * @private
1079
1094
  */
1080
1095
  #executeVdomUpdate(vdom, vnode, resolve, reject) {
@@ -1393,11 +1408,13 @@ class Base extends CoreBase {
1393
1408
  }
1394
1409
 
1395
1410
  /**
1396
- * Checks for vdom updates inside the parent chain and if found, registers the component for a vdom update once done
1411
+ * Checks for vdom updates inside the parent chain and if found.
1412
+ * Registers the component for a vdom update once done.
1397
1413
  * @param {String} parentId=this.parentId
1414
+ * @param {Function} [resolve] gets passed by updateVdom()
1398
1415
  * @returns {Boolean}
1399
1416
  */
1400
- isParentVdomUpdating(parentId=this.parentId) {
1417
+ isParentVdomUpdating(parentId=this.parentId, resolve) {
1401
1418
  if (parentId !== 'document.body') {
1402
1419
  let me = this,
1403
1420
  parent = Neo.getComponent(parentId);
@@ -1408,8 +1425,11 @@ class Base extends CoreBase {
1408
1425
  console.warn('vdom parent update conflict with:', parent, 'for:', me)
1409
1426
  }
1410
1427
 
1411
- console.log('add cache', me.id);
1412
1428
  NeoArray.add(parent.childUpdateCache, me.id);
1429
+
1430
+ // Adding the resolve fn to its own cache, since the parent will trigger
1431
+ // a new update() directly on this cmp
1432
+ resolve && me.resolveUpdateCache.push(resolve)
1413
1433
  return true
1414
1434
  } else {
1415
1435
  return me.isParentVdomUpdating(parent.parentId)
@@ -1501,15 +1521,19 @@ class Base extends CoreBase {
1501
1521
  /**
1502
1522
  * Checks the needsVdomUpdate config inside the parent tree
1503
1523
  * @param {String} parentId=this.parentId
1524
+ * @param {Function} [resolve] gets passed by updateVdom()
1504
1525
  * @returns {Boolean}
1505
1526
  */
1506
- needsParentUpdate(parentId=this.parentId) {
1527
+ needsParentUpdate(parentId=this.parentId, resolve) {
1507
1528
  if (parentId !== 'document.body') {
1508
1529
  let me = this,
1509
1530
  parent = Neo.getComponent(parentId);
1510
1531
 
1511
1532
  if (parent) {
1512
1533
  if (parent.needsVdomUpdate) {
1534
+ parent.resolveUpdateCache.push(...me.resolveUpdateCache);
1535
+ resolve && parent.resolveUpdateCache.push(resolve);
1536
+ me.resolveUpdateCache = [];
1513
1537
  return true
1514
1538
  } else {
1515
1539
  return me.needsParentUpdate(parent.parentId)
@@ -1608,7 +1632,7 @@ class Base extends CoreBase {
1608
1632
  * @param {Neo.vdom.VNode} [vnode= this.vnode]
1609
1633
  * @returns {Promise<any>}
1610
1634
  */
1611
- promiseVdomUpdate(vdom=this.vdom, vnode=this.vnode) {
1635
+ promiseUpdate(vdom=this.vdom, vnode=this.vnode) {
1612
1636
  return new Promise((resolve, reject) => {
1613
1637
  this.updateVdom(vdom, vnode, resolve, reject)
1614
1638
  })
@@ -1702,6 +1726,9 @@ class Base extends CoreBase {
1702
1726
 
1703
1727
  delete me.vdom.removeDom;
1704
1728
 
1729
+ me._needsVdomUpdate = false;
1730
+ me.afterSetNeedsVdomUpdate?.(false, true)
1731
+
1705
1732
  Neo.vdom.Helper.create({
1706
1733
  appName : me.appName,
1707
1734
  autoMount,
@@ -1725,11 +1752,14 @@ class Base extends CoreBase {
1725
1752
  resolveVdomUpdate(resolve) {
1726
1753
  let me = this;
1727
1754
 
1755
+ me.doResolveUpdateCache();
1756
+
1728
1757
  resolve?.();
1729
1758
 
1730
1759
  if (me.needsVdomUpdate) {
1731
1760
  me.childUpdateCache = []; // if a new update is scheduled, we can clear the cache => these updates are included
1732
- me.vdom = me.vdom // trigger the next update cycle
1761
+
1762
+ me.update()
1733
1763
  } else {
1734
1764
  [...me.childUpdateCache].forEach(id => {
1735
1765
  Neo.getComponent(id)?.update();
@@ -1762,7 +1792,7 @@ class Base extends CoreBase {
1762
1792
  return Promise.resolve()
1763
1793
  }
1764
1794
 
1765
- return me.promiseVdomUpdate()
1795
+ return me.promiseUpdate()
1766
1796
  }
1767
1797
  }
1768
1798
 
@@ -2007,13 +2037,14 @@ class Base extends CoreBase {
2007
2037
  * Gets called after the vdom config gets changed in case the component is already mounted (delta updates).
2008
2038
  * @param {Object} vdom=this.vdom
2009
2039
  * @param {Neo.vdom.VNode} vnode=this.vnode
2010
- * @param {function} [resolve] used by promiseVdomUpdate()
2011
- * @param {function} [reject] used by promiseVdomUpdate()
2040
+ * @param {function} [resolve] used by promiseUpdate()
2041
+ * @param {function} [reject] used by promiseUpdate()
2012
2042
  * @protected
2013
2043
  */
2014
2044
  updateVdom(vdom=this.vdom, vnode=this.vnode, resolve, reject) {
2015
- let me = this,
2016
- app = Neo.apps[me.appName],
2045
+ let me = this,
2046
+ app = Neo.apps[me.appName],
2047
+ mounted = me.mounted,
2017
2048
  listenerId;
2018
2049
 
2019
2050
  // It is important to keep the vdom tree stable to ensure that containers do not lose the references to their
@@ -2029,11 +2060,14 @@ class Base extends CoreBase {
2029
2060
  vdom = Object.assign(me._vdom, vdom)
2030
2061
  }
2031
2062
 
2032
- if (me.silentVdomUpdate) {
2033
- me.needsVdomUpdate = true;
2034
- resolve?.()
2063
+ if (resolve && me.isVdomUpdating) {
2064
+ me.resolveUpdateCache.push(resolve)
2065
+ }
2066
+
2067
+ if (me.isVdomUpdating || me.silentVdomUpdate) {
2068
+ me.needsVdomUpdate = true
2035
2069
  } else {
2036
- if (!me.mounted && me.isConstructed && !me.hasRenderingListener && app?.rendering === true) {
2070
+ if (!mounted && me.isConstructed && !me.hasRenderingListener && app?.rendering === true) {
2037
2071
  me.hasRenderingListener = true;
2038
2072
 
2039
2073
  listenerId = app.on('mounted', () => {
@@ -2044,15 +2078,22 @@ class Base extends CoreBase {
2044
2078
  })
2045
2079
  })
2046
2080
  } else {
2047
- if (me.mounted && vnode && !me.needsParentUpdate() && !me.isParentVdomUpdating()) {
2081
+ if (resolve && (!mounted || !vnode)) {
2082
+ me.resolveUpdateCache.push(resolve)
2083
+ }
2084
+
2085
+ if (
2086
+ mounted
2087
+ && vnode
2088
+ && !me.needsParentUpdate(me.parentId, resolve)
2089
+ && !me.isParentVdomUpdating(me.parentId, resolve)
2090
+ ) {
2048
2091
  me.#executeVdomUpdate(vdom, vnode, resolve, reject)
2049
- } else {
2050
- resolve?.()
2051
2092
  }
2052
2093
  }
2053
2094
  }
2054
2095
 
2055
- me.hasUnmountedVdomChanges = !me.mounted && me.hasBeenMounted
2096
+ me.hasUnmountedVdomChanges = !mounted && me.hasBeenMounted
2056
2097
  }
2057
2098
  }
2058
2099
 
@@ -255,7 +255,7 @@ class Circle extends Component {
255
255
  me.createItems(oldValue, true);
256
256
  me.updateItemPositions(true);
257
257
 
258
- me.promiseVdomUpdate().then(() => {
258
+ me.promiseUpdate().then(() => {
259
259
  if (!me.collapsed) {
260
260
  me.updateItemOpacity(1, true, oldValue);
261
261
  me.update();
@@ -720,7 +720,7 @@ class Circle extends Component {
720
720
 
721
721
  me.circleCenterHasTransitionCls = false;
722
722
 
723
- me.promiseVdomUpdate().then(() => {
723
+ me.promiseUpdate().then(() => {
724
724
  me.updateItemAngle(true);
725
725
  circleCenterEl.style.transform = transform;
726
726
  me.update();
@@ -447,7 +447,7 @@ class DateSelector extends Component {
447
447
  vdom.cn[2].cn[0].cn[slideDirection === 'right'? 'unshift' : 'push'](vdom.cn[1]);
448
448
  vdom.cn.splice(1, 1);
449
449
 
450
- me.promiseVdomUpdate().then(() => {
450
+ me.promiseUpdate().then(() => {
451
451
  me.changeMonthTransitionCallback({data: data[0], slideDirection: slideDirection});
452
452
  me.updateHeaderMonthTransitionCallback(headerMonthOpts);
453
453
  me.update();
@@ -533,7 +533,7 @@ class DateSelector extends Component {
533
533
  vdom.cn[2].cn[0].cn[scrollFromTop ? 'unshift' : 'push'](vdom.cn[1]);
534
534
  vdom.cn.splice(1, 1);
535
535
 
536
- me.promiseVdomUpdate(vdom).then(() => {
536
+ me.promiseUpdate(vdom).then(() => {
537
537
  y = scrollFromTop ? -data.height : 0;
538
538
  vdom.cn[1].cn[0].style.transform = `translateY(${y}px)`;
539
539
  me.update();
@@ -844,7 +844,7 @@ class DateSelector extends Component {
844
844
 
845
845
  me.isUpdating = true;
846
846
 
847
- me.promiseVdomUpdate(me.vdom).then(() => {
847
+ me.promiseUpdate(me.vdom).then(() => {
848
848
  me.isUpdating = false;
849
849
  });
850
850
  }
@@ -440,7 +440,7 @@ class Gallery extends Component {
440
440
  itemsRoot.cn.push(vdomItem);
441
441
  }
442
442
 
443
- me.promiseVdomUpdate(vdom).then(() => {
443
+ me.promiseUpdate(vdom).then(() => {
444
444
  me[itemsMounted] = true;
445
445
  });
446
446
  }
@@ -581,7 +581,7 @@ class Helix extends Component {
581
581
 
582
582
  me[lockWheel] = false;
583
583
 
584
- me.promiseVdomUpdate(vdom).then(() => {
584
+ me.promiseUpdate(vdom).then(() => {
585
585
  me[itemsMounted] = true;
586
586
  me.fire('itemsMounted');
587
587
 
@@ -422,7 +422,7 @@ class Base extends Component {
422
422
  }
423
423
 
424
424
  if (!silent) {
425
- me.promiseVdomUpdate().then(() => {
425
+ me.promiseUpdate().then(() => {
426
426
  me.fire('insert', { index, item });
427
427
  });
428
428
  }
@@ -1,6 +1,5 @@
1
1
  import Container from './Base.mjs';
2
2
  import Panel from './Panel.mjs';
3
- import Toolbar from './Toolbar.mjs';
4
3
  import Viewport from './Viewport.mjs';
5
4
 
6
- export {Container, Panel, Toolbar, Viewport};
5
+ export {Container, Panel, Viewport};
@@ -1,4 +1,4 @@
1
- import Socket from './Socket.mjs';
2
- import Xhr from './Xhr.mjs';
1
+ import WebSocket from './WebSocket.mjs';
2
+ import Xhr from './Xhr.mjs';
3
3
 
4
- export {Socket, Xhr};
4
+ export {WebSocket, Xhr};
@@ -197,7 +197,7 @@ class DateField extends Picker {
197
197
  if (me.hidePickerOnSelect) {
198
198
  VDomUtil.removeVdomChild(vdom, me.getPickerId());
199
199
 
200
- me.promiseVdomUpdate().then(data => {
200
+ me.promiseUpdate().then(data => {
201
201
  me.value = opts.value;
202
202
  });
203
203
  } else {
@@ -23,7 +23,7 @@ class Text extends Base {
23
23
  * @protected
24
24
  * @static
25
25
  */
26
- static labelPositions = ['bottom', 'inline', 'left', 'right', 'top']
26
+ static labelPositions = ['bottom', 'inline', 'left', 'right', 'top']
27
27
 
28
28
  static config = {
29
29
  /**
@@ -220,14 +220,18 @@ class Text extends Base {
220
220
  * @member {Object} _vdom
221
221
  */
222
222
  _vdom:
223
- {cn: [
224
- {tag: 'label', cls: [], style: {}},
225
- {tag: 'label', cls: []},
226
- {tag: 'input', cls: ['neo-textfield-input'], flag: 'neo-real-input', style: {}},
227
- {cls: ['neo-textfield-error-wrapper'], removeDom: true, cn: [
228
- {cls: ['neo-textfield-error']}
229
- ]}
230
- ]}
223
+ {
224
+ cn: [
225
+ {tag: 'label', cls: [], style: {}},
226
+ {tag: 'label', cls: []},
227
+ {tag: 'input', cls: ['neo-textfield-input'], flag: 'neo-real-input', style: {}},
228
+ {
229
+ cls: ['neo-textfield-error-wrapper'], removeDom: true, cn: [
230
+ {cls: ['neo-textfield-error']}
231
+ ]
232
+ }
233
+ ]
234
+ }
231
235
  }
232
236
 
233
237
  /**
@@ -246,9 +250,9 @@ class Text extends Base {
246
250
  let me = this;
247
251
 
248
252
  me.addDomListeners([
249
- {input : me.onInputValueChange, scope: me},
250
- {mouseenter: me.onMouseEnter, scope: me},
251
- {mouseleave: me.onMouseLeave, scope: me}
253
+ {input: me.onInputValueChange, scope: me},
254
+ {mouseenter: me.onMouseEnter, scope: me},
255
+ {mouseleave: me.onMouseLeave, scope: me}
252
256
  ]);
253
257
  }
254
258
 
@@ -530,7 +534,7 @@ class Text extends Base {
530
534
  delete me.getCenterBorderEl()?.width;
531
535
  }
532
536
 
533
- me.promiseVdomUpdate().then(() => {
537
+ me.promiseUpdate().then(() => {
534
538
  me.updateCenterBorderElWidth(isEmpty)
535
539
  })
536
540
  } else {
@@ -637,7 +641,7 @@ class Text extends Base {
637
641
  * @protected
638
642
  */
639
643
  afterSetReadOnly(value, oldValue) {
640
- let me = this,
644
+ let me = this,
641
645
  cls = me.cls;
642
646
 
643
647
  NeoArray[value ? 'add' : 'remove'](cls, 'neo-readonly');
@@ -663,7 +667,7 @@ class Text extends Base {
663
667
 
664
668
  me.validate(false);
665
669
  me.changeInputElKey('required', value ? value : null);
666
- me.labelText = me.labelText; // apply the optional text if needed
670
+ me.labelText = me.labelText; // apply the optional text if needed
667
671
 
668
672
  me.silentVdomUpdate = false;
669
673
 
@@ -753,10 +757,10 @@ class Text extends Base {
753
757
  });
754
758
 
755
759
  postTriggers.sort((a, b) => b.weight - a.weight); // DESC
756
- preTriggers .sort((a, b) => a.weight - b.weight); // ASC
760
+ preTriggers.sort((a, b) => a.weight - b.weight); // ASC
757
761
 
758
762
  postTriggers = postTriggers.map(a => a.vdom);
759
- preTriggers = preTriggers .map(a => a.vdom);
763
+ preTriggers = preTriggers.map(a => a.vdom);
760
764
 
761
765
  if (inputEl.tag === 'input') {
762
766
  // wrap the input tag
@@ -774,13 +778,13 @@ class Text extends Base {
774
778
  } else {
775
779
  if (inputEl.tag !== 'input') {
776
780
  // replacing the input wrapper div with the input tag
777
- width = inputEl.width;
778
- vdom.cn[2] = me.getInputEl();
781
+ width = inputEl.width;
782
+ vdom.cn[2] = me.getInputEl();
779
783
  vdom.cn[2].width = width;
780
784
  }
781
785
  }
782
786
 
783
- me.promiseVdomUpdate().then(() => {
787
+ me.promiseUpdate().then(() => {
784
788
  me.updateTriggerVnodes()
785
789
  })
786
790
  }
@@ -807,7 +811,7 @@ class Text extends Base {
807
811
  cls = me.cls;
808
812
 
809
813
  NeoArray[me.hasContent() ? 'add' : 'remove'](cls, 'neo-has-content');
810
- NeoArray[isDirty ? 'add' : 'remove'](cls, 'neo-is-dirty');
814
+ NeoArray[isDirty ? 'add' : 'remove'](cls, 'neo-is-dirty');
811
815
  me.cls = cls;
812
816
 
813
817
  me.silentVdomUpdate = false;
@@ -1242,7 +1246,7 @@ class Text extends Base {
1242
1246
  vnode.vnode.attributes.value = value;
1243
1247
  }
1244
1248
 
1245
- me.value = me.inputValueAdjustor(value)
1249
+ me.value = me.inputValueAdjustor(value)
1246
1250
  }
1247
1251
 
1248
1252
  /**
@@ -1278,7 +1282,7 @@ class Text extends Base {
1278
1282
  * @param {Array} [triggerSource] pass a shallow copy of this.triggers
1279
1283
  * @returns {Boolean} true in case a trigger was found & removed
1280
1284
  */
1281
- removeTrigger(type, silent=false, triggerSource) {
1285
+ removeTrigger(type, silent = false, triggerSource) {
1282
1286
  let me = this,
1283
1287
  hasMatch = false,
1284
1288
  triggers = triggerSource || me.triggers || [],
@@ -1308,7 +1312,7 @@ class Text extends Base {
1308
1312
  * You can optionally pass a new value, which will adjust the originalConfig.value if needed.
1309
1313
  * @param {String|null} [value=null]
1310
1314
  */
1311
- reset(value=null) {
1315
+ reset(value = null) {
1312
1316
  let me = this;
1313
1317
 
1314
1318
  if (me.clearToOriginalValue) {
@@ -1331,7 +1335,7 @@ class Text extends Base {
1331
1335
  * @param {Boolean} [silent=false] true to get the value, but not apply it to the DOM
1332
1336
  * @protected
1333
1337
  */
1334
- updateCenterBorderElWidth(silent=false) {
1338
+ updateCenterBorderElWidth(silent = false) {
1335
1339
  let me = this;
1336
1340
 
1337
1341
  me.mounted && me.getDomRect(me.getCenterBorderEl().id).then(data => {
@@ -1348,7 +1352,7 @@ class Text extends Base {
1348
1352
  @param {String|null} value
1349
1353
  @param {Boolean} silent=false
1350
1354
  */
1351
- updateError(value, silent=false) {
1355
+ updateError(value, silent = false) {
1352
1356
  let me = this,
1353
1357
  cls = me.cls,
1354
1358
  errorNode, errorWrapper;
@@ -1394,9 +1398,9 @@ class Text extends Base {
1394
1398
  * todo: this could be handled by component.Base
1395
1399
  */
1396
1400
  updateTriggerVnodes() {
1397
- let me = this,
1398
- triggerRoot = me.vnode?.childNodes[1],
1399
- childNodes = triggerRoot?.childNodes || [],
1401
+ let me = this,
1402
+ triggerRoot = me.vnode?.childNodes[1],
1403
+ childNodes = triggerRoot?.childNodes || [],
1400
1404
  trigger;
1401
1405
 
1402
1406
  childNodes.forEach(vnode => {
@@ -1415,7 +1419,7 @@ class Text extends Base {
1415
1419
  * @param {Boolean} silent=true
1416
1420
  * @returns {Boolean} Returns true in case there are no client-side errors
1417
1421
  */
1418
- validate(silent=true) {
1422
+ validate(silent = true) {
1419
1423
  let me = this,
1420
1424
  maxLength = me.maxLength,
1421
1425
  minLength = me.minLength,
@@ -1433,30 +1437,28 @@ class Text extends Base {
1433
1437
  me.clean = false;
1434
1438
  }
1435
1439
 
1436
- if (Neo.isFunction(me.validator)) {
1437
- errorText = me.validator(me);
1438
-
1439
- if (errorText !== true) {
1440
- me._error = errorText;
1441
- returnValue = false;
1442
- }
1443
- }
1444
-
1445
1440
  if (isEmpty) {
1446
1441
  if (required) {
1447
- me._error = me.errorTextRequired;
1442
+ me._error = me.errorTextRequired;
1448
1443
  returnValue = false;
1449
1444
  }
1450
1445
  } else {
1451
1446
  if (Neo.isNumber(maxLength) && valueLength > maxLength) {
1452
- me._error = me.errorTextMaxLength(errorParam);
1447
+ me._error = me.errorTextMaxLength(errorParam);
1453
1448
  returnValue = false;
1454
1449
  } else if (Neo.isNumber(minLength) && valueLength < minLength) {
1455
- me._error = me.errorTextMinLength(errorParam);
1450
+ me._error = me.errorTextMinLength(errorParam);
1456
1451
  returnValue = false;
1457
1452
  } else if (inputPattern && !inputPattern.test(value)) {
1458
- me._error = me.errorTextInputPattern(errorParam);
1453
+ me._error = me.errorTextInputPattern(errorParam);
1459
1454
  returnValue = false;
1455
+ } else if (Neo.isFunction(me.validator)) {
1456
+ errorText = me.validator(me);
1457
+
1458
+ if (errorText !== true) {
1459
+ me._error = errorText;
1460
+ returnValue = false;
1461
+ }
1460
1462
  }
1461
1463
  }
1462
1464
 
@@ -13,6 +13,8 @@ class ZipCode extends Text {
13
13
  * @static
14
14
  */
15
15
  static countryCodes = {
16
+ AT: /^\d{4}$/,
17
+ CH: /^\d{4}$/,
16
18
  DE: /^(?!01000|99999)(0[1-9]\d{3}|[1-9]\d{4})$/
17
19
  }
18
20
 
@@ -40,12 +42,12 @@ class ZipCode extends Text {
40
42
  * The data.Model field inside the related country field which provides the country code (e.g. 'DE')
41
43
  * @member {String} countryKeyProperty='id'
42
44
  */
43
- countryKeyProperty: 'id',
45
+ countryKeyProperty: "id",
44
46
  /**
45
47
  * data passes inputPattern, maxLength, minLength & valueLength properties
46
- * @member {Function} errorTextInputPattern=data=>`Not a valid zip code`
48
+ * @member {Function} errorTextInputPattern=data=>'Not a valid zip code'
47
49
  */
48
- errorTextInputPattern: data => `Not a valid zip code`
50
+ errorTextInputPattern: (data) => 'Not a valid zip code'
49
51
  }
50
52
 
51
53
  /**
@@ -59,7 +61,7 @@ class ZipCode extends Text {
59
61
 
60
62
  me.inputPattern = ZipCode.countryCodes[value] || null;
61
63
 
62
- oldValue !== undefined && me.value && !me.clean && me.validate(false);
64
+ oldValue !== undefined && me.value && !me.clean && me.validate(false)
63
65
  }
64
66
 
65
67
  /**
@@ -99,14 +101,14 @@ class ZipCode extends Text {
99
101
  return me.up().getReference(value)
100
102
  }
101
103
 
102
- return value;
104
+ return value
103
105
  }
104
106
 
105
107
  /**
106
108
  * @param {Object} data
107
109
  */
108
110
  onCountryFieldChange(data) {
109
- this.countryCode = data.record?.[this.countryKeyProperty] || null;
111
+ this.countryCode = data.record?.[this.countryKeyProperty] || null
110
112
  }
111
113
  }
112
114
 
package/src/grid/View.mjs CHANGED
@@ -150,7 +150,7 @@ class View extends Component {
150
150
  container.dockLeftMargin = dockLeftMargin;
151
151
  container.dockRightMargin = dockRightMargin;
152
152
 
153
- me.promiseVdomUpdate().then(() => {
153
+ me.promiseUpdate().then(() => {
154
154
  if (selectedRows?.length > 0) {
155
155
  // this logic only works for selection.table.RowModel
156
156
  Neo.main.DomAccess.scrollToTableRow({id: selectedRows[0]});
package/src/list/Base.mjs CHANGED
@@ -485,7 +485,7 @@ class Base extends Component {
485
485
  listItem && vdom.cn.push(listItem);
486
486
  });
487
487
 
488
- !silent && me.promiseVdomUpdate().then(() => {
488
+ !silent && me.promiseUpdate().then(() => {
489
489
  me.fire('createItems');
490
490
  });
491
491
  }
@@ -215,12 +215,14 @@ class DeltaUpdates extends Base {
215
215
  case 'style':
216
216
  if (Neo.isObject(value)) {
217
217
  Object.entries(value).forEach(([key, val]) => {
218
+ let important;
219
+
218
220
  if (Neo.isString(val) && val.includes('!important')) {
219
221
  val = val.replace('!important', '').trim();
220
- node.style.setProperty(Neo.decamel(key), val, 'important');
221
- } else {
222
- node.style[Neo.decamel(key)] = val;
222
+ important = 'important';
223
223
  }
224
+
225
+ node.style.setProperty(Neo.decamel(key), val, important);
224
226
  });
225
227
  }
226
228
  break;
@@ -214,7 +214,7 @@ class View extends Component {
214
214
  container.dockLeftMargin = dockLeftMargin;
215
215
  container.dockRightMargin = dockRightMargin;
216
216
 
217
- me.promiseVdomUpdate().then(() => {
217
+ me.promiseUpdate().then(() => {
218
218
  if (selectedRows?.length > 0) {
219
219
  // this logic only works for selection.table.RowModel
220
220
  Neo.main.DomAccess.scrollToTableRow({id: selectedRows[0]});