neo.mjs 6.10.9 → 6.10.11

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 (80) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/portal/view/learn/ContentTreeList.mjs +24 -12
  3. package/apps/portal/view/learn/LivePreview.mjs +28 -11
  4. package/buildScripts/createAppMinimal.mjs +391 -0
  5. package/examples/ServiceWorker.mjs +2 -2
  6. package/examples/button/base/neo-config.json +2 -1
  7. package/examples/list/chip/neo-config.json +1 -2
  8. package/package.json +72 -70
  9. package/resources/data/deck/learnneo/data/theBeatles.json +22 -0
  10. package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +29 -20
  11. package/resources/data/deck/learnneo/p/ComponentModels.md +116 -1
  12. package/resources/data/deck/learnneo/p/Config.md +157 -0
  13. package/resources/data/deck/learnneo/p/DescribingTheUI.md +67 -1
  14. package/resources/data/deck/learnneo/p/Earthquakes.md +214 -0
  15. package/resources/data/deck/learnneo/p/Events.md +142 -1
  16. package/resources/data/deck/learnneo/p/Extending.md +116 -1
  17. package/resources/data/deck/learnneo/p/References.md +126 -0
  18. package/resources/data/deck/learnneo/p/TestLivePreview.md +28 -6
  19. package/resources/data/deck/learnneo/t.json +5 -6
  20. package/resources/data/deck/training/p/2022-12-27T21-55-30-948Z.md +1 -1
  21. package/resources/data/deck/training/p/2022-12-27T22-23-55-083Z.md +1 -1
  22. package/resources/data/deck/training/p/2022-12-29T16-00-13-223Z.md +1 -1
  23. package/resources/data/deck/training/p/2022-12-29T18-34-25-826Z.md +1 -1
  24. package/resources/data/deck/training/p/2022-12-29T18-36-56-893Z.md +1 -1
  25. package/resources/data/deck/training/p/2022-12-31T18-43-56-338Z.md +1 -1
  26. package/resources/data/deck/training/p/2022-12-31T18-51-50-682Z.md +1 -1
  27. package/resources/data/deck/training/p/2022-12-31T18-54-04-176Z.md +1 -1
  28. package/resources/data/deck/training/p/2023-01-01T17-49-18-429Z.md +1 -1
  29. package/resources/data/deck/training/p/2023-01-01T21-23-17-716Z.md +1 -1
  30. package/resources/data/deck/training/p/2023-01-06T23-21-31-685Z.md +1 -1
  31. package/resources/data/deck/training/p/2023-01-06T23-34-13-897Z.md +2 -2
  32. package/resources/data/deck/training/p/2023-01-06T23-46-36-687Z.md +1 -1
  33. package/resources/data/deck/training/p/2023-01-08T01-24-21-088Z.md +1 -1
  34. package/resources/data/deck/training/p/2023-01-08T02-11-26-333Z.md +2 -2
  35. package/resources/data/deck/training/p/2023-01-14T00-40-27-784Z.md +2 -2
  36. package/resources/data/deck/training/p/2023-07-31T00-37-21-927Z.md +2 -2
  37. package/resources/data/deck/training/p/2023-10-14T19-25-08-153Z.md +3 -3
  38. package/resources/scss/src/apps/newwebsite/Viewport.scss +32 -0
  39. package/resources/scss/src/apps/portal/learn/ContentView.scss +20 -4
  40. package/resources/scss/src/apps/portal/learn/LivePreview.scss +8 -0
  41. package/resources/scss/src/component/Base.scss +13 -4
  42. package/resources/scss/src/form/field/Select.scss +2 -5
  43. package/resources/scss/src/form/field/Text.scss +0 -1
  44. package/resources/scss/src/list/Base.scss +47 -2
  45. package/resources/scss/src/list/Chip.scss +10 -4
  46. package/resources/scss/theme-dark/list/Base.scss +11 -10
  47. package/resources/scss/theme-light/list/Base.scss +11 -10
  48. package/resources/scss/theme-neo-light/design-tokens/Components.scss +3 -0
  49. package/resources/scss/theme-neo-light/list/Base.scss +1 -0
  50. package/src/DefaultConfig.mjs +3 -3
  51. package/src/collection/Base.mjs +4 -0
  52. package/src/component/Base.mjs +7 -0
  53. package/src/container/Base.mjs +6 -12
  54. package/src/core/Base.mjs +5 -2
  55. package/src/data/Model.mjs +7 -0
  56. package/src/data/RecordFactory.mjs +5 -4
  57. package/src/form/field/Base.mjs +11 -0
  58. package/src/form/field/Picker.mjs +0 -1
  59. package/src/form/field/Select.mjs +208 -257
  60. package/src/form/field/Text.mjs +3 -3
  61. package/src/form/field/trigger/Base.mjs +5 -6
  62. package/src/layout/Flexbox.mjs +23 -31
  63. package/src/layout/HBox.mjs +1 -1
  64. package/src/layout/VBox.mjs +1 -1
  65. package/src/list/Base.mjs +64 -31
  66. package/src/main/DomAccess.mjs +55 -28
  67. package/src/main/DomEvents.mjs +2 -1
  68. package/src/main/DomUtils.mjs +66 -0
  69. package/src/main/addon/Navigator.mjs +332 -0
  70. package/src/manager/DomEvent.mjs +2 -1
  71. package/src/selection/ListModel.mjs +46 -82
  72. package/src/selection/Model.mjs +56 -33
  73. package/src/util/Array.mjs +5 -2
  74. package/src/util/Function.mjs +31 -0
  75. package/src/util/String.mjs +9 -0
  76. package/src/vdom/Helper.mjs +1 -2
  77. package/test/components/app.mjs +4 -3
  78. package/test/components/files/component/ChipList.mjs +125 -0
  79. package/test/components/files/form/field/Select.mjs +177 -2
  80. package/test/components/siesta.js +34 -1
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.10.9'
23
+ * @member {String} version='6.10.11'
24
24
  */
25
- version: '6.10.9'
25
+ version: '6.10.11'
26
26
  }
27
27
 
28
28
  /**
@@ -1,6 +1,6 @@
1
1
  import ContentStore from '../../store/Content.mjs'
2
- import LivePreview from './LivePreview.mjs';
3
- import TreeList from '../../../../src/tree/List.mjs';
2
+ import LivePreview from './LivePreview.mjs';
3
+ import TreeList from '../../../../src/tree/List.mjs';
4
4
 
5
5
  /**
6
6
  * @class Portal.view.learn.ContentTreeList
@@ -57,14 +57,17 @@ class ContentTreeList extends TreeList {
57
57
 
58
58
  await Neo.main.addon.Markdown.markdownToHtml(modifiedHtml)
59
59
  .then(
60
- html => me.fire('contentChange', {
61
- component: me,
62
- html,
63
- record,
64
- isLab: record.name?.startsWith('Lab:')
65
- }),
60
+ html => {
61
+ html = me.insertLabDivs(html);
62
+ me.fire('contentChange', {
63
+ component: me,
64
+ html,
65
+ record,
66
+ isLab: record.name?.startsWith('Lab:')
67
+ });
68
+ },
66
69
  () => me.fire('contentChange', {component: me}));
67
- await this.timeout(50);
70
+ await this.timeout(50); // Do we need this?
68
71
  Object.keys(neoDivs).forEach(key => {
69
72
  // Create LivePreview for each iteration, set value to neoDivs[key]
70
73
  let foo = Neo.create(LivePreview, {
@@ -72,7 +75,6 @@ class ContentTreeList extends TreeList {
72
75
  parentId: key,
73
76
  appName: this.appName
74
77
  })
75
- console.log(foo);
76
78
  });
77
79
  }
78
80
  }
@@ -89,12 +91,23 @@ class ContentTreeList extends TreeList {
89
91
  var updatedHtml = htmlString.replace(preRegex, (match, preContent) => {
90
92
  const key = `pre-live-preview-${Neo.core.IdGenerator.getId()}-${count++}`;
91
93
  map[key] = preContent;
92
- return `<div id="${key}"/>`;
94
+ return `<div id="${key}"></div>`;
93
95
  });
94
96
  return updatedHtml;
95
97
 
96
98
  }
97
99
 
100
+ insertLabDivs(inputString) {
101
+ // Replace <!-- lab --> with <div class="lab">
102
+ let modifiedString = inputString.replace(/<!--\s*lab\s*-->/g, '<div class="lab">');
103
+
104
+ // Replace <!-- /lab --> with </div>
105
+ modifiedString = modifiedString.replace(/<!--\s*\/lab\s*-->/g, '</div>');
106
+
107
+ return modifiedString;
108
+
109
+ }
110
+
98
111
  async highlightPreContent(htmlString) {
99
112
  // 1. Replace <pre data-javascript> with unique tokens and create a HighlightJS.highlightAuto promise for each
100
113
  // 2. When all promises are resolved, use their values to replace the tokens.
@@ -169,7 +182,6 @@ class ContentTreeList extends TreeList {
169
182
  me.deck = search.deck || 'learnneo';
170
183
 
171
184
  me.doLoadStore();
172
- console.log(search);
173
185
  })
174
186
  }
175
187
 
@@ -13,6 +13,7 @@ class LivePreview extends Base {
13
13
  * @protected
14
14
  */
15
15
  className: 'Portal.view.learn.LivePreview',
16
+ baseCls: ['learn-live-preview'],
16
17
  value_: null,
17
18
  autoMount: true,
18
19
  autoRender: true,
@@ -22,18 +23,20 @@ class LivePreview extends Base {
22
23
  * @member {Object[]} items
23
24
  */
24
25
  items: [{
25
- module : TabContainer,
26
+ module: TabContainer,
26
27
  reference: 'tab-container',
27
28
  cls: 'live-preview-container',
28
-
29
29
  items: [{
30
30
  module: TextArea,
31
31
  hideLabel: true,
32
32
  style: {height: '100%'},
33
33
  reference: 'textArea',
34
34
  tabButtonConfig: {
35
- text: 'Editor'
35
+ text: 'Source'
36
36
  },
37
+ listeners: {
38
+ change: data => data.component.up({className: 'Portal.view.learn.LivePreview'}).value = data.value
39
+ }
37
40
  }, {
38
41
  tabButtonConfig: {
39
42
  text: 'Preview'
@@ -58,10 +61,8 @@ class LivePreview extends Base {
58
61
  me.getReference('tab-container').on('activeIndexChange', me.onActiveIndexChange, me)
59
62
  }
60
63
 
61
- doIt(button) {
62
- let source = this.getReference('source').getValue();
63
-
64
- this.getReference('codePreview').src = source;
64
+ doRunSource() {
65
+ let source = this.value;
65
66
 
66
67
  const importRegex = /import\s+([\w-]+)\s+from\s+['"]([^'"]+)['"]/;
67
68
  const exportRegex = /export\s+(?:default\s+)?(?:const|let|var|class|function|async\s+function|generator\s+function|async\s+generator\s+function|(\{[\s\S]*?\}))/g;
@@ -73,6 +74,7 @@ class LivePreview extends Base {
73
74
 
74
75
  const moduleNameAndPath = [];
75
76
 
77
+ const className = this.findLastClassName(source);
76
78
  source.split('\n').forEach(line => {
77
79
  let importMatch = line.match(importRegex);
78
80
  if (importMatch) {
@@ -123,13 +125,11 @@ class LivePreview extends Base {
123
125
  .then(([${params.join(', ')}]) => {
124
126
  ${vars.join('\n')}
125
127
  ${cleanLines.join('\n')}
126
- container.add({module:Bar});
128
+ if (${className} && Neo.component.Base.isPrototypeOf(${className})) container.add({module:${className}});
127
129
  })
128
130
  .catch(error=>container.add({ntype:'component',html:error.message}));
129
131
  `;
130
132
 
131
- // console.log(codeString);
132
-
133
133
  const container = this.getReference('preview');
134
134
  container.removeAll();
135
135
  try {
@@ -176,7 +176,24 @@ class LivePreview extends Base {
176
176
  * @param {Number} data.value
177
177
  */
178
178
  onActiveIndexChange(data) {
179
- console.log('onActiveIndexChange', data)
179
+ if (data.item.reference !== 'preview') return;
180
+ this.doRunSource();
181
+ }
182
+ findLastClassName(sourceCode) {
183
+ // Define a regular expression to match class declarations
184
+ const classDeclarationRegex = /class\s+([a-zA-Z$_][a-zA-Z0-9$_]*)\s*(?:extends\s+[a-zA-Z$_][a-zA-Z0-9$_]*)?\s*{[\s\S]*?}/g;
185
+
186
+ let match;
187
+ let lastClassName = null;
188
+
189
+ // Iterate through all matches of the regular expression
190
+ while ((match = classDeclarationRegex.exec(sourceCode)) !== null) {
191
+ // Update the last class name found
192
+ lastClassName = match[1];
193
+ }
194
+
195
+ return lastClassName;
196
+
180
197
  }
181
198
  }
182
199
 
@@ -0,0 +1,391 @@
1
+ import chalk from 'chalk';
2
+ import { spawnSync } from 'child_process';
3
+ import { Command } from 'commander/esm.mjs';
4
+ import envinfo from 'envinfo';
5
+ import fs from 'fs-extra';
6
+ import inquirer from 'inquirer';
7
+ import os from 'os';
8
+ import path from 'path';
9
+
10
+ const __dirname = path.resolve(),
11
+ cwd = process.cwd(),
12
+ requireJson = path => JSON.parse(fs.readFileSync((path))),
13
+ packageJson = requireJson(path.join(__dirname, 'package.json')),
14
+ insideNeo = packageJson.name === 'neo.mjs',
15
+ neoPath = insideNeo ? './' : './node_modules/neo.mjs/',
16
+ addonChoices = fs.readdirSync(path.join(neoPath, '/src/main/addon')).map(item => item.slice(0, -4)),
17
+ program = new Command(),
18
+ programName = `${packageJson.name} create-app`,
19
+ questions = [],
20
+ scssFolders = fs.readdirSync(path.join(neoPath, '/resources/scss')),
21
+ themeFolders = [];
22
+
23
+ scssFolders.forEach(folder => {
24
+ if (folder.includes('theme')) {
25
+ themeFolders.push(`neo-${folder}`);
26
+ }
27
+ });
28
+
29
+ program
30
+ .name(programName)
31
+ .version(packageJson.version)
32
+ .option('-i, --info', 'print environment debug info')
33
+ .option('-a, --appName <value>')
34
+ .option('-m, --mainThreadAddons <value>', `Comma separated list of:\n${addonChoices.join(', ')}\nDefaults to DragDrop, Stylesheet`)
35
+ .option('-s, --useServiceWorker <value>', '"yes", "no"')
36
+ .option('-t, --themes <value>', ['all', ...themeFolders, 'none'].join(", "))
37
+ .option('-u, --useSharedWorkers <value>', '"yes", "no"')
38
+ .allowUnknownOption()
39
+ .on('--help', () => {
40
+ console.log('\nIn case you have any issues, please create a ticket here:');
41
+ console.log(chalk.cyan(process.env.npm_package_bugs_url));
42
+ })
43
+ .parse(process.argv);
44
+
45
+ const programOpts = program.opts();
46
+
47
+ if (programOpts.info) {
48
+ console.log(chalk.bold('\nEnvironment Info:'));
49
+ console.log(`\n current version of ${packageJson.name}: ${packageJson.version}`);
50
+ console.log(` running from ${__dirname}`);
51
+
52
+ envinfo
53
+ .run({
54
+ System: ['OS', 'CPU'],
55
+ Binaries: ['Node', 'npm', 'Yarn'],
56
+ Browsers: ['Chrome', 'Edge', 'Firefox', 'Safari'],
57
+ npmPackages: ['neo.mjs']
58
+ }, {
59
+ duplicates: true,
60
+ showNotFound: true
61
+ })
62
+ .then(console.log);
63
+ } else {
64
+ console.log(chalk.green(programName));
65
+
66
+ if (programOpts.mainThreadAddons) {
67
+ programOpts.mainThreadAddons = programOpts.mainThreadAddons.split(',');
68
+ }
69
+
70
+ if (!programOpts.appName) {
71
+ questions.push({
72
+ type: 'input',
73
+ name: 'appName',
74
+ message: 'Please choose a name for your neo app:',
75
+ default: 'MyApp'
76
+ });
77
+ }
78
+
79
+ if (!programOpts.themes) {
80
+ questions.push({
81
+ type: 'list',
82
+ name: 'themes',
83
+ message: 'Please choose a theme for your neo app:',
84
+ choices: ['all', ...themeFolders, 'none'],
85
+ default: 'all'
86
+ });
87
+ }
88
+
89
+ if (!programOpts.mainThreadAddons) {
90
+ questions.push({
91
+ type: 'checkbox',
92
+ name: 'mainThreadAddons',
93
+ message: 'Please choose your main thread addons:',
94
+ choices: addonChoices,
95
+ default: ['DragDrop', 'Stylesheet']
96
+ });
97
+ }
98
+
99
+ if (!programOpts.useSharedWorkers) {
100
+ questions.push({
101
+ type: 'list',
102
+ name: 'useSharedWorkers',
103
+ message: 'Do you want to use SharedWorkers? Pick yes for multiple main threads (Browser Windows):',
104
+ choices: ['yes', 'no'],
105
+ default: 'no'
106
+ });
107
+ }
108
+
109
+ if (!programOpts.useServiceWorker) {
110
+ questions.push({
111
+ type: 'list',
112
+ name: 'useServiceWorker',
113
+ message: 'Do you want to use a ServiceWorker for caching assets?',
114
+ choices: ['yes', 'no'],
115
+ default: 'no'
116
+ });
117
+ }
118
+
119
+ inquirer.prompt(questions).then(answers => {
120
+ let appName = programOpts.appName || answers.appName,
121
+ mainThreadAddons = programOpts.mainThreadAddons || answers.mainThreadAddons,
122
+ themes = programOpts.themes || answers.themes,
123
+ useSharedWorkers = programOpts.useSharedWorkers || answers.useSharedWorkers,
124
+ useServiceWorker = programOpts.useServiceWorker || answers.useServiceWorker,
125
+ lAppName = appName.toLowerCase(),
126
+ appPath = 'apps/' + lAppName + '/',
127
+ dir = 'apps/' + lAppName,
128
+ folder = path.resolve(cwd, dir),
129
+ startDate = new Date();
130
+
131
+ if (!Array.isArray(themes)) {
132
+ themes = [themes];
133
+ }
134
+
135
+ if (themes.length > 0 && !themes.includes('none') && !mainThreadAddons.includes('Stylesheet')) {
136
+ console.error('ERROR! The Stylesheet mainThreadAddon is mandatory in case you are using themes');
137
+ console.log('Exiting with error.');
138
+ process.exit(1);
139
+ }
140
+
141
+ fs.mkdir(path.join(folder, '/view'), {recursive: true}, (err) => {
142
+ if (err) {
143
+ throw err;
144
+ }
145
+
146
+ let content, className;
147
+ const neoSrcPath = `../../../${insideNeo ? '' : 'node_modules/neo.mjs/'}src`;
148
+
149
+ const appContent = [
150
+ "import Viewport from './view/Viewport.mjs';",
151
+ "",
152
+ "export const onStart = () => Neo.app({",
153
+ " mainView: Viewport,",
154
+ " name : '" + appName + "'",
155
+ "});"
156
+ ].join(os.EOL);
157
+
158
+ fs.writeFileSync(folder + '/app.mjs', appContent);
159
+
160
+ const indexContent = `
161
+ <!DOCTYPE HTML>
162
+ <html>
163
+ <head>
164
+ <meta name="viewport" content="width=device-width, initial-scale=1">
165
+ <meta charset="UTF-8">
166
+ <title>${appName}</title>
167
+ </head>
168
+ <body>
169
+ <script src="../../src/MicroLoader.mjs" type="module"></script>
170
+ <script>
171
+ new MutationObserver((mutationsList, observer) => {
172
+ for (let mutation of mutationsList) {
173
+ for (let addedNode of mutation.addedNodes) {
174
+ if (addedNode.className && addedNode.className.includes(\'neo-viewport\')) {
175
+ addedNode.addEventListener("contextmenu", function (e) {
176
+ if (!(e.ctrlKey || e.metaKey)) return;
177
+ e.stopPropagation();
178
+ e.preventDefault();
179
+ const event = new Event('neo-debug-item-select', {bubbles: true});
180
+ e.target.dispatchEvent(event);
181
+ });
182
+ observer.disconnect(); // We found the viewport so we\'re finished listening
183
+ }
184
+ }
185
+ }
186
+ }).observe(document.body, {childList: true, subtree: false});
187
+ </script>
188
+ </body>
189
+ </html>
190
+ `;
191
+ fs.writeFileSync(path.join(folder, 'index.html'), indexContent);
192
+
193
+
194
+
195
+ let neoConfig = {
196
+ appPath: `${insideNeo ? '' : '../../'}${appPath}app.mjs`,
197
+ basePath: '../../',
198
+ environment: 'development',
199
+ mainPath: `${insideNeo ? './' : '../node_modules/neo.mjs/src/'}Main.mjs`
200
+ };
201
+
202
+ if (!(mainThreadAddons.includes('DragDrop') && mainThreadAddons.includes('Stylesheet') && mainThreadAddons.length === 2)) {
203
+ neoConfig.mainThreadAddons = mainThreadAddons;
204
+ }
205
+
206
+ if (!themes.includes('all')) { // default value
207
+ if (themes.includes('none')) {
208
+ neoConfig.themes = [];
209
+ } else {
210
+ neoConfig.themes = themes;
211
+ }
212
+ }
213
+
214
+ if (useSharedWorkers !== 'no') {
215
+ neoConfig.useSharedWorkers = true;
216
+ }
217
+
218
+ if (useServiceWorker !== 'no') {
219
+ neoConfig.useServiceWorker = true;
220
+ }
221
+
222
+ if (!insideNeo) {
223
+ neoConfig.workerBasePath = '../../node_modules/neo.mjs/src/worker/';
224
+ }
225
+
226
+ let configs = Object.entries(neoConfig).sort((a, b) => a[0].localeCompare(b[0]));
227
+ neoConfig = {};
228
+
229
+ configs.forEach(([key, value]) => {
230
+ neoConfig[key] = value;
231
+ });
232
+
233
+ fs.writeFileSync(path.join(folder, 'neo-config.json'), JSON.stringify(neoConfig, null, 4));
234
+
235
+ // App source files: viewport and main view
236
+
237
+
238
+
239
+
240
+ // -------------------------------------------------------------------------
241
+
242
+ className = 'Viewport';
243
+ content = `
244
+ import Base from '${neoSrcPath}/container/Viewport.mjs';
245
+ import MainView from './MainView.mjs';
246
+
247
+ class ${className} extends Base {
248
+ static config = {
249
+ className: '${appName}.view.${className}',
250
+ autoMount: true,
251
+ layout: {ntype: 'fit'},
252
+ items: [{module:MainView}],
253
+ }
254
+ afterSetMounted(value, oldValue) {
255
+ super.afterSetMounted(value, oldValue);
256
+ if (!value) return;
257
+ this.addDomListeners({
258
+ "neo-debug-item-select": (event) => {
259
+ event.path.forEach((item) => {
260
+ const component = Neo.getComponent(item.id);
261
+ if (component) console.log(component);
262
+ });
263
+ },
264
+ });
265
+ }
266
+ }
267
+ Neo.applyClassConfig(${className});
268
+ export default ${className};
269
+ `;
270
+ fs.writeFileSync(path.join(`${folder}/view/${className}.mjs`), content);
271
+
272
+
273
+
274
+
275
+ // -------------------------------------------------------------------------
276
+
277
+ className = 'MainView';
278
+ content = `
279
+ import Base from '${neoSrcPath}/container/Base.mjs';
280
+ import Controller from './${className}Controller.mjs';
281
+ import ViewModel from './${className}Model.mjs';
282
+
283
+ class ${className} extends Base {
284
+ static config = {
285
+ className: '${appName}.view.${className}',
286
+
287
+ controller: {module: Controller},
288
+ model: {module: ViewModel},
289
+
290
+ layout: {ntype: 'fit'},
291
+ items: [],
292
+ }
293
+ }
294
+
295
+ Neo.applyClassConfig(${className});
296
+
297
+ export default ${className};
298
+ `;
299
+ fs.writeFileSync(path.join(`${folder}/view/${className}.mjs`), content);
300
+
301
+
302
+
303
+
304
+
305
+ // -------------------------------------------------------------------------
306
+
307
+ className = 'MainViewController';
308
+ content = `
309
+ import Base from '${neoSrcPath}/controller/Component.mjs';
310
+
311
+ class ${className} extends Base {
312
+ static config = {
313
+ className: '${appName}.view.${className}',
314
+ }
315
+ }
316
+
317
+ Neo.applyClassConfig(${className});
318
+
319
+ export default ${className};
320
+ `;
321
+ fs.writeFileSync(path.join(`${folder}/view/${className}.mjs`), content);
322
+
323
+
324
+
325
+
326
+
327
+ // -------------------------------------------------------------------------
328
+
329
+ className = 'MainViewModel';
330
+ content = `
331
+ import Base from '${neoSrcPath}/model/Component.mjs';
332
+
333
+ class ${className} extends Base {
334
+ static config = {
335
+ className: '${appName}.view.${className}',
336
+
337
+ data: {}
338
+ }
339
+ }
340
+
341
+ Neo.applyClassConfig(${className});
342
+
343
+ export default ${className};
344
+ `;
345
+ fs.writeFileSync(path.join(`${folder}/view/${className}.mjs`), content);
346
+
347
+
348
+
349
+
350
+
351
+ // -------------------------------------------------------------------------
352
+
353
+ let appJsonPath = path.resolve(cwd, 'buildScripts/myApps.json'),
354
+ appJson;
355
+
356
+ if (fs.existsSync(appJsonPath)) {
357
+ appJson = requireJson(appJsonPath);
358
+ } else {
359
+ appJsonPath = path.resolve(__dirname, 'buildScripts/webpack/json/myApps.json');
360
+
361
+ if (fs.existsSync(appJsonPath)) {
362
+ appJson = requireJson(appJsonPath);
363
+ } else {
364
+ appJson = requireJson(path.resolve(__dirname, 'buildScripts/webpack/json/myApps.template.json'));
365
+ }
366
+ }
367
+
368
+ if (!appJson.apps.includes(appName)) {
369
+ appJson.apps.push(appName);
370
+ appJson.apps.sort();
371
+ }
372
+
373
+ fs.writeFileSync(appJsonPath, JSON.stringify(appJson, null, 4));
374
+
375
+ if (mainThreadAddons.includes('HighlightJS')) {
376
+ spawnSync('node', [
377
+ './buildScripts/copyFolder.mjs',
378
+ '-s',
379
+ path.resolve(neoPath, 'docs/resources'),
380
+ '-t',
381
+ path.resolve(folder, 'resources'),
382
+ ], {env: process.env, cwd: process.cwd(), stdio: 'inherit'});
383
+ }
384
+
385
+ const processTime = (Math.round((new Date - startDate) * 100) / 100000).toFixed(2);
386
+ console.log(`\nTotal time for ${programName}: ${processTime} s`);
387
+
388
+ process.exit();
389
+ });
390
+ });
391
+ }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.10.9'
23
+ * @member {String} version='6.10.11'
24
24
  */
25
- version: '6.10.9'
25
+ version: '6.10.11'
26
26
  }
27
27
 
28
28
  /**
@@ -2,5 +2,6 @@
2
2
  "appPath" : "examples/button/base/app.mjs",
3
3
  "basePath" : "../../../",
4
4
  "environment": "development",
5
- "mainPath" : "./Main.mjs"
5
+ "mainPath" : "./Main.mjs",
6
+ "themes" : ["neo-theme-neo-light"]
6
7
  }
@@ -2,6 +2,5 @@
2
2
  "appPath" : "examples/list/chip/app.mjs",
3
3
  "basePath" : "../../../",
4
4
  "environment" : "development",
5
- "mainPath" : "./Main.mjs",
6
- "mainThreadAddons": ["Stylesheet"]
5
+ "mainPath" : "./Main.mjs"
7
6
  }