neo.mjs 9.11.1 → 9.13.0
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/README.md +6 -6
- package/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/blog.json +2 -2
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/docs/app/view/ApiTreeList.mjs +11 -1
- package/docs/app/view/MainContainer.mjs +7 -4
- package/package.json +4 -4
- package/src/DefaultConfig.mjs +2 -2
- package/src/code/LivePreview.mjs +19 -8
- package/src/component/Base.mjs +2 -3
- package/src/data/Store.mjs +25 -16
- package/src/form/field/Text.mjs +6 -2
- package/src/form/field/trigger/Base.mjs +2 -2
- package/src/vdom/Helper.mjs +48 -13
package/README.md
CHANGED
@@ -115,17 +115,17 @@ import Component from '../../src/component/Base.mjs';
|
|
115
115
|
|
116
116
|
class MyComponent extends Component {
|
117
117
|
static config = {
|
118
|
-
className
|
119
|
-
|
120
|
-
domListeners
|
118
|
+
className : 'MyComponent',
|
119
|
+
myConfig_ : 'defaultValue',
|
120
|
+
domListeners: {
|
121
121
|
click: 'onClick'
|
122
122
|
}
|
123
123
|
}
|
124
124
|
|
125
|
-
|
126
|
-
console.log('
|
125
|
+
afterSetMyConfig(value, oldValue) {
|
126
|
+
console.log('myConfig changed:', value, oldValue)
|
127
127
|
}
|
128
|
-
|
128
|
+
|
129
129
|
onClick(data) {
|
130
130
|
console.log('Clicked!', data)
|
131
131
|
}
|
package/ServiceWorker.mjs
CHANGED
package/apps/portal/index.html
CHANGED
@@ -6,10 +6,10 @@
|
|
6
6
|
"image" : "json-blueprints.png",
|
7
7
|
"name" : "How JSON Blueprints & Shared Workers Power Next-Gen AI Interfaces",
|
8
8
|
"provider" : "Medium",
|
9
|
-
"publisher" : "",
|
9
|
+
"publisher" : "ITNEXT",
|
10
10
|
"selectedInto": [],
|
11
11
|
"type" : "Blog Post",
|
12
|
-
"url" : "https://
|
12
|
+
"url" : "https://itnext.io/the-ui-revolution-how-json-blueprints-shared-workers-power-next-gen-ai-interfaces-60a2bf0fc1dc?source=friends_link&sk=1b0b306285e23bb12f31271dd87bebe5"
|
13
13
|
}, {
|
14
14
|
"author" : "Tobias Uhlig",
|
15
15
|
"authorImage" : "author_TobiasUhlig.jpeg",
|
@@ -29,7 +29,17 @@ class ApiTreeList extends TreeList {
|
|
29
29
|
*/
|
30
30
|
onConstructed() {
|
31
31
|
super.onConstructed();
|
32
|
-
|
32
|
+
|
33
|
+
this.store.load().then(data => {
|
34
|
+
if (!data) {
|
35
|
+
this.html = [
|
36
|
+
'<div style="padding: 1em">',
|
37
|
+
'To get the content please use:</br>',
|
38
|
+
'<code>npm run generate-docs-json</code>',
|
39
|
+
'</div>'
|
40
|
+
].join('')
|
41
|
+
}
|
42
|
+
})
|
33
43
|
}
|
34
44
|
}
|
35
45
|
|
@@ -127,12 +127,15 @@ class MainContainer extends Viewport {
|
|
127
127
|
onConstructed() {
|
128
128
|
super.onConstructed();
|
129
129
|
|
130
|
-
let me
|
130
|
+
let me = this,
|
131
|
+
url = '../../docs/output/all.json';
|
131
132
|
|
132
|
-
Neo.Xhr.promiseJson({
|
133
|
-
|
133
|
+
Neo.Xhr.promiseJson({url}).catch(err => {
|
134
|
+
console.error('Error for Neo.Xhr.request', {id: me.store.id, error: err, url})
|
134
135
|
}).then(data => {
|
135
|
-
|
136
|
+
if (data) {
|
137
|
+
me.store.items = data.json
|
138
|
+
}
|
136
139
|
})
|
137
140
|
}
|
138
141
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name" : "neo.mjs",
|
3
|
-
"version" : "9.
|
3
|
+
"version" : "9.13.0",
|
4
4
|
"description" : "The webworkers driven UI framework",
|
5
5
|
"type" : "module",
|
6
6
|
"repository" : {
|
@@ -63,10 +63,10 @@
|
|
63
63
|
"monaco-editor" : "0.50.0",
|
64
64
|
"neo-jsdoc" : "1.0.1",
|
65
65
|
"neo-jsdoc-x" : "1.0.5",
|
66
|
-
"postcss" : "^8.5.
|
67
|
-
"sass" : "^1.89.
|
66
|
+
"postcss" : "^8.5.5",
|
67
|
+
"sass" : "^1.89.2",
|
68
68
|
"siesta-lite" : "5.5.2",
|
69
|
-
"terser" : "^5.
|
69
|
+
"terser" : "^5.42.0",
|
70
70
|
"url" : "^0.11.4",
|
71
71
|
"webpack" : "^5.99.9",
|
72
72
|
"webpack-cli" : "^6.0.1",
|
package/src/DefaultConfig.mjs
CHANGED
@@ -264,12 +264,12 @@ const DefaultConfig = {
|
|
264
264
|
useVdomWorker: true,
|
265
265
|
/**
|
266
266
|
* buildScripts/injectPackageVersion.mjs will update this value
|
267
|
-
* @default '9.
|
267
|
+
* @default '9.13.0'
|
268
268
|
* @memberOf! module:Neo
|
269
269
|
* @name config.version
|
270
270
|
* @type String
|
271
271
|
*/
|
272
|
-
version: '9.
|
272
|
+
version: '9.13.0'
|
273
273
|
};
|
274
274
|
|
275
275
|
Object.assign(DefaultConfig, {
|
package/src/code/LivePreview.mjs
CHANGED
@@ -223,9 +223,8 @@ class LivePreview extends Container {
|
|
223
223
|
}
|
224
224
|
|
225
225
|
let me = this,
|
226
|
-
{
|
226
|
+
{environment} = Neo.config,
|
227
227
|
container = me.getPreviewContainer(),
|
228
|
-
hasJsModules = config.environment === 'development' || config.environment === 'dist/esm',
|
229
228
|
source = me.editorValue || me.value,
|
230
229
|
className = me.findLastClassName(source),
|
231
230
|
cleanLines = [],
|
@@ -242,13 +241,25 @@ class LivePreview extends Container {
|
|
242
241
|
path = importMatch[2],
|
243
242
|
index;
|
244
243
|
|
245
|
-
|
244
|
+
// We want the non-minified version for code which can not get bundled.
|
245
|
+
if (environment === 'dist/development') {
|
246
246
|
index = path.lastIndexOf('../');
|
247
247
|
|
248
248
|
if (index === 0) {
|
249
|
-
path = '../../../../src/' + path.slice(index + 3)
|
249
|
+
path = '../../../../src/' + path.slice(index + 3)
|
250
250
|
} else {
|
251
|
-
path = path.slice(0, index) + '../../../' + path.slice(index + 3)
|
251
|
+
path = path.slice(0, index) + '../../../' + path.slice(index + 3)
|
252
|
+
}
|
253
|
+
}
|
254
|
+
|
255
|
+
// We want the minified version of the code which can not get bundled.
|
256
|
+
else if (environment === 'dist/production') {
|
257
|
+
index = path.lastIndexOf('../');
|
258
|
+
|
259
|
+
if (index === 0) {
|
260
|
+
path = '../../../esm/src/' + path.slice(index + 3)
|
261
|
+
} else {
|
262
|
+
path = path.slice(0, index) + '../../esm/' + path.slice(index + 3)
|
252
263
|
}
|
253
264
|
}
|
254
265
|
|
@@ -261,9 +272,9 @@ class LivePreview extends Container {
|
|
261
272
|
});
|
262
273
|
|
263
274
|
// Figure out the parts of the source we'll be running.
|
264
|
-
//
|
265
|
-
//
|
266
|
-
//
|
275
|
+
// * The promises/import() corresponding to the user's import statements
|
276
|
+
// * The vars holding the name of the imported module based on the module name for each import
|
277
|
+
// * The rest of the user-provided source
|
267
278
|
// It'll end up looking like this:
|
268
279
|
// Promise.all([
|
269
280
|
// import('../../../node_modules/neo.mjs/src/container/Base.mjs'),
|
package/src/component/Base.mjs
CHANGED
@@ -8,7 +8,6 @@ import NeoArray from '../util/Array.mjs';
|
|
8
8
|
import Observable from '../core/Observable.mjs';
|
9
9
|
import Rectangle from '../util/Rectangle.mjs';
|
10
10
|
import Style from '../util/Style.mjs';
|
11
|
-
import Util from '../core/Util.mjs';
|
12
11
|
import VDomUtil from '../util/VDom.mjs';
|
13
12
|
import VNodeUtil from '../util/VNode.mjs';
|
14
13
|
|
@@ -517,8 +516,8 @@ class Component extends Base {
|
|
517
516
|
* @returns {Object} all styles of this.el
|
518
517
|
*/
|
519
518
|
addStyle(value) {
|
520
|
-
if (
|
521
|
-
value =
|
519
|
+
if (Neo.isString(value)) {
|
520
|
+
value = Neo.createStyleObject(value)
|
522
521
|
}
|
523
522
|
|
524
523
|
// todo: add a check if something has changed
|
package/src/data/Store.mjs
CHANGED
@@ -351,9 +351,10 @@ class Store extends Base {
|
|
351
351
|
* @param {String} opts.responseType
|
352
352
|
* @param {Object} opts.scope
|
353
353
|
* @param {String} opts.url
|
354
|
+
* @returns {Promise<Object|Object[]>}
|
354
355
|
* @protected
|
355
356
|
*/
|
356
|
-
load(opts={}) {
|
357
|
+
async load(opts={}) {
|
357
358
|
let me = this,
|
358
359
|
params = {page: me.currentPage, pageSize: me.pageSize, ...opts.params};
|
359
360
|
|
@@ -371,26 +372,34 @@ class Store extends Base {
|
|
371
372
|
service = Neo.ns(apiArray.join('.'));
|
372
373
|
|
373
374
|
if (!service) {
|
374
|
-
console.
|
375
|
+
console.error('Api is not defined', this)
|
375
376
|
} else {
|
376
|
-
service[fn](params)
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
}
|
377
|
+
const response = await service[fn](params);
|
378
|
+
|
379
|
+
if (response.success) {
|
380
|
+
me.totalCount = response.totalCount;
|
381
|
+
me.data = Neo.ns(me.responseRoot, false, response); // fires the load event
|
382
|
+
|
383
|
+
return me.data
|
384
|
+
}
|
385
|
+
|
386
|
+
return null
|
384
387
|
}
|
385
388
|
} else {
|
386
389
|
opts.url ??= me.url;
|
387
390
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
391
|
+
try {
|
392
|
+
const data = await Neo.Xhr.promiseJson(opts);
|
393
|
+
|
394
|
+
if (data) {
|
395
|
+
me.data = Neo.ns(me.responseRoot, false, data.json) || data.json // fires the load event
|
396
|
+
}
|
397
|
+
|
398
|
+
return data?.json || null
|
399
|
+
} catch(err) {
|
400
|
+
console.error('Error for Neo.Xhr.request', {id: me.id, error: err, url: opts.url});
|
401
|
+
return null
|
402
|
+
}
|
394
403
|
}
|
395
404
|
}
|
396
405
|
|
package/src/form/field/Text.mjs
CHANGED
@@ -247,8 +247,8 @@ class Text extends Field {
|
|
247
247
|
*/
|
248
248
|
validator: null,
|
249
249
|
/**
|
250
|
-
*
|
251
|
-
* @member {Boolean}
|
250
|
+
* get value can be xssProtected and values are escaped
|
251
|
+
* @member {Boolean} xssProtected_=false
|
252
252
|
*/
|
253
253
|
xssProtected_: false,
|
254
254
|
/**
|
@@ -1074,6 +1074,10 @@ class Text extends Field {
|
|
1074
1074
|
})
|
1075
1075
|
}
|
1076
1076
|
|
1077
|
+
me.triggers?.forEach(trigger => {
|
1078
|
+
trigger.destroy()
|
1079
|
+
})
|
1080
|
+
|
1077
1081
|
super.destroy(...args)
|
1078
1082
|
}
|
1079
1083
|
|
@@ -177,7 +177,7 @@ class Base extends Component {
|
|
177
177
|
*/
|
178
178
|
onMouseEnter() {
|
179
179
|
this.isHovered = true;
|
180
|
-
this.hidden = false
|
180
|
+
this.hidden = false
|
181
181
|
}
|
182
182
|
|
183
183
|
/**
|
@@ -185,7 +185,7 @@ class Base extends Component {
|
|
185
185
|
*/
|
186
186
|
onMouseLeave() {
|
187
187
|
this.isHovered = false;
|
188
|
-
this.hidden = true
|
188
|
+
this.hidden = true
|
189
189
|
}
|
190
190
|
|
191
191
|
/**
|
package/src/vdom/Helper.mjs
CHANGED
@@ -35,42 +35,73 @@ class Helper extends Base {
|
|
35
35
|
singleton: true
|
36
36
|
}
|
37
37
|
|
38
|
+
/**
|
39
|
+
* The following top-level attributes will get converted into styles:
|
40
|
+
* height, maxHeight, maxWidth, minHeight, minWidth, width
|
41
|
+
*
|
42
|
+
* Some tags must not do the transformation, so we add them here.
|
43
|
+
* @member {Set} rawDimensionTags
|
44
|
+
*/
|
45
|
+
rawDimensionTags = new Set([
|
46
|
+
'circle',
|
47
|
+
'clipPath',
|
48
|
+
'ellipse',
|
49
|
+
'filter',
|
50
|
+
'foreignObject',
|
51
|
+
'image',
|
52
|
+
'marker',
|
53
|
+
'mask',
|
54
|
+
'pattern',
|
55
|
+
'rect',
|
56
|
+
'svg',
|
57
|
+
'use'
|
58
|
+
])
|
38
59
|
/**
|
39
60
|
* @member {Boolean} returnChildNodeOuterHtml=false
|
40
61
|
*/
|
41
62
|
returnChildNodeOuterHtml = false
|
42
63
|
/**
|
43
64
|
* Void attributes inside html tags
|
44
|
-
* @member {
|
65
|
+
* @member {Set} voidAttributes
|
45
66
|
* @protected
|
46
67
|
*/
|
47
|
-
voidAttributes = [
|
68
|
+
voidAttributes = new Set([
|
48
69
|
'checked',
|
49
|
-
'
|
50
|
-
|
70
|
+
'defer',
|
71
|
+
'disabled',
|
72
|
+
'ismap',
|
73
|
+
'multiple',
|
74
|
+
'nohref',
|
75
|
+
'noresize',
|
76
|
+
'noshade',
|
77
|
+
'nowrap',
|
78
|
+
'open',
|
79
|
+
'readonly',
|
80
|
+
'required',
|
81
|
+
'reversed',
|
82
|
+
'selected'
|
83
|
+
])
|
51
84
|
/**
|
52
85
|
* Void html tags
|
53
|
-
* @member {
|
86
|
+
* @member {Set} voidElements
|
54
87
|
* @protected
|
55
88
|
*/
|
56
|
-
voidElements = [
|
89
|
+
voidElements = new Set([
|
57
90
|
'area',
|
58
91
|
'base',
|
59
92
|
'br',
|
60
93
|
'col',
|
61
|
-
'command',
|
62
94
|
'embed',
|
63
95
|
'hr',
|
64
96
|
'img',
|
65
97
|
'input',
|
66
|
-
'keygen',
|
67
98
|
'link',
|
68
99
|
'meta',
|
69
100
|
'param',
|
70
101
|
'source',
|
71
102
|
'track',
|
72
103
|
'wbr'
|
73
|
-
]
|
104
|
+
])
|
74
105
|
|
75
106
|
/**
|
76
107
|
* Creates a Neo.vdom.VNode tree for the given vdom template.
|
@@ -117,7 +148,7 @@ class Helper extends Base {
|
|
117
148
|
* @protected
|
118
149
|
*/
|
119
150
|
createCloseTag(vnode) {
|
120
|
-
return this.voidElements.
|
151
|
+
return this.voidElements.has(vnode.nodeName) ? '' : '</' + vnode.nodeName + '>'
|
121
152
|
}
|
122
153
|
|
123
154
|
/**
|
@@ -362,7 +393,7 @@ class Helper extends Base {
|
|
362
393
|
}
|
363
394
|
|
364
395
|
Object.entries(attributes).forEach(([key, value]) => {
|
365
|
-
if (this.voidAttributes.
|
396
|
+
if (this.voidAttributes.get(key)) {
|
366
397
|
if (value === 'true') { // vnode attribute values get converted into strings
|
367
398
|
string += ` ${key}`
|
368
399
|
}
|
@@ -528,8 +559,12 @@ class Helper extends Base {
|
|
528
559
|
case 'minHeight':
|
529
560
|
case 'minWidth':
|
530
561
|
case 'width':
|
531
|
-
|
532
|
-
|
562
|
+
if (me.rawDimensionTags.get(node.nodeName)) {
|
563
|
+
node.attributes[key] = value + ''
|
564
|
+
} else {
|
565
|
+
hasUnit = value != parseInt(value);
|
566
|
+
node.style[key] = value + (hasUnit ? '' : 'px')
|
567
|
+
}
|
533
568
|
break
|
534
569
|
case 'componentId':
|
535
570
|
case 'id':
|