neo.mjs 7.0.2 → 7.0.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.
package/README.md CHANGED
@@ -11,12 +11,15 @@
11
11
  <a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-green.svg?logo=GitHub&logoColor=white" alt="PRs Welcome"></a>
12
12
  </p>
13
13
 
14
- # Harness the Power of Multi-Threading for Ultra-Fast Frontends
14
+ # Modern Enterprise-Ready JavaScript Framework
15
15
 
16
16
  ## Content
17
17
  1. <a href="#introduction">Introduction</a>
18
18
  2. <a href="#slack-channel">Slack Channel for questions & feedback</a>
19
19
  3. <a href="#architectures">Scalable frontend architectures</a>
20
+ 4. <a href="#getting-started">Getting Started</a>
21
+ 5. <a href="#cli">Command-Line Interface</a>
22
+ 6. <a href="#blog">Blog</a>
20
23
 
21
24
  </br></br>
22
25
  <h2 id="introduction">1. Introduction</h2>
@@ -56,17 +59,36 @@ Potential Use-Cases:
56
59
  Join our community:</br>
57
60
  <a href="https://join.slack.com/t/neomjs/shared_invite/zt-6c50ueeu-3E1~M4T9xkNnb~M_prEEOA"><img src="https://img.shields.io/badge/Slack-neo.mjs-brightgreen.svg?logo=slack&style=for-the-badge" alt="Join the Slack channel"></a>
58
61
 
62
+ </br></br>
63
+ <h2 id="getting-started">4. Getting Started</h2>
64
+ Take a look at the <a href="./.github/GETTING_STARTED.md">Getting Started Guide</a>
65
+ </br></br>
66
+ There are 2 options:
59
67
 
68
+ 1. In case you want to create a Neo.mjs App (workspace), use
69
+ > npx neo-app@latest
70
+
71
+ 2. In case you want to work on the Framework and your App in parallel, you can fork this repository and use
72
+ > npm run create-app
73
+
74
+ inside of it.
60
75
 
61
- </br></br>
62
76
 
63
- [Spoiler] We are in the middle of wrapping up the new Framework Website,
64
- which will include the first version of a self-study based Learning Section.
77
+ * You can easily move your app from the framework to a workspace or vice versa.
78
+ * The CLI inside the framework and inside a workspace works the same.
65
79
 
66
- We are aiming to release it on August 1st, 2024.
80
+ Make sure to take a look into the <a href="https://neomjs.com/dist/production/apps/portal/#/learn/Setup">Learning Section</a>
67
81
 
68
- The current development state is already inside the dev branch.
82
+ The most advanced tutorial to help you with getting up to speed is this one:</br>
83
+ <a href="https://neomjs.com/dist/production/apps/portal/#/learn/Earthquakes">Earthquakes Tutorial</a>
69
84
 
85
+ </br></br>
86
+ <h2 id="cli">5. Command-Line Interface</h2>
87
+ You can find an in-depth description here: <a href="./buildScripts/README.md">Neo.mjs CLI</a>
88
+
89
+ </br></br>
90
+ <h2 id="blog">6. Blog</h2>
91
+ All Blog Posts are listed here: <a href="https://neomjs.com/dist/production/apps/portal/#/blog">Neo.mjs Blog</a>
70
92
 
71
93
  </br></br>
72
94
  Copyright (c) 2015 - today, <a href="https://www.linkedin.com/in/tobiasuhlig/">Tobias Uhlig</a>
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='7.0.2'
23
+ * @member {String} version='7.0.3'
24
24
  */
25
- version: '7.0.2'
25
+ version: '7.0.3'
26
26
  }
27
27
 
28
28
  /**
@@ -4,16 +4,6 @@ Neo.overwrites = {
4
4
  Base: {
5
5
  editRoute: false
6
6
  }
7
- },
8
- form: {
9
- field: {
10
- Base: {
11
- delayable: {
12
- fireChangeEvent : null,
13
- fireUserChangeEvent: null
14
- }
15
- }
16
- }
17
7
  }
18
8
  }
19
9
  }
@@ -16,7 +16,7 @@
16
16
  "@type": "Organization",
17
17
  "name": "Neo.mjs"
18
18
  },
19
- "datePublished": "2024-08-18",
19
+ "datePublished": "2024-08-27",
20
20
  "publisher": {
21
21
  "@type": "Organization",
22
22
  "name": "Neo.mjs"
@@ -37,6 +37,7 @@ class FeatureSection extends Container {
37
37
  */
38
38
  headline_: null,
39
39
  /**
40
+ * Can either contain a route or a URL
40
41
  * @member {String|null} learnMoreRoute_=null
41
42
  */
42
43
  learnMoreRoute_: null,
@@ -136,7 +137,8 @@ class FeatureSection extends Container {
136
137
  * @protected
137
138
  */
138
139
  afterSetLearnMoreRoute(value, oldValue) {
139
- this.getItem('learn-more-button').route = value
140
+ let targetConfig = value.startsWith('http') ? 'url' : 'route';
141
+ this.getItem('learn-more-button')[targetConfig] = value
140
142
  }
141
143
 
142
144
  /**
@@ -111,7 +111,7 @@ class FooterContainer extends Container {
111
111
  }, {
112
112
  module: Component,
113
113
  cls : ['neo-version'],
114
- html : 'v7.0.2'
114
+ html : 'v7.0.3'
115
115
  }]
116
116
  }],
117
117
  /**
@@ -20,9 +20,9 @@ class Colors extends FeatureSection {
20
20
  */
21
21
  headline: 'Amazing Potential',
22
22
  /**
23
- * @member {String} learnMoreRoute='#/learn/WhyNeo-Speed'
23
+ * @member {String} learnMoreRoute='https://itnext.io/sharing-real-time-websocket-data-across-multiple-browser-windows-4e0538dd7563?source=friends_link&sk=9efb3e4f38c82fb3e04899c61bb5fcb8'
24
24
  */
25
- learnMoreRoute: '#/learn/WhyNeo-Speed',
25
+ learnMoreRoute: 'https://itnext.io/sharing-real-time-websocket-data-across-multiple-browser-windows-4e0538dd7563?source=friends_link&sk=9efb3e4f38c82fb3e04899c61bb5fcb8',
26
26
  /**
27
27
  * @member {String} livePreviewCode
28
28
  */
@@ -11,8 +11,8 @@ You can run each script inside your terminal. E.g.:
11
11
 
12
12
  Make sure to call them on the top-level folder (the one containing the package.json).
13
13
 
14
- In case you want to pass program options, please use the node based calls instead. E.g.:
15
- > node ./buildScripts/buildAll.js -h
14
+ In case you want to pass program options, use -- before adding options. E.g.:
15
+ > npm run build-all -- -h
16
16
 
17
17
  All programs which are using options also have the visual inquirer interface in place.</br>
18
18
  So it is up to you if you prefer adding the options manually (e.g. for adding them into your own CI),</br>
@@ -25,15 +25,14 @@ where the framework is included as a node module, but needs to deploy to a top-l
25
25
  ## Content
26
26
  1. <a href="#build-all">build-all</a>
27
27
  2. <a href="#build-all-questions">build-all-questions</a>
28
- 3. <a href="#build-my-apps">build-my-apps</a>
29
- 4. <a href="#build-themes">build-themes</a>
30
- 5. <a href="#build-threads">build-threads</a>
31
- 6. <a href="#create-app">create-app</a>
32
- 7. <a href="#generate-docs-json">generate-docs-json</a>
33
- 8. <a href="#server-start">server-start</a>
28
+ 3. <a href="#build-themes">build-themes</a>
29
+ 4. <a href="#build-threads">build-threads</a>
30
+ 5. <a href="#create-app">create-app</a>
31
+ 6. <a href="#generate-docs-json">generate-docs-json</a>
32
+ 7. <a href="#server-start">server-start</a>
34
33
 
35
34
  ## build-all
36
- > node ./buildScripts/buildAll.js -f -n
35
+ > npm run build-all
37
36
 
38
37
  It is strongly recommended to run this program after each git pull on this repo.
39
38
 
@@ -70,7 +69,7 @@ or dist/production.
70
69
  Source code: <a href="./buildAll.js">build-all</a>
71
70
 
72
71
  ## build-all-questions
73
- > node ./buildScripts/buildAll.js -f
72
+ > npm run build-all-questions
74
73
 
75
74
  This entry point is running the build-all program without passing options,
76
75
  so we can select them using the inquirer interface.
@@ -130,64 +129,8 @@ neo.mjs buildAll
130
129
 
131
130
  Source code: <a href="./buildAll.js">build-all</a>
132
131
 
133
- ## build-my-apps
134
- > node ./buildScripts/webpack/buildMyApps.js -f
135
-
136
- ```bash
137
- Options:
138
- -V, --version output the version number
139
- -i, --info print environment debug info
140
- -a, --apps <value> "all", "Covid", "RealWorld", "RealWorld2", "SharedCovid", "SharedCovidChart", "SharedCovidGallery",
141
- "SharedCovidHelix", "SharedCovidMap", "SharedDialog", "SharedDialog2", "Website"
142
- -e, --env <value> "all", "dev", "prod"
143
- -f, --framework
144
- -n, --noquestions
145
- -h, --help display help for command
146
- ```
147
-
148
- build-my-apps is very similar to build-threads => App.
149
-
150
- In both cases we are parsing <a href="../src/worker/App.mjs">worker/App</a>,
151
- which will dynamically import all Apps inside the src/app folder and the Docs App and create split chunks
152
- for all combinations. This enables you to add multiple Apps on one Page with close to zero overhead
153
- in dist/development & dist/production.
154
-
155
- The only difference to build-threads => App is that you can limit the generation of the App related index.html files,
156
- so it is a little faster.
157
-
158
- Let us take a look at the different inquirer steps:
159
- 1. Pick the -e (env) option:
160
- ```bash
161
- neo % npm run build-my-apps
162
-
163
- > neo.mjs@1.4.14 build-my-apps /Users/Shared/github/neomjs/neo
164
- > node ./buildScripts/webpack/buildMyApps.js -f
165
-
166
- neo.mjs buildMyApps
167
- ? Please choose the environment: (Use arrow keys)
168
- ❯ all
169
- dev
170
- prod
171
- ```
172
- 2. Pick the -a (apps) option:
173
- ```bash
174
- neo.mjs buildMyApps
175
- ? Please choose the environment: all
176
- ? Please choose which apps you want to build: (Press <space> to select, <a> to toggle all, <i> to invert selection)
177
- ❯◯ Covid
178
- ◯ RealWorld
179
- ◯ RealWorld2
180
- ◯ SharedCovid
181
- ◯ SharedCovidChart
182
- ◯ SharedCovidGallery
183
- ◯ SharedCovidHelix
184
- (Move up and down to reveal more choices)
185
- ```
186
-
187
- Source code: <a href="./webpack/buildMyApps.js">build-my-apps</a>
188
-
189
132
  ## build-themes
190
- > node ./buildScripts/webpack/buildThemes.js -f
133
+ > npm run build-themes
191
134
 
192
135
  ```bash
193
136
  Options:
@@ -238,7 +181,7 @@ neo.mjs buildThemes
238
181
  Source code: <a href="./webpack/buildThemes.js">build-themes</a>
239
182
 
240
183
  ## build-threads
241
- > node ./buildScripts/webpack/buildThreads.js -f
184
+ > npm run build-threads
242
185
 
243
186
  Since the default neo.mjs setup is using 3 workers, we have the following 4 threads to build:</br>
244
187
  "app", "data", "main", "vdom"
@@ -286,7 +229,7 @@ neo.mjs buildThreads
286
229
  Source code: <a href="./webpack/buildThreads.js">build-threads</a>
287
230
 
288
231
  ## create-app
289
- > node ./buildScripts/createApp.js
232
+ > npm run create-app
290
233
 
291
234
  Again: In case you want to create an App (workspace) based on neo.mjs, you don't need to clone this repository.</br>
292
235
  Please take a look at the <a href="https://github.com/neomjs/create-app">create-app repository</a> (npx neo-app).
@@ -294,14 +237,14 @@ Please take a look at the <a href="https://github.com/neomjs/create-app">create-
294
237
  If you want to create a new Demo App inside the framework repo,
295
238
  using the create-app program makes sense, since you can work on the app & framework code in parallel.
296
239
 
297
- Using the default options, this will generate the following 3 files:
240
+ Using the default options, this will generate the following 4 files:
298
241
  ```
299
242
  neo
300
243
  | - apps
301
244
  | | - myapp
302
245
  | | | - app.mjs
303
- | | | - config.json
304
246
  | | | - index.html
247
+ | | | - neo-config.json
305
248
  | | | - MainContainer.mjs
306
249
  ```
307
250
 
@@ -377,14 +320,15 @@ neo.mjs create-app
377
320
  No worries, you can easily change the options after you created your App shell.
378
321
 
379
322
  E.g. in case you want to add the MapboxGL main thread addon later on,
380
- you can add it inside your index.html file:
381
- ```js
382
- Object.assign(Neo.config, {
383
- appPath : 'apps/myapp/app.mjs',
384
- basePath : '../../',
385
- environment : 'development',
386
- mainThreadAddons: ['MapboxGL', 'Stylesheet']
387
- });
323
+ you can add it inside your neo-config.json file:
324
+ ```json
325
+ {
326
+ "appPath" : "apps/myapp/app.mjs",
327
+ "basePath" : "../../",
328
+ "environment" : "development",
329
+ "mainPath" : "./Main.mjs",
330
+ "mainThreadAddons": ["DragDrop", "MapboxGL", "Navigator", "Stylesheet"]
331
+ }
388
332
  ```
389
333
 
390
334
  Regarding the -u (SharedWorkers) option:</br>
@@ -399,7 +343,7 @@ Using SharedWorkers, you need to open a separate Window to inspect them:</br>
399
343
  Source code: <a href="./buildScripts/createApp.js">create-app</a>
400
344
 
401
345
  ## generate-docs-json
402
- > node ./buildScripts/docs/jsdocx.js
346
+ > npm run generate-docs-json
403
347
 
404
348
  neo.mjs is using jsdoc
405
349
  > https://github.com/jsdoc/jsdoc
@@ -414,7 +358,7 @@ There are several enhancements around it to polish it for our class system impro
414
358
  Source code: <a href="./docs/jsdocx.js">generate-docs-json</a>
415
359
 
416
360
  ## server-start
417
- > webpack serve -c ./buildScripts/webpack/webpack.server.config.js --open
361
+ > npm run server-start
418
362
 
419
363
  To open JS modules locally inside your Browser you need a web-server, since importing files is not possible
420
364
  otherwise for security reasons. You could enable this on an OS level, but this is definitely not recommended.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='7.0.2'
23
+ * @member {String} version='7.0.3'
24
24
  */
25
- version: '7.0.2'
25
+ version: '7.0.3'
26
26
  }
27
27
 
28
28
  /**
@@ -148,6 +148,7 @@ class MainContainer extends ConfigurationViewport {
148
148
  ntype : 'button',
149
149
  appName : this.appName,
150
150
  text : '\u22ee',
151
+ windowId: this.windowId,
151
152
  menu : {
152
153
  items : [{
153
154
  text : 'Menu option 1'
@@ -45,7 +45,8 @@ class MainStore extends Store {
45
45
  colspan : {firstname: 3},
46
46
  country : 'Germany',
47
47
  firstname: 'Colspan 3',
48
- githubId : 'random'
48
+ githubId : 'random',
49
+ lastname : ''
49
50
  }]
50
51
  }
51
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "7.0.2",
3
+ "version": "7.0.3",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -53,15 +53,15 @@
53
53
  "fs-extra": "^11.2.0",
54
54
  "highlightjs-line-numbers.js": "^2.8.0",
55
55
  "inquirer": "^10.1.8",
56
- "marked": "^14.0.0",
57
- "monaco-editor": "^0.50.0",
56
+ "marked": "^14.1.0",
57
+ "monaco-editor": "0.50.0",
58
58
  "neo-jsdoc": "1.0.1",
59
59
  "neo-jsdoc-x": "1.0.5",
60
60
  "postcss": "^8.4.41",
61
61
  "sass": "^1.77.8",
62
62
  "siesta-lite": "5.5.2",
63
63
  "url": "^0.11.4",
64
- "webpack": "^5.93.0",
64
+ "webpack": "^5.94.0",
65
65
  "webpack-cli": "^5.1.4",
66
66
  "webpack-dev-server": "^5.0.4",
67
67
  "webpack-hook-plugin": "^1.0.7",
@@ -4,4 +4,8 @@
4
4
  min-height: 23em;
5
5
  }
6
6
  }
7
+
8
+ @media (min-width: 841px) {
9
+ max-height: 100%;
10
+ }
7
11
  }
@@ -262,12 +262,12 @@ const DefaultConfig = {
262
262
  useVdomWorker: true,
263
263
  /**
264
264
  * buildScripts/injectPackageVersion.mjs will update this value
265
- * @default '7.0.2'
265
+ * @default '7.0.3'
266
266
  * @memberOf! module:Neo
267
267
  * @name config.version
268
268
  * @type String
269
269
  */
270
- version: '7.0.2'
270
+ version: '7.0.3'
271
271
  };
272
272
 
273
273
  Object.assign(DefaultConfig, {
package/src/Neo.mjs CHANGED
@@ -54,13 +54,6 @@ Neo = globalThis.Neo = Object.assign({
54
54
  */
55
55
  insideWorker: typeof DedicatedWorkerGlobalScope !== 'undefined' || typeof WorkerGlobalScope !== 'undefined',
56
56
 
57
- /**
58
- * @deprecated in neo.mjs v7.0
59
- */
60
- applyClassConfig(cls) {
61
- return Neo.setupClass(cls)
62
- },
63
-
64
57
  /**
65
58
  * Maps methods from one namespace to another one
66
59
  * @example
@@ -257,16 +257,18 @@ class Base extends Component {
257
257
  items = isArray ? value : value.items,
258
258
  menuConfig = isArray ? {} : value,
259
259
  model = me.getModel(),
260
+ {appName, theme, windowId} = me,
260
261
 
261
262
  config = Neo.merge({
262
263
  module : module.default,
263
264
  align : {edgeAlign : 't0-b0', target: me.id},
264
- appName : me.appName,
265
+ appName,
265
266
  displayField : 'text',
266
267
  floating : true,
267
268
  hidden : true,
268
269
  parentComponent: me,
269
- theme : me.theme
270
+ theme,
271
+ windowId
270
272
  }, menuConfig);
271
273
 
272
274
  if (items) {
@@ -385,6 +387,22 @@ class Base extends Component {
385
387
  me.update()
386
388
  }
387
389
 
390
+ /**
391
+ * Triggered after the windowId config got changed
392
+ * @param {Number|null} value
393
+ * @param {Number|null} oldValue
394
+ * @protected
395
+ */
396
+ afterSetWindowId(value, oldValue) {
397
+ super.afterSetWindowId(value, oldValue);
398
+
399
+ let {menuList} = this;
400
+
401
+ if (menuList) {
402
+ menuList.windowId = value
403
+ }
404
+ }
405
+
388
406
  /**
389
407
  * Converts the iconCls array into a string on beforeGet
390
408
  * @returns {String}
@@ -189,6 +189,22 @@ class Split extends Button {
189
189
  me.ntype = ntype;
190
190
  }
191
191
 
192
+ /**
193
+ * Triggered after the windowId config got changed
194
+ * @param {Number|null} value
195
+ * @param {Number|null} oldValue
196
+ * @protected
197
+ */
198
+ afterSetWindowId(value, oldValue) {
199
+ let {triggerButton} = this;
200
+
201
+ if (triggerButton) {
202
+ triggerButton.appName = value;
203
+ }
204
+
205
+ super.afterSetWindowId(value, oldValue)
206
+ }
207
+
192
208
  /**
193
209
  * @param {Boolean} [updateParentVdom=false]
194
210
  * @param {Boolean} [silent=false]
@@ -129,12 +129,12 @@ class Base extends CoreBase {
129
129
  }
130
130
 
131
131
  /**
132
- * Adds one or more items to the end of the collection and returns the new length of the collection.
132
+ * Adds one or more items to the end of the collection
133
133
  * @param {Array|Object} item The item(s) to add
134
134
  * @returns {Object[]} an array containing all added items
135
135
  */
136
136
  add(item) {
137
- return this.splice(0, null, item).addedItems
137
+ return this.splice(null, null, item).addedItems
138
138
  }
139
139
 
140
140
  /**
@@ -515,7 +515,7 @@ class Base extends CoreBase {
515
515
  * @protected
516
516
  */
517
517
  afterSetAppName(value, oldValue) {
518
- value && Neo.currentWorker.insertThemeFiles(value, this.windowId, this.__proto__)
518
+
519
519
  }
520
520
 
521
521
  /**
@@ -1036,16 +1036,21 @@ class Base extends CoreBase {
1036
1036
  * @protected
1037
1037
  */
1038
1038
  afterSetWindowId(value, oldValue) {
1039
- let controller = this.controller;
1039
+ let me = this,
1040
+ controller = me.controller;
1041
+
1042
+ if (value) {
1043
+ Neo.currentWorker.insertThemeFiles(value, me.__proto__);
1040
1044
 
1041
- if (controller && value) {
1042
- controller.windowId = value
1045
+ if (controller) {
1046
+ controller.windowId = value
1047
+ }
1043
1048
  }
1044
1049
 
1045
1050
  // If a component gets moved into a different window, an update cycle might still be running.
1046
1051
  // Since the update might no longer get mapped, we want to re-enable this instance for future updates.
1047
1052
  if (oldValue) {
1048
- this.isVdomUpdating = false
1053
+ me.isVdomUpdating = false
1049
1054
  }
1050
1055
  }
1051
1056
 
@@ -1,8 +1,6 @@
1
1
  import BaseComponent from '../component/Base.mjs';
2
2
  import VDomUtil from '../util/VDom.mjs';
3
3
 
4
- let isOperaMini = null;
5
-
6
4
  /**
7
5
  * @class Neo.component.Video
8
6
  * @extends Neo.component.Base
@@ -10,7 +8,7 @@ let isOperaMini = null;
10
8
  * @example
11
9
  * ntype : 'video',
12
10
  * url : 'https://video-ssl.itunes.apple.com/itunes-assets/Video125/v4/a0/57/54/a0575426-dd8e-2d25-bdf3-139702870b50/mzvf_786190431362224858.640x464.h264lc.U.p.m4v'
13
- * autoplay: true
11
+ * autoPlay: true
14
12
  *
15
13
  * @methods
16
14
  * play
@@ -36,14 +34,9 @@ class Video extends BaseComponent {
36
34
  * Automatically start the video
37
35
  * Initial setting, which does not make sense to change later
38
36
  * !!Most browsers only support muted autostart
39
- * @member {Boolean} autoplay=false
40
- */
41
- autoplay: false,
42
- /**
43
- * In case the browser does not support the video source the component should show an error.
44
- * @member {String} errorMsg='The browser does not support the video'
37
+ * @member {Boolean} autoPlay=false
45
38
  */
46
- errorMsg: 'Your browser does not support the video tag.',
39
+ autoPlay: false,
47
40
  /**
48
41
  * Current state of the video
49
42
  * @member {Boolean} playing_=false
@@ -115,18 +108,12 @@ class Video extends BaseComponent {
115
108
  * @param {String} value
116
109
  * @param {String|null} oldValue
117
110
  */
118
- async afterSetUrl(value, oldValue) {
111
+ afterSetUrl(value, oldValue) {
119
112
  if (!value) return;
120
113
 
121
114
  let me = this,
122
115
  {vdom} = me,
123
- media = VDomUtil.getFlags(vdom, 'media')[0],
124
- userAgent;
125
-
126
- if (isOperaMini === null) {
127
- userAgent = await Neo.Main.getByPath({path: 'navigator.userAgent'});
128
- isOperaMini = userAgent.includes('Opera Mini');
129
- }
116
+ media = VDomUtil.getFlags(vdom, 'media')[0];
130
117
 
131
118
  media.cn = [{
132
119
  tag : 'source',
@@ -134,14 +121,6 @@ class Video extends BaseComponent {
134
121
  type: me.type
135
122
  }];
136
123
 
137
- // Opera Mini might not support the video-source => check the user agent string
138
- if (isOperaMini) {
139
- media.cn.push({
140
- tag : 'span',
141
- html: me.errorMsg
142
- })
143
- }
144
-
145
124
  this.update()
146
125
  }
147
126
 
@@ -156,17 +135,17 @@ class Video extends BaseComponent {
156
135
  * @protected
157
136
  */
158
137
  handleAutoplay() {
159
- if (!this.autoplay) return;
138
+ if (!this.autoPlay) return;
160
139
 
161
140
  let {vdom} = this,
162
- media = VDomUtil.getFlags(vdom, 'media')[0];
141
+ media = VDomUtil.getFlags(vdom, 'media')[0];
163
142
 
164
143
  // Most browsers require videos to be muted for autoplay to work.
165
144
  media.muted = true;
166
145
  // Allows inline playback on iOS devices
167
146
  media.playsInline = true;
168
147
 
169
- this.playing = true;
148
+ this.playing = true
170
149
  }
171
150
 
172
151
  /**
@@ -222,7 +222,8 @@ class Base extends Component {
222
222
  afterSetWindowId(value, oldValue) {
223
223
  super.afterSetWindowId(value, oldValue);
224
224
 
225
- let me = this;
225
+ let me = this,
226
+ {layout} = me;
226
227
 
227
228
  value && me.items?.forEach(item => {
228
229
  if (!Neo.isString(item)) {
@@ -230,8 +231,8 @@ class Base extends Component {
230
231
  }
231
232
  })
232
233
 
233
- if (value && me.layout) {
234
- me.layout.windowId = value
234
+ if (value && layout && !Neo.isString(layout)) {
235
+ layout.windowId = value
235
236
  }
236
237
  }
237
238
 
@@ -286,14 +286,15 @@ class Base extends Panel {
286
286
  afterSetResizable(value, oldValue) {
287
287
  if (value && !this.getPlugin('resizable')) {
288
288
  import('../plugin/Resizable.mjs').then(module => {
289
- let me = this,
290
- {appName} = me,
291
- plugins = me.plugins || [];
289
+ let me = this,
290
+ {appName, windowId} = me,
291
+ plugins = me.plugins || [];
292
292
 
293
293
  plugins.push({
294
294
  module : module.default,
295
295
  appName,
296
296
  delegationCls: 'neo-dialog',
297
+ windowId,
297
298
  ...me.resizablePluginConfig
298
299
  });
299
300
 
@@ -326,6 +327,27 @@ class Base extends Panel {
326
327
  this.syncTrapFocus()
327
328
  }
328
329
 
330
+ /**
331
+ * Triggered after the windowId config got changed
332
+ * @param {Number|null} value
333
+ * @param {Number|null} oldValue
334
+ * @protected
335
+ */
336
+ afterSetWindowId(value, oldValue) {
337
+ let me = this,
338
+ resizable = me.getPlugin('resizable');
339
+
340
+ if (me.dragZone) {
341
+ me.dragZone.windowId = value
342
+ }
343
+
344
+ if (resizable) {
345
+ resizable.windowId = value
346
+ }
347
+
348
+ super.afterSetWindowId(value, oldValue)
349
+ }
350
+
329
351
  /**
330
352
  *
331
353
  */
@@ -480,9 +502,10 @@ class Base extends Panel {
480
502
  *
481
503
  */
482
504
  createHeader() {
483
- let me = this,
484
- cls = ['neo-header-toolbar', 'neo-toolbar'],
485
- headers = me.headers || [];
505
+ let me = this,
506
+ {windowId} = me,
507
+ cls = ['neo-header-toolbar', 'neo-toolbar'],
508
+ headers = me.headers || [];
486
509
 
487
510
  me.draggable && cls.push('neo-draggable');
488
511
 
@@ -495,6 +518,7 @@ class Base extends Panel {
495
518
  id : me.getHeaderToolbarId(),
496
519
  listeners: {headerAction: me.executeHeaderAction, scope: me},
497
520
  title : me.title,
521
+ windowId,
498
522
  ...me.headerConfig
499
523
  });
500
524
 
@@ -661,8 +685,9 @@ class Base extends Panel {
661
685
  * @param data
662
686
  */
663
687
  onDragStart(data) {
664
- let me = this,
665
- style = me.style || {};
688
+ let me = this,
689
+ {windowId} = me,
690
+ style = me.style || {};
666
691
 
667
692
  if (!me.maximized) {
668
693
  me.isDragging = true;
@@ -679,6 +704,7 @@ class Base extends Panel {
679
704
  dragProxyConfig : {vdom: me.getProxyVdom()},
680
705
  owner : me,
681
706
  useProxyWrapper : false,
707
+ windowId,
682
708
  ...me.dragZoneConfig
683
709
  });
684
710
 
@@ -144,7 +144,11 @@ class DragZone extends Base {
144
144
  * True creates a position:absolute wrapper div which contains the cloned element
145
145
  * @member {Boolean} useProxyWrapper=true
146
146
  */
147
- useProxyWrapper: true
147
+ useProxyWrapper: true,
148
+ /**
149
+ * @member {Number|null} windowId_=null
150
+ */
151
+ windowId_: null
148
152
  }
149
153
 
150
154
  /**
@@ -159,15 +163,13 @@ class DragZone extends Base {
159
163
  }
160
164
 
161
165
  /**
162
- * Triggered after the appName config got changed
163
- * @param {String|null} value
164
- * @param {String|null} oldValue
166
+ * Triggered after the windowId config got changed
167
+ * @param {Number|null} value
168
+ * @param {Number|null} oldValue
165
169
  * @protected
166
170
  */
167
- afterSetAppName(value, oldValue) {
168
- if (value) {
169
- Neo.currentWorker.insertThemeFiles(value, this.owner.windowId, this.__proto__)
170
- }
171
+ afterSetWindowId(value, oldValue) {
172
+ value && Neo.currentWorker.insertThemeFiles(value, this.__proto__)
171
173
  }
172
174
 
173
175
  /**
@@ -901,6 +901,8 @@ class Text extends Base {
901
901
  * @protected
902
902
  */
903
903
  afterSetWindowId(value, oldValue) {
904
+ super.afterSetWindowId(value, oldValue);
905
+
904
906
  value && this.triggers?.forEach(item => {
905
907
  item.windowId = value
906
908
  })
@@ -94,6 +94,20 @@ class Time extends Picker {
94
94
  this.clock.time = value
95
95
  }
96
96
  }
97
+
98
+ /**
99
+ * Triggered after the windowId config got changed
100
+ * @param {Number} value
101
+ * @param {Number|null} oldValue
102
+ * @protected
103
+ */
104
+ afterSetWindowId(value, oldValue) {
105
+ super.afterSetWindowId(value, oldValue);
106
+
107
+ if (value) {
108
+ this.clock.windowId = value
109
+ }
110
+ }
97
111
  }
98
112
 
99
113
  export default Neo.setupClass(Time);
@@ -25,7 +25,7 @@ class Base extends CoreBase {
25
25
  */
26
26
  appName_: null,
27
27
  /**
28
- * The Id of the Container instance this layout is bound to
28
+ * The id of the Container instance this layout is bound to
29
29
  * @member {?String} containerId=null
30
30
  * @protected
31
31
  */
@@ -43,9 +43,9 @@ class Base extends CoreBase {
43
43
  */
44
44
  isLayout: true,
45
45
  /**
46
- * @member {Number|null} windowId=null
46
+ * @member {Number|null} windowId_=null
47
47
  */
48
- windowId: null
48
+ windowId_: null
49
49
  }
50
50
 
51
51
  /**
@@ -59,13 +59,13 @@ class Base extends CoreBase {
59
59
  }
60
60
 
61
61
  /**
62
- * Triggered after the appName config got changed
63
- * @param {String|null} value
64
- * @param {String|null} oldValue
62
+ * Triggered after the windowId config got changed
63
+ * @param {Number} value
64
+ * @param {Number|null} oldValue
65
65
  * @protected
66
66
  */
67
- afterSetAppName(value, oldValue) {
68
- value && Neo.currentWorker.insertThemeFiles(value, this.container.windowId, this.__proto__)
67
+ afterSetWindowId(value, oldValue) {
68
+ value && Neo.currentWorker.insertThemeFiles(value, this.__proto__)
69
69
  }
70
70
 
71
71
  /**
@@ -37,6 +37,20 @@ class Component extends Base {
37
37
  })
38
38
  }
39
39
 
40
+ /**
41
+ * Triggered after the windowId config got changed
42
+ * @param {Number|null} value
43
+ * @param {Number|null} oldValue
44
+ * @protected
45
+ */
46
+ afterSetWindowId(value, oldValue) {
47
+ super.afterSetWindowId(value, oldValue);
48
+
49
+ value && this.items?.forEach(item => {
50
+ item.windowId = value
51
+ })
52
+ }
53
+
40
54
  /**
41
55
  *
42
56
  */
@@ -136,7 +136,7 @@ class PrefixField extends Base {
136
136
  ]);
137
137
 
138
138
  me.owner.on('mounted', () => {
139
- Neo.currentWorker.insertThemeFiles(owner.appName, owner.windowId, me.__proto__)
139
+ Neo.currentWorker.insertThemeFiles(owner.windowId, me.__proto__)
140
140
  }, me, {once: true})
141
141
  }
142
142
 
@@ -164,7 +164,11 @@ class Resizable extends Base {
164
164
  * @member {Object} targetNode=null
165
165
  * @protected
166
166
  */
167
- targetNode: null
167
+ targetNode: null,
168
+ /**
169
+ * @member {Number|null} windowId_=null
170
+ */
171
+ windowId_: null
168
172
  }
169
173
 
170
174
  /**
@@ -228,14 +232,24 @@ class Resizable extends Base {
228
232
  * @protected
229
233
  */
230
234
  afterSetAppName(value, oldValue) {
235
+ if (this.dragZone) {
236
+ this.dragZone.appName = value
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Triggered after the windowId config got changed
242
+ * @param {Number} value
243
+ * @param {Number|null} oldValue
244
+ * @protected
245
+ */
246
+ afterSetWindowId(value, oldValue) {
231
247
  let me = this;
232
248
 
233
- if (value) {
234
- Neo.currentWorker.insertThemeFiles(value, me.owner.windowId, me.__proto__)
235
- }
249
+ value && Neo.currentWorker.insertThemeFiles(value, me.__proto__)
236
250
 
237
251
  if (me.dragZone) {
238
- me.dragZone.appName = value
252
+ me.dragZone.windowId = value
239
253
  }
240
254
  }
241
255
 
@@ -464,9 +464,11 @@ class Button extends BaseButton {
464
464
 
465
465
  /**
466
466
  * @param {Object} data
467
+ * @param {Neo.button.Base} data.column
467
468
  * @param {String} data.dataField
468
469
  * @param {Number} data.index
469
470
  * @param {Object} data.record
471
+ * @param {Neo.table.Container} data.tableContainer
470
472
  * @param {Number|String} data.value
471
473
  * @returns {*}
472
474
  */
@@ -112,12 +112,27 @@ class Base extends Container {
112
112
  appName : me.appName,
113
113
  boundaryContainerId: me.id,
114
114
  owner : me,
115
+ windowId : me.windowId,
115
116
  ...me.sortZoneConfig
116
117
  })
117
118
  })
118
119
  }
119
120
  }
120
121
 
122
+ /**
123
+ * Triggered after the windowId config got changed
124
+ * @param {Number|null} value
125
+ * @param {Number|null} oldValue
126
+ * @protected
127
+ */
128
+ afterSetWindowId(value, oldValue) {
129
+ super.afterSetWindowId(value, oldValue);
130
+
131
+ if (this.sortZone) {
132
+ this.sortZone.windowId = value
133
+ }
134
+ }
135
+
121
136
  /**
122
137
  * Checks if the new dock position matches a value of the static dockPositions config
123
138
  * @param {String} value
@@ -275,12 +275,11 @@ class App extends Base {
275
275
 
276
276
  /**
277
277
  * In case you don't want to include prototype based CSS files, use the className param instead
278
- * @param {String} appName
279
278
  * @param {Number} windowId
280
279
  * @param {Neo.core.Base} [proto]
281
280
  * @param {String} [className]
282
281
  */
283
- insertThemeFiles(appName, windowId, proto, className) {
282
+ insertThemeFiles(windowId, proto, className) {
284
283
  if (Neo.config.themes.length > 0) {
285
284
  className = className || proto.className;
286
285
  //console.log(windowId, className);
@@ -290,7 +289,7 @@ class App extends Base {
290
289
  classPath, classRoot, fileName, lClassRoot, mapClassName, ns, themeFolders;
291
290
 
292
291
  if (!cssMap) {
293
- me.themeFilesCache.push([appName, windowId, proto])
292
+ me.themeFilesCache.push([windowId, proto])
294
293
  } else {
295
294
  // we need to modify app related class names
296
295
  if (!className.startsWith('Neo.')) {
@@ -306,7 +305,7 @@ class App extends Base {
306
305
 
307
306
  if (parent && parent !== Neo.core.Base.prototype) {
308
307
  if (!Neo.ns(`${windowId}.${parent.className}`, false, cssMap)) {
309
- me.insertThemeFiles(appName, windowId, parent)
308
+ me.insertThemeFiles(windowId, parent)
310
309
  }
311
310
  }
312
311
 
@@ -321,7 +320,6 @@ class App extends Base {
321
320
  ns[fileName] = true;
322
321
 
323
322
  Neo.main.addon.Stylesheet.addThemeFiles({
324
- appName,
325
323
  className: mapClassName || className,
326
324
  folders : themeFolders,
327
325
  windowId