neo.mjs 10.0.0-alpha.2 → 10.0.0-alpha.4
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/.github/CODING_GUIDELINES.md +1 -1
- package/README.md +52 -11
- package/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +2 -1
- package/apps/portal/view/learn/MainContainerStateProvider.mjs +3 -6
- package/apps/realworld/view/HomeComponent.mjs +1 -1
- package/apps/realworld/view/user/ProfileComponent.mjs +1 -1
- package/apps/sharedcovid/view/MainContainerController.mjs +1 -1
- package/apps/shareddialog/view/MainContainerController.mjs +2 -2
- package/examples/component/gallery/ImageStore.mjs +2 -2
- package/examples/component/helix/ImageStore.mjs +2 -2
- package/learn/README.md +83 -0
- package/learn/guides/ApplicationBootstrap.md +354 -0
- package/learn/guides/DeclarativeComponentTreesVsImperativeVdom.md +500 -0
- package/learn/guides/WorkingWithVDom.md +748 -0
- package/learn/tree.json +53 -0
- package/package.json +2 -2
- package/src/DefaultConfig.mjs +27 -14
- package/src/Main.mjs +1 -7
- package/src/Neo.mjs +16 -0
- package/src/button/Base.mjs +2 -2
- package/src/calendar/view/MainContainerStateProvider.mjs +1 -1
- package/src/grid/header/Button.mjs +1 -1
- package/src/layout/Cube.mjs +2 -2
- package/src/main/DeltaUpdates.mjs +20 -12
- package/src/main/addon/Navigator.mjs +1 -1
- package/src/main/addon/WindowPosition.mjs +1 -1
- package/src/main/render/StringBasedRenderer.mjs +1 -1
- package/src/tab/header/Toolbar.mjs +1 -1
- package/src/table/header/Button.mjs +1 -1
- package/src/toolbar/Base.mjs +1 -1
- package/src/util/VDom.mjs +1 -1
- package/src/util/VNode.mjs +1 -1
- package/src/vdom/Helper.mjs +96 -49
- package/src/vdom/VNode.mjs +38 -2
- package/src/worker/App.mjs +2 -1
- package/src/worker/Base.mjs +87 -5
- package/src/worker/Manager.mjs +86 -28
- package/resources/data/deck/learnneo/tree.json +0 -50
- package/resources/data/deck/whyneo.md +0 -80
- /package/{resources/data/deck/learnneo/pages → learn}/Glossary.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/UsingTheseTopics.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/ConfigSystem.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Effort.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Features.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/FormsEngine.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/FourEnvironments.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Introduction.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/MultiWindow.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/OffTheMainThread.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Quick.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Speed.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/ComponentModels.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Config.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/DescribingTheUI.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Events.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Extending.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/References.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Setup.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Workspaces.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/ComponentsAndContainers.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/CustomComponents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Forms.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/InstanceLifecycle.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Layouts.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MainThreadAddonExample.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MainThreadAddonIntro.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Mixins.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MultiWindow.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/PortalApp.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/StateProviders.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Tables.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/events/CustomEvents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/events/DomEvents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/ClassFeatures.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Classes.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/NewNode.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Overrides.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Super.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/Earthquakes.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/RSP.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/TodoList.md +0 -0
- /package/resources/data/{deck/learnneo/data/theBeatles.json → theBeatles.json} +0 -0
package/learn/tree.json
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
{"data": [
|
2
|
+
{"name": "Using These Topics", "parentId": null, "id": "UsingTheseTopics" },
|
3
|
+
{"name": "Benefits", "parentId": null, "isLeaf": false, "id": "Benefits"},
|
4
|
+
{"name": "Introduction ", "parentId": "Benefits", "id": "benefits.Introduction"},
|
5
|
+
{"name": "Off the Main Thread", "parentId": "Benefits", "id": "benefits.OffTheMainThread"},
|
6
|
+
{"name": "4 Environments", "parentId": "Benefits", "id": "benefits.FourEnvironments"},
|
7
|
+
{"name": "Unified Config System", "parentId": "Benefits", "id": "benefits.ConfigSystem"},
|
8
|
+
{"name": "Extreme Speed", "parentId": "Benefits", "id": "benefits.Speed"},
|
9
|
+
{"name": "Multi-Window Applications", "parentId": "Benefits", "id": "benefits.MultiWindow"},
|
10
|
+
{"name": "Quick Application Development", "parentId": "Benefits", "id": "benefits.Quick"},
|
11
|
+
{"name": "Complexity and Effort", "parentId": "Benefits", "id": "benefits.Effort"},
|
12
|
+
{"name": "Forms Engine", "parentId": "Benefits", "id": "benefits.FormsEngine"},
|
13
|
+
{"name": "Features and Benefits Summary", "parentId": "Benefits", "id": "benefits.Features"},
|
14
|
+
{"name": "Getting Started", "parentId": null, "isLeaf": false, "id": "GettingStarted", "collapsed": true},
|
15
|
+
{"name": "Setup", "parentId": "GettingStarted", "id": "gettingstarted.Setup"},
|
16
|
+
{"name": "Workspaces and Applications", "parentId": "GettingStarted", "id": "gettingstarted.Workspaces"},
|
17
|
+
{"name": "Describing a View", "parentId": "GettingStarted", "id": "gettingstarted.DescribingTheUI"},
|
18
|
+
{"name": "Events", "parentId": "GettingStarted", "id": "gettingstarted.Events"},
|
19
|
+
{"name": "Component References", "parentId": "GettingStarted", "id": "gettingstarted.References"},
|
20
|
+
{"name": "Extending Classes", "parentId": "GettingStarted", "id": "gettingstarted.Extending"},
|
21
|
+
{"name": "Config", "parentId": "GettingStarted", "id": "gettingstarted.Config"},
|
22
|
+
{"name": "Shared Bindable Data", "parentId": "GettingStarted", "id": "gettingstarted.ComponentModels"},
|
23
|
+
{"name": "Guides", "parentId": null, "isLeaf": false, "id": "InDepth", "collapsed": true},
|
24
|
+
{"name": "Application Bootstrap", "parentId": "InDepth", "id": "guides.ApplicationBootstrap"},
|
25
|
+
{"name": "Declarative Component Trees VS Imperative Vdom", "parentId": "InDepth", "id": "guides.DeclarativeComponentTreesVsImperativeVdom"},
|
26
|
+
{"name": "Working with VDom", "parentId": "InDepth", "id": "guides.WorkingWithVDom"},
|
27
|
+
{"name": "Instance Lifecycle", "parentId": "InDepth", "id": "guides.InstanceLifecycle", "hidden": true},
|
28
|
+
{"name": "User Input (Forms)", "parentId": "InDepth", "id": "guides.Forms", "hidden": true},
|
29
|
+
{"name": "Component and Container Basics", "parentId": "InDepth", "id": "guides.ComponentsAndContainers"},
|
30
|
+
{"name": "Layouts", "parentId": "InDepth", "isLeaf": false, "id": "guides.Layouts", "hidden": true},
|
31
|
+
{"name": "Shared Bindable Data (State Providers)", "parentId": "InDepth", "id": "guides.StateProviders"},
|
32
|
+
{"name": "Custom Components", "parentId": "InDepth", "id": "guides.CustomComponents", "hidden": true},
|
33
|
+
{"name": "Events", "parentId": "InDepth", "isLeaf": false, "id": "GuideEvents"},
|
34
|
+
{"name": "Custom Events", "parentId": "GuideEvents", "id": "guides.events.CustomEvents"},
|
35
|
+
{"name": "DOM Events", "parentId": "GuideEvents", "id": "guides.events.DomEvents"},
|
36
|
+
{"name": "Portal App", "parentId": "InDepth", "id": "guides.PortalApp"},
|
37
|
+
{"name": "Tables (Stores)", "parentId": "InDepth", "id": "guides.Tables", "hidden": true},
|
38
|
+
{"name": "Multi-Window Applications", "parentId": "InDepth", "id": "guides.MultiWindow", "hidden": true},
|
39
|
+
{"name": "Main Thread Addons", "parentId": "InDepth", "isLeaf": false, "id": "MainThreadAddons", "hidden": true},
|
40
|
+
{"name": "Introduction", "parentId": "MainThreadAddons", "id": "guides.MainThreadAddonIntro"},
|
41
|
+
{"name": "Example", "parentId": "MainThreadAddons", "id": "guides.MainThreadAddonExample"},
|
42
|
+
{"name": "Mixins", "parentId": "InDepth", "id": "guides.Mixins", "hidden": true},
|
43
|
+
{"name": "Tutorials", "parentId": null, "isLeaf": false, "id": "Tutorials", "collapsed": true},
|
44
|
+
{"name": "Rock Scissors Paper", "parentId": "Tutorials", "id": "tutorials.RSP", "hidden": true},
|
45
|
+
{"name": "Earthquakes", "parentId": "Tutorials", "id": "tutorials.Earthquakes"},
|
46
|
+
{"name": "Todo List", "parentId": "Tutorials", "id": "tutorials.TodoList"},
|
47
|
+
{"name": "JavaScript Classes", "parentId": null, "isLeaf": false, "id": "JavaScript", "hidden": true},
|
48
|
+
{"name": "Classes, Properties, and Methods", "parentId": "JavaScript", "id": "javascript.Classes"},
|
49
|
+
{"name": "Overriding Methods", "parentId": "JavaScript", "id": "javascript.Overrides"},
|
50
|
+
{"name": "Other JavaScript Class Features", "parentId": "JavaScript", "id": "javascript.ClassFeatures"},
|
51
|
+
{"name": "Super", "parentId": "JavaScript", "id": "javascript.Super"},
|
52
|
+
{"name": "New Node", "parentId": "JavaScript", "id": "javascript.NewNode"}
|
53
|
+
]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name" : "neo.mjs",
|
3
|
-
"version" : "10.0.0-alpha.
|
3
|
+
"version" : "10.0.0-alpha.4",
|
4
4
|
"description" : "Neo.mjs: The multi-threaded UI framework for building ultra-fast, desktop-like web applications with uncompromised responsiveness, inherent security, and a transpilation-free dev mode.",
|
5
5
|
"type" : "module",
|
6
6
|
"repository" : {
|
@@ -94,7 +94,7 @@
|
|
94
94
|
"postcss" : "^8.5.6",
|
95
95
|
"sass" : "^1.89.2",
|
96
96
|
"siesta-lite" : "5.5.2",
|
97
|
-
"terser" : "^5.43.
|
97
|
+
"terser" : "^5.43.1",
|
98
98
|
"url" : "^0.11.4",
|
99
99
|
"webpack" : "^5.99.9",
|
100
100
|
"webpack-cli" : "^6.0.1",
|
package/src/DefaultConfig.mjs
CHANGED
@@ -200,6 +200,31 @@ const DefaultConfig = {
|
|
200
200
|
* @type Boolean
|
201
201
|
*/
|
202
202
|
useCanvasWorker: false,
|
203
|
+
/**
|
204
|
+
* `true` will enable the advanced, secure, and performant direct DOM API rendering strategy (recommended).
|
205
|
+
* In this mode, `Neo.vdom.Helper` will create and send structured VNode object graphs to the Main Thread.
|
206
|
+
* `Neo.main.DeltaUpdates` will then use `Neo.main.render.DomApiRenderer` to directly manipulate the DOM.
|
207
|
+
* Crucially, `Neo.main.render.DomApiRenderer` builds new **DOM subtrees** (from the received VNode object graphs)
|
208
|
+
* as detached DocumentFragments or elements, entirely outside the live DOM tree.
|
209
|
+
* These fully constructed fragments are then inserted into the live document in a **single, atomic operation**.
|
210
|
+
* This approach inherently minimizes costly browser reflows/repaints, drastically reduces Cross-Site Scripting (XSS) risks,
|
211
|
+
* and optimizes for surgical, atomic DOM updates for unparalleled performance.
|
212
|
+
*
|
213
|
+
* `false` will enable the legacy string-based rendering strategy.
|
214
|
+
* In this mode, `Neo.vdom.Helper` will generate complete HTML strings (`outerHTML`) for VNode subtrees.
|
215
|
+
* `Neo.main.DeltaUpdates` will then use `Neo.main.render.StringBasedRenderer` to insert these
|
216
|
+
* strings into the DOM using methods like `parentNode.insertAdjacentHTML()`.
|
217
|
+
* While performant for large insertions, this mode is generally less secure due to potential XSS vectors
|
218
|
+
* and relies on browser HTML parsing, which can be less efficient for granular updates.
|
219
|
+
*
|
220
|
+
* This configuration affects both the initial painting of your applications and the creation
|
221
|
+
* of new component trees at runtime.
|
222
|
+
* @default true
|
223
|
+
* @memberOf! module:Neo
|
224
|
+
* @name config.useDomApiRenderer
|
225
|
+
* @type Boolean
|
226
|
+
*/
|
227
|
+
useDomApiRenderer: true,
|
203
228
|
/**
|
204
229
|
* Flag if vdom ids should get mapped into DOM element ids.
|
205
230
|
* false will convert them into a "data-neo-id" attribute.
|
@@ -246,18 +271,6 @@ const DefaultConfig = {
|
|
246
271
|
* @type Boolean
|
247
272
|
*/
|
248
273
|
useSharedWorkers: false,
|
249
|
-
/**
|
250
|
-
* `true` will let the `vdom.Helper` create a String-based representation of the vnode tree.
|
251
|
-
* Main will then use e.g.`parentNode.insertAdjacentHTML('beforeend', delta.outerHTML);`
|
252
|
-
* This affects the initial painting of your apps, but also the creation of new component trees at run-time.
|
253
|
-
* `false` will skip the creation of the String, and instead use DOM APIs to generate a fragment inside Main,
|
254
|
-
* into which the vnode tree will get applied.
|
255
|
-
* @default false
|
256
|
-
* @memberOf! module:Neo
|
257
|
-
* @name config.useStringBasedMounting
|
258
|
-
* @type Boolean
|
259
|
-
*/
|
260
|
-
useStringBasedMounting: false,
|
261
274
|
/**
|
262
275
|
* True will generate a new task worker, which can get filled with own expensive remote methods
|
263
276
|
* @default false
|
@@ -276,12 +289,12 @@ const DefaultConfig = {
|
|
276
289
|
useVdomWorker: true,
|
277
290
|
/**
|
278
291
|
* buildScripts/injectPackageVersion.mjs will update this value
|
279
|
-
* @default '10.0.0-alpha.
|
292
|
+
* @default '10.0.0-alpha.4'
|
280
293
|
* @memberOf! module:Neo
|
281
294
|
* @name config.version
|
282
295
|
* @type String
|
283
296
|
*/
|
284
|
-
version: '10.0.0-alpha.
|
297
|
+
version: '10.0.0-alpha.4'
|
285
298
|
};
|
286
299
|
|
287
300
|
Object.assign(DefaultConfig, {
|
package/src/Main.mjs
CHANGED
@@ -42,7 +42,7 @@ class Main extends core.Base {
|
|
42
42
|
readQueue: [],
|
43
43
|
/**
|
44
44
|
* Remote method access for other workers
|
45
|
-
* @member {Object} remote
|
45
|
+
* @member {Object} remote
|
46
46
|
* @protected
|
47
47
|
*/
|
48
48
|
remote: {
|
@@ -252,12 +252,6 @@ class Main extends core.Base {
|
|
252
252
|
|
253
253
|
DomAccess.onDomContentLoaded();
|
254
254
|
|
255
|
-
// We need different publicPath values for the main thread inside the webpack based dist envs,
|
256
|
-
// depending on the hierarchy level of the app entry point
|
257
|
-
if (environment === 'dist/development' || environment === 'dist/production') {
|
258
|
-
__webpack_require__.p = config.basePath.substring(6)
|
259
|
-
}
|
260
|
-
|
261
255
|
// Intended for the online examples where we need an easy way to add GA to every generated app
|
262
256
|
if (config.useGoogleAnalytics && !mainThreadAddons.includes('AnalyticsByGoogle')) {
|
263
257
|
mainThreadAddons.push('AnalyticsByGoogle')
|
package/src/Neo.mjs
CHANGED
@@ -436,6 +436,22 @@ Neo = globalThis.Neo = Object.assign({
|
|
436
436
|
return Neo.create(className, config)
|
437
437
|
},
|
438
438
|
|
439
|
+
/**
|
440
|
+
* Updates the global Neo.config object across all active workers and connected browser windows.
|
441
|
+
*
|
442
|
+
* This is the unified entry point for changing global framework configurations.
|
443
|
+
* The framework automatically handles the complex multi-threaded and multi-window
|
444
|
+
* synchronization (via App Workers and Shared Workers, if active), ensuring
|
445
|
+
* consistency across the entire application without boilerplate.
|
446
|
+
*
|
447
|
+
* You can pass a partial config object to update specific keys.
|
448
|
+
* For nested objects, Neo.mjs performs a deep merge to preserve existing properties.
|
449
|
+
*
|
450
|
+
* @memberOf module:Neo
|
451
|
+
* @function setGlobalConfig
|
452
|
+
* @param {Object} config The partial or full Neo.config object with changes to apply.
|
453
|
+
*/
|
454
|
+
|
439
455
|
/**
|
440
456
|
* Internally used at the end of each class / module definition
|
441
457
|
* @memberOf module:Neo
|
package/src/button/Base.mjs
CHANGED
@@ -225,8 +225,8 @@ class Button extends Component {
|
|
225
225
|
afterSetBadgeText(value, oldValue) {
|
226
226
|
let {badgeNode} = this;
|
227
227
|
|
228
|
-
badgeNode.html = value;
|
229
228
|
badgeNode.removeDom = !Boolean(value);
|
229
|
+
badgeNode.text = value;
|
230
230
|
|
231
231
|
this.update()
|
232
232
|
}
|
@@ -380,7 +380,7 @@ class Button extends Component {
|
|
380
380
|
textNode.removeDom = isEmpty;
|
381
381
|
|
382
382
|
if (!isEmpty) {
|
383
|
-
textNode.
|
383
|
+
textNode.text = value
|
384
384
|
}
|
385
385
|
|
386
386
|
me.update()
|
package/src/layout/Cube.mjs
CHANGED
@@ -258,7 +258,7 @@ class Cube extends Card {
|
|
258
258
|
if (index < 6) {
|
259
259
|
wrapperCls = NeoArray.union(wrapperCls, 'neo-face', Object.keys(Cube.faces)[index]);
|
260
260
|
|
261
|
-
switch(index) {
|
261
|
+
switch (index) {
|
262
262
|
case 0:
|
263
263
|
case 1:
|
264
264
|
wrapperCls = NeoArray.union(wrapperCls, 'neo-face-z');
|
@@ -341,7 +341,7 @@ class Cube extends Card {
|
|
341
341
|
if (index < 6) {
|
342
342
|
NeoArray.remove(wrapperCls, ['neo-face', Object.keys(Cube.faces)[index]]);
|
343
343
|
|
344
|
-
switch(index) {
|
344
|
+
switch (index) {
|
345
345
|
case 0:
|
346
346
|
case 1:
|
347
347
|
NeoArray.remove(wrapperCls, 'neo-face-z');
|
@@ -54,7 +54,6 @@ class DeltaUpdates extends Base {
|
|
54
54
|
* @private
|
55
55
|
*/
|
56
56
|
#renderer = null
|
57
|
-
|
58
57
|
/**
|
59
58
|
* Private property to signal that the renderer module has been loaded.
|
60
59
|
* This will be a Promise that resolves when the module is ready.
|
@@ -69,21 +68,28 @@ class DeltaUpdates extends Base {
|
|
69
68
|
construct(config) {
|
70
69
|
super.construct(config);
|
71
70
|
|
72
|
-
let me
|
71
|
+
let me = this,
|
72
|
+
{environment} = NeoConfig;
|
73
73
|
|
74
|
-
if (
|
74
|
+
if (NeoConfig.renderCountDeltas) {
|
75
75
|
me.renderCountDeltas = true
|
76
76
|
}
|
77
77
|
|
78
|
+
// We need different publicPath values for the main thread inside the webpack based dist envs,
|
79
|
+
// depending on the hierarchy level of the app entry point
|
80
|
+
if (environment === 'dist/development' || environment === 'dist/production') {
|
81
|
+
__webpack_require__.p = NeoConfig.basePath.substring(6)
|
82
|
+
}
|
83
|
+
|
78
84
|
// Initiate the asynchronous loading of the renderer here.
|
79
85
|
me.#_readyPromise = (async () => {
|
80
86
|
try {
|
81
87
|
let module;
|
82
88
|
|
83
|
-
if (NeoConfig.
|
84
|
-
module = await import('./render/StringBasedRenderer.mjs')
|
85
|
-
} else {
|
89
|
+
if (NeoConfig.useDomApiRenderer) {
|
86
90
|
module = await import('./render/DomApiRenderer.mjs')
|
91
|
+
} else {
|
92
|
+
module = await import('./render/StringBasedRenderer.mjs')
|
87
93
|
}
|
88
94
|
|
89
95
|
me.#renderer = module.default
|
@@ -168,7 +174,7 @@ class DeltaUpdates extends Base {
|
|
168
174
|
* - `insertAdjacentHTML()` is generally faster than creating a node via template,
|
169
175
|
* but it's only available for manipulating children (elements), not `childNodes` (all nodes).
|
170
176
|
* - For performance, in cases where there are no comment nodes (i.e., no wrapped text nodes),
|
171
|
-
* the method prioritizes `insertAdjacentHTML()` when `
|
177
|
+
* the method prioritizes `insertAdjacentHTML()` when `useDomApiRenderer` is false.
|
172
178
|
*
|
173
179
|
* @param {Object} delta
|
174
180
|
* @param {Boolean} delta.hasLeadingTextChildren Flag to honor leading comments, which require special treatment.
|
@@ -178,8 +184,10 @@ class DeltaUpdates extends Base {
|
|
178
184
|
* @param {Neo.vdom.VNode} [delta.vnode] The VNode representation of the new node (for direct DOM API mounting).
|
179
185
|
*/
|
180
186
|
insertNode({hasLeadingTextChildren, index, outerHTML, parentId, vnode}) {
|
187
|
+
let me = this;
|
188
|
+
|
181
189
|
// This method is synchronous and *expects* the renderer to be loaded
|
182
|
-
if (!
|
190
|
+
if (!me.#renderer) {
|
183
191
|
console.error('DeltaUpdates renderer not ready during insertNode!');
|
184
192
|
return
|
185
193
|
}
|
@@ -187,10 +195,10 @@ class DeltaUpdates extends Base {
|
|
187
195
|
const parentNode = DomAccess.getElementOrBody(parentId);
|
188
196
|
|
189
197
|
if (parentNode) {
|
190
|
-
if (
|
191
|
-
|
198
|
+
if (NeoConfig.useDomApiRenderer) {
|
199
|
+
me.#renderer.createDomTree({index, isRoot: true, parentNode, vnode})
|
192
200
|
} else {
|
193
|
-
|
201
|
+
me.#renderer.insertNodeAsString({hasLeadingTextChildren, index, outerHTML, parentNode})
|
194
202
|
}
|
195
203
|
}
|
196
204
|
}
|
@@ -324,7 +332,7 @@ class DeltaUpdates extends Base {
|
|
324
332
|
|
325
333
|
if (node) {
|
326
334
|
Object.entries(delta).forEach(([prop, value]) => {
|
327
|
-
switch(prop) {
|
335
|
+
switch (prop) {
|
328
336
|
case 'attributes':
|
329
337
|
Object.entries(value).forEach(([key, val]) => {
|
330
338
|
if (voidAttributes.has(key)) {
|
@@ -212,7 +212,7 @@ class Navigator extends Base {
|
|
212
212
|
let {key, target} = keyEvent,
|
213
213
|
newActiveElement;
|
214
214
|
|
215
|
-
switch(key) {
|
215
|
+
switch (key) {
|
216
216
|
// Move to the previous navigable item
|
217
217
|
case data.previousKey:
|
218
218
|
newActiveElement = me.navigateGetAdjacent(-1, data);
|
@@ -11,7 +11,7 @@ const StringBasedRenderer = {
|
|
11
11
|
|
12
12
|
/**
|
13
13
|
* Handles string-based insertion of a new node into the DOM.
|
14
|
-
* This method is called by `insertNode()` when `NeoConfig.
|
14
|
+
* This method is called by `insertNode()` when `NeoConfig.useDomApiRenderer` is false.
|
15
15
|
*
|
16
16
|
* @param {Object} data
|
17
17
|
* @param {Boolean} data.hasLeadingTextChildren Flag to honor leading comments.
|
package/src/toolbar/Base.mjs
CHANGED
package/src/util/VDom.mjs
CHANGED
package/src/util/VNode.mjs
CHANGED
@@ -43,7 +43,7 @@ class VNode extends Base {
|
|
43
43
|
|
44
44
|
optsArray.forEach(([key, value]) => {
|
45
45
|
if (vnode.hasOwnProperty(key)) {
|
46
|
-
switch(key) {
|
46
|
+
switch (key) {
|
47
47
|
case 'attributes':
|
48
48
|
if (Neo.isObject(value) && Neo.isObject(vnode[key])) {
|
49
49
|
Object.entries(value).forEach(([attrKey, attrValue]) => {
|