neo.mjs 10.0.0-beta.1 → 10.0.0-beta.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/ServiceWorker.mjs +2 -2
- package/apps/colors/view/GridContainer.mjs +1 -1
- package/apps/covid/view/AttributionComponent.mjs +1 -1
- package/apps/covid/view/HeaderContainer.mjs +6 -6
- package/apps/covid/view/MainContainerController.mjs +5 -5
- package/apps/covid/view/TableContainerController.mjs +1 -1
- package/apps/covid/view/country/Gallery.mjs +13 -13
- package/apps/covid/view/country/Helix.mjs +13 -13
- package/apps/covid/view/country/HistoricalDataTable.mjs +1 -1
- package/apps/email/view/Viewport.mjs +2 -2
- package/apps/form/view/FormPageContainer.mjs +2 -3
- package/apps/form/view/SideNavList.mjs +1 -1
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_dist_esm.json +1 -1
- package/apps/portal/resources/data/examples_dist_prod.json +2 -2
- package/apps/portal/view/HeaderToolbar.mjs +3 -3
- package/apps/portal/view/about/Container.mjs +2 -2
- package/apps/portal/view/about/MemberContainer.mjs +3 -3
- package/apps/portal/view/blog/List.mjs +7 -7
- package/apps/portal/view/examples/List.mjs +4 -4
- package/apps/portal/view/home/ContentBox.mjs +2 -2
- package/apps/portal/view/home/FeatureSection.mjs +3 -3
- package/apps/portal/view/home/FooterContainer.mjs +7 -7
- package/apps/portal/view/home/parts/AfterMath.mjs +3 -3
- package/apps/portal/view/home/parts/MainNeo.mjs +3 -3
- package/apps/portal/view/home/parts/References.mjs +6 -6
- package/apps/portal/view/learn/ContentComponent.mjs +18 -11
- package/apps/portal/view/learn/PageSectionsContainer.mjs +1 -1
- package/apps/portal/view/learn/PageSectionsList.mjs +2 -2
- package/apps/portal/view/services/Component.mjs +16 -16
- package/apps/realworld/view/FooterComponent.mjs +1 -1
- package/apps/realworld/view/HeaderComponent.mjs +8 -8
- package/apps/realworld/view/HomeComponent.mjs +6 -6
- package/apps/realworld/view/article/CommentComponent.mjs +4 -4
- package/apps/realworld/view/article/Component.mjs +14 -14
- package/apps/realworld/view/article/CreateCommentComponent.mjs +3 -3
- package/apps/realworld/view/article/CreateComponent.mjs +3 -3
- package/apps/realworld/view/article/PreviewComponent.mjs +1 -1
- package/apps/realworld/view/article/TagListComponent.mjs +2 -2
- package/apps/realworld/view/user/ProfileComponent.mjs +8 -8
- package/apps/realworld/view/user/SettingsComponent.mjs +4 -4
- package/apps/realworld/view/user/SignUpComponent.mjs +4 -4
- package/apps/realworld2/view/FooterComponent.mjs +1 -1
- package/apps/realworld2/view/HomeContainer.mjs +3 -3
- package/apps/realworld2/view/article/DetailsContainer.mjs +1 -1
- package/apps/realworld2/view/article/PreviewComponent.mjs +7 -7
- package/apps/realworld2/view/article/TagListComponent.mjs +2 -2
- package/apps/realworld2/view/user/ProfileContainer.mjs +1 -1
- package/apps/route/view/center/CardAdministration.mjs +2 -2
- package/apps/route/view/center/CardAdministrationDenied.mjs +1 -1
- package/apps/route/view/center/CardContact.mjs +2 -2
- package/apps/route/view/center/CardHome.mjs +1 -1
- package/apps/route/view/center/CardSection1.mjs +1 -1
- package/apps/route/view/center/CardSection2.mjs +1 -1
- package/apps/sharedcovid/view/AttributionComponent.mjs +1 -1
- package/apps/sharedcovid/view/HeaderContainer.mjs +6 -6
- package/apps/sharedcovid/view/MainContainerController.mjs +5 -5
- package/apps/sharedcovid/view/TableContainerController.mjs +1 -1
- package/apps/sharedcovid/view/country/Gallery.mjs +13 -13
- package/apps/sharedcovid/view/country/Helix.mjs +13 -13
- package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -1
- package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +1 -1
- package/apps/shareddialog/view/MainContainer.mjs +1 -1
- package/buildScripts/createApp.mjs +2 -2
- package/learn/Glossary.md +261 -0
- package/learn/README.md +9 -14
- package/learn/benefits/ConfigSystem.md +536 -26
- package/learn/benefits/Effort.md +47 -2
- package/learn/benefits/Features.md +50 -32
- package/learn/benefits/FormsEngine.md +54 -24
- package/learn/benefits/MultiWindow.md +31 -5
- package/learn/benefits/Quick.md +45 -12
- package/learn/benefits/RPCLayer.md +75 -0
- package/learn/benefits/Speed.md +17 -12
- package/learn/guides/Collections.md +436 -0
- package/learn/guides/ConfigSystemDeepDive.md +280 -0
- package/learn/guides/CustomComponents.md +256 -14
- package/learn/guides/DeclarativeComponentTreesVsImperativeVdom.md +17 -17
- package/learn/guides/ExtendingNeoClasses.md +331 -0
- package/learn/guides/Forms.md +449 -1
- package/learn/guides/InstanceLifecycle.md +295 -1
- package/learn/guides/Layouts.md +246 -1
- package/learn/guides/MainThreadAddons.md +475 -0
- package/learn/guides/Records.md +286 -0
- package/learn/guides/WorkingWithVDom.md +14 -14
- package/learn/guides/form_fields/ComboBox.md +241 -0
- package/learn/tree.json +57 -51
- package/package.json +2 -2
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +9 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/Main.mjs +8 -7
- package/src/Neo.mjs +16 -2
- package/src/button/Base.mjs +2 -2
- package/src/calendar/view/SettingsContainer.mjs +2 -2
- package/src/calendar/view/YearComponent.mjs +9 -9
- package/src/calendar/view/calendars/ColorsList.mjs +1 -1
- package/src/calendar/view/calendars/List.mjs +1 -1
- package/src/calendar/view/month/Component.mjs +15 -15
- package/src/calendar/view/week/Component.mjs +12 -12
- package/src/calendar/view/week/EventDragZone.mjs +4 -4
- package/src/calendar/view/week/TimeAxisComponent.mjs +3 -3
- package/src/component/Base.mjs +17 -2
- package/src/component/Carousel.mjs +2 -2
- package/src/component/Chip.mjs +3 -3
- package/src/component/Circle.mjs +2 -2
- package/src/component/DateSelector.mjs +8 -8
- package/src/component/Helix.mjs +1 -1
- package/src/component/Label.mjs +3 -18
- package/src/component/Legend.mjs +3 -3
- package/src/component/MagicMoveText.mjs +6 -14
- package/src/component/Process.mjs +3 -3
- package/src/component/Progress.mjs +1 -1
- package/src/component/StatusBadge.mjs +2 -2
- package/src/component/Timer.mjs +2 -2
- package/src/component/Toast.mjs +5 -3
- package/src/container/AccordionItem.mjs +2 -2
- package/src/container/Base.mjs +1 -1
- package/src/core/Base.mjs +18 -2
- package/src/date/DayViewComponent.mjs +2 -2
- package/src/date/SelectorContainer.mjs +1 -1
- package/src/form/field/CheckBox.mjs +4 -4
- package/src/form/field/ComboBox.mjs +6 -1
- package/src/form/field/FileUpload.mjs +25 -39
- package/src/form/field/Range.mjs +1 -1
- package/src/form/field/Text.mjs +3 -3
- package/src/form/field/TextArea.mjs +2 -3
- package/src/grid/Body.mjs +6 -2
- package/src/list/Color.mjs +2 -2
- package/src/main/DeltaUpdates.mjs +157 -98
- package/src/main/addon/AmCharts.mjs +53 -73
- package/src/main/addon/Base.mjs +11 -0
- package/src/main/addon/MonacoEditor.mjs +31 -58
- package/src/manager/ClassHierarchy.mjs +114 -0
- package/src/menu/List.mjs +1 -1
- package/src/plugin/Popover.mjs +2 -2
- package/src/sitemap/Component.mjs +1 -1
- package/src/table/Body.mjs +6 -2
- package/src/tooltip/Base.mjs +1 -6
- package/src/tree/Accordion.mjs +3 -3
- package/src/vdom/Helper.mjs +21 -19
- package/src/worker/App.mjs +1 -2
- package/src/worker/Base.mjs +6 -4
- package/src/worker/Canvas.mjs +2 -3
- package/src/worker/Data.mjs +5 -7
- package/src/worker/Task.mjs +2 -3
- package/src/worker/VDom.mjs +3 -4
- package/src/worker/mixin/RemoteMethodAccess.mjs +4 -1
- package/learn/guides/MainThreadAddonExample.md +0 -15
- package/learn/guides/MainThreadAddonIntro.md +0 -44
@@ -16,6 +16,20 @@ class MonacoEditor extends Base {
|
|
16
16
|
* @protected
|
17
17
|
*/
|
18
18
|
className: 'Neo.main.addon.MonacoEditor',
|
19
|
+
/**
|
20
|
+
* List methods which must get cached until the addon reaches its `isReady` state
|
21
|
+
* @member {String[]} interceptRemotes
|
22
|
+
*/
|
23
|
+
interceptRemotes: [
|
24
|
+
'createInstance',
|
25
|
+
'destroyInstance',
|
26
|
+
'getValue',
|
27
|
+
'layoutEditor',
|
28
|
+
'setLanguage',
|
29
|
+
'setTheme',
|
30
|
+
'setValue',
|
31
|
+
'updateOptions'
|
32
|
+
],
|
19
33
|
/**
|
20
34
|
* @member {String} libraryBasePath='../../node_modules/monaco-editor/min/vs'
|
21
35
|
*/
|
@@ -53,23 +67,18 @@ class MonacoEditor extends Base {
|
|
53
67
|
createInstance(data) {
|
54
68
|
let me = this,
|
55
69
|
{id} = data,
|
56
|
-
|
70
|
+
node = DomAccess.getElement(id),
|
71
|
+
editor;
|
57
72
|
|
58
|
-
|
59
|
-
|
60
|
-
} else {
|
61
|
-
delete data.appName;
|
62
|
-
delete data.id;
|
73
|
+
delete data.appName;
|
74
|
+
delete data.id;
|
63
75
|
|
64
|
-
|
76
|
+
if (node) {
|
77
|
+
editor = me.map[id] = monaco.editor.create(node, data);
|
65
78
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
editor.getModel().onDidChangeContent(me.onContentChange.bind(me, id))
|
70
|
-
} else if (Neo.config.environment === 'development') {
|
71
|
-
console.warn(`addon.MonacoEditor: node ${id} not found`)
|
72
|
-
}
|
79
|
+
editor.getModel().onDidChangeContent(me.onContentChange.bind(me, id))
|
80
|
+
} else if (Neo.config.environment === 'development') {
|
81
|
+
console.warn(`addon.MonacoEditor: node ${id} not found`)
|
73
82
|
}
|
74
83
|
}
|
75
84
|
|
@@ -78,14 +87,8 @@ class MonacoEditor extends Base {
|
|
78
87
|
* @param {String} data.id
|
79
88
|
*/
|
80
89
|
destroyInstance(data) {
|
81
|
-
|
82
|
-
|
83
|
-
if (!me.isReady) {
|
84
|
-
return me.cacheMethodCall({fn: 'destroyInstance', data})
|
85
|
-
} else {
|
86
|
-
// todo: destroy the editor instance if possible
|
87
|
-
delete this.map[data.id]
|
88
|
-
}
|
90
|
+
// todo: destroy the editor instance if possible
|
91
|
+
delete this.map[data.id]
|
89
92
|
}
|
90
93
|
|
91
94
|
/**
|
@@ -94,13 +97,7 @@ class MonacoEditor extends Base {
|
|
94
97
|
* @returns {Object}
|
95
98
|
*/
|
96
99
|
getValue(data) {
|
97
|
-
|
98
|
-
|
99
|
-
if (!me.isReady) {
|
100
|
-
return me.cacheMethodCall({fn: 'getValue', data})
|
101
|
-
} else {
|
102
|
-
return me.map[data.id].getModel().getValue()
|
103
|
-
}
|
100
|
+
return this.map[data.id].getModel().getValue()
|
104
101
|
}
|
105
102
|
|
106
103
|
/**
|
@@ -109,7 +106,7 @@ class MonacoEditor extends Base {
|
|
109
106
|
* @param {String} data.id
|
110
107
|
*/
|
111
108
|
layoutEditor(data) {
|
112
|
-
this.
|
109
|
+
this.map[data.id].layout()
|
113
110
|
}
|
114
111
|
|
115
112
|
/**
|
@@ -154,13 +151,7 @@ class MonacoEditor extends Base {
|
|
154
151
|
* @param {String} data.value
|
155
152
|
*/
|
156
153
|
setLanguage(data) {
|
157
|
-
|
158
|
-
|
159
|
-
if (!me.isReady) {
|
160
|
-
return me.cacheMethodCall({fn: 'setLanguage', data})
|
161
|
-
} else {
|
162
|
-
me.map[data.id].getModel().setLanguage(data.value)
|
163
|
-
}
|
154
|
+
this.map[data.id].getModel().setLanguage(data.value)
|
164
155
|
}
|
165
156
|
|
166
157
|
/**
|
@@ -169,13 +160,7 @@ class MonacoEditor extends Base {
|
|
169
160
|
* @param {String} data.value
|
170
161
|
*/
|
171
162
|
setTheme(data) {
|
172
|
-
|
173
|
-
|
174
|
-
if (!me.isReady) {
|
175
|
-
return me.cacheMethodCall({fn: 'setTheme', data})
|
176
|
-
} else {
|
177
|
-
me.map[data.id]._themeService.setTheme(data.value)
|
178
|
-
}
|
163
|
+
this.map[data.id]._themeService.setTheme(data.value)
|
179
164
|
}
|
180
165
|
|
181
166
|
/**
|
@@ -184,13 +169,7 @@ class MonacoEditor extends Base {
|
|
184
169
|
* @param {String} data.value
|
185
170
|
*/
|
186
171
|
setValue(data) {
|
187
|
-
|
188
|
-
|
189
|
-
if (!me.isReady) {
|
190
|
-
return me.cacheMethodCall({fn: 'setValue', data})
|
191
|
-
} else {
|
192
|
-
me.map[data.id].getModel().setValue(data.value)
|
193
|
-
}
|
172
|
+
this.map[data.id].getModel().setValue(data.value)
|
194
173
|
}
|
195
174
|
|
196
175
|
/**
|
@@ -199,13 +178,7 @@ class MonacoEditor extends Base {
|
|
199
178
|
* @param {Object} data.options
|
200
179
|
*/
|
201
180
|
updateOptions(data) {
|
202
|
-
|
203
|
-
|
204
|
-
if (!me.isReady) {
|
205
|
-
return me.cacheMethodCall({fn: 'updateOptions', data})
|
206
|
-
} else {
|
207
|
-
me.map[data.id].updateOptions(data.options)
|
208
|
-
}
|
181
|
+
this.map[data.id].updateOptions(data.options)
|
209
182
|
}
|
210
183
|
}
|
211
184
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
import BaseManager from './Base.mjs';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @class Neo.manager.ClassHierarchy
|
5
|
+
* @extends Neo.manager.Base
|
6
|
+
* @singleton
|
7
|
+
*
|
8
|
+
* This manager maintains a registry of all classes defined within the Neo.mjs framework's current realm (main or worker),
|
9
|
+
* including their inheritance relationships and key metadata.
|
10
|
+
* Each registered item (value in the manager's store) has the following structure:
|
11
|
+
* @typedef {Object} ClassHierarchyInfo
|
12
|
+
* @property {String} className - The full Neo.mjs class name (e.g., 'Neo.component.Base').
|
13
|
+
* @property {Function|Object} module - The direct reference to the class constructor function itself (for non-singletons)
|
14
|
+
* or the instantiated singleton object (for singletons).
|
15
|
+
* @property {String|null} ntype - The ntype of the class if defined (e.g., 'button', 'container'), otherwise `null`.
|
16
|
+
* @property {String|null} parentClassName - The full class name of its direct parent class,
|
17
|
+
* or `null` if it's a top-level class (e.g., 'Neo.core.Base').
|
18
|
+
*/
|
19
|
+
class ClassHierarchy extends BaseManager {
|
20
|
+
static config = {
|
21
|
+
/**
|
22
|
+
* @member {String} className='Neo.manager.ClassHierarchy'
|
23
|
+
* @protected
|
24
|
+
*/
|
25
|
+
className: 'Neo.manager.ClassHierarchy',
|
26
|
+
/**
|
27
|
+
* @member {String} keyProperty='className'
|
28
|
+
* @protected
|
29
|
+
*/
|
30
|
+
keyProperty: 'className',
|
31
|
+
/**
|
32
|
+
* @member {Boolean} singleton=true
|
33
|
+
* @protected
|
34
|
+
*/
|
35
|
+
singleton: true
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Memoizes the return values of isA() calls
|
40
|
+
* @member {Map} isAQueryMap=new Map()
|
41
|
+
* @protected
|
42
|
+
*/
|
43
|
+
isAQueryMap = new Map()
|
44
|
+
|
45
|
+
/**
|
46
|
+
* @param {Object} config
|
47
|
+
*/
|
48
|
+
construct(config) {
|
49
|
+
super.construct(config);
|
50
|
+
this.consumeTempMap()
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Register all classes that got applied to the Neo namespace before this instance got created
|
55
|
+
* @protected
|
56
|
+
*/
|
57
|
+
consumeTempMap() {
|
58
|
+
if (Neo.classHierarchyMap) {
|
59
|
+
this.add(Object.values(Neo.classHierarchyMap));
|
60
|
+
delete Neo.classHierarchyMap
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Both params represent classNames.
|
66
|
+
*
|
67
|
+
* Example use cases:
|
68
|
+
* - isA('Neo.button.Menu', 'Neo.button.Base') => true
|
69
|
+
* - isA('Neo.button.Base', 'Neo.button.Menu') => false
|
70
|
+
* - isA('Neo.button.Base', 'Neo.component.Base') => true
|
71
|
+
* - isA('Neo.component.Base', 'Neo.core.Base') => true
|
72
|
+
* @param {String} descendant
|
73
|
+
* @param {String} ancestor
|
74
|
+
* @returns {Boolean}
|
75
|
+
*/
|
76
|
+
isA(descendant, ancestor) {
|
77
|
+
if (descendant === ancestor) {
|
78
|
+
return true
|
79
|
+
}
|
80
|
+
|
81
|
+
let parent = descendant,
|
82
|
+
{isAQueryMap} = this,
|
83
|
+
queryName = `${descendant},${ancestor}`,
|
84
|
+
returnValue = false;
|
85
|
+
|
86
|
+
if (isAQueryMap.has(queryName)) {
|
87
|
+
return isAQueryMap.get(queryName)
|
88
|
+
}
|
89
|
+
|
90
|
+
while (parent = this.get(parent)?.parentClassName) {
|
91
|
+
if (parent === ancestor) {
|
92
|
+
returnValue = true;
|
93
|
+
break
|
94
|
+
}
|
95
|
+
|
96
|
+
// Assumption: component.Base directly extends core.Base
|
97
|
+
if (parent === 'Neo.component.Base' && ancestor !== 'Neo.core.Base') {
|
98
|
+
returnValue = false;
|
99
|
+
break
|
100
|
+
}
|
101
|
+
|
102
|
+
if (parent === 'Neo.core.Base') {
|
103
|
+
returnValue = false;
|
104
|
+
break
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
isAQueryMap.set(queryName, returnValue);
|
109
|
+
|
110
|
+
return returnValue
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
export default Neo.setupClass(ClassHierarchy);
|
package/src/menu/List.mjs
CHANGED
@@ -182,7 +182,7 @@ class List extends BaseList {
|
|
182
182
|
let me = this,
|
183
183
|
{iconCls} = record,
|
184
184
|
id = record[me.store.keyProperty],
|
185
|
-
vdomCn = [{tag: 'span', cls: ['neo-content'],
|
185
|
+
vdomCn = [{tag: 'span', cls: ['neo-content'], text: record[me.displayField]}];
|
186
186
|
|
187
187
|
if (iconCls && iconCls !== '') {
|
188
188
|
vdomCn.unshift({tag: 'i', cls: ['neo-menu-icon', 'neo-icon', iconCls], id: me.getIconId(id)})
|
package/src/plugin/Popover.mjs
CHANGED
@@ -18,10 +18,10 @@ import Plugin from './Base.mjs';
|
|
18
18
|
* ntype : 'panel',
|
19
19
|
* headers: [{
|
20
20
|
* dock: 'top',
|
21
|
-
*
|
21
|
+
* text: 'HEADER'
|
22
22
|
* }],
|
23
23
|
* items : [{
|
24
|
-
*
|
24
|
+
* text: 'This is a comment about the button'
|
25
25
|
* }]
|
26
26
|
* }]
|
27
27
|
* }]
|
package/src/table/Body.mjs
CHANGED
@@ -177,7 +177,7 @@ class TableBody extends Component {
|
|
177
177
|
|
178
178
|
switch (Neo.typeOf(rendererOutput)) {
|
179
179
|
case 'Object': {
|
180
|
-
if (rendererOutput.html) {
|
180
|
+
if (rendererOutput.html || rendererOutput.text) {
|
181
181
|
rendererOutput.cls && cellCls.push(...rendererOutput.cls);
|
182
182
|
} else {
|
183
183
|
rendererOutput = [rendererOutput];
|
@@ -230,7 +230,11 @@ class TableBody extends Component {
|
|
230
230
|
}
|
231
231
|
|
232
232
|
if (Neo.typeOf(rendererOutput) === 'Object') {
|
233
|
-
|
233
|
+
if (Object.hasOwn(rendererOutput, 'html')) {
|
234
|
+
cellConfig.html = rendererOutput.html || ''
|
235
|
+
} else {
|
236
|
+
cellConfig.text = rendererOutput.text || ''
|
237
|
+
}
|
234
238
|
} else {
|
235
239
|
cellConfig.cn = rendererOutput
|
236
240
|
}
|
package/src/tooltip/Base.mjs
CHANGED
@@ -76,12 +76,7 @@ class Tooltip extends Container {
|
|
76
76
|
* True prevents the tooltip from hiding while the mouse cursor is above it
|
77
77
|
* @member {Boolean|null} stayOnHover_=true
|
78
78
|
*/
|
79
|
-
stayOnHover_: true
|
80
|
-
/**
|
81
|
-
* Shortcut to add a label item
|
82
|
-
* @member {String} text_=null
|
83
|
-
*/
|
84
|
-
text_: null
|
79
|
+
stayOnHover_: true
|
85
80
|
}
|
86
81
|
|
87
82
|
/**
|
package/src/tree/Accordion.mjs
CHANGED
@@ -277,13 +277,13 @@ class AccordionTree extends TreeList {
|
|
277
277
|
tag : 'span',
|
278
278
|
cls : [itemCls + '-content-header'],
|
279
279
|
id : id + '__item-content-header',
|
280
|
-
|
280
|
+
text: item[me.fields.header]
|
281
281
|
}, {
|
282
282
|
flag: 'content',
|
283
283
|
tag : 'span',
|
284
284
|
cls : [itemCls + '-content-text'],
|
285
285
|
id : id + '__item-content-text',
|
286
|
-
|
286
|
+
text: item[me.fields.text]
|
287
287
|
}]
|
288
288
|
}],
|
289
289
|
style: {
|
@@ -428,7 +428,7 @@ class AccordionTree extends TreeList {
|
|
428
428
|
NeoArray.add(cls, clsItems);
|
429
429
|
itemVdom.cls = cls
|
430
430
|
} else {
|
431
|
-
itemVdom.
|
431
|
+
itemVdom.text = field.value
|
432
432
|
}
|
433
433
|
}
|
434
434
|
});
|
package/src/vdom/Helper.mjs
CHANGED
@@ -37,23 +37,6 @@ class Helper extends Base {
|
|
37
37
|
singleton: true
|
38
38
|
}
|
39
39
|
|
40
|
-
/**
|
41
|
-
* @returns {Promise<void>}
|
42
|
-
*/
|
43
|
-
async initAsync() {
|
44
|
-
super.initAsync();
|
45
|
-
|
46
|
-
let me = this;
|
47
|
-
|
48
|
-
// Subscribe to global Neo.config changes for dynamic renderer switching.
|
49
|
-
Neo.currentWorker.on({
|
50
|
-
neoConfigChange: me.onNeoConfigChange,
|
51
|
-
scope : me
|
52
|
-
});
|
53
|
-
|
54
|
-
await me.importUtil()
|
55
|
-
}
|
56
|
-
|
57
40
|
/**
|
58
41
|
* @param {Object} config
|
59
42
|
* @param {Object} config.deltas
|
@@ -517,6 +500,25 @@ class Helper extends Base {
|
|
517
500
|
}
|
518
501
|
}
|
519
502
|
|
503
|
+
/**
|
504
|
+
* @returns {Promise<void>}
|
505
|
+
*/
|
506
|
+
async initAsync() {
|
507
|
+
super.initAsync();
|
508
|
+
|
509
|
+
let me = this;
|
510
|
+
|
511
|
+
if (!NeoConfig.unitTestMode) {
|
512
|
+
// Subscribe to global Neo.config changes for dynamic renderer switching.
|
513
|
+
Neo.currentWorker.on({
|
514
|
+
neoConfigChange: me.onNeoConfigChange,
|
515
|
+
scope : me
|
516
|
+
})
|
517
|
+
}
|
518
|
+
|
519
|
+
await me.importUtil()
|
520
|
+
}
|
521
|
+
|
520
522
|
/**
|
521
523
|
* @param {Object} config
|
522
524
|
* @param {Object} config.deltas
|
@@ -629,12 +631,12 @@ class Helper extends Base {
|
|
629
631
|
|
630
632
|
/**
|
631
633
|
* Handler for global Neo.config changes.
|
632
|
-
* If
|
634
|
+
* If the `Neo.config.useDomApiRenderer` value changes, this method dynamically loads the renderer utilities.
|
633
635
|
* @param {Object} config
|
634
636
|
* @return {Promise<void>}
|
635
637
|
*/
|
636
638
|
async onNeoConfigChange(config) {
|
637
|
-
if(Object.hasOwn(config, 'useDomApiRenderer')) {
|
639
|
+
if (Object.hasOwn(config, 'useDomApiRenderer')) {
|
638
640
|
await this.importUtil()
|
639
641
|
}
|
640
642
|
}
|
package/src/worker/App.mjs
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
import Neo from '../Neo.mjs';
|
2
2
|
import Base from './Base.mjs';
|
3
|
-
import * as core from '../core/_export.mjs';
|
4
3
|
import Application from '../controller/Application.mjs';
|
5
|
-
import
|
4
|
+
import InstanceManager from '../manager/Instance.mjs';
|
6
5
|
import DomEventManager from '../manager/DomEvent.mjs';
|
7
6
|
import HashHistory from '../util/HashHistory.mjs';
|
8
7
|
|
package/src/worker/Base.mjs
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
import Base
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
import * as core from '../core/_export.mjs';
|
3
|
+
import Observable from '../core/Observable.mjs';
|
4
|
+
import ClassHierarchyManager from '../manager/ClassHierarchy.mjs';
|
5
|
+
import Message from './Message.mjs';
|
6
|
+
import RemoteMethodAccess from './mixin/RemoteMethodAccess.mjs';
|
5
7
|
|
6
8
|
/**
|
7
9
|
* The abstract base class for e.g. the App, Data & VDom worker
|
package/src/worker/Canvas.mjs
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
import Neo
|
2
|
-
import Base
|
3
|
-
import * as core from '../core/_export.mjs';
|
1
|
+
import Neo from '../Neo.mjs';
|
2
|
+
import Base from './Base.mjs';
|
4
3
|
|
5
4
|
/**
|
6
5
|
* The Canvas worker is responsible for dynamically manipulating offscreen canvas.
|
package/src/worker/Data.mjs
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
import Neo
|
2
|
-
import Base
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import Util from '../core/Util.mjs';
|
6
|
-
import Xhr from '../Xhr.mjs';
|
1
|
+
import Neo from '../Neo.mjs';
|
2
|
+
import Base from './Base.mjs';
|
3
|
+
import Fetch from '../Fetch.mjs';
|
4
|
+
import Xhr from '../Xhr.mjs';
|
7
5
|
|
8
6
|
/**
|
9
|
-
* The Data worker is responsible to handle all
|
7
|
+
* The Data worker is responsible to handle all the communication to the backend (e.g. Ajax-calls).
|
10
8
|
* See the tutorials for further infos.
|
11
9
|
* @class Neo.worker.Data
|
12
10
|
* @extends Neo.worker.Base
|
package/src/worker/Task.mjs
CHANGED
package/src/worker/VDom.mjs
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
import Neo
|
2
|
-
import Base
|
3
|
-
import
|
4
|
-
import Helper from '../vdom/Helper.mjs';
|
1
|
+
import Neo from '../Neo.mjs';
|
2
|
+
import Base from './Base.mjs';
|
3
|
+
import Helper from '../vdom/Helper.mjs';
|
5
4
|
|
6
5
|
/**
|
7
6
|
* The Vdom worker converts vdom templates into vnodes, as well as creating delta-updates.
|
@@ -90,7 +90,10 @@ class RemoteMethodAccess extends Base {
|
|
90
90
|
throw new Error('Invalid remote method name "' + msg.remoteMethod + '"')
|
91
91
|
}
|
92
92
|
|
93
|
-
|
93
|
+
// Check for interception
|
94
|
+
if (!pkg.isReady && pkg.interceptRemotes?.includes(msg.remoteMethod)) {
|
95
|
+
out = pkg.onInterceptRemotes(msg);
|
96
|
+
} else if (Array.isArray(msg.data)) {
|
94
97
|
out = method.call(pkg, ...msg.data)
|
95
98
|
} else {
|
96
99
|
out = method.call(pkg, msg.data)
|
@@ -1,15 +0,0 @@
|
|
1
|
-
Let's go through the steps of creating a main thread addon.
|
2
|
-
|
3
|
-
Let's say we needed to show a code editor. There are a lot of libraries
|
4
|
-
for this, such as Ace (<a href="https://ace.c9.io/" target="_blank">ace.c9.io</a>).
|
5
|
-
From a coding perspective, these editors have a simple API: a setter
|
6
|
-
to specify the string being edited, a getter to read the string, and
|
7
|
-
a change event fired as the user types.
|
8
|
-
|
9
|
-
Here's what we need to do:
|
10
|
-
- Define a main thread addon and its API
|
11
|
-
- Define a component wrapper
|
12
|
-
|
13
|
-
### Define the Main Thread Addon
|
14
|
-
|
15
|
-
### Define the component wrapper
|
@@ -1,44 +0,0 @@
|
|
1
|
-
Neo.mjs is multi-threaded. There are worker threads
|
2
|
-
that handle data access, application logic,
|
3
|
-
and keeping track of DOM updates. Practically all your
|
4
|
-
application logic is run in parallel in these threads.
|
5
|
-
However, anything that needs to actually reference or update
|
6
|
-
the DOM (`window.document`), or just use the `window` object, must be done in the main
|
7
|
-
application thread.
|
8
|
-
|
9
|
-
That's the purpose of main thread addons. These are classes whose
|
10
|
-
methods can be accessed from other web workers, but are
|
11
|
-
actually executed in the main thread.
|
12
|
-
|
13
|
-
For example, what if you needed to read the browser's
|
14
|
-
URL? That information is in `window.location`.
|
15
|
-
But `window` is a main thread variable! To access that
|
16
|
-
from a web-worker our code has to say "hey main thread,
|
17
|
-
please return a specified `window` property." Neo.mjs
|
18
|
-
lets you do that via `Neo.Main.getByPath()`. For
|
19
|
-
example, the following statement logs the URL query string.
|
20
|
-
|
21
|
-
```javascript readonly
|
22
|
-
const search = await Neo.Main.getByPath({path: 'window.location.search'});
|
23
|
-
console.log(search); // Logs the search string
|
24
|
-
```
|
25
|
-
|
26
|
-
`Neo.Main` & `Neo.main.DomAccess` provide some basic methods for accessing the
|
27
|
-
main thread, but in case you want to use a third party library which relies on directly
|
28
|
-
working with the DOM, you'd use a _main thread addon_.
|
29
|
-
|
30
|
-
Google Maps is a good example of this. In Neo.mjs, most
|
31
|
-
views are responsible for updating their own vdom, but
|
32
|
-
the responsibility for rendering maps and markers is handled
|
33
|
-
by Google Maps itself — we _ask_ Google Maps to do
|
34
|
-
certain things via the Google Maps API. Therefore, in Neo.mjs,
|
35
|
-
Google Maps is implemented as a main thread addon which
|
36
|
-
loads the libraries and exposes whatever methods we'll need
|
37
|
-
to run from the other Neo.mjs threads. In addition, in a
|
38
|
-
Neo.mjs application we want to use Google Maps like any other
|
39
|
-
component, so Neo.mjs also provides a component wrapper. In
|
40
|
-
summary:
|
41
|
-
- The main-thread addon contains the code run in the main thread,
|
42
|
-
and exposes what methods can be run by other web-workers (remote method access)
|
43
|
-
- The component wrapper lets you use it like any other component,
|
44
|
-
internally calling the main thread methods as needed.
|