neo.mjs 9.16.0 → 10.0.0-alpha.2
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 +127 -121
- package/ServiceWorker.mjs +2 -2
- package/apps/email/view/Viewport.mjs +2 -2
- package/apps/form/view/Viewport.mjs +1 -1
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/examples/List.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/realworld2/view/HomeContainer.mjs +1 -1
- package/apps/route/view/center/CardAdministration.mjs +3 -3
- package/apps/route/view/center/CardAdministrationDenied.mjs +2 -2
- package/apps/route/view/center/CardContact.mjs +2 -2
- package/apps/route/view/center/CardHome.mjs +2 -2
- package/apps/route/view/center/CardSection1.mjs +2 -2
- package/apps/route/view/center/CardSection2.mjs +2 -2
- package/buildScripts/createApp.mjs +2 -2
- package/docs/app/view/classdetails/HeaderComponent.mjs +3 -3
- package/docs/app/view/classdetails/MembersList.mjs +43 -46
- package/docs/app/view/classdetails/SourceViewComponent.mjs +1 -1
- package/docs/app/view/classdetails/TutorialComponent.mjs +1 -1
- package/examples/component/toast/MainContainer.mjs +16 -16
- package/examples/component/wrapper/googleMaps/MarkerDialog.mjs +4 -4
- package/examples/fields/MainContainer.mjs +1 -1
- package/examples/panel/MainContainer.mjs +2 -2
- package/examples/tab/container/MainContainer.mjs +3 -3
- package/examples/tabs/MainContainer.mjs +2 -2
- package/examples/tabs/MainContainer2.mjs +3 -3
- package/examples/viewport/MainContainer.mjs +2 -2
- package/package.json +33 -5
- package/resources/data/deck/learnneo/pages/benefits/FourEnvironments.md +1 -1
- package/resources/data/deck/learnneo/pages/benefits/Introduction.md +4 -3
- package/resources/data/deck/learnneo/pages/guides/events/DomEvents.md +5 -5
- package/resources/data/deck/training/pages/2022-12-27T21-55-23-144Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T18-36-08-226Z.md +1 -1
- package/resources/data/deck/training/pages/2022-12-29T18-36-56-893Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-08-919Z.md +2 -2
- package/resources/data/deck/training/pages/2022-12-29T20-37-20-344Z.md +2 -2
- package/resources/data/deck/training/pages/2023-01-13T21-48-17-258Z.md +2 -2
- package/resources/data/deck/training/pages/2023-02-05T17-44-53-815Z.md +9 -9
- package/resources/data/deck/training/pages/2023-10-14T19-25-08-153Z.md +1 -1
- package/src/DefaultConfig.mjs +14 -2
- package/src/Main.mjs +15 -6
- package/src/button/Base.mjs +1 -1
- package/src/calendar/view/calendars/List.mjs +1 -1
- package/src/component/Base.mjs +11 -11
- package/src/component/Chip.mjs +1 -1
- package/src/component/Helix.mjs +3 -3
- package/src/component/Process.mjs +2 -2
- package/src/component/StatusBadge.mjs +2 -2
- package/src/component/Timer.mjs +1 -1
- package/src/component/Toast.mjs +2 -2
- package/src/container/Base.mjs +1 -1
- package/src/form/field/CheckBox.mjs +2 -2
- package/src/form/field/FileUpload.mjs +14 -14
- package/src/form/field/Range.mjs +1 -1
- package/src/form/field/Text.mjs +1 -1
- package/src/form/field/trigger/Base.mjs +2 -2
- package/src/form/field/trigger/SpinUpDown.mjs +2 -2
- package/src/grid/View.mjs +1 -1
- package/src/main/DeltaUpdates.mjs +442 -0
- package/src/main/DomAccess.mjs +13 -95
- package/src/main/render/DomApiRenderer.mjs +138 -0
- package/src/main/render/StringBasedRenderer.mjs +58 -0
- package/src/table/View.mjs +1 -1
- package/src/table/plugin/CellEditing.mjs +1 -1
- package/src/tree/Accordion.mjs +11 -11
- package/src/tree/List.mjs +12 -5
- package/src/vdom/Helper.mjs +179 -309
- package/src/vdom/VNode.mjs +47 -11
- package/src/vdom/domConstants.mjs +65 -0
- package/src/vdom/util/DomApiVnodeCreator.mjs +51 -0
- package/src/vdom/util/StringFromVnode.mjs +123 -0
- package/src/worker/mixin/RemoteMethodAccess.mjs +13 -1
- package/src/main/mixin/DeltaUpdates.mjs +0 -352
@@ -0,0 +1,442 @@
|
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
import DomAccess from './DomAccess.mjs';
|
3
|
+
import {voidAttributes} from '../vdom/domConstants.mjs';
|
4
|
+
|
5
|
+
const NeoConfig = Neo.config;
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Logic to apply the deltas generated by vdom.Helper to the real DOM
|
9
|
+
* @class Neo.main.DeltaUpdates
|
10
|
+
* @extends Neo.core.Base
|
11
|
+
* @singleton
|
12
|
+
*/
|
13
|
+
class DeltaUpdates extends Base {
|
14
|
+
static config = {
|
15
|
+
/**
|
16
|
+
* @member {String} className='Neo.main.DeltaUpdates'
|
17
|
+
* @protected
|
18
|
+
*/
|
19
|
+
className: 'Neo.main.DeltaUpdates',
|
20
|
+
/**
|
21
|
+
* @member {Number} countDeltas=0
|
22
|
+
* @protected
|
23
|
+
*/
|
24
|
+
countDeltas: 0,
|
25
|
+
/**
|
26
|
+
* @member {Number} countDeltasPer250ms=0
|
27
|
+
* @protected
|
28
|
+
*/
|
29
|
+
countDeltasPer250ms: 0,
|
30
|
+
/**
|
31
|
+
* @member {Number} countUpdates=0
|
32
|
+
* @protected
|
33
|
+
*/
|
34
|
+
countUpdates: 0,
|
35
|
+
/**
|
36
|
+
* @member {Boolean} renderCountDeltas_=false
|
37
|
+
* @protected
|
38
|
+
*/
|
39
|
+
renderCountDeltas_: false,
|
40
|
+
/**
|
41
|
+
* @member {Boolean} singleton=true
|
42
|
+
*/
|
43
|
+
singleton: true
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* @member {Number} logDeltasIntervalId=0
|
48
|
+
* @protected
|
49
|
+
*/
|
50
|
+
logDeltasIntervalId = 0
|
51
|
+
/**
|
52
|
+
* Private property to store the dynamically loaded renderer module.
|
53
|
+
* @member {Neo.main.render.DomApiRenderer|Neo.main.render.DomApiRenderer|null} #renderer=null
|
54
|
+
* @private
|
55
|
+
*/
|
56
|
+
#renderer = null
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Private property to signal that the renderer module has been loaded.
|
60
|
+
* This will be a Promise that resolves when the module is ready.
|
61
|
+
* @private
|
62
|
+
* @member {Promise<void>|null} #_readyPromise
|
63
|
+
*/
|
64
|
+
#_readyPromise = null
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @param {Object} config
|
68
|
+
*/
|
69
|
+
construct(config) {
|
70
|
+
super.construct(config);
|
71
|
+
|
72
|
+
let me = this;
|
73
|
+
|
74
|
+
if (Neo.config.renderCountDeltas) {
|
75
|
+
me.renderCountDeltas = true
|
76
|
+
}
|
77
|
+
|
78
|
+
// Initiate the asynchronous loading of the renderer here.
|
79
|
+
me.#_readyPromise = (async () => {
|
80
|
+
try {
|
81
|
+
let module;
|
82
|
+
|
83
|
+
if (NeoConfig.useStringBasedMounting) {
|
84
|
+
module = await import('./render/StringBasedRenderer.mjs')
|
85
|
+
} else {
|
86
|
+
module = await import('./render/DomApiRenderer.mjs')
|
87
|
+
}
|
88
|
+
|
89
|
+
me.#renderer = module.default
|
90
|
+
} catch (err) {
|
91
|
+
console.error('DeltaUpdates: Failed to load renderer module:', err);
|
92
|
+
throw err // Re-throw to propagate initialization failures
|
93
|
+
}
|
94
|
+
})()
|
95
|
+
}
|
96
|
+
|
97
|
+
/**
|
98
|
+
* Triggered after the renderCountDeltas config got changed
|
99
|
+
* @param {Boolean} value
|
100
|
+
* @param {Boolean} oldValue
|
101
|
+
* @protected
|
102
|
+
*/
|
103
|
+
afterSetRenderCountDeltas(value, oldValue) {
|
104
|
+
let me = this,
|
105
|
+
{logDeltasIntervalId} = me,
|
106
|
+
node;
|
107
|
+
|
108
|
+
if (value) {
|
109
|
+
if (logDeltasIntervalId === 0) {
|
110
|
+
me.logDeltasIntervalId = setInterval(() => {
|
111
|
+
node = document.getElementById('neo-delta-updates');
|
112
|
+
|
113
|
+
if (node) {
|
114
|
+
node.innerHTML = String(me.countDeltasPer250ms * 4)
|
115
|
+
}
|
116
|
+
|
117
|
+
me.countDeltasPer250ms = 0
|
118
|
+
}, 250)
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
logDeltasIntervalId && clearInterval(logDeltasIntervalId);
|
122
|
+
me.logDeltasInterval = 0
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* @param {HTMLElement} node
|
128
|
+
* @param {String} nodeName
|
129
|
+
*/
|
130
|
+
changeNodeName(node, nodeName) {
|
131
|
+
let {attributes} = node,
|
132
|
+
clone = document.createElement(nodeName),
|
133
|
+
i = 0,
|
134
|
+
len = attributes.length,
|
135
|
+
attribute;
|
136
|
+
|
137
|
+
if (node) {
|
138
|
+
for (; i < len; i++) {
|
139
|
+
attribute = attributes.item(i);
|
140
|
+
clone.setAttribute(attribute.nodeName, attribute.nodeValue)
|
141
|
+
}
|
142
|
+
|
143
|
+
clone.innerHTML= node.innerHTML;
|
144
|
+
|
145
|
+
node.parentNode.replaceChild(clone, node)
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* @param {Object} delta
|
151
|
+
* @param {String} delta.id
|
152
|
+
*/
|
153
|
+
focusNode({id}) {
|
154
|
+
DomAccess.getElement(id)?.focus()
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Inserts a new node into the DOM tree based on delta updates.
|
159
|
+
* This method handles both string-based (outerHTML) and direct DOM API (vnode) mounting.
|
160
|
+
* It ensures the node is inserted at the correct index within the parent.
|
161
|
+
*
|
162
|
+
* Implementation Details & Considerations:
|
163
|
+
* - `parentNode.children` contains only element nodes (tags).
|
164
|
+
* - `parentNode.childNodes` contains all nodes, including text and comment nodes.
|
165
|
+
* - Since every `vtype:'text'` is wrapped inside a comment block (as an ID),
|
166
|
+
* calculating a "realIndex" is necessary for string-based insertions to
|
167
|
+
* correctly account for non-element nodes.
|
168
|
+
* - `insertAdjacentHTML()` is generally faster than creating a node via template,
|
169
|
+
* but it's only available for manipulating children (elements), not `childNodes` (all nodes).
|
170
|
+
* - For performance, in cases where there are no comment nodes (i.e., no wrapped text nodes),
|
171
|
+
* the method prioritizes `insertAdjacentHTML()` when `useStringBasedMounting` is true.
|
172
|
+
*
|
173
|
+
* @param {Object} delta
|
174
|
+
* @param {Boolean} delta.hasLeadingTextChildren Flag to honor leading comments, which require special treatment.
|
175
|
+
* @param {Number} delta.index The index at which to insert the new node within its parent.
|
176
|
+
* @param {String} [delta.outerHTML] The string representation of the new node (for string-based mounting).
|
177
|
+
* @param {String} delta.parentId The ID of the parent DOM node.
|
178
|
+
* @param {Neo.vdom.VNode} [delta.vnode] The VNode representation of the new node (for direct DOM API mounting).
|
179
|
+
*/
|
180
|
+
insertNode({hasLeadingTextChildren, index, outerHTML, parentId, vnode}) {
|
181
|
+
// This method is synchronous and *expects* the renderer to be loaded
|
182
|
+
if (!this.#renderer) {
|
183
|
+
console.error('DeltaUpdates renderer not ready during insertNode!');
|
184
|
+
return
|
185
|
+
}
|
186
|
+
|
187
|
+
const parentNode = DomAccess.getElementOrBody(parentId);
|
188
|
+
|
189
|
+
if (parentNode) {
|
190
|
+
if (!NeoConfig.useStringBasedMounting) {
|
191
|
+
this.#renderer.createDomTree({index, isRoot: true, parentNode, vnode})
|
192
|
+
} else {
|
193
|
+
this.#renderer.insertNodeAsString({hasLeadingTextChildren, index, outerHTML, parentNode})
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Moves an existing DOM node to a new position within its parent
|
200
|
+
* or to a new parent.
|
201
|
+
* This method directly manipulates the DOM using the pre-calculated physical index.
|
202
|
+
*
|
203
|
+
* @param {Object} delta
|
204
|
+
* @param {String} delta.id The ID of the DOM node to move.
|
205
|
+
* @param {Number} delta.index The physical index at which to insert the node
|
206
|
+
* @param {String} delta.parentId The ID of the target parent DOM node.
|
207
|
+
*/
|
208
|
+
moveNode({id, index, parentId}) {
|
209
|
+
let node = DomAccess.getElement(id),
|
210
|
+
parentNode = DomAccess.getElement(parentId);
|
211
|
+
|
212
|
+
if (node && parentNode) {
|
213
|
+
// If the target index is at or beyond the end of the parent's current childNodes, append the node.
|
214
|
+
if (index >= parentNode.childNodes.length) {
|
215
|
+
parentNode.appendChild(node)
|
216
|
+
} else {
|
217
|
+
// Get the reference node at the target physical index.
|
218
|
+
let referenceNode = parentNode.childNodes[index];
|
219
|
+
|
220
|
+
// Only proceed if the node is not already at its target position.
|
221
|
+
if (node !== referenceNode) {
|
222
|
+
// Perform a direct swap operation if immediate element siblings.
|
223
|
+
if (node.nodeType === 1 && node === referenceNode.nextElementSibling) {
|
224
|
+
node.replaceWith(referenceNode)
|
225
|
+
}
|
226
|
+
|
227
|
+
parentNode.insertBefore(node, referenceNode)
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
/**
|
234
|
+
* @param {Object} delta
|
235
|
+
* @param {String} delta.parentId
|
236
|
+
*/
|
237
|
+
removeAll({parentId}) {
|
238
|
+
let node = DomAccess.getElement(parentId);
|
239
|
+
|
240
|
+
if (node) {
|
241
|
+
node.innerHTML = ''
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* @param {Object} delta
|
247
|
+
* @param {String} delta.id
|
248
|
+
* @param {String} delta.parentId
|
249
|
+
*/
|
250
|
+
removeNode({id, parentId}) {
|
251
|
+
const node = DomAccess.getElement(id);
|
252
|
+
|
253
|
+
if (node) {
|
254
|
+
node.remove();
|
255
|
+
}
|
256
|
+
// Potentially a vtype: 'text' node (wrapped between 2 comments)
|
257
|
+
else if (parentId) {
|
258
|
+
const
|
259
|
+
parentNode = DomAccess.getElementOrBody(parentId),
|
260
|
+
isComment = Node.COMMENT_NODE;
|
261
|
+
|
262
|
+
if (parentNode) {
|
263
|
+
// Find the starting comment node using its id marker
|
264
|
+
const startComment = Array.from(parentNode.childNodes).find(n =>
|
265
|
+
n.nodeType === isComment && n.nodeValue.includes(` ${id} `)
|
266
|
+
);
|
267
|
+
|
268
|
+
if (startComment) {
|
269
|
+
const
|
270
|
+
textNode = startComment.nextSibling,
|
271
|
+
// Ensure endComment is a comment node before attempting to remove
|
272
|
+
endComment = textNode?.nextSibling?.nodeType === isComment ? textNode.nextSibling : null;
|
273
|
+
|
274
|
+
// Remove the three parts: start comment, text node, end comment
|
275
|
+
startComment.remove();
|
276
|
+
textNode?.remove();
|
277
|
+
endComment?.remove()
|
278
|
+
}
|
279
|
+
}
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
/**
|
284
|
+
* @param {Object} delta
|
285
|
+
* @param {String} delta.fromId
|
286
|
+
* @param {String} delta.parentId
|
287
|
+
* @param {String} delta.toId
|
288
|
+
*/
|
289
|
+
replaceChild({fromId, parentId, toId}) {
|
290
|
+
let node = DomAccess.getElement(parentId);
|
291
|
+
|
292
|
+
node?.replaceChild(DomAccess.getElement(toId), DomAccess.getElement(fromId))
|
293
|
+
}
|
294
|
+
|
295
|
+
/**
|
296
|
+
* @param {Object} delta
|
297
|
+
* @param {String} [delta.id]
|
298
|
+
* @param {String} [delta.value
|
299
|
+
*/
|
300
|
+
setTextContent({id, value}) {
|
301
|
+
let node = DomAccess.getElement(id);
|
302
|
+
|
303
|
+
if (node) {
|
304
|
+
node.textContent = value
|
305
|
+
}
|
306
|
+
}
|
307
|
+
|
308
|
+
/**
|
309
|
+
* @param {Object} delta
|
310
|
+
* @param {Object} [delta.attributes]
|
311
|
+
* @param {String} [delta.cls]
|
312
|
+
* @param {String} [delta.id]
|
313
|
+
* @param {String} [delta.innerHTML]
|
314
|
+
* @param {String} [delta.outerHTML]
|
315
|
+
* @param {Object} [delta.style]
|
316
|
+
*/
|
317
|
+
updateNode(delta) {
|
318
|
+
let me = this,
|
319
|
+
node = DomAccess.getElementOrBody(delta.id);
|
320
|
+
|
321
|
+
if (!node) {
|
322
|
+
console.log('node not found', delta.id);
|
323
|
+
}
|
324
|
+
|
325
|
+
if (node) {
|
326
|
+
Object.entries(delta).forEach(([prop, value]) => {
|
327
|
+
switch(prop) {
|
328
|
+
case 'attributes':
|
329
|
+
Object.entries(value).forEach(([key, val]) => {
|
330
|
+
if (voidAttributes.has(key)) {
|
331
|
+
node[key] = val === 'true' // vnode attribute values get converted into strings
|
332
|
+
} else if (val === null || val === '') {
|
333
|
+
if (key === 'value') {
|
334
|
+
node[key] = '' // input fields => pseudo attribute can not be removed
|
335
|
+
} else {
|
336
|
+
node.removeAttribute(key)
|
337
|
+
}
|
338
|
+
} else if (key === 'id') {
|
339
|
+
node[NeoConfig.useDomIds ? 'id' : 'data-neo-id'] = val
|
340
|
+
} else if (key === 'spellcheck' && val === 'false') {
|
341
|
+
// see https://github.com/neomjs/neo/issues/1922
|
342
|
+
node[key] = false
|
343
|
+
} else {
|
344
|
+
if (key === 'value') {
|
345
|
+
node[key] = val
|
346
|
+
} else {
|
347
|
+
node.setAttribute(key, val)
|
348
|
+
}
|
349
|
+
}
|
350
|
+
});
|
351
|
+
break
|
352
|
+
case 'cls':
|
353
|
+
value.add && node.classList.add(...value.add);
|
354
|
+
value.remove && node.classList.remove(...value.remove);
|
355
|
+
break
|
356
|
+
case 'innerHTML':
|
357
|
+
node.innerHTML = value || '';
|
358
|
+
break
|
359
|
+
case 'nodeName':
|
360
|
+
me.changeNodeName(node, value);
|
361
|
+
break
|
362
|
+
case 'outerHTML':
|
363
|
+
node.outerHTML = value || '';
|
364
|
+
break
|
365
|
+
case 'style':
|
366
|
+
if (Neo.isObject(value)) {
|
367
|
+
Object.entries(value).forEach(([key, val]) => {
|
368
|
+
let important;
|
369
|
+
|
370
|
+
if (Neo.isString(val) && val.includes('!important')) {
|
371
|
+
val = val.replace('!important', '').trim();
|
372
|
+
important = 'important'
|
373
|
+
}
|
374
|
+
|
375
|
+
node.style.setProperty(Neo.decamel(key), val, important)
|
376
|
+
})
|
377
|
+
}
|
378
|
+
break
|
379
|
+
}
|
380
|
+
})
|
381
|
+
}
|
382
|
+
}
|
383
|
+
|
384
|
+
/**
|
385
|
+
* @param {Object} delta
|
386
|
+
* @param {String} delta.id
|
387
|
+
* @param {String} delta.parentId
|
388
|
+
* @param {String} delta.value
|
389
|
+
*/
|
390
|
+
updateVtext({id, parentId, value}) {
|
391
|
+
let node = DomAccess.getElement(parentId),
|
392
|
+
innerHTML = node.innerHTML,
|
393
|
+
startTag = `<!-- ${id} -->`,
|
394
|
+
reg = new RegExp(startTag + '[\\s\\S]*?<!-- \/neo-vtext -->');
|
395
|
+
|
396
|
+
node.innerHTML = innerHTML.replace(reg, value)
|
397
|
+
}
|
398
|
+
|
399
|
+
/**
|
400
|
+
* @param {Object} data
|
401
|
+
* @param {Object|Object[]} data.deltas
|
402
|
+
* @param {String} data.id
|
403
|
+
* @param {String} [data.origin='app']
|
404
|
+
*/
|
405
|
+
update(data) {
|
406
|
+
// This method is synchronous and *expects* the renderer to be loaded
|
407
|
+
if (!this.#renderer) {
|
408
|
+
console.error('DeltaUpdates renderer not ready during insertNode!');
|
409
|
+
return
|
410
|
+
}
|
411
|
+
|
412
|
+
let me = this,
|
413
|
+
{deltas} = data,
|
414
|
+
i = 0,
|
415
|
+
len;
|
416
|
+
|
417
|
+
deltas = Array.isArray(deltas) ? deltas : [deltas];
|
418
|
+
len = deltas.length;
|
419
|
+
|
420
|
+
if (NeoConfig.logDeltaUpdates && len > 0) {
|
421
|
+
me.countDeltas += len;
|
422
|
+
me.countUpdates++;
|
423
|
+
console.log('update ' + me.countUpdates, 'total deltas ', me.countDeltas, Neo.clone(data, true))
|
424
|
+
}
|
425
|
+
|
426
|
+
if (NeoConfig.renderCountDeltas && len > 0) {
|
427
|
+
me.countDeltasPer250ms += len
|
428
|
+
}
|
429
|
+
|
430
|
+
for (; i < len; i++) {
|
431
|
+
me[deltas[i].action || 'updateNode'](deltas[i])
|
432
|
+
}
|
433
|
+
|
434
|
+
Neo.worker.Manager.sendMessage(data.origin || 'app', {
|
435
|
+
action : 'reply',
|
436
|
+
replyId: data.id,
|
437
|
+
success: true
|
438
|
+
})
|
439
|
+
}
|
440
|
+
}
|
441
|
+
|
442
|
+
export default Neo.setupClass(DeltaUpdates);
|
package/src/main/DomAccess.mjs
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
import Base
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import Rectangle from '../util/Rectangle.mjs';
|
6
|
-
import StringUtil from '../util/String.mjs';
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
import DomUtils from './DomUtils.mjs';
|
3
|
+
import Rectangle from '../util/Rectangle.mjs';
|
4
|
+
import StringUtil from '../util/String.mjs';
|
7
5
|
|
8
6
|
const
|
9
7
|
doPreventDefault = e => e.preventDefault(),
|
@@ -43,34 +41,19 @@ const
|
|
43
41
|
* @singleton
|
44
42
|
*/
|
45
43
|
class DomAccess extends Base {
|
44
|
+
/**
|
45
|
+
* True automatically applies the core.Observable mixin
|
46
|
+
* @member {Boolean} observable=true
|
47
|
+
* @static
|
48
|
+
*/
|
49
|
+
static observable = true
|
50
|
+
|
46
51
|
static config = {
|
47
52
|
/**
|
48
53
|
* @member {String} className='Neo.main.DomAccess'
|
49
54
|
* @protected
|
50
55
|
*/
|
51
56
|
className: 'Neo.main.DomAccess',
|
52
|
-
/**
|
53
|
-
* @member {Number} countDeltas=0
|
54
|
-
* @protected
|
55
|
-
*/
|
56
|
-
countDeltas: 0,
|
57
|
-
/**
|
58
|
-
* @member {Number} countDeltasPer250ms=0
|
59
|
-
* @protected
|
60
|
-
*/
|
61
|
-
countDeltasPer250ms: 0,
|
62
|
-
/**
|
63
|
-
* @member {Number} countUpdates=0
|
64
|
-
* @protected
|
65
|
-
*/
|
66
|
-
countUpdates: 0,
|
67
|
-
/**
|
68
|
-
* @member {Array} mixins=[DeltaUpdates, Observable]
|
69
|
-
*/
|
70
|
-
mixins: [
|
71
|
-
DeltaUpdates,
|
72
|
-
Observable
|
73
|
-
],
|
74
57
|
/**
|
75
58
|
* Remote method access for other workers
|
76
59
|
* @member {Object} remote
|
@@ -104,33 +87,13 @@ class DomAccess extends Base {
|
|
104
87
|
'windowScrollTo'
|
105
88
|
]
|
106
89
|
},
|
107
|
-
/**
|
108
|
-
* @member {Boolean} renderCountDeltas_=false
|
109
|
-
* @protected
|
110
|
-
*/
|
111
|
-
renderCountDeltas_: false,
|
112
90
|
/**
|
113
91
|
* @member {Boolean} singleton=true
|
114
92
|
* @protected
|
115
93
|
*/
|
116
|
-
singleton: true
|
117
|
-
/**
|
118
|
-
* Void attributes inside html tags
|
119
|
-
* @member {String[]} voidAttributes
|
120
|
-
* @protected
|
121
|
-
*/
|
122
|
-
voidAttributes: [
|
123
|
-
'checked',
|
124
|
-
'required'
|
125
|
-
]
|
94
|
+
singleton: true
|
126
95
|
}
|
127
96
|
|
128
|
-
/**
|
129
|
-
* @member {Number} logDeltasIntervalId=0
|
130
|
-
* @protected
|
131
|
-
*/
|
132
|
-
logDeltasIntervalId = 0
|
133
|
-
|
134
97
|
/**
|
135
98
|
* @returns {HTMLElement}
|
136
99
|
*/
|
@@ -154,10 +117,6 @@ class DomAccess extends Base {
|
|
154
117
|
|
155
118
|
let me = this;
|
156
119
|
|
157
|
-
if (Neo.config.renderCountDeltas) {
|
158
|
-
me.renderCountDeltas = true
|
159
|
-
}
|
160
|
-
|
161
120
|
me.initGlobalListeners();
|
162
121
|
|
163
122
|
// Set up our aligning callback which is called when things change which may
|
@@ -229,35 +188,6 @@ class DomAccess extends Base {
|
|
229
188
|
document.head.appendChild(script)
|
230
189
|
}
|
231
190
|
|
232
|
-
/**
|
233
|
-
* Triggered after the renderCountDeltas config got changed
|
234
|
-
* @param {Boolean} value
|
235
|
-
* @param {Boolean} oldValue
|
236
|
-
* @protected
|
237
|
-
*/
|
238
|
-
afterSetRenderCountDeltas(value, oldValue) {
|
239
|
-
let me = this,
|
240
|
-
{logDeltasIntervalId} = me,
|
241
|
-
node;
|
242
|
-
|
243
|
-
if (value) {
|
244
|
-
if (logDeltasIntervalId === 0) {
|
245
|
-
me.logDeltasIntervalId = setInterval(() => {
|
246
|
-
node = document.getElementById('neo-delta-updates');
|
247
|
-
|
248
|
-
if (node) {
|
249
|
-
node.innerHTML = String(me.countDeltasPer250ms * 4)
|
250
|
-
}
|
251
|
-
|
252
|
-
me.countDeltasPer250ms = 0
|
253
|
-
}, 250)
|
254
|
-
}
|
255
|
-
} else {
|
256
|
-
logDeltasIntervalId && clearInterval(logDeltasIntervalId);
|
257
|
-
me.logDeltasInterval = 0
|
258
|
-
}
|
259
|
-
}
|
260
|
-
|
261
191
|
/**
|
262
192
|
* @param {Object} data
|
263
193
|
* @returns {Promise<void>}
|
@@ -865,7 +795,7 @@ class DomAccess extends Base {
|
|
865
795
|
* @protected
|
866
796
|
*/
|
867
797
|
read(data) {
|
868
|
-
|
798
|
+
Neo.isFunction(data) && data()
|
869
799
|
}
|
870
800
|
|
871
801
|
/**
|
@@ -1160,18 +1090,6 @@ class DomAccess extends Base {
|
|
1160
1090
|
top : data.top || 0
|
1161
1091
|
})
|
1162
1092
|
}
|
1163
|
-
|
1164
|
-
/**
|
1165
|
-
* @param {Object} data
|
1166
|
-
* @protected
|
1167
|
-
*/
|
1168
|
-
write(data) {
|
1169
|
-
this.du_insertNode({
|
1170
|
-
index : data.parentIndex,
|
1171
|
-
outerHTML: data.html || data.outerHTML,
|
1172
|
-
parentId : data.parentId
|
1173
|
-
})
|
1174
|
-
}
|
1175
1093
|
}
|
1176
1094
|
|
1177
1095
|
export default Neo.setupClass(DomAccess);
|