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.
- package/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/view/learn/ContentTreeList.mjs +24 -12
- package/apps/portal/view/learn/LivePreview.mjs +28 -11
- package/buildScripts/createAppMinimal.mjs +391 -0
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/button/base/neo-config.json +2 -1
- package/examples/list/chip/neo-config.json +1 -2
- package/package.json +72 -70
- package/resources/data/deck/learnneo/data/theBeatles.json +22 -0
- package/resources/data/deck/learnneo/p/2023-10-14T19-25-08-153Z.md +29 -20
- package/resources/data/deck/learnneo/p/ComponentModels.md +116 -1
- package/resources/data/deck/learnneo/p/Config.md +157 -0
- package/resources/data/deck/learnneo/p/DescribingTheUI.md +67 -1
- package/resources/data/deck/learnneo/p/Earthquakes.md +214 -0
- package/resources/data/deck/learnneo/p/Events.md +142 -1
- package/resources/data/deck/learnneo/p/Extending.md +116 -1
- package/resources/data/deck/learnneo/p/References.md +126 -0
- package/resources/data/deck/learnneo/p/TestLivePreview.md +28 -6
- package/resources/data/deck/learnneo/t.json +5 -6
- package/resources/data/deck/training/p/2022-12-27T21-55-30-948Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-27T22-23-55-083Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-29T16-00-13-223Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-29T18-34-25-826Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-29T18-36-56-893Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-31T18-43-56-338Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-31T18-51-50-682Z.md +1 -1
- package/resources/data/deck/training/p/2022-12-31T18-54-04-176Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-01T17-49-18-429Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-01T21-23-17-716Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-06T23-21-31-685Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-06T23-34-13-897Z.md +2 -2
- package/resources/data/deck/training/p/2023-01-06T23-46-36-687Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-08T01-24-21-088Z.md +1 -1
- package/resources/data/deck/training/p/2023-01-08T02-11-26-333Z.md +2 -2
- package/resources/data/deck/training/p/2023-01-14T00-40-27-784Z.md +2 -2
- package/resources/data/deck/training/p/2023-07-31T00-37-21-927Z.md +2 -2
- package/resources/data/deck/training/p/2023-10-14T19-25-08-153Z.md +3 -3
- package/resources/scss/src/apps/newwebsite/Viewport.scss +32 -0
- package/resources/scss/src/apps/portal/learn/ContentView.scss +20 -4
- package/resources/scss/src/apps/portal/learn/LivePreview.scss +8 -0
- package/resources/scss/src/component/Base.scss +13 -4
- package/resources/scss/src/form/field/Select.scss +2 -5
- package/resources/scss/src/form/field/Text.scss +0 -1
- package/resources/scss/src/list/Base.scss +47 -2
- package/resources/scss/src/list/Chip.scss +10 -4
- package/resources/scss/theme-dark/list/Base.scss +11 -10
- package/resources/scss/theme-light/list/Base.scss +11 -10
- package/resources/scss/theme-neo-light/design-tokens/Components.scss +3 -0
- package/resources/scss/theme-neo-light/list/Base.scss +1 -0
- package/src/DefaultConfig.mjs +3 -3
- package/src/collection/Base.mjs +4 -0
- package/src/component/Base.mjs +7 -0
- package/src/container/Base.mjs +6 -12
- package/src/core/Base.mjs +5 -2
- package/src/data/Model.mjs +7 -0
- package/src/data/RecordFactory.mjs +5 -4
- package/src/form/field/Base.mjs +11 -0
- package/src/form/field/Picker.mjs +0 -1
- package/src/form/field/Select.mjs +208 -257
- package/src/form/field/Text.mjs +3 -3
- package/src/form/field/trigger/Base.mjs +5 -6
- package/src/layout/Flexbox.mjs +23 -31
- package/src/layout/HBox.mjs +1 -1
- package/src/layout/VBox.mjs +1 -1
- package/src/list/Base.mjs +64 -31
- package/src/main/DomAccess.mjs +55 -28
- package/src/main/DomEvents.mjs +2 -1
- package/src/main/DomUtils.mjs +66 -0
- package/src/main/addon/Navigator.mjs +332 -0
- package/src/manager/DomEvent.mjs +2 -1
- package/src/selection/ListModel.mjs +46 -82
- package/src/selection/Model.mjs +56 -33
- package/src/util/Array.mjs +5 -2
- package/src/util/Function.mjs +31 -0
- package/src/util/String.mjs +9 -0
- package/src/vdom/Helper.mjs +1 -2
- package/test/components/app.mjs +4 -3
- package/test/components/files/component/ChipList.mjs +125 -0
- package/test/components/files/form/field/Select.mjs +177 -2
- package/test/components/siesta.js +34 -1
package/apps/ServiceWorker.mjs
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import ContentStore from '../../store/Content.mjs'
|
2
|
-
import LivePreview
|
3
|
-
import TreeList
|
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 =>
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
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: '
|
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
|
-
|
62
|
-
let source = this.
|
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
|
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
|
-
|
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
|
+
}
|