neo.mjs 10.0.0-alpha.4 → 10.0.0-alpha.5

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.
Files changed (35) hide show
  1. package/ServiceWorker.mjs +2 -2
  2. package/apps/portal/index.html +1 -1
  3. package/apps/portal/view/blog/List.mjs +1 -1
  4. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  5. package/buildScripts/buildThemes.mjs +1 -1
  6. package/examples/grid/animatedRowSorting/Viewport.mjs +4 -4
  7. package/examples/grid/bigData/ControlsContainer.mjs +3 -3
  8. package/examples/grid/bigData/GridContainer.mjs +8 -8
  9. package/examples/grid/cellEditing/MainContainer.mjs +5 -5
  10. package/examples/grid/container/MainContainer.mjs +4 -4
  11. package/examples/grid/nestedRecordFields/Viewport.mjs +5 -5
  12. package/learn/guides/ApplicationBootstrap.md +18 -20
  13. package/package.json +1 -1
  14. package/resources/scss/src/grid/{View.scss → Body.scss} +2 -2
  15. package/resources/scss/src/grid/VerticalScrollbar.scss +1 -1
  16. package/resources/scss/src/grid/plugin/AnimateRows.scss +1 -1
  17. package/resources/scss/src/grid/plugin/CellEditing.scss +1 -1
  18. package/resources/scss/theme-dark/grid/{View.scss → Body.scss} +1 -1
  19. package/resources/scss/theme-light/grid/{View.scss → Body.scss} +1 -1
  20. package/resources/scss/theme-neo-light/grid/{View.scss → Body.scss} +1 -1
  21. package/src/DefaultConfig.mjs +2 -2
  22. package/src/grid/{View.mjs → Body.mjs} +17 -17
  23. package/src/grid/Container.mjs +58 -58
  24. package/src/grid/ScrollManager.mjs +56 -56
  25. package/src/grid/VerticalScrollbar.mjs +2 -2
  26. package/src/grid/_export.mjs +2 -2
  27. package/src/grid/column/AnimatedChange.mjs +5 -5
  28. package/src/grid/column/Base.mjs +1 -1
  29. package/src/grid/column/Component.mjs +6 -6
  30. package/src/grid/header/Toolbar.mjs +9 -9
  31. package/src/grid/plugin/AnimateRows.mjs +1 -2
  32. package/src/util/Style.mjs +2 -6
  33. package/src/vdom/Helper.mjs +1 -1
  34. package/src/worker/App.mjs +6 -18
  35. package/src/worker/Manager.mjs +4 -8
package/ServiceWorker.mjs CHANGED
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='10.0.0-alpha.4'
23
+ * @member {String} version='10.0.0-alpha.5'
24
24
  */
25
- version: '10.0.0-alpha.4'
25
+ version: '10.0.0-alpha.5'
26
26
  }
27
27
 
28
28
  /**
@@ -16,7 +16,7 @@
16
16
  "@type": "Organization",
17
17
  "name": "Neo.mjs"
18
18
  },
19
- "datePublished": "2025-06-22",
19
+ "datePublished": "2025-06-24",
20
20
  "publisher": {
21
21
  "@type": "Organization",
22
22
  "name": "Neo.mjs"
@@ -174,7 +174,7 @@ class List extends BaseList {
174
174
  record = store.getAt(index);
175
175
  name = record.name.replace(List.nameRegEx, "$1");
176
176
 
177
- item.style = item.style || {};
177
+ item.style ??= {};
178
178
 
179
179
  if (emptyValue) {
180
180
  itemName.html = name;
@@ -107,7 +107,7 @@ class FooterContainer extends Container {
107
107
  }, {
108
108
  module: Component,
109
109
  cls : ['neo-version'],
110
- html : 'v10.0.0-alpha.4'
110
+ html : 'v10.0.0-alpha.5'
111
111
  }]
112
112
  }],
113
113
  /**
@@ -12,7 +12,7 @@ import * as sass from 'sass';
12
12
  const
13
13
  __dirname = path.resolve(),
14
14
  cwd = process.cwd(),
15
- requireJson = path => JSON.parse(fs.readFileSync((path))),
15
+ requireJson = path => JSON.parse(fs.readFileSync(path)),
16
16
  packageJson = requireJson(path.resolve(cwd, 'package.json')),
17
17
  insideNeo = packageJson.name.includes('neo.mjs'),
18
18
  neoPath = path.resolve(insideNeo ? './' : './node_modules/neo.mjs/'),
@@ -52,12 +52,12 @@ class Viewport extends BaseViewport {
52
52
  store : MainStore,
53
53
  wrapperStyle: {maxWidth: '902px'},
54
54
 
55
- columnDefaults: {
56
- width: 200
55
+ bodyConfig: {
56
+ animatedRowSorting: true
57
57
  },
58
58
 
59
- viewConfig: {
60
- animatedRowSorting: true
59
+ columnDefaults: {
60
+ width: 200
61
61
  },
62
62
 
63
63
  columns: [
@@ -207,7 +207,7 @@ class ControlsContainer extends Container {
207
207
  */
208
208
  onBufferColumnRangeChange(data) {
209
209
  if (data.oldValue) {
210
- this.grid.view.bufferColumnRange = parseInt(data.value.id)
210
+ this.grid.body.bufferColumnRange = parseInt(data.value.id)
211
211
  }
212
212
  }
213
213
 
@@ -216,7 +216,7 @@ class ControlsContainer extends Container {
216
216
  */
217
217
  onBufferRowRangeChange(data) {
218
218
  if (data.oldValue) {
219
- this.grid.view.bufferRowRange = parseInt(data.value.id)
219
+ this.grid.body.bufferRowRange = parseInt(data.value.id)
220
220
  }
221
221
  }
222
222
 
@@ -263,7 +263,7 @@ class ControlsContainer extends Container {
263
263
  * @param {Object} data
264
264
  */
265
265
  onSelectionModelChange(data) {
266
- this.grid.view.selectionModel = data.component.selectionModel
266
+ this.grid.body.selectionModel = data.component.selectionModel
267
267
  }
268
268
 
269
269
  /**
@@ -17,6 +17,13 @@ class GridContainer extends BaseGridContainer {
17
17
  * @member {Number} amountColumns_=50
18
18
  */
19
19
  amountColumns_: 50,
20
+ /**
21
+ * @member {Object} bodyConfig
22
+ */
23
+ bodyConfig: {
24
+ bufferColumnRange: 3,
25
+ bufferRowRange : 5
26
+ },
20
27
  /**
21
28
  * Default configs for each column
22
29
  * @member {Object} columnDefaults
@@ -29,14 +36,7 @@ class GridContainer extends BaseGridContainer {
29
36
  /**
30
37
  * @member {Object[]} store=MainStore
31
38
  */
32
- store: MainStore,
33
- /**
34
- * @member {Object} viewConfig
35
- */
36
- viewConfig: {
37
- bufferColumnRange: 3,
38
- bufferRowRange : 5
39
- }
39
+ store: MainStore
40
40
  }
41
41
 
42
42
  /**
@@ -114,6 +114,10 @@ class MainContainer extends ConfigurationViewport {
114
114
  store : MainStore,
115
115
  wrapperStyle: {maxWidth: '1002px'},
116
116
 
117
+ bodyConfig: {
118
+ selectionModel: CellModel
119
+ },
120
+
117
121
  columnDefaults: {
118
122
  editable: true,
119
123
  width : 200
@@ -160,11 +164,7 @@ class MainContainer extends ConfigurationViewport {
160
164
  dataField: 'githubId',
161
165
  editable : false,
162
166
  text : 'Github Id (Non-editable)'
163
- }],
164
-
165
- viewConfig: {
166
- selectionModel: CellModel
167
- }
167
+ }]
168
168
  }
169
169
  }
170
170
 
@@ -88,6 +88,10 @@ class MainContainer extends ConfigurationViewport {
88
88
  width: 200
89
89
  },
90
90
 
91
+ bodyConfig: {
92
+ selectionModel: CellModel
93
+ },
94
+
91
95
  columns: [
92
96
  {dataField: 'firstname', text: 'Firstname'},
93
97
  {dataField: 'lastname', text: 'Lastname'},
@@ -95,10 +99,6 @@ class MainContainer extends ConfigurationViewport {
95
99
  {dataField: 'country', text: 'Country'}
96
100
  ],
97
101
 
98
- viewConfig: {
99
- selectionModel: CellModel
100
- },
101
-
102
102
  wrapperStyle: {
103
103
  height: '250px'
104
104
  }
@@ -51,6 +51,10 @@ class Viewport extends BaseViewport {
51
51
  bind : {store: 'stores.mainStore'},
52
52
  reference: 'grid',
53
53
 
54
+ bodyConfig: {
55
+ highlightModifiedCells: true
56
+ },
57
+
54
58
  columnDefaults: {
55
59
  width: 200
56
60
  },
@@ -66,11 +70,7 @@ class Viewport extends BaseViewport {
66
70
  handler: 'editButtonHandler',
67
71
  text : 'Edit'
68
72
  }}
69
- ],
70
-
71
- viewConfig: {
72
- highlightModifiedCells: true
73
- }
73
+ ]
74
74
  }]
75
75
  }
76
76
  }
@@ -14,6 +14,15 @@ using Web Workers.
14
14
 
15
15
  ## Bootstrap Sequence
16
16
 
17
+ ```
18
+ myapp/
19
+ ├── view/
20
+ │ └── Viewport.mjs // The app main view
21
+ ├── app.mjs // The entry-point for your code inside the app worker
22
+ ├── index.html // The entry-point for a main-thread
23
+ └── neo-config.json // Framework global configs for your app
24
+ ```
25
+
17
26
  ### 1. Entry Point: index.html
18
27
 
19
28
  The bootstrap process begins with a minimal HTML file:
@@ -66,7 +75,7 @@ of all available configuration options, you can refer to the `src/DefaultConfig.
66
75
  "basePath" : "../../",
67
76
  "environment" : "development",
68
77
  "mainPath" : "./Main.mjs",
69
- "mainThreadAddons": ["Stylesheet"],
78
+ "mainThreadAddons": ["DragDrop", "Navigator", "Stylesheet"],
70
79
  "themes" : ["neo-theme-light"],
71
80
  "useCanvasWorker" : false,
72
81
  "useDataWorker" : false,
@@ -149,12 +158,10 @@ The Main class:
149
158
  3. Listens for the 'domContentLoaded' event
150
159
  4. When the DOM is loaded, it loads any main thread addons and notifies the WorkerManager
151
160
 
152
- ### 5. Worker Manager: Creating Workers
153
-
154
- The `WorkerManager` is responsible for creating and managing the workers:
161
+ ### 5. Neo.worker.Manager: Creating Workers
155
162
 
156
163
  ```javascript
157
- class Manager extends Base {
164
+ class Manager extends core.Base {
158
165
  // ...
159
166
 
160
167
  createWorkers() {
@@ -198,24 +205,20 @@ class Manager extends Base {
198
205
  if (me.constructedThreads === me.activeWorkers) {
199
206
  // All workers are constructed, load the application
200
207
  NeoConfig.appPath && me.timeout(NeoConfig.loadApplicationDelay).then(() => {
201
- me.loadApplication(NeoConfig.appPath)
208
+ me.loadApplication()
202
209
  })
203
210
  }
204
211
  }
205
212
 
206
- loadApplication(path) {
207
- this.sendMessage('app', {
208
- action : 'loadApplication',
209
- path,
210
- resourcesPath: NeoConfig.resourcesPath
211
- })
213
+ loadApplication() {
214
+ this.sendMessage('app', {action: 'loadApplication' })
212
215
  }
213
216
 
214
217
  // ...
215
218
  }
216
219
  ```
217
220
 
218
- The WorkerManager:
221
+ `Neo.worker.Manager`:
219
222
  1. Detects browser features (Web Workers, SharedWorkers)
220
223
  2. Creates workers for App, VDom, Data, etc. based on configuration
221
224
  3. Sends the Neo.config to each worker
@@ -262,12 +265,7 @@ class App extends Base {
262
265
  path = path.slice(0, -4)
263
266
  }
264
267
 
265
- return import(
266
- /* webpackInclude: /(?:\/|\\)app.mjs$/ */
267
- /* webpackExclude: /(?:\/|\\)(dist|node_modules)/ */
268
- /* webpackMode: "lazy" */
269
- `../../${path}.mjs`
270
- )
268
+ return import(`../../${path}.mjs`)
271
269
  }
272
270
 
273
271
  // ...
@@ -285,7 +283,7 @@ The App worker:
285
283
  Finally, the application's `app.mjs` file is loaded and executed:
286
284
 
287
285
  ```javascript
288
- import Overwrites from './Overwrites.mjs'; // Optional framework extensions
286
+ import Overwrites from './Overwrites.mjs'; // Optional class config default value changes for framework classes
289
287
  import Viewport from './view/Viewport.mjs'; // Your main UI component
290
288
 
291
289
  export const onStart = () => Neo.app({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name" : "neo.mjs",
3
- "version" : "10.0.0-alpha.4",
3
+ "version" : "10.0.0-alpha.5",
4
4
  "description" : "Neo.mjs: The multi-threaded UI framework for building ultra-fast, desktop-like web applications with uncompromised responsiveness, inherent security, and a transpilation-free dev mode.",
5
5
  "type" : "module",
6
6
  "repository" : {
@@ -1,4 +1,4 @@
1
- .neo-grid-view-wrapper {
1
+ .neo-grid-body-wrapper {
2
2
  height : 100%;
3
3
  overflow-anchor: none;
4
4
  overflow-x : hidden;
@@ -11,7 +11,7 @@
11
11
  }
12
12
  }
13
13
 
14
- .neo-grid-view {
14
+ .neo-grid-body {
15
15
  height : 100%;
16
16
  overflow-x: visible;
17
17
 
@@ -14,7 +14,7 @@
14
14
  }
15
15
  }
16
16
 
17
- .neo-grid-wrapper:has(.neo-grid-view.neo-is-scrolling) {
17
+ .neo-grid-wrapper:has(.neo-grid-body.neo-is-scrolling) {
18
18
  .neo-grid-vertical-scrollbar {
19
19
  opacity: 1;
20
20
  }
@@ -1,4 +1,4 @@
1
- .neo-grid-view {
1
+ .neo-grid-body {
2
2
  &.neo-animate-rows {
3
3
  .neo-grid-row {
4
4
  transition:
@@ -1,4 +1,4 @@
1
- .neo-grid-view {
1
+ .neo-grid-body {
2
2
  .neo-grid-cell {
3
3
  &:has(.neo-grid-editor) {
4
4
  padding: 1px 4px 2px;
@@ -1,4 +1,4 @@
1
- :root .neo-theme-dark { // .neo-grid-view
1
+ :root .neo-theme-dark { // .neo-grid-body
2
2
  --grid-cell-background-color-hover : #54595c;
3
3
  --grid-cell-ismodified-color : orange;
4
4
  --grid-cell-ismodified-size : 10px;
@@ -1,6 +1,6 @@
1
1
  @use "sass:color";
2
2
 
3
- :root .neo-theme-light { // .neo-grid-view
3
+ :root .neo-theme-light { // .neo-grid-body
4
4
  --grid-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
5
5
  --grid-cell-ismodified-color : orange;
6
6
  --grid-cell-ismodified-size : 10px;
@@ -1,6 +1,6 @@
1
1
  @use "sass:color";
2
2
 
3
- :root .neo-theme-neo-light { // .neo-grid-view
3
+ :root .neo-theme-neo-light { // .neo-grid-body
4
4
  --grid-cell-background-color-hover : #{color.adjust(#33343d, $lightness: 70%)};
5
5
  --grid-cell-ismodified-color : orange;
6
6
  --grid-cell-ismodified-size : 10px;
@@ -289,12 +289,12 @@ const DefaultConfig = {
289
289
  useVdomWorker: true,
290
290
  /**
291
291
  * buildScripts/injectPackageVersion.mjs will update this value
292
- * @default '10.0.0-alpha.4'
292
+ * @default '10.0.0-alpha.5'
293
293
  * @memberOf! module:Neo
294
294
  * @name config.version
295
295
  * @type String
296
296
  */
297
- version: '10.0.0-alpha.4'
297
+ version: '10.0.0-alpha.5'
298
298
  };
299
299
 
300
300
  Object.assign(DefaultConfig, {
@@ -6,21 +6,21 @@ import RowModel from '../selection/grid/RowModel.mjs';
6
6
  import VDomUtil from '../util/VDom.mjs';
7
7
 
8
8
  /**
9
- * @class Neo.grid.View
9
+ * @class Neo.grid.Body
10
10
  * @extends Neo.component.Base
11
11
  */
12
- class GridView extends Component {
12
+ class GridBody extends Component {
13
13
  static config = {
14
14
  /**
15
- * @member {String} className='Neo.grid.View'
15
+ * @member {String} className='Neo.grid.Body'
16
16
  * @protected
17
17
  */
18
- className: 'Neo.grid.View',
18
+ className: 'Neo.grid.Body',
19
19
  /**
20
- * @member {String} ntype='grid-view'
20
+ * @member {String} ntype='grid-body'
21
21
  * @protected
22
22
  */
23
- ntype: 'grid-view',
23
+ ntype: 'grid-body',
24
24
  /**
25
25
  * @member {Boolean} animatedRowSorting_=false
26
26
  */
@@ -36,23 +36,23 @@ class GridView extends Component {
36
36
  */
37
37
  availableRows_: 0,
38
38
  /**
39
- * Internal flag. Gets calculated after mounting grid.View rows
39
+ * Internal flag. Gets calculated after mounting grid.Body rows
40
40
  * @member {Number} availableWidth_=0
41
41
  */
42
42
  availableWidth_: 0,
43
43
  /**
44
- * @member {String[]} baseCls=['neo-grid-view']
44
+ * @member {String[]} baseCls=['neo-grid-body']
45
45
  * @protected
46
46
  */
47
- baseCls: ['neo-grid-view'],
47
+ baseCls: ['neo-grid-body'],
48
48
  /**
49
- * The amount of columns (cells) to paint before the first & after the last visible column,
49
+ * The number of columns (cells) to paint before the first and after the last visible column,
50
50
  * to enhance the scrolling performance
51
51
  * @member {Number} bufferColumnRange_=0
52
52
  */
53
53
  bufferColumnRange_: 0,
54
54
  /**
55
- * The amount of rows to paint before the first & after the last visible row,
55
+ * The number of rows to paint before the first and after the last visible row,
56
56
  * to enhance the scrolling performance
57
57
  * @member {Number} bufferRowRange_=3
58
58
  */
@@ -63,7 +63,7 @@ class GridView extends Component {
63
63
  */
64
64
  colspanField: 'colspan',
65
65
  /**
66
- * Internal flag. Gets calculated after mounting grid.View rows
66
+ * Internal flag. Gets calculated after mounting grid.Body rows
67
67
  * @member {Number} containerWidth_=0
68
68
  */
69
69
  containerWidth_: 0,
@@ -150,9 +150,9 @@ class GridView extends Component {
150
150
  */
151
151
  visibleRows: [0, 0],
152
152
  /**
153
- * @member {String[]} wrapperCls=[]
153
+ * @member {String[]} wrapperCls=['neo-grid-body-wrapper']
154
154
  */
155
- wrapperCls: ['neo-grid-view-wrapper'],
155
+ wrapperCls: ['neo-grid-body-wrapper'],
156
156
  /**
157
157
  * @member {Object} _vdom
158
158
  */
@@ -686,7 +686,7 @@ class GridView extends Component {
686
686
  dataField = me.getCellDataField(id),
687
687
  record = me.getRecord(id);
688
688
 
689
- me.parent.fire(eventName, {data, dataField, record, view: me})
689
+ me.parent.fire(eventName, {body: me, data, dataField, record})
690
690
  }
691
691
 
692
692
  /**
@@ -698,7 +698,7 @@ class GridView extends Component {
698
698
  id = data.currentTarget,
699
699
  record = me.getRecord(id);
700
700
 
701
- me.parent.fire(eventName, {data, record, view: me})
701
+ me.parent.fire(eventName, {body: me, data, record})
702
702
  }
703
703
 
704
704
  /**
@@ -1133,4 +1133,4 @@ class GridView extends Component {
1133
1133
  }
1134
1134
  }
1135
1135
 
1136
- export default Neo.setupClass(GridView);
1136
+ export default Neo.setupClass(GridBody);
@@ -1,7 +1,7 @@
1
1
  import BaseContainer from '../container/Base.mjs';
2
2
  import ClassSystemUtil from '../util/ClassSystem.mjs';
3
3
  import Collection from '../collection/Base.mjs';
4
- import GridView from './View.mjs';
4
+ import GridBody from './Body.mjs';
5
5
  import ScrollManager from './ScrollManager.mjs';
6
6
  import Store from '../data/Store.mjs';
7
7
  import VerticalScrollbar from './VerticalScrollbar.mjs';
@@ -52,6 +52,16 @@ class GridContainer extends BaseContainer {
52
52
  * @protected
53
53
  */
54
54
  baseCls: ['neo-grid-container'],
55
+ /**
56
+ * Configs for Neo.grid.Body
57
+ * @member {Object|null} [bodyConfig=null]
58
+ */
59
+ bodyConfig: null,
60
+ /**
61
+ * @member {String|null} bodyId_=null
62
+ * @protected
63
+ */
64
+ bodyId_: null,
55
65
  /**
56
66
  * true uses grid.plugin.CellEditing
57
67
  * @member {Boolean} cellEditing_=false
@@ -105,16 +115,6 @@ class GridContainer extends BaseContainer {
105
115
  * @member {Neo.data.Store} store_=null
106
116
  */
107
117
  store_: null,
108
- /**
109
- * Configs for Neo.grid.View
110
- * @member {Object|null} [viewConfig=null]
111
- */
112
- viewConfig: null,
113
- /**
114
- * @member {String|null} viewId_=null
115
- * @protected
116
- */
117
- viewId_: null,
118
118
  /**
119
119
  * @member {Array|null} items=null
120
120
  * @protected
@@ -142,19 +142,19 @@ class GridContainer extends BaseContainer {
142
142
  scrollManager = null
143
143
 
144
144
  /**
145
- * Convenience method to access the Neo.grid.header.Toolbar
146
- * @returns {Neo.grid.header.Toolbar|null}
145
+ * Convenience method to access the Neo.grid.Body
146
+ * @returns {Neo.grid.Body|null}
147
147
  */
148
- get headerToolbar() {
149
- return Neo.getComponent(this.headerToolbarId) || Neo.get(this.headerToolbarId)
148
+ get body() {
149
+ return Neo.getComponent(this.bodyId) || Neo.get(this.bodyId)
150
150
  }
151
151
 
152
152
  /**
153
- * Convenience method to access the Neo.grid.View
154
- * @returns {Neo.grid.View|null}
153
+ * Convenience method to access the Neo.grid.header.Toolbar
154
+ * @returns {Neo.grid.header.Toolbar|null}
155
155
  */
156
- get view() {
157
- return Neo.getComponent(this.viewId) || Neo.get(this.viewId)
156
+ get headerToolbar() {
157
+ return Neo.getComponent(this.headerToolbarId) || Neo.get(this.headerToolbarId)
158
158
  }
159
159
 
160
160
  /**
@@ -166,8 +166,8 @@ class GridContainer extends BaseContainer {
166
166
  let me = this,
167
167
  {appName, rowHeight, store, windowId} = me;
168
168
 
169
+ me.bodyId = Neo.getId('grid-body');
169
170
  me.headerToolbarId = Neo.getId('grid-header-toolbar');
170
- me.viewId = Neo.getId('grid-view');
171
171
 
172
172
  me.items = [{
173
173
  module : header.Toolbar,
@@ -176,13 +176,13 @@ class GridContainer extends BaseContainer {
176
176
  sortable : me.sortable,
177
177
  ...me.headerToolbarConfig
178
178
  }, {
179
- module : GridView,
179
+ module : GridBody,
180
180
  flex : 1,
181
181
  gridContainer: me,
182
- id : me.viewId,
182
+ id : me.bodyId,
183
183
  rowHeight,
184
184
  store,
185
- ...me.viewConfig
185
+ ...me.bodyConfig
186
186
  }];
187
187
 
188
188
  me.scrollbar = Neo.create({
@@ -218,7 +218,7 @@ class GridContainer extends BaseContainer {
218
218
 
219
219
  if (mounted) {
220
220
  ResizeObserver.register(resizeParams);
221
- await me.passSizeToView()
221
+ await me.passSizeToBody()
222
222
  } else {
223
223
  me.initialResizeEvent = true;
224
224
  ResizeObserver.unregister(resizeParams)
@@ -262,9 +262,9 @@ class GridContainer extends BaseContainer {
262
262
 
263
263
  await me.timeout(50);
264
264
 
265
- await me.passSizeToView();
265
+ await me.passSizeToBody();
266
266
 
267
- me.view?.createViewData()
267
+ me.body?.createViewData()
268
268
  }
269
269
  }
270
270
 
@@ -287,14 +287,14 @@ class GridContainer extends BaseContainer {
287
287
  */
288
288
  afterSetRowHeight(value, oldValue) {
289
289
  if (value > 0) {
290
- let {scrollbar, view} = this;
290
+ let {body, scrollbar} = this;
291
291
 
292
292
  if (scrollbar) {
293
293
  scrollbar.rowHeight = value
294
294
  }
295
295
 
296
- if (view) {
297
- view.rowHeight = value
296
+ if (body) {
297
+ body.rowHeight = value
298
298
  }
299
299
  }
300
300
  }
@@ -340,12 +340,22 @@ class GridContainer extends BaseContainer {
340
340
  value ?.on(listeners);
341
341
  oldValue?.un(listeners);
342
342
 
343
- // in case we dynamically change the store, the view needs to get the new reference
344
- if (me.view) {
345
- me.view.store = value
343
+ // in case we dynamically change the store, grid.Body needs to get the new reference
344
+ if (me.body) {
345
+ me.body.store = value
346
346
  }
347
347
  }
348
348
 
349
+ /**
350
+ * Triggered before the bodyId config gets changed.
351
+ * @param {String} value
352
+ * @param {String} oldValue
353
+ * @protected
354
+ */
355
+ beforeSetBodyId(value, oldValue) {
356
+ return value || oldValue
357
+ }
358
+
349
359
  /**
350
360
  * Triggered before the columns config gets changed.
351
361
  * @param {Object[]} value
@@ -384,16 +394,6 @@ class GridContainer extends BaseContainer {
384
394
  return value
385
395
  }
386
396
 
387
- /**
388
- * Triggered before the viewId config gets changed.
389
- * @param {String} value
390
- * @param {String} oldValue
391
- * @protected
392
- */
393
- beforeSetViewId(value, oldValue) {
394
- return value || oldValue
395
- }
396
-
397
397
  /**
398
398
  * In case you want to update multiple existing records in parallel,
399
399
  * using this method is faster than updating each record one by one.
@@ -401,19 +401,19 @@ class GridContainer extends BaseContainer {
401
401
  * @param {Object[]} records
402
402
  */
403
403
  bulkUpdateRecords(records) {
404
- let {store, view} = this,
404
+ let {body, store} = this,
405
405
  {keyProperty} = store;
406
406
 
407
- if (view) {
408
- view.silentVdomUpdate = true;
407
+ if (body) {
408
+ body.silentVdomUpdate = true;
409
409
 
410
410
  records.forEach(item => {
411
411
  store.get(item[keyProperty])?.set(item)
412
412
  });
413
413
 
414
- view.silentVdomUpdate = false;
414
+ body.silentVdomUpdate = false;
415
415
 
416
- view.update()
416
+ body.update()
417
417
  }
418
418
  }
419
419
 
@@ -527,9 +527,9 @@ class GridContainer extends BaseContainer {
527
527
  let me = this;
528
528
 
529
529
  me.scrollManager = Neo.create({
530
+ gridBody : me.body,
530
531
  module : ScrollManager,
531
- gridContainer: me,
532
- gridView : me.view
532
+ gridContainer: me
533
533
  })
534
534
  }
535
535
 
@@ -540,11 +540,11 @@ class GridContainer extends BaseContainer {
540
540
  let me = this;
541
541
 
542
542
  if (!me.initialResizeEvent) {
543
- await me.passSizeToView(true);
543
+ await me.passSizeToBody(true);
544
544
 
545
- me.view.updateMountedAndVisibleColumns();
545
+ me.body.updateMountedAndVisibleColumns();
546
546
 
547
- await me.headerToolbar.passSizeToView()
547
+ await me.headerToolbar.passSizeToBody()
548
548
  } else {
549
549
  me.initialResizeEvent = false
550
550
  }
@@ -561,7 +561,7 @@ class GridContainer extends BaseContainer {
561
561
 
562
562
  me.store.sort(opts);
563
563
  me.removeSortingCss(opts.property);
564
- opts.direction && me.view.onStoreLoad()
564
+ opts.direction && me.body.onStoreLoad()
565
565
  }
566
566
 
567
567
  /**
@@ -589,16 +589,16 @@ class GridContainer extends BaseContainer {
589
589
  * @param {Boolean} silent=false
590
590
  * @returns {Promise<void>}
591
591
  */
592
- async passSizeToView(silent=false) {
592
+ async passSizeToBody(silent=false) {
593
593
  let me = this,
594
594
  [containerRect, headerRect] = await me.getDomRect([me.id, me.headerToolbarId]);
595
595
 
596
596
  // delay for slow connections, where the container-sizing is not done yet
597
597
  if (containerRect.height === headerRect.height) {
598
598
  await me.timeout(100);
599
- await me.passSizeToView(silent)
599
+ await me.passSizeToBody(silent)
600
600
  } else {
601
- me.view[silent ? 'setSilent' : 'set']({
601
+ me.body[silent ? 'setSilent' : 'set']({
602
602
  availableHeight: containerRect.height - headerRect.height,
603
603
  containerWidth : containerRect.width
604
604
  })
@@ -624,8 +624,8 @@ class GridContainer extends BaseContainer {
624
624
  */
625
625
  scrollByColumns(index, step) {
626
626
  let me = this,
627
- {view} = me,
628
- {columnPositions, containerWidth, mountedColumns, visibleColumns} = view,
627
+ {body} = me,
628
+ {columnPositions, containerWidth, mountedColumns, visibleColumns} = body,
629
629
  countColumns = columnPositions.getCount(),
630
630
  newIndex = index + step,
631
631
  column, mounted, scrollLeft, visible;
@@ -24,15 +24,15 @@ class ScrollManager extends Base {
24
24
  }
25
25
 
26
26
  /**
27
- * @member {Neo.grid.Container|null} gridContainer=null
27
+ * @member {Neo.grid.Body|null} gridBody=null
28
28
  * @protected
29
29
  */
30
- gridContainer = null
30
+ gridBody = null
31
31
  /**
32
- * @member {Neo.grid.View|null} gridView=null
32
+ * @member {Neo.grid.Container|null} gridContainer=null
33
33
  * @protected
34
34
  */
35
- gridView = null
35
+ gridContainer = null
36
36
  /**
37
37
  * Storing touchmove position for mobile envs
38
38
  * @member {Number} lastTouchX=0
@@ -52,7 +52,7 @@ class ScrollManager extends Base {
52
52
  scrollTimeoutId = null
53
53
  /**
54
54
  * Flag for identifying the ownership of a touchmove operation
55
- * @member {'container'|'view'|null} touchMoveOwner=null
55
+ * @member {'body'|'container'|null} touchMoveOwner=null
56
56
  * @protected
57
57
  */
58
58
  touchMoveOwner = null
@@ -65,19 +65,59 @@ class ScrollManager extends Base {
65
65
 
66
66
  let me = this;
67
67
 
68
- me.gridContainer.addDomListeners({
69
- scroll: me.onContainerScroll,
70
- scope : me
71
- });
72
-
73
- me.gridView.addDomListeners({
74
- scroll : me.onViewScroll,
68
+ me.gridBody.addDomListeners({
69
+ scroll : me.onBodyScroll,
75
70
  touchcancel: me.onTouchCancel,
76
71
  touchend : me.onTouchEnd,
77
72
  scope : me
73
+ });
74
+
75
+ me.gridContainer.addDomListeners({
76
+ scroll: me.onContainerScroll,
77
+ scope : me
78
78
  })
79
79
  }
80
80
 
81
+ /**
82
+ * Only triggers for vertical scrolling
83
+ * @param {Object} data
84
+ * @protected
85
+ */
86
+ onBodyScroll({scrollTop, touches}) {
87
+ let me = this,
88
+ body = me.gridBody,
89
+ deltaX, lastTouchX;
90
+
91
+ me.scrollTop = scrollTop;
92
+
93
+ me.scrollTimeoutId && clearTimeout(me.scrollTimeoutId);
94
+
95
+ me.scrollTimeoutId = setTimeout(() => {
96
+ body.isScrolling = false
97
+ }, 100);
98
+
99
+ body.set({isScrolling: true, scrollTop});
100
+
101
+ if (touches) {
102
+ if (me.touchMoveOwner !== 'container') {
103
+ me.touchMoveOwner = 'body'
104
+ }
105
+
106
+ if (me.touchMoveOwner === 'body') {
107
+ lastTouchX = touches.lastTouch.clientX - touches.firstTouch.clientX;
108
+ deltaX = me.lastTouchX - lastTouchX;
109
+
110
+ deltaX !== 0 && Neo.main.DomAccess.scrollTo({
111
+ direction: 'left',
112
+ id : me.gridContainer.id,
113
+ value : me.scrollLeft + deltaX
114
+ })
115
+
116
+ me.lastTouchX = lastTouchX
117
+ }
118
+ }
119
+ }
120
+
81
121
  /**
82
122
  * @param {Object} data
83
123
  * @param {Number} data.scrollLeft
@@ -86,18 +126,18 @@ class ScrollManager extends Base {
86
126
  */
87
127
  onContainerScroll({scrollLeft, target, touches}) {
88
128
  let me = this,
89
- view = me.gridView,
129
+ body = me.gridBody,
90
130
  deltaY, lastTouchY;
91
131
 
92
132
  // We must ignore events for grid-scrollbar
93
133
  if (target.id.includes('grid-container')) {
94
134
  me .scrollLeft = scrollLeft;
95
- view.scrollLeft = scrollLeft;
135
+ body.scrollLeft = scrollLeft;
96
136
 
97
137
  me.gridContainer.headerToolbar.scrollLeft = scrollLeft;
98
138
 
99
139
  if (touches && !me.gridContainer.headerToolbar.cls.includes('neo-is-dragging')) {
100
- if (me.touchMoveOwner !== 'view') {
140
+ if (me.touchMoveOwner !== 'body') {
101
141
  me.touchMoveOwner = 'container'
102
142
  }
103
143
 
@@ -107,7 +147,7 @@ class ScrollManager extends Base {
107
147
 
108
148
  deltaY !== 0 && Neo.main.DomAccess.scrollTo({
109
149
  direction: 'top',
110
- id : view.vdom.id,
150
+ id : body.vdom.id,
111
151
  value : me.scrollTop + deltaY
112
152
  })
113
153
 
@@ -134,46 +174,6 @@ class ScrollManager extends Base {
134
174
  me.lastTouchX = 0;
135
175
  me.lastTouchY = 0
136
176
  }
137
-
138
- /**
139
- * Only triggers for vertical scrolling
140
- * @param {Object} data
141
- * @protected
142
- */
143
- onViewScroll({scrollTop, touches}) {
144
- let me = this,
145
- view = me.gridView,
146
- deltaX, lastTouchX;
147
-
148
- me.scrollTop = scrollTop;
149
-
150
- me.scrollTimeoutId && clearTimeout(me.scrollTimeoutId);
151
-
152
- me.scrollTimeoutId = setTimeout(() => {
153
- view.isScrolling = false
154
- }, 100);
155
-
156
- view.set({isScrolling: true, scrollTop});
157
-
158
- if (touches) {
159
- if (me.touchMoveOwner !== 'container') {
160
- me.touchMoveOwner = 'view'
161
- }
162
-
163
- if (me.touchMoveOwner === 'view') {
164
- lastTouchX = touches.lastTouch.clientX - touches.firstTouch.clientX;
165
- deltaX = me.lastTouchX - lastTouchX;
166
-
167
- deltaX !== 0 && Neo.main.DomAccess.scrollTo({
168
- direction: 'left',
169
- id : me.gridContainer.id,
170
- value : me.scrollLeft + deltaX
171
- })
172
-
173
- me.lastTouchX = lastTouchX
174
- }
175
- }
176
- }
177
177
  }
178
178
 
179
179
  export default Neo.setupClass(ScrollManager);
@@ -53,9 +53,9 @@ class VerticalScrollbar extends Component {
53
53
 
54
54
  if (mounted) {
55
55
  ScrollSync.register({
56
- fromId: me.parent.view.vdom.id,
56
+ fromId: me.parent.body.vdom.id,
57
57
  toId : me.id,
58
- twoWay: !Neo.config.hasTouchEvents, // Syncing the scroller back to the view affects mobile scrolling
58
+ twoWay: !Neo.config.hasTouchEvents, // Syncing the scroller back to the body affects mobile scrolling
59
59
  ...params
60
60
  })
61
61
  } else {
@@ -1,5 +1,5 @@
1
1
  import * as header from './header/_export.mjs';
2
+ import Body from './Body.mjs';
2
3
  import Container from './Container.mjs';
3
- import View from './View.mjs';
4
4
 
5
- export {header, Container, View};
5
+ export {Body, header, Container};
@@ -55,7 +55,7 @@ class AnimatedChange extends Column {
55
55
  */
56
56
  async onRecordChange({fields, record}) {
57
57
  let me = this,
58
- {view} = me.parent,
58
+ {body} = me.parent,
59
59
  cellId, field, node;
60
60
 
61
61
  for (field of fields) {
@@ -63,16 +63,16 @@ class AnimatedChange extends Column {
63
63
  // Wait for the next animation frame
64
64
  await me.timeout(20);
65
65
 
66
- cellId = view.getCellId(me.parent.store.indexOf(record), me.dataField);
67
- node = VdomUtil.find(view.vdom, cellId)?.vdom;
66
+ cellId = body.getCellId(me.parent.store.indexOf(record), me.dataField);
67
+ node = VdomUtil.find(body.vdom, cellId)?.vdom;
68
68
 
69
69
  if (node) {
70
70
  NeoArray.add(node.cls, me.getAnimationCls(record));
71
71
 
72
- // This will trigger a 2nd view update, after grid.View: onStoreRecordChange()
72
+ // This will trigger a 2nd body update, after grid.Body: onStoreRecordChange()
73
73
  // It is crucial to restart the keyframe based animation
74
74
  // => The previous update call will remove the last animationCls
75
- view.update()
75
+ body.update()
76
76
  }
77
77
 
78
78
  break
@@ -26,7 +26,7 @@ class Column extends Base {
26
26
  renderer_: 'cellRenderer',
27
27
  /**
28
28
  * Scope to execute the column renderer.
29
- * Defaults to the grid.View.
29
+ * Defaults to the grid.Body.
30
30
  * You can pass the strings 'this' or 'me'
31
31
  * @member {Neo.core.Base|String|null} rendererScope=null
32
32
  */
@@ -76,7 +76,7 @@ class Component extends Column {
76
76
  */
77
77
  cellRenderer(data) {
78
78
  let {gridContainer, record, rowIndex} = data,
79
- {appName, view, windowId} = gridContainer,
79
+ {appName, body, windowId} = gridContainer,
80
80
  me = this,
81
81
  {recordProperty} = me,
82
82
  id = me.getComponentId(rowIndex),
@@ -104,7 +104,7 @@ class Component extends Column {
104
104
  ...componentConfig,
105
105
  appName,
106
106
  id,
107
- parentComponent : view,
107
+ parentComponent : body,
108
108
  [recordProperty]: record,
109
109
  windowId
110
110
  });
@@ -118,10 +118,10 @@ class Component extends Column {
118
118
  }
119
119
 
120
120
  if (me.useBindings) {
121
- view.getStateProvider()?.parseConfig(component)
121
+ body.getStateProvider()?.parseConfig(component)
122
122
  }
123
123
 
124
- view.updateDepth = -1;
124
+ body.updateDepth = -1;
125
125
 
126
126
  return component.createVdomReference()
127
127
  }
@@ -132,9 +132,9 @@ class Component extends Column {
132
132
  */
133
133
  getComponentId(rowIndex) {
134
134
  let me = this,
135
- {view} = me.parent;
135
+ {body} = me.parent;
136
136
 
137
- return `${me.id}-component-${rowIndex % (view.availableRows + 2 * view.bufferRowRange)}`
137
+ return `${me.id}-component-${rowIndex % (body.availableRows + 2 * body.bufferRowRange)}`
138
138
  }
139
139
  }
140
140
 
@@ -89,7 +89,7 @@ class Toolbar extends BaseToolbar {
89
89
  */
90
90
  afterSetMounted(value, oldValue) {
91
91
  super.afterSetMounted(value, oldValue);
92
- value && this.passSizeToView()
92
+ value && this.passSizeToBody()
93
93
  }
94
94
 
95
95
  /**
@@ -181,7 +181,7 @@ class Toolbar extends BaseToolbar {
181
181
 
182
182
  me.promiseUpdate().then(() => {
183
183
  // To prevent duplicate calls, we need to check the mounted state before the update call
184
- mounted && me.passSizeToView()
184
+ mounted && me.passSizeToBody()
185
185
  })
186
186
  }
187
187
 
@@ -203,10 +203,10 @@ class Toolbar extends BaseToolbar {
203
203
  * @param {Boolean} silent=false
204
204
  * @returns {Promise<void>}
205
205
  */
206
- async passSizeToView(silent=false) {
206
+ async passSizeToBody(silent=false) {
207
207
  let me = this,
208
208
  {items} = me,
209
- {view} = me.parent,
209
+ {body} = me.parent,
210
210
  rects = await me.getDomRect(items.map(item => item.id)),
211
211
  lastItem = rects[rects.length - 1],
212
212
  columnPositions = rects.map((item, index) => ({dataField: items[index].dataField, width: item.width, x: item.x - rects[0].x})),
@@ -225,16 +225,16 @@ class Toolbar extends BaseToolbar {
225
225
  // Delay for slow connections, where the container-sizing is not done yet
226
226
  if (!layoutFinished) {
227
227
  await me.timeout(100);
228
- await me.passSizeToView(silent)
228
+ await me.passSizeToBody(silent)
229
229
  } else {
230
- view.columnPositions.clear();
231
- view.columnPositions.add(columnPositions);
230
+ body.columnPositions.clear();
231
+ body.columnPositions.add(columnPositions);
232
232
 
233
- view[silent ? 'setSilent' : 'set']({
233
+ body[silent ? 'setSilent' : 'set']({
234
234
  availableWidth: lastItem.x + lastItem.width - rects[0].x
235
235
  });
236
236
 
237
- !silent && view.updateMountedAndVisibleColumns()
237
+ !silent && body.updateMountedAndVisibleColumns()
238
238
  }
239
239
  }
240
240
 
@@ -1,5 +1,4 @@
1
1
  import Base from '../../plugin/Base.mjs';
2
- import CssUtil from '../../util/Css.mjs';
3
2
  import NeoArray from '../../util/Array.mjs';
4
3
 
5
4
  /**
@@ -151,7 +150,7 @@ class AnimateRows extends Base {
151
150
 
152
151
  for (rowIndex=mountedRows[0]; rowIndex < mountedRows[1]; rowIndex++) {
153
152
  record = owner.store.getAt(rowIndex);
154
- id = owner.getRowId(record, rowIndex)
153
+ id = owner.getRowId(rowIndex)
155
154
  mapItem = map[id];
156
155
 
157
156
  if (mapItem) {
@@ -36,19 +36,15 @@ class Style extends Base {
36
36
  return null
37
37
  } else if (!oldStyle) {
38
38
  return Neo.clone(newStyle)
39
- } else if (!newStyle) {
40
- Object.keys(oldStyle).forEach(function(style) {
41
- styles[style] = null
42
- });
43
39
  } else {
44
- Object.keys(newStyle).forEach(style => {
40
+ newStyle && Object.keys(newStyle).forEach(style => {
45
41
  if (!oldStyle.hasOwnProperty(style) || oldStyle[style] !== newStyle[style]) {
46
42
  styles[style] = newStyle[style]
47
43
  }
48
44
  });
49
45
 
50
46
  Object.keys(oldStyle).forEach(style => {
51
- if (!newStyle.hasOwnProperty(style)) {
47
+ if (!newStyle || !newStyle.hasOwnProperty(style)) {
52
48
  styles[style] = null
53
49
  }
54
50
  });
@@ -107,7 +107,7 @@ class Helper extends Base {
107
107
  Object.entries(value).forEach(([key, value]) => {
108
108
  const
109
109
  oldValue = oldVnode.attributes[key],
110
- hasOldValue = Object.hasOwn(oldVnode.attributes, 'key');
110
+ hasOldValue = Object.hasOwn(oldVnode.attributes, key);
111
111
 
112
112
  // If the attribute has an old value AND the value hasn't changed, skip.
113
113
  if (hasOldValue && oldValue === value) {
@@ -46,11 +46,6 @@ class App extends Base {
46
46
  singleton: true
47
47
  }
48
48
 
49
- /**
50
- * @member {Object|null} data=null
51
- * @protected
52
- */
53
- data = null
54
49
  /**
55
50
  * @member {Boolean} isUsingStateProviders=false
56
51
  * @protected
@@ -388,23 +383,16 @@ class App extends Base {
388
383
  * @param {Object} data
389
384
  */
390
385
  onLoadApplication(data) {
391
- let me = this,
392
- {config} = Neo,
393
- app, path;
394
-
395
- if (data) {
396
- me.data = data;
397
- config.resourcesPath = data.resourcesPath
398
- }
399
-
400
- path = me.data.path;
386
+ let me = this,
387
+ {config} = Neo,
388
+ {appPath} = config;
401
389
 
402
390
  if (config.environment !== 'development') {
403
- path = path.startsWith('/') ? path.substring(1) : path
391
+ appPath = appPath.startsWith('/') ? appPath.substring(1) : appPath
404
392
  }
405
393
 
406
- me.importApp(path).then(module => {
407
- app = module.onStart();
394
+ me.importApp(appPath).then(module => {
395
+ module.onStart();
408
396
 
409
397
  // short delay to ensure Component Controllers are ready
410
398
  config.hash && me.timeout(5).then(() => {
@@ -270,14 +270,10 @@ class Manager extends Base {
270
270
  }
271
271
 
272
272
  /**
273
- * @param {String} path
273
+ *
274
274
  */
275
- loadApplication(path) {
276
- this.sendMessage('app', {
277
- action : 'loadApplication',
278
- path,
279
- resourcesPath: NeoConfig.resourcesPath
280
- })
275
+ loadApplication() {
276
+ this.sendMessage('app', {action: 'loadApplication' })
281
277
  }
282
278
 
283
279
  /**
@@ -291,7 +287,7 @@ class Manager extends Base {
291
287
  if (me.constructedThreads === me.activeWorkers) {
292
288
  // better safe than sorry => all remotes need to be registered
293
289
  NeoConfig.appPath && me.timeout(NeoConfig.loadApplicationDelay).then(() => {
294
- me.loadApplication(NeoConfig.appPath)
290
+ me.loadApplication()
295
291
  })
296
292
  }
297
293
  }