neo.mjs 10.0.0-alpha.4 → 10.0.0-beta.1
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/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_devmode.json +26 -27
- package/apps/portal/resources/data/examples_dist_dev.json +26 -27
- package/apps/portal/resources/data/examples_dist_esm.json +26 -27
- package/apps/portal/resources/data/examples_dist_prod.json +27 -28
- package/apps/portal/view/blog/List.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +102 -111
- package/buildScripts/buildThemes.mjs +1 -1
- package/examples/grid/animatedRowSorting/Viewport.mjs +4 -4
- package/examples/grid/bigData/ControlsContainer.mjs +3 -3
- package/examples/grid/bigData/GridContainer.mjs +8 -8
- package/examples/grid/cellEditing/MainContainer.mjs +5 -5
- package/examples/grid/container/MainContainer.mjs +4 -4
- package/examples/grid/nestedRecordFields/Viewport.mjs +5 -5
- package/examples/table/cellEditing/MainContainer.mjs +1 -1
- package/examples/table/container/MainContainer.mjs +3 -3
- package/examples/table/nestedRecordFields/Viewport.mjs +6 -6
- package/examples/tableFiltering/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer2.mjs +1 -1
- package/examples/tablePerformance/MainContainer3.mjs +2 -2
- package/examples/tableStore/MainContainer.mjs +2 -2
- package/learn/UsingTheseTopics.md +2 -2
- package/learn/benefits/ConfigSystem.md +2 -2
- package/learn/benefits/FormsEngine.md +14 -14
- package/learn/benefits/MultiWindow.md +2 -2
- package/learn/benefits/OffTheMainThread.md +2 -2
- package/learn/benefits/Speed.md +2 -2
- package/learn/gettingstarted/ComponentModels.md +4 -4
- package/learn/gettingstarted/Config.md +6 -6
- package/learn/gettingstarted/DescribingTheUI.md +4 -4
- package/learn/gettingstarted/Events.md +6 -6
- package/learn/gettingstarted/Extending.md +4 -4
- package/learn/gettingstarted/References.md +6 -6
- package/learn/gettingstarted/Workspaces.md +6 -6
- package/learn/guides/ApplicationBootstrap.md +40 -42
- package/learn/guides/ComponentsAndContainers.md +12 -12
- package/learn/guides/CustomComponents.md +2 -2
- package/learn/guides/MainThreadAddonIntro.md +2 -2
- package/learn/guides/PortalApp.md +2 -2
- package/learn/guides/StateProviders.md +12 -12
- package/learn/guides/events/CustomEvents.md +16 -16
- package/learn/guides/events/DomEvents.md +12 -12
- package/learn/javascript/ClassFeatures.md +3 -2
- package/learn/javascript/Classes.md +8 -8
- package/learn/javascript/NewNode.md +4 -4
- package/learn/javascript/Overrides.md +8 -8
- package/learn/javascript/Super.md +10 -8
- package/learn/tutorials/Earthquakes.md +54 -57
- package/learn/tutorials/TodoList.md +4 -4
- package/package.json +1 -1
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +12 -0
- package/resources/scss/src/grid/{View.scss → Body.scss} +2 -2
- package/resources/scss/src/grid/VerticalScrollbar.scss +1 -1
- package/resources/scss/src/grid/plugin/AnimateRows.scss +1 -1
- package/resources/scss/src/grid/plugin/CellEditing.scss +1 -1
- package/resources/scss/src/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/src/table/plugin/CellEditing.scss +1 -1
- package/resources/scss/theme-dark/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-dark/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/Global.scss +1 -2
- package/resources/scss/theme-neo-light/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/table/{View.scss → Body.scss} +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/core/Base.mjs +59 -12
- package/src/core/Util.mjs +14 -2
- package/src/draggable/grid/header/toolbar/SortZone.mjs +21 -21
- package/src/draggable/table/header/toolbar/SortZone.mjs +1 -1
- package/src/grid/{View.mjs → Body.mjs} +19 -20
- package/src/grid/Container.mjs +58 -58
- package/src/grid/ScrollManager.mjs +56 -56
- package/src/grid/VerticalScrollbar.mjs +2 -2
- package/src/grid/_export.mjs +2 -2
- package/src/grid/column/AnimatedChange.mjs +5 -5
- package/src/grid/column/Base.mjs +1 -1
- package/src/grid/column/Component.mjs +6 -6
- package/src/grid/header/Toolbar.mjs +9 -9
- package/src/grid/plugin/AnimateRows.mjs +1 -2
- package/src/main/addon/AmCharts.mjs +8 -11
- package/src/main/addon/Base.mjs +150 -42
- package/src/main/addon/GoogleMaps.mjs +9 -16
- package/src/main/addon/HighlightJS.mjs +2 -13
- package/src/main/addon/IntersectionObserver.mjs +21 -21
- package/src/main/addon/MonacoEditor.mjs +1 -6
- package/src/table/{View.mjs → Body.mjs} +19 -20
- package/src/table/Container.mjs +43 -43
- package/src/table/_export.mjs +2 -2
- package/src/table/plugin/CellEditing.mjs +19 -19
- package/src/util/Style.mjs +2 -6
- package/src/vdom/Helper.mjs +10 -13
- package/src/worker/App.mjs +6 -18
- package/src/worker/Base.mjs +1 -1
- package/src/worker/Manager.mjs +4 -8
- package/src/worker/mixin/RemoteMethodAccess.mjs +1 -1
@@ -1,145 +1,144 @@
|
|
1
1
|
[{
|
2
2
|
"id" : 24,
|
3
3
|
"environments": ["Desktop", "Mobile"],
|
4
|
-
"image" : "devmode/liquid-glass.png",
|
5
|
-
"name" : "Liquid Glass effect",
|
6
|
-
"sourceUrl" : "https://github.com/neomjs/liquid-glass-demo/blob/main/apps/myapp/view/GlassComponent.mjs",
|
7
|
-
"url" : "https://neomjs.github.io/pages2/workspace/neo-liquid-glass-demo/dist/production/apps/myapp/index.html"
|
8
|
-
}, {
|
9
|
-
"id" : 23,
|
10
|
-
"environments": ["Desktop", "Mobile"],
|
11
4
|
"image" : "devmode/bigData.png",
|
12
5
|
"name" : "Buffered Data Grid with 5M cells",
|
13
6
|
"sourceUrl" : "examples/grid/bigData",
|
14
7
|
"url" : "dist/production/examples/grid/bigData/index.html"
|
15
8
|
}, {
|
16
|
-
"id" :
|
9
|
+
"id" : 23,
|
17
10
|
"image" : "devmode/sharedcovid.png",
|
18
11
|
"name" : "Multi Window Covid App",
|
19
12
|
"sharedWorkers": true,
|
20
13
|
"sourceUrl" : "apps/sharedcovid",
|
21
14
|
"url" : "dist/production/apps/sharedcovid/index.html#mainview=table"
|
22
15
|
}, {
|
23
|
-
"id" :
|
16
|
+
"id" : 22,
|
24
17
|
"image" : "devmode/calendar-preview.png",
|
25
18
|
"name" : "Calendar",
|
26
19
|
"sourceUrl": "src/calendar",
|
27
20
|
"url" : "dist/production/examples/calendar/basic/index.html"
|
28
21
|
}, {
|
29
|
-
"id" :
|
22
|
+
"id" : 21,
|
30
23
|
"image" : "devmode/helix.png",
|
31
24
|
"name" : "component.Helix",
|
32
25
|
"sourceUrl": "examples/component/helix",
|
33
26
|
"url" : "dist/production/examples/component/helix/index.html"
|
34
27
|
}, {
|
35
|
-
"id" :
|
28
|
+
"id" : 20,
|
36
29
|
"image" : "devmode/mwCoronaGallery.png",
|
37
30
|
"name" : "Multi Window Covid Gallery",
|
38
31
|
"sharedWorkers": true,
|
39
32
|
"sourceUrl" : "examples/component/multiWindowCoronaGallery",
|
40
33
|
"url" : "dist/production/examples/component/multiWindowCoronaGallery/index.html"
|
41
34
|
}, {
|
42
|
-
"id" :
|
35
|
+
"id" : 19,
|
43
36
|
"image" : "devmode/offscreenCanvas.png",
|
44
37
|
"name" : "OffscreenCanvas",
|
45
38
|
"sourceUrl": "https://github.com/neomjs/offscreen-canvas/tree/main/apps/myapp",
|
46
39
|
"url" : "https://neomjs.github.io/pages2/workspace/neo-offscreen-canvas-demo/dist/production/apps/myapp/index.html"
|
47
40
|
}, {
|
48
|
-
"id" :
|
41
|
+
"id" : 18,
|
49
42
|
"image" : "devmode/sharedOffscreenCanvas.png",
|
50
43
|
"name" : "Multi-Window OffscreenCanvas",
|
51
44
|
"sharedWorkers": true,
|
52
45
|
"sourceUrl" : "https://github.com/neomjs/shared-offscreen",
|
53
46
|
"url" : "https://neomjs.github.io/pages2/workspace/neo-shared-offscreen-canvas-demo/dist/production/apps/mainapp/index.html"
|
54
47
|
}, {
|
55
|
-
"id" :
|
48
|
+
"id" : 17,
|
56
49
|
"image" : "devmode/multi_window_dd.png",
|
57
50
|
"name" : "Multi-Window Drag&Drop",
|
58
51
|
"sharedWorkers": true,
|
59
52
|
"sourceUrl" : "apps/shareddialog",
|
60
53
|
"url" : "dist/production/apps/shareddialog/index.html"
|
61
54
|
}, {
|
62
|
-
"id" :
|
55
|
+
"id" : 16,
|
63
56
|
"image" : "devmode/tabContainer.png",
|
64
57
|
"name" : "tab.Container",
|
65
58
|
"sourceUrl": "examples/tab/container",
|
66
59
|
"url" : "dist/production/examples/tab/container/index.html"
|
67
60
|
}, {
|
68
|
-
"id" :
|
61
|
+
"id" : 15,
|
69
62
|
"image" : "devmode/model-component-example.png",
|
70
63
|
"name" : "State Provider Example",
|
71
64
|
"sourceUrl": "examples/stateProvider/advanced",
|
72
65
|
"url" : "dist/production/examples/stateProvider/advanced/index.html"
|
73
66
|
}, {
|
74
|
-
"id" :
|
67
|
+
"id" : 14,
|
75
68
|
"image" : "devmode/dragdrop.png",
|
76
69
|
"name" : "Dialog drag&drop",
|
77
70
|
"sourceUrl": "examples/dialog",
|
78
71
|
"url" : "dist/production/examples/dialog/"
|
79
72
|
}, {
|
80
|
-
"id" :
|
73
|
+
"id" : 13,
|
81
74
|
"image" : "dist_prod/colorsApp.png",
|
82
75
|
"name" : "Colors Dashboard",
|
83
76
|
"sharedWorkers": true,
|
84
77
|
"sourceUrl" : "apps/colors",
|
85
78
|
"url" : "dist/production/apps/colors/index.html"
|
86
79
|
}, {
|
87
|
-
"id" :
|
80
|
+
"id" : 12,
|
88
81
|
"image" : "devmode/covidDashboard.png",
|
89
82
|
"name" : "Covid Dashboard",
|
90
83
|
"sourceUrl": "apps/covid",
|
91
84
|
"url" : "dist/production/apps/covid/index.html#mainview=table"
|
92
85
|
}, {
|
93
|
-
"id" :
|
86
|
+
"id" : 11,
|
94
87
|
"image" : "devmode/coronaHelix.png",
|
95
88
|
"name" : "COVID-19 Helix",
|
96
89
|
"sourceUrl": "examples/component/coronaHelix",
|
97
90
|
"url" : "dist/production/examples/component/coronaHelix/index.html"
|
98
91
|
}, {
|
99
|
-
"id" :
|
92
|
+
"id" : 10,
|
100
93
|
"image" : "devmode/coronaGallery.png",
|
101
94
|
"name" : "COVID-19 Gallery",
|
102
95
|
"sourceUrl": "examples/component/coronaGallery",
|
103
96
|
"url" : "dist/production/examples/component/coronaGallery/index.html"
|
104
97
|
}, {
|
105
|
-
"id" :
|
98
|
+
"id" : 9,
|
106
99
|
"image" : "devmode/gallery.png",
|
107
100
|
"name" : "component.Gallery",
|
108
101
|
"sourceUrl": "examples/component/gallery",
|
109
102
|
"url" : "dist/production/examples/component/gallery/index.html"
|
110
103
|
}, {
|
111
|
-
"id" :
|
104
|
+
"id" : 8,
|
112
105
|
"image" : "devmode/tableFiltering.png",
|
113
106
|
"name" : "Table Filtering",
|
114
107
|
"sourceUrl": "examples/tableFiltering",
|
115
108
|
"url" : "dist/production/examples/tableFiltering/"
|
116
109
|
}, {
|
117
|
-
"id" :
|
110
|
+
"id" : 7,
|
118
111
|
"image" : "devmode/dateSelector.png",
|
119
112
|
"name" : "component.DateSelector",
|
120
113
|
"sourceUrl": "examples/component/dateSelector",
|
121
114
|
"url" : "dist/production/examples/component/dateSelector/index.html"
|
122
115
|
}, {
|
123
|
-
"id" :
|
116
|
+
"id" : 6,
|
124
117
|
"image" : "devmode/dateField.png",
|
125
118
|
"name" : "form.field.Date",
|
126
119
|
"sourceUrl": "examples/form/field/date",
|
127
120
|
"url" : "dist/production/examples/form/field/date/index.html"
|
128
121
|
}, {
|
129
|
-
"id" :
|
122
|
+
"id" : 5,
|
130
123
|
"image" : "devmode/selectField.png",
|
131
124
|
"name" : "form.field.ComboBox",
|
132
125
|
"sourceUrl": "examples/form/field/combobox",
|
133
126
|
"url" : "dist/production/examples/form/field/combobox/index.html"
|
134
127
|
}, {
|
135
|
-
"id" :
|
128
|
+
"id" : 4,
|
136
129
|
"environments" : ["Desktop", "Mobile"],
|
137
130
|
"image" : "dist_prod/portalApp.png",
|
138
131
|
"name" : "Portal App",
|
139
132
|
"sharedWorkers": true,
|
140
133
|
"sourceUrl" : "apps/portal",
|
141
134
|
"url" : "dist/production/apps/portal/index.html"
|
142
|
-
},
|
135
|
+
},{
|
136
|
+
"id" : 3,
|
137
|
+
"image" : "devmode/liquid-glass.png",
|
138
|
+
"name" : "Liquid Glass effect",
|
139
|
+
"sourceUrl": "https://github.com/neomjs/liquid-glass-demo/blob/main/apps/myapp/view/GlassComponent.mjs",
|
140
|
+
"url" : "https://neomjs.github.io/pages2/workspace/neo-liquid-glass-demo/dist/production/apps/myapp/index.html"
|
141
|
+
}, , {
|
143
142
|
"hidden" : true,
|
144
143
|
"id" : 2,
|
145
144
|
"image" : "devmode/realworldApp.png",
|
@@ -5,9 +5,9 @@ import {marked} from '../../../../node_modules/marked/lib/marked.esm.js';
|
|
5
5
|
const
|
6
6
|
labCloseRegex = /<!--\s*\/lab\s*-->/g,
|
7
7
|
labOpenRegex = /<!--\s*lab\s*-->/g,
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
regexLivePreview = /```(javascript|html|css|json)\s+live-preview\s*\n([\s\S]*?)\n```/g,
|
9
|
+
regexNeoComponent = /```json\s+neo-component\s*\n([\s\S]*?)\n```/g,
|
10
|
+
regexReadonly = /```(javascript|html|css|json)\s+readonly\s*\n([\s\S]*?)\n```/g;
|
11
11
|
|
12
12
|
/**
|
13
13
|
* @class Portal.view.learn.ContentComponent
|
@@ -164,48 +164,48 @@ class ContentComponent extends Component {
|
|
164
164
|
{appName, windowId} = me,
|
165
165
|
path = me.getStateProvider().getData('contentPath'),
|
166
166
|
pagesFolder = path.includes('/learn/') ? '' : 'pages/',
|
167
|
-
baseConfigs, content, data, html, instance,
|
167
|
+
baseConfigs, content, data, html, instance, neoComponents, neoDivs;
|
168
168
|
|
169
169
|
path += `${pagesFolder + record.id.replaceAll('.', '/')}.md`;
|
170
170
|
|
171
171
|
if (record.isLeaf && path) {
|
172
|
-
baseConfigs
|
173
|
-
data
|
174
|
-
content
|
175
|
-
|
176
|
-
content
|
177
|
-
|
172
|
+
baseConfigs = {appName, autoMount: true, autoRender: true, parentComponent: me, windowId};
|
173
|
+
data = await fetch(path);
|
174
|
+
content = await data.text();
|
175
|
+
// Update content sections (modifies markdown content with h2/h3 tags and IDs)
|
176
|
+
content = me.updateContentSectionsStore(content);
|
177
|
+
content = `<h1 class='neo-h1'>${record.name}</h1>\n${content}`;
|
178
|
+
// Initialize maps for custom components and live previews
|
178
179
|
neoComponents = {};
|
179
180
|
neoDivs = {};
|
180
|
-
|
181
|
-
|
182
|
-
//
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
//
|
188
|
-
//
|
189
|
-
|
190
|
-
|
191
|
-
html =
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
me.html = html;
|
181
|
+
// Process custom Neo.mjs component blocks (synchronous)
|
182
|
+
content = me.processNeoComponentsBlocks(content, neoComponents);
|
183
|
+
// Process custom Live Preview blocks (synchronous)
|
184
|
+
content = me.processLivePreviewBlocks(content, neoDivs);
|
185
|
+
// Process custom Readonly Code blocks (asynchronous due to HighlightJS)
|
186
|
+
// This will replace the markdown fenced block with the highlighted HTML <pre> tag.
|
187
|
+
content = await me.processReadonlyCodeBlocks(content, windowId);
|
188
|
+
// Parse the (now modified) markdown content into HTML
|
189
|
+
// This content string now contains standard markdown PLUS the HTML divs/pres we injected.
|
190
|
+
html = marked.parse(content);
|
191
|
+
// Insert lab divs (these are markdown comments, so process on the final HTML)
|
192
|
+
html = me.insertLabDivs(html); // Keep existing method
|
193
|
+
|
194
|
+
me.toggleCls('lab', record.name?.startsWith('Lab:')); // Keep existing method
|
195
|
+
|
196
|
+
me.html = html; // Set the component's HTML
|
197
197
|
|
198
198
|
await me.timeout(Neo.config.environment === 'development' ? 100 : 150);
|
199
199
|
|
200
|
+
// Create instances for custom components and live previews (keep existing logic)
|
200
201
|
Object.keys(neoComponents).forEach(key => {
|
201
202
|
instance = Neo.create({
|
202
203
|
...baseConfigs,
|
203
|
-
className: 'Neo.component.Base',
|
204
|
+
className: 'Neo.component.Base', // Adjust if specific component classes are implied by JSON
|
204
205
|
parentId : key,
|
205
206
|
...neoComponents[key]
|
206
207
|
});
|
207
|
-
|
208
|
-
me.customComponents.push(instance)
|
208
|
+
me.customComponents.push(instance);
|
209
209
|
});
|
210
210
|
|
211
211
|
Object.keys(neoDivs).forEach(key => {
|
@@ -213,10 +213,9 @@ class ContentComponent extends Component {
|
|
213
213
|
...baseConfigs,
|
214
214
|
module : LivePreview,
|
215
215
|
parentId: key,
|
216
|
-
value : neoDivs[key]
|
216
|
+
value : neoDivs[key].code // Pass the extracted code content
|
217
217
|
});
|
218
|
-
|
219
|
-
me.livePreviews.push(instance)
|
218
|
+
me.livePreviews.push(instance);
|
220
219
|
});
|
221
220
|
|
222
221
|
Neo.main.addon.IntersectionObserver.observe({
|
@@ -224,87 +223,10 @@ class ContentComponent extends Component {
|
|
224
223
|
id : me.id,
|
225
224
|
observe : ['.neo-h2', '.neo-h3'],
|
226
225
|
windowId : me.windowId
|
227
|
-
})
|
226
|
+
});
|
228
227
|
}
|
229
228
|
}
|
230
229
|
|
231
|
-
/**
|
232
|
-
* @param {String} htmlString
|
233
|
-
* @param {Object} map
|
234
|
-
* @returns {String}
|
235
|
-
*/
|
236
|
-
extractNeoComponents(htmlString, map) {
|
237
|
-
// 1. Replace <pre data-neo-component> with <div id='neo-learn-content-component-x'/>
|
238
|
-
// and update map with key/value pairs, where the key is the ID and the value is the <pre> contents.
|
239
|
-
// Replace the content with tokens, and create a promise to update the corresponding content
|
240
|
-
return htmlString.replace(preNeoComponentRegex, (match, preContent) => {
|
241
|
-
const key = Neo.core.IdGenerator.getId('learn-content-component');
|
242
|
-
map[key] = JSON.parse(preContent);
|
243
|
-
return `<div id="${key}"></div>`
|
244
|
-
})
|
245
|
-
}
|
246
|
-
|
247
|
-
/**
|
248
|
-
* @param {String} htmlString
|
249
|
-
* @param {Object} map
|
250
|
-
* @returns {String}
|
251
|
-
*/
|
252
|
-
extractLivePreviewContent(htmlString, map) {
|
253
|
-
// 1. Replace <pre data-neo> with <div id='neo-pre-live-preview-x'/>
|
254
|
-
// and update map with key/value pairs, where the key is the ID and the value is the <pre> contents.
|
255
|
-
// Replace the content with tokens, and create a promise to update the corresponding content
|
256
|
-
return htmlString.replace(preLivePreviewRegex, (match, preContent) => {
|
257
|
-
const key = Neo.core.IdGenerator.getId('pre-live-preview');
|
258
|
-
map[key] = preContent;
|
259
|
-
return `<div id="${key}"></div>`
|
260
|
-
})
|
261
|
-
}
|
262
|
-
|
263
|
-
/**
|
264
|
-
* @param preContent
|
265
|
-
* @param token
|
266
|
-
* @param id
|
267
|
-
* @returns {Object}
|
268
|
-
*/
|
269
|
-
getHighlightPromise(preContent, token, id) {
|
270
|
-
// Resolves to an object of the form {after, token}, where after is the updated <pre> tag content
|
271
|
-
return Neo.main.addon.HighlightJS.highlightAuto({html: preContent, windowId: this.windowId})
|
272
|
-
.then(value => ({after: `<pre data-javascript id="${id}">${value}</pre>`, token}))
|
273
|
-
}
|
274
|
-
|
275
|
-
/**
|
276
|
-
* @param {String} htmlString
|
277
|
-
* @returns {Promise<*>}
|
278
|
-
*/
|
279
|
-
async highlightPreContent(htmlString) {
|
280
|
-
// 1. Replace <pre data-javascript> with unique tokens and create a HighlightJS.highlightAuto promise for each
|
281
|
-
// 2. When all promises are resolved, use their values to replace the tokens.
|
282
|
-
|
283
|
-
// Note that if we were to import HighlightJS directly, we wouldn't need all this async code.
|
284
|
-
|
285
|
-
// Create an array to store promises for each replacement
|
286
|
-
const replacementPromises = [];
|
287
|
-
let count = 0;
|
288
|
-
|
289
|
-
// Replace the content with tokens, and create a promise to update the corresponding content
|
290
|
-
let updatedHtml = htmlString.replace(preJsRegex, (match, preContent) => {
|
291
|
-
const token = `__NEO-PRE-TOKEN-${++count}__`;
|
292
|
-
replacementPromises.push(this.getHighlightPromise(preContent, token, `pre-preview-${Neo.core.IdGenerator.getId()}`));
|
293
|
-
return token
|
294
|
-
});
|
295
|
-
|
296
|
-
// Assert: updateHtml is the original, but with <pre data-javascript> replaced with tokens.
|
297
|
-
|
298
|
-
// Wait for all replacement promises to resolve
|
299
|
-
let replacements = await Promise.all(replacementPromises)
|
300
|
-
|
301
|
-
// Replace each token with the resolved content
|
302
|
-
replacements.forEach((replacement) => updatedHtml = updatedHtml.replace(replacement.token, replacement.after));
|
303
|
-
|
304
|
-
// Return the final updated HTML string
|
305
|
-
return updatedHtml
|
306
|
-
}
|
307
|
-
|
308
230
|
/**
|
309
231
|
* @param {String} inputString
|
310
232
|
* @returns {String}
|
@@ -335,6 +257,75 @@ class ContentComponent extends Component {
|
|
335
257
|
}
|
336
258
|
}
|
337
259
|
|
260
|
+
/**
|
261
|
+
* Extracts live preview code blocks from Markdown content before marked.js parsing.
|
262
|
+
* Replaces them with HTML placeholders.
|
263
|
+
* @param {String} contentString The raw Markdown content string.
|
264
|
+
* @param {Object} map A map to store the extracted code content keyed by placeholder ID.
|
265
|
+
* @returns {String} The modified Markdown content string with placeholders.
|
266
|
+
*/
|
267
|
+
processLivePreviewBlocks(contentString, map) {
|
268
|
+
return contentString.replace(regexLivePreview, (match, language, code) => {
|
269
|
+
const key = Neo.core.IdGenerator.getId('pre-live-preview');
|
270
|
+
map[key] = {code, language};
|
271
|
+
return `<div id="${key}"></div>`
|
272
|
+
})
|
273
|
+
}
|
274
|
+
|
275
|
+
/**
|
276
|
+
* Extracts Neo.mjs component config blocks from Markdown content before marked.js parsing.
|
277
|
+
* Replaces them with HTML placeholders.
|
278
|
+
* @param {String} contentString The raw Markdown content string.
|
279
|
+
* @param {Object} map A map to store the extracted JSON config keyed by placeholder ID.
|
280
|
+
* @returns {String} The modified Markdown content string with placeholders.
|
281
|
+
*/
|
282
|
+
processNeoComponentsBlocks(contentString, map) {
|
283
|
+
return contentString.replace(regexNeoComponent, (match, code) => {
|
284
|
+
const key = Neo.core.IdGenerator.getId('learn-content-component');
|
285
|
+
map[key] = JSON.parse(code);
|
286
|
+
return `<div id="${key}"></div>`
|
287
|
+
})
|
288
|
+
}
|
289
|
+
|
290
|
+
/**
|
291
|
+
* Highlights readonly code blocks using HighlightJS.
|
292
|
+
* Replaces the Markdown fenced block with the highlighted HTML <pre> tag.
|
293
|
+
* @param {String} contentString The raw Markdown content string.
|
294
|
+
* @param {String} windowId The ID of the current window for HighlightJS.
|
295
|
+
* @returns {Promise<String>} A promise that resolves to the modified Markdown string with highlighted HTML.
|
296
|
+
*/
|
297
|
+
async processReadonlyCodeBlocks(contentString, windowId) {
|
298
|
+
let replacementPromises = [],
|
299
|
+
count = 0,
|
300
|
+
replacements;
|
301
|
+
|
302
|
+
// Replace the content with tokens, and create a promise to update the corresponding content
|
303
|
+
let updatedContent = contentString.replace(regexReadonly, (match, language, code) => {
|
304
|
+
const token = `__NEO-READONLY-TOKEN-${++count}__`;
|
305
|
+
// Call HighlightJS.highlightAuto for each block.
|
306
|
+
// The result will be HTML. We'll wrap it in a <pre data-javascript> later.
|
307
|
+
replacementPromises.push(
|
308
|
+
Neo.main.addon.HighlightJS.highlightAuto({html: code, windowId})
|
309
|
+
.then(highlightedHtml => ({
|
310
|
+
after: `<pre data-javascript id="pre-readonly-${Neo.core.IdGenerator.getId()}">${highlightedHtml}</pre>`,
|
311
|
+
token: token
|
312
|
+
}))
|
313
|
+
);
|
314
|
+
|
315
|
+
return token; // Replace the original Markdown block with a temporary token
|
316
|
+
});
|
317
|
+
|
318
|
+
// Wait for all highlighting promises to resolve
|
319
|
+
replacements = await Promise.all(replacementPromises);
|
320
|
+
|
321
|
+
// Replace each token with the resolved highlighted HTML content
|
322
|
+
replacements.forEach(replacement => {
|
323
|
+
updatedContent = updatedContent.replace(replacement.token, replacement.after)
|
324
|
+
});
|
325
|
+
|
326
|
+
return updatedContent
|
327
|
+
}
|
328
|
+
|
338
329
|
/**
|
339
330
|
* Updates the contentSections VM store and replaces ## with h2 tags
|
340
331
|
* @param {String} content
|
@@ -12,7 +12,7 @@ import * as sass from 'sass';
|
|
12
12
|
const
|
13
13
|
__dirname = path.resolve(),
|
14
14
|
cwd = process.cwd(),
|
15
|
-
requireJson = path => JSON.parse(fs.readFileSync(
|
15
|
+
requireJson = path => JSON.parse(fs.readFileSync(path)),
|
16
16
|
packageJson = requireJson(path.resolve(cwd, 'package.json')),
|
17
17
|
insideNeo = packageJson.name.includes('neo.mjs'),
|
18
18
|
neoPath = path.resolve(insideNeo ? './' : './node_modules/neo.mjs/'),
|
@@ -52,12 +52,12 @@ class Viewport extends BaseViewport {
|
|
52
52
|
store : MainStore,
|
53
53
|
wrapperStyle: {maxWidth: '902px'},
|
54
54
|
|
55
|
-
|
56
|
-
|
55
|
+
bodyConfig: {
|
56
|
+
animatedRowSorting: true
|
57
57
|
},
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
columnDefaults: {
|
60
|
+
width: 200
|
61
61
|
},
|
62
62
|
|
63
63
|
columns: [
|
@@ -207,7 +207,7 @@ class ControlsContainer extends Container {
|
|
207
207
|
*/
|
208
208
|
onBufferColumnRangeChange(data) {
|
209
209
|
if (data.oldValue) {
|
210
|
-
this.grid.
|
210
|
+
this.grid.body.bufferColumnRange = parseInt(data.value.id)
|
211
211
|
}
|
212
212
|
}
|
213
213
|
|
@@ -216,7 +216,7 @@ class ControlsContainer extends Container {
|
|
216
216
|
*/
|
217
217
|
onBufferRowRangeChange(data) {
|
218
218
|
if (data.oldValue) {
|
219
|
-
this.grid.
|
219
|
+
this.grid.body.bufferRowRange = parseInt(data.value.id)
|
220
220
|
}
|
221
221
|
}
|
222
222
|
|
@@ -263,7 +263,7 @@ class ControlsContainer extends Container {
|
|
263
263
|
* @param {Object} data
|
264
264
|
*/
|
265
265
|
onSelectionModelChange(data) {
|
266
|
-
this.grid.
|
266
|
+
this.grid.body.selectionModel = data.component.selectionModel
|
267
267
|
}
|
268
268
|
|
269
269
|
/**
|
@@ -17,6 +17,13 @@ class GridContainer extends BaseGridContainer {
|
|
17
17
|
* @member {Number} amountColumns_=50
|
18
18
|
*/
|
19
19
|
amountColumns_: 50,
|
20
|
+
/**
|
21
|
+
* @member {Object} bodyConfig
|
22
|
+
*/
|
23
|
+
bodyConfig: {
|
24
|
+
bufferColumnRange: 3,
|
25
|
+
bufferRowRange : 5
|
26
|
+
},
|
20
27
|
/**
|
21
28
|
* Default configs for each column
|
22
29
|
* @member {Object} columnDefaults
|
@@ -29,14 +36,7 @@ class GridContainer extends BaseGridContainer {
|
|
29
36
|
/**
|
30
37
|
* @member {Object[]} store=MainStore
|
31
38
|
*/
|
32
|
-
store: MainStore
|
33
|
-
/**
|
34
|
-
* @member {Object} viewConfig
|
35
|
-
*/
|
36
|
-
viewConfig: {
|
37
|
-
bufferColumnRange: 3,
|
38
|
-
bufferRowRange : 5
|
39
|
-
}
|
39
|
+
store: MainStore
|
40
40
|
}
|
41
41
|
|
42
42
|
/**
|
@@ -114,6 +114,10 @@ class MainContainer extends ConfigurationViewport {
|
|
114
114
|
store : MainStore,
|
115
115
|
wrapperStyle: {maxWidth: '1002px'},
|
116
116
|
|
117
|
+
bodyConfig: {
|
118
|
+
selectionModel: CellModel
|
119
|
+
},
|
120
|
+
|
117
121
|
columnDefaults: {
|
118
122
|
editable: true,
|
119
123
|
width : 200
|
@@ -160,11 +164,7 @@ class MainContainer extends ConfigurationViewport {
|
|
160
164
|
dataField: 'githubId',
|
161
165
|
editable : false,
|
162
166
|
text : 'Github Id (Non-editable)'
|
163
|
-
}]
|
164
|
-
|
165
|
-
viewConfig: {
|
166
|
-
selectionModel: CellModel
|
167
|
-
}
|
167
|
+
}]
|
168
168
|
}
|
169
169
|
}
|
170
170
|
|
@@ -88,6 +88,10 @@ class MainContainer extends ConfigurationViewport {
|
|
88
88
|
width: 200
|
89
89
|
},
|
90
90
|
|
91
|
+
bodyConfig: {
|
92
|
+
selectionModel: CellModel
|
93
|
+
},
|
94
|
+
|
91
95
|
columns: [
|
92
96
|
{dataField: 'firstname', text: 'Firstname'},
|
93
97
|
{dataField: 'lastname', text: 'Lastname'},
|
@@ -95,10 +99,6 @@ class MainContainer extends ConfigurationViewport {
|
|
95
99
|
{dataField: 'country', text: 'Country'}
|
96
100
|
],
|
97
101
|
|
98
|
-
viewConfig: {
|
99
|
-
selectionModel: CellModel
|
100
|
-
},
|
101
|
-
|
102
102
|
wrapperStyle: {
|
103
103
|
height: '250px'
|
104
104
|
}
|
@@ -51,6 +51,10 @@ class Viewport extends BaseViewport {
|
|
51
51
|
bind : {store: 'stores.mainStore'},
|
52
52
|
reference: 'grid',
|
53
53
|
|
54
|
+
bodyConfig: {
|
55
|
+
highlightModifiedCells: true
|
56
|
+
},
|
57
|
+
|
54
58
|
columnDefaults: {
|
55
59
|
width: 200
|
56
60
|
},
|
@@ -66,11 +70,7 @@ class Viewport extends BaseViewport {
|
|
66
70
|
handler: 'editButtonHandler',
|
67
71
|
text : 'Edit'
|
68
72
|
}}
|
69
|
-
]
|
70
|
-
|
71
|
-
viewConfig: {
|
72
|
-
highlightModifiedCells: true
|
73
|
-
}
|
73
|
+
]
|
74
74
|
}]
|
75
75
|
}
|
76
76
|
}
|
@@ -115,7 +115,7 @@ class MainContainer extends ConfigurationViewport {
|
|
115
115
|
id : 'myTableStoreContainer',
|
116
116
|
store: MainStore,
|
117
117
|
|
118
|
-
|
118
|
+
bodyConfig: {
|
119
119
|
selectionModel: CellModel
|
120
120
|
},
|
121
121
|
|
@@ -139,7 +139,7 @@ class MainContainer extends ConfigurationViewport {
|
|
139
139
|
text : 'Edit'
|
140
140
|
}));
|
141
141
|
|
142
|
-
me.
|
142
|
+
me.body.updateDepth = -1;
|
143
143
|
|
144
144
|
return button.createVdomReference()
|
145
145
|
}
|
@@ -168,7 +168,7 @@ class MainContainer extends ConfigurationViewport {
|
|
168
168
|
}
|
169
169
|
}));
|
170
170
|
|
171
|
-
me.
|
171
|
+
me.body.updateDepth = -1;
|
172
172
|
|
173
173
|
return button.createVdomReference()
|
174
174
|
}
|