neo.mjs 6.9.2 → 6.9.4

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='6.9.2'
23
+ * @member {String} version='6.9.4'
24
24
  */
25
- version: '6.9.2'
25
+ version: '6.9.4'
26
26
  }
27
27
 
28
28
  /**
@@ -45,7 +45,7 @@ class MainContainerController extends Component {
45
45
  */
46
46
 
47
47
 
48
- doPrehandling(value, oldValue, params = null) {
48
+ doPrehandling(params = null, value, oldValue) {
49
49
  const userId = parseInt(params.userId);
50
50
  if (userId > 0 && userId === this.data.activeUser) {
51
51
  return true;
@@ -137,27 +137,27 @@ class MainContainerController extends Component {
137
137
  this.#removeMetaButtonSelection();
138
138
  }
139
139
 
140
- handleHomeRoute(value, oldValue, params = null) {
140
+ handleHomeRoute(params = null, value, oldValue) {
141
141
  const centerContainer = this.getReference('center-container');
142
142
  centerContainer.layout.activeIndex = 4;
143
143
  }
144
144
 
145
- handleSection1Route(value, oldValue, params = null) {
145
+ handleSection1Route(params = null, value, oldValue) {
146
146
  const centerContainer = this.getReference('center-container');
147
147
  centerContainer.layout.activeIndex = 2;
148
148
  }
149
149
 
150
- handleSection2Route(value, oldValue, params = null) {
150
+ handleSection2Route(params = null, value, oldValue) {
151
151
  const centerContainer = this.getReference('center-container');
152
152
  centerContainer.layout.activeIndex = 3;
153
153
  }
154
154
 
155
- handleContactRoute(value, oldValue, params = null) {
155
+ handleContactRoute(params = null, value, oldValue) {
156
156
  const centerContainer = this.getReference('center-container');
157
157
  centerContainer.layout.activeIndex = 0;
158
158
  }
159
159
 
160
- handleUserRoute(value, oldValue, params = null) {
160
+ handleUserRoute(params = null, value, oldValue) {
161
161
  const centerContainer = this.getReference('center-container');
162
162
  centerContainer.layout.activeIndex = 1
163
163
  }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.9.2'
23
+ * @member {String} version='6.9.4'
24
24
  */
25
- version: '6.9.2'
25
+ version: '6.9.4'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "6.9.2",
3
+ "version": "6.9.4",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -56,7 +56,7 @@
56
56
  "neo-jsdoc": "1.0.1",
57
57
  "neo-jsdoc-x": "1.0.5",
58
58
  "postcss": "^8.4.31",
59
- "sass": "^1.69.4",
59
+ "sass": "^1.69.5",
60
60
  "showdown": "^2.1.0",
61
61
  "webpack": "^5.89.0",
62
62
  "webpack-cli": "^5.1.4",
@@ -236,12 +236,12 @@ const DefaultConfig = {
236
236
  useVdomWorker: true,
237
237
  /**
238
238
  * buildScripts/injectPackageVersion.mjs will update this value
239
- * @default '6.9.2'
239
+ * @default '6.9.4'
240
240
  * @memberOf! module:Neo
241
241
  * @name config.version
242
242
  * @type String
243
243
  */
244
- version: '6.9.2'
244
+ version: '6.9.4'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
@@ -625,7 +625,8 @@ class Base extends CoreBase {
625
625
  me[state]()
626
626
  }
627
627
 
628
- me.fire(state, {id: me.id})
628
+ me.fire(state, {id: me.id});
629
+ me.fire('hiddenChange', {id: me.id, oldValue, value})
629
630
  }
630
631
 
631
632
  /**
@@ -1,6 +1,10 @@
1
1
  import CoreBase from '../core/Base.mjs';
2
2
  import HashHistory from '../util/HashHistory.mjs';
3
3
 
4
+ const
5
+ amountSlashesRegex = /\//g,
6
+ routeParamRegex = /{[^\s/]+}/g
7
+
4
8
  /**
5
9
  * @class Neo.controller.Base
6
10
  * @extends Neo.core.Base
@@ -17,22 +21,25 @@ class Base extends CoreBase {
17
21
  * @protected
18
22
  */
19
23
  ntype: 'controller',
20
-
21
24
  /**
22
- * @member {Object} routes={}
25
+ * @member {String} defaultRoute=undefined
23
26
  */
24
- routes_: {},
25
-
27
+ defaultRoute: null,
26
28
  /**
27
29
  * @member {Object} handleRoutes={}
28
30
  */
29
31
  handleRoutes: {},
30
-
31
32
  /**
32
- * @member {String} defaultRoute=undefined
33
+ * @example
34
+ * routes: {
35
+ * '/home' : 'handleHomeRoute',
36
+ * '/users/{userId}' : {handler: 'handleUserRoute', preHandler: 'preHandleUserRoute'},
37
+ * '/users/{userId}/posts/{postId}': 'handlePostRoute',
38
+ * 'default' : 'handleOtherRoutes'
39
+ * }
40
+ * @member {Object} routes={}
33
41
  */
34
- defaultRoute: null
35
-
42
+ routes_: {}
36
43
  }
37
44
 
38
45
  /**
@@ -41,43 +48,33 @@ class Base extends CoreBase {
41
48
  construct(config) {
42
49
  super.construct(config);
43
50
 
44
- const me = this;
45
- HashHistory.on('change', me.onHashChange, me);
51
+ HashHistory.on('change', this.onHashChange, this)
46
52
  }
47
53
 
48
54
  /**
49
- * Triggered after the badgePosition config got changed
50
- * @param {String} value
51
- * @param {String} oldValue
55
+ * Triggered after the routes config got changed
56
+ * @param {Object} value
57
+ * @param {Object} oldValue
52
58
  * @protected
53
59
  */
54
60
  afterSetRoutes(value, oldValue){
55
- const me = this;
61
+ let me = this,
62
+ routeKeys = Object.keys(value);
56
63
 
57
- const functionSort = (a,b) => {
58
- const usedRegex = new RegExp("/", "g");
59
- return a.match(usedRegex).length - b.match(usedRegex).length;
60
- }
61
- me.routes = Object.keys(value).sort(functionSort).reduce(
62
- (obj, key) => {
63
- obj[key] = value[key];
64
- return obj;
65
- },
66
- {}
67
- );
68
-
64
+ me.routes = routeKeys.sort(me.#sortRoutes).reduce((obj, key) => {
65
+ obj[key] = value[key];
66
+ return obj
67
+ }, {});
69
68
 
70
69
  me.handleRoutes = {};
71
- if (Object.keys(me.routes).length > 0) {
72
- Object.keys(me.routes).forEach(key => {
73
- if (key.toLowerCase() === 'default'){
74
- me.defaultRoute = value[key];
75
- } else {
76
- me.handleRoutes[key] = new RegExp(key.replace(/{[^\s/]+}/g, '([\\w-]+)')+'$');
77
- }
78
70
 
79
- });
80
- }
71
+ routeKeys.forEach(key => {
72
+ if (key.toLowerCase() === 'default'){
73
+ me.defaultRoute = value[key]
74
+ } else {
75
+ me.handleRoutes[key] = new RegExp(key.replace(routeParamRegex, '([\\w-]+)')+'$')
76
+ }
77
+ })
81
78
  }
82
79
 
83
80
  /**
@@ -90,12 +87,12 @@ class Base extends CoreBase {
90
87
  }
91
88
 
92
89
  /**
93
- * Placeholder method which gets triggered when an invalid route is called
94
- * @param {Object} value
95
- * @param {Object} oldValue
90
+ *
96
91
  */
97
- onNoRouteFound(value, oldValue) {
92
+ onConstructed() {
93
+ let currentHash = HashHistory.first();
98
94
 
95
+ currentHash && this.onHashChange(currentHash, null)
99
96
  }
100
97
 
101
98
  /**
@@ -104,73 +101,85 @@ class Base extends CoreBase {
104
101
  * @param {Object} oldValue
105
102
  */
106
103
  onHashChange(value, oldValue) {
104
+ let me = this,
105
+ hasRouteBeenFound = false,
106
+ handleRoutes = me.handleRoutes,
107
+ routeKeys = Object.keys(handleRoutes),
108
+ routes = me.routes,
109
+ handler, preHandler, responsePreHandler, result, route;
110
+
111
+ routeKeys.forEach(key => {
112
+ handler = null;
113
+ preHandler = null;
114
+ responsePreHandler = null;
115
+
116
+ result = value.hashString.match(handleRoutes[key]);
117
+
118
+ if (result) {
119
+ const
120
+ arrayParamIds = key.match(routeParamRegex),
121
+ arrayParamValues = result.splice(1, result.length - 1),
122
+ paramObject = {};
123
+
124
+ if (arrayParamIds && arrayParamIds.length !== arrayParamValues.length) {
125
+ throw 'Number of IDs and number of Values do not match';
126
+ }
107
127
 
108
- const me = this;
109
- let hasRouteBeenFound = false;
110
- Object.keys(me.handleRoutes).forEach( key => {
111
- let preHandler = undefined;
112
- let executeHandler = undefined;
113
- let responsePreHandler = undefined;
114
-
115
- const result = value.hashString.match(me.handleRoutes[key]);
116
- if (result){
117
-
118
- const paramsRegex = /{[^\s/]+}/g;
119
- const arrayParamIds = key.match(paramsRegex);
120
- const arrayParamValues = result.splice(1,result.length - 1);
121
- if (arrayParamIds && arrayParamIds.length !== arrayParamValues.length){
122
- throw "Number of IDs and number of Values do not match";
123
- }
124
-
125
- const paramObject = {};
126
- for(let i=0; arrayParamIds && i< arrayParamIds.length; i++){
127
- paramObject[ arrayParamIds[i].substring(1,arrayParamIds[i].length -1)] = arrayParamValues[i];
128
+ for (let i = 0; arrayParamIds && i < arrayParamIds.length; i++) {
129
+ paramObject[arrayParamIds[i].substring(1, arrayParamIds[i].length - 1)] = arrayParamValues[i];
128
130
  }
129
131
 
130
- const target = me.routes[key];
131
- if (Neo.isString(target)){
132
- executeHandler = this.routes[key];
132
+ route = routes[key];
133
+
134
+ if (Neo.isString(route)) {
135
+ handler = route;
133
136
  responsePreHandler = true;
134
- }
135
- if (Neo.isObject(target)){
136
- executeHandler = this.routes[key].handler;
137
- preHandler = this.routes[key].preHandler;
137
+ } else if (Neo.isObject(route)) {
138
+ handler = route.handler;
139
+ preHandler = route.preHandler;
140
+
138
141
  if (preHandler) {
139
- responsePreHandler = me[preHandler]?.call(this, value, oldValue, paramObject);
142
+ responsePreHandler = me[preHandler]?.call(me, paramObject, value, oldValue);
140
143
  } else {
141
144
  responsePreHandler = true;
142
- console.warn('No preHandler defined for routes -> todo it better');
143
- }
145
+ }
144
146
  }
145
147
 
146
148
  hasRouteBeenFound = true;
147
149
 
148
150
  if (responsePreHandler) {
149
- this[executeHandler]?.call(this, value, oldValue, paramObject);
151
+ me[handler]?.call(me, paramObject, value, oldValue)
150
152
  }
151
153
  }
152
154
  });
153
155
 
154
- if (Object.keys(me.handleRoutes).length > 0 && !hasRouteBeenFound) {
156
+ if (routeKeys.length > 0 && !hasRouteBeenFound) {
155
157
  if (me.defaultRoute) {
156
- this[me.defaultRoute]?.call(this, value, oldValue);
158
+ me[me.defaultRoute]?.(value, oldValue)
157
159
  } else {
158
- this.onNoRouteFound(value, oldValue);
160
+ me.onNoRouteFound(value, oldValue)
159
161
  }
160
162
  }
161
163
  }
162
164
 
163
165
  /**
164
- *
166
+ * Placeholder method which gets triggered when an invalid route is called
167
+ * @param {Object} value
168
+ * @param {Object} oldValue
165
169
  */
166
- onConstructed() {
167
- let currentHash = HashHistory.first();
170
+ onNoRouteFound(value, oldValue) {
168
171
 
169
- currentHash && this.onHashChange(currentHash, null);
170
172
  }
171
173
 
172
-
173
-
174
+ /**
175
+ * Internal helper method to sort routes by their amount of slashes
176
+ * @param {String} route1
177
+ * @param {String} route2
178
+ * @returns {Number}
179
+ */
180
+ #sortRoutes(route1, route2) {
181
+ return route1.match(amountSlashesRegex).length - route2.match(amountSlashesRegex).length
182
+ }
174
183
  }
175
184
 
176
185
  Neo.applyClassConfig(Base);
@@ -134,6 +134,15 @@ class Component extends Base {
134
134
  return component || null
135
135
  }
136
136
 
137
+ /**
138
+ * Convenience shortcut for accessing model.Component based data.Stores
139
+ * @param {String} key
140
+ * @returns {Neo.data.Store}
141
+ */
142
+ getStore(key) {
143
+ return this.getModel().getStore(key)
144
+ }
145
+
137
146
  /**
138
147
  * Override this method inside your view controllers as a starting point in case you need references
139
148
  * (instead of using onConstructed() inside your controller)
@@ -85,13 +85,6 @@ class Picker extends Text {
85
85
  }]
86
86
  }
87
87
 
88
- /**
89
- * Internal flag to prevent showing a picker multiple times
90
- * @member {Boolean} pickerIsMounting=false
91
- * @protected
92
- */
93
- pickerIsMounting = false
94
-
95
88
  /**
96
89
  * @param {Object} config
97
90
  */
@@ -183,6 +176,8 @@ class Picker extends Text {
183
176
  }
184
177
  });
185
178
 
179
+ me.picker.on('hiddenChange', me.onPickerHiddenChange, me);
180
+
186
181
  return me.picker
187
182
  }
188
183
 
@@ -291,6 +286,17 @@ class Picker extends Text {
291
286
  this.pickerIsMounted && this.hidePicker()
292
287
  }
293
288
 
289
+ /**
290
+ * @param {Object} data
291
+ * @param {String} data.id
292
+ * @param {Boolean} data.oldValue
293
+ * @param {Boolean} data.value
294
+ * @protected
295
+ */
296
+ onPickerHiddenChange(data) {
297
+ this.pickerIsMounted = !data.value
298
+ }
299
+
294
300
  /**
295
301
  * Called by form.field.trigger.Picker
296
302
  * @protected
@@ -303,8 +309,7 @@ class Picker extends Text {
303
309
  *
304
310
  */
305
311
  showPicker() {
306
- let picker = this.getPicker();
307
- picker.hidden = false
312
+ this.getPicker().hidden = false
308
313
  }
309
314
 
310
315
  /**
@@ -661,12 +661,13 @@ class Select extends Picker {
661
661
  autocomplete: 'no',
662
662
  autocorrect : 'off',
663
663
  cls : ['neo-textfield-input', 'neo-typeahead-input'],
664
+ disabled : true,
664
665
  id : me.getInputHintId(),
665
666
  spellcheck : 'false'
666
667
  }, inputEl.vdom]
667
668
  }
668
669
  } else {
669
- VDomUtil.replaceVdomChild(vdom, inputEl.parentNode.id, inputEl.vdom);
670
+ VDomUtil.replaceVdomChild(vdom, inputEl.parentNode.id, inputEl.vdom)
670
671
  }
671
672
 
672
673
  !silent && me.update()
@@ -458,7 +458,7 @@ class Component extends Base {
458
458
  * Access the closest store inside the VM parent chain.
459
459
  * @param {String} key
460
460
  * @param {Neo.model.Component} originModel=this for internal usage only
461
- * @returns {*} value
461
+ * @returns {Neo.data.Store}
462
462
  */
463
463
  getStore(key, originModel=this) {
464
464
  let me = this,
@@ -20,6 +20,11 @@ class Button extends BaseButton {
20
20
  * @member {String[]} baseCls=['neo-button','neo-tab-button']
21
21
  */
22
22
  baseCls: ['neo-tab-header-button', 'neo-button'],
23
+ /**
24
+ * Specify a role tag attribute for the vdom root.
25
+ * @member {String|null} role='tab'
26
+ */
27
+ role: 'tab',
23
28
  /**
24
29
  * @member {Boolean} useActiveTabIndicator_=true
25
30
  */
@@ -28,7 +33,7 @@ class Button extends BaseButton {
28
33
  * @member {Object} _vdom
29
34
  */
30
35
  _vdom:
31
- {tag: 'button', type: 'button', cn: [
36
+ {tag: 'button', cn: [
32
37
  {tag: 'span', cls: ['neo-button-glyph']},
33
38
  {tag: 'span', cls: ['neo-button-text']},
34
39
  {cls: ['neo-button-badge']},
@@ -39,6 +44,26 @@ class Button extends BaseButton {
39
44
  ]}
40
45
  }
41
46
 
47
+ /**
48
+ * Triggered after the pressed config got changed
49
+ * @param {Boolean} value
50
+ * @param {Boolean} oldValue
51
+ * @protected
52
+ */
53
+ afterSetPressed(value, oldValue) {
54
+ super.afterSetPressed(value, oldValue);
55
+
56
+ let me = this;
57
+
58
+ if (value) {
59
+ me.vdom['aria-selected'] = true
60
+ } else {
61
+ delete me.vdom['aria-selected']
62
+ }
63
+
64
+ me.update()
65
+ }
66
+
42
67
  /**
43
68
  * Triggered after the useActiveTabIndicator config got changed
44
69
  * @param {Boolean} value