@lvce-editor/renderer-process 30.17.1 → 30.19.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/editorOnly.css +191 -0
- package/dist/editorOnlyRendererProcessMain.js +2815 -0
- package/dist/rendererProcessMain.js +24 -12
- package/package.json +1 -1
|
@@ -0,0 +1,2815 @@
|
|
|
1
|
+
const normalizeLine = line => {
|
|
2
|
+
if (line.startsWith('Error: ')) {
|
|
3
|
+
return line.slice('Error: '.length);
|
|
4
|
+
}
|
|
5
|
+
if (line.startsWith('VError: ')) {
|
|
6
|
+
return line.slice('VError: '.length);
|
|
7
|
+
}
|
|
8
|
+
return line;
|
|
9
|
+
};
|
|
10
|
+
const getCombinedMessage = (error, message) => {
|
|
11
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
12
|
+
if (message) {
|
|
13
|
+
return `${message}: ${stringifiedError}`;
|
|
14
|
+
}
|
|
15
|
+
return stringifiedError;
|
|
16
|
+
};
|
|
17
|
+
const NewLine$2 = '\n';
|
|
18
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
19
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
20
|
+
};
|
|
21
|
+
const mergeStacks = (parent, child) => {
|
|
22
|
+
if (!child) {
|
|
23
|
+
return parent;
|
|
24
|
+
}
|
|
25
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
26
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
27
|
+
if (childNewLineIndex === -1) {
|
|
28
|
+
return parent;
|
|
29
|
+
}
|
|
30
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
31
|
+
const childRest = child.slice(childNewLineIndex);
|
|
32
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
33
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
34
|
+
return parentFirstLine + childRest;
|
|
35
|
+
}
|
|
36
|
+
return child;
|
|
37
|
+
};
|
|
38
|
+
class VError extends Error {
|
|
39
|
+
constructor(error, message) {
|
|
40
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
41
|
+
super(combinedMessage);
|
|
42
|
+
this.name = 'VError';
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
45
|
+
}
|
|
46
|
+
if (error.codeFrame) {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
this.codeFrame = error.codeFrame;
|
|
49
|
+
}
|
|
50
|
+
if (error.code) {
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
this.code = error.code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isMessagePort = value => {
|
|
58
|
+
return value && value instanceof MessagePort;
|
|
59
|
+
};
|
|
60
|
+
const isMessagePortMain = value => {
|
|
61
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
62
|
+
};
|
|
63
|
+
const isOffscreenCanvas = value => {
|
|
64
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
65
|
+
};
|
|
66
|
+
const isInstanceOf = (value, constructorName) => {
|
|
67
|
+
return value?.constructor?.name === constructorName;
|
|
68
|
+
};
|
|
69
|
+
const isSocket = value => {
|
|
70
|
+
return isInstanceOf(value, 'Socket');
|
|
71
|
+
};
|
|
72
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
73
|
+
const isTransferrable = value => {
|
|
74
|
+
for (const fn of transferrables) {
|
|
75
|
+
if (fn(value)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
};
|
|
81
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
82
|
+
if (!value) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (isTransferrable(value)) {
|
|
86
|
+
transferrables.push(value);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (Array.isArray(value)) {
|
|
90
|
+
for (const item of value) {
|
|
91
|
+
walkValue(item, transferrables, isTransferrable);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (typeof value === 'object') {
|
|
96
|
+
for (const property of Object.values(value)) {
|
|
97
|
+
walkValue(property, transferrables, isTransferrable);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const getTransferrables = value => {
|
|
102
|
+
const transferrables = [];
|
|
103
|
+
walkValue(value, transferrables, isTransferrable);
|
|
104
|
+
return transferrables;
|
|
105
|
+
};
|
|
106
|
+
const attachEvents = that => {
|
|
107
|
+
const handleMessage = (...args) => {
|
|
108
|
+
const data = that.getData(...args);
|
|
109
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
110
|
+
data
|
|
111
|
+
}));
|
|
112
|
+
};
|
|
113
|
+
that.onMessage(handleMessage);
|
|
114
|
+
const handleClose = event => {
|
|
115
|
+
that.dispatchEvent(new Event('close'));
|
|
116
|
+
};
|
|
117
|
+
that.onClose(handleClose);
|
|
118
|
+
};
|
|
119
|
+
class Ipc extends EventTarget {
|
|
120
|
+
constructor(rawIpc) {
|
|
121
|
+
super();
|
|
122
|
+
this._rawIpc = rawIpc;
|
|
123
|
+
attachEvents(this);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
127
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
128
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
129
|
+
const NewLine$1 = '\n';
|
|
130
|
+
const joinLines$1 = lines => {
|
|
131
|
+
return lines.join(NewLine$1);
|
|
132
|
+
};
|
|
133
|
+
const RE_AT = /^\s+at/;
|
|
134
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
135
|
+
const isNormalStackLine = line => {
|
|
136
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
137
|
+
};
|
|
138
|
+
const getDetails = lines => {
|
|
139
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
140
|
+
if (index === -1) {
|
|
141
|
+
return {
|
|
142
|
+
actualMessage: joinLines$1(lines),
|
|
143
|
+
rest: []
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
let lastIndex = index - 1;
|
|
147
|
+
while (++lastIndex < lines.length) {
|
|
148
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
actualMessage: lines[index - 1],
|
|
154
|
+
rest: lines.slice(index, lastIndex)
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const splitLines$1 = lines => {
|
|
158
|
+
return lines.split(NewLine$1);
|
|
159
|
+
};
|
|
160
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
161
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
162
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
163
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
164
|
+
};
|
|
165
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
166
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
167
|
+
};
|
|
168
|
+
const getMessageCodeBlock = stderr => {
|
|
169
|
+
const lines = splitLines$1(stderr);
|
|
170
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
171
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
172
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
173
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
174
|
+
return relevantMessage;
|
|
175
|
+
};
|
|
176
|
+
const isModuleNotFoundMessage = line => {
|
|
177
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
178
|
+
};
|
|
179
|
+
const getModuleNotFoundError = stderr => {
|
|
180
|
+
const lines = splitLines$1(stderr);
|
|
181
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
182
|
+
const message = lines[messageIndex];
|
|
183
|
+
return {
|
|
184
|
+
code: ERR_MODULE_NOT_FOUND,
|
|
185
|
+
message
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
const isModuleNotFoundError = stderr => {
|
|
189
|
+
if (!stderr) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
193
|
+
};
|
|
194
|
+
const isModulesSyntaxError = stderr => {
|
|
195
|
+
if (!stderr) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
199
|
+
};
|
|
200
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
201
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
202
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
203
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
204
|
+
};
|
|
205
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
206
|
+
const message = getMessageCodeBlock(stderr);
|
|
207
|
+
return {
|
|
208
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE,
|
|
209
|
+
message: `Incompatible native node module: ${message}`
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
const getModuleSyntaxError = () => {
|
|
213
|
+
return {
|
|
214
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
|
|
215
|
+
message: `ES Modules are not supported in electron`
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
219
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
220
|
+
return getNativeModuleErrorMessage(stderr);
|
|
221
|
+
}
|
|
222
|
+
if (isModulesSyntaxError(stderr)) {
|
|
223
|
+
return getModuleSyntaxError();
|
|
224
|
+
}
|
|
225
|
+
if (isModuleNotFoundError(stderr)) {
|
|
226
|
+
return getModuleNotFoundError(stderr);
|
|
227
|
+
}
|
|
228
|
+
const lines = splitLines$1(stderr);
|
|
229
|
+
const {
|
|
230
|
+
actualMessage,
|
|
231
|
+
rest
|
|
232
|
+
} = getDetails(lines);
|
|
233
|
+
return {
|
|
234
|
+
code: '',
|
|
235
|
+
message: actualMessage,
|
|
236
|
+
stack: rest
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
class IpcError extends VError {
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
242
|
+
if (stdout || stderr) {
|
|
243
|
+
// @ts-ignore
|
|
244
|
+
const {
|
|
245
|
+
code,
|
|
246
|
+
message,
|
|
247
|
+
stack
|
|
248
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
249
|
+
const cause = new Error(message);
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
cause.code = code;
|
|
252
|
+
if (stack) {
|
|
253
|
+
Object.defineProperty(cause, 'stack', {
|
|
254
|
+
configurable: true,
|
|
255
|
+
enumerable: false,
|
|
256
|
+
value: stack,
|
|
257
|
+
writable: true
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
super(cause, betterMessage);
|
|
261
|
+
} else {
|
|
262
|
+
super(betterMessage);
|
|
263
|
+
}
|
|
264
|
+
// @ts-ignore
|
|
265
|
+
this.name = 'IpcError';
|
|
266
|
+
// @ts-ignore
|
|
267
|
+
this.stdout = stdout;
|
|
268
|
+
// @ts-ignore
|
|
269
|
+
this.stderr = stderr;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const readyMessage = 'ready';
|
|
273
|
+
const getData$2 = event => {
|
|
274
|
+
return event.data;
|
|
275
|
+
};
|
|
276
|
+
const addListener = (emitter, type, callback) => {
|
|
277
|
+
if ('addEventListener' in emitter) {
|
|
278
|
+
emitter.addEventListener(type, callback);
|
|
279
|
+
} else {
|
|
280
|
+
emitter.on(type, callback);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
const removeListener = (emitter, type, callback) => {
|
|
284
|
+
if ('removeEventListener' in emitter) {
|
|
285
|
+
emitter.removeEventListener(type, callback);
|
|
286
|
+
} else {
|
|
287
|
+
emitter.off(type, callback);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
const getFirstEvent = (eventEmitter, eventMap) => {
|
|
291
|
+
const {
|
|
292
|
+
promise,
|
|
293
|
+
resolve
|
|
294
|
+
} = Promise.withResolvers();
|
|
295
|
+
const listenerMap = Object.create(null);
|
|
296
|
+
const cleanup = value => {
|
|
297
|
+
for (const event of Object.keys(eventMap)) {
|
|
298
|
+
removeListener(eventEmitter, event, listenerMap[event]);
|
|
299
|
+
}
|
|
300
|
+
resolve(value);
|
|
301
|
+
};
|
|
302
|
+
for (const [event, type] of Object.entries(eventMap)) {
|
|
303
|
+
const listener = event => {
|
|
304
|
+
cleanup({
|
|
305
|
+
event,
|
|
306
|
+
type
|
|
307
|
+
});
|
|
308
|
+
};
|
|
309
|
+
addListener(eventEmitter, event, listener);
|
|
310
|
+
listenerMap[event] = listener;
|
|
311
|
+
}
|
|
312
|
+
return promise;
|
|
313
|
+
};
|
|
314
|
+
const Message$1 = 3;
|
|
315
|
+
const create$5$1 = async ({
|
|
316
|
+
isMessagePortOpen,
|
|
317
|
+
messagePort
|
|
318
|
+
}) => {
|
|
319
|
+
if (!isMessagePort(messagePort)) {
|
|
320
|
+
throw new IpcError('port must be of type MessagePort');
|
|
321
|
+
}
|
|
322
|
+
if (isMessagePortOpen) {
|
|
323
|
+
return messagePort;
|
|
324
|
+
}
|
|
325
|
+
const eventPromise = getFirstEvent(messagePort, {
|
|
326
|
+
message: Message$1
|
|
327
|
+
});
|
|
328
|
+
messagePort.start();
|
|
329
|
+
const {
|
|
330
|
+
event,
|
|
331
|
+
type
|
|
332
|
+
} = await eventPromise;
|
|
333
|
+
if (type !== Message$1) {
|
|
334
|
+
throw new IpcError('Failed to wait for ipc message');
|
|
335
|
+
}
|
|
336
|
+
if (event.data !== readyMessage) {
|
|
337
|
+
throw new IpcError('unexpected first message');
|
|
338
|
+
}
|
|
339
|
+
return messagePort;
|
|
340
|
+
};
|
|
341
|
+
const signal$1 = messagePort => {
|
|
342
|
+
messagePort.start();
|
|
343
|
+
};
|
|
344
|
+
class IpcParentWithMessagePort extends Ipc {
|
|
345
|
+
getData = getData$2;
|
|
346
|
+
send(message) {
|
|
347
|
+
this._rawIpc.postMessage(message);
|
|
348
|
+
}
|
|
349
|
+
sendAndTransfer(message) {
|
|
350
|
+
const transfer = getTransferrables(message);
|
|
351
|
+
this._rawIpc.postMessage(message, transfer);
|
|
352
|
+
}
|
|
353
|
+
dispose() {
|
|
354
|
+
this._rawIpc.close();
|
|
355
|
+
}
|
|
356
|
+
onMessage(callback) {
|
|
357
|
+
this._rawIpc.addEventListener('message', callback);
|
|
358
|
+
}
|
|
359
|
+
onClose(callback) {}
|
|
360
|
+
}
|
|
361
|
+
const wrap$5 = messagePort => {
|
|
362
|
+
return new IpcParentWithMessagePort(messagePort);
|
|
363
|
+
};
|
|
364
|
+
const IpcParentWithMessagePort$1 = {
|
|
365
|
+
__proto__: null,
|
|
366
|
+
create: create$5$1,
|
|
367
|
+
signal: signal$1,
|
|
368
|
+
wrap: wrap$5
|
|
369
|
+
};
|
|
370
|
+
const Message = 'message';
|
|
371
|
+
const Error$1 = 'error';
|
|
372
|
+
const getFirstWorkerEvent = worker => {
|
|
373
|
+
return getFirstEvent(worker, {
|
|
374
|
+
error: Error$1,
|
|
375
|
+
message: Message
|
|
376
|
+
});
|
|
377
|
+
};
|
|
378
|
+
const isErrorEvent = event => {
|
|
379
|
+
return event instanceof ErrorEvent;
|
|
380
|
+
};
|
|
381
|
+
const getWorkerDisplayName = name => {
|
|
382
|
+
if (!name) {
|
|
383
|
+
return '<unknown> worker';
|
|
384
|
+
}
|
|
385
|
+
if (name.endsWith('Worker') || name.endsWith('worker')) {
|
|
386
|
+
return name.toLowerCase();
|
|
387
|
+
}
|
|
388
|
+
return `${name} Worker`;
|
|
389
|
+
};
|
|
390
|
+
const tryToGetActualErrorMessage = async ({
|
|
391
|
+
name
|
|
392
|
+
}) => {
|
|
393
|
+
const displayName = getWorkerDisplayName(name);
|
|
394
|
+
return `Failed to start ${displayName}: Worker Launch Error`;
|
|
395
|
+
};
|
|
396
|
+
class WorkerError extends Error {
|
|
397
|
+
constructor(event) {
|
|
398
|
+
super(event.message);
|
|
399
|
+
const stackLines = splitLines$1(this.stack || '');
|
|
400
|
+
const relevantLines = stackLines.slice(1);
|
|
401
|
+
const relevant = joinLines$1(relevantLines);
|
|
402
|
+
this.stack = `${event.message}
|
|
403
|
+
at Module (${event.filename}:${event.lineno}:${event.colno})
|
|
404
|
+
${relevant}`;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const Module = 'module';
|
|
408
|
+
const create$4$1 = async ({
|
|
409
|
+
name,
|
|
410
|
+
url
|
|
411
|
+
}) => {
|
|
412
|
+
const worker = new Worker(url, {
|
|
413
|
+
name,
|
|
414
|
+
type: Module
|
|
415
|
+
});
|
|
416
|
+
const {
|
|
417
|
+
event,
|
|
418
|
+
type
|
|
419
|
+
} = await getFirstWorkerEvent(worker);
|
|
420
|
+
switch (type) {
|
|
421
|
+
case Message:
|
|
422
|
+
if (event.data !== readyMessage) {
|
|
423
|
+
throw new IpcError('unexpected first message from worker');
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
case Error$1:
|
|
427
|
+
if (isErrorEvent(event)) {
|
|
428
|
+
throw new WorkerError(event);
|
|
429
|
+
}
|
|
430
|
+
const actualErrorMessage = await tryToGetActualErrorMessage({
|
|
431
|
+
name
|
|
432
|
+
});
|
|
433
|
+
throw new Error(actualErrorMessage);
|
|
434
|
+
}
|
|
435
|
+
return worker;
|
|
436
|
+
};
|
|
437
|
+
const getData = event => {
|
|
438
|
+
// TODO why are some events not instance of message event?
|
|
439
|
+
if (event instanceof MessageEvent) {
|
|
440
|
+
return event.data;
|
|
441
|
+
}
|
|
442
|
+
return event;
|
|
443
|
+
};
|
|
444
|
+
class IpcParentWithModuleWorker extends Ipc {
|
|
445
|
+
getData(event) {
|
|
446
|
+
return getData(event);
|
|
447
|
+
}
|
|
448
|
+
send(message) {
|
|
449
|
+
this._rawIpc.postMessage(message);
|
|
450
|
+
}
|
|
451
|
+
sendAndTransfer(message) {
|
|
452
|
+
const transfer = getTransferrables(message);
|
|
453
|
+
this._rawIpc.postMessage(message, transfer);
|
|
454
|
+
}
|
|
455
|
+
dispose() {
|
|
456
|
+
// ignore
|
|
457
|
+
}
|
|
458
|
+
onClose(callback) {
|
|
459
|
+
// ignore
|
|
460
|
+
}
|
|
461
|
+
onMessage(callback) {
|
|
462
|
+
this._rawIpc.addEventListener('message', callback);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const wrap$4 = worker => {
|
|
466
|
+
return new IpcParentWithModuleWorker(worker);
|
|
467
|
+
};
|
|
468
|
+
const IpcParentWithModuleWorker$1 = {
|
|
469
|
+
__proto__: null,
|
|
470
|
+
create: create$4$1,
|
|
471
|
+
wrap: wrap$4
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
class CommandNotFoundError extends Error {
|
|
475
|
+
constructor(command) {
|
|
476
|
+
super(`Command not found ${command}`);
|
|
477
|
+
this.name = 'CommandNotFoundError';
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
const commands = Object.create(null);
|
|
481
|
+
const register = commandMap => {
|
|
482
|
+
Object.assign(commands, commandMap);
|
|
483
|
+
};
|
|
484
|
+
const getCommand = key => {
|
|
485
|
+
return commands[key];
|
|
486
|
+
};
|
|
487
|
+
const execute = (command, ...args) => {
|
|
488
|
+
const fn = getCommand(command);
|
|
489
|
+
if (!fn) {
|
|
490
|
+
throw new CommandNotFoundError(command);
|
|
491
|
+
}
|
|
492
|
+
return fn(...args);
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const Two$1 = '2.0';
|
|
496
|
+
const callbacks = Object.create(null);
|
|
497
|
+
const get$3 = id => {
|
|
498
|
+
return callbacks[id];
|
|
499
|
+
};
|
|
500
|
+
const remove = id => {
|
|
501
|
+
delete callbacks[id];
|
|
502
|
+
};
|
|
503
|
+
class JsonRpcError extends Error {
|
|
504
|
+
constructor(message) {
|
|
505
|
+
super(message);
|
|
506
|
+
this.name = 'JsonRpcError';
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
const NewLine = '\n';
|
|
510
|
+
const DomException = 'DOMException';
|
|
511
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
512
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
513
|
+
const TypeError$1 = 'TypeError';
|
|
514
|
+
const getErrorConstructor = (message, type) => {
|
|
515
|
+
if (type) {
|
|
516
|
+
switch (type) {
|
|
517
|
+
case DomException:
|
|
518
|
+
return DOMException;
|
|
519
|
+
case ReferenceError$1:
|
|
520
|
+
return ReferenceError;
|
|
521
|
+
case SyntaxError$1:
|
|
522
|
+
return SyntaxError;
|
|
523
|
+
case TypeError$1:
|
|
524
|
+
return TypeError;
|
|
525
|
+
default:
|
|
526
|
+
return Error;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
if (message.startsWith('TypeError: ')) {
|
|
530
|
+
return TypeError;
|
|
531
|
+
}
|
|
532
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
533
|
+
return SyntaxError;
|
|
534
|
+
}
|
|
535
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
536
|
+
return ReferenceError;
|
|
537
|
+
}
|
|
538
|
+
return Error;
|
|
539
|
+
};
|
|
540
|
+
const constructError = (message, type, name) => {
|
|
541
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
542
|
+
if (ErrorConstructor === DOMException && name) {
|
|
543
|
+
return new ErrorConstructor(message, name);
|
|
544
|
+
}
|
|
545
|
+
if (ErrorConstructor === Error) {
|
|
546
|
+
const error = new Error(message);
|
|
547
|
+
if (name && name !== 'VError') {
|
|
548
|
+
Object.defineProperty(error, 'name', {
|
|
549
|
+
configurable: true,
|
|
550
|
+
value: name
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
return error;
|
|
554
|
+
}
|
|
555
|
+
return new ErrorConstructor(message);
|
|
556
|
+
};
|
|
557
|
+
const joinLines = lines => {
|
|
558
|
+
return lines.join(NewLine);
|
|
559
|
+
};
|
|
560
|
+
const splitLines = lines => {
|
|
561
|
+
return lines.split(NewLine);
|
|
562
|
+
};
|
|
563
|
+
const getCurrentStack = () => {
|
|
564
|
+
const stackLinesToSkip = 3;
|
|
565
|
+
const currentStack = joinLines(splitLines(new Error().stack || '').slice(stackLinesToSkip));
|
|
566
|
+
return currentStack;
|
|
567
|
+
};
|
|
568
|
+
const getNewLineIndex = (string, startIndex) => {
|
|
569
|
+
{
|
|
570
|
+
return string.indexOf(NewLine);
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
const getParentStack = error => {
|
|
574
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
575
|
+
if (parentStack.startsWith(' at')) {
|
|
576
|
+
parentStack = error.message + NewLine + parentStack;
|
|
577
|
+
}
|
|
578
|
+
return parentStack;
|
|
579
|
+
};
|
|
580
|
+
const MethodNotFound = -32601;
|
|
581
|
+
const Custom = -32001;
|
|
582
|
+
const setStack = (error, stack) => {
|
|
583
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, 'stack');
|
|
584
|
+
if (descriptor) {
|
|
585
|
+
if (!descriptor.configurable && !descriptor.writable) {
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
if (!descriptor.configurable && descriptor.writable) {
|
|
589
|
+
error.stack = stack;
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
Object.defineProperty(error, 'stack', {
|
|
594
|
+
configurable: true,
|
|
595
|
+
value: stack,
|
|
596
|
+
writable: true
|
|
597
|
+
});
|
|
598
|
+
};
|
|
599
|
+
const restoreExistingError = (error, currentStack) => {
|
|
600
|
+
if (typeof error.stack === 'string') {
|
|
601
|
+
setStack(error, `${error.stack}${NewLine}${currentStack}`);
|
|
602
|
+
}
|
|
603
|
+
return error;
|
|
604
|
+
};
|
|
605
|
+
const restoreMethodNotFoundError = (error, currentStack) => {
|
|
606
|
+
const restoredError = new JsonRpcError(error.message);
|
|
607
|
+
const parentStack = getParentStack(error);
|
|
608
|
+
setStack(restoredError, `${parentStack}${NewLine}${currentStack}`);
|
|
609
|
+
return restoredError;
|
|
610
|
+
};
|
|
611
|
+
const restoreStackFromData = (restoredError, error, currentStack) => {
|
|
612
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
613
|
+
setStack(restoredError, `${error.data.type}: ${error.message}${NewLine}${error.data.stack}${NewLine}${currentStack}`);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
if (error.data.stack) {
|
|
617
|
+
setStack(restoredError, error.data.stack);
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
const applyDataProperties = (restoredError, error) => {
|
|
621
|
+
restoreStackFromData(restoredError, error, getCurrentStack());
|
|
622
|
+
if (error.data.codeFrame) {
|
|
623
|
+
// @ts-ignore
|
|
624
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
625
|
+
}
|
|
626
|
+
if (error.data.code) {
|
|
627
|
+
// @ts-ignore
|
|
628
|
+
restoredError.code = error.data.code;
|
|
629
|
+
}
|
|
630
|
+
if (error.data.type) {
|
|
631
|
+
// @ts-ignore
|
|
632
|
+
restoredError.name = error.data.type;
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
const applyDirectProperties = (restoredError, error) => {
|
|
636
|
+
if (error.stack) {
|
|
637
|
+
const lowerStack = restoredError.stack || '';
|
|
638
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
639
|
+
const parentStack = getParentStack(error);
|
|
640
|
+
// @ts-ignore
|
|
641
|
+
setStack(restoredError, `${parentStack}${lowerStack.slice(indexNewLine)}`);
|
|
642
|
+
}
|
|
643
|
+
if (error.codeFrame) {
|
|
644
|
+
// @ts-ignore
|
|
645
|
+
restoredError.codeFrame = error.codeFrame;
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
const restoreMessageError = (error, _currentStack) => {
|
|
649
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
650
|
+
if (error.data) {
|
|
651
|
+
applyDataProperties(restoredError, error);
|
|
652
|
+
} else {
|
|
653
|
+
applyDirectProperties(restoredError, error);
|
|
654
|
+
}
|
|
655
|
+
return restoredError;
|
|
656
|
+
};
|
|
657
|
+
const restoreJsonRpcError = error => {
|
|
658
|
+
const currentStack = getCurrentStack();
|
|
659
|
+
if (error && error instanceof Error) {
|
|
660
|
+
return restoreExistingError(error, currentStack);
|
|
661
|
+
}
|
|
662
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
663
|
+
return restoreMethodNotFoundError(error, currentStack);
|
|
664
|
+
}
|
|
665
|
+
if (error && error.message) {
|
|
666
|
+
return restoreMessageError(error);
|
|
667
|
+
}
|
|
668
|
+
if (typeof error === 'string') {
|
|
669
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
670
|
+
}
|
|
671
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
672
|
+
};
|
|
673
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
674
|
+
if ('error' in responseMessage) {
|
|
675
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
676
|
+
throw restoredError;
|
|
677
|
+
}
|
|
678
|
+
if ('result' in responseMessage) {
|
|
679
|
+
return responseMessage.result;
|
|
680
|
+
}
|
|
681
|
+
throw new JsonRpcError('unexpected response message');
|
|
682
|
+
};
|
|
683
|
+
const warn = (...args) => {
|
|
684
|
+
console.warn(...args);
|
|
685
|
+
};
|
|
686
|
+
const resolve = (id, response) => {
|
|
687
|
+
const fn = get$3(id);
|
|
688
|
+
if (!fn) {
|
|
689
|
+
console.log(response);
|
|
690
|
+
warn(`callback ${id} may already be disposed`);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
fn(response);
|
|
694
|
+
remove(id);
|
|
695
|
+
};
|
|
696
|
+
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
697
|
+
const getErrorType = prettyError => {
|
|
698
|
+
if (prettyError && prettyError.type) {
|
|
699
|
+
return prettyError.type;
|
|
700
|
+
}
|
|
701
|
+
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
|
|
702
|
+
return prettyError.constructor.name;
|
|
703
|
+
}
|
|
704
|
+
return undefined;
|
|
705
|
+
};
|
|
706
|
+
const isAlreadyStack = line => {
|
|
707
|
+
return line.trim().startsWith('at ');
|
|
708
|
+
};
|
|
709
|
+
const getStack = prettyError => {
|
|
710
|
+
const stackString = prettyError.stack || '';
|
|
711
|
+
const newLineIndex = stackString.indexOf('\n');
|
|
712
|
+
if (newLineIndex !== -1 && !isAlreadyStack(stackString.slice(0, newLineIndex))) {
|
|
713
|
+
return stackString.slice(newLineIndex + 1);
|
|
714
|
+
}
|
|
715
|
+
return stackString;
|
|
716
|
+
};
|
|
717
|
+
const getErrorProperty = (error, prettyError) => {
|
|
718
|
+
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
719
|
+
return {
|
|
720
|
+
code: MethodNotFound,
|
|
721
|
+
data: error.stack,
|
|
722
|
+
message: error.message
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
return {
|
|
726
|
+
code: Custom,
|
|
727
|
+
data: {
|
|
728
|
+
code: prettyError.code,
|
|
729
|
+
codeFrame: prettyError.codeFrame,
|
|
730
|
+
name: prettyError.name,
|
|
731
|
+
stack: getStack(prettyError),
|
|
732
|
+
type: getErrorType(prettyError)
|
|
733
|
+
},
|
|
734
|
+
message: prettyError.message
|
|
735
|
+
};
|
|
736
|
+
};
|
|
737
|
+
const create$1$1 = (id, error) => {
|
|
738
|
+
return {
|
|
739
|
+
error,
|
|
740
|
+
id,
|
|
741
|
+
jsonrpc: Two$1
|
|
742
|
+
};
|
|
743
|
+
};
|
|
744
|
+
const getErrorResponse = (id, error, preparePrettyError, logError) => {
|
|
745
|
+
const prettyError = preparePrettyError(error);
|
|
746
|
+
logError(error, prettyError);
|
|
747
|
+
const errorProperty = getErrorProperty(error, prettyError);
|
|
748
|
+
return create$1$1(id, errorProperty);
|
|
749
|
+
};
|
|
750
|
+
const create$7 = (message, result) => {
|
|
751
|
+
return {
|
|
752
|
+
id: message.id,
|
|
753
|
+
jsonrpc: Two$1,
|
|
754
|
+
result: result ?? null
|
|
755
|
+
};
|
|
756
|
+
};
|
|
757
|
+
const getSuccessResponse = (message, result) => {
|
|
758
|
+
const resultProperty = result ?? null;
|
|
759
|
+
return create$7(message, resultProperty);
|
|
760
|
+
};
|
|
761
|
+
const getErrorResponseSimple = (id, error) => {
|
|
762
|
+
return {
|
|
763
|
+
error: {
|
|
764
|
+
code: Custom,
|
|
765
|
+
data: error,
|
|
766
|
+
// @ts-ignore
|
|
767
|
+
message: error.message
|
|
768
|
+
},
|
|
769
|
+
id,
|
|
770
|
+
jsonrpc: Two$1
|
|
771
|
+
};
|
|
772
|
+
};
|
|
773
|
+
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
774
|
+
try {
|
|
775
|
+
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
776
|
+
return getSuccessResponse(message, result);
|
|
777
|
+
} catch (error) {
|
|
778
|
+
if (ipc.canUseSimpleErrorResponse) {
|
|
779
|
+
return getErrorResponseSimple(message.id, error);
|
|
780
|
+
}
|
|
781
|
+
return getErrorResponse(message.id, error, preparePrettyError, logError);
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
const defaultPreparePrettyError = error => {
|
|
785
|
+
return error;
|
|
786
|
+
};
|
|
787
|
+
const defaultLogError = () => {
|
|
788
|
+
// ignore
|
|
789
|
+
};
|
|
790
|
+
const defaultRequiresSocket = () => {
|
|
791
|
+
return false;
|
|
792
|
+
};
|
|
793
|
+
const defaultResolve = resolve;
|
|
794
|
+
|
|
795
|
+
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
796
|
+
const normalizeParams = args => {
|
|
797
|
+
if (args.length === 1) {
|
|
798
|
+
const options = args[0];
|
|
799
|
+
return {
|
|
800
|
+
execute: options.execute,
|
|
801
|
+
ipc: options.ipc,
|
|
802
|
+
logError: options.logError || defaultLogError,
|
|
803
|
+
message: options.message,
|
|
804
|
+
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
805
|
+
requiresSocket: options.requiresSocket || defaultRequiresSocket,
|
|
806
|
+
resolve: options.resolve || defaultResolve
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
return {
|
|
810
|
+
execute: args[2],
|
|
811
|
+
ipc: args[0],
|
|
812
|
+
logError: args[5],
|
|
813
|
+
message: args[1],
|
|
814
|
+
preparePrettyError: args[4],
|
|
815
|
+
requiresSocket: args[6],
|
|
816
|
+
resolve: args[3]
|
|
817
|
+
};
|
|
818
|
+
};
|
|
819
|
+
const handleJsonRpcMessage = async (...args) => {
|
|
820
|
+
const options = normalizeParams(args);
|
|
821
|
+
const {
|
|
822
|
+
execute,
|
|
823
|
+
ipc,
|
|
824
|
+
logError,
|
|
825
|
+
message,
|
|
826
|
+
preparePrettyError,
|
|
827
|
+
requiresSocket,
|
|
828
|
+
resolve
|
|
829
|
+
} = options;
|
|
830
|
+
if ('id' in message) {
|
|
831
|
+
if ('method' in message) {
|
|
832
|
+
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
833
|
+
try {
|
|
834
|
+
ipc.send(response);
|
|
835
|
+
} catch (error) {
|
|
836
|
+
const errorResponse = getErrorResponse(message.id, error, preparePrettyError, logError);
|
|
837
|
+
ipc.send(errorResponse);
|
|
838
|
+
}
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
resolve(message.id, message);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if ('method' in message) {
|
|
845
|
+
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
throw new JsonRpcError('unexpected message');
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
const Two = '2.0';
|
|
852
|
+
|
|
853
|
+
const create$6 = (method, params) => {
|
|
854
|
+
return {
|
|
855
|
+
jsonrpc: Two,
|
|
856
|
+
method,
|
|
857
|
+
params
|
|
858
|
+
};
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
const create$5 = (id, method, params) => {
|
|
862
|
+
const message = {
|
|
863
|
+
id,
|
|
864
|
+
jsonrpc: Two,
|
|
865
|
+
method,
|
|
866
|
+
params
|
|
867
|
+
};
|
|
868
|
+
return message;
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
let id = 0;
|
|
872
|
+
const create$4 = () => {
|
|
873
|
+
return ++id;
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
const registerPromise = map => {
|
|
877
|
+
const id = create$4();
|
|
878
|
+
const {
|
|
879
|
+
promise,
|
|
880
|
+
resolve
|
|
881
|
+
} = Promise.withResolvers();
|
|
882
|
+
map[id] = resolve;
|
|
883
|
+
return {
|
|
884
|
+
id,
|
|
885
|
+
promise
|
|
886
|
+
};
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
const invokeHelper = async (callbacks, ipc, method, params, useSendAndTransfer) => {
|
|
890
|
+
const {
|
|
891
|
+
id,
|
|
892
|
+
promise
|
|
893
|
+
} = registerPromise(callbacks);
|
|
894
|
+
const message = create$5(id, method, params);
|
|
895
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
896
|
+
ipc.sendAndTransfer(message);
|
|
897
|
+
} else {
|
|
898
|
+
ipc.send(message);
|
|
899
|
+
}
|
|
900
|
+
const responseMessage = await promise;
|
|
901
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
902
|
+
};
|
|
903
|
+
const createRpc = ipc => {
|
|
904
|
+
const callbacks = Object.create(null);
|
|
905
|
+
ipc._resolve = (id, response) => {
|
|
906
|
+
const fn = callbacks[id];
|
|
907
|
+
if (!fn) {
|
|
908
|
+
console.warn(`callback ${id} may already be disposed`);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
fn(response);
|
|
912
|
+
delete callbacks[id];
|
|
913
|
+
};
|
|
914
|
+
const rpc = {
|
|
915
|
+
async dispose() {
|
|
916
|
+
await ipc?.dispose();
|
|
917
|
+
},
|
|
918
|
+
invoke(method, ...params) {
|
|
919
|
+
return invokeHelper(callbacks, ipc, method, params, false);
|
|
920
|
+
},
|
|
921
|
+
invokeAndTransfer(method, ...params) {
|
|
922
|
+
return invokeHelper(callbacks, ipc, method, params, true);
|
|
923
|
+
},
|
|
924
|
+
// @ts-ignore
|
|
925
|
+
ipc,
|
|
926
|
+
/**
|
|
927
|
+
* @deprecated
|
|
928
|
+
*/
|
|
929
|
+
send(method, ...params) {
|
|
930
|
+
const message = create$6(method, params);
|
|
931
|
+
ipc.send(message);
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
return rpc;
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const requiresSocket = () => {
|
|
938
|
+
return false;
|
|
939
|
+
};
|
|
940
|
+
const preparePrettyError = error => {
|
|
941
|
+
return error;
|
|
942
|
+
};
|
|
943
|
+
const logError = () => {
|
|
944
|
+
// handled by renderer worker
|
|
945
|
+
};
|
|
946
|
+
const handleMessage = event => {
|
|
947
|
+
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
948
|
+
const actualExecute = event?.target?.execute || execute;
|
|
949
|
+
return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
950
|
+
};
|
|
951
|
+
|
|
952
|
+
const handleIpc = ipc => {
|
|
953
|
+
if ('addEventListener' in ipc) {
|
|
954
|
+
ipc.addEventListener('message', handleMessage);
|
|
955
|
+
} else if ('on' in ipc) {
|
|
956
|
+
// deprecated
|
|
957
|
+
ipc.on('message', handleMessage);
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
const unhandleIpc = ipc => {
|
|
961
|
+
if ('removeEventListener' in ipc) {
|
|
962
|
+
ipc.removeEventListener('message', handleMessage);
|
|
963
|
+
} else {
|
|
964
|
+
// deprecated
|
|
965
|
+
ipc.onmessage = null;
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
const create$3 = async ({
|
|
970
|
+
commandMap,
|
|
971
|
+
isMessagePortOpen = true,
|
|
972
|
+
messagePort
|
|
973
|
+
}) => {
|
|
974
|
+
// TODO create a commandMap per rpc instance
|
|
975
|
+
register(commandMap);
|
|
976
|
+
const rawIpc = await IpcParentWithMessagePort$1.create({
|
|
977
|
+
isMessagePortOpen,
|
|
978
|
+
messagePort
|
|
979
|
+
});
|
|
980
|
+
const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
|
|
981
|
+
handleIpc(ipc);
|
|
982
|
+
const rpc = createRpc(ipc);
|
|
983
|
+
messagePort.start();
|
|
984
|
+
return rpc;
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
const isWorker = value => {
|
|
988
|
+
return value instanceof Worker;
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
const create$2 = async ({
|
|
992
|
+
commandMap,
|
|
993
|
+
name,
|
|
994
|
+
port,
|
|
995
|
+
url
|
|
996
|
+
}) => {
|
|
997
|
+
// TODO create a commandMap per rpc instance
|
|
998
|
+
register(commandMap);
|
|
999
|
+
const worker = await IpcParentWithModuleWorker$1.create({
|
|
1000
|
+
name,
|
|
1001
|
+
url
|
|
1002
|
+
});
|
|
1003
|
+
if (!isWorker(worker)) {
|
|
1004
|
+
throw new Error(`worker must be of type Worker`);
|
|
1005
|
+
}
|
|
1006
|
+
const ipc = IpcParentWithModuleWorker$1.wrap(worker);
|
|
1007
|
+
handleIpc(ipc);
|
|
1008
|
+
const workerRpc = createRpc(ipc);
|
|
1009
|
+
await workerRpc.invokeAndTransfer('initialize', 'message-port', port);
|
|
1010
|
+
unhandleIpc(ipc);
|
|
1011
|
+
return workerRpc;
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
const commandMapRef = {};
|
|
1015
|
+
|
|
1016
|
+
const getEditorOnlyConfig = () => {
|
|
1017
|
+
const configElement = document.getElementById('Config');
|
|
1018
|
+
if (!configElement?.textContent) {
|
|
1019
|
+
return {};
|
|
1020
|
+
}
|
|
1021
|
+
const config = JSON.parse(configElement.textContent);
|
|
1022
|
+
return config.editorOnly || {};
|
|
1023
|
+
};
|
|
1024
|
+
|
|
1025
|
+
const controlOrMeta = event => {
|
|
1026
|
+
return event.ctrlKey || event.metaKey;
|
|
1027
|
+
};
|
|
1028
|
+
const getShortcutCommand = event => {
|
|
1029
|
+
if (!controlOrMeta(event)) {
|
|
1030
|
+
return '';
|
|
1031
|
+
}
|
|
1032
|
+
switch (event.key.toLowerCase()) {
|
|
1033
|
+
case 'a':
|
|
1034
|
+
return 'selectAll';
|
|
1035
|
+
case 'y':
|
|
1036
|
+
return 'redo';
|
|
1037
|
+
case 'z':
|
|
1038
|
+
return event.shiftKey ? 'redo' : 'undo';
|
|
1039
|
+
default:
|
|
1040
|
+
return '';
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
const getHorizontalCommand = event => {
|
|
1044
|
+
if (event.key === 'ArrowLeft') {
|
|
1045
|
+
if (event.shiftKey) {
|
|
1046
|
+
return 'selectCharacterLeft';
|
|
1047
|
+
}
|
|
1048
|
+
return controlOrMeta(event) ? 'cursorWordLeft' : 'cursorLeft';
|
|
1049
|
+
}
|
|
1050
|
+
if (event.key === 'ArrowRight') {
|
|
1051
|
+
if (event.shiftKey) {
|
|
1052
|
+
return 'selectCharacterRight';
|
|
1053
|
+
}
|
|
1054
|
+
return controlOrMeta(event) ? 'cursorWordRight' : 'cursorRight';
|
|
1055
|
+
}
|
|
1056
|
+
return '';
|
|
1057
|
+
};
|
|
1058
|
+
const getNavigationCommand = event => {
|
|
1059
|
+
switch (event.key) {
|
|
1060
|
+
case 'ArrowDown':
|
|
1061
|
+
return event.shiftKey ? 'selectDown' : 'cursorDown';
|
|
1062
|
+
case 'ArrowUp':
|
|
1063
|
+
return event.shiftKey ? 'selectUp' : 'cursorUp';
|
|
1064
|
+
case 'Backspace':
|
|
1065
|
+
return controlOrMeta(event) ? 'deleteWordLeft' : 'deleteLeft';
|
|
1066
|
+
case 'Delete':
|
|
1067
|
+
return controlOrMeta(event) ? 'deleteWordRight' : 'deleteRight';
|
|
1068
|
+
case 'End':
|
|
1069
|
+
return 'cursorEnd';
|
|
1070
|
+
case 'Home':
|
|
1071
|
+
return 'cursorHome';
|
|
1072
|
+
case 'PageDown':
|
|
1073
|
+
return 'cursorPageDown';
|
|
1074
|
+
case 'Tab':
|
|
1075
|
+
return 'handleTab';
|
|
1076
|
+
default:
|
|
1077
|
+
return '';
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
const getEditorCommand = event => {
|
|
1081
|
+
return getShortcutCommand(event) || getHorizontalCommand(event) || getNavigationCommand(event);
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
const uidSymbol = Symbol('uid');
|
|
1085
|
+
|
|
1086
|
+
const getUidTarget = $Element => {
|
|
1087
|
+
while ($Element) {
|
|
1088
|
+
if (Object.getOwnPropertyDescriptor($Element, uidSymbol)?.value) {
|
|
1089
|
+
return $Element;
|
|
1090
|
+
}
|
|
1091
|
+
$Element = $Element.parentNode;
|
|
1092
|
+
}
|
|
1093
|
+
return undefined;
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
const setComponentUid = ($Element, uid) => {
|
|
1097
|
+
Object.defineProperty($Element, uidSymbol, {
|
|
1098
|
+
configurable: true,
|
|
1099
|
+
value: uid,
|
|
1100
|
+
writable: true
|
|
1101
|
+
});
|
|
1102
|
+
};
|
|
1103
|
+
const getComponentUid = $Element => {
|
|
1104
|
+
const $Target = getUidTarget($Element);
|
|
1105
|
+
if (!$Target) {
|
|
1106
|
+
return 0;
|
|
1107
|
+
}
|
|
1108
|
+
return Object.getOwnPropertyDescriptor($Target, uidSymbol)?.value;
|
|
1109
|
+
};
|
|
1110
|
+
const getComponentUidFromEvent = event => {
|
|
1111
|
+
const {
|
|
1112
|
+
currentTarget,
|
|
1113
|
+
target
|
|
1114
|
+
} = event;
|
|
1115
|
+
return getComponentUid(currentTarget || target);
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
const dragInfos = Object.create(null);
|
|
1119
|
+
const getDragInfo = id => {
|
|
1120
|
+
return dragInfos[id];
|
|
1121
|
+
};
|
|
1122
|
+
const isDragInfoOld = data => {
|
|
1123
|
+
return Array.isArray(data);
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
const setDragImage = (dataTransfer, label) => {
|
|
1127
|
+
const dragImage = document.createElement('div');
|
|
1128
|
+
dragImage.className = 'DragImage';
|
|
1129
|
+
dragImage.textContent = label;
|
|
1130
|
+
document.body.append(dragImage);
|
|
1131
|
+
dataTransfer.setDragImage(dragImage, -10, -10);
|
|
1132
|
+
const handleTimeout = () => {
|
|
1133
|
+
dragImage.remove();
|
|
1134
|
+
};
|
|
1135
|
+
setTimeout(handleTimeout, 0);
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
const applyDragInfoMaybe = event => {
|
|
1139
|
+
const {
|
|
1140
|
+
dataTransfer,
|
|
1141
|
+
target
|
|
1142
|
+
} = event;
|
|
1143
|
+
if (dataTransfer) {
|
|
1144
|
+
const uid = getComponentUid(target);
|
|
1145
|
+
const dragInfo = getDragInfo(uid);
|
|
1146
|
+
if (!dragInfo) {
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (isDragInfoOld(dragInfo)) {
|
|
1150
|
+
for (const item of dragInfo) {
|
|
1151
|
+
dataTransfer.setData(item.type, item.data);
|
|
1152
|
+
}
|
|
1153
|
+
} else {
|
|
1154
|
+
for (const item of dragInfo.items) {
|
|
1155
|
+
dataTransfer.items.add(item.data, item.type);
|
|
1156
|
+
}
|
|
1157
|
+
if (dragInfo.label) {
|
|
1158
|
+
setDragImage(dataTransfer, dragInfo.label);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
const PointerMove = 'pointermove';
|
|
1165
|
+
const PointerUp = 'pointerup';
|
|
1166
|
+
const lostpointercapture = 'lostpointercapture';
|
|
1167
|
+
|
|
1168
|
+
const createEventState = () => {
|
|
1169
|
+
let ignore = false;
|
|
1170
|
+
return {
|
|
1171
|
+
startIgnore() {
|
|
1172
|
+
ignore = true;
|
|
1173
|
+
},
|
|
1174
|
+
stopIgnore() {
|
|
1175
|
+
ignore = false;
|
|
1176
|
+
},
|
|
1177
|
+
enabled() {
|
|
1178
|
+
return ignore;
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
};
|
|
1182
|
+
const eventState = createEventState();
|
|
1183
|
+
const startIgnore = () => {
|
|
1184
|
+
eventState.startIgnore();
|
|
1185
|
+
};
|
|
1186
|
+
const stopIgnore = () => {
|
|
1187
|
+
eventState.stopIgnore();
|
|
1188
|
+
};
|
|
1189
|
+
const enabled = () => {
|
|
1190
|
+
return eventState.enabled();
|
|
1191
|
+
};
|
|
1192
|
+
|
|
1193
|
+
const createIdGenerator = () => {
|
|
1194
|
+
let id = 0;
|
|
1195
|
+
return () => {
|
|
1196
|
+
return ++id;
|
|
1197
|
+
};
|
|
1198
|
+
};
|
|
1199
|
+
const create$1 = createIdGenerator();
|
|
1200
|
+
|
|
1201
|
+
const state$2 = Object.create(null);
|
|
1202
|
+
const add$1 = promise => {
|
|
1203
|
+
const id = create$1();
|
|
1204
|
+
state$2[id] = promise;
|
|
1205
|
+
return id;
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
const unwrapItemString = async item => {
|
|
1209
|
+
const {
|
|
1210
|
+
resolve,
|
|
1211
|
+
promise
|
|
1212
|
+
} = Promise.withResolvers();
|
|
1213
|
+
item.getAsString(resolve);
|
|
1214
|
+
const value = await promise;
|
|
1215
|
+
return {
|
|
1216
|
+
kind: 'string',
|
|
1217
|
+
type: item.type,
|
|
1218
|
+
value
|
|
1219
|
+
};
|
|
1220
|
+
};
|
|
1221
|
+
const unwrapItemFile = async item => {
|
|
1222
|
+
// @ts-ignore
|
|
1223
|
+
if (item.getAsFileSystemHandle) {
|
|
1224
|
+
// @ts-ignore
|
|
1225
|
+
const file = await item.getAsFileSystemHandle();
|
|
1226
|
+
return {
|
|
1227
|
+
kind: 'file',
|
|
1228
|
+
type: item.type,
|
|
1229
|
+
value: file
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
const file = item.getAsFile();
|
|
1233
|
+
return {
|
|
1234
|
+
kind: 'file-legacy',
|
|
1235
|
+
type: item.type,
|
|
1236
|
+
value: file
|
|
1237
|
+
};
|
|
1238
|
+
};
|
|
1239
|
+
const unknownItem = {
|
|
1240
|
+
kind: 'unknown',
|
|
1241
|
+
type: '',
|
|
1242
|
+
value: ''
|
|
1243
|
+
};
|
|
1244
|
+
const unwrapItem = item => {
|
|
1245
|
+
switch (item.kind) {
|
|
1246
|
+
case 'file':
|
|
1247
|
+
return unwrapItemFile(item);
|
|
1248
|
+
case 'string':
|
|
1249
|
+
return unwrapItemString(item);
|
|
1250
|
+
default:
|
|
1251
|
+
return unknownItem;
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
const handleDataTransferFiles = event => {
|
|
1255
|
+
if (!event.dataTransfer) {
|
|
1256
|
+
return [];
|
|
1257
|
+
}
|
|
1258
|
+
const items = [...event.dataTransfer.items];
|
|
1259
|
+
const promises = items.map(unwrapItem);
|
|
1260
|
+
const ids = promises.map(promise => add$1(promise));
|
|
1261
|
+
return ids;
|
|
1262
|
+
};
|
|
1263
|
+
const handleClipboardDataFiles = event => {
|
|
1264
|
+
if (!event.clipboardData) {
|
|
1265
|
+
return [];
|
|
1266
|
+
}
|
|
1267
|
+
const files = [];
|
|
1268
|
+
for (const item of event.clipboardData.items) {
|
|
1269
|
+
if (item.kind !== 'file') {
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1272
|
+
const file = item.getAsFile();
|
|
1273
|
+
if (file) {
|
|
1274
|
+
files.push(file);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
return files;
|
|
1278
|
+
};
|
|
1279
|
+
const getTargetName = event => {
|
|
1280
|
+
const {
|
|
1281
|
+
target
|
|
1282
|
+
} = event;
|
|
1283
|
+
if (target.name) {
|
|
1284
|
+
return target.name;
|
|
1285
|
+
}
|
|
1286
|
+
const namedTarget = target.closest?.('[name]') || target.parentElement?.closest?.('[name]');
|
|
1287
|
+
if (event.currentTarget?.contains && namedTarget !== event.currentTarget && !event.currentTarget.contains(namedTarget)) {
|
|
1288
|
+
return '';
|
|
1289
|
+
}
|
|
1290
|
+
return namedTarget?.getAttribute?.('name') || namedTarget?.name || '';
|
|
1291
|
+
};
|
|
1292
|
+
const getNestedProperty = (value, path) => {
|
|
1293
|
+
const parts = path.split('.');
|
|
1294
|
+
let current = value;
|
|
1295
|
+
for (const part of parts) {
|
|
1296
|
+
if (current === undefined || current === null) {
|
|
1297
|
+
return undefined;
|
|
1298
|
+
}
|
|
1299
|
+
current = current[part];
|
|
1300
|
+
}
|
|
1301
|
+
return current;
|
|
1302
|
+
};
|
|
1303
|
+
const getEventListenerArg = (param, event) => {
|
|
1304
|
+
switch (param) {
|
|
1305
|
+
case 'event.altKey':
|
|
1306
|
+
return event.altKey;
|
|
1307
|
+
case 'event.button':
|
|
1308
|
+
return event.button;
|
|
1309
|
+
case 'event.clientX':
|
|
1310
|
+
return event.clientX;
|
|
1311
|
+
case 'event.clientY':
|
|
1312
|
+
return event.clientY;
|
|
1313
|
+
case 'event.clipboardData.files':
|
|
1314
|
+
return handleClipboardDataFiles(event);
|
|
1315
|
+
case 'event.ctrlKey':
|
|
1316
|
+
return event.ctrlKey;
|
|
1317
|
+
case 'event.data':
|
|
1318
|
+
return event.data;
|
|
1319
|
+
case 'event.dataTransfer.files':
|
|
1320
|
+
return event.dataTransfer.files;
|
|
1321
|
+
case 'event.dataTransfer.files2':
|
|
1322
|
+
return handleDataTransferFiles(event);
|
|
1323
|
+
case 'event.defaultPrevented':
|
|
1324
|
+
return event.defaultPrevented;
|
|
1325
|
+
case 'event.deltaMode':
|
|
1326
|
+
return event.deltaMode;
|
|
1327
|
+
case 'event.deltaX':
|
|
1328
|
+
return event.deltaX;
|
|
1329
|
+
case 'event.deltaY':
|
|
1330
|
+
return event.deltaY;
|
|
1331
|
+
case 'event.detail':
|
|
1332
|
+
return event.detail;
|
|
1333
|
+
case 'event.inputType':
|
|
1334
|
+
return event.inputType;
|
|
1335
|
+
case 'event.isTrusted':
|
|
1336
|
+
return event.isTrusted;
|
|
1337
|
+
case 'event.key':
|
|
1338
|
+
return event.key;
|
|
1339
|
+
case 'event.shiftKey':
|
|
1340
|
+
return event.shiftKey;
|
|
1341
|
+
case 'event.target.checked':
|
|
1342
|
+
return event.target.checked;
|
|
1343
|
+
case 'event.target.className':
|
|
1344
|
+
return event.target.className;
|
|
1345
|
+
case 'event.target.href':
|
|
1346
|
+
return event.target.href;
|
|
1347
|
+
case 'event.target.name':
|
|
1348
|
+
return getTargetName(event);
|
|
1349
|
+
case 'event.target.nodeName':
|
|
1350
|
+
return event.target.nodeName;
|
|
1351
|
+
case 'event.target.scrollTop':
|
|
1352
|
+
return event.target.scrollTop;
|
|
1353
|
+
case 'event.target.selectionEnd':
|
|
1354
|
+
return event.target.selectionEnd;
|
|
1355
|
+
case 'event.target.selectionStart':
|
|
1356
|
+
return event.target.selectionStart;
|
|
1357
|
+
case 'event.target.src':
|
|
1358
|
+
return event.target.src;
|
|
1359
|
+
case 'event.target.value':
|
|
1360
|
+
return event.target.value;
|
|
1361
|
+
case 'event.x':
|
|
1362
|
+
return event.x;
|
|
1363
|
+
case 'event.y':
|
|
1364
|
+
return event.y;
|
|
1365
|
+
default:
|
|
1366
|
+
if (typeof param === 'string' && param.startsWith('event.currentTarget.')) {
|
|
1367
|
+
const path = param.slice('event.currentTarget.'.length);
|
|
1368
|
+
return getNestedProperty(event.currentTarget, path);
|
|
1369
|
+
}
|
|
1370
|
+
if (typeof param === 'string' && param.startsWith('event.target.')) {
|
|
1371
|
+
const path = param.slice('event.target.'.length);
|
|
1372
|
+
return getNestedProperty(event.target, path);
|
|
1373
|
+
}
|
|
1374
|
+
return param;
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
const getEventListenerArgs = (params, event) => {
|
|
1379
|
+
const serialized = Array.from(params, param => getEventListenerArg(param, event));
|
|
1380
|
+
return serialized;
|
|
1381
|
+
};
|
|
1382
|
+
|
|
1383
|
+
const state$1 = {
|
|
1384
|
+
ipc: undefined
|
|
1385
|
+
};
|
|
1386
|
+
const getIpc = () => {
|
|
1387
|
+
return state$1.ipc;
|
|
1388
|
+
};
|
|
1389
|
+
const setIpc = value => {
|
|
1390
|
+
state$1.ipc = value;
|
|
1391
|
+
};
|
|
1392
|
+
|
|
1393
|
+
const nameAnonymousFunction = (fn, name) => {
|
|
1394
|
+
Object.defineProperty(fn, 'name', {
|
|
1395
|
+
value: name
|
|
1396
|
+
});
|
|
1397
|
+
};
|
|
1398
|
+
|
|
1399
|
+
const isInputElement = element => {
|
|
1400
|
+
return element instanceof HTMLInputElement;
|
|
1401
|
+
};
|
|
1402
|
+
|
|
1403
|
+
const preventEventsMaybe = (info, event) => {
|
|
1404
|
+
if (info.preventDefault === 2) {
|
|
1405
|
+
if (!isInputElement(event.target)) {
|
|
1406
|
+
event.preventDefault();
|
|
1407
|
+
}
|
|
1408
|
+
} else if (info.preventDefault) {
|
|
1409
|
+
event.preventDefault();
|
|
1410
|
+
}
|
|
1411
|
+
if (info.stopPropagation) {
|
|
1412
|
+
event.stopPropagation();
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
const applyPointerTrackMaybe = (info, map, event) => {
|
|
1417
|
+
const {
|
|
1418
|
+
trackPointerEvents
|
|
1419
|
+
} = info;
|
|
1420
|
+
if (!trackPointerEvents) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const {
|
|
1424
|
+
pointerId,
|
|
1425
|
+
target
|
|
1426
|
+
} = event;
|
|
1427
|
+
target.setPointerCapture(pointerId);
|
|
1428
|
+
const [pointerMoveKey, pointerUpKey] = trackPointerEvents;
|
|
1429
|
+
const pointerMove = map[pointerMoveKey];
|
|
1430
|
+
const pointerUp = map[pointerUpKey];
|
|
1431
|
+
const cleanup = () => {
|
|
1432
|
+
target.removeEventListener(PointerMove, pointerMove);
|
|
1433
|
+
target.removeEventListener(PointerUp, handlePointerUp);
|
|
1434
|
+
target.removeEventListener(lostpointercapture, handlePointerUp);
|
|
1435
|
+
};
|
|
1436
|
+
const handlePointerUp = event => {
|
|
1437
|
+
cleanup();
|
|
1438
|
+
pointerUp(event);
|
|
1439
|
+
};
|
|
1440
|
+
target.addEventListener(PointerMove, pointerMove);
|
|
1441
|
+
target.addEventListener(PointerUp, handlePointerUp);
|
|
1442
|
+
target.addEventListener(lostpointercapture, handlePointerUp);
|
|
1443
|
+
};
|
|
1444
|
+
const createFn = (info, map) => {
|
|
1445
|
+
const fn = event => {
|
|
1446
|
+
if (enabled()) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
const uid = getComponentUidFromEvent(event);
|
|
1450
|
+
const args = getEventListenerArgs(info.params, event);
|
|
1451
|
+
preventEventsMaybe(info, event);
|
|
1452
|
+
applyDragInfoMaybe(event);
|
|
1453
|
+
applyPointerTrackMaybe(info, map, event);
|
|
1454
|
+
if (args.length === 0) {
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
const ipc = getIpc();
|
|
1458
|
+
ipc.send('Viewlet.executeViewletCommand', uid, ...args);
|
|
1459
|
+
};
|
|
1460
|
+
nameAnonymousFunction(fn, info.name);
|
|
1461
|
+
if (info.passive) {
|
|
1462
|
+
// TODO avoid mutating function property, maybe return an object with function and options
|
|
1463
|
+
fn.passive = true;
|
|
1464
|
+
}
|
|
1465
|
+
if (info.capture) {
|
|
1466
|
+
// TODO avoid mutating function property, maybe return an object with function and options
|
|
1467
|
+
fn.capture = true;
|
|
1468
|
+
}
|
|
1469
|
+
return fn;
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
const listeners = Object.create(null);
|
|
1473
|
+
const registerEventListeners = (id, eventListeners) => {
|
|
1474
|
+
const map = Object.create(null);
|
|
1475
|
+
for (const info of eventListeners) {
|
|
1476
|
+
const fn = createFn(info, map);
|
|
1477
|
+
map[info.name] = fn;
|
|
1478
|
+
}
|
|
1479
|
+
listeners[id] = map;
|
|
1480
|
+
};
|
|
1481
|
+
const getEventListenerMap = id => {
|
|
1482
|
+
const map = listeners[id];
|
|
1483
|
+
return map;
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
const clearNode = $Node => {
|
|
1487
|
+
$Node.textContent = '';
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
const Audio$1 = 'audio';
|
|
1491
|
+
const Button$1 = 'button';
|
|
1492
|
+
const Col$1 = 'col';
|
|
1493
|
+
const ColGroup$1 = 'colgroup';
|
|
1494
|
+
const Del$1 = 'del';
|
|
1495
|
+
const Div$1 = 'div';
|
|
1496
|
+
const H1$1 = 'h1';
|
|
1497
|
+
const H2$1 = 'h2';
|
|
1498
|
+
const H3$1 = 'h3';
|
|
1499
|
+
const H4$1 = 'h4';
|
|
1500
|
+
const H5$1 = 'h5';
|
|
1501
|
+
const H6$1 = 'h6';
|
|
1502
|
+
const I$1 = 'i';
|
|
1503
|
+
const Img$1 = 'img';
|
|
1504
|
+
const Input$1 = 'input';
|
|
1505
|
+
const Ins$1 = 'ins';
|
|
1506
|
+
const Kbd$1 = 'kbd';
|
|
1507
|
+
const Span$1 = 'span';
|
|
1508
|
+
const Table$1 = 'table';
|
|
1509
|
+
const TBody$1 = 'tbody';
|
|
1510
|
+
const Td$1 = 'td';
|
|
1511
|
+
const Th$1 = 'th';
|
|
1512
|
+
const THead$1 = 'thead';
|
|
1513
|
+
const Tr$1 = 'tr';
|
|
1514
|
+
const Article$1 = 'article';
|
|
1515
|
+
const Aside$1 = 'aside';
|
|
1516
|
+
const Footer$1 = 'footer';
|
|
1517
|
+
const Header$1 = 'header';
|
|
1518
|
+
const Nav$1 = 'nav';
|
|
1519
|
+
const Section$1 = 'section';
|
|
1520
|
+
const Search$1 = 'search';
|
|
1521
|
+
const Dd$1 = 'dd';
|
|
1522
|
+
const Dl$1 = 'dl';
|
|
1523
|
+
const Figcaption$1 = 'figcaption';
|
|
1524
|
+
const Figure$1 = 'figure';
|
|
1525
|
+
const Hr$1 = 'hr';
|
|
1526
|
+
const Li$1 = 'li';
|
|
1527
|
+
const Ol$1 = 'ol';
|
|
1528
|
+
const P$1 = 'p';
|
|
1529
|
+
const Pre$1 = 'pre';
|
|
1530
|
+
const A$1 = 'a';
|
|
1531
|
+
const Br$1 = 'br';
|
|
1532
|
+
const Cite$1 = 'cite';
|
|
1533
|
+
const Data$1 = 'data';
|
|
1534
|
+
const Time$1 = 'time';
|
|
1535
|
+
const Tfoot$1 = 'tfoot';
|
|
1536
|
+
const Ul$1 = 'ul';
|
|
1537
|
+
const Video$1 = 'video';
|
|
1538
|
+
const TextArea$1 = 'textarea';
|
|
1539
|
+
const Select$1 = 'select';
|
|
1540
|
+
const Option$1 = 'option';
|
|
1541
|
+
const Code$1 = 'code';
|
|
1542
|
+
const Label$1 = 'label';
|
|
1543
|
+
const Dt$1 = 'dt';
|
|
1544
|
+
const Iframe$1 = 'iframe';
|
|
1545
|
+
const Main$1 = 'main';
|
|
1546
|
+
const Em$1 = 'em';
|
|
1547
|
+
const Strong$1 = 'strong';
|
|
1548
|
+
const Style$1 = 'style';
|
|
1549
|
+
const Html$1 = 'html';
|
|
1550
|
+
const Head$1 = 'head';
|
|
1551
|
+
const Title$1 = 'title';
|
|
1552
|
+
const Meta$1 = 'meta';
|
|
1553
|
+
const Canvas$1 = 'canvas';
|
|
1554
|
+
const Circle$1 = 'circle';
|
|
1555
|
+
const Form$1 = 'form';
|
|
1556
|
+
const Defs$1 = 'defs';
|
|
1557
|
+
const Ellipse$1 = 'ellipse';
|
|
1558
|
+
const G$1 = 'g';
|
|
1559
|
+
const Line$1 = 'line';
|
|
1560
|
+
const Path$1 = 'path';
|
|
1561
|
+
const Polygon$1 = 'polygon';
|
|
1562
|
+
const Polyline$1 = 'polyline';
|
|
1563
|
+
const Quote$1 = 'quote';
|
|
1564
|
+
const BlockQuote$1 = 'blockquote';
|
|
1565
|
+
const Rect$1 = 'rect';
|
|
1566
|
+
const Svg$1 = 'svg';
|
|
1567
|
+
const Use$1 = 'use';
|
|
1568
|
+
|
|
1569
|
+
const Audio = 0;
|
|
1570
|
+
const Button = 1;
|
|
1571
|
+
const Col = 2;
|
|
1572
|
+
const ColGroup = 3;
|
|
1573
|
+
const Div = 4;
|
|
1574
|
+
const H1 = 5;
|
|
1575
|
+
const Input = 6;
|
|
1576
|
+
const Kbd = 7;
|
|
1577
|
+
const Span = 8;
|
|
1578
|
+
const Table = 9;
|
|
1579
|
+
const TBody = 10;
|
|
1580
|
+
const Td = 11;
|
|
1581
|
+
const Text$1 = 12;
|
|
1582
|
+
const Th = 13;
|
|
1583
|
+
const THead = 14;
|
|
1584
|
+
const Tr = 15;
|
|
1585
|
+
const I = 16;
|
|
1586
|
+
const Img = 17;
|
|
1587
|
+
const Ins = 20;
|
|
1588
|
+
const Del = 21;
|
|
1589
|
+
const H2 = 22;
|
|
1590
|
+
const H3 = 23;
|
|
1591
|
+
const H4 = 24;
|
|
1592
|
+
const H5 = 25;
|
|
1593
|
+
const H6 = 26;
|
|
1594
|
+
const Article = 27;
|
|
1595
|
+
const Aside = 28;
|
|
1596
|
+
const Footer = 29;
|
|
1597
|
+
const Header = 30;
|
|
1598
|
+
const Nav = 40;
|
|
1599
|
+
const Section = 41;
|
|
1600
|
+
const Search = 42;
|
|
1601
|
+
const Dd = 43;
|
|
1602
|
+
const Dl = 44;
|
|
1603
|
+
const Figcaption = 45;
|
|
1604
|
+
const Figure = 46;
|
|
1605
|
+
const Hr = 47;
|
|
1606
|
+
const Li = 48;
|
|
1607
|
+
const Ol = 49;
|
|
1608
|
+
const P = 50;
|
|
1609
|
+
const Pre = 51;
|
|
1610
|
+
const A = 53;
|
|
1611
|
+
const Br = 55;
|
|
1612
|
+
const Cite = 56;
|
|
1613
|
+
const Data = 57;
|
|
1614
|
+
const Time = 58;
|
|
1615
|
+
const Tfoot = 59;
|
|
1616
|
+
const Ul = 60;
|
|
1617
|
+
const Video = 61;
|
|
1618
|
+
const TextArea = 62;
|
|
1619
|
+
const Select = 63;
|
|
1620
|
+
const Option = 64;
|
|
1621
|
+
const Code = 65;
|
|
1622
|
+
const Label = 66;
|
|
1623
|
+
const Dt = 67;
|
|
1624
|
+
const Iframe = 68;
|
|
1625
|
+
const Main = 69;
|
|
1626
|
+
const Strong = 70;
|
|
1627
|
+
const Em = 71;
|
|
1628
|
+
const Style = 72;
|
|
1629
|
+
const Html = 73;
|
|
1630
|
+
const Head = 74;
|
|
1631
|
+
const Title = 75;
|
|
1632
|
+
const Meta = 76;
|
|
1633
|
+
const Canvas = 77;
|
|
1634
|
+
const Form = 78;
|
|
1635
|
+
const BlockQuote = 79;
|
|
1636
|
+
const Quote = 80;
|
|
1637
|
+
const Circle = 81;
|
|
1638
|
+
const Defs = 82;
|
|
1639
|
+
const Ellipse = 83;
|
|
1640
|
+
const G = 84;
|
|
1641
|
+
const Line = 85;
|
|
1642
|
+
const Path = 86;
|
|
1643
|
+
const Polygon = 87;
|
|
1644
|
+
const Polyline = 88;
|
|
1645
|
+
const Rect = 89;
|
|
1646
|
+
const Svg = 90;
|
|
1647
|
+
const Use = 91;
|
|
1648
|
+
const Reference$1 = 100;
|
|
1649
|
+
|
|
1650
|
+
const VirtualDomElements = {
|
|
1651
|
+
__proto__: null,
|
|
1652
|
+
A,
|
|
1653
|
+
Article,
|
|
1654
|
+
Aside,
|
|
1655
|
+
Audio,
|
|
1656
|
+
BlockQuote,
|
|
1657
|
+
Br,
|
|
1658
|
+
Button,
|
|
1659
|
+
Canvas,
|
|
1660
|
+
Circle,
|
|
1661
|
+
Cite,
|
|
1662
|
+
Code,
|
|
1663
|
+
Col,
|
|
1664
|
+
ColGroup,
|
|
1665
|
+
Data,
|
|
1666
|
+
Dd,
|
|
1667
|
+
Defs,
|
|
1668
|
+
Del,
|
|
1669
|
+
Div,
|
|
1670
|
+
Dl,
|
|
1671
|
+
Dt,
|
|
1672
|
+
Ellipse,
|
|
1673
|
+
Em,
|
|
1674
|
+
Figcaption,
|
|
1675
|
+
Figure,
|
|
1676
|
+
Footer,
|
|
1677
|
+
Form,
|
|
1678
|
+
G,
|
|
1679
|
+
H1,
|
|
1680
|
+
H2,
|
|
1681
|
+
H3,
|
|
1682
|
+
H4,
|
|
1683
|
+
H5,
|
|
1684
|
+
H6,
|
|
1685
|
+
Head,
|
|
1686
|
+
Header,
|
|
1687
|
+
Hr,
|
|
1688
|
+
Html,
|
|
1689
|
+
I,
|
|
1690
|
+
Iframe,
|
|
1691
|
+
Img,
|
|
1692
|
+
Input,
|
|
1693
|
+
Ins,
|
|
1694
|
+
Kbd,
|
|
1695
|
+
Label,
|
|
1696
|
+
Li,
|
|
1697
|
+
Line,
|
|
1698
|
+
Main,
|
|
1699
|
+
Meta,
|
|
1700
|
+
Nav,
|
|
1701
|
+
Ol,
|
|
1702
|
+
Option,
|
|
1703
|
+
P,
|
|
1704
|
+
Path,
|
|
1705
|
+
Polygon,
|
|
1706
|
+
Polyline,
|
|
1707
|
+
Pre,
|
|
1708
|
+
Quote,
|
|
1709
|
+
Rect,
|
|
1710
|
+
Reference: Reference$1,
|
|
1711
|
+
Search,
|
|
1712
|
+
Section,
|
|
1713
|
+
Select,
|
|
1714
|
+
Span,
|
|
1715
|
+
Strong,
|
|
1716
|
+
Style,
|
|
1717
|
+
Svg,
|
|
1718
|
+
TBody,
|
|
1719
|
+
THead,
|
|
1720
|
+
Table,
|
|
1721
|
+
Td,
|
|
1722
|
+
Text: Text$1,
|
|
1723
|
+
TextArea,
|
|
1724
|
+
Tfoot,
|
|
1725
|
+
Th,
|
|
1726
|
+
Time,
|
|
1727
|
+
Title,
|
|
1728
|
+
Tr,
|
|
1729
|
+
Ul,
|
|
1730
|
+
Use,
|
|
1731
|
+
Video
|
|
1732
|
+
};
|
|
1733
|
+
|
|
1734
|
+
const elementTagMap = {
|
|
1735
|
+
[A]: A$1,
|
|
1736
|
+
[Article]: Article$1,
|
|
1737
|
+
[Aside]: Aside$1,
|
|
1738
|
+
[Audio]: Audio$1,
|
|
1739
|
+
[BlockQuote]: BlockQuote$1,
|
|
1740
|
+
[Br]: Br$1,
|
|
1741
|
+
[Button]: Button$1,
|
|
1742
|
+
[Canvas]: Canvas$1,
|
|
1743
|
+
[Circle]: Circle$1,
|
|
1744
|
+
[Cite]: Cite$1,
|
|
1745
|
+
[Code]: Code$1,
|
|
1746
|
+
[Col]: Col$1,
|
|
1747
|
+
[ColGroup]: ColGroup$1,
|
|
1748
|
+
[Data]: Data$1,
|
|
1749
|
+
[Dd]: Dd$1,
|
|
1750
|
+
[Defs]: Defs$1,
|
|
1751
|
+
[Del]: Del$1,
|
|
1752
|
+
[Div]: Div$1,
|
|
1753
|
+
[Dl]: Dl$1,
|
|
1754
|
+
[Dt]: Dt$1,
|
|
1755
|
+
[Ellipse]: Ellipse$1,
|
|
1756
|
+
[Em]: Em$1,
|
|
1757
|
+
[Figcaption]: Figcaption$1,
|
|
1758
|
+
[Figure]: Figure$1,
|
|
1759
|
+
[Footer]: Footer$1,
|
|
1760
|
+
[Form]: Form$1,
|
|
1761
|
+
[G]: G$1,
|
|
1762
|
+
[H1]: H1$1,
|
|
1763
|
+
[H2]: H2$1,
|
|
1764
|
+
[H3]: H3$1,
|
|
1765
|
+
[H4]: H4$1,
|
|
1766
|
+
[H5]: H5$1,
|
|
1767
|
+
[H6]: H6$1,
|
|
1768
|
+
[Head]: Head$1,
|
|
1769
|
+
[Header]: Header$1,
|
|
1770
|
+
[Hr]: Hr$1,
|
|
1771
|
+
[Html]: Html$1,
|
|
1772
|
+
[I]: I$1,
|
|
1773
|
+
[Iframe]: Iframe$1,
|
|
1774
|
+
[Img]: Img$1,
|
|
1775
|
+
[Input]: Input$1,
|
|
1776
|
+
[Ins]: Ins$1,
|
|
1777
|
+
[Kbd]: Kbd$1,
|
|
1778
|
+
[Label]: Label$1,
|
|
1779
|
+
[Li]: Li$1,
|
|
1780
|
+
[Line]: Line$1,
|
|
1781
|
+
[Main]: Main$1,
|
|
1782
|
+
[Meta]: Meta$1,
|
|
1783
|
+
[Nav]: Nav$1,
|
|
1784
|
+
[Ol]: Ol$1,
|
|
1785
|
+
[Option]: Option$1,
|
|
1786
|
+
[P]: P$1,
|
|
1787
|
+
[Path]: Path$1,
|
|
1788
|
+
[Polygon]: Polygon$1,
|
|
1789
|
+
[Polyline]: Polyline$1,
|
|
1790
|
+
[Pre]: Pre$1,
|
|
1791
|
+
[Quote]: Quote$1,
|
|
1792
|
+
[Rect]: Rect$1,
|
|
1793
|
+
[Search]: Search$1,
|
|
1794
|
+
[Section]: Section$1,
|
|
1795
|
+
[Select]: Select$1,
|
|
1796
|
+
[Span]: Span$1,
|
|
1797
|
+
[Strong]: Strong$1,
|
|
1798
|
+
[Style]: Style$1,
|
|
1799
|
+
[Svg]: Svg$1,
|
|
1800
|
+
[Table]: Table$1,
|
|
1801
|
+
[TBody]: TBody$1,
|
|
1802
|
+
[Td]: Td$1,
|
|
1803
|
+
[TextArea]: TextArea$1,
|
|
1804
|
+
[Tfoot]: Tfoot$1,
|
|
1805
|
+
[Th]: Th$1,
|
|
1806
|
+
[THead]: THead$1,
|
|
1807
|
+
[Time]: Time$1,
|
|
1808
|
+
[Title]: Title$1,
|
|
1809
|
+
[Tr]: Tr$1,
|
|
1810
|
+
[Ul]: Ul$1,
|
|
1811
|
+
[Use]: Use$1,
|
|
1812
|
+
[Video]: Video$1
|
|
1813
|
+
};
|
|
1814
|
+
const getElementTag$1 = type => {
|
|
1815
|
+
const elementTag = elementTagMap[type];
|
|
1816
|
+
if (elementTag) {
|
|
1817
|
+
return elementTag;
|
|
1818
|
+
}
|
|
1819
|
+
throw new Error(`element tag not found ${type}`);
|
|
1820
|
+
};
|
|
1821
|
+
|
|
1822
|
+
const ElementTagMap = {
|
|
1823
|
+
__proto__: null,
|
|
1824
|
+
getElementTag: getElementTag$1
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
const {
|
|
1828
|
+
getElementTag
|
|
1829
|
+
} = ElementTagMap;
|
|
1830
|
+
|
|
1831
|
+
const instances = Object.create(null);
|
|
1832
|
+
const get$2 = viewletId => {
|
|
1833
|
+
return instances[viewletId];
|
|
1834
|
+
};
|
|
1835
|
+
const set$2 = (viewletId, instance) => {
|
|
1836
|
+
instances[viewletId] = instance;
|
|
1837
|
+
};
|
|
1838
|
+
|
|
1839
|
+
const getEventListenerOptions = (eventName, value) => {
|
|
1840
|
+
if (value.passive) {
|
|
1841
|
+
return {
|
|
1842
|
+
passive: true
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
if (value.capture) {
|
|
1846
|
+
return {
|
|
1847
|
+
capture: true
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
switch (eventName) {
|
|
1851
|
+
case 'wheel':
|
|
1852
|
+
return {
|
|
1853
|
+
passive: true
|
|
1854
|
+
};
|
|
1855
|
+
default:
|
|
1856
|
+
return undefined;
|
|
1857
|
+
}
|
|
1858
|
+
};
|
|
1859
|
+
|
|
1860
|
+
const cache = new Map();
|
|
1861
|
+
const has = listener => {
|
|
1862
|
+
return cache.has(listener);
|
|
1863
|
+
};
|
|
1864
|
+
const set$1 = (listener, value) => {
|
|
1865
|
+
cache.set(listener, value);
|
|
1866
|
+
};
|
|
1867
|
+
const get$1 = listener => {
|
|
1868
|
+
return cache.get(listener);
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1871
|
+
const getWrappedListener = (listener, returnValue) => {
|
|
1872
|
+
if (!returnValue) {
|
|
1873
|
+
return listener;
|
|
1874
|
+
}
|
|
1875
|
+
if (!has(listener)) {
|
|
1876
|
+
const wrapped = event => {
|
|
1877
|
+
const uid = getComponentUidFromEvent(event);
|
|
1878
|
+
const result = listener(event);
|
|
1879
|
+
// TODO check for empty array by value
|
|
1880
|
+
if (result.length === 0) {
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
const ipc = getIpc();
|
|
1884
|
+
ipc.send('Viewlet.executeViewletCommand', uid, ...result);
|
|
1885
|
+
};
|
|
1886
|
+
nameAnonymousFunction(wrapped, listener.name);
|
|
1887
|
+
set$1(listener, wrapped);
|
|
1888
|
+
}
|
|
1889
|
+
return get$1(listener);
|
|
1890
|
+
};
|
|
1891
|
+
|
|
1892
|
+
const attachedListeners = new WeakMap();
|
|
1893
|
+
const getOptions = fn => {
|
|
1894
|
+
if (fn.passive) {
|
|
1895
|
+
return {
|
|
1896
|
+
passive: true
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
if (fn.capture) {
|
|
1900
|
+
return {
|
|
1901
|
+
capture: true
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
return undefined;
|
|
1905
|
+
};
|
|
1906
|
+
const attachEvent = ($Node, eventMap, key, value, newEventMap) => {
|
|
1907
|
+
const keyLower = key.toLowerCase();
|
|
1908
|
+
const listenersByEvent = attachedListeners.get($Node) || new Map();
|
|
1909
|
+
const previous = listenersByEvent.get(keyLower);
|
|
1910
|
+
if (previous) {
|
|
1911
|
+
$Node.removeEventListener(keyLower, previous.listener, previous.options);
|
|
1912
|
+
}
|
|
1913
|
+
const fn = newEventMap?.[value];
|
|
1914
|
+
if (fn) {
|
|
1915
|
+
const options = getOptions(fn);
|
|
1916
|
+
// TODO support event listener options
|
|
1917
|
+
$Node.addEventListener(keyLower, fn, options);
|
|
1918
|
+
listenersByEvent.set(keyLower, {
|
|
1919
|
+
listener: fn,
|
|
1920
|
+
options
|
|
1921
|
+
});
|
|
1922
|
+
attachedListeners.set($Node, listenersByEvent);
|
|
1923
|
+
return;
|
|
1924
|
+
}
|
|
1925
|
+
const listener = eventMap[value];
|
|
1926
|
+
if (!listener) {
|
|
1927
|
+
console.warn('listener not found', value);
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
const options = getEventListenerOptions(key, value);
|
|
1931
|
+
const wrapped = getWrappedListener(listener, eventMap.returnValue);
|
|
1932
|
+
$Node.addEventListener(keyLower, wrapped, options);
|
|
1933
|
+
listenersByEvent.set(keyLower, {
|
|
1934
|
+
listener: wrapped,
|
|
1935
|
+
options
|
|
1936
|
+
});
|
|
1937
|
+
attachedListeners.set($Node, listenersByEvent);
|
|
1938
|
+
};
|
|
1939
|
+
const detachEvent = ($Node, key) => {
|
|
1940
|
+
const keyLower = key.toLowerCase();
|
|
1941
|
+
const listenersByEvent = attachedListeners.get($Node);
|
|
1942
|
+
const previous = listenersByEvent?.get(keyLower);
|
|
1943
|
+
if (!previous) {
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
$Node.removeEventListener(keyLower, previous.listener, previous.options);
|
|
1947
|
+
listenersByEvent?.delete(keyLower);
|
|
1948
|
+
};
|
|
1949
|
+
|
|
1950
|
+
const toCamelCase = key => {
|
|
1951
|
+
let camelCaseKey = '';
|
|
1952
|
+
let shouldUpperCase = false;
|
|
1953
|
+
for (const char of key) {
|
|
1954
|
+
if (char === '-') {
|
|
1955
|
+
shouldUpperCase = true;
|
|
1956
|
+
continue;
|
|
1957
|
+
}
|
|
1958
|
+
camelCaseKey += shouldUpperCase ? char.toUpperCase() : char;
|
|
1959
|
+
shouldUpperCase = false;
|
|
1960
|
+
}
|
|
1961
|
+
return camelCaseKey;
|
|
1962
|
+
};
|
|
1963
|
+
const setStyle = ($Element, styleString) => {
|
|
1964
|
+
if (typeof styleString !== 'string') {
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
for (const declaration of styleString.split(';')) {
|
|
1968
|
+
const colonIndex = declaration.indexOf(':');
|
|
1969
|
+
if (colonIndex === -1) {
|
|
1970
|
+
continue;
|
|
1971
|
+
}
|
|
1972
|
+
const key = declaration.slice(0, colonIndex).trim();
|
|
1973
|
+
const value = declaration.slice(colonIndex + 1).trim();
|
|
1974
|
+
if (!key || !value) {
|
|
1975
|
+
continue;
|
|
1976
|
+
}
|
|
1977
|
+
if (key.startsWith('--')) {
|
|
1978
|
+
$Element.style.setProperty(key, value);
|
|
1979
|
+
continue;
|
|
1980
|
+
}
|
|
1981
|
+
const camelCaseKey = toCamelCase(key);
|
|
1982
|
+
$Element.style[camelCaseKey] = value;
|
|
1983
|
+
}
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
const removedAttributeProps = new Map([['ariaActivedescendant', 'aria-activedescendant'], ['ariaControls', 'aria-controls'], ['ariaDescribedBy', 'aria-describedby'], ['ariaInvalid', 'aria-invalid'], ['ariaLabelledBy', 'aria-labelledby'], ['ariaOwns', 'aria-owns'], ['className', 'class'], ['htmlFor', 'for'], ['inputType', 'type']]);
|
|
1987
|
+
const pixelStyleProps = new Set(['height', 'left', 'marginTop', 'paddingLeft', 'paddingRight', 'top', 'width']);
|
|
1988
|
+
const eventProps = new Set(['onBlur', 'onChange', 'onClick', 'onContextMenu', 'onBeforeInput', 'onDblClick', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDragStart', 'onDrop', 'onError', 'onFocus', 'onFocusIn', 'onFocusOut', 'onInput', 'onKeydown', 'onKeyDown', 'onKeyUp', 'onLoadedData', 'onMouseDown', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onPointerDown', 'onPointerMove', 'onPointerOut', 'onPointerOver', 'onScroll', 'onSelectionChange', 'onSubmit', 'onTimeUpdate', 'onWheel']);
|
|
1989
|
+
const setOptionalAttribute = ($Element, attributeName, value) => {
|
|
1990
|
+
if (value) {
|
|
1991
|
+
$Element.setAttribute(attributeName, value);
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
$Element.removeAttribute(attributeName);
|
|
1995
|
+
};
|
|
1996
|
+
const setDimension = ($Element, key, value) => {
|
|
1997
|
+
if ($Element instanceof HTMLImageElement) {
|
|
1998
|
+
$Element[key] = value;
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
2001
|
+
$Element.style[key] = typeof value === 'number' ? `${value}px` : value;
|
|
2002
|
+
};
|
|
2003
|
+
const setPixelStyle = ($Element, key, value) => {
|
|
2004
|
+
$Element.style[key] = typeof value === 'number' ? `${value}px` : value;
|
|
2005
|
+
};
|
|
2006
|
+
const setEventProp = ($Element, key, value, eventMap, newEventMap) => {
|
|
2007
|
+
if (!eventMap || !value) {
|
|
2008
|
+
return;
|
|
2009
|
+
}
|
|
2010
|
+
const eventName = key.slice(2).toLowerCase();
|
|
2011
|
+
attachEvent($Element, eventMap, eventName, value, newEventMap);
|
|
2012
|
+
};
|
|
2013
|
+
const removeProp = ($Element, key) => {
|
|
2014
|
+
if (eventProps.has(key)) {
|
|
2015
|
+
const eventName = key.slice(2).toLowerCase();
|
|
2016
|
+
detachEvent($Element, eventName);
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
if ((key === 'height' || key === 'width') && $Element instanceof HTMLImageElement) {
|
|
2020
|
+
$Element.removeAttribute(key);
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
if (pixelStyleProps.has(key)) {
|
|
2024
|
+
$Element.style[key] = '';
|
|
2025
|
+
return;
|
|
2026
|
+
}
|
|
2027
|
+
const attributeName = removedAttributeProps.get(key) || key;
|
|
2028
|
+
$Element.removeAttribute(attributeName);
|
|
2029
|
+
};
|
|
2030
|
+
const setProp = ($Element, key, value, eventMap, newEventMap) => {
|
|
2031
|
+
if (key.startsWith('aria-')) {
|
|
2032
|
+
$Element.setAttribute(key, String(value));
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
switch (key) {
|
|
2036
|
+
case 'ariaActivedescendant':
|
|
2037
|
+
setOptionalAttribute($Element, 'aria-activedescendant', value);
|
|
2038
|
+
return;
|
|
2039
|
+
case 'ariaControls':
|
|
2040
|
+
$Element.setAttribute('aria-controls', value);
|
|
2041
|
+
return;
|
|
2042
|
+
case 'ariaDescribedBy':
|
|
2043
|
+
$Element.setAttribute('aria-describedby', value);
|
|
2044
|
+
return;
|
|
2045
|
+
case 'ariaInvalid':
|
|
2046
|
+
$Element.setAttribute('aria-invalid', value);
|
|
2047
|
+
return;
|
|
2048
|
+
case 'ariaLabelledBy':
|
|
2049
|
+
$Element.setAttribute('aria-labelledby', value);
|
|
2050
|
+
return;
|
|
2051
|
+
case 'ariaOwns':
|
|
2052
|
+
setOptionalAttribute($Element, 'aria-owns', value);
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
if (key === 'height' || key === 'width') {
|
|
2056
|
+
setDimension($Element, key, value);
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
if (key === 'id') {
|
|
2060
|
+
if (value) {
|
|
2061
|
+
$Element[key] = value;
|
|
2062
|
+
} else {
|
|
2063
|
+
$Element.removeAttribute(key);
|
|
2064
|
+
}
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
if (key === 'inputType') {
|
|
2068
|
+
// @ts-ignore
|
|
2069
|
+
$Element.type = value;
|
|
2070
|
+
return;
|
|
2071
|
+
}
|
|
2072
|
+
if (pixelStyleProps.has(key)) {
|
|
2073
|
+
setPixelStyle($Element, key, value);
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
if (key === 'maskImage') {
|
|
2077
|
+
$Element.style.maskImage = `url('${value}')`;
|
|
2078
|
+
$Element.style.webkitMaskImage = `url('${value}')`;
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
if (eventProps.has(key)) {
|
|
2082
|
+
setEventProp($Element, key, value, eventMap, newEventMap);
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
if (key === 'style') {
|
|
2086
|
+
setStyle($Element, value);
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
if (key === 'translate') {
|
|
2090
|
+
$Element.style[key] = value;
|
|
2091
|
+
return;
|
|
2092
|
+
}
|
|
2093
|
+
if (key.startsWith('data-')) {
|
|
2094
|
+
$Element.dataset[key.slice('data-'.length)] = value;
|
|
2095
|
+
return;
|
|
2096
|
+
}
|
|
2097
|
+
$Element[key] = value;
|
|
2098
|
+
};
|
|
2099
|
+
|
|
2100
|
+
const setProps = ($Element, props, eventMap, newEventMap) => {
|
|
2101
|
+
for (const key in props) {
|
|
2102
|
+
if (key === 'childCount' || key === 'type') {
|
|
2103
|
+
continue;
|
|
2104
|
+
}
|
|
2105
|
+
setProp($Element, key, props[key], eventMap, newEventMap);
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
|
|
2109
|
+
const {
|
|
2110
|
+
Text,
|
|
2111
|
+
Reference} = VirtualDomElements;
|
|
2112
|
+
|
|
2113
|
+
const renderDomTextNode = element => {
|
|
2114
|
+
return document.createTextNode(element.text);
|
|
2115
|
+
};
|
|
2116
|
+
const renderDomElement = (element, eventMap, newEventMap) => {
|
|
2117
|
+
const tag = getElementTag(element.type);
|
|
2118
|
+
const $Element = document.createElement(tag);
|
|
2119
|
+
setProps($Element, element, eventMap, newEventMap);
|
|
2120
|
+
return $Element;
|
|
2121
|
+
};
|
|
2122
|
+
const renderReferenceNode = (element, eventMap, newEventMap) => {
|
|
2123
|
+
const instance = get$2(element.uid);
|
|
2124
|
+
if (!instance || !instance.state) {
|
|
2125
|
+
return document.createTextNode('Reference node not found');
|
|
2126
|
+
}
|
|
2127
|
+
const $Node = instance.state.$Viewlet;
|
|
2128
|
+
const props = Object.fromEntries(Object.entries(element).filter(([key]) => key !== 'uid'));
|
|
2129
|
+
setProps($Node, props, eventMap, newEventMap);
|
|
2130
|
+
return $Node;
|
|
2131
|
+
};
|
|
2132
|
+
const render$2 = (element, eventMap, newEventMap) => {
|
|
2133
|
+
switch (element.type) {
|
|
2134
|
+
case Reference:
|
|
2135
|
+
return renderReferenceNode(element, eventMap, newEventMap);
|
|
2136
|
+
case Text:
|
|
2137
|
+
return renderDomTextNode(element);
|
|
2138
|
+
default:
|
|
2139
|
+
return renderDomElement(element, eventMap, newEventMap);
|
|
2140
|
+
}
|
|
2141
|
+
};
|
|
2142
|
+
|
|
2143
|
+
const renderInternal = ($Parent, elements, eventMap, newEventMap) => {
|
|
2144
|
+
const max = elements.length - 1;
|
|
2145
|
+
let stack = [];
|
|
2146
|
+
for (let i = max; i >= 0; i--) {
|
|
2147
|
+
const element = elements[i];
|
|
2148
|
+
const $Element = render$2(element, eventMap, newEventMap);
|
|
2149
|
+
if (element.childCount > 0) {
|
|
2150
|
+
// @ts-expect-error
|
|
2151
|
+
$Element.append(...stack.slice(0, element.childCount));
|
|
2152
|
+
stack = stack.slice(element.childCount);
|
|
2153
|
+
}
|
|
2154
|
+
stack.unshift($Element);
|
|
2155
|
+
}
|
|
2156
|
+
$Parent.append(...stack);
|
|
2157
|
+
};
|
|
2158
|
+
|
|
2159
|
+
const renderInto = ($Parent, dom, eventMap = {}) => {
|
|
2160
|
+
clearNode($Parent);
|
|
2161
|
+
renderInternal($Parent, dom, eventMap);
|
|
2162
|
+
};
|
|
2163
|
+
/**
|
|
2164
|
+
*
|
|
2165
|
+
* @param {any[]} elements
|
|
2166
|
+
* @returns
|
|
2167
|
+
*/
|
|
2168
|
+
const render$1 = (elements, eventMap = {}, newEventMap = {}) => {
|
|
2169
|
+
const $Root = document.createElement('div');
|
|
2170
|
+
renderInternal($Root, elements, eventMap, newEventMap);
|
|
2171
|
+
return $Root;
|
|
2172
|
+
};
|
|
2173
|
+
|
|
2174
|
+
const setText$1 = ($Element, value) => {
|
|
2175
|
+
$Element.nodeValue = value;
|
|
2176
|
+
};
|
|
2177
|
+
const removeChild = ($Element, index) => {
|
|
2178
|
+
const $Child = $Element.childNodes[index];
|
|
2179
|
+
if ($Child) {
|
|
2180
|
+
$Child.remove();
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
const add = ($Element, nodes, eventMap = {}) => {
|
|
2184
|
+
renderInternal($Element, nodes, eventMap, eventMap);
|
|
2185
|
+
};
|
|
2186
|
+
const replace = ($Element, nodes, eventMap = {}) => {
|
|
2187
|
+
// Create a temporary container to render the new nodes
|
|
2188
|
+
const $Temp = document.createElement('div');
|
|
2189
|
+
renderInternal($Temp, nodes, eventMap, eventMap);
|
|
2190
|
+
// Replace the current element with the new node(s)
|
|
2191
|
+
const $NewNode = $Temp.firstChild;
|
|
2192
|
+
if (!$NewNode) {
|
|
2193
|
+
// No node was created, just remove the old element
|
|
2194
|
+
$Element.remove();
|
|
2195
|
+
return $Element;
|
|
2196
|
+
}
|
|
2197
|
+
$Element.replaceWith($NewNode);
|
|
2198
|
+
return $NewNode;
|
|
2199
|
+
};
|
|
2200
|
+
|
|
2201
|
+
const SetText = 1;
|
|
2202
|
+
const Replace = 2;
|
|
2203
|
+
const SetAttribute = 3;
|
|
2204
|
+
const RemoveAttribute = 4;
|
|
2205
|
+
const Add = 6;
|
|
2206
|
+
const NavigateChild = 7;
|
|
2207
|
+
const NavigateParent = 8;
|
|
2208
|
+
const RemoveChild = 9;
|
|
2209
|
+
const NavigateSibling = 10;
|
|
2210
|
+
const SetReferenceNodeUid = 11;
|
|
2211
|
+
|
|
2212
|
+
const handleNavigateChild = (state, patches, patchIndex) => {
|
|
2213
|
+
const patch = patches[patchIndex];
|
|
2214
|
+
const $Children = state.current.childNodes;
|
|
2215
|
+
const $Child = $Children[patch.index];
|
|
2216
|
+
if ($Child) {
|
|
2217
|
+
state.current = $Child;
|
|
2218
|
+
return true;
|
|
2219
|
+
}
|
|
2220
|
+
const nextPatch = patches[patchIndex + 1];
|
|
2221
|
+
if (nextPatch && (nextPatch.type === Replace || nextPatch.type === SetReferenceNodeUid) && patch.index === $Children.length) {
|
|
2222
|
+
const $Placeholder = document.createComment('virtual-dom-placeholder');
|
|
2223
|
+
state.current.append($Placeholder);
|
|
2224
|
+
state.current = $Placeholder;
|
|
2225
|
+
return true;
|
|
2226
|
+
}
|
|
2227
|
+
console.error('Cannot navigate to child: child not found at index', {
|
|
2228
|
+
$Current: state.current,
|
|
2229
|
+
index: patch.index,
|
|
2230
|
+
childCount: $Children.length
|
|
2231
|
+
});
|
|
2232
|
+
return false;
|
|
2233
|
+
};
|
|
2234
|
+
const handleNavigateParent = state => {
|
|
2235
|
+
const $Parent = state.current.parentNode;
|
|
2236
|
+
if (!$Parent) {
|
|
2237
|
+
console.error('Cannot navigate to parent: current node has no parent', {
|
|
2238
|
+
$Current: state.current
|
|
2239
|
+
});
|
|
2240
|
+
return false;
|
|
2241
|
+
}
|
|
2242
|
+
state.current = $Parent;
|
|
2243
|
+
return true;
|
|
2244
|
+
};
|
|
2245
|
+
const handleNavigateSibling = (state, patch, $Element, patchIndex) => {
|
|
2246
|
+
const $Parent = state.current.parentNode;
|
|
2247
|
+
if (!$Parent) {
|
|
2248
|
+
console.error('Cannot navigate to sibling: current node has no parent', {
|
|
2249
|
+
patchIndex
|
|
2250
|
+
});
|
|
2251
|
+
return false;
|
|
2252
|
+
}
|
|
2253
|
+
let $Sibling = $Parent.childNodes[patch.index];
|
|
2254
|
+
if (!$Sibling && !state.hasAppliedMutation && state.current !== $Element) {
|
|
2255
|
+
$Sibling = $Element.childNodes[patch.index];
|
|
2256
|
+
}
|
|
2257
|
+
if (!$Sibling) {
|
|
2258
|
+
console.error('Cannot navigate to sibling: sibling not found at index', {
|
|
2259
|
+
$Parent,
|
|
2260
|
+
index: patch.index,
|
|
2261
|
+
childCount: $Parent.childNodes.length
|
|
2262
|
+
});
|
|
2263
|
+
return false;
|
|
2264
|
+
}
|
|
2265
|
+
state.current = $Sibling;
|
|
2266
|
+
return true;
|
|
2267
|
+
};
|
|
2268
|
+
const handleSetReferenceNodeUid = (state, patch) => {
|
|
2269
|
+
const instance = get$2(patch.uid);
|
|
2270
|
+
if (!instance || !instance.state) {
|
|
2271
|
+
console.error('Cannot set reference node uid: instance not found', {
|
|
2272
|
+
uid: patch.uid
|
|
2273
|
+
});
|
|
2274
|
+
return false;
|
|
2275
|
+
}
|
|
2276
|
+
const $NewNode = instance.state.$Viewlet;
|
|
2277
|
+
// @ts-ignore
|
|
2278
|
+
state.current.replaceWith($NewNode);
|
|
2279
|
+
state.current = $NewNode;
|
|
2280
|
+
state.hasAppliedMutation = true;
|
|
2281
|
+
return true;
|
|
2282
|
+
};
|
|
2283
|
+
const handleNavigationPatch = (state, patch, patches, patchIndex, $Element) => {
|
|
2284
|
+
switch (patch.type) {
|
|
2285
|
+
case NavigateChild:
|
|
2286
|
+
return handleNavigateChild(state, patches, patchIndex);
|
|
2287
|
+
case NavigateParent:
|
|
2288
|
+
return handleNavigateParent(state);
|
|
2289
|
+
case NavigateSibling:
|
|
2290
|
+
return handleNavigateSibling(state, patch, $Element, patchIndex);
|
|
2291
|
+
default:
|
|
2292
|
+
return true;
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
const applyMutationPatch = (state, patch, events) => {
|
|
2296
|
+
switch (patch.type) {
|
|
2297
|
+
case Add:
|
|
2298
|
+
add(state.current, patch.nodes, events);
|
|
2299
|
+
state.hasAppliedMutation = true;
|
|
2300
|
+
break;
|
|
2301
|
+
case RemoveAttribute:
|
|
2302
|
+
removeProp(state.current, patch.key);
|
|
2303
|
+
state.hasAppliedMutation = true;
|
|
2304
|
+
break;
|
|
2305
|
+
case RemoveChild:
|
|
2306
|
+
removeChild(state.current, patch.index);
|
|
2307
|
+
state.hasAppliedMutation = true;
|
|
2308
|
+
break;
|
|
2309
|
+
case Replace:
|
|
2310
|
+
state.current = replace(state.current, patch.nodes, events);
|
|
2311
|
+
state.hasAppliedMutation = true;
|
|
2312
|
+
break;
|
|
2313
|
+
case SetAttribute:
|
|
2314
|
+
setProp(state.current, patch.key, patch.value, events);
|
|
2315
|
+
state.hasAppliedMutation = true;
|
|
2316
|
+
break;
|
|
2317
|
+
case SetText:
|
|
2318
|
+
setText$1(state.current, patch.value);
|
|
2319
|
+
state.hasAppliedMutation = true;
|
|
2320
|
+
break;
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
const applyPatch = ($Element, patches, eventMap = {}, id = 0) => {
|
|
2324
|
+
const events = getEventListenerMap(id) || eventMap;
|
|
2325
|
+
const state = {
|
|
2326
|
+
current: $Element,
|
|
2327
|
+
hasAppliedMutation: false
|
|
2328
|
+
};
|
|
2329
|
+
for (let patchIndex = 0; patchIndex < patches.length; patchIndex++) {
|
|
2330
|
+
const patch = patches[patchIndex];
|
|
2331
|
+
try {
|
|
2332
|
+
if (!handleNavigationPatch(state, patch, patches, patchIndex, $Element)) {
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
if (patch.type === SetReferenceNodeUid) {
|
|
2336
|
+
if (!handleSetReferenceNodeUid(state, patch)) {
|
|
2337
|
+
return;
|
|
2338
|
+
}
|
|
2339
|
+
continue;
|
|
2340
|
+
}
|
|
2341
|
+
applyMutationPatch(state, patch, events);
|
|
2342
|
+
} catch (error) {
|
|
2343
|
+
console.error('Error applying patch at index ' + patchIndex, patch, error);
|
|
2344
|
+
throw error;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2349
|
+
const getActiveElementInside = $Viewlet => {
|
|
2350
|
+
if (!$Viewlet) {
|
|
2351
|
+
return undefined;
|
|
2352
|
+
}
|
|
2353
|
+
const $ActiveElement = document.activeElement;
|
|
2354
|
+
if (!$ActiveElement) {
|
|
2355
|
+
return undefined;
|
|
2356
|
+
}
|
|
2357
|
+
if (!$Viewlet.contains($ActiveElement)) {
|
|
2358
|
+
return undefined;
|
|
2359
|
+
}
|
|
2360
|
+
return $ActiveElement;
|
|
2361
|
+
};
|
|
2362
|
+
|
|
2363
|
+
const queryInputs = $Viewlet => {
|
|
2364
|
+
return [...$Viewlet.querySelectorAll(':scope input, :scope textarea, :scope select')];
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
const focusElement = $Element => {
|
|
2368
|
+
$Element.focus({
|
|
2369
|
+
preventScroll: true
|
|
2370
|
+
});
|
|
2371
|
+
};
|
|
2372
|
+
const getInputMap = $Viewlet => {
|
|
2373
|
+
const $$Inputs = queryInputs($Viewlet);
|
|
2374
|
+
const inputMap = Object.create(null);
|
|
2375
|
+
for (const $Input of $$Inputs) {
|
|
2376
|
+
inputMap[$Input.name] = $Input.value;
|
|
2377
|
+
}
|
|
2378
|
+
return inputMap;
|
|
2379
|
+
};
|
|
2380
|
+
const createHiddenContainer = (activeElement, focused) => {
|
|
2381
|
+
const $Hidden = document.createElement('div');
|
|
2382
|
+
$Hidden.style.display = 'none';
|
|
2383
|
+
if (focused && activeElement && document.body) {
|
|
2384
|
+
document.body.append($Hidden);
|
|
2385
|
+
$Hidden.append(activeElement);
|
|
2386
|
+
}
|
|
2387
|
+
return $Hidden;
|
|
2388
|
+
};
|
|
2389
|
+
const restoreFocusedElement = ($Hidden, $New, focused) => {
|
|
2390
|
+
const $NewFocused = $New.querySelector(`[name="${CSS.escape(focused)}"]`);
|
|
2391
|
+
if (!$NewFocused) {
|
|
2392
|
+
return;
|
|
2393
|
+
}
|
|
2394
|
+
const $Previous = $Hidden.firstChild;
|
|
2395
|
+
if (!$Previous) {
|
|
2396
|
+
return;
|
|
2397
|
+
}
|
|
2398
|
+
$Previous.className = $NewFocused.className;
|
|
2399
|
+
$Previous.placeholder = $NewFocused.placeholder;
|
|
2400
|
+
if ($NewFocused.childNodes) {
|
|
2401
|
+
$Previous.replaceChildren(...$NewFocused.childNodes);
|
|
2402
|
+
}
|
|
2403
|
+
$NewFocused.replaceWith($Previous);
|
|
2404
|
+
};
|
|
2405
|
+
const renderWithUid = ($Viewlet, dom, eventMap, uid, inputMap, focused, $Hidden) => {
|
|
2406
|
+
const newEventMap = getEventListenerMap(uid);
|
|
2407
|
+
const $New = render$1(dom, eventMap, newEventMap).firstChild;
|
|
2408
|
+
setComponentUid($New, uid);
|
|
2409
|
+
const $$NewInputs = queryInputs($New);
|
|
2410
|
+
for (const $Input of $$NewInputs) {
|
|
2411
|
+
$Input.value = inputMap[$Input.name] || $Input.value || '';
|
|
2412
|
+
}
|
|
2413
|
+
$Viewlet.replaceWith($New);
|
|
2414
|
+
if (focused) {
|
|
2415
|
+
restoreFocusedElement($Hidden, $New, focused);
|
|
2416
|
+
}
|
|
2417
|
+
return $New;
|
|
2418
|
+
};
|
|
2419
|
+
const restoreFocus = ($Viewlet, isRootTree, isTreeFocused, focused) => {
|
|
2420
|
+
if (isRootTree) {
|
|
2421
|
+
focusElement($Viewlet);
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
if (isTreeFocused) {
|
|
2425
|
+
const $Tree = $Viewlet.querySelector(':scope [role="tree"]');
|
|
2426
|
+
if ($Tree) {
|
|
2427
|
+
// @ts-ignore
|
|
2428
|
+
focusElement($Tree);
|
|
2429
|
+
}
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
if (!focused) {
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
const $Focused = $Viewlet.querySelector(`[name="${CSS.escape(focused)}"]`);
|
|
2436
|
+
if ($Focused) {
|
|
2437
|
+
// @ts-ignore
|
|
2438
|
+
focusElement($Focused);
|
|
2439
|
+
}
|
|
2440
|
+
};
|
|
2441
|
+
const rememberFocus = ($Viewlet, dom, eventMap, uid = 0) => {
|
|
2442
|
+
startIgnore();
|
|
2443
|
+
const oldLeft = $Viewlet.style.left;
|
|
2444
|
+
const oldTop = $Viewlet.style.top;
|
|
2445
|
+
const oldWidth = $Viewlet.style.width;
|
|
2446
|
+
const oldHeight = $Viewlet.style.height;
|
|
2447
|
+
const activeElement = getActiveElementInside($Viewlet);
|
|
2448
|
+
const isTreeFocused = activeElement?.getAttribute('role') === 'tree';
|
|
2449
|
+
const isRootTree = $Viewlet.getAttribute('role') === 'tree' && activeElement === $Viewlet;
|
|
2450
|
+
const focused = activeElement?.getAttribute('name') || null;
|
|
2451
|
+
const $Hidden = createHiddenContainer(activeElement, focused);
|
|
2452
|
+
if (uid) {
|
|
2453
|
+
const numericUid = Number(uid);
|
|
2454
|
+
const inputMap = getInputMap($Viewlet);
|
|
2455
|
+
$Viewlet = renderWithUid($Viewlet, dom, eventMap, numericUid, inputMap, focused, $Hidden);
|
|
2456
|
+
}
|
|
2457
|
+
if (!uid) {
|
|
2458
|
+
renderInto($Viewlet, dom, eventMap);
|
|
2459
|
+
}
|
|
2460
|
+
$Hidden.remove();
|
|
2461
|
+
restoreFocus($Viewlet, isRootTree, isTreeFocused, focused);
|
|
2462
|
+
$Viewlet.style.top = oldTop;
|
|
2463
|
+
$Viewlet.style.left = oldLeft;
|
|
2464
|
+
$Viewlet.style.height = oldHeight;
|
|
2465
|
+
$Viewlet.style.width = oldWidth;
|
|
2466
|
+
stopIgnore();
|
|
2467
|
+
return $Viewlet;
|
|
2468
|
+
};
|
|
2469
|
+
|
|
2470
|
+
const state = {
|
|
2471
|
+
styleSheets: Object.create(null),
|
|
2472
|
+
texts: Object.create(null)
|
|
2473
|
+
};
|
|
2474
|
+
const set = (id, sheet) => {
|
|
2475
|
+
state.styleSheets[id] = sheet;
|
|
2476
|
+
};
|
|
2477
|
+
const get = id => {
|
|
2478
|
+
return state.styleSheets[id];
|
|
2479
|
+
};
|
|
2480
|
+
const setText = (id, text) => {
|
|
2481
|
+
state.texts[id] = text;
|
|
2482
|
+
};
|
|
2483
|
+
|
|
2484
|
+
const addCssStyleSheet = (id, text) => {
|
|
2485
|
+
const existing = get(id);
|
|
2486
|
+
if (existing) {
|
|
2487
|
+
existing.replaceSync(text);
|
|
2488
|
+
setText(id, text);
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
2491
|
+
const sheet = new CSSStyleSheet({});
|
|
2492
|
+
set(id, sheet);
|
|
2493
|
+
setText(id, text);
|
|
2494
|
+
sheet.replaceSync(text);
|
|
2495
|
+
document.adoptedStyleSheets.push(sheet);
|
|
2496
|
+
};
|
|
2497
|
+
|
|
2498
|
+
const ignoreCommand = () => {};
|
|
2499
|
+
const getElement = uid => {
|
|
2500
|
+
const instance = get$2(uid);
|
|
2501
|
+
const element = instance?.state?.$Viewlet;
|
|
2502
|
+
if (!(element instanceof HTMLElement)) {
|
|
2503
|
+
throw new TypeError(`Editor element ${uid} not found`);
|
|
2504
|
+
}
|
|
2505
|
+
return element;
|
|
2506
|
+
};
|
|
2507
|
+
const create = uid => {
|
|
2508
|
+
const element = document.createElement('div');
|
|
2509
|
+
setComponentUid(element, uid);
|
|
2510
|
+
set$2(uid, {
|
|
2511
|
+
factory: {},
|
|
2512
|
+
state: {
|
|
2513
|
+
$Viewlet: element
|
|
2514
|
+
}
|
|
2515
|
+
});
|
|
2516
|
+
document.body.append(element);
|
|
2517
|
+
};
|
|
2518
|
+
const dispose = uid => {
|
|
2519
|
+
getElement(uid).remove();
|
|
2520
|
+
set$2(uid, undefined);
|
|
2521
|
+
};
|
|
2522
|
+
const focusSelector = (uid, selector) => {
|
|
2523
|
+
const element = getElement(uid).querySelector(selector);
|
|
2524
|
+
element?.focus();
|
|
2525
|
+
};
|
|
2526
|
+
const setBounds = (uid, left, top, width, height) => {
|
|
2527
|
+
const element = getElement(uid);
|
|
2528
|
+
element.style.left = `${left}px`;
|
|
2529
|
+
element.style.top = `${top}px`;
|
|
2530
|
+
element.style.width = `${width}px`;
|
|
2531
|
+
element.style.height = `${height}px`;
|
|
2532
|
+
};
|
|
2533
|
+
const setPatches = (uid, patches) => {
|
|
2534
|
+
const element = getElement(uid);
|
|
2535
|
+
if (patches.length === 1 && patches[0].type === 6) {
|
|
2536
|
+
const replacement = rememberFocus(element, patches[0].nodes, {}, uid);
|
|
2537
|
+
setComponentUid(replacement, uid);
|
|
2538
|
+
const instance = get$2(uid);
|
|
2539
|
+
set$2(uid, {
|
|
2540
|
+
...instance,
|
|
2541
|
+
state: {
|
|
2542
|
+
...instance.state,
|
|
2543
|
+
$Viewlet: replacement
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
applyPatch(element, patches, {}, uid);
|
|
2549
|
+
};
|
|
2550
|
+
const setSelectionByName = (uid, name, start, end) => {
|
|
2551
|
+
const input = getElement(uid).querySelector(`[name="${CSS.escape(name)}"]`);
|
|
2552
|
+
if (!input) {
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
input.selectionStart = start;
|
|
2556
|
+
input.selectionEnd = end;
|
|
2557
|
+
};
|
|
2558
|
+
const setUid = (uid, componentUid) => {
|
|
2559
|
+
setComponentUid(getElement(uid), componentUid);
|
|
2560
|
+
};
|
|
2561
|
+
const setValueByName = (uid, name, value) => {
|
|
2562
|
+
const input = getElement(uid).querySelector(`[name="${CSS.escape(name)}"]`);
|
|
2563
|
+
if (input) {
|
|
2564
|
+
input.value = value;
|
|
2565
|
+
}
|
|
2566
|
+
};
|
|
2567
|
+
const commandHandlers = {
|
|
2568
|
+
'Viewlet.dispose': dispose,
|
|
2569
|
+
'Viewlet.focusSelector': focusSelector,
|
|
2570
|
+
'Viewlet.setAdditionalFocus': ignoreCommand,
|
|
2571
|
+
'Viewlet.setBounds': setBounds,
|
|
2572
|
+
'Viewlet.setCss': addCssStyleSheet,
|
|
2573
|
+
'Viewlet.setFocusContext': ignoreCommand,
|
|
2574
|
+
'Viewlet.setPatches': setPatches,
|
|
2575
|
+
'Viewlet.setSelectionByName': setSelectionByName,
|
|
2576
|
+
'Viewlet.setUid': setUid,
|
|
2577
|
+
'Viewlet.setValueByName': setValueByName,
|
|
2578
|
+
'Viewlet.unsetAdditionalFocus': ignoreCommand
|
|
2579
|
+
};
|
|
2580
|
+
const executeCommands = commands => {
|
|
2581
|
+
for (const [command, ...args] of commands) {
|
|
2582
|
+
const handler = commandHandlers[command];
|
|
2583
|
+
if (!handler) {
|
|
2584
|
+
throw new Error(`Unsupported editor-only render command: ${command}`);
|
|
2585
|
+
}
|
|
2586
|
+
handler(...args);
|
|
2587
|
+
}
|
|
2588
|
+
};
|
|
2589
|
+
|
|
2590
|
+
const Web = 1;
|
|
2591
|
+
const Electron = 2;
|
|
2592
|
+
const Remote = 3;
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* @returns {number}
|
|
2596
|
+
*/
|
|
2597
|
+
const getPlatform = () => {
|
|
2598
|
+
// @ts-expect-error
|
|
2599
|
+
if (typeof PLATFORM !== 'undefined') {
|
|
2600
|
+
// @ts-expect-error
|
|
2601
|
+
return PLATFORM;
|
|
2602
|
+
}
|
|
2603
|
+
// @ts-ignore
|
|
2604
|
+
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
2605
|
+
return Remote;
|
|
2606
|
+
}
|
|
2607
|
+
if (globalThis.isElectron) {
|
|
2608
|
+
return Electron;
|
|
2609
|
+
}
|
|
2610
|
+
if (typeof location !== 'undefined' && location.search === '?web') {
|
|
2611
|
+
return Web;
|
|
2612
|
+
}
|
|
2613
|
+
return Remote;
|
|
2614
|
+
};
|
|
2615
|
+
const platform = getPlatform();
|
|
2616
|
+
|
|
2617
|
+
const getAssetDir = () => {
|
|
2618
|
+
// @ts-expect-error
|
|
2619
|
+
if (typeof ASSET_DIR !== 'undefined') {
|
|
2620
|
+
// @ts-expect-error
|
|
2621
|
+
return ASSET_DIR;
|
|
2622
|
+
}
|
|
2623
|
+
if (platform === Electron) {
|
|
2624
|
+
return '../../../../..';
|
|
2625
|
+
}
|
|
2626
|
+
return '';
|
|
2627
|
+
};
|
|
2628
|
+
const assetDir = getAssetDir();
|
|
2629
|
+
|
|
2630
|
+
const getConfiguredWorkerUrl = key => {
|
|
2631
|
+
if (typeof location === 'undefined' || typeof document === 'undefined') {
|
|
2632
|
+
return '';
|
|
2633
|
+
}
|
|
2634
|
+
const configElement = document.getElementById('Config');
|
|
2635
|
+
if (!configElement) {
|
|
2636
|
+
return '';
|
|
2637
|
+
}
|
|
2638
|
+
const text = configElement.textContent;
|
|
2639
|
+
if (!text) {
|
|
2640
|
+
return '';
|
|
2641
|
+
}
|
|
2642
|
+
const config = JSON.parse(text);
|
|
2643
|
+
return config[key] || '';
|
|
2644
|
+
};
|
|
2645
|
+
|
|
2646
|
+
const getConfiguredEditorWorkerUrl = () => {
|
|
2647
|
+
return getConfiguredWorkerUrl('editorWorkerUrl');
|
|
2648
|
+
};
|
|
2649
|
+
|
|
2650
|
+
const editorWorkerUrl = getConfiguredEditorWorkerUrl() || `${assetDir}/packages/renderer-worker/node_modules/@lvce-editor/editor-worker/dist/editorWorkerMain.js`;
|
|
2651
|
+
|
|
2652
|
+
const getConfiguredSyntaxHighlightingWorkerUrl = () => {
|
|
2653
|
+
return getConfiguredWorkerUrl('syntaxHighlightingWorkerUrl');
|
|
2654
|
+
};
|
|
2655
|
+
|
|
2656
|
+
const syntaxHighlightingWorkerUrl = getConfiguredSyntaxHighlightingWorkerUrl() || `${assetDir}/packages/renderer-worker/node_modules/@lvce-editor/syntax-highlighting-worker/dist/syntaxHighlightingWorkerMain.js`;
|
|
2657
|
+
|
|
2658
|
+
const editorUid = 1;
|
|
2659
|
+
const getCharWidth = (fontFamily, fontSize, fontWeight) => {
|
|
2660
|
+
const canvas = document.createElement('canvas');
|
|
2661
|
+
const context = canvas.getContext('2d');
|
|
2662
|
+
if (!context) {
|
|
2663
|
+
return 9;
|
|
2664
|
+
}
|
|
2665
|
+
context.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
2666
|
+
return context.measureText('a').width;
|
|
2667
|
+
};
|
|
2668
|
+
const launchWorker = async (name, url, commandMap) => {
|
|
2669
|
+
const {
|
|
2670
|
+
port1,
|
|
2671
|
+
port2
|
|
2672
|
+
} = new MessageChannel();
|
|
2673
|
+
await create$2({
|
|
2674
|
+
commandMap: {},
|
|
2675
|
+
name,
|
|
2676
|
+
port: port1,
|
|
2677
|
+
url
|
|
2678
|
+
});
|
|
2679
|
+
return create$3({
|
|
2680
|
+
commandMap,
|
|
2681
|
+
messagePort: port2
|
|
2682
|
+
});
|
|
2683
|
+
};
|
|
2684
|
+
const getBounds = () => {
|
|
2685
|
+
return {
|
|
2686
|
+
height: window.innerHeight,
|
|
2687
|
+
width: window.innerWidth,
|
|
2688
|
+
x: 0,
|
|
2689
|
+
y: 0
|
|
2690
|
+
};
|
|
2691
|
+
};
|
|
2692
|
+
const getEditorMethod = command => {
|
|
2693
|
+
return command.includes('.') ? command : `Editor.${command}`;
|
|
2694
|
+
};
|
|
2695
|
+
const render = async editorRpc => {
|
|
2696
|
+
const diffResult = await editorRpc.invoke('Editor.diff2', editorUid);
|
|
2697
|
+
const commands = await editorRpc.invoke('Editor.render2', editorUid, diffResult);
|
|
2698
|
+
executeCommands(commands);
|
|
2699
|
+
};
|
|
2700
|
+
const focus = () => {
|
|
2701
|
+
const input = document.querySelector('.EditorInput textarea');
|
|
2702
|
+
input?.focus();
|
|
2703
|
+
};
|
|
2704
|
+
const markRendered = async () => {
|
|
2705
|
+
await new Promise(resolve => {
|
|
2706
|
+
requestAnimationFrame(() => {
|
|
2707
|
+
requestAnimationFrame(() => resolve());
|
|
2708
|
+
});
|
|
2709
|
+
});
|
|
2710
|
+
performance.mark('syntax-highlight-rendered');
|
|
2711
|
+
document.documentElement.dataset.renderBenchmarkReady = 'true';
|
|
2712
|
+
};
|
|
2713
|
+
const setError = error => {
|
|
2714
|
+
document.documentElement.dataset.benchmarkReady = 'error';
|
|
2715
|
+
document.body.textContent = error instanceof Error ? error.stack || error.message : String(error);
|
|
2716
|
+
};
|
|
2717
|
+
const main = async () => {
|
|
2718
|
+
document.documentElement.dataset.benchmarkStage = 'starting';
|
|
2719
|
+
try {
|
|
2720
|
+
document.documentElement.dataset.benchmarkStage = 'launching-syntax-worker';
|
|
2721
|
+
const syntaxHighlightingRpc = await launchWorker('Syntax Highlighting Worker', syntaxHighlightingWorkerUrl, {});
|
|
2722
|
+
Object.assign(commandMapRef, {
|
|
2723
|
+
'Main.handleModifiedStatusChange': () => undefined,
|
|
2724
|
+
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker': async (port, initialCommand) => {
|
|
2725
|
+
document.documentElement.dataset.benchmarkStage = 'connecting-syntax-worker';
|
|
2726
|
+
await syntaxHighlightingRpc.invokeAndTransfer(initialCommand, port);
|
|
2727
|
+
document.documentElement.dataset.benchmarkStage = 'syntax-worker-connected';
|
|
2728
|
+
}
|
|
2729
|
+
});
|
|
2730
|
+
document.documentElement.dataset.benchmarkStage = 'launching-editor-worker';
|
|
2731
|
+
const editorRpc = await launchWorker('Editor Worker', editorWorkerUrl, commandMapRef);
|
|
2732
|
+
document.documentElement.dataset.benchmarkStage = 'initializing-editor-worker';
|
|
2733
|
+
await editorRpc.invoke('Initialize.initialize', true, true);
|
|
2734
|
+
document.documentElement.dataset.benchmarkStage = 'creating-editor';
|
|
2735
|
+
const config = getEditorOnlyConfig();
|
|
2736
|
+
const fontFamily = config.fontFamily || 'monospace';
|
|
2737
|
+
const fontSize = config.fontSize || 15;
|
|
2738
|
+
const fontWeight = config.fontWeight || 400;
|
|
2739
|
+
const bounds = getBounds();
|
|
2740
|
+
await editorRpc.invoke('Editor.createStandalone', {
|
|
2741
|
+
assetDir: '',
|
|
2742
|
+
charWidth: getCharWidth(fontFamily, fontSize, fontWeight),
|
|
2743
|
+
content: config.content || '',
|
|
2744
|
+
fontFamily,
|
|
2745
|
+
fontSize,
|
|
2746
|
+
fontWeight,
|
|
2747
|
+
...bounds,
|
|
2748
|
+
id: editorUid,
|
|
2749
|
+
languageId: config.languageId || 'plaintext',
|
|
2750
|
+
letterSpacing: config.letterSpacing || 0,
|
|
2751
|
+
lineNumbers: config.lineNumbers || false,
|
|
2752
|
+
platform: Web,
|
|
2753
|
+
rowHeight: config.rowHeight || 20,
|
|
2754
|
+
tabSize: config.tabSize || 2,
|
|
2755
|
+
tokenizePath: config.tokenizePath || '',
|
|
2756
|
+
uri: config.uri || 'file:///standalone.txt'
|
|
2757
|
+
});
|
|
2758
|
+
document.documentElement.dataset.benchmarkStage = 'rendering-editor';
|
|
2759
|
+
create(editorUid);
|
|
2760
|
+
const listeners = await editorRpc.invoke('Editor.renderEventListeners');
|
|
2761
|
+
registerEventListeners(editorUid, listeners);
|
|
2762
|
+
let text = config.content || '';
|
|
2763
|
+
let pending = Promise.resolve();
|
|
2764
|
+
const executeQueued = async (previous, command, args) => {
|
|
2765
|
+
try {
|
|
2766
|
+
await previous;
|
|
2767
|
+
await editorRpc.invoke(getEditorMethod(command), editorUid, ...args);
|
|
2768
|
+
await render(editorRpc);
|
|
2769
|
+
text = await editorRpc.invoke('Editor.getText', editorUid);
|
|
2770
|
+
} catch (error) {
|
|
2771
|
+
setError(error);
|
|
2772
|
+
}
|
|
2773
|
+
};
|
|
2774
|
+
const execute = (command, ...args) => {
|
|
2775
|
+
pending = executeQueued(pending, command, args);
|
|
2776
|
+
};
|
|
2777
|
+
setIpc({
|
|
2778
|
+
send(method, uid, command, ...args) {
|
|
2779
|
+
if (method !== 'Viewlet.executeViewletCommand' || uid !== editorUid) {
|
|
2780
|
+
throw new Error(`Unsupported editor-only event: ${method}`);
|
|
2781
|
+
}
|
|
2782
|
+
execute(command, ...args);
|
|
2783
|
+
}
|
|
2784
|
+
});
|
|
2785
|
+
document.addEventListener('keydown', event => {
|
|
2786
|
+
const command = getEditorCommand(event);
|
|
2787
|
+
if (!command) {
|
|
2788
|
+
return;
|
|
2789
|
+
}
|
|
2790
|
+
event.preventDefault();
|
|
2791
|
+
execute(command);
|
|
2792
|
+
}, {
|
|
2793
|
+
capture: true
|
|
2794
|
+
});
|
|
2795
|
+
window.addEventListener('resize', () => {
|
|
2796
|
+
execute('resize', getBounds());
|
|
2797
|
+
});
|
|
2798
|
+
await render(editorRpc);
|
|
2799
|
+
Object.defineProperty(window, '__typingBenchmark', {
|
|
2800
|
+
configurable: true,
|
|
2801
|
+
value: {
|
|
2802
|
+
focus,
|
|
2803
|
+
getText: () => text
|
|
2804
|
+
}
|
|
2805
|
+
});
|
|
2806
|
+
focus();
|
|
2807
|
+
await markRendered();
|
|
2808
|
+
document.documentElement.dataset.benchmarkReady = 'true';
|
|
2809
|
+
document.documentElement.dataset.benchmarkStage = 'ready';
|
|
2810
|
+
} catch (error) {
|
|
2811
|
+
setError(error);
|
|
2812
|
+
}
|
|
2813
|
+
};
|
|
2814
|
+
|
|
2815
|
+
main();
|