@lvce-editor/virtual-dom 9.3.0 → 9.5.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/dist/index.js
CHANGED
|
@@ -1,9 +1,350 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const uidSymbol = Symbol('uid');
|
|
2
|
+
|
|
3
|
+
const getUidTarget = $Element => {
|
|
4
|
+
while ($Element) {
|
|
5
|
+
if ($Element[uidSymbol]) {
|
|
6
|
+
return $Element;
|
|
7
|
+
}
|
|
8
|
+
$Element = $Element.parentNode;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
4
11
|
};
|
|
5
|
-
|
|
6
|
-
|
|
12
|
+
|
|
13
|
+
const setComponentUid = ($Element, uid) => {
|
|
14
|
+
$Element[uidSymbol] = uid;
|
|
15
|
+
};
|
|
16
|
+
const getComponentUid = $Element => {
|
|
17
|
+
const $Target = getUidTarget($Element);
|
|
18
|
+
if (!$Target) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
return $Target[uidSymbol];
|
|
22
|
+
};
|
|
23
|
+
const getComponentUidFromEvent = event => {
|
|
24
|
+
const {
|
|
25
|
+
currentTarget,
|
|
26
|
+
target
|
|
27
|
+
} = event;
|
|
28
|
+
return getComponentUid(currentTarget || target);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const dragInfos = Object.create(null);
|
|
32
|
+
const setDragInfo = (id, data) => {
|
|
33
|
+
dragInfos[id] = data;
|
|
34
|
+
};
|
|
35
|
+
const getDragInfo = id => {
|
|
36
|
+
return dragInfos[id];
|
|
37
|
+
};
|
|
38
|
+
const removeDragInfo = id => {
|
|
39
|
+
delete dragInfos[id];
|
|
40
|
+
};
|
|
41
|
+
const isDragInfoOld = data => {
|
|
42
|
+
return Array.isArray(data);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const setDragImage = (dataTransfer, label) => {
|
|
46
|
+
const dragImage = document.createElement('div');
|
|
47
|
+
dragImage.className = 'DragImage';
|
|
48
|
+
dragImage.textContent = label;
|
|
49
|
+
document.body.append(dragImage);
|
|
50
|
+
dataTransfer.setDragImage(dragImage, -10, -10);
|
|
51
|
+
const handleTimeOut = () => {
|
|
52
|
+
dragImage.remove();
|
|
53
|
+
};
|
|
54
|
+
setTimeout(handleTimeOut, 0);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const applyDragInfoMaybe = event => {
|
|
58
|
+
const {
|
|
59
|
+
dataTransfer,
|
|
60
|
+
target
|
|
61
|
+
} = event;
|
|
62
|
+
if (dataTransfer) {
|
|
63
|
+
const uid = getComponentUid(target);
|
|
64
|
+
const dragInfo = getDragInfo(uid);
|
|
65
|
+
if (!dragInfo) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (isDragInfoOld(dragInfo)) {
|
|
69
|
+
for (const item of dragInfo) {
|
|
70
|
+
dataTransfer.setData(item.type, item.data);
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
for (const item of dragInfo.items) {
|
|
74
|
+
dataTransfer.items.add(item.data, item.type);
|
|
75
|
+
}
|
|
76
|
+
if (dragInfo.label) {
|
|
77
|
+
setDragImage(dataTransfer, dragInfo.label);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const PointerMove = 'pointermove';
|
|
84
|
+
const lostpointercapture = 'lostpointercapture';
|
|
85
|
+
|
|
86
|
+
let ignore = false;
|
|
87
|
+
const startIgnore = () => {
|
|
88
|
+
ignore = true;
|
|
89
|
+
};
|
|
90
|
+
const stopIgnore = () => {
|
|
91
|
+
ignore = false;
|
|
92
|
+
};
|
|
93
|
+
const enabled = () => {
|
|
94
|
+
return ignore;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
let id = 0;
|
|
98
|
+
const create = () => {
|
|
99
|
+
return ++id;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const state$1 = Object.create(null);
|
|
103
|
+
const acquire = id => {
|
|
104
|
+
const promise = state$1[id];
|
|
105
|
+
delete state$1[id];
|
|
106
|
+
return promise;
|
|
107
|
+
};
|
|
108
|
+
const getFileHandles = async ids => {
|
|
109
|
+
const promises = ids.map(acquire);
|
|
110
|
+
const handles = await Promise.all(promises);
|
|
111
|
+
return handles;
|
|
112
|
+
};
|
|
113
|
+
const add$1 = promise => {
|
|
114
|
+
const id = create();
|
|
115
|
+
state$1[id] = promise;
|
|
116
|
+
return id;
|
|
117
|
+
};
|
|
118
|
+
const addFileHandle = fileHandle => {
|
|
119
|
+
const promise = Promise.resolve(fileHandle);
|
|
120
|
+
return add$1(promise);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const unwrapItemString = async item => {
|
|
124
|
+
const {
|
|
125
|
+
resolve,
|
|
126
|
+
promise
|
|
127
|
+
} = Promise.withResolvers();
|
|
128
|
+
item.getAsString(resolve);
|
|
129
|
+
const value = await promise;
|
|
130
|
+
return {
|
|
131
|
+
kind: 'string',
|
|
132
|
+
type: item.type,
|
|
133
|
+
value
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
const unwrapItemFile = async item => {
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
const file = await item.getAsFileSystemHandle();
|
|
139
|
+
return {
|
|
140
|
+
kind: 'file',
|
|
141
|
+
type: item.type,
|
|
142
|
+
value: file
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const unknownItem = {
|
|
146
|
+
kind: 'unknown',
|
|
147
|
+
type: '',
|
|
148
|
+
value: ''
|
|
149
|
+
};
|
|
150
|
+
const unwrapItem = item => {
|
|
151
|
+
switch (item.kind) {
|
|
152
|
+
case 'file':
|
|
153
|
+
return unwrapItemFile(item);
|
|
154
|
+
case 'string':
|
|
155
|
+
return unwrapItemString(item);
|
|
156
|
+
default:
|
|
157
|
+
return unknownItem;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const handleDataTransferFiles = event => {
|
|
161
|
+
if (!event.dataTransfer) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
const items = [...event.dataTransfer.items];
|
|
165
|
+
const promises = items.map(unwrapItem);
|
|
166
|
+
const ids = promises.map(promise => add$1(promise));
|
|
167
|
+
return ids;
|
|
168
|
+
};
|
|
169
|
+
const getEventListenerArg = (param, event) => {
|
|
170
|
+
switch (param) {
|
|
171
|
+
case 'event.altKey':
|
|
172
|
+
return event.altKey;
|
|
173
|
+
case 'event.button':
|
|
174
|
+
return event.button;
|
|
175
|
+
case 'event.clientX':
|
|
176
|
+
return event.clientX;
|
|
177
|
+
case 'event.clientY':
|
|
178
|
+
return event.clientY;
|
|
179
|
+
case 'event.ctrlKey':
|
|
180
|
+
return event.ctrlKey;
|
|
181
|
+
case 'event.data':
|
|
182
|
+
return event.data;
|
|
183
|
+
case 'event.dataTransfer.files':
|
|
184
|
+
return event.dataTransfer.files;
|
|
185
|
+
case 'event.dataTransfer.files2':
|
|
186
|
+
return handleDataTransferFiles(event);
|
|
187
|
+
case 'event.defaultPrevented':
|
|
188
|
+
return event.defaultPrevented;
|
|
189
|
+
case 'event.deltaMode':
|
|
190
|
+
return event.deltaMode;
|
|
191
|
+
case 'event.deltaX':
|
|
192
|
+
return event.deltaX;
|
|
193
|
+
case 'event.deltaY':
|
|
194
|
+
return event.deltaY;
|
|
195
|
+
case 'event.detail':
|
|
196
|
+
return event.detail;
|
|
197
|
+
case 'event.inputType':
|
|
198
|
+
return event.inputType;
|
|
199
|
+
case 'event.isTrusted':
|
|
200
|
+
return event.isTrusted;
|
|
201
|
+
case 'event.key':
|
|
202
|
+
return event.key;
|
|
203
|
+
case 'event.shiftKey':
|
|
204
|
+
return event.shiftKey;
|
|
205
|
+
case 'event.target.checked':
|
|
206
|
+
return event.target.checked;
|
|
207
|
+
case 'event.target.className':
|
|
208
|
+
return event.target.className;
|
|
209
|
+
case 'event.target.href':
|
|
210
|
+
return event.target.href;
|
|
211
|
+
case 'event.target.name':
|
|
212
|
+
return event.target.name || '';
|
|
213
|
+
case 'event.target.nodeName':
|
|
214
|
+
return event.target.nodeName;
|
|
215
|
+
case 'event.target.scrollTop':
|
|
216
|
+
return event.target.scrollTop;
|
|
217
|
+
case 'event.target.selectionEnd':
|
|
218
|
+
return event.target.selectionEnd;
|
|
219
|
+
case 'event.target.selectionStart':
|
|
220
|
+
return event.target.selectionStart;
|
|
221
|
+
case 'event.target.src':
|
|
222
|
+
return event.target.src;
|
|
223
|
+
case 'event.target.value':
|
|
224
|
+
return event.target.value;
|
|
225
|
+
case 'event.x':
|
|
226
|
+
return event.x;
|
|
227
|
+
case 'event.y':
|
|
228
|
+
return event.y;
|
|
229
|
+
default:
|
|
230
|
+
if (typeof param === 'string' && param.startsWith('event.currentTarget.')) {
|
|
231
|
+
const rest = param.slice('event.currentTarget.'.length);
|
|
232
|
+
const parts = rest.split('.');
|
|
233
|
+
let current = event.currentTarget;
|
|
234
|
+
for (const part of parts) {
|
|
235
|
+
current = current[part];
|
|
236
|
+
}
|
|
237
|
+
return current;
|
|
238
|
+
}
|
|
239
|
+
if (typeof param === 'string' && param.startsWith('event.target.dataset')) {
|
|
240
|
+
const rest = param.slice('event.target.dataset.'.length);
|
|
241
|
+
return event.target.dataset[rest];
|
|
242
|
+
}
|
|
243
|
+
return param;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const getEventListenerArgs = (params, event) => {
|
|
248
|
+
const serialized = [];
|
|
249
|
+
for (const param of params) {
|
|
250
|
+
serialized.push(getEventListenerArg(param, event));
|
|
251
|
+
}
|
|
252
|
+
return serialized;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const state = {
|
|
256
|
+
ipc: undefined
|
|
257
|
+
};
|
|
258
|
+
const getIpc = () => {
|
|
259
|
+
return state.ipc;
|
|
260
|
+
};
|
|
261
|
+
const setIpc = value => {
|
|
262
|
+
state.ipc = value;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const nameAnonymousFunction = (fn, name) => {
|
|
266
|
+
Object.defineProperty(fn, 'name', {
|
|
267
|
+
value: name
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const isInputElement = element => {
|
|
272
|
+
return element instanceof HTMLInputElement;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const preventEventsMaybe = (info, event) => {
|
|
276
|
+
if (info.preventDefault === 2) {
|
|
277
|
+
if (!isInputElement(event.target)) {
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
}
|
|
280
|
+
} else if (info.preventDefault) {
|
|
281
|
+
event.preventDefault();
|
|
282
|
+
}
|
|
283
|
+
if (info.stopPropagation) {
|
|
284
|
+
event.stopPropagation();
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const applyPointerTrackMaybe = (info, map, event) => {
|
|
289
|
+
const {
|
|
290
|
+
trackPointerEvents
|
|
291
|
+
} = info;
|
|
292
|
+
if (!trackPointerEvents) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const {
|
|
296
|
+
pointerId,
|
|
297
|
+
target
|
|
298
|
+
} = event;
|
|
299
|
+
target.setPointerCapture(pointerId);
|
|
300
|
+
const [pointerMoveKey, pointerUpKey] = trackPointerEvents;
|
|
301
|
+
target.addEventListener(PointerMove, map[pointerMoveKey]);
|
|
302
|
+
target.addEventListener(lostpointercapture, map[pointerUpKey]);
|
|
303
|
+
};
|
|
304
|
+
const createFn = (info, map) => {
|
|
305
|
+
const fn = event => {
|
|
306
|
+
if (enabled()) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const uid = getComponentUidFromEvent(event);
|
|
310
|
+
const args = getEventListenerArgs(info.params, event);
|
|
311
|
+
preventEventsMaybe(info, event);
|
|
312
|
+
applyDragInfoMaybe(event);
|
|
313
|
+
applyPointerTrackMaybe(info, map, event);
|
|
314
|
+
if (args.length === 0) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const ipc = getIpc();
|
|
318
|
+
ipc.send('Viewlet.executeViewletCommand', uid, ...args);
|
|
319
|
+
};
|
|
320
|
+
nameAnonymousFunction(fn, info.name);
|
|
321
|
+
if (info.passive) {
|
|
322
|
+
// TODO avoid mutating function property, maybe return an object with function and options
|
|
323
|
+
fn.passive = true;
|
|
324
|
+
}
|
|
325
|
+
if (info.capture) {
|
|
326
|
+
// TODO avoid mutating function property, maybe return an object with function and options
|
|
327
|
+
fn.capture = true;
|
|
328
|
+
}
|
|
329
|
+
return fn;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const listeners = Object.create(null);
|
|
333
|
+
const registerEventListeners = (id, eventListeners) => {
|
|
334
|
+
const map = Object.create(null);
|
|
335
|
+
for (const info of eventListeners) {
|
|
336
|
+
const fn = createFn(info, map);
|
|
337
|
+
map[info.name] = fn;
|
|
338
|
+
}
|
|
339
|
+
listeners[id] = map;
|
|
340
|
+
};
|
|
341
|
+
const getEventListenerMap = id => {
|
|
342
|
+
const map = listeners[id];
|
|
343
|
+
return map;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const clearNode = $Node => {
|
|
347
|
+
$Node.textContent = '';
|
|
7
348
|
};
|
|
8
349
|
|
|
9
350
|
const Audio$2 = 'audio';
|
|
@@ -364,67 +705,35 @@ const ElementTagMap = {
|
|
|
364
705
|
|
|
365
706
|
const {
|
|
366
707
|
getElementTag
|
|
367
|
-
} = ElementTagMap;
|
|
368
|
-
|
|
369
|
-
const getEventListenerOptions = (eventName, value) => {
|
|
370
|
-
if (value.passive) {
|
|
371
|
-
return {
|
|
372
|
-
passive: true
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
if (value.capture) {
|
|
376
|
-
return {
|
|
377
|
-
capture: true
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
switch (eventName) {
|
|
381
|
-
case 'wheel':
|
|
382
|
-
return {
|
|
383
|
-
passive: true
|
|
384
|
-
};
|
|
385
|
-
default:
|
|
386
|
-
return undefined;
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
const uidSymbol = Symbol('uid');
|
|
391
|
-
|
|
392
|
-
const getUidTarget = $Element => {
|
|
393
|
-
while ($Element) {
|
|
394
|
-
if ($Element[uidSymbol]) {
|
|
395
|
-
return $Element;
|
|
396
|
-
}
|
|
397
|
-
$Element = $Element.parentNode;
|
|
398
|
-
}
|
|
399
|
-
return undefined;
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
const setComponentUid = ($Element, uid) => {
|
|
403
|
-
$Element[uidSymbol] = uid;
|
|
404
|
-
};
|
|
405
|
-
const getComponentUid = $Element => {
|
|
406
|
-
const $Target = getUidTarget($Element);
|
|
407
|
-
if (!$Target) {
|
|
408
|
-
return 0;
|
|
409
|
-
}
|
|
410
|
-
return $Target[uidSymbol];
|
|
411
|
-
};
|
|
412
|
-
const getComponentUidFromEvent = event => {
|
|
413
|
-
const {
|
|
414
|
-
currentTarget,
|
|
415
|
-
target
|
|
416
|
-
} = event;
|
|
417
|
-
return getComponentUid(currentTarget || target);
|
|
418
|
-
};
|
|
708
|
+
} = ElementTagMap;
|
|
419
709
|
|
|
420
|
-
const
|
|
421
|
-
|
|
710
|
+
const instances = Object.create(null);
|
|
711
|
+
const get$1 = viewletId => {
|
|
712
|
+
return instances[viewletId];
|
|
422
713
|
};
|
|
423
|
-
const
|
|
424
|
-
|
|
714
|
+
const set$1 = (viewletId, instance) => {
|
|
715
|
+
instances[viewletId] = instance;
|
|
425
716
|
};
|
|
426
|
-
|
|
427
|
-
|
|
717
|
+
|
|
718
|
+
const getEventListenerOptions = (eventName, value) => {
|
|
719
|
+
if (value.passive) {
|
|
720
|
+
return {
|
|
721
|
+
passive: true
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
if (value.capture) {
|
|
725
|
+
return {
|
|
726
|
+
capture: true
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
switch (eventName) {
|
|
730
|
+
case 'wheel':
|
|
731
|
+
return {
|
|
732
|
+
passive: true
|
|
733
|
+
};
|
|
734
|
+
default:
|
|
735
|
+
return undefined;
|
|
736
|
+
}
|
|
428
737
|
};
|
|
429
738
|
|
|
430
739
|
const cache = new Map();
|
|
@@ -438,12 +747,6 @@ const get = listener => {
|
|
|
438
747
|
return cache.get(listener);
|
|
439
748
|
};
|
|
440
749
|
|
|
441
|
-
const nameAnonymousFunction = (fn, name) => {
|
|
442
|
-
Object.defineProperty(fn, 'name', {
|
|
443
|
-
value: name
|
|
444
|
-
});
|
|
445
|
-
};
|
|
446
|
-
|
|
447
750
|
const getWrappedListener = (listener, returnValue) => {
|
|
448
751
|
if (!returnValue) {
|
|
449
752
|
return listener;
|
|
@@ -777,392 +1080,131 @@ const renderDomElement = (element, eventMap, newEventMap) => {
|
|
|
777
1080
|
setProps($Element, element, eventMap, newEventMap);
|
|
778
1081
|
return $Element;
|
|
779
1082
|
};
|
|
780
|
-
const renderReferenceNode = element => {
|
|
781
|
-
const instance = get$1(element.uid);
|
|
782
|
-
if (!instance || !instance.state) {
|
|
783
|
-
return document.createTextNode('Reference node not found');
|
|
784
|
-
}
|
|
785
|
-
const $Node = instance.state.$Viewlet;
|
|
786
|
-
return $Node;
|
|
787
|
-
};
|
|
788
|
-
const render$1 = (element, eventMap, newEventMap) => {
|
|
789
|
-
switch (element.type) {
|
|
790
|
-
case Reference:
|
|
791
|
-
return renderReferenceNode(element);
|
|
792
|
-
case Text:
|
|
793
|
-
return renderDomTextNode(element);
|
|
794
|
-
default:
|
|
795
|
-
return renderDomElement(element, eventMap, newEventMap);
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
const renderInternal = ($Parent, elements, eventMap, newEventMap) => {
|
|
800
|
-
const max = elements.length - 1;
|
|
801
|
-
let stack = [];
|
|
802
|
-
for (let i = max; i >= 0; i--) {
|
|
803
|
-
const element = elements[i];
|
|
804
|
-
const $Element = render$1(element, eventMap, newEventMap);
|
|
805
|
-
if (element.childCount > 0) {
|
|
806
|
-
// @ts-expect-error
|
|
807
|
-
$Element.append(...stack.slice(0, element.childCount));
|
|
808
|
-
stack = stack.slice(element.childCount);
|
|
809
|
-
}
|
|
810
|
-
stack.unshift($Element);
|
|
811
|
-
}
|
|
812
|
-
$Parent.append(...stack);
|
|
813
|
-
};
|
|
814
|
-
|
|
815
|
-
// Map of property names to attribute names for cases where they differ
|
|
816
|
-
const propertyToAttribute = {
|
|
817
|
-
className: 'class',
|
|
818
|
-
htmlFor: 'for',
|
|
819
|
-
ariaActivedescendant: 'aria-activedescendant',
|
|
820
|
-
ariaControls: 'aria-controls',
|
|
821
|
-
ariaLabelledBy: 'aria-labelledby',
|
|
822
|
-
ariaOwns: 'aria-owns',
|
|
823
|
-
inputType: 'type'
|
|
824
|
-
};
|
|
825
|
-
|
|
826
|
-
// Style properties that need to be set on element.style
|
|
827
|
-
const styleProperties = new Set(['width', 'height', 'top', 'left', 'marginTop', 'paddingLeft', 'paddingRight']);
|
|
828
|
-
const removeAttribute = ($Element, key) => {
|
|
829
|
-
// Handle style properties
|
|
830
|
-
if (styleProperties.has(key)) {
|
|
831
|
-
// @ts-ignore - dynamic style property access
|
|
832
|
-
$Element.style[key] = '';
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
835
|
-
const attributeName = propertyToAttribute[key] || key;
|
|
836
|
-
$Element.removeAttribute(attributeName);
|
|
837
|
-
};
|
|
838
|
-
const setText = ($Element, value) => {
|
|
839
|
-
$Element.nodeValue = value;
|
|
840
|
-
};
|
|
841
|
-
const removeChild = ($Element, index) => {
|
|
842
|
-
const $Child = $Element.childNodes[index];
|
|
843
|
-
if ($Child) {
|
|
844
|
-
$Child.remove();
|
|
845
|
-
}
|
|
846
|
-
};
|
|
847
|
-
const add$1 = ($Element, nodes, eventMap = {}) => {
|
|
848
|
-
renderInternal($Element, nodes, eventMap, eventMap);
|
|
849
|
-
};
|
|
850
|
-
const replace = ($Element, nodes, eventMap = {}) => {
|
|
851
|
-
// Create a temporary container to render the new nodes
|
|
852
|
-
const $Temp = document.createElement('div');
|
|
853
|
-
renderInternal($Temp, nodes, eventMap, eventMap);
|
|
854
|
-
// Replace the current element with the new node(s)
|
|
855
|
-
const $NewNode = $Temp.firstChild;
|
|
856
|
-
if (!$NewNode) {
|
|
857
|
-
// No node was created, just remove the old element
|
|
858
|
-
$Element.remove();
|
|
859
|
-
return $Element;
|
|
860
|
-
}
|
|
861
|
-
$Element.replaceWith($NewNode);
|
|
862
|
-
return $NewNode;
|
|
863
|
-
};
|
|
864
|
-
|
|
865
|
-
const SetText = 1;
|
|
866
|
-
const Replace = 2;
|
|
867
|
-
const SetAttribute = 3;
|
|
868
|
-
const RemoveAttribute = 4;
|
|
869
|
-
const Add = 6;
|
|
870
|
-
const NavigateChild = 7;
|
|
871
|
-
const NavigateParent = 8;
|
|
872
|
-
const RemoveChild = 9;
|
|
873
|
-
const NavigateSibling = 10;
|
|
874
|
-
const SetReferenceNodeUid = 11;
|
|
875
|
-
|
|
876
|
-
const dragInfos = Object.create(null);
|
|
877
|
-
const setDragInfo = (id, data) => {
|
|
878
|
-
dragInfos[id] = data;
|
|
879
|
-
};
|
|
880
|
-
const getDragInfo = id => {
|
|
881
|
-
return dragInfos[id];
|
|
882
|
-
};
|
|
883
|
-
const removeDragInfo = id => {
|
|
884
|
-
delete dragInfos[id];
|
|
885
|
-
};
|
|
886
|
-
const isDragInfoOld = data => {
|
|
887
|
-
return Array.isArray(data);
|
|
888
|
-
};
|
|
889
|
-
|
|
890
|
-
const setDragImage = (dataTransfer, label) => {
|
|
891
|
-
const dragImage = document.createElement('div');
|
|
892
|
-
dragImage.className = 'DragImage';
|
|
893
|
-
dragImage.textContent = label;
|
|
894
|
-
document.body.append(dragImage);
|
|
895
|
-
dataTransfer.setDragImage(dragImage, -10, -10);
|
|
896
|
-
const handleTimeOut = () => {
|
|
897
|
-
dragImage.remove();
|
|
898
|
-
};
|
|
899
|
-
setTimeout(handleTimeOut, 0);
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
const applyDragInfoMaybe = event => {
|
|
903
|
-
const {
|
|
904
|
-
dataTransfer,
|
|
905
|
-
target
|
|
906
|
-
} = event;
|
|
907
|
-
if (dataTransfer) {
|
|
908
|
-
const uid = getComponentUid(target);
|
|
909
|
-
const dragInfo = getDragInfo(uid);
|
|
910
|
-
if (!dragInfo) {
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
if (isDragInfoOld(dragInfo)) {
|
|
914
|
-
for (const item of dragInfo) {
|
|
915
|
-
dataTransfer.setData(item.type, item.data);
|
|
916
|
-
}
|
|
917
|
-
} else {
|
|
918
|
-
for (const item of dragInfo.items) {
|
|
919
|
-
dataTransfer.items.add(item.data, item.type);
|
|
920
|
-
}
|
|
921
|
-
if (dragInfo.label) {
|
|
922
|
-
setDragImage(dataTransfer, dragInfo.label);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
};
|
|
927
|
-
|
|
928
|
-
const PointerMove = 'pointermove';
|
|
929
|
-
const lostpointercapture = 'lostpointercapture';
|
|
930
|
-
|
|
931
|
-
let ignore = false;
|
|
932
|
-
const startIgnore = () => {
|
|
933
|
-
ignore = true;
|
|
934
|
-
};
|
|
935
|
-
const stopIgnore = () => {
|
|
936
|
-
ignore = false;
|
|
937
|
-
};
|
|
938
|
-
const enabled = () => {
|
|
939
|
-
return ignore;
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
let id = 0;
|
|
943
|
-
const create = () => {
|
|
944
|
-
return ++id;
|
|
945
|
-
};
|
|
946
|
-
|
|
947
|
-
const state = Object.create(null);
|
|
948
|
-
const acquire = id => {
|
|
949
|
-
const promise = state[id];
|
|
950
|
-
delete state[id];
|
|
951
|
-
return promise;
|
|
952
|
-
};
|
|
953
|
-
const getFileHandles = async ids => {
|
|
954
|
-
const promises = ids.map(acquire);
|
|
955
|
-
const handles = await Promise.all(promises);
|
|
956
|
-
return handles;
|
|
957
|
-
};
|
|
958
|
-
const add = promise => {
|
|
959
|
-
const id = create();
|
|
960
|
-
state[id] = promise;
|
|
961
|
-
return id;
|
|
962
|
-
};
|
|
963
|
-
const addFileHandle = fileHandle => {
|
|
964
|
-
const promise = Promise.resolve(fileHandle);
|
|
965
|
-
return add(promise);
|
|
966
|
-
};
|
|
967
|
-
|
|
968
|
-
const unwrapItemString = async item => {
|
|
969
|
-
const {
|
|
970
|
-
resolve,
|
|
971
|
-
promise
|
|
972
|
-
} = Promise.withResolvers();
|
|
973
|
-
item.getAsString(resolve);
|
|
974
|
-
const value = await promise;
|
|
975
|
-
return {
|
|
976
|
-
kind: 'string',
|
|
977
|
-
type: item.type,
|
|
978
|
-
value
|
|
979
|
-
};
|
|
980
|
-
};
|
|
981
|
-
const unwrapItemFile = async item => {
|
|
982
|
-
// @ts-ignore
|
|
983
|
-
const file = await item.getAsFileSystemHandle();
|
|
984
|
-
return {
|
|
985
|
-
kind: 'file',
|
|
986
|
-
type: item.type,
|
|
987
|
-
value: file
|
|
988
|
-
};
|
|
989
|
-
};
|
|
990
|
-
const unknownItem = {
|
|
991
|
-
kind: 'unknown',
|
|
992
|
-
type: '',
|
|
993
|
-
value: ''
|
|
994
|
-
};
|
|
995
|
-
const unwrapItem = item => {
|
|
996
|
-
switch (item.kind) {
|
|
997
|
-
case 'file':
|
|
998
|
-
return unwrapItemFile(item);
|
|
999
|
-
case 'string':
|
|
1000
|
-
return unwrapItemString(item);
|
|
1001
|
-
default:
|
|
1002
|
-
return unknownItem;
|
|
1003
|
-
}
|
|
1004
|
-
};
|
|
1005
|
-
const handleDataTransferFiles = event => {
|
|
1006
|
-
if (!event.dataTransfer) {
|
|
1007
|
-
return [];
|
|
1083
|
+
const renderReferenceNode = element => {
|
|
1084
|
+
const instance = get$1(element.uid);
|
|
1085
|
+
if (!instance || !instance.state) {
|
|
1086
|
+
return document.createTextNode('Reference node not found');
|
|
1008
1087
|
}
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1011
|
-
const ids = promises.map(promise => add(promise));
|
|
1012
|
-
return ids;
|
|
1088
|
+
const $Node = instance.state.$Viewlet;
|
|
1089
|
+
return $Node;
|
|
1013
1090
|
};
|
|
1014
|
-
const
|
|
1015
|
-
switch (
|
|
1016
|
-
case
|
|
1017
|
-
return
|
|
1018
|
-
case
|
|
1019
|
-
return
|
|
1020
|
-
case 'event.clientX':
|
|
1021
|
-
return event.clientX;
|
|
1022
|
-
case 'event.clientY':
|
|
1023
|
-
return event.clientY;
|
|
1024
|
-
case 'event.ctrlKey':
|
|
1025
|
-
return event.ctrlKey;
|
|
1026
|
-
case 'event.data':
|
|
1027
|
-
return event.data;
|
|
1028
|
-
case 'event.dataTransfer.files':
|
|
1029
|
-
return event.dataTransfer.files;
|
|
1030
|
-
case 'event.dataTransfer.files2':
|
|
1031
|
-
return handleDataTransferFiles(event);
|
|
1032
|
-
case 'event.defaultPrevented':
|
|
1033
|
-
return event.defaultPrevented;
|
|
1034
|
-
case 'event.deltaMode':
|
|
1035
|
-
return event.deltaMode;
|
|
1036
|
-
case 'event.deltaX':
|
|
1037
|
-
return event.deltaX;
|
|
1038
|
-
case 'event.deltaY':
|
|
1039
|
-
return event.deltaY;
|
|
1040
|
-
case 'event.detail':
|
|
1041
|
-
return event.detail;
|
|
1042
|
-
case 'event.inputType':
|
|
1043
|
-
return event.inputType;
|
|
1044
|
-
case 'event.isTrusted':
|
|
1045
|
-
return event.isTrusted;
|
|
1046
|
-
case 'event.key':
|
|
1047
|
-
return event.key;
|
|
1048
|
-
case 'event.shiftKey':
|
|
1049
|
-
return event.shiftKey;
|
|
1050
|
-
case 'event.target.checked':
|
|
1051
|
-
return event.target.checked;
|
|
1052
|
-
case 'event.target.className':
|
|
1053
|
-
return event.target.className;
|
|
1054
|
-
case 'event.target.href':
|
|
1055
|
-
return event.target.href;
|
|
1056
|
-
case 'event.target.name':
|
|
1057
|
-
return event.target.name || '';
|
|
1058
|
-
case 'event.target.nodeName':
|
|
1059
|
-
return event.target.nodeName;
|
|
1060
|
-
case 'event.target.scrollTop':
|
|
1061
|
-
return event.target.scrollTop;
|
|
1062
|
-
case 'event.target.selectionEnd':
|
|
1063
|
-
return event.target.selectionEnd;
|
|
1064
|
-
case 'event.target.selectionStart':
|
|
1065
|
-
return event.target.selectionStart;
|
|
1066
|
-
case 'event.target.src':
|
|
1067
|
-
return event.target.src;
|
|
1068
|
-
case 'event.target.value':
|
|
1069
|
-
return event.target.value;
|
|
1070
|
-
case 'event.x':
|
|
1071
|
-
return event.x;
|
|
1072
|
-
case 'event.y':
|
|
1073
|
-
return event.y;
|
|
1091
|
+
const render$1 = (element, eventMap, newEventMap) => {
|
|
1092
|
+
switch (element.type) {
|
|
1093
|
+
case Reference:
|
|
1094
|
+
return renderReferenceNode(element);
|
|
1095
|
+
case Text:
|
|
1096
|
+
return renderDomTextNode(element);
|
|
1074
1097
|
default:
|
|
1075
|
-
|
|
1076
|
-
const rest = param.slice('event.target.dataset.'.length);
|
|
1077
|
-
return event.target.dataset[rest];
|
|
1078
|
-
}
|
|
1079
|
-
return param;
|
|
1098
|
+
return renderDomElement(element, eventMap, newEventMap);
|
|
1080
1099
|
}
|
|
1081
1100
|
};
|
|
1082
1101
|
|
|
1083
|
-
const
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1102
|
+
const renderInternal = ($Parent, elements, eventMap, newEventMap) => {
|
|
1103
|
+
const max = elements.length - 1;
|
|
1104
|
+
let stack = [];
|
|
1105
|
+
for (let i = max; i >= 0; i--) {
|
|
1106
|
+
const element = elements[i];
|
|
1107
|
+
const $Element = render$1(element, eventMap, newEventMap);
|
|
1108
|
+
if (element.childCount > 0) {
|
|
1109
|
+
// @ts-expect-error
|
|
1110
|
+
$Element.append(...stack.slice(0, element.childCount));
|
|
1111
|
+
stack = stack.slice(element.childCount);
|
|
1112
|
+
}
|
|
1113
|
+
stack.unshift($Element);
|
|
1087
1114
|
}
|
|
1088
|
-
|
|
1115
|
+
$Parent.append(...stack);
|
|
1089
1116
|
};
|
|
1090
1117
|
|
|
1091
|
-
const
|
|
1092
|
-
|
|
1118
|
+
const renderInto = ($Parent, dom, eventMap = {}) => {
|
|
1119
|
+
clearNode($Parent);
|
|
1120
|
+
renderInternal($Parent, dom, eventMap);
|
|
1093
1121
|
};
|
|
1094
1122
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1123
|
+
/**
|
|
1124
|
+
*
|
|
1125
|
+
* @param {any[]} elements
|
|
1126
|
+
* @returns
|
|
1127
|
+
*/
|
|
1128
|
+
const render = (elements, eventMap = {}, newEventMap = {}) => {
|
|
1129
|
+
const $Root = document.createElement('div');
|
|
1130
|
+
renderInternal($Root, elements, eventMap, newEventMap);
|
|
1131
|
+
return $Root;
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1134
|
+
const rememberFocus2 = ($Viewlet, dom, eventMap, uid = 0) => {
|
|
1135
|
+
if (uid) {
|
|
1136
|
+
const newEventMap = getEventListenerMap(uid);
|
|
1137
|
+
const $New = render(dom, eventMap, newEventMap).firstChild;
|
|
1138
|
+
setComponentUid($New, uid);
|
|
1139
|
+
$Viewlet.replaceWith($New);
|
|
1140
|
+
$Viewlet = $New;
|
|
1141
|
+
} else {
|
|
1142
|
+
renderInto($Viewlet, dom, eventMap);
|
|
1105
1143
|
}
|
|
1144
|
+
return $Viewlet;
|
|
1106
1145
|
};
|
|
1107
1146
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1147
|
+
// Map of property names to attribute names for cases where they differ
|
|
1148
|
+
const propertyToAttribute = {
|
|
1149
|
+
className: 'class',
|
|
1150
|
+
htmlFor: 'for',
|
|
1151
|
+
ariaActivedescendant: 'aria-activedescendant',
|
|
1152
|
+
ariaControls: 'aria-controls',
|
|
1153
|
+
ariaLabelledBy: 'aria-labelledby',
|
|
1154
|
+
ariaOwns: 'aria-owns',
|
|
1155
|
+
inputType: 'type'
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
// Style properties that need to be set on element.style
|
|
1159
|
+
const styleProperties = new Set(['width', 'height', 'top', 'left', 'marginTop', 'paddingLeft', 'paddingRight']);
|
|
1160
|
+
const removeAttribute = ($Element, key) => {
|
|
1161
|
+
// Handle style properties
|
|
1162
|
+
if (styleProperties.has(key)) {
|
|
1163
|
+
// @ts-ignore - dynamic style property access
|
|
1164
|
+
$Element.style[key] = '';
|
|
1113
1165
|
return;
|
|
1114
1166
|
}
|
|
1115
|
-
const
|
|
1116
|
-
|
|
1117
|
-
target
|
|
1118
|
-
} = event;
|
|
1119
|
-
target.setPointerCapture(pointerId);
|
|
1120
|
-
const [pointerMoveKey, pointerUpKey] = trackPointerEvents;
|
|
1121
|
-
target.addEventListener(PointerMove, map[pointerMoveKey]);
|
|
1122
|
-
target.addEventListener(lostpointercapture, map[pointerUpKey]);
|
|
1167
|
+
const attributeName = propertyToAttribute[key] || key;
|
|
1168
|
+
$Element.removeAttribute(attributeName);
|
|
1123
1169
|
};
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
if (enabled()) {
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
const uid = getComponentUidFromEvent(event);
|
|
1130
|
-
const args = getEventListenerArgs(info.params, event);
|
|
1131
|
-
preventEventsMaybe(info, event);
|
|
1132
|
-
applyDragInfoMaybe(event);
|
|
1133
|
-
applyPointerTrackMaybe(info, map, event);
|
|
1134
|
-
if (args.length === 0) {
|
|
1135
|
-
return;
|
|
1136
|
-
}
|
|
1137
|
-
const ipc = getIpc();
|
|
1138
|
-
ipc.send('Viewlet.executeViewletCommand', uid, ...args);
|
|
1139
|
-
};
|
|
1140
|
-
nameAnonymousFunction(fn, info.name);
|
|
1141
|
-
if (info.passive) {
|
|
1142
|
-
// TODO avoid mutating function property, maybe return an object with function and options
|
|
1143
|
-
fn.passive = true;
|
|
1144
|
-
}
|
|
1145
|
-
if (info.capture) {
|
|
1146
|
-
// TODO avoid mutating function property, maybe return an object with function and options
|
|
1147
|
-
fn.capture = true;
|
|
1148
|
-
}
|
|
1149
|
-
return fn;
|
|
1170
|
+
const setText = ($Element, value) => {
|
|
1171
|
+
$Element.nodeValue = value;
|
|
1150
1172
|
};
|
|
1151
|
-
|
|
1152
|
-
const
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
for (const info of eventListeners) {
|
|
1156
|
-
const fn = createFn(info, map);
|
|
1157
|
-
map[info.name] = fn;
|
|
1173
|
+
const removeChild = ($Element, index) => {
|
|
1174
|
+
const $Child = $Element.childNodes[index];
|
|
1175
|
+
if ($Child) {
|
|
1176
|
+
$Child.remove();
|
|
1158
1177
|
}
|
|
1159
|
-
listeners[id] = map;
|
|
1160
1178
|
};
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
|
|
1179
|
+
const add = ($Element, nodes, eventMap = {}) => {
|
|
1180
|
+
renderInternal($Element, nodes, eventMap, eventMap);
|
|
1181
|
+
};
|
|
1182
|
+
const replace = ($Element, nodes, eventMap = {}) => {
|
|
1183
|
+
// Create a temporary container to render the new nodes
|
|
1184
|
+
const $Temp = document.createElement('div');
|
|
1185
|
+
renderInternal($Temp, nodes, eventMap, eventMap);
|
|
1186
|
+
// Replace the current element with the new node(s)
|
|
1187
|
+
const $NewNode = $Temp.firstChild;
|
|
1188
|
+
if (!$NewNode) {
|
|
1189
|
+
// No node was created, just remove the old element
|
|
1190
|
+
$Element.remove();
|
|
1191
|
+
return $Element;
|
|
1192
|
+
}
|
|
1193
|
+
$Element.replaceWith($NewNode);
|
|
1194
|
+
return $NewNode;
|
|
1164
1195
|
};
|
|
1165
1196
|
|
|
1197
|
+
const SetText = 1;
|
|
1198
|
+
const Replace = 2;
|
|
1199
|
+
const SetAttribute = 3;
|
|
1200
|
+
const RemoveAttribute = 4;
|
|
1201
|
+
const Add = 6;
|
|
1202
|
+
const NavigateChild = 7;
|
|
1203
|
+
const NavigateParent = 8;
|
|
1204
|
+
const RemoveChild = 9;
|
|
1205
|
+
const NavigateSibling = 10;
|
|
1206
|
+
const SetReferenceNodeUid = 11;
|
|
1207
|
+
|
|
1166
1208
|
const applyPatch = ($Element, patches, eventMap = {}, id = 0) => {
|
|
1167
1209
|
const events = getEventListenerMap(id) || eventMap;
|
|
1168
1210
|
let $Current = $Element;
|
|
@@ -1171,7 +1213,7 @@ const applyPatch = ($Element, patches, eventMap = {}, id = 0) => {
|
|
|
1171
1213
|
try {
|
|
1172
1214
|
switch (patch.type) {
|
|
1173
1215
|
case Add:
|
|
1174
|
-
add
|
|
1216
|
+
add($Current, patch.nodes, events);
|
|
1175
1217
|
break;
|
|
1176
1218
|
case NavigateChild:
|
|
1177
1219
|
{
|
|
@@ -1287,26 +1329,6 @@ const queryInputs = $Viewlet => {
|
|
|
1287
1329
|
return [...$Viewlet.querySelectorAll('input, textarea, select')];
|
|
1288
1330
|
};
|
|
1289
1331
|
|
|
1290
|
-
const clearNode = $Node => {
|
|
1291
|
-
$Node.textContent = '';
|
|
1292
|
-
};
|
|
1293
|
-
|
|
1294
|
-
const renderInto = ($Parent, dom, eventMap = {}) => {
|
|
1295
|
-
clearNode($Parent);
|
|
1296
|
-
renderInternal($Parent, dom, eventMap);
|
|
1297
|
-
};
|
|
1298
|
-
|
|
1299
|
-
/**
|
|
1300
|
-
*
|
|
1301
|
-
* @param {any[]} elements
|
|
1302
|
-
* @returns
|
|
1303
|
-
*/
|
|
1304
|
-
const render = (elements, eventMap = {}, newEventMap = {}) => {
|
|
1305
|
-
const $Root = document.createElement('div');
|
|
1306
|
-
renderInternal($Root, elements, eventMap, newEventMap);
|
|
1307
|
-
return $Root;
|
|
1308
|
-
};
|
|
1309
|
-
|
|
1310
1332
|
const focusElement = $Element => {
|
|
1311
1333
|
$Element.focus({
|
|
1312
1334
|
preventScroll: true
|
|
@@ -1385,4 +1407,4 @@ const rememberFocus = ($Viewlet, dom, eventMap, uid = 0) => {
|
|
|
1385
1407
|
return $Viewlet;
|
|
1386
1408
|
};
|
|
1387
1409
|
|
|
1388
|
-
export { VirtualDomElements, addFileHandle, applyPatch, getComponentUid, getComponentUidFromEvent, getDragInfo, getFileHandles, get$1 as getViewletInstance, registerEventListeners, rememberFocus, removeDragInfo, render, renderInto, setComponentUid, setDragInfo, setIpc, set$1 as setViewletInstance };
|
|
1410
|
+
export { VirtualDomElements, addFileHandle, applyPatch, getComponentUid, getComponentUidFromEvent, getDragInfo, getFileHandles, get$1 as getViewletInstance, registerEventListeners, rememberFocus, rememberFocus2, removeDragInfo, render, renderInto, setComponentUid, setDragInfo, setIpc, set$1 as setViewletInstance };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { rememberFocus2 } from '../RememberFocus2/RememberFocus2.ts';
|
|
1
2
|
export { applyPatch } from '../ApplyPatch/ApplyPatch.ts';
|
|
2
3
|
export { getComponentUid, getComponentUidFromEvent, setComponentUid, } from '../ComponentUid/ComponentUid.ts';
|
|
3
4
|
export { getDragInfo, removeDragInfo, setDragInfo, } from '../DragInfo/DragInfo.ts';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const rememberFocus2: ($Viewlet: HTMLElement, dom: any[], eventMap: any, uid?: number) => any;
|