neo.mjs 10.0.0-alpha.4 → 10.0.0-beta.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.
Files changed (98) hide show
  1. package/ServiceWorker.mjs +2 -2
  2. package/apps/portal/index.html +1 -1
  3. package/apps/portal/resources/data/examples_devmode.json +26 -27
  4. package/apps/portal/resources/data/examples_dist_dev.json +26 -27
  5. package/apps/portal/resources/data/examples_dist_esm.json +26 -27
  6. package/apps/portal/resources/data/examples_dist_prod.json +27 -28
  7. package/apps/portal/view/blog/List.mjs +1 -1
  8. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  9. package/apps/portal/view/learn/ContentComponent.mjs +102 -111
  10. package/buildScripts/buildThemes.mjs +1 -1
  11. package/examples/grid/animatedRowSorting/Viewport.mjs +4 -4
  12. package/examples/grid/bigData/ControlsContainer.mjs +3 -3
  13. package/examples/grid/bigData/GridContainer.mjs +8 -8
  14. package/examples/grid/cellEditing/MainContainer.mjs +5 -5
  15. package/examples/grid/container/MainContainer.mjs +4 -4
  16. package/examples/grid/nestedRecordFields/Viewport.mjs +5 -5
  17. package/examples/table/cellEditing/MainContainer.mjs +1 -1
  18. package/examples/table/container/MainContainer.mjs +3 -3
  19. package/examples/table/nestedRecordFields/Viewport.mjs +6 -6
  20. package/examples/tableFiltering/MainContainer.mjs +1 -1
  21. package/examples/tablePerformance/MainContainer.mjs +1 -1
  22. package/examples/tablePerformance/MainContainer2.mjs +1 -1
  23. package/examples/tablePerformance/MainContainer3.mjs +2 -2
  24. package/examples/tableStore/MainContainer.mjs +2 -2
  25. package/learn/UsingTheseTopics.md +2 -2
  26. package/learn/benefits/ConfigSystem.md +2 -2
  27. package/learn/benefits/FormsEngine.md +14 -14
  28. package/learn/benefits/MultiWindow.md +2 -2
  29. package/learn/benefits/OffTheMainThread.md +2 -2
  30. package/learn/benefits/Speed.md +2 -2
  31. package/learn/gettingstarted/ComponentModels.md +4 -4
  32. package/learn/gettingstarted/Config.md +6 -6
  33. package/learn/gettingstarted/DescribingTheUI.md +4 -4
  34. package/learn/gettingstarted/Events.md +6 -6
  35. package/learn/gettingstarted/Extending.md +4 -4
  36. package/learn/gettingstarted/References.md +6 -6
  37. package/learn/gettingstarted/Workspaces.md +6 -6
  38. package/learn/guides/ApplicationBootstrap.md +40 -42
  39. package/learn/guides/ComponentsAndContainers.md +12 -12
  40. package/learn/guides/CustomComponents.md +2 -2
  41. package/learn/guides/MainThreadAddonIntro.md +2 -2
  42. package/learn/guides/PortalApp.md +2 -2
  43. package/learn/guides/StateProviders.md +12 -12
  44. package/learn/guides/events/CustomEvents.md +16 -16
  45. package/learn/guides/events/DomEvents.md +12 -12
  46. package/learn/javascript/ClassFeatures.md +3 -2
  47. package/learn/javascript/Classes.md +8 -8
  48. package/learn/javascript/NewNode.md +4 -4
  49. package/learn/javascript/Overrides.md +8 -8
  50. package/learn/javascript/Super.md +10 -8
  51. package/learn/tutorials/Earthquakes.md +54 -57
  52. package/learn/tutorials/TodoList.md +4 -4
  53. package/package.json +1 -1
  54. package/resources/scss/src/apps/portal/learn/ContentComponent.scss +12 -0
  55. package/resources/scss/src/grid/{View.scss → Body.scss} +2 -2
  56. package/resources/scss/src/grid/VerticalScrollbar.scss +1 -1
  57. package/resources/scss/src/grid/plugin/AnimateRows.scss +1 -1
  58. package/resources/scss/src/grid/plugin/CellEditing.scss +1 -1
  59. package/resources/scss/src/table/{View.scss → Body.scss} +1 -1
  60. package/resources/scss/src/table/plugin/CellEditing.scss +1 -1
  61. package/resources/scss/theme-dark/grid/{View.scss → Body.scss} +1 -1
  62. package/resources/scss/theme-dark/table/{View.scss → Body.scss} +1 -1
  63. package/resources/scss/theme-light/grid/{View.scss → Body.scss} +1 -1
  64. package/resources/scss/theme-light/table/{View.scss → Body.scss} +1 -1
  65. package/resources/scss/theme-neo-light/Global.scss +1 -2
  66. package/resources/scss/theme-neo-light/grid/{View.scss → Body.scss} +1 -1
  67. package/resources/scss/theme-neo-light/table/{View.scss → Body.scss} +1 -1
  68. package/src/DefaultConfig.mjs +2 -2
  69. package/src/core/Base.mjs +59 -12
  70. package/src/core/Util.mjs +14 -2
  71. package/src/draggable/grid/header/toolbar/SortZone.mjs +21 -21
  72. package/src/draggable/table/header/toolbar/SortZone.mjs +1 -1
  73. package/src/grid/{View.mjs → Body.mjs} +19 -20
  74. package/src/grid/Container.mjs +58 -58
  75. package/src/grid/ScrollManager.mjs +56 -56
  76. package/src/grid/VerticalScrollbar.mjs +2 -2
  77. package/src/grid/_export.mjs +2 -2
  78. package/src/grid/column/AnimatedChange.mjs +5 -5
  79. package/src/grid/column/Base.mjs +1 -1
  80. package/src/grid/column/Component.mjs +6 -6
  81. package/src/grid/header/Toolbar.mjs +9 -9
  82. package/src/grid/plugin/AnimateRows.mjs +1 -2
  83. package/src/main/addon/AmCharts.mjs +8 -11
  84. package/src/main/addon/Base.mjs +150 -42
  85. package/src/main/addon/GoogleMaps.mjs +9 -16
  86. package/src/main/addon/HighlightJS.mjs +2 -13
  87. package/src/main/addon/IntersectionObserver.mjs +21 -21
  88. package/src/main/addon/MonacoEditor.mjs +1 -6
  89. package/src/table/{View.mjs → Body.mjs} +19 -20
  90. package/src/table/Container.mjs +43 -43
  91. package/src/table/_export.mjs +2 -2
  92. package/src/table/plugin/CellEditing.mjs +19 -19
  93. package/src/util/Style.mjs +2 -6
  94. package/src/vdom/Helper.mjs +10 -13
  95. package/src/worker/App.mjs +6 -18
  96. package/src/worker/Base.mjs +1 -1
  97. package/src/worker/Manager.mjs +4 -8
  98. package/src/worker/mixin/RemoteMethodAccess.mjs +1 -1
@@ -14,11 +14,20 @@ using Web Workers.
14
14
 
15
15
  ## Bootstrap Sequence
16
16
 
17
+ ```text
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:
20
29
 
21
- ```html
30
+ ```html readonly
22
31
  <!DOCTYPE HTML>
23
32
  <html>
24
33
  <head>
@@ -42,7 +51,7 @@ The only JavaScript file imported is the `MicroLoader.mjs`, which is loaded as a
42
51
 
43
52
  The `MicroLoader.mjs` is a small script that fetches the application configuration and bootstraps the main thread:
44
53
 
45
- ```javascript
54
+ ```javascript readonly
46
55
  fetch('./neo-config.json').then(r => r.json()).then(d => {
47
56
  globalThis.Neo = {config: {...d}};
48
57
  import(d.mainPath)
@@ -60,13 +69,13 @@ It performs these steps:
60
69
  The `neo-config.json` file contains essential configuration for the application bootstrap. For a complete overview
61
70
  of all available configuration options, you can refer to the `src/DefaultConfig.mjs` file in the Neo.mjs framework:
62
71
 
63
- ```json
72
+ ```json readonly
64
73
  {
65
74
  "appPath" : "apps/myapp/app.mjs",
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,
@@ -79,23 +88,23 @@ of all available configuration options, you can refer to the `src/DefaultConfig.
79
88
  ```
80
89
 
81
90
  **Key Configuration Properties:**
82
- - **`appPath`** - Points to your application's entry point (app.mjs)
83
- - **`basePath`** - Root path for resolving other paths
84
- - **`environment`** - Controls optimization and debugging features
85
- - **`mainPath`** - Framework's main thread bootstrap file
86
- - **`mainThreadAddons`** - Additional features to load in the main thread
87
- - **`themes`** - CSS themes to load
88
- - **`useCanvasWorker`** - Controls whether to use a separate worker for canvas operations
89
- - **`useDataWorker`** - Controls whether to use a separate worker for data operations
90
- - **`useServiceWorker`** - Controls whether to use a service worker for caching
91
- - **`useSharedWorkers`** - When set to true, ALL workers (App, VDom, Data, etc.) will be created as SharedWorkers,
91
+ - `appPath` - Points to your application's entry point (app.mjs)
92
+ - `basePath` - Root path for resolving other paths
93
+ - `environment` - Controls optimization and debugging features
94
+ - `mainPath` - Framework's main thread bootstrap file
95
+ - `mainThreadAddons` - Additional features to load in the main thread
96
+ - `themes` - CSS themes to load
97
+ - `useCanvasWorker` - Controls whether to use a separate worker for canvas operations
98
+ - `useDataWorker` - Controls whether to use a separate worker for data operations
99
+ - `useServiceWorker` - Controls whether to use a service worker for caching
100
+ - `useSharedWorkers` - When set to true, ALL workers (App, VDom, Data, etc.) will be created as SharedWorkers,
92
101
  enabling multi-window applications. When false, all workers will be dedicated workers (better for single-page applications).
93
- The `worker.Base` class provides an abstraction layer that supports both types with a consistent API, allowing developers
102
+ The worker.Base class provides an abstraction layer that supports both types with a consistent API, allowing developers
94
103
  to create an app with dedicated workers first (which are easier to debug) and then switch to shared workers with just
95
104
  a one-line configuration change.
96
- - **`useTaskWorker`** - Controls whether to use a separate worker for background tasks
97
- - **`useVdomWorker`** - Controls whether to use a separate worker for virtual DOM operations
98
- - **`workerBasePath`** - Location of worker initialization files
105
+ - `useTaskWorker` - Controls whether to use a separate worker for background tasks
106
+ - `useVdomWorker` - Controls whether to use a separate worker for virtual DOM operations
107
+ - `workerBasePath` - Location of worker initialization files
99
108
 
100
109
  **Configuration Categories:**
101
110
  - **Path Resolution** - Where to find files and modules (auto-generated by default)
@@ -107,7 +116,7 @@ of all available configuration options, you can refer to the `src/DefaultConfig.
107
116
 
108
117
  The MicroLoader imports `Main.mjs`, which initializes the main thread:
109
118
 
110
- ```javascript
119
+ ```javascript readonly
111
120
  import Neo from './Neo.mjs';
112
121
  import * as core from './core/_export.mjs';
113
122
  import DomAccess from './main/DomAccess.mjs';
@@ -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
161
+ ### 5. Neo.worker.Manager: Creating Workers
153
162
 
154
- The `WorkerManager` is responsible for creating and managing the workers:
155
-
156
- ```javascript
157
- class Manager extends Base {
163
+ ```javascript readonly
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
@@ -227,7 +230,7 @@ The App worker receives the 'loadApplication' message and loads the application.
227
230
  in Neo.mjs is an instance of Neo.controller.Application, which is not common in other frameworks like React, Angular,
228
231
  or Vue (which typically just use a tag):
229
232
 
230
- ```javascript
233
+ ```javascript readonly
231
234
  class App extends Base {
232
235
  // ...
233
236
 
@@ -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
  // ...
@@ -284,8 +282,8 @@ The App worker:
284
282
 
285
283
  Finally, the application's `app.mjs` file is loaded and executed:
286
284
 
287
- ```javascript
288
- import Overwrites from './Overwrites.mjs'; // Optional framework extensions
285
+ ```javascript readonly
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({
@@ -303,7 +301,7 @@ The app.mjs file:
303
301
 
304
302
  When Neo.app() is called, it creates an Application controller and instantiates your mainView component:
305
303
 
306
- ```javascript
304
+ ```javascript readonly
307
305
  // Your Viewport component
308
306
  class Viewport extends Container {
309
307
  static config = {
@@ -25,7 +25,7 @@ primitive. Components introduce various properties, such as `width`, `height`, `
25
25
 
26
26
  Here's a container, with one child item.
27
27
 
28
- <pre data-code-livepreview>
28
+ ```javascript live-preview
29
29
  import Container from '../container/Base.mjs';
30
30
 
31
31
  class MainView extends Container {
@@ -42,12 +42,12 @@ class MainView extends Container {
42
42
  }
43
43
 
44
44
  MainView = Neo.setupClass(MainView);
45
- </pre>
45
+ ```
46
46
 
47
47
  Components also have an `html`. The `html` property is rarely used, and goes against the abstract philosophy of Neo.mjs, but
48
48
  sometimes it's handy as a placeholder as you stub out views.
49
49
 
50
- <pre data-code-livepreview>
50
+ ```javascript live-preview
51
51
  import Container from '../container/Base.mjs';
52
52
 
53
53
  class MainView extends Container {
@@ -65,7 +65,7 @@ class MainView extends Container {
65
65
  }
66
66
 
67
67
  MainView = Neo.setupClass(MainView);
68
- </pre>
68
+ ```
69
69
 
70
70
 
71
71
  ## Layout
@@ -77,7 +77,7 @@ some commonly-used layouts.
77
77
 
78
78
  Fix is used when there's a single child. The component is sized to fit the container.
79
79
 
80
- <pre data-code-livepreview>
80
+ ```javascript live-preview
81
81
  import Container from '../container/Base.mjs';
82
82
 
83
83
  class MainView extends Container {
@@ -92,13 +92,13 @@ class MainView extends Container {
92
92
  }
93
93
 
94
94
  MainView = Neo.setupClass(MainView);
95
- </pre>
95
+ ```
96
96
 
97
97
  ### Vbox and hbox
98
98
 
99
99
  With `vbox` and `hbox`, items are arranged vertically or horizontally.
100
100
 
101
- <pre data-code-livepreview>
101
+ ```javascript live-preview
102
102
  import Button from '../button/Base.mjs';
103
103
  import Container from '../container/Base.mjs';
104
104
 
@@ -119,13 +119,13 @@ class MainView extends Container {
119
119
  }
120
120
 
121
121
  MainView = Neo.setupClass(MainView);
122
- </pre>
122
+ ```
123
123
 
124
124
  ### Card
125
125
 
126
126
  A card container has multiple child items, one of which is visible.
127
127
 
128
- <pre data-code-livepreview>
128
+ ```javascript live-preview
129
129
  import Button from '../button/Base.mjs';
130
130
  import Container from '../container/Base.mjs';
131
131
 
@@ -167,7 +167,7 @@ class MainView extends Container {
167
167
  }
168
168
 
169
169
  MainView = Neo.setupClass(MainView);
170
- </pre>
170
+ ```
171
171
 
172
172
 
173
173
 
@@ -177,7 +177,7 @@ MainView = Neo.setupClass(MainView);
177
177
  Neo.mjs is class-based, and thus, any component or container can be defined as its own class, and reused like any
178
178
  other component in the framework.
179
179
 
180
- <pre data-code-livepreview>
180
+ ```javascript live-preview
181
181
  import Button from '../button/Base.mjs';
182
182
  // In practice this would be some handy reusable component
183
183
  class MySpecialButton extends Button {
@@ -209,5 +209,5 @@ class MainView extends Container {
209
209
  }
210
210
 
211
211
  MainView = Neo.setupClass(MainView);
212
- </pre>
212
+ ```
213
213
 
@@ -9,7 +9,7 @@ Neo.mjs is class-based, which means you're free to extend any component (or any
9
9
 
10
10
  ## Lifecycle config properties
11
11
 
12
- <pre data-code-livepreview>
12
+ ```javascript live-preview
13
13
  import Button from '../button/Base.mjs';
14
14
  // In practice this would be some handy reusable component
15
15
  class MySpecialButton extends Button {
@@ -41,5 +41,5 @@ class MainView extends Container {
41
41
  }
42
42
 
43
43
  Neo.setupClass(MainView);
44
- </pre>
44
+ ```
45
45
 
@@ -18,10 +18,10 @@ please return a specified `window` property." Neo.mjs
18
18
  lets you do that via `Neo.Main.getByPath()`. For
19
19
  example, the following statement logs the URL query string.
20
20
 
21
- <pre data-code-readonly>
21
+ ```javascript readonly
22
22
  const search = await Neo.Main.getByPath({path: 'window.location.search'});
23
23
  console.log(search); // Logs the search string
24
- </pre>
24
+ ```
25
25
 
26
26
  `Neo.Main` & `Neo.main.DomAccess` provide some basic methods for accessing the
27
27
  main thread, but in case you want to use a third party library which relies on directly
@@ -27,9 +27,9 @@ The setting will get stored inside the LocalStorage,
27
27
  so you will need to click the following Button a 2nd time to deactivate it again.
28
28
  Or you can clear the LocalStorage manually.</br></br>
29
29
 
30
- <pre data-neo-component>
30
+ ```json neo-component
31
31
  {
32
32
  "className": "Portal.view.learn.CubeLayoutButton",
33
33
  "style" : {"margin": 0}
34
34
  }
35
- </pre>
35
+ ```
@@ -10,7 +10,7 @@ Other libraries or frameworks often call state providers "Stores".
10
10
 
11
11
  ## Inline State Providers
12
12
  ### Direct Bindings
13
- <pre data-code-livepreview>
13
+ ```javascript live-preview
14
14
  import Button from '../button/Base.mjs';
15
15
  import Container from '../container/Base.mjs';
16
16
  import Label from '../component/Label.mjs';
@@ -49,7 +49,7 @@ class MainView extends Container {
49
49
  }
50
50
  }
51
51
  MainView = Neo.setupClass(MainView);
52
- </pre>
52
+ ```
53
53
 
54
54
  We use a Container with a stateProvider containing the data props `hello` and `world`.
55
55
  Inside the Container are 2 Labels which bind their `text` config to a data prop directly.
@@ -58,7 +58,7 @@ We can easily bind 1:1 to specific data props using the following syntax:</br>
58
58
  `bind: {text: data => data.hello}`
59
59
 
60
60
  ### Bindings with multiple data props
61
- <pre data-code-livepreview>
61
+ ```javascript live-preview
62
62
  import Button from '../button/Base.mjs';
63
63
  import Container from '../container/Base.mjs';
64
64
  import Label from '../component/Label.mjs';
@@ -104,7 +104,7 @@ class MainView extends Container {
104
104
  }
105
105
  }
106
106
  MainView = Neo.setupClass(MainView);
107
- </pre>
107
+ ```
108
108
 
109
109
  We use a Container with a stateProvider containing the data props `hello` and `world`.
110
110
  Inside the Container are 3 Labels which bind their `text` config to a combination of both data props.
@@ -128,7 +128,7 @@ data.component equals to the Button instance itself. Since the Button instance d
128
128
  `getStateProvider()` will return the closest stateProvider inside the parent chain.
129
129
 
130
130
  ### Nested Inline State Providers
131
- <pre data-code-livepreview>
131
+ ```javascript live-preview
132
132
  import Button from '../button/Base.mjs';
133
133
  import Container from '../container/Base.mjs';
134
134
  import Label from '../component/Label.mjs';
@@ -182,7 +182,7 @@ class MainView extends Container {
182
182
  }
183
183
  }
184
184
  MainView = Neo.setupClass(MainView);
185
- </pre>
185
+ ```
186
186
 
187
187
  The output of this demo is supposed to exactly look the same like the previous demo.
188
188
 
@@ -203,7 +203,7 @@ We can even change data props which live inside different stateProviders at once
203
203
  Hint: Modify the example code (Button handler) to try it out right away!
204
204
 
205
205
  ### Nested Data Properties
206
- <pre data-code-livepreview>
206
+ ```javascript live-preview
207
207
  import Button from '../button/Base.mjs';
208
208
  import Container from '../container/Base.mjs';
209
209
  import Label from '../component/Label.mjs';
@@ -244,7 +244,7 @@ class MainView extends Container {
244
244
  }
245
245
  }
246
246
  MainView = Neo.setupClass(MainView);
247
- </pre>
247
+ ```
248
248
  Data props inside VMs can be nested. Our stateProvider contains a `user` data prop as an object,
249
249
  which contains the nested props `firstname` and `lastname`.
250
250
 
@@ -262,7 +262,7 @@ Or we can directly pass the object containing the change(s):</br>
262
262
  Hint: This will not override left out nested data props (lastname in this case).
263
263
 
264
264
  ### Dialog connecting to a Container
265
- <pre data-code-livepreview>
265
+ ```javascript live-preview
266
266
  import Controller from '../controller/Component.mjs';
267
267
  import Dialog from '../dialog/Base.mjs';
268
268
  import Panel from '../container/Panel.mjs';
@@ -378,13 +378,13 @@ class MainView extends Viewport {
378
378
  }
379
379
 
380
380
  MainView = Neo.setupClass(MainView);
381
- </pre>
381
+ ```
382
382
 
383
383
  ## Class based State Providers
384
384
  When your stateProviders contain many data props or need custom logic, you can easily move them into their own classes.
385
385
 
386
386
  ### Direct Bindings
387
- <pre data-code-livepreview>
387
+ ```javascript live-preview
388
388
  import Button from '../button/Base.mjs';
389
389
  import Container from '../container/Base.mjs';
390
390
  import Label from '../component/Label.mjs';
@@ -436,4 +436,4 @@ class MainView extends Container {
436
436
  }
437
437
  }
438
438
  MainView = Neo.setupClass(MainView);
439
- </pre>
439
+ ```
@@ -1,7 +1,7 @@
1
1
  As you read in the <a href="#/learn/Events">Getting Started > Events</a> topic, components, stores, and many other objects fire events.
2
2
 
3
3
 
4
- <pre data-code-livepreview>
4
+ ```javascript live-preview
5
5
  import Container from '../container/Base.mjs';
6
6
  import TextField from '../form/field/Text.mjs';
7
7
 
@@ -26,7 +26,7 @@ class MainView extends Container {
26
26
  }
27
27
  }
28
28
  MainView = Neo.setupClass(MainView);
29
- </pre>
29
+ ```
30
30
 
31
31
  ## Event listeners
32
32
 
@@ -35,7 +35,7 @@ MainView = Neo.setupClass(MainView);
35
35
  The event listener function can be coded in-line. Normally you want event handlers to be in a view's
36
36
  controller, but for very simple situation it can be convenient to use this syntax.
37
37
 
38
- <pre data-code-livepreview>
38
+ ```javascript live-preview
39
39
  import Container from '../container/Base.mjs';
40
40
  import TextField from '../form/field/Text.mjs';
41
41
 
@@ -54,7 +54,7 @@ class MainView extends Container {
54
54
  }
55
55
  }
56
56
  MainView = Neo.setupClass(MainView);
57
- </pre>
57
+ ```
58
58
 
59
59
  ### As a view method
60
60
 
@@ -62,7 +62,7 @@ You can also use the `up.` qualifier to specify a method in the component's pare
62
62
  in-line syntax you saw above, using the `up.` syntax might be convenient for simple classees,
63
63
  or when you simply haven't gotten around to defining a view's controller.
64
64
 
65
- <pre data-code-livepreview>
65
+ ```javascript live-preview
66
66
  import Container from '../container/Base.mjs';
67
67
  import TextField from '../form/field/Text.mjs';
68
68
 
@@ -84,7 +84,7 @@ class MainView extends Container {
84
84
  }
85
85
  }
86
86
  MainView = Neo.setupClass(MainView);
87
- </pre>
87
+ ```
88
88
 
89
89
  ### As a controller method
90
90
 
@@ -92,7 +92,7 @@ Despite the examples above, the most correct way of setting up event handlers is
92
92
  Any view class can specify a controller &mdash; wWhen the view is created a controller instance is
93
93
  also created.
94
94
 
95
- <pre data-code-livepreview>
95
+ ```javascript live-preview
96
96
  import Controller from '../controller/Component.mjs';
97
97
 
98
98
  class MainViewController extends Controller {
@@ -125,7 +125,7 @@ class MainView extends Container {
125
125
  }
126
126
  }
127
127
  MainView = Neo.setupClass(MainView);
128
- </pre>
128
+ ```
129
129
 
130
130
  ## Adding listeners procedurally
131
131
 
@@ -134,7 +134,7 @@ a listener procedurally.
134
134
 
135
135
  Any observable class has an `addListener` method, along with an easier-to-type version called `on`.
136
136
 
137
- <pre data-code-livepreview>
137
+ ```javascript live-preview
138
138
  import Controller from '../controller/Component.mjs';
139
139
 
140
140
  class MainViewController extends Controller {
@@ -167,11 +167,11 @@ class MainView extends Container {
167
167
  }
168
168
  }
169
169
  MainView = Neo.setupClass(MainView);
170
- </pre>
170
+ ```
171
171
 
172
172
  The method specified in `on()` doesn't have to be an arrow function; you can use a controller function.
173
173
 
174
- <pre data-code-livepreview>
174
+ ```javascript live-preview
175
175
  import Controller from '../controller/Component.mjs';
176
176
 
177
177
  class MainViewController extends Controller {
@@ -208,7 +208,7 @@ class MainView extends Container {
208
208
  }
209
209
  }
210
210
  MainView = Neo.setupClass(MainView);
211
- </pre>
211
+ ```
212
212
 
213
213
  ## Events versus binding
214
214
 
@@ -241,7 +241,7 @@ will automatically be reflected in the view model.
241
241
  To contrast syntax, and to illustrate the simplicity of a binding, let's look at two exmaples of updating a component
242
242
  to reflect the value of a text field. THe first example uses events; the second uses bindings.
243
243
 
244
- <pre data-code-livepreview>
244
+ ```javascript live-preview
245
245
  import Component from '../component/Base.mjs';
246
246
  import Container from '../container/Base.mjs';
247
247
  import TextField from '../form/field/Text.mjs';
@@ -277,9 +277,9 @@ class MainView extends Container {
277
277
  }
278
278
  }
279
279
  MainView = Neo.setupClass(MainView);
280
- </pre>
280
+ ```
281
281
 
282
- <pre data-code-livepreview>
282
+ ```javascript live-preview
283
283
  import Component from '../component/Base.mjs';
284
284
  import Container from '../container/Base.mjs';
285
285
  import TextField from '../form/field/Text.mjs';
@@ -313,7 +313,7 @@ class MainView extends Container {
313
313
  }
314
314
  }
315
315
  MainView = Neo.setupClass(MainView);
316
- </pre>
316
+ ```
317
317
 
318
318
  ##How are events set up?
319
319
 
@@ -34,7 +34,7 @@ the class. If you add `console.log(this);`, the output is most likely not want y
34
34
  For the second Button we are defining a non-bound function, in which case `this` will point
35
35
  to the Component instance.
36
36
 
37
- <pre data-code-livepreview>
37
+ ```javascript live-preview
38
38
  import Container from '../container/Base.mjs';
39
39
 
40
40
  class MainView extends Container {
@@ -62,7 +62,7 @@ class MainView extends Container {
62
62
  }
63
63
  }
64
64
  MainView = Neo.setupClass(MainView);
65
- </pre>
65
+ ```
66
66
 
67
67
  ### Handler inside the Component Tree
68
68
 
@@ -72,7 +72,7 @@ A good example would be `tab.header.Toolbar`, where clicking on a Button will ch
72
72
  You can use string based listeners. In case the handler method lives within the parent tree (any level),
73
73
  we need to prefix these listeners with `up.`.
74
74
 
75
- <pre data-code-livepreview>
75
+ ```javascript live-preview
76
76
  import Container from '../container/Base.mjs';
77
77
 
78
78
  class MainView extends Container {
@@ -95,7 +95,7 @@ class MainView extends Container {
95
95
  }
96
96
  }
97
97
  MainView = Neo.setupClass(MainView);
98
- </pre>
98
+ ```
99
99
 
100
100
  ### Handler inside a ViewController
101
101
 
@@ -107,7 +107,7 @@ to find the closest match.
107
107
 
108
108
  A good use case would be a form submit Button, where a click will trigger a communication to the backend.
109
109
 
110
- <pre data-code-livepreview>
110
+ ```javascript live-preview
111
111
  import Container from '../container/Base.mjs';
112
112
  import Controller from '../controller/Component.mjs';
113
113
 
@@ -138,7 +138,7 @@ class MainView extends Container {
138
138
  }
139
139
  }
140
140
  MainView = Neo.setupClass(MainView);
141
- </pre>
141
+ ```
142
142
 
143
143
  ## Listener Options
144
144
 
@@ -146,7 +146,7 @@ MainView = Neo.setupClass(MainView);
146
146
 
147
147
  We can further delegate listeners to specific DOM nodes within our Component:
148
148
 
149
- <pre data-code-livepreview>
149
+ ```javascript live-preview
150
150
  import Container from '../container/Base.mjs';
151
151
 
152
152
  class MainView extends Container {
@@ -172,7 +172,7 @@ class MainView extends Container {
172
172
  }
173
173
  }
174
174
  MainView = Neo.setupClass(MainView);
175
- </pre>
175
+ ```
176
176
 
177
177
  In case you click on the blue div, no console logs will appear.
178
178
  They do, when clicking on the white inner div.
@@ -184,7 +184,7 @@ we will get logs when clicking on the blue div too.
184
184
 
185
185
  We can prevent listeners from bubbling upwards:
186
186
 
187
- <pre data-code-livepreview>
187
+ ```javascript live-preview
188
188
  import Container from '../container/Base.mjs';
189
189
 
190
190
  class MainView extends Container {
@@ -221,7 +221,7 @@ class MainView extends Container {
221
221
  }
222
222
  }
223
223
  MainView = Neo.setupClass(MainView);
224
- </pre>
224
+ ```
225
225
 
226
226
  Clicking on the inner (white) div will only trigger the inner listener and you will get one log.
227
227
 
@@ -237,7 +237,7 @@ While we could just manually order the array inside the following example,
237
237
  there can be use cases where multiple subscribers get added at run-time and developers
238
238
  can not be sure about the adding order.
239
239
 
240
- <pre data-code-livepreview>
240
+ ```javascript live-preview
241
241
  import Container from '../container/Base.mjs';
242
242
 
243
243
  class MainView extends Container {
@@ -257,7 +257,7 @@ class MainView extends Container {
257
257
  }
258
258
  }
259
259
  MainView = Neo.setupClass(MainView);
260
- </pre>
260
+ ```
261
261
 
262
262
  Try it: In case you remove `priority: 2` inside the source view,
263
263
  the order of the logs will change.
@@ -1,6 +1,7 @@
1
1
  Neo.mjs uses standard modular JavaScript, so you're free to use other class
2
2
  features, like private members.
3
- <pre><code class="javascript">
3
+
4
+ ```javascript readonly
4
5
  class Human extends Mammal {
5
6
  static config = {
6
7
  className: 'Simple.example.Human',
@@ -33,4 +34,4 @@ const myPerson = Neo.create(Human, {
33
34
  });
34
35
 
35
36
  myPerson.speak(true);
36
- </code></pre>
37
+ ```