@lvce-editor/title-bar-worker 1.0.0 → 1.2.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/titleBarWorkerMain.js +2554 -711
- package/package.json +6 -7
|
@@ -1,3 +1,444 @@
|
|
|
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
|
+
class AssertionError extends Error {
|
|
58
|
+
constructor(message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = 'AssertionError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const getType = value => {
|
|
64
|
+
switch (typeof value) {
|
|
65
|
+
case 'number':
|
|
66
|
+
return 'number';
|
|
67
|
+
case 'function':
|
|
68
|
+
return 'function';
|
|
69
|
+
case 'string':
|
|
70
|
+
return 'string';
|
|
71
|
+
case 'object':
|
|
72
|
+
if (value === null) {
|
|
73
|
+
return 'null';
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
return 'array';
|
|
77
|
+
}
|
|
78
|
+
return 'object';
|
|
79
|
+
case 'boolean':
|
|
80
|
+
return 'boolean';
|
|
81
|
+
default:
|
|
82
|
+
return 'unknown';
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const object = value => {
|
|
86
|
+
const type = getType(value);
|
|
87
|
+
if (type !== 'object') {
|
|
88
|
+
throw new AssertionError('expected value to be of type object');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const number = value => {
|
|
92
|
+
const type = getType(value);
|
|
93
|
+
if (type !== 'number') {
|
|
94
|
+
throw new AssertionError('expected value to be of type number');
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const array = value => {
|
|
98
|
+
const type = getType(value);
|
|
99
|
+
if (type !== 'array') {
|
|
100
|
+
throw new AssertionError('expected value to be of type array');
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const string = value => {
|
|
104
|
+
const type = getType(value);
|
|
105
|
+
if (type !== 'string') {
|
|
106
|
+
throw new AssertionError('expected value to be of type string');
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const boolean = value => {
|
|
110
|
+
const type = getType(value);
|
|
111
|
+
if (type !== 'boolean') {
|
|
112
|
+
throw new AssertionError('expected value to be of type boolean');
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const isMessagePort = value => {
|
|
117
|
+
return value && value instanceof MessagePort;
|
|
118
|
+
};
|
|
119
|
+
const isMessagePortMain = value => {
|
|
120
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
121
|
+
};
|
|
122
|
+
const isOffscreenCanvas = value => {
|
|
123
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
124
|
+
};
|
|
125
|
+
const isInstanceOf = (value, constructorName) => {
|
|
126
|
+
return value?.constructor?.name === constructorName;
|
|
127
|
+
};
|
|
128
|
+
const isSocket = value => {
|
|
129
|
+
return isInstanceOf(value, 'Socket');
|
|
130
|
+
};
|
|
131
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
132
|
+
const isTransferrable = value => {
|
|
133
|
+
for (const fn of transferrables) {
|
|
134
|
+
if (fn(value)) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
};
|
|
140
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
141
|
+
if (!value) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (isTransferrable(value)) {
|
|
145
|
+
transferrables.push(value);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (Array.isArray(value)) {
|
|
149
|
+
for (const item of value) {
|
|
150
|
+
walkValue(item, transferrables, isTransferrable);
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === 'object') {
|
|
155
|
+
for (const property of Object.values(value)) {
|
|
156
|
+
walkValue(property, transferrables, isTransferrable);
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const getTransferrables = value => {
|
|
162
|
+
const transferrables = [];
|
|
163
|
+
walkValue(value, transferrables, isTransferrable);
|
|
164
|
+
return transferrables;
|
|
165
|
+
};
|
|
166
|
+
const attachEvents = that => {
|
|
167
|
+
const handleMessage = (...args) => {
|
|
168
|
+
const data = that.getData(...args);
|
|
169
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
170
|
+
data
|
|
171
|
+
}));
|
|
172
|
+
};
|
|
173
|
+
that.onMessage(handleMessage);
|
|
174
|
+
const handleClose = event => {
|
|
175
|
+
that.dispatchEvent(new Event('close'));
|
|
176
|
+
};
|
|
177
|
+
that.onClose(handleClose);
|
|
178
|
+
};
|
|
179
|
+
class Ipc extends EventTarget {
|
|
180
|
+
constructor(rawIpc) {
|
|
181
|
+
super();
|
|
182
|
+
this._rawIpc = rawIpc;
|
|
183
|
+
attachEvents(this);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
187
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
188
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
189
|
+
const NewLine$1 = '\n';
|
|
190
|
+
const joinLines$1 = lines => {
|
|
191
|
+
return lines.join(NewLine$1);
|
|
192
|
+
};
|
|
193
|
+
const RE_AT = /^\s+at/;
|
|
194
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
195
|
+
const isNormalStackLine = line => {
|
|
196
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
197
|
+
};
|
|
198
|
+
const getDetails = lines => {
|
|
199
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
200
|
+
if (index === -1) {
|
|
201
|
+
return {
|
|
202
|
+
actualMessage: joinLines$1(lines),
|
|
203
|
+
rest: []
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
let lastIndex = index - 1;
|
|
207
|
+
while (++lastIndex < lines.length) {
|
|
208
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
actualMessage: lines[index - 1],
|
|
214
|
+
rest: lines.slice(index, lastIndex)
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
const splitLines$1 = lines => {
|
|
218
|
+
return lines.split(NewLine$1);
|
|
219
|
+
};
|
|
220
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
221
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
222
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
223
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
224
|
+
};
|
|
225
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
226
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
227
|
+
};
|
|
228
|
+
const getMessageCodeBlock = stderr => {
|
|
229
|
+
const lines = splitLines$1(stderr);
|
|
230
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
231
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
232
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
233
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
234
|
+
return relevantMessage;
|
|
235
|
+
};
|
|
236
|
+
const isModuleNotFoundMessage = line => {
|
|
237
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
238
|
+
};
|
|
239
|
+
const getModuleNotFoundError = stderr => {
|
|
240
|
+
const lines = splitLines$1(stderr);
|
|
241
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
242
|
+
const message = lines[messageIndex];
|
|
243
|
+
return {
|
|
244
|
+
message,
|
|
245
|
+
code: ERR_MODULE_NOT_FOUND
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
const isModuleNotFoundError = stderr => {
|
|
249
|
+
if (!stderr) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
253
|
+
};
|
|
254
|
+
const isModulesSyntaxError = stderr => {
|
|
255
|
+
if (!stderr) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
259
|
+
};
|
|
260
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
261
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
262
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
263
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
264
|
+
};
|
|
265
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
266
|
+
const message = getMessageCodeBlock(stderr);
|
|
267
|
+
return {
|
|
268
|
+
message: `Incompatible native node module: ${message}`,
|
|
269
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
const getModuleSyntaxError = () => {
|
|
273
|
+
return {
|
|
274
|
+
message: `ES Modules are not supported in electron`,
|
|
275
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
279
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
280
|
+
return getNativeModuleErrorMessage(stderr);
|
|
281
|
+
}
|
|
282
|
+
if (isModulesSyntaxError(stderr)) {
|
|
283
|
+
return getModuleSyntaxError();
|
|
284
|
+
}
|
|
285
|
+
if (isModuleNotFoundError(stderr)) {
|
|
286
|
+
return getModuleNotFoundError(stderr);
|
|
287
|
+
}
|
|
288
|
+
const lines = splitLines$1(stderr);
|
|
289
|
+
const {
|
|
290
|
+
actualMessage,
|
|
291
|
+
rest
|
|
292
|
+
} = getDetails(lines);
|
|
293
|
+
return {
|
|
294
|
+
message: actualMessage,
|
|
295
|
+
code: '',
|
|
296
|
+
stack: rest
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
class IpcError extends VError {
|
|
300
|
+
// @ts-ignore
|
|
301
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
302
|
+
if (stdout || stderr) {
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
const {
|
|
305
|
+
message,
|
|
306
|
+
code,
|
|
307
|
+
stack
|
|
308
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
309
|
+
const cause = new Error(message);
|
|
310
|
+
// @ts-ignore
|
|
311
|
+
cause.code = code;
|
|
312
|
+
cause.stack = stack;
|
|
313
|
+
super(cause, betterMessage);
|
|
314
|
+
} else {
|
|
315
|
+
super(betterMessage);
|
|
316
|
+
}
|
|
317
|
+
// @ts-ignore
|
|
318
|
+
this.name = 'IpcError';
|
|
319
|
+
// @ts-ignore
|
|
320
|
+
this.stdout = stdout;
|
|
321
|
+
// @ts-ignore
|
|
322
|
+
this.stderr = stderr;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const readyMessage = 'ready';
|
|
326
|
+
const getData$2 = event => {
|
|
327
|
+
return event.data;
|
|
328
|
+
};
|
|
329
|
+
const listen$7 = () => {
|
|
330
|
+
// @ts-ignore
|
|
331
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
332
|
+
throw new TypeError('module is not in web worker scope');
|
|
333
|
+
}
|
|
334
|
+
return globalThis;
|
|
335
|
+
};
|
|
336
|
+
const signal$8 = global => {
|
|
337
|
+
global.postMessage(readyMessage);
|
|
338
|
+
};
|
|
339
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
340
|
+
getData(event) {
|
|
341
|
+
return getData$2(event);
|
|
342
|
+
}
|
|
343
|
+
send(message) {
|
|
344
|
+
// @ts-ignore
|
|
345
|
+
this._rawIpc.postMessage(message);
|
|
346
|
+
}
|
|
347
|
+
sendAndTransfer(message) {
|
|
348
|
+
const transfer = getTransferrables(message);
|
|
349
|
+
// @ts-ignore
|
|
350
|
+
this._rawIpc.postMessage(message, transfer);
|
|
351
|
+
}
|
|
352
|
+
dispose() {
|
|
353
|
+
// ignore
|
|
354
|
+
}
|
|
355
|
+
onClose(callback) {
|
|
356
|
+
// ignore
|
|
357
|
+
}
|
|
358
|
+
onMessage(callback) {
|
|
359
|
+
this._rawIpc.addEventListener('message', callback);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const wrap$f = global => {
|
|
363
|
+
return new IpcChildWithModuleWorker(global);
|
|
364
|
+
};
|
|
365
|
+
const withResolvers = () => {
|
|
366
|
+
let _resolve;
|
|
367
|
+
const promise = new Promise(resolve => {
|
|
368
|
+
_resolve = resolve;
|
|
369
|
+
});
|
|
370
|
+
return {
|
|
371
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
372
|
+
resolve: _resolve,
|
|
373
|
+
promise
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
const waitForFirstMessage = async port => {
|
|
377
|
+
const {
|
|
378
|
+
resolve,
|
|
379
|
+
promise
|
|
380
|
+
} = withResolvers();
|
|
381
|
+
port.addEventListener('message', resolve, {
|
|
382
|
+
once: true
|
|
383
|
+
});
|
|
384
|
+
const event = await promise;
|
|
385
|
+
// @ts-ignore
|
|
386
|
+
return event.data;
|
|
387
|
+
};
|
|
388
|
+
const listen$6 = async () => {
|
|
389
|
+
const parentIpcRaw = listen$7();
|
|
390
|
+
signal$8(parentIpcRaw);
|
|
391
|
+
const parentIpc = wrap$f(parentIpcRaw);
|
|
392
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
393
|
+
if (firstMessage.method !== 'initialize') {
|
|
394
|
+
throw new IpcError('unexpected first message');
|
|
395
|
+
}
|
|
396
|
+
const type = firstMessage.params[0];
|
|
397
|
+
if (type === 'message-port') {
|
|
398
|
+
parentIpc.send({
|
|
399
|
+
jsonrpc: '2.0',
|
|
400
|
+
id: firstMessage.id,
|
|
401
|
+
result: null
|
|
402
|
+
});
|
|
403
|
+
parentIpc.dispose();
|
|
404
|
+
const port = firstMessage.params[1];
|
|
405
|
+
return port;
|
|
406
|
+
}
|
|
407
|
+
return globalThis;
|
|
408
|
+
};
|
|
409
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
410
|
+
getData(event) {
|
|
411
|
+
return getData$2(event);
|
|
412
|
+
}
|
|
413
|
+
send(message) {
|
|
414
|
+
this._rawIpc.postMessage(message);
|
|
415
|
+
}
|
|
416
|
+
sendAndTransfer(message) {
|
|
417
|
+
const transfer = getTransferrables(message);
|
|
418
|
+
this._rawIpc.postMessage(message, transfer);
|
|
419
|
+
}
|
|
420
|
+
dispose() {
|
|
421
|
+
if (this._rawIpc.close) {
|
|
422
|
+
this._rawIpc.close();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
onClose(callback) {
|
|
426
|
+
// ignore
|
|
427
|
+
}
|
|
428
|
+
onMessage(callback) {
|
|
429
|
+
this._rawIpc.addEventListener('message', callback);
|
|
430
|
+
this._rawIpc.start();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const wrap$e = port => {
|
|
434
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
435
|
+
};
|
|
436
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
437
|
+
__proto__: null,
|
|
438
|
+
listen: listen$6,
|
|
439
|
+
wrap: wrap$e
|
|
440
|
+
};
|
|
441
|
+
|
|
1
442
|
const Two = '2.0';
|
|
2
443
|
const create$4 = (method, params) => {
|
|
3
444
|
return {
|
|
@@ -6,24 +447,19 @@ const create$4 = (method, params) => {
|
|
|
6
447
|
params
|
|
7
448
|
};
|
|
8
449
|
};
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const set = (id, fn) => {
|
|
13
|
-
state$1.callbacks[id] = fn;
|
|
450
|
+
const callbacks = Object.create(null);
|
|
451
|
+
const set$1 = (id, fn) => {
|
|
452
|
+
callbacks[id] = fn;
|
|
14
453
|
};
|
|
15
|
-
const get = id => {
|
|
16
|
-
return
|
|
454
|
+
const get$1 = id => {
|
|
455
|
+
return callbacks[id];
|
|
17
456
|
};
|
|
18
457
|
const remove = id => {
|
|
19
|
-
delete
|
|
458
|
+
delete callbacks[id];
|
|
20
459
|
};
|
|
21
|
-
let id = 0;
|
|
460
|
+
let id$a = 0;
|
|
22
461
|
const create$3 = () => {
|
|
23
|
-
return ++id;
|
|
24
|
-
};
|
|
25
|
-
const warn = (...args) => {
|
|
26
|
-
console.warn(...args);
|
|
462
|
+
return ++id$a;
|
|
27
463
|
};
|
|
28
464
|
const registerPromise = () => {
|
|
29
465
|
const id = create$3();
|
|
@@ -31,23 +467,13 @@ const registerPromise = () => {
|
|
|
31
467
|
resolve,
|
|
32
468
|
promise
|
|
33
469
|
} = Promise.withResolvers();
|
|
34
|
-
set(id, resolve);
|
|
470
|
+
set$1(id, resolve);
|
|
35
471
|
return {
|
|
36
472
|
id,
|
|
37
473
|
promise
|
|
38
474
|
};
|
|
39
475
|
};
|
|
40
|
-
const
|
|
41
|
-
const fn = get(id);
|
|
42
|
-
if (!fn) {
|
|
43
|
-
console.log(response);
|
|
44
|
-
warn(`callback ${id} may already be disposed`);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
fn(response);
|
|
48
|
-
remove(id);
|
|
49
|
-
};
|
|
50
|
-
const create$2 = (method, params) => {
|
|
476
|
+
const create$2$1 = (method, params) => {
|
|
51
477
|
const {
|
|
52
478
|
id,
|
|
53
479
|
promise
|
|
@@ -69,7 +495,7 @@ class JsonRpcError extends Error {
|
|
|
69
495
|
this.name = 'JsonRpcError';
|
|
70
496
|
}
|
|
71
497
|
}
|
|
72
|
-
const NewLine
|
|
498
|
+
const NewLine = '\n';
|
|
73
499
|
const DomException = 'DOMException';
|
|
74
500
|
const ReferenceError$1 = 'ReferenceError';
|
|
75
501
|
const SyntaxError$1 = 'SyntaxError';
|
|
@@ -114,40 +540,40 @@ const constructError = (message, type, name) => {
|
|
|
114
540
|
}
|
|
115
541
|
return new ErrorConstructor(message);
|
|
116
542
|
};
|
|
117
|
-
const getNewLineIndex
|
|
118
|
-
return string.indexOf(NewLine
|
|
543
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
544
|
+
return string.indexOf(NewLine, startIndex);
|
|
119
545
|
};
|
|
120
546
|
const getParentStack = error => {
|
|
121
547
|
let parentStack = error.stack || error.data || error.message || '';
|
|
122
548
|
if (parentStack.startsWith(' at')) {
|
|
123
|
-
parentStack = error.message + NewLine
|
|
549
|
+
parentStack = error.message + NewLine + parentStack;
|
|
124
550
|
}
|
|
125
551
|
return parentStack;
|
|
126
552
|
};
|
|
127
|
-
const joinLines
|
|
128
|
-
return lines.join(NewLine
|
|
553
|
+
const joinLines = lines => {
|
|
554
|
+
return lines.join(NewLine);
|
|
129
555
|
};
|
|
130
556
|
const MethodNotFound = -32601;
|
|
131
557
|
const Custom = -32001;
|
|
132
|
-
const splitLines
|
|
133
|
-
return lines.split(NewLine
|
|
558
|
+
const splitLines = lines => {
|
|
559
|
+
return lines.split(NewLine);
|
|
134
560
|
};
|
|
135
561
|
const restoreJsonRpcError = error => {
|
|
136
562
|
if (error && error instanceof Error) {
|
|
137
563
|
return error;
|
|
138
564
|
}
|
|
139
|
-
const currentStack = joinLines
|
|
565
|
+
const currentStack = joinLines(splitLines(new Error().stack || '').slice(1));
|
|
140
566
|
if (error && error.code && error.code === MethodNotFound) {
|
|
141
567
|
const restoredError = new JsonRpcError(error.message);
|
|
142
568
|
const parentStack = getParentStack(error);
|
|
143
|
-
restoredError.stack = parentStack + NewLine
|
|
569
|
+
restoredError.stack = parentStack + NewLine + currentStack;
|
|
144
570
|
return restoredError;
|
|
145
571
|
}
|
|
146
572
|
if (error && error.message) {
|
|
147
573
|
const restoredError = constructError(error.message, error.type, error.name);
|
|
148
574
|
if (error.data) {
|
|
149
575
|
if (error.data.stack && error.data.type && error.message) {
|
|
150
|
-
restoredError.stack = error.data.type + ': ' + error.message + NewLine
|
|
576
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
151
577
|
} else if (error.data.stack) {
|
|
152
578
|
restoredError.stack = error.data.stack;
|
|
153
579
|
}
|
|
@@ -167,7 +593,7 @@ const restoreJsonRpcError = error => {
|
|
|
167
593
|
if (error.stack) {
|
|
168
594
|
const lowerStack = restoredError.stack || '';
|
|
169
595
|
// @ts-ignore
|
|
170
|
-
const indexNewLine = getNewLineIndex
|
|
596
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
171
597
|
const parentStack = getParentStack(error);
|
|
172
598
|
// @ts-ignore
|
|
173
599
|
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
@@ -194,6 +620,19 @@ const unwrapJsonRpcResult = responseMessage => {
|
|
|
194
620
|
}
|
|
195
621
|
throw new JsonRpcError('unexpected response message');
|
|
196
622
|
};
|
|
623
|
+
const warn = (...args) => {
|
|
624
|
+
console.warn(...args);
|
|
625
|
+
};
|
|
626
|
+
const resolve = (id, response) => {
|
|
627
|
+
const fn = get$1(id);
|
|
628
|
+
if (!fn) {
|
|
629
|
+
console.log(response);
|
|
630
|
+
warn(`callback ${id} may already be disposed`);
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
fn(response);
|
|
634
|
+
remove(id);
|
|
635
|
+
};
|
|
197
636
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
198
637
|
const getErrorType = prettyError => {
|
|
199
638
|
if (prettyError && prettyError.type) {
|
|
@@ -320,831 +759,2235 @@ const handleJsonRpcMessage = async (...args) => {
|
|
|
320
759
|
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
321
760
|
return;
|
|
322
761
|
}
|
|
323
|
-
throw new JsonRpcError('unexpected message');
|
|
762
|
+
throw new JsonRpcError('unexpected message');
|
|
763
|
+
};
|
|
764
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
765
|
+
const {
|
|
766
|
+
message,
|
|
767
|
+
promise
|
|
768
|
+
} = create$2$1(method, params);
|
|
769
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
770
|
+
ipc.sendAndTransfer(message);
|
|
771
|
+
} else {
|
|
772
|
+
ipc.send(message);
|
|
773
|
+
}
|
|
774
|
+
const responseMessage = await promise;
|
|
775
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
776
|
+
};
|
|
777
|
+
const send = (transport, method, ...params) => {
|
|
778
|
+
const message = create$4(method, params);
|
|
779
|
+
transport.send(message);
|
|
780
|
+
};
|
|
781
|
+
const invoke$1 = (ipc, method, ...params) => {
|
|
782
|
+
return invokeHelper(ipc, method, params, false);
|
|
783
|
+
};
|
|
784
|
+
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
785
|
+
return invokeHelper(ipc, method, params, true);
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
const commands = Object.create(null);
|
|
789
|
+
const register = commandMap => {
|
|
790
|
+
Object.assign(commands, commandMap);
|
|
791
|
+
};
|
|
792
|
+
const getCommand = key => {
|
|
793
|
+
return commands[key];
|
|
794
|
+
};
|
|
795
|
+
const execute = (command, ...args) => {
|
|
796
|
+
const fn = getCommand(command);
|
|
797
|
+
if (!fn) {
|
|
798
|
+
throw new Error(`command not found ${command}`);
|
|
799
|
+
}
|
|
800
|
+
return fn(...args);
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
const createRpc = ipc => {
|
|
804
|
+
const rpc = {
|
|
805
|
+
// @ts-ignore
|
|
806
|
+
ipc,
|
|
807
|
+
/**
|
|
808
|
+
* @deprecated
|
|
809
|
+
*/
|
|
810
|
+
send(method, ...params) {
|
|
811
|
+
send(ipc, method, ...params);
|
|
812
|
+
},
|
|
813
|
+
invoke(method, ...params) {
|
|
814
|
+
return invoke$1(ipc, method, ...params);
|
|
815
|
+
},
|
|
816
|
+
invokeAndTransfer(method, ...params) {
|
|
817
|
+
return invokeAndTransfer(ipc, method, ...params);
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
return rpc;
|
|
821
|
+
};
|
|
822
|
+
const requiresSocket = () => {
|
|
823
|
+
return false;
|
|
824
|
+
};
|
|
825
|
+
const preparePrettyError = error => {
|
|
826
|
+
return error;
|
|
827
|
+
};
|
|
828
|
+
const logError = () => {
|
|
829
|
+
// handled by renderer worker
|
|
830
|
+
};
|
|
831
|
+
const handleMessage = event => {
|
|
832
|
+
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
833
|
+
const actualExecute = event?.target?.execute || execute;
|
|
834
|
+
return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
835
|
+
};
|
|
836
|
+
const handleIpc = ipc => {
|
|
837
|
+
if ('addEventListener' in ipc) {
|
|
838
|
+
ipc.addEventListener('message', handleMessage);
|
|
839
|
+
} else if ('on' in ipc) {
|
|
840
|
+
// deprecated
|
|
841
|
+
ipc.on('message', handleMessage);
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
const listen$1 = async (module, options) => {
|
|
845
|
+
const rawIpc = await module.listen(options);
|
|
846
|
+
if (module.signal) {
|
|
847
|
+
module.signal(rawIpc);
|
|
848
|
+
}
|
|
849
|
+
const ipc = module.wrap(rawIpc);
|
|
850
|
+
return ipc;
|
|
851
|
+
};
|
|
852
|
+
const create$2 = async ({
|
|
853
|
+
commandMap
|
|
854
|
+
}) => {
|
|
855
|
+
// TODO create a commandMap per rpc instance
|
|
856
|
+
register(commandMap);
|
|
857
|
+
const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
|
|
858
|
+
handleIpc(ipc);
|
|
859
|
+
const rpc = createRpc(ipc);
|
|
860
|
+
return rpc;
|
|
861
|
+
};
|
|
862
|
+
const WebWorkerRpcClient = {
|
|
863
|
+
__proto__: null,
|
|
864
|
+
create: create$2
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
const Menu$1 = 'menu';
|
|
868
|
+
const MenuBar = 'menubar';
|
|
869
|
+
const MenuItem$1 = 'menuitem';
|
|
870
|
+
const MenuItemCheckBox = 'menuitemcheckbox';
|
|
871
|
+
const Separator$1 = 'separator';
|
|
872
|
+
|
|
873
|
+
const Menu = 'Menu';
|
|
874
|
+
const MenuItem = 'MenuItem';
|
|
875
|
+
const MenuItemFocused = 'MenuItemFocused';
|
|
876
|
+
const MenuItemSeparator = 'MenuItemSeparator';
|
|
877
|
+
const MenuItemSeparatorLine = 'MenuItemSeparatorLine';
|
|
878
|
+
const MenuItemSubMenu = 'MenuItemSubMenu';
|
|
879
|
+
const MenuItemSubMenuArrowRight = 'MenuItemSubMenuArrowRight';
|
|
880
|
+
const TitleBarEntryActive = 'TitleBarEntryActive';
|
|
881
|
+
const TitleBarTopLevelEntry = 'TitleBarTopLevelEntry';
|
|
882
|
+
const TitleBarTopLevelEntryLabel = 'TitleBarTopLevelEntryLabel';
|
|
883
|
+
|
|
884
|
+
const getKeyBindingString = (key, altKey, ctrlKey, shiftKey, metaKey) => {
|
|
885
|
+
let string = '';
|
|
886
|
+
if (ctrlKey) {
|
|
887
|
+
string += 'Ctrl+';
|
|
888
|
+
}
|
|
889
|
+
if (shiftKey) {
|
|
890
|
+
string += 'Shift+';
|
|
891
|
+
}
|
|
892
|
+
string += key.toUpperCase();
|
|
893
|
+
return string;
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
const Separator = 1;
|
|
897
|
+
const None = 0;
|
|
898
|
+
const SubMenu = 4;
|
|
899
|
+
const Checked = 2;
|
|
900
|
+
const Unchecked = 3;
|
|
901
|
+
const Disabled = 5;
|
|
902
|
+
const RestoreFocus = 6;
|
|
903
|
+
const Ignore = 7;
|
|
904
|
+
|
|
905
|
+
const Backspace$1 = 1;
|
|
906
|
+
const Tab$1 = 2;
|
|
907
|
+
const Enter$1 = 3;
|
|
908
|
+
const Escape$1 = 8;
|
|
909
|
+
const Space$1 = 9;
|
|
910
|
+
const PageUp$1 = 10;
|
|
911
|
+
const PageDown$1 = 11;
|
|
912
|
+
const End$1 = 255;
|
|
913
|
+
const Home$1 = 12;
|
|
914
|
+
const LeftArrow$1 = 13;
|
|
915
|
+
const UpArrow$1 = 14;
|
|
916
|
+
const RightArrow$1 = 15;
|
|
917
|
+
const DownArrow$1 = 16;
|
|
918
|
+
const Insert$1 = 17;
|
|
919
|
+
const Delete$1 = 18;
|
|
920
|
+
const Digit0$1 = 19;
|
|
921
|
+
const Digit1$1 = 20;
|
|
922
|
+
const Digit2$1 = 21;
|
|
923
|
+
const Digit3$1 = 22;
|
|
924
|
+
const Digit4$1 = 23;
|
|
925
|
+
const Digit5$1 = 24;
|
|
926
|
+
const Digit6$1 = 25;
|
|
927
|
+
const Digit7$1 = 26;
|
|
928
|
+
const Digit8$1 = 27;
|
|
929
|
+
const Digit9$1 = 28;
|
|
930
|
+
const KeyA$1 = 29;
|
|
931
|
+
const KeyB$1 = 30;
|
|
932
|
+
const KeyC$1 = 31;
|
|
933
|
+
const KeyD$1 = 32;
|
|
934
|
+
const KeyE$1 = 33;
|
|
935
|
+
const KeyF$1 = 34;
|
|
936
|
+
const KeyG$1 = 35;
|
|
937
|
+
const KeyH$1 = 36;
|
|
938
|
+
const KeyI$1 = 37;
|
|
939
|
+
const KeyJ$1 = 38;
|
|
940
|
+
const KeyK$1 = 39;
|
|
941
|
+
const KeyL$1 = 40;
|
|
942
|
+
const KeyM$1 = 41;
|
|
943
|
+
const KeyN$1 = 42;
|
|
944
|
+
const KeyO$1 = 43;
|
|
945
|
+
const KeyP$1 = 44;
|
|
946
|
+
const KeyQ$1 = 45;
|
|
947
|
+
const KeyR$1 = 46;
|
|
948
|
+
const KeyS$1 = 47;
|
|
949
|
+
const KeyT$1 = 48;
|
|
950
|
+
const KeyU$1 = 49;
|
|
951
|
+
const KeyV$1 = 50;
|
|
952
|
+
const KeyW$1 = 51;
|
|
953
|
+
const KeyX$1 = 52;
|
|
954
|
+
const KeyY$1 = 53;
|
|
955
|
+
const KeyZ$1 = 54;
|
|
956
|
+
const F1$1 = 57;
|
|
957
|
+
const F2$1 = 58;
|
|
958
|
+
const F3$1 = 59;
|
|
959
|
+
const F4$1 = 60;
|
|
960
|
+
const F5$1 = 61;
|
|
961
|
+
const F6$1 = 62;
|
|
962
|
+
const Equal$1 = 84;
|
|
963
|
+
const Comma$1 = 85;
|
|
964
|
+
const Minus$1 = 86;
|
|
965
|
+
const Backquote$1 = 89;
|
|
966
|
+
const Backslash$1 = 91;
|
|
967
|
+
const Star$1 = 131;
|
|
968
|
+
const Plus$1 = 132;
|
|
969
|
+
|
|
970
|
+
const Unknown = 'Unknown';
|
|
971
|
+
const Backspace = 'Backspace';
|
|
972
|
+
const Tab = 'Tab';
|
|
973
|
+
const Enter = 'Enter';
|
|
974
|
+
const Escape = 'Escape';
|
|
975
|
+
const Space = 'Space';
|
|
976
|
+
const PageUp = 'PageUp';
|
|
977
|
+
const PageDown = 'PageDown';
|
|
978
|
+
const End = 'End';
|
|
979
|
+
const Home = 'Home';
|
|
980
|
+
const LeftArrow = 'LeftArrow';
|
|
981
|
+
const UpArrow = 'UpArrow';
|
|
982
|
+
const RightArrow = 'RightArrow';
|
|
983
|
+
const DownArrow = 'DownArrow';
|
|
984
|
+
const Insert = 'Insert';
|
|
985
|
+
const Delete = 'Delete';
|
|
986
|
+
const Digit0 = '0';
|
|
987
|
+
const Digit1 = '1';
|
|
988
|
+
const Digit2 = '2';
|
|
989
|
+
const Digit3 = '3';
|
|
990
|
+
const Digit4 = '4';
|
|
991
|
+
const Digit5 = '5';
|
|
992
|
+
const Digit6 = '6';
|
|
993
|
+
const Digit7 = '7';
|
|
994
|
+
const Digit8 = '8';
|
|
995
|
+
const Digit9 = '9';
|
|
996
|
+
const KeyA = 'a';
|
|
997
|
+
const KeyB = 'b';
|
|
998
|
+
const KeyC = 'c';
|
|
999
|
+
const KeyD = 'd';
|
|
1000
|
+
const KeyE = 'e';
|
|
1001
|
+
const KeyF = 'f';
|
|
1002
|
+
const KeyG = 'g';
|
|
1003
|
+
const KeyH = 'h';
|
|
1004
|
+
const KeyI = 'i';
|
|
1005
|
+
const KeyJ = 'j';
|
|
1006
|
+
const KeyK = 'k';
|
|
1007
|
+
const KeyL = 'l';
|
|
1008
|
+
const KeyM = 'm';
|
|
1009
|
+
const KeyN = 'n';
|
|
1010
|
+
const KeyO = 'o';
|
|
1011
|
+
const KeyP = 'p';
|
|
1012
|
+
const KeyQ = 'q';
|
|
1013
|
+
const KeyR = 'r';
|
|
1014
|
+
const KeyS = 's';
|
|
1015
|
+
const KeyT = 't';
|
|
1016
|
+
const KeyU = 'u';
|
|
1017
|
+
const KeyV = 'v';
|
|
1018
|
+
const KeyW = 'w';
|
|
1019
|
+
const KeyX = 'x';
|
|
1020
|
+
const KeyY = 'y';
|
|
1021
|
+
const KeyZ = 'z';
|
|
1022
|
+
const F1 = 'F1';
|
|
1023
|
+
const F2 = 'F2';
|
|
1024
|
+
const F3 = 'F3';
|
|
1025
|
+
const F4 = 'F4';
|
|
1026
|
+
const F5 = 'F5';
|
|
1027
|
+
const F6 = 'F6';
|
|
1028
|
+
const Equal = '=';
|
|
1029
|
+
const Comma = ',';
|
|
1030
|
+
const Minus = 'Minus';
|
|
1031
|
+
const Backquote = 'Backquote';
|
|
1032
|
+
const Backslash = 'Backslash';
|
|
1033
|
+
const Star = '*';
|
|
1034
|
+
const Plus = '+';
|
|
1035
|
+
|
|
1036
|
+
const getKeyCodeString = keyCode => {
|
|
1037
|
+
switch (keyCode) {
|
|
1038
|
+
case Backspace$1:
|
|
1039
|
+
return Backspace;
|
|
1040
|
+
case Tab$1:
|
|
1041
|
+
return Tab;
|
|
1042
|
+
case Escape$1:
|
|
1043
|
+
return Escape;
|
|
1044
|
+
case Enter$1:
|
|
1045
|
+
return Enter;
|
|
1046
|
+
case Space$1:
|
|
1047
|
+
return Space;
|
|
1048
|
+
case PageUp$1:
|
|
1049
|
+
return PageUp;
|
|
1050
|
+
case PageDown$1:
|
|
1051
|
+
return PageDown;
|
|
1052
|
+
case End$1:
|
|
1053
|
+
return End;
|
|
1054
|
+
case Home$1:
|
|
1055
|
+
return Home;
|
|
1056
|
+
case LeftArrow$1:
|
|
1057
|
+
return LeftArrow;
|
|
1058
|
+
case UpArrow$1:
|
|
1059
|
+
return UpArrow;
|
|
1060
|
+
case RightArrow$1:
|
|
1061
|
+
return RightArrow;
|
|
1062
|
+
case DownArrow$1:
|
|
1063
|
+
return DownArrow;
|
|
1064
|
+
case Insert$1:
|
|
1065
|
+
return Insert;
|
|
1066
|
+
case Delete$1:
|
|
1067
|
+
return Delete;
|
|
1068
|
+
case Digit0$1:
|
|
1069
|
+
return Digit0;
|
|
1070
|
+
case Digit1$1:
|
|
1071
|
+
return Digit1;
|
|
1072
|
+
case Digit2$1:
|
|
1073
|
+
return Digit2;
|
|
1074
|
+
case Digit3$1:
|
|
1075
|
+
return Digit3;
|
|
1076
|
+
case Digit4$1:
|
|
1077
|
+
return Digit4;
|
|
1078
|
+
case Digit5$1:
|
|
1079
|
+
return Digit5;
|
|
1080
|
+
case Digit6$1:
|
|
1081
|
+
return Digit6;
|
|
1082
|
+
case Digit7$1:
|
|
1083
|
+
return Digit7;
|
|
1084
|
+
case Digit8$1:
|
|
1085
|
+
return Digit8;
|
|
1086
|
+
case Digit9$1:
|
|
1087
|
+
return Digit9;
|
|
1088
|
+
case KeyA$1:
|
|
1089
|
+
return KeyA;
|
|
1090
|
+
case KeyB$1:
|
|
1091
|
+
return KeyB;
|
|
1092
|
+
case KeyC$1:
|
|
1093
|
+
return KeyC;
|
|
1094
|
+
case KeyD$1:
|
|
1095
|
+
return KeyD;
|
|
1096
|
+
case KeyE$1:
|
|
1097
|
+
return KeyE;
|
|
1098
|
+
case KeyF$1:
|
|
1099
|
+
return KeyF;
|
|
1100
|
+
case KeyG$1:
|
|
1101
|
+
return KeyG;
|
|
1102
|
+
case KeyH$1:
|
|
1103
|
+
return KeyH;
|
|
1104
|
+
case KeyI$1:
|
|
1105
|
+
return KeyI;
|
|
1106
|
+
case KeyJ$1:
|
|
1107
|
+
return KeyJ;
|
|
1108
|
+
case KeyK$1:
|
|
1109
|
+
return KeyK;
|
|
1110
|
+
case KeyL$1:
|
|
1111
|
+
return KeyL;
|
|
1112
|
+
case KeyM$1:
|
|
1113
|
+
return KeyM;
|
|
1114
|
+
case KeyN$1:
|
|
1115
|
+
return KeyN;
|
|
1116
|
+
case KeyO$1:
|
|
1117
|
+
return KeyO;
|
|
1118
|
+
case KeyP$1:
|
|
1119
|
+
return KeyP;
|
|
1120
|
+
case KeyQ$1:
|
|
1121
|
+
return KeyQ;
|
|
1122
|
+
case KeyR$1:
|
|
1123
|
+
return KeyR;
|
|
1124
|
+
case KeyS$1:
|
|
1125
|
+
return KeyS;
|
|
1126
|
+
case KeyT$1:
|
|
1127
|
+
return KeyT;
|
|
1128
|
+
case KeyU$1:
|
|
1129
|
+
return KeyU;
|
|
1130
|
+
case KeyV$1:
|
|
1131
|
+
return KeyV;
|
|
1132
|
+
case KeyW$1:
|
|
1133
|
+
return KeyW;
|
|
1134
|
+
case KeyX$1:
|
|
1135
|
+
return KeyX;
|
|
1136
|
+
case KeyY$1:
|
|
1137
|
+
return KeyY;
|
|
1138
|
+
case KeyZ$1:
|
|
1139
|
+
return KeyZ;
|
|
1140
|
+
case F1$1:
|
|
1141
|
+
return F1;
|
|
1142
|
+
case F2$1:
|
|
1143
|
+
return F2;
|
|
1144
|
+
case F3$1:
|
|
1145
|
+
return F3;
|
|
1146
|
+
case F4$1:
|
|
1147
|
+
return F4;
|
|
1148
|
+
case F5$1:
|
|
1149
|
+
return F5;
|
|
1150
|
+
case F6$1:
|
|
1151
|
+
return F6;
|
|
1152
|
+
case Backslash$1:
|
|
1153
|
+
return Backslash;
|
|
1154
|
+
case Equal$1:
|
|
1155
|
+
return Equal;
|
|
1156
|
+
case Comma$1:
|
|
1157
|
+
return Comma;
|
|
1158
|
+
case Backquote$1:
|
|
1159
|
+
return Backquote;
|
|
1160
|
+
case Plus$1:
|
|
1161
|
+
return Plus;
|
|
1162
|
+
case Star$1:
|
|
1163
|
+
return Star;
|
|
1164
|
+
case Minus$1:
|
|
1165
|
+
return Minus;
|
|
1166
|
+
default:
|
|
1167
|
+
return Unknown;
|
|
1168
|
+
}
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
1172
|
+
const Shift = 1 << 10 >>> 0;
|
|
1173
|
+
|
|
1174
|
+
const parseKey = rawKey => {
|
|
1175
|
+
number(rawKey);
|
|
1176
|
+
const isCtrl = Boolean(rawKey & CtrlCmd);
|
|
1177
|
+
const isShift = Boolean(rawKey & Shift);
|
|
1178
|
+
const keyCode = rawKey & 0x00_00_00_ff;
|
|
1179
|
+
const key = getKeyCodeString(keyCode);
|
|
1180
|
+
return {
|
|
1181
|
+
key,
|
|
1182
|
+
isCtrl,
|
|
1183
|
+
isShift
|
|
1184
|
+
};
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
const Div = 4;
|
|
1188
|
+
const Span = 8;
|
|
1189
|
+
const Text = 12;
|
|
1190
|
+
|
|
1191
|
+
const text = data => {
|
|
1192
|
+
return {
|
|
1193
|
+
type: Text,
|
|
1194
|
+
text: data,
|
|
1195
|
+
childCount: 0
|
|
1196
|
+
};
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
const separator = {
|
|
1200
|
+
type: Div,
|
|
1201
|
+
className: MenuItemSeparator,
|
|
1202
|
+
role: Separator$1,
|
|
1203
|
+
childCount: 1
|
|
1204
|
+
};
|
|
1205
|
+
const separatorLine = {
|
|
1206
|
+
type: Div,
|
|
1207
|
+
className: MenuItemSeparatorLine,
|
|
1208
|
+
childCount: 0
|
|
1209
|
+
};
|
|
1210
|
+
const checkboxUnchecked = {
|
|
1211
|
+
type: Div,
|
|
1212
|
+
className: MenuItem,
|
|
1213
|
+
role: MenuItemCheckBox,
|
|
1214
|
+
ariaChecked: false,
|
|
1215
|
+
tabIndex: -1,
|
|
1216
|
+
childCount: 1
|
|
1217
|
+
};
|
|
1218
|
+
const checkboxChecked = {
|
|
1219
|
+
type: Div,
|
|
1220
|
+
className: `${MenuItem} MenuItemCheckMark`,
|
|
1221
|
+
role: MenuItemCheckBox,
|
|
1222
|
+
ariaChecked: true,
|
|
1223
|
+
tabIndex: -1,
|
|
1224
|
+
childCount: 2
|
|
1225
|
+
};
|
|
1226
|
+
const disabled = {
|
|
1227
|
+
type: Div,
|
|
1228
|
+
className: MenuItem,
|
|
1229
|
+
role: MenuItem$1,
|
|
1230
|
+
tabIndex: -1,
|
|
1231
|
+
disabled: true,
|
|
1232
|
+
childCount: 1
|
|
1233
|
+
};
|
|
1234
|
+
const arrowRight = {
|
|
1235
|
+
type: Div,
|
|
1236
|
+
className: MenuItemSubMenuArrowRight,
|
|
1237
|
+
childCount: 0
|
|
1238
|
+
};
|
|
1239
|
+
const getMenuItemSeparatorDom = menuItem => {
|
|
1240
|
+
return [separator, separatorLine];
|
|
1241
|
+
};
|
|
1242
|
+
const getMenuItemCheckedDom = menuItem => {
|
|
1243
|
+
const {
|
|
1244
|
+
label
|
|
1245
|
+
} = menuItem;
|
|
1246
|
+
return [checkboxChecked, {
|
|
1247
|
+
type: Div,
|
|
1248
|
+
className: 'MenuItemCheckmarkIcon MaskIconCheck'
|
|
1249
|
+
}, text(label)];
|
|
1250
|
+
};
|
|
1251
|
+
const getMenuItemUncheckedDom = menuItem => {
|
|
1252
|
+
const {
|
|
1253
|
+
label
|
|
1254
|
+
} = menuItem;
|
|
1255
|
+
return [checkboxUnchecked, text(label)];
|
|
1256
|
+
};
|
|
1257
|
+
const getMenuItemDisabledDom = menuItem => {
|
|
1258
|
+
const {
|
|
1259
|
+
label
|
|
1260
|
+
} = menuItem;
|
|
1261
|
+
return [disabled, text(label)];
|
|
1262
|
+
};
|
|
1263
|
+
const getMenuItemDefaultDom = menuItem => {
|
|
1264
|
+
const {
|
|
1265
|
+
label,
|
|
1266
|
+
isFocused,
|
|
1267
|
+
key
|
|
1268
|
+
} = menuItem;
|
|
1269
|
+
let className = MenuItem;
|
|
1270
|
+
if (isFocused) {
|
|
1271
|
+
className += ' ' + MenuItemFocused;
|
|
1272
|
+
}
|
|
1273
|
+
const dom = [];
|
|
1274
|
+
dom.push({
|
|
1275
|
+
type: Div,
|
|
1276
|
+
className,
|
|
1277
|
+
role: MenuItem$1,
|
|
1278
|
+
tabIndex: -1,
|
|
1279
|
+
childCount: 1
|
|
1280
|
+
}, text(label));
|
|
1281
|
+
if (key) {
|
|
1282
|
+
dom[0].childCount++;
|
|
1283
|
+
const parsedKey = parseKey(key);
|
|
1284
|
+
const keyBindingsString = getKeyBindingString(parsedKey.key, false, parsedKey.isCtrl, parsedKey.isShift);
|
|
1285
|
+
dom.push({
|
|
1286
|
+
type: Span,
|
|
1287
|
+
className: 'MenuItemKeyBinding',
|
|
1288
|
+
childCount: 1
|
|
1289
|
+
}, text(keyBindingsString));
|
|
1290
|
+
}
|
|
1291
|
+
return dom;
|
|
1292
|
+
};
|
|
1293
|
+
const getMenuItemSubMenuDom = menuItem => {
|
|
1294
|
+
const {
|
|
1295
|
+
label,
|
|
1296
|
+
isFocused,
|
|
1297
|
+
isExpanded,
|
|
1298
|
+
level
|
|
1299
|
+
} = menuItem;
|
|
1300
|
+
let className = MenuItem;
|
|
1301
|
+
className += ' ' + MenuItemSubMenu;
|
|
1302
|
+
if (isFocused) {
|
|
1303
|
+
className += ' ' + MenuItemFocused;
|
|
1304
|
+
}
|
|
1305
|
+
return [{
|
|
1306
|
+
type: Div,
|
|
1307
|
+
className,
|
|
1308
|
+
role: MenuItem$1,
|
|
1309
|
+
tabIndex: -1,
|
|
1310
|
+
ariaHasPopup: true,
|
|
1311
|
+
ariaExpanded: isExpanded,
|
|
1312
|
+
ariaOwns: isExpanded ? `Menu-${level + 1}` : undefined,
|
|
1313
|
+
childCount: 2
|
|
1314
|
+
}, text(label), arrowRight];
|
|
1315
|
+
};
|
|
1316
|
+
const getMenuItemVirtualDom = menuItem => {
|
|
1317
|
+
const {
|
|
1318
|
+
flags
|
|
1319
|
+
} = menuItem;
|
|
1320
|
+
switch (flags) {
|
|
1321
|
+
case None:
|
|
1322
|
+
case RestoreFocus:
|
|
1323
|
+
case Ignore:
|
|
1324
|
+
return getMenuItemDefaultDom(menuItem);
|
|
1325
|
+
case Separator:
|
|
1326
|
+
return getMenuItemSeparatorDom();
|
|
1327
|
+
case Checked:
|
|
1328
|
+
return getMenuItemCheckedDom(menuItem);
|
|
1329
|
+
case Unchecked:
|
|
1330
|
+
return getMenuItemUncheckedDom(menuItem);
|
|
1331
|
+
case Disabled:
|
|
1332
|
+
return getMenuItemDisabledDom(menuItem);
|
|
1333
|
+
case SubMenu:
|
|
1334
|
+
return getMenuItemSubMenuDom(menuItem);
|
|
1335
|
+
default:
|
|
1336
|
+
return [];
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
const getMenuVirtualDom = menuItems => {
|
|
1340
|
+
const dom = [];
|
|
1341
|
+
dom.push({
|
|
1342
|
+
type: Div,
|
|
1343
|
+
className: Menu,
|
|
1344
|
+
role: Menu$1,
|
|
1345
|
+
tabIndex: -1,
|
|
1346
|
+
childCount: menuItems.length
|
|
1347
|
+
});
|
|
1348
|
+
dom.push(...menuItems.flatMap(getMenuItemVirtualDom));
|
|
1349
|
+
return dom;
|
|
1350
|
+
};
|
|
1351
|
+
|
|
1352
|
+
const HandleClick = 'handleClick';
|
|
1353
|
+
const HandleFocusIn = 'handleFocusIn';
|
|
1354
|
+
const HandleFocusOut = 'handleFocusOut';
|
|
1355
|
+
const HandlePointerOut = 'handlePointerOut';
|
|
1356
|
+
const HandlePointerOver = 'handlePointerOver';
|
|
1357
|
+
|
|
1358
|
+
const getItemVirtualDom = item => {
|
|
1359
|
+
// @ts-ignore
|
|
1360
|
+
const {
|
|
1361
|
+
keyboardShortCut,
|
|
1362
|
+
label,
|
|
1363
|
+
isOpen,
|
|
1364
|
+
isFocused
|
|
1365
|
+
} = item;
|
|
1366
|
+
const dom = [];
|
|
1367
|
+
dom.push({
|
|
1368
|
+
type: Div,
|
|
1369
|
+
className: TitleBarTopLevelEntry,
|
|
1370
|
+
ariaHasPopup: true,
|
|
1371
|
+
ariaExpanded: isOpen,
|
|
1372
|
+
role: MenuItem$1,
|
|
1373
|
+
childCount: 1,
|
|
1374
|
+
ariaKeyShortcuts: keyboardShortCut
|
|
1375
|
+
});
|
|
1376
|
+
if (isOpen) {
|
|
1377
|
+
// @ts-ignore
|
|
1378
|
+
dom[0].ariaOwns = 'Menu-0';
|
|
1379
|
+
}
|
|
1380
|
+
if (isFocused) {
|
|
1381
|
+
dom[0].className += ' ' + TitleBarEntryActive;
|
|
1382
|
+
// @ts-ignore
|
|
1383
|
+
dom[0].id = 'TitleBarEntryActive';
|
|
1384
|
+
dom.push({
|
|
1385
|
+
type: Div,
|
|
1386
|
+
className: TitleBarTopLevelEntryLabel,
|
|
1387
|
+
childCount: 1
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
dom.push(text(label));
|
|
1391
|
+
return dom;
|
|
324
1392
|
};
|
|
325
|
-
const
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
promise
|
|
329
|
-
} = create$2(method, params);
|
|
330
|
-
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
331
|
-
ipc.sendAndTransfer(message);
|
|
332
|
-
} else {
|
|
333
|
-
ipc.send(message);
|
|
334
|
-
}
|
|
335
|
-
const responseMessage = await promise;
|
|
336
|
-
return unwrapJsonRpcResult(responseMessage);
|
|
1393
|
+
const getTitleBarMenuBarItemsVirtualDom = visibleItems => {
|
|
1394
|
+
const dom = visibleItems.flatMap(getItemVirtualDom);
|
|
1395
|
+
return dom;
|
|
337
1396
|
};
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
1397
|
+
|
|
1398
|
+
const getTitleBarMenuBarVirtualDom = visibleItems => {
|
|
1399
|
+
return [{
|
|
1400
|
+
type: Div,
|
|
1401
|
+
className: 'Viewlet TitleBarMenuBar',
|
|
1402
|
+
role: MenuBar,
|
|
1403
|
+
tabIndex: 0,
|
|
1404
|
+
childCount: visibleItems.length,
|
|
1405
|
+
onMouseDown: HandleClick,
|
|
1406
|
+
onFocusOut: HandleFocusOut,
|
|
1407
|
+
onFocusIn: HandleFocusIn,
|
|
1408
|
+
onPointerOver: HandlePointerOver,
|
|
1409
|
+
onPointerOut: HandlePointerOut
|
|
1410
|
+
}, ...getTitleBarMenuBarItemsVirtualDom(visibleItems)];
|
|
341
1411
|
};
|
|
342
|
-
|
|
343
|
-
|
|
1412
|
+
|
|
1413
|
+
const getVisible = (items, focusedIndex, expanded, level) => {
|
|
1414
|
+
const visibleItems = [];
|
|
1415
|
+
const {
|
|
1416
|
+
length
|
|
1417
|
+
} = items;
|
|
1418
|
+
for (let i = 0; i < length; i++) {
|
|
1419
|
+
const item = items[i];
|
|
1420
|
+
const {
|
|
1421
|
+
flags,
|
|
1422
|
+
label
|
|
1423
|
+
} = item;
|
|
1424
|
+
visibleItems.push({
|
|
1425
|
+
label,
|
|
1426
|
+
flags,
|
|
1427
|
+
isFocused: i === focusedIndex,
|
|
1428
|
+
isExpanded: i === focusedIndex && expanded,
|
|
1429
|
+
level,
|
|
1430
|
+
key: item.key
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
return visibleItems;
|
|
344
1434
|
};
|
|
345
|
-
|
|
346
|
-
|
|
1435
|
+
|
|
1436
|
+
const Ellipsis = 'Ellipsis';
|
|
1437
|
+
|
|
1438
|
+
const emptyObject = {};
|
|
1439
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1440
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
1441
|
+
if (placeholders === emptyObject) {
|
|
1442
|
+
return key;
|
|
1443
|
+
}
|
|
1444
|
+
const replacer = (match, rest) => {
|
|
1445
|
+
return placeholders[rest];
|
|
1446
|
+
};
|
|
1447
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
347
1448
|
};
|
|
348
1449
|
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
|
|
1450
|
+
const About = 'About';
|
|
1451
|
+
const CheckForUpdates = 'Check For Updates';
|
|
1452
|
+
const ClearRecentlyOpened = 'Clear Recently Opened';
|
|
1453
|
+
const Edit$1 = 'Edit';
|
|
1454
|
+
const File$1 = 'File';
|
|
1455
|
+
const Go$1 = 'Go';
|
|
1456
|
+
const Help$1 = 'Help';
|
|
1457
|
+
const MoreDot = 'More ...';
|
|
1458
|
+
const Run$1 = 'Run';
|
|
1459
|
+
const Selection$1 = 'Selection';
|
|
1460
|
+
const Terminal$1 = 'Terminal';
|
|
1461
|
+
const View$1 = 'View';
|
|
1462
|
+
|
|
1463
|
+
const moreDot = () => {
|
|
1464
|
+
return i18nString(MoreDot);
|
|
352
1465
|
};
|
|
353
|
-
const
|
|
354
|
-
return
|
|
1466
|
+
const clearRecentlyOpened = () => {
|
|
1467
|
+
return i18nString(ClearRecentlyOpened);
|
|
355
1468
|
};
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
1469
|
+
|
|
1470
|
+
const getVisibleTitleBarEntries = (entries, width, focusedIndex, isMenuOpen) => {
|
|
1471
|
+
array(entries);
|
|
1472
|
+
number(width);
|
|
1473
|
+
let total = 0;
|
|
1474
|
+
const visible = [];
|
|
1475
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1476
|
+
const entry = entries[i];
|
|
1477
|
+
total += entry.width;
|
|
1478
|
+
if (total >= width) {
|
|
1479
|
+
break;
|
|
1480
|
+
}
|
|
1481
|
+
const isOpen = i === focusedIndex && isMenuOpen;
|
|
1482
|
+
const isFocused = i === focusedIndex;
|
|
1483
|
+
visible.push({
|
|
1484
|
+
...entry,
|
|
1485
|
+
isOpen,
|
|
1486
|
+
isFocused
|
|
1487
|
+
});
|
|
360
1488
|
}
|
|
361
|
-
|
|
1489
|
+
const hasOverflow = visible.length < entries.length;
|
|
1490
|
+
if (hasOverflow) {
|
|
1491
|
+
const padding = 8;
|
|
1492
|
+
const moreIconWidth = 22;
|
|
1493
|
+
const totalPadding = padding * 2;
|
|
1494
|
+
const hasStillOverflow = total + moreIconWidth + totalPadding > width;
|
|
1495
|
+
if (hasStillOverflow) {
|
|
1496
|
+
visible.pop();
|
|
1497
|
+
}
|
|
1498
|
+
visible.push({
|
|
1499
|
+
ariaLabel: moreDot(),
|
|
1500
|
+
icon: Ellipsis,
|
|
1501
|
+
label: '',
|
|
1502
|
+
width: moreIconWidth + totalPadding
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
return visible;
|
|
362
1506
|
};
|
|
363
1507
|
|
|
364
|
-
const
|
|
365
|
-
|
|
1508
|
+
const SetFocusedIndex = 'setFocusedIndex';
|
|
1509
|
+
const SetMenus = 'setMenus';
|
|
1510
|
+
|
|
1511
|
+
const renderTitleBarEntries = {
|
|
1512
|
+
isEqual(oldState, newState) {
|
|
1513
|
+
return oldState.titleBarEntries === newState.titleBarEntries && oldState.width === newState.width && oldState.focusedIndex === newState.focusedIndex && oldState.isMenuOpen === newState.isMenuOpen;
|
|
1514
|
+
},
|
|
1515
|
+
apply(oldState, newState) {
|
|
1516
|
+
const visibleEntries = getVisibleTitleBarEntries(newState.titleBarEntries, newState.width, newState.focusedIndex, newState.isMenuOpen);
|
|
1517
|
+
const dom = getTitleBarMenuBarVirtualDom(visibleEntries);
|
|
1518
|
+
return ['Viewlet.setDom2', dom];
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
const renderFocusedIndex = {
|
|
1522
|
+
isEqual(oldState, newState) {
|
|
1523
|
+
return oldState.focusedIndex === newState.focusedIndex && oldState.isMenuOpen === newState.isMenuOpen;
|
|
1524
|
+
},
|
|
1525
|
+
apply(oldState, newState) {
|
|
1526
|
+
return [/* method */SetFocusedIndex, /* oldFocusedIndex */oldState.focusedIndex, /* newfocusedIndex */newState.focusedIndex, /* oldIsMenuOpen */oldState.isMenuOpen, /* newIsMenuOpen */newState.isMenuOpen];
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
const renderMenus = {
|
|
1530
|
+
isEqual(oldState, newState) {
|
|
1531
|
+
return oldState.menus === newState.menus;
|
|
1532
|
+
},
|
|
1533
|
+
apply(oldState, newState) {
|
|
1534
|
+
const oldMenus = oldState.menus;
|
|
1535
|
+
const newMenus = newState.menus;
|
|
1536
|
+
const oldLength = oldMenus.length;
|
|
1537
|
+
const newLength = newMenus.length;
|
|
1538
|
+
const commonLength = Math.min(oldLength, newLength);
|
|
1539
|
+
const changes = [];
|
|
1540
|
+
for (let i = 0; i < commonLength; i++) {
|
|
1541
|
+
const oldMenu = oldMenus[i];
|
|
1542
|
+
const newMenu = newMenus[i];
|
|
1543
|
+
if (oldMenu !== newMenu) {
|
|
1544
|
+
const visible = getVisible(newMenu.items, newMenu.focusedIndex, newMenu.expanded, newMenu.level);
|
|
1545
|
+
const dom = getMenuVirtualDom(visible).slice(1);
|
|
1546
|
+
changes.push([/* method */'updateMenu', newMenu, /* newLength */newLength, dom]);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
const difference = newLength - oldLength;
|
|
1550
|
+
if (difference > 0) {
|
|
1551
|
+
const newMenu = newMenus.at(-1);
|
|
1552
|
+
const visible = getVisible(newMenu.items, newMenu.focusedIndex, newMenu.expanded, newMenu.level);
|
|
1553
|
+
const dom = getMenuVirtualDom(visible).slice(1);
|
|
1554
|
+
changes.push(['addMenu', newMenu, dom]);
|
|
1555
|
+
} else if (difference < 0) {
|
|
1556
|
+
changes.push(['closeMenus', newLength]);
|
|
1557
|
+
}
|
|
1558
|
+
return [/* method */SetMenus, /* changes */changes, newState.uid];
|
|
1559
|
+
}
|
|
366
1560
|
};
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
1561
|
+
const render = [renderTitleBarEntries, renderFocusedIndex, renderMenus];
|
|
1562
|
+
|
|
1563
|
+
const create$1 = () => {
|
|
1564
|
+
const states = Object.create(null);
|
|
1565
|
+
return {
|
|
1566
|
+
get(uid) {
|
|
1567
|
+
return states[uid];
|
|
1568
|
+
},
|
|
1569
|
+
set(uid, oldState, newState) {
|
|
1570
|
+
states[uid] = {
|
|
1571
|
+
oldState,
|
|
1572
|
+
newState
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
377
1575
|
};
|
|
378
|
-
that.onClose(handleClose);
|
|
379
1576
|
};
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
if (Array.isArray(value)) {
|
|
397
|
-
for (const item of value) {
|
|
398
|
-
walkValue(item, transferrables, isTransferrable);
|
|
399
|
-
}
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
if (typeof value === 'object') {
|
|
403
|
-
for (const property of Object.values(value)) {
|
|
404
|
-
walkValue(property, transferrables, isTransferrable);
|
|
1577
|
+
|
|
1578
|
+
const {
|
|
1579
|
+
get,
|
|
1580
|
+
set
|
|
1581
|
+
} = create$1();
|
|
1582
|
+
|
|
1583
|
+
const doRender = async uid => {
|
|
1584
|
+
const {
|
|
1585
|
+
oldState,
|
|
1586
|
+
newState
|
|
1587
|
+
} = get(uid);
|
|
1588
|
+
const commands = [];
|
|
1589
|
+
for (const item of render) {
|
|
1590
|
+
if (!item.isEqual(oldState, newState)) {
|
|
1591
|
+
commands.push(item.apply(oldState, newState));
|
|
405
1592
|
}
|
|
406
|
-
return;
|
|
407
1593
|
}
|
|
1594
|
+
return commands;
|
|
408
1595
|
};
|
|
409
|
-
|
|
410
|
-
|
|
1596
|
+
|
|
1597
|
+
const commandsIds = ['closeMenu', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusPrevious', 'handleKeyArrowDown', 'handleKeyArrowLeft', 'handleKeyArrowRight', 'handleKeyArrowUp', 'handleKeyEnd', 'handleKeyEnter', 'handleKeyEscape', 'handleKeyHome', 'handleKeySpace', 'handleMenuClick', 'handleMenuMouseOver', 'handleMouseOver', 'handleMouseOut', 'toggleIndex', 'toggleMenu', 'handleClick', 'handleFocus'];
|
|
1598
|
+
const getCommandIds = () => {
|
|
1599
|
+
return commandsIds;
|
|
411
1600
|
};
|
|
412
|
-
|
|
413
|
-
|
|
1601
|
+
|
|
1602
|
+
const FocusTitleBarMenuBar = 26;
|
|
1603
|
+
|
|
1604
|
+
const getKeyBindings = () => {
|
|
1605
|
+
return [{
|
|
1606
|
+
key: DownArrow$1,
|
|
1607
|
+
command: 'TitleBarMenuBar.handleKeyArrowDown',
|
|
1608
|
+
when: FocusTitleBarMenuBar
|
|
1609
|
+
}, {
|
|
1610
|
+
key: UpArrow$1,
|
|
1611
|
+
command: 'TitleBarMenuBar.handleKeyArrowUp',
|
|
1612
|
+
when: FocusTitleBarMenuBar
|
|
1613
|
+
}, {
|
|
1614
|
+
key: RightArrow$1,
|
|
1615
|
+
command: 'TitleBarMenuBar.handleKeyArrowRight',
|
|
1616
|
+
when: FocusTitleBarMenuBar
|
|
1617
|
+
}, {
|
|
1618
|
+
key: LeftArrow$1,
|
|
1619
|
+
command: 'TitleBarMenuBar.handleKeyArrowLeft',
|
|
1620
|
+
when: FocusTitleBarMenuBar
|
|
1621
|
+
}, {
|
|
1622
|
+
key: Space$1,
|
|
1623
|
+
command: 'TitleBarMenuBar.handleKeySpace',
|
|
1624
|
+
when: FocusTitleBarMenuBar
|
|
1625
|
+
}, {
|
|
1626
|
+
key: Home$1,
|
|
1627
|
+
command: 'TitleBarMenuBar.handleKeyHome',
|
|
1628
|
+
when: FocusTitleBarMenuBar
|
|
1629
|
+
}, {
|
|
1630
|
+
key: End$1,
|
|
1631
|
+
command: 'TitleBarMenuBar.handleKeyEnd',
|
|
1632
|
+
when: FocusTitleBarMenuBar
|
|
1633
|
+
}, {
|
|
1634
|
+
key: Escape$1,
|
|
1635
|
+
command: 'TitleBarMenuBar.handleKeyEscape',
|
|
1636
|
+
when: FocusTitleBarMenuBar
|
|
1637
|
+
}];
|
|
414
1638
|
};
|
|
415
|
-
|
|
416
|
-
|
|
1639
|
+
|
|
1640
|
+
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
1641
|
+
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
417
1642
|
};
|
|
418
|
-
|
|
419
|
-
|
|
1643
|
+
|
|
1644
|
+
const state$1 = {
|
|
1645
|
+
ctx: undefined
|
|
420
1646
|
};
|
|
421
|
-
const
|
|
422
|
-
|
|
1647
|
+
const getOrCreate = createCtx => {
|
|
1648
|
+
if (state$1.ctx) {
|
|
1649
|
+
return state$1.ctx;
|
|
1650
|
+
}
|
|
1651
|
+
state$1.ctx = createCtx();
|
|
1652
|
+
return state$1.ctx;
|
|
423
1653
|
};
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
1654
|
+
|
|
1655
|
+
const createCtx = () => {
|
|
1656
|
+
const canvas = new OffscreenCanvas(0, 0);
|
|
1657
|
+
const ctx = /** @type {OffscreenCanvasRenderingContext2D} */canvas.getContext('2d');
|
|
1658
|
+
if (!ctx) {
|
|
1659
|
+
throw new Error('Failed to get canvas context 2d');
|
|
430
1660
|
}
|
|
431
|
-
return
|
|
1661
|
+
return ctx;
|
|
432
1662
|
};
|
|
433
|
-
const
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
return transferrables;
|
|
1663
|
+
const getContext = () => {
|
|
1664
|
+
const ctx = getOrCreate(createCtx);
|
|
1665
|
+
return ctx;
|
|
437
1666
|
};
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
throw new TypeError('module is not in web worker scope');
|
|
442
|
-
}
|
|
443
|
-
return globalThis;
|
|
1667
|
+
|
|
1668
|
+
const px = value => {
|
|
1669
|
+
return `${value}px`;
|
|
444
1670
|
};
|
|
445
|
-
|
|
446
|
-
|
|
1671
|
+
|
|
1672
|
+
const getLetterSpacingString = letterSpacing => {
|
|
1673
|
+
return px(letterSpacing);
|
|
447
1674
|
};
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const transfer = getTransferrables(message);
|
|
458
|
-
// @ts-ignore
|
|
459
|
-
this._rawIpc.postMessage(message, transfer);
|
|
460
|
-
}
|
|
461
|
-
dispose() {
|
|
462
|
-
// ignore
|
|
463
|
-
}
|
|
464
|
-
onClose(callback) {
|
|
465
|
-
// ignore
|
|
466
|
-
}
|
|
467
|
-
onMessage(callback) {
|
|
468
|
-
this._rawIpc.addEventListener('message', callback);
|
|
1675
|
+
const measureTextWidth = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
1676
|
+
string(text);
|
|
1677
|
+
number(fontWeight);
|
|
1678
|
+
number(fontSize);
|
|
1679
|
+
string(fontFamily);
|
|
1680
|
+
boolean(isMonoSpaceFont);
|
|
1681
|
+
number(charWidth);
|
|
1682
|
+
if (typeof letterSpacing !== 'number') {
|
|
1683
|
+
throw new TypeError('letterSpacing must be of type number');
|
|
469
1684
|
}
|
|
470
|
-
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
const
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
1685
|
+
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
1686
|
+
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
1687
|
+
const ctx = getContext();
|
|
1688
|
+
// @ts-ignore
|
|
1689
|
+
ctx.letterSpacing = letterSpacingString;
|
|
1690
|
+
ctx.font = fontString;
|
|
1691
|
+
const metrics = ctx.measureText(text);
|
|
1692
|
+
const {
|
|
1693
|
+
width
|
|
1694
|
+
} = metrics;
|
|
1695
|
+
return width;
|
|
480
1696
|
};
|
|
481
|
-
|
|
482
|
-
|
|
1697
|
+
|
|
1698
|
+
const measureTitleBarEntryWidth = (label, fontWeight, fontSize, fontFamily, letterSpacing) => {
|
|
1699
|
+
const isMonospaceFont = false;
|
|
1700
|
+
const charWidth = 0;
|
|
1701
|
+
return measureTextWidth(label, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
483
1702
|
};
|
|
484
|
-
|
|
485
|
-
|
|
1703
|
+
|
|
1704
|
+
const addWidths = (entries, labelPadding, fontWeight, fontSize, fontFamily, letterSpacing) => {
|
|
1705
|
+
const withWidths = [];
|
|
1706
|
+
for (const entry of entries) {
|
|
1707
|
+
const textWidth = measureTitleBarEntryWidth(entry.label, fontWeight, fontSize, fontFamily, letterSpacing);
|
|
1708
|
+
const width = textWidth + labelPadding * 2;
|
|
1709
|
+
withWidths.push({
|
|
1710
|
+
...entry,
|
|
1711
|
+
width
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1714
|
+
return withWidths;
|
|
486
1715
|
};
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const
|
|
490
|
-
|
|
1716
|
+
|
|
1717
|
+
const loadContent = async (state, titleBarEntries) => {
|
|
1718
|
+
const {
|
|
1719
|
+
labelFontFamily,
|
|
1720
|
+
labelFontSize,
|
|
1721
|
+
labelFontWeight,
|
|
1722
|
+
labelLetterSpacing,
|
|
1723
|
+
labelPadding
|
|
1724
|
+
} = state;
|
|
1725
|
+
const withWidths = addWidths(titleBarEntries, labelPadding, labelFontWeight, labelFontSize, labelFontFamily, labelLetterSpacing);
|
|
491
1726
|
return {
|
|
492
|
-
|
|
493
|
-
|
|
1727
|
+
...state,
|
|
1728
|
+
titleBarEntries: withWidths
|
|
494
1729
|
};
|
|
495
1730
|
};
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
1731
|
+
|
|
1732
|
+
/**
|
|
1733
|
+
* @enum {string}
|
|
1734
|
+
*/
|
|
1735
|
+
const UiStrings$2 = {
|
|
1736
|
+
Copy: 'Copy',
|
|
1737
|
+
CopyLineDown: 'Copy Line Down',
|
|
1738
|
+
CopyLineUp: 'Copy Line Up',
|
|
1739
|
+
Cut: 'Cut',
|
|
1740
|
+
MoveLineDown: 'Move Line Down',
|
|
1741
|
+
MoveLineUp: 'Move Line Up',
|
|
1742
|
+
Paste: 'Paste',
|
|
1743
|
+
Redo: 'Redo',
|
|
1744
|
+
SelectAll: 'Select All',
|
|
1745
|
+
ToggleBlockComment: 'Toggle Block Comment',
|
|
1746
|
+
ToggleLineComment: 'Toggle Line Comment',
|
|
1747
|
+
Undo: 'Undo'};
|
|
1748
|
+
const cut = () => {
|
|
1749
|
+
return i18nString(UiStrings$2.Cut);
|
|
1750
|
+
};
|
|
1751
|
+
const copy = () => {
|
|
1752
|
+
return i18nString(UiStrings$2.Copy);
|
|
1753
|
+
};
|
|
1754
|
+
const paste = () => {
|
|
1755
|
+
return i18nString(UiStrings$2.Paste);
|
|
1756
|
+
};
|
|
1757
|
+
const undo = () => {
|
|
1758
|
+
return i18nString(UiStrings$2.Undo);
|
|
1759
|
+
};
|
|
1760
|
+
const redo = () => {
|
|
1761
|
+
return i18nString(UiStrings$2.Redo);
|
|
1762
|
+
};
|
|
1763
|
+
const toggleLineComment = () => {
|
|
1764
|
+
return i18nString(UiStrings$2.ToggleLineComment);
|
|
1765
|
+
};
|
|
1766
|
+
const toggleBlockComment = () => {
|
|
1767
|
+
return i18nString(UiStrings$2.ToggleBlockComment);
|
|
1768
|
+
};
|
|
1769
|
+
const selectAll = () => {
|
|
1770
|
+
return i18nString(UiStrings$2.SelectAll);
|
|
1771
|
+
};
|
|
1772
|
+
const copyLineUp = () => {
|
|
1773
|
+
return i18nString(UiStrings$2.CopyLineUp);
|
|
1774
|
+
};
|
|
1775
|
+
const copyLineDown = () => {
|
|
1776
|
+
return i18nString(UiStrings$2.CopyLineDown);
|
|
1777
|
+
};
|
|
1778
|
+
const moveLineUp = () => {
|
|
1779
|
+
return i18nString(UiStrings$2.MoveLineUp);
|
|
1780
|
+
};
|
|
1781
|
+
const moveLineDown = () => {
|
|
1782
|
+
return i18nString(UiStrings$2.MoveLineDown);
|
|
504
1783
|
};
|
|
505
|
-
|
|
506
|
-
|
|
1784
|
+
|
|
1785
|
+
const Edit = 2;
|
|
1786
|
+
const File = 5;
|
|
1787
|
+
const Go = 6;
|
|
1788
|
+
const Help = 7;
|
|
1789
|
+
const OpenRecent = 9;
|
|
1790
|
+
const Run = 10;
|
|
1791
|
+
const Selection = 11;
|
|
1792
|
+
const Terminal = 14;
|
|
1793
|
+
const TitleBar = 15;
|
|
1794
|
+
const View = 16;
|
|
1795
|
+
|
|
1796
|
+
const menuEntrySeparator = {
|
|
1797
|
+
id: 'separator',
|
|
1798
|
+
label: '',
|
|
1799
|
+
flags: Separator,
|
|
1800
|
+
command: ''
|
|
507
1801
|
};
|
|
508
|
-
|
|
509
|
-
|
|
1802
|
+
|
|
1803
|
+
const id$9 = Edit;
|
|
1804
|
+
const getMenuEntries$c = () => {
|
|
1805
|
+
return [{
|
|
1806
|
+
id: 'undo',
|
|
1807
|
+
label: undo(),
|
|
1808
|
+
flags: Disabled,
|
|
1809
|
+
command: /* TODO */-1
|
|
1810
|
+
}, {
|
|
1811
|
+
id: 'redo',
|
|
1812
|
+
label: redo(),
|
|
1813
|
+
flags: Disabled,
|
|
1814
|
+
command: /* TODO */-1
|
|
1815
|
+
}, menuEntrySeparator, {
|
|
1816
|
+
id: 'cut',
|
|
1817
|
+
label: cut(),
|
|
1818
|
+
flags: None,
|
|
1819
|
+
command: /* Editor.cut */'Editor.cut'
|
|
1820
|
+
}, {
|
|
1821
|
+
id: 'copy',
|
|
1822
|
+
label: copy(),
|
|
1823
|
+
flags: None,
|
|
1824
|
+
command: /* Editor.copy */'Editor.copy'
|
|
1825
|
+
}, {
|
|
1826
|
+
id: 'paste',
|
|
1827
|
+
label: paste(),
|
|
1828
|
+
flags: None,
|
|
1829
|
+
command: /* Editor.paste */'Editor.paste'
|
|
1830
|
+
}, menuEntrySeparator, {
|
|
1831
|
+
id: 'toggle-line-comment',
|
|
1832
|
+
label: toggleLineComment(),
|
|
1833
|
+
flags: None,
|
|
1834
|
+
command: /* Editor.toggleLineComment */'Editor.toggleLineComment'
|
|
1835
|
+
}, {
|
|
1836
|
+
id: 'toggle-block-comment',
|
|
1837
|
+
label: toggleBlockComment(),
|
|
1838
|
+
flags: None,
|
|
1839
|
+
command: /* Editor.toggleBlockComment */'Editor.toggleBlockComment'
|
|
1840
|
+
}];
|
|
510
1841
|
};
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
517
|
-
return relevantMessage;
|
|
1842
|
+
|
|
1843
|
+
const MenuEntriesEdit = {
|
|
1844
|
+
__proto__: null,
|
|
1845
|
+
getMenuEntries: getMenuEntries$c,
|
|
1846
|
+
id: id$9
|
|
518
1847
|
};
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
1848
|
+
|
|
1849
|
+
/**
|
|
1850
|
+
* @enum {string}
|
|
1851
|
+
*/
|
|
1852
|
+
const UiStrings$1 = {
|
|
1853
|
+
NewFile: 'New File',
|
|
1854
|
+
NewWindow: 'New Window',
|
|
1855
|
+
OpenFile: 'Open File',
|
|
1856
|
+
OpenFolder: 'Open Folder',
|
|
1857
|
+
OpenRecent: 'Open Recent',
|
|
1858
|
+
Save: 'Save',
|
|
1859
|
+
SaveAll: 'Save All'
|
|
525
1860
|
};
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
return false;
|
|
529
|
-
}
|
|
530
|
-
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
1861
|
+
const newFile = () => {
|
|
1862
|
+
return i18nString(UiStrings$1.NewFile);
|
|
531
1863
|
};
|
|
532
|
-
const
|
|
533
|
-
return
|
|
534
|
-
message: `ES Modules are not supported in electron`,
|
|
535
|
-
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
536
|
-
};
|
|
1864
|
+
const newWindow = () => {
|
|
1865
|
+
return i18nString(UiStrings$1.NewWindow);
|
|
537
1866
|
};
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
return false;
|
|
541
|
-
}
|
|
542
|
-
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
1867
|
+
const openFile = () => {
|
|
1868
|
+
return i18nString(UiStrings$1.OpenFile);
|
|
543
1869
|
};
|
|
544
|
-
const
|
|
545
|
-
return
|
|
1870
|
+
const openFolder = () => {
|
|
1871
|
+
return i18nString(UiStrings$1.OpenFolder);
|
|
546
1872
|
};
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
if (index === -1) {
|
|
550
|
-
return {
|
|
551
|
-
actualMessage: joinLines(lines),
|
|
552
|
-
rest: []
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
let lastIndex = index - 1;
|
|
556
|
-
while (++lastIndex < lines.length) {
|
|
557
|
-
if (!isNormalStackLine(lines[lastIndex])) {
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
return {
|
|
562
|
-
actualMessage: lines[index - 1],
|
|
563
|
-
rest: lines.slice(index, lastIndex)
|
|
564
|
-
};
|
|
1873
|
+
const openRecent = () => {
|
|
1874
|
+
return i18nString(UiStrings$1.OpenRecent);
|
|
565
1875
|
};
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
return getNativeModuleErrorMessage(stderr);
|
|
569
|
-
}
|
|
570
|
-
if (isModulesSyntaxError(stderr)) {
|
|
571
|
-
return getModuleSyntaxError();
|
|
572
|
-
}
|
|
573
|
-
if (isModuleNotFoundError(stderr)) {
|
|
574
|
-
return getModuleNotFoundError(stderr);
|
|
575
|
-
}
|
|
576
|
-
const lines = splitLines(stderr);
|
|
577
|
-
const {
|
|
578
|
-
actualMessage,
|
|
579
|
-
rest
|
|
580
|
-
} = getDetails(lines);
|
|
581
|
-
return {
|
|
582
|
-
message: `${actualMessage}`,
|
|
583
|
-
code: '',
|
|
584
|
-
stack: rest
|
|
585
|
-
};
|
|
1876
|
+
const save = () => {
|
|
1877
|
+
return i18nString(UiStrings$1.Save);
|
|
586
1878
|
};
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
return line.slice('Error: '.length);
|
|
590
|
-
}
|
|
591
|
-
if (line.startsWith('VError: ')) {
|
|
592
|
-
return line.slice('VError: '.length);
|
|
593
|
-
}
|
|
594
|
-
return line;
|
|
1879
|
+
const saveAll = () => {
|
|
1880
|
+
return i18nString(UiStrings$1.SaveAll);
|
|
595
1881
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
1882
|
+
|
|
1883
|
+
const platform = 1;
|
|
1884
|
+
|
|
1885
|
+
const Web = 1;
|
|
1886
|
+
|
|
1887
|
+
const id$8 = File;
|
|
1888
|
+
const getMenuEntries$b = () => {
|
|
1889
|
+
const entries = [{
|
|
1890
|
+
id: 'newFile',
|
|
1891
|
+
label: newFile(),
|
|
1892
|
+
flags: None,
|
|
1893
|
+
command: -1
|
|
1894
|
+
}, {
|
|
1895
|
+
id: 'newWindow',
|
|
1896
|
+
label: newWindow(),
|
|
1897
|
+
flags: None,
|
|
1898
|
+
command: /* Window.openNew */'Window.openNew'
|
|
1899
|
+
}, menuEntrySeparator, {
|
|
1900
|
+
id: 'openFile',
|
|
1901
|
+
label: openFile(),
|
|
1902
|
+
flags: None,
|
|
1903
|
+
command: 'Dialog.openFile'
|
|
1904
|
+
}, {
|
|
1905
|
+
id: 'openFolder',
|
|
1906
|
+
label: openFolder(),
|
|
1907
|
+
flags: RestoreFocus,
|
|
1908
|
+
command: 'Dialog.openFolder'
|
|
1909
|
+
}, {
|
|
1910
|
+
id: OpenRecent,
|
|
1911
|
+
label: openRecent(),
|
|
1912
|
+
flags: SubMenu,
|
|
1913
|
+
command: ''
|
|
1914
|
+
}, menuEntrySeparator, {
|
|
1915
|
+
id: 'save',
|
|
1916
|
+
label: save(),
|
|
1917
|
+
flags: None,
|
|
1918
|
+
command: 'Main.save'
|
|
1919
|
+
}, {
|
|
1920
|
+
id: 'saveAll',
|
|
1921
|
+
label: saveAll(),
|
|
1922
|
+
flags: None,
|
|
1923
|
+
command: 'Main.saveAll'
|
|
1924
|
+
}];
|
|
1925
|
+
return entries;
|
|
602
1926
|
};
|
|
603
|
-
|
|
604
|
-
const
|
|
605
|
-
|
|
1927
|
+
|
|
1928
|
+
const MenuEntriesFile = {
|
|
1929
|
+
__proto__: null,
|
|
1930
|
+
getMenuEntries: getMenuEntries$b,
|
|
1931
|
+
id: id$8
|
|
606
1932
|
};
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const parentNewLineIndex = getNewLineIndex(parent);
|
|
612
|
-
const childNewLineIndex = getNewLineIndex(child);
|
|
613
|
-
if (childNewLineIndex === -1) {
|
|
614
|
-
return parent;
|
|
615
|
-
}
|
|
616
|
-
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
617
|
-
const childRest = child.slice(childNewLineIndex);
|
|
618
|
-
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
619
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
620
|
-
return parentFirstLine + childRest;
|
|
621
|
-
}
|
|
622
|
-
return child;
|
|
1933
|
+
|
|
1934
|
+
const id$7 = Go;
|
|
1935
|
+
const getMenuEntries$a = () => {
|
|
1936
|
+
return [];
|
|
623
1937
|
};
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (error instanceof Error) {
|
|
630
|
-
this.stack = mergeStacks(this.stack, error.stack);
|
|
631
|
-
}
|
|
632
|
-
if (error.codeFrame) {
|
|
633
|
-
// @ts-ignore
|
|
634
|
-
this.codeFrame = error.codeFrame;
|
|
635
|
-
}
|
|
636
|
-
if (error.code) {
|
|
637
|
-
// @ts-ignore
|
|
638
|
-
this.code = error.code;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
class IpcError extends VError {
|
|
643
|
-
// @ts-ignore
|
|
644
|
-
constructor(betterMessage, stdout = '', stderr = '') {
|
|
645
|
-
if (stdout || stderr) {
|
|
646
|
-
// @ts-ignore
|
|
647
|
-
const {
|
|
648
|
-
message,
|
|
649
|
-
code,
|
|
650
|
-
stack
|
|
651
|
-
} = getHelpfulChildProcessError(stdout, stderr);
|
|
652
|
-
const cause = new Error(message);
|
|
653
|
-
// @ts-ignore
|
|
654
|
-
cause.code = code;
|
|
655
|
-
cause.stack = stack;
|
|
656
|
-
super(cause, betterMessage);
|
|
657
|
-
} else {
|
|
658
|
-
super(betterMessage);
|
|
659
|
-
}
|
|
660
|
-
// @ts-ignore
|
|
661
|
-
this.name = 'IpcError';
|
|
662
|
-
// @ts-ignore
|
|
663
|
-
this.stdout = stdout;
|
|
664
|
-
// @ts-ignore
|
|
665
|
-
this.stderr = stderr;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
const withResolvers = () => {
|
|
669
|
-
let _resolve;
|
|
670
|
-
const promise = new Promise(resolve => {
|
|
671
|
-
_resolve = resolve;
|
|
672
|
-
});
|
|
673
|
-
return {
|
|
674
|
-
resolve: _resolve,
|
|
675
|
-
promise
|
|
676
|
-
};
|
|
1938
|
+
|
|
1939
|
+
const MenuEntriesGo = {
|
|
1940
|
+
__proto__: null,
|
|
1941
|
+
getMenuEntries: getMenuEntries$a,
|
|
1942
|
+
id: id$7
|
|
677
1943
|
};
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
promise
|
|
682
|
-
} = withResolvers();
|
|
683
|
-
port.addEventListener('message', resolve, {
|
|
684
|
-
once: true
|
|
685
|
-
});
|
|
686
|
-
const event = await promise;
|
|
687
|
-
// @ts-ignore
|
|
688
|
-
return event.data;
|
|
1944
|
+
|
|
1945
|
+
const checkForUpdates = () => {
|
|
1946
|
+
return i18nString(CheckForUpdates);
|
|
689
1947
|
};
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
signal$2(parentIpcRaw);
|
|
693
|
-
const parentIpc = wrap$5(parentIpcRaw);
|
|
694
|
-
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
695
|
-
if (firstMessage.method !== 'initialize') {
|
|
696
|
-
throw new IpcError('unexpected first message');
|
|
697
|
-
}
|
|
698
|
-
const type = firstMessage.params[0];
|
|
699
|
-
if (type === 'message-port') {
|
|
700
|
-
parentIpc.send({
|
|
701
|
-
jsonrpc: '2.0',
|
|
702
|
-
id: firstMessage.id,
|
|
703
|
-
result: null
|
|
704
|
-
});
|
|
705
|
-
parentIpc.dispose();
|
|
706
|
-
const port = firstMessage.params[1];
|
|
707
|
-
return port;
|
|
708
|
-
}
|
|
709
|
-
return globalThis;
|
|
1948
|
+
const about = () => {
|
|
1949
|
+
return i18nString(About);
|
|
710
1950
|
};
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
getData(event) {
|
|
716
|
-
return getData$1(event);
|
|
717
|
-
}
|
|
718
|
-
send(message) {
|
|
719
|
-
this._rawIpc.postMessage(message);
|
|
720
|
-
}
|
|
721
|
-
sendAndTransfer(message) {
|
|
722
|
-
const transfer = getTransferrables(message);
|
|
723
|
-
this._rawIpc.postMessage(message, transfer);
|
|
724
|
-
}
|
|
725
|
-
dispose() {
|
|
726
|
-
if (this._rawIpc.close) {
|
|
727
|
-
this._rawIpc.close();
|
|
728
|
-
}
|
|
1951
|
+
|
|
1952
|
+
const isAutoUpdateSupported = () => {
|
|
1953
|
+
{
|
|
1954
|
+
return false;
|
|
729
1955
|
}
|
|
730
|
-
|
|
731
|
-
|
|
1956
|
+
};
|
|
1957
|
+
|
|
1958
|
+
const id$6 = Help;
|
|
1959
|
+
const getMenuEntries$9 = async () => {
|
|
1960
|
+
const autoUpdateSupported = isAutoUpdateSupported();
|
|
1961
|
+
const entries = [];
|
|
1962
|
+
if (autoUpdateSupported) {
|
|
1963
|
+
entries.push(menuEntrySeparator, {
|
|
1964
|
+
id: 'checkForUpdates',
|
|
1965
|
+
label: checkForUpdates(),
|
|
1966
|
+
flags: RestoreFocus,
|
|
1967
|
+
command: 'AutoUpdater.checkForUpdates'
|
|
1968
|
+
});
|
|
732
1969
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
this._rawIpc.start();
|
|
1970
|
+
if (entries.length > 0) {
|
|
1971
|
+
entries.push(menuEntrySeparator);
|
|
736
1972
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
wrap: wrap$4
|
|
1973
|
+
entries.push({
|
|
1974
|
+
id: 'about',
|
|
1975
|
+
label: about(),
|
|
1976
|
+
flags: RestoreFocus,
|
|
1977
|
+
command: 'About.showAbout'
|
|
1978
|
+
});
|
|
1979
|
+
return entries;
|
|
745
1980
|
};
|
|
746
1981
|
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
*/
|
|
752
|
-
send(method, ...params) {
|
|
753
|
-
send(ipc, method, ...params);
|
|
754
|
-
},
|
|
755
|
-
invoke(method, ...params) {
|
|
756
|
-
return invoke(ipc, method, ...params);
|
|
757
|
-
},
|
|
758
|
-
invokeAndTransfer(method, ...params) {
|
|
759
|
-
return invokeAndTransfer(ipc, method, ...params);
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
return rpc;
|
|
763
|
-
};
|
|
764
|
-
const requiresSocket = () => {
|
|
765
|
-
return false;
|
|
1982
|
+
const MenuEntriesHelp = {
|
|
1983
|
+
__proto__: null,
|
|
1984
|
+
getMenuEntries: getMenuEntries$9,
|
|
1985
|
+
id: id$6
|
|
766
1986
|
};
|
|
767
|
-
|
|
768
|
-
|
|
1987
|
+
|
|
1988
|
+
const state = {
|
|
1989
|
+
rpc: undefined
|
|
769
1990
|
};
|
|
770
|
-
const
|
|
771
|
-
|
|
1991
|
+
const invoke = (method, ...params) => {
|
|
1992
|
+
const {
|
|
1993
|
+
rpc
|
|
1994
|
+
} = state;
|
|
1995
|
+
// @ts-ignore
|
|
1996
|
+
return rpc.invoke(method, ...params);
|
|
772
1997
|
};
|
|
773
|
-
const
|
|
774
|
-
|
|
1998
|
+
const setRpc = rpc => {
|
|
1999
|
+
state.rpc = rpc;
|
|
775
2000
|
};
|
|
776
|
-
|
|
777
|
-
|
|
2001
|
+
|
|
2002
|
+
const getTitle = uri => {
|
|
2003
|
+
if (!uri) {
|
|
2004
|
+
return '';
|
|
2005
|
+
}
|
|
2006
|
+
return uri;
|
|
778
2007
|
};
|
|
779
2008
|
|
|
780
|
-
|
|
781
|
-
const
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
2009
|
+
const MAX_MENU_RECENT_ENTRIES = 10;
|
|
2010
|
+
const toMenuItem = folder => {
|
|
2011
|
+
const label = getTitle(folder);
|
|
2012
|
+
return {
|
|
2013
|
+
label,
|
|
2014
|
+
flags: None,
|
|
2015
|
+
command: 'Workspace.setPath',
|
|
2016
|
+
args: [folder]
|
|
2017
|
+
};
|
|
786
2018
|
};
|
|
787
|
-
const
|
|
788
|
-
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
const
|
|
795
|
-
|
|
2019
|
+
const getRecentlyOpened = () => {
|
|
2020
|
+
return invoke(/* RecentlyOpened.getRecentlyOpened */'RecentlyOpened.getRecentlyOpened');
|
|
2021
|
+
};
|
|
2022
|
+
const id$5 = OpenRecent;
|
|
2023
|
+
const getMenuEntries$8 = async () => {
|
|
2024
|
+
const allItems = await getRecentlyOpened();
|
|
2025
|
+
const itemsToShow = allItems.slice(0, MAX_MENU_RECENT_ENTRIES);
|
|
2026
|
+
const items = [];
|
|
2027
|
+
if (itemsToShow.length > 0) {
|
|
2028
|
+
items.push(...itemsToShow.map(toMenuItem), menuEntrySeparator);
|
|
2029
|
+
}
|
|
2030
|
+
items.push({
|
|
2031
|
+
id: 'more',
|
|
2032
|
+
label: moreDot(),
|
|
2033
|
+
flags: None,
|
|
2034
|
+
command: 'QuickPick.showRecent'
|
|
2035
|
+
}, menuEntrySeparator, {
|
|
2036
|
+
id: 'clearRecentlyOpened',
|
|
2037
|
+
label: clearRecentlyOpened(),
|
|
2038
|
+
flags: None,
|
|
2039
|
+
command: 'RecentlyOpened.clearRecentlyOpened'
|
|
2040
|
+
});
|
|
2041
|
+
return items;
|
|
796
2042
|
};
|
|
797
|
-
|
|
2043
|
+
|
|
2044
|
+
const MenuEntriesOpenRecent = {
|
|
798
2045
|
__proto__: null,
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
const Enter = 3;
|
|
803
|
-
const Escape = 8;
|
|
804
|
-
const Space = 9;
|
|
805
|
-
const End = 255;
|
|
806
|
-
const Home = 12;
|
|
807
|
-
const LeftArrow = 13;
|
|
808
|
-
const UpArrow = 14;
|
|
809
|
-
const RightArrow = 15;
|
|
810
|
-
const DownArrow = 16;
|
|
811
|
-
const Delete = 18;
|
|
812
|
-
const KeyC = 31;
|
|
813
|
-
const KeyV = 50;
|
|
814
|
-
const F2 = 58;
|
|
815
|
-
const Star = 131;
|
|
2046
|
+
getMenuEntries: getMenuEntries$8,
|
|
2047
|
+
id: id$5
|
|
2048
|
+
};
|
|
816
2049
|
|
|
817
|
-
const
|
|
818
|
-
const
|
|
2050
|
+
const id$4 = Run;
|
|
2051
|
+
const getMenuEntries$7 = () => {
|
|
2052
|
+
return [];
|
|
2053
|
+
};
|
|
819
2054
|
|
|
820
|
-
const
|
|
821
|
-
|
|
2055
|
+
const MenuEntriesRun = {
|
|
2056
|
+
__proto__: null,
|
|
2057
|
+
getMenuEntries: getMenuEntries$7,
|
|
2058
|
+
id: id$4
|
|
2059
|
+
};
|
|
822
2060
|
|
|
823
|
-
const
|
|
2061
|
+
const id$3 = Selection;
|
|
2062
|
+
const getMenuEntries$6 = () => {
|
|
824
2063
|
return [{
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
key: LeftArrow,
|
|
830
|
-
command: 'Explorer.handleArrowLeft',
|
|
831
|
-
when: FocusExplorer
|
|
2064
|
+
id: 'selectAll',
|
|
2065
|
+
label: selectAll(),
|
|
2066
|
+
flags: None,
|
|
2067
|
+
command: 'Editor.selectAll'
|
|
832
2068
|
}, {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
2069
|
+
id: 'copyLineUp',
|
|
2070
|
+
label: copyLineUp(),
|
|
2071
|
+
flags: None,
|
|
2072
|
+
command: 'Editor.copyLineUp'
|
|
836
2073
|
}, {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
2074
|
+
id: 'copyLineDown',
|
|
2075
|
+
label: copyLineDown(),
|
|
2076
|
+
flags: None,
|
|
2077
|
+
command: 'Editor.copyLineDown'
|
|
840
2078
|
}, {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
2079
|
+
id: 'moveLineUp',
|
|
2080
|
+
label: moveLineUp(),
|
|
2081
|
+
flags: Disabled,
|
|
2082
|
+
command: 'Editor.moveLineUp'
|
|
844
2083
|
}, {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
2084
|
+
id: 'moveLineDown',
|
|
2085
|
+
label: moveLineDown(),
|
|
2086
|
+
flags: Disabled,
|
|
2087
|
+
command: 'Editor.moveLineDown'
|
|
2088
|
+
}];
|
|
2089
|
+
};
|
|
2090
|
+
|
|
2091
|
+
const MenuEntriesSelection = {
|
|
2092
|
+
__proto__: null,
|
|
2093
|
+
getMenuEntries: getMenuEntries$6,
|
|
2094
|
+
id: id$3
|
|
2095
|
+
};
|
|
2096
|
+
|
|
2097
|
+
/**
|
|
2098
|
+
* @enum {string}
|
|
2099
|
+
*/
|
|
2100
|
+
const UiStrings = {
|
|
2101
|
+
NewTerminal: 'New Terminal'
|
|
2102
|
+
};
|
|
2103
|
+
const newTerminal = () => {
|
|
2104
|
+
return i18nString(UiStrings.NewTerminal);
|
|
2105
|
+
};
|
|
2106
|
+
|
|
2107
|
+
const id$2 = Terminal;
|
|
2108
|
+
const getMenuEntries$5 = () => {
|
|
2109
|
+
return [{
|
|
2110
|
+
id: 'newTerminal',
|
|
2111
|
+
label: newTerminal(),
|
|
2112
|
+
flags: None,
|
|
2113
|
+
command: 'Layout.togglePanel',
|
|
2114
|
+
args: ['Terminal']
|
|
2115
|
+
}];
|
|
2116
|
+
};
|
|
2117
|
+
|
|
2118
|
+
const MenuEntriesTerminal = {
|
|
2119
|
+
__proto__: null,
|
|
2120
|
+
getMenuEntries: getMenuEntries$5,
|
|
2121
|
+
id: id$2
|
|
2122
|
+
};
|
|
2123
|
+
|
|
2124
|
+
const file = () => {
|
|
2125
|
+
return i18nString(File$1);
|
|
2126
|
+
};
|
|
2127
|
+
const edit = () => {
|
|
2128
|
+
return i18nString(Edit$1);
|
|
2129
|
+
};
|
|
2130
|
+
const selection = () => {
|
|
2131
|
+
return i18nString(Selection$1);
|
|
2132
|
+
};
|
|
2133
|
+
const view = () => {
|
|
2134
|
+
return i18nString(View$1);
|
|
2135
|
+
};
|
|
2136
|
+
const go = () => {
|
|
2137
|
+
return i18nString(Go$1);
|
|
2138
|
+
};
|
|
2139
|
+
const run = () => {
|
|
2140
|
+
return i18nString(Run$1);
|
|
2141
|
+
};
|
|
2142
|
+
const terminal = () => {
|
|
2143
|
+
return i18nString(Terminal$1);
|
|
2144
|
+
};
|
|
2145
|
+
const help = () => {
|
|
2146
|
+
return i18nString(Help$1);
|
|
2147
|
+
};
|
|
2148
|
+
|
|
2149
|
+
const getMenuEntries$4 = () => {
|
|
2150
|
+
return [{
|
|
2151
|
+
id: File,
|
|
2152
|
+
label: file(),
|
|
2153
|
+
flags: SubMenu
|
|
848
2154
|
}, {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
2155
|
+
id: Edit,
|
|
2156
|
+
label: edit(),
|
|
2157
|
+
flags: SubMenu
|
|
852
2158
|
}, {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
2159
|
+
id: Selection,
|
|
2160
|
+
label: selection(),
|
|
2161
|
+
flags: SubMenu
|
|
856
2162
|
}, {
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
2163
|
+
id: View,
|
|
2164
|
+
label: view(),
|
|
2165
|
+
flags: SubMenu
|
|
860
2166
|
}, {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
2167
|
+
id: Go,
|
|
2168
|
+
label: go(),
|
|
2169
|
+
flags: SubMenu
|
|
864
2170
|
}, {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
2171
|
+
id: Run,
|
|
2172
|
+
label: run(),
|
|
2173
|
+
keyboardShortCut: 'Alt+r',
|
|
2174
|
+
flags: SubMenu
|
|
868
2175
|
}, {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
2176
|
+
id: Terminal,
|
|
2177
|
+
label: terminal(),
|
|
2178
|
+
keyboardShortCut: 'Alt+t',
|
|
2179
|
+
flags: SubMenu
|
|
872
2180
|
}, {
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
2181
|
+
id: Help,
|
|
2182
|
+
label: help(),
|
|
2183
|
+
keyboardShortCut: 'Alt+h',
|
|
2184
|
+
flags: SubMenu
|
|
2185
|
+
}];
|
|
2186
|
+
};
|
|
2187
|
+
|
|
2188
|
+
const getMenuEntries$3 = () => {
|
|
2189
|
+
return [{
|
|
2190
|
+
id: File,
|
|
2191
|
+
label: file(),
|
|
2192
|
+
flags: None
|
|
876
2193
|
}, {
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
2194
|
+
id: Edit,
|
|
2195
|
+
label: edit(),
|
|
2196
|
+
flags: None
|
|
880
2197
|
}, {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
2198
|
+
id: Selection,
|
|
2199
|
+
label: selection(),
|
|
2200
|
+
flags: None
|
|
884
2201
|
}, {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
2202
|
+
id: View,
|
|
2203
|
+
label: view(),
|
|
2204
|
+
flags: None
|
|
888
2205
|
}, {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
2206
|
+
id: Go,
|
|
2207
|
+
label: go(),
|
|
2208
|
+
flags: None
|
|
892
2209
|
}, {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
2210
|
+
id: Help,
|
|
2211
|
+
label: help(),
|
|
2212
|
+
flags: None
|
|
896
2213
|
}];
|
|
897
2214
|
};
|
|
898
2215
|
|
|
899
|
-
const
|
|
900
|
-
|
|
2216
|
+
const getFn = () => {
|
|
2217
|
+
switch (platform) {
|
|
2218
|
+
case Web:
|
|
2219
|
+
return getMenuEntries$3;
|
|
2220
|
+
default:
|
|
2221
|
+
return getMenuEntries$4;
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
const id$1 = TitleBar;
|
|
2225
|
+
const getMenuEntries$2 = async () => {
|
|
2226
|
+
const fn = getFn();
|
|
2227
|
+
return fn();
|
|
2228
|
+
};
|
|
901
2229
|
|
|
902
|
-
const
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
2230
|
+
const MenuEntriesTitleBar = {
|
|
2231
|
+
__proto__: null,
|
|
2232
|
+
getMenuEntries: getMenuEntries$2,
|
|
2233
|
+
id: id$1
|
|
2234
|
+
};
|
|
907
2235
|
|
|
908
|
-
const
|
|
909
|
-
const
|
|
910
|
-
|
|
2236
|
+
const id = View;
|
|
2237
|
+
const getMenuEntries$1 = () => {
|
|
2238
|
+
return [];
|
|
2239
|
+
};
|
|
911
2240
|
|
|
912
|
-
const
|
|
913
|
-
|
|
2241
|
+
const MenuEntriesView = {
|
|
2242
|
+
__proto__: null,
|
|
2243
|
+
getMenuEntries: getMenuEntries$1,
|
|
2244
|
+
id
|
|
2245
|
+
};
|
|
914
2246
|
|
|
915
|
-
const
|
|
2247
|
+
const menus = [MenuEntriesEdit, MenuEntriesFile, MenuEntriesGo, MenuEntriesHelp, MenuEntriesRun, MenuEntriesSelection, MenuEntriesTerminal, MenuEntriesTitleBar, MenuEntriesView, MenuEntriesOpenRecent];
|
|
2248
|
+
const getMenus = () => {
|
|
2249
|
+
return menus;
|
|
2250
|
+
};
|
|
2251
|
+
const getMenuEntries = async (id, ...args) => {
|
|
2252
|
+
try {
|
|
2253
|
+
const module = menus[0];
|
|
2254
|
+
// @ts-ignore
|
|
2255
|
+
const inject = module.inject || [];
|
|
2256
|
+
// @ts-ignore
|
|
2257
|
+
return module.getMenuEntries(...args);
|
|
2258
|
+
} catch (error) {
|
|
2259
|
+
throw new VError(error, `Failed to load menu entries for id ${id}`);
|
|
2260
|
+
}
|
|
2261
|
+
};
|
|
2262
|
+
|
|
2263
|
+
const saveState = uid => {
|
|
2264
|
+
return {};
|
|
2265
|
+
};
|
|
2266
|
+
|
|
2267
|
+
const terminate = () => {
|
|
2268
|
+
globalThis.close();
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
const create = (id, uri, x, y, width, height) => {
|
|
2272
|
+
const state = {
|
|
2273
|
+
uid: id,
|
|
2274
|
+
titleBarEntries: [],
|
|
2275
|
+
focusedIndex: -1,
|
|
2276
|
+
isMenuOpen: false,
|
|
2277
|
+
menus: [],
|
|
2278
|
+
labelFontWeight: 400,
|
|
2279
|
+
labelFontSize: 13,
|
|
2280
|
+
labelFontFamily: 'system-ui, Ubuntu, Droid Sans, sans-serif',
|
|
2281
|
+
labelPadding: 8,
|
|
2282
|
+
labelLetterSpacing: 0,
|
|
2283
|
+
titleBarHeight: height,
|
|
2284
|
+
x,
|
|
2285
|
+
y,
|
|
2286
|
+
width,
|
|
2287
|
+
height
|
|
2288
|
+
};
|
|
2289
|
+
set(id, state, state);
|
|
2290
|
+
return state;
|
|
2291
|
+
};
|
|
2292
|
+
|
|
2293
|
+
const closeMenu = (state, keepFocus) => {
|
|
2294
|
+
const {
|
|
2295
|
+
focusedIndex
|
|
2296
|
+
} = state;
|
|
2297
|
+
// TODO send to renderer process
|
|
2298
|
+
// 1. close menu
|
|
2299
|
+
// 2. focus top level entry
|
|
2300
|
+
const newFocusedIndex = keepFocus ? focusedIndex : -1;
|
|
916
2301
|
return {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
2302
|
+
...state,
|
|
2303
|
+
menus: [],
|
|
2304
|
+
isMenuOpen: false,
|
|
2305
|
+
focusedIndex: newFocusedIndex
|
|
920
2306
|
};
|
|
921
2307
|
};
|
|
922
2308
|
|
|
923
|
-
const
|
|
924
|
-
|
|
2309
|
+
const first = () => {
|
|
2310
|
+
return 0;
|
|
2311
|
+
};
|
|
2312
|
+
const last = items => {
|
|
2313
|
+
return items.length - 1;
|
|
2314
|
+
};
|
|
2315
|
+
const next = (items, index) => {
|
|
2316
|
+
return (index + 1) % items.length;
|
|
2317
|
+
};
|
|
2318
|
+
const previous = (items, index) => {
|
|
2319
|
+
return index === 0 ? items.length - 1 : index - 1;
|
|
2320
|
+
};
|
|
2321
|
+
|
|
2322
|
+
const getTotalWidth = entries => {
|
|
2323
|
+
let total = 0;
|
|
2324
|
+
for (const entry of entries) {
|
|
2325
|
+
total += entry.width;
|
|
2326
|
+
}
|
|
2327
|
+
return total;
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
// TODO lazyload menuEntries and use Command.execute (maybe)
|
|
2331
|
+
const MENU_WIDTH = 150;
|
|
2332
|
+
const CONTEXT_MENU_ITEM_HEIGHT = 26;
|
|
2333
|
+
const CONTEXT_MENU_SEPARATOR_HEIGHT = 11;
|
|
2334
|
+
const CONTEXT_MENU_PADDING = 8;
|
|
2335
|
+
const CONTEXT_MENU_WIDTH = 250;
|
|
2336
|
+
const getMenuWidth = () => {
|
|
2337
|
+
return CONTEXT_MENU_WIDTH;
|
|
2338
|
+
};
|
|
2339
|
+
const getMenuHeight = items => {
|
|
2340
|
+
let height = CONTEXT_MENU_PADDING;
|
|
2341
|
+
for (const item of items) {
|
|
2342
|
+
switch (item.flags) {
|
|
2343
|
+
case Separator:
|
|
2344
|
+
height += CONTEXT_MENU_SEPARATOR_HEIGHT;
|
|
2345
|
+
break;
|
|
2346
|
+
default:
|
|
2347
|
+
height += CONTEXT_MENU_ITEM_HEIGHT;
|
|
2348
|
+
break;
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
return height;
|
|
2352
|
+
};
|
|
2353
|
+
|
|
2354
|
+
// TODO difference between focusing with mouse or keyboard
|
|
2355
|
+
// with mouse -> open submenu
|
|
2356
|
+
// with keyboard -> don't open submenu, only focus
|
|
2357
|
+
|
|
2358
|
+
const getIndexToFocusNextStartingAt = (items, startIndex) => {
|
|
2359
|
+
for (let i = startIndex; i < startIndex + items.length; i++) {
|
|
2360
|
+
const index = i % items.length;
|
|
2361
|
+
const item = items[index];
|
|
2362
|
+
if (canBeFocused(item)) {
|
|
2363
|
+
return index;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
return -1;
|
|
2367
|
+
};
|
|
2368
|
+
const getIndexToFocusFirst = items => {
|
|
2369
|
+
return getIndexToFocusNextStartingAt(items, 0);
|
|
2370
|
+
};
|
|
2371
|
+
const getIndexToFocusLast = items => {
|
|
2372
|
+
return getIndexToFocusPreviousStartingAt(items, items.length - 1);
|
|
2373
|
+
};
|
|
2374
|
+
|
|
2375
|
+
// TODO this code seems a bit too complicated, maybe it can be simplified
|
|
2376
|
+
const getIndexToFocusPreviousStartingAt = (items, startIndex) => {
|
|
2377
|
+
for (let i = startIndex; i > startIndex - items.length; i--) {
|
|
2378
|
+
const index = (i + items.length) % items.length;
|
|
2379
|
+
const item = items[index];
|
|
2380
|
+
if (canBeFocused(item)) {
|
|
2381
|
+
return index;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
return -1;
|
|
2385
|
+
};
|
|
2386
|
+
const getIndexToFocusPrevious = menu => {
|
|
2387
|
+
const startIndex = menu.focusedIndex === -1 ? menu.items.length - 1 : menu.focusedIndex - 1;
|
|
2388
|
+
return getIndexToFocusPreviousStartingAt(menu.items, startIndex);
|
|
2389
|
+
};
|
|
2390
|
+
const canBeFocused = item => {
|
|
2391
|
+
switch (item.flags) {
|
|
2392
|
+
case Separator:
|
|
2393
|
+
case Disabled:
|
|
2394
|
+
return false;
|
|
2395
|
+
default:
|
|
2396
|
+
return true;
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
const getIndexToFocusNext = menu => {
|
|
2400
|
+
const startIndex = menu.focusedIndex + 1;
|
|
2401
|
+
return getIndexToFocusNextStartingAt(menu.items, startIndex);
|
|
2402
|
+
};
|
|
2403
|
+
|
|
2404
|
+
// TODO handle printable letter and focus item that starts with that letter
|
|
2405
|
+
|
|
2406
|
+
// TODO pageup / pagedown keys
|
|
2407
|
+
|
|
2408
|
+
// TODO more tests
|
|
2409
|
+
|
|
2410
|
+
const openMenuAtIndex = async (state, index, shouldBeFocused) => {
|
|
925
2411
|
const {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
2412
|
+
titleBarEntries,
|
|
2413
|
+
titleBarHeight,
|
|
2414
|
+
x
|
|
2415
|
+
} = state;
|
|
2416
|
+
// TODO race conditions
|
|
2417
|
+
// TODO send renderer process
|
|
2418
|
+
// 1. open menu, items to show
|
|
2419
|
+
// 2. focus menu
|
|
2420
|
+
const titleBarEntry = titleBarEntries[index];
|
|
2421
|
+
const {
|
|
2422
|
+
id
|
|
2423
|
+
} = titleBarEntry;
|
|
2424
|
+
const items = await getMenuEntries(id);
|
|
2425
|
+
const relevantEntries = titleBarEntries.slice(0, index);
|
|
2426
|
+
const totalWidths = getTotalWidth(relevantEntries);
|
|
2427
|
+
const offset = totalWidths;
|
|
2428
|
+
// TODO race condition: another menu might already be open at this point
|
|
2429
|
+
|
|
2430
|
+
const menuX = x + offset;
|
|
2431
|
+
const menuY = titleBarHeight;
|
|
2432
|
+
const width = getMenuWidth();
|
|
2433
|
+
const height = getMenuHeight(items);
|
|
2434
|
+
const menuFocusedIndex = shouldBeFocused ? getIndexToFocusNextStartingAt(items, 0) : -1;
|
|
2435
|
+
const menu = {
|
|
2436
|
+
id,
|
|
2437
|
+
items,
|
|
2438
|
+
focusedIndex: menuFocusedIndex,
|
|
2439
|
+
level: 0,
|
|
2440
|
+
x: menuX,
|
|
2441
|
+
y: menuY,
|
|
2442
|
+
width,
|
|
2443
|
+
height
|
|
2444
|
+
};
|
|
2445
|
+
const menus = [menu];
|
|
2446
|
+
return {
|
|
2447
|
+
...state,
|
|
2448
|
+
isMenuOpen: true,
|
|
2449
|
+
focusedIndex: index,
|
|
2450
|
+
menus
|
|
2451
|
+
};
|
|
2452
|
+
};
|
|
2453
|
+
|
|
2454
|
+
const focusIndex = async (state, index) => {
|
|
2455
|
+
object(state);
|
|
2456
|
+
number(index);
|
|
2457
|
+
const {
|
|
2458
|
+
isMenuOpen
|
|
2459
|
+
} = state;
|
|
2460
|
+
if (isMenuOpen) {
|
|
2461
|
+
return openMenuAtIndex(state, index, /* focus */false);
|
|
945
2462
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
2463
|
+
return {
|
|
2464
|
+
...state,
|
|
2465
|
+
focusedIndex: index
|
|
2466
|
+
};
|
|
2467
|
+
};
|
|
2468
|
+
|
|
2469
|
+
const focusFirst = state => {
|
|
2470
|
+
const indexToFocus = first();
|
|
2471
|
+
return focusIndex(state, indexToFocus);
|
|
2472
|
+
};
|
|
2473
|
+
|
|
2474
|
+
const focus = state => {
|
|
2475
|
+
return focusFirst(state);
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2478
|
+
const focusLast = state => {
|
|
2479
|
+
const {
|
|
2480
|
+
titleBarEntries
|
|
2481
|
+
} = state;
|
|
2482
|
+
const indexToFocus = last(titleBarEntries);
|
|
2483
|
+
return focusIndex(state, indexToFocus);
|
|
2484
|
+
};
|
|
2485
|
+
|
|
2486
|
+
const focusNext = state => {
|
|
2487
|
+
const {
|
|
2488
|
+
titleBarEntries,
|
|
2489
|
+
focusedIndex
|
|
2490
|
+
} = state;
|
|
2491
|
+
const indexToFocus = next(titleBarEntries, focusedIndex);
|
|
2492
|
+
return focusIndex(state, indexToFocus);
|
|
2493
|
+
};
|
|
2494
|
+
|
|
2495
|
+
const focusPrevious = state => {
|
|
2496
|
+
const {
|
|
2497
|
+
titleBarEntries,
|
|
2498
|
+
focusedIndex
|
|
2499
|
+
} = state;
|
|
2500
|
+
const indexToFocus = previous(titleBarEntries, focusedIndex);
|
|
2501
|
+
return focusIndex(state, indexToFocus);
|
|
2502
|
+
};
|
|
2503
|
+
|
|
2504
|
+
const LeftClick = 0;
|
|
2505
|
+
|
|
2506
|
+
const toggleIndex = (state, index) => {
|
|
2507
|
+
const {
|
|
2508
|
+
isMenuOpen,
|
|
2509
|
+
focusedIndex
|
|
2510
|
+
} = state;
|
|
2511
|
+
if (isMenuOpen && focusedIndex === index) {
|
|
2512
|
+
return closeMenu(state, /* keepFocus */true);
|
|
2513
|
+
}
|
|
2514
|
+
return openMenuAtIndex(state, index, /* focus */false);
|
|
2515
|
+
};
|
|
2516
|
+
|
|
2517
|
+
const handleClick = (state, button, index) => {
|
|
2518
|
+
if (button !== LeftClick) {
|
|
2519
|
+
return state;
|
|
2520
|
+
}
|
|
2521
|
+
if (index === -1) {
|
|
2522
|
+
return state;
|
|
2523
|
+
}
|
|
2524
|
+
return toggleIndex(state, index);
|
|
2525
|
+
};
|
|
2526
|
+
|
|
2527
|
+
// TODO remove this file and merge with whenExpressions
|
|
2528
|
+
const TitleBarMenuBar = FocusTitleBarMenuBar;
|
|
2529
|
+
|
|
2530
|
+
const handleFocus = async state => {
|
|
2531
|
+
await invoke('Focus.setFocus', TitleBarMenuBar);
|
|
2532
|
+
return state;
|
|
2533
|
+
};
|
|
2534
|
+
|
|
2535
|
+
/**
|
|
2536
|
+
* @param {boolean} focus
|
|
2537
|
+
*/
|
|
2538
|
+
const openMenu = (state, focus) => {
|
|
2539
|
+
const {
|
|
2540
|
+
focusedIndex
|
|
2541
|
+
} = state;
|
|
2542
|
+
if (focusedIndex === -1) {
|
|
2543
|
+
return state;
|
|
955
2544
|
}
|
|
956
|
-
|
|
957
|
-
return dom;
|
|
2545
|
+
return openMenuAtIndex(state, focusedIndex, focus);
|
|
958
2546
|
};
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
return
|
|
2547
|
+
|
|
2548
|
+
const handleKeyArrowDownMenuClosed = state => {
|
|
2549
|
+
return openMenu(state, /* focus */true);
|
|
962
2550
|
};
|
|
963
2551
|
|
|
964
|
-
const
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
2552
|
+
const handleKeyArrowDownMenuOpen = state => {
|
|
2553
|
+
const {
|
|
2554
|
+
menus
|
|
2555
|
+
} = state;
|
|
2556
|
+
const menu = menus.at(-1);
|
|
2557
|
+
const newFocusedIndex = getIndexToFocusNext(menu);
|
|
2558
|
+
const newMenus = [...menus.slice(0, -1), {
|
|
2559
|
+
...menu,
|
|
2560
|
+
focusedIndex: newFocusedIndex
|
|
2561
|
+
}];
|
|
2562
|
+
return {
|
|
2563
|
+
...state,
|
|
2564
|
+
menus: newMenus
|
|
2565
|
+
};
|
|
977
2566
|
};
|
|
978
2567
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
return 'function';
|
|
991
|
-
case 'string':
|
|
992
|
-
return 'string';
|
|
993
|
-
case 'object':
|
|
994
|
-
if (value === null) {
|
|
995
|
-
return 'null';
|
|
996
|
-
}
|
|
997
|
-
if (Array.isArray(value)) {
|
|
998
|
-
return 'array';
|
|
999
|
-
}
|
|
1000
|
-
return 'object';
|
|
1001
|
-
case 'boolean':
|
|
1002
|
-
return 'boolean';
|
|
1003
|
-
default:
|
|
1004
|
-
return 'unknown';
|
|
1005
|
-
}
|
|
2568
|
+
const ifElse = (menuOpenFunction, menuClosedFunction) => {
|
|
2569
|
+
const ifElseFunction = (state, ...args) => {
|
|
2570
|
+
const {
|
|
2571
|
+
isMenuOpen
|
|
2572
|
+
} = state;
|
|
2573
|
+
if (isMenuOpen) {
|
|
2574
|
+
return menuOpenFunction(state, ...args);
|
|
2575
|
+
}
|
|
2576
|
+
return menuClosedFunction(state, ...args);
|
|
2577
|
+
};
|
|
2578
|
+
return ifElseFunction;
|
|
1006
2579
|
};
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
2580
|
+
|
|
2581
|
+
const handleKeyArrowDown = ifElse(handleKeyArrowDownMenuOpen, handleKeyArrowDownMenuClosed);
|
|
2582
|
+
|
|
2583
|
+
const handleKeyArrowLeftMenuClosed = state => {
|
|
2584
|
+
// TODO menu collapse
|
|
2585
|
+
return focusPrevious(state);
|
|
1012
2586
|
};
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
2587
|
+
|
|
2588
|
+
const closeOneMenu = state => {
|
|
2589
|
+
const {
|
|
2590
|
+
menus
|
|
2591
|
+
} = state;
|
|
2592
|
+
const parentMenu = menus.at(-2);
|
|
2593
|
+
const newParentMenu = {
|
|
2594
|
+
...parentMenu,
|
|
2595
|
+
expanded: false
|
|
2596
|
+
};
|
|
2597
|
+
const newMenus = [...menus.slice(0, -2), newParentMenu];
|
|
2598
|
+
return {
|
|
2599
|
+
...state,
|
|
2600
|
+
menus: newMenus
|
|
2601
|
+
};
|
|
2602
|
+
};
|
|
2603
|
+
|
|
2604
|
+
const handleKeyArrowLeftMenuOpen = state => {
|
|
2605
|
+
const {
|
|
2606
|
+
menus
|
|
2607
|
+
} = state;
|
|
2608
|
+
if (menus.length > 1) {
|
|
2609
|
+
return closeOneMenu(state);
|
|
1017
2610
|
}
|
|
2611
|
+
return focusPrevious(state);
|
|
1018
2612
|
};
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
2613
|
+
|
|
2614
|
+
const handleKeyArrowLeft = ifElse(handleKeyArrowLeftMenuOpen, handleKeyArrowLeftMenuClosed);
|
|
2615
|
+
|
|
2616
|
+
// TODO menu should not be needed initially, only when item is selected and menu is opened
|
|
2617
|
+
const handleKeyArrowRightMenuOpen = async state => {
|
|
2618
|
+
const {
|
|
2619
|
+
menus
|
|
2620
|
+
} = state;
|
|
2621
|
+
// if menu can open sub menu to the right -> do that
|
|
2622
|
+
const menu = menus.at(-1);
|
|
2623
|
+
const {
|
|
2624
|
+
items,
|
|
2625
|
+
focusedIndex,
|
|
2626
|
+
x,
|
|
2627
|
+
y
|
|
2628
|
+
} = menu;
|
|
2629
|
+
if (focusedIndex === -1) {
|
|
2630
|
+
return focusNext(state);
|
|
2631
|
+
}
|
|
2632
|
+
const item = items[focusedIndex];
|
|
2633
|
+
if (item.flags === SubMenu) {
|
|
2634
|
+
const subMenuEntries = await getMenuEntries(item.id);
|
|
2635
|
+
const subMenu = {
|
|
2636
|
+
level: menus.length,
|
|
2637
|
+
items: subMenuEntries,
|
|
2638
|
+
focusedIndex: 0,
|
|
2639
|
+
y: y + focusedIndex * 25,
|
|
2640
|
+
x: x + MENU_WIDTH
|
|
2641
|
+
};
|
|
2642
|
+
const newParentMenu = {
|
|
2643
|
+
...menu,
|
|
2644
|
+
expanded: true
|
|
2645
|
+
};
|
|
2646
|
+
const newMenus = [...menus.slice(0, -1), newParentMenu, subMenu];
|
|
2647
|
+
return {
|
|
2648
|
+
...state,
|
|
2649
|
+
menus: newMenus
|
|
2650
|
+
};
|
|
1023
2651
|
}
|
|
2652
|
+
return focusNext(state);
|
|
1024
2653
|
};
|
|
1025
2654
|
|
|
1026
|
-
const
|
|
1027
|
-
|
|
2655
|
+
const handleKeyArrowRight = ifElse(handleKeyArrowRightMenuOpen, focusNext);
|
|
2656
|
+
|
|
2657
|
+
const noop = state => {
|
|
2658
|
+
return state;
|
|
1028
2659
|
};
|
|
1029
2660
|
|
|
1030
|
-
const
|
|
1031
|
-
|
|
2661
|
+
const handleKeyArrowUpMenuOpen = state => {
|
|
2662
|
+
const {
|
|
2663
|
+
menus
|
|
2664
|
+
} = state;
|
|
2665
|
+
const menu = menus.at(-1);
|
|
2666
|
+
const previousIndex = getIndexToFocusPrevious(menu);
|
|
2667
|
+
const newMenus = [...menus.slice(0, -1), {
|
|
2668
|
+
...menu,
|
|
2669
|
+
focusedIndex: previousIndex
|
|
2670
|
+
}];
|
|
2671
|
+
return {
|
|
2672
|
+
...state,
|
|
2673
|
+
menus: newMenus
|
|
2674
|
+
};
|
|
1032
2675
|
};
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
2676
|
+
|
|
2677
|
+
const handleKeyArrowUp = ifElse(handleKeyArrowUpMenuOpen, noop);
|
|
2678
|
+
|
|
2679
|
+
const handleKeyEndMenuOpen = state => {
|
|
2680
|
+
const {
|
|
2681
|
+
menus
|
|
2682
|
+
} = state;
|
|
2683
|
+
const menu = menus[0];
|
|
2684
|
+
const newFocusedIndex = getIndexToFocusLast(menu.items);
|
|
2685
|
+
const newMenus = [{
|
|
2686
|
+
...menu,
|
|
2687
|
+
focusedIndex: newFocusedIndex
|
|
2688
|
+
}];
|
|
2689
|
+
return {
|
|
2690
|
+
...state,
|
|
2691
|
+
menus: newMenus
|
|
2692
|
+
};
|
|
1039
2693
|
};
|
|
1040
2694
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
2695
|
+
// TODO this is also use for pagedown -> maybe find a better name for this function
|
|
2696
|
+
const handleKeyEnd = ifElse(handleKeyEndMenuOpen, focusLast);
|
|
2697
|
+
|
|
2698
|
+
const handleKeyEnterMenuClosed = state => {
|
|
2699
|
+
return openMenu(state, /* focus */true);
|
|
2700
|
+
};
|
|
2701
|
+
|
|
2702
|
+
const handleKeyEnterMenuOpen = state => {
|
|
2703
|
+
// TODO
|
|
2704
|
+
// await Menu.selectCurrent()
|
|
2705
|
+
return state;
|
|
2706
|
+
};
|
|
2707
|
+
|
|
2708
|
+
const handleKeyEnter = ifElse(handleKeyEnterMenuOpen, handleKeyEnterMenuClosed);
|
|
2709
|
+
|
|
2710
|
+
const handleKeyEscapeMenuOpen = state => {
|
|
2711
|
+
const {
|
|
2712
|
+
menus
|
|
2713
|
+
} = state;
|
|
2714
|
+
if (menus.length > 1) {
|
|
2715
|
+
return closeOneMenu(state);
|
|
1046
2716
|
}
|
|
1047
|
-
return
|
|
2717
|
+
return closeMenu(state, /* keepFocus */true);
|
|
1048
2718
|
};
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
2719
|
+
|
|
2720
|
+
const handleKeyEscape = ifElse(handleKeyEscapeMenuOpen, noop);
|
|
2721
|
+
|
|
2722
|
+
const handleKeyHomeMenuOpen = state => {
|
|
2723
|
+
const {
|
|
2724
|
+
menus
|
|
2725
|
+
} = state;
|
|
2726
|
+
const menu = menus[0];
|
|
2727
|
+
const newFocusedIndex = getIndexToFocusFirst(menu.items);
|
|
2728
|
+
const newMenus = [{
|
|
2729
|
+
...menu,
|
|
2730
|
+
focusedIndex: newFocusedIndex
|
|
2731
|
+
}];
|
|
2732
|
+
return {
|
|
2733
|
+
...state,
|
|
2734
|
+
menus: newMenus
|
|
2735
|
+
};
|
|
1052
2736
|
};
|
|
1053
2737
|
|
|
1054
|
-
const
|
|
1055
|
-
|
|
2738
|
+
const handleKeyHome = ifElse(handleKeyHomeMenuOpen, focusFirst);
|
|
2739
|
+
|
|
2740
|
+
const handleKeySpaceMenuClosed = state => {
|
|
2741
|
+
return openMenu(state, /* focus */true);
|
|
1056
2742
|
};
|
|
1057
2743
|
|
|
1058
|
-
const
|
|
1059
|
-
|
|
2744
|
+
const handleKeySpaceMenuOpen = state => {
|
|
2745
|
+
// TODO
|
|
2746
|
+
// await Menu.selectCurrent()
|
|
2747
|
+
return state;
|
|
1060
2748
|
};
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
if (typeof letterSpacing !== 'number') {
|
|
1069
|
-
throw new TypeError('letterSpacing must be of type number');
|
|
1070
|
-
}
|
|
1071
|
-
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
1072
|
-
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
1073
|
-
const ctx = getContext();
|
|
1074
|
-
// @ts-ignore
|
|
1075
|
-
ctx.letterSpacing = letterSpacingString;
|
|
1076
|
-
ctx.font = fontString;
|
|
1077
|
-
const metrics = ctx.measureText(text);
|
|
1078
|
-
const width = metrics.width;
|
|
1079
|
-
return width;
|
|
2749
|
+
|
|
2750
|
+
// TODO this is same as handle key enter -> merge the functions
|
|
2751
|
+
const handleKeySpace = ifElse(handleKeySpaceMenuOpen, handleKeySpaceMenuClosed);
|
|
2752
|
+
|
|
2753
|
+
const executeMenuItemCommand = async item => {
|
|
2754
|
+
// TODO
|
|
2755
|
+
throw new Error('not implemented');
|
|
1080
2756
|
};
|
|
1081
2757
|
|
|
1082
|
-
const
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
return measureTextWidth(label, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
|
|
2758
|
+
const selectIndexIgnore = async (state, item) => {
|
|
2759
|
+
await executeMenuItemCommand();
|
|
2760
|
+
return state;
|
|
1086
2761
|
};
|
|
1087
2762
|
|
|
1088
|
-
const
|
|
2763
|
+
const selectIndexNone = async (state, item) => {
|
|
2764
|
+
await executeMenuItemCommand();
|
|
1089
2765
|
return {
|
|
1090
|
-
|
|
1091
|
-
titleBarEntries: [],
|
|
1092
|
-
focusedIndex: -1,
|
|
1093
|
-
isMenuOpen: false,
|
|
2766
|
+
...state,
|
|
1094
2767
|
menus: [],
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
2768
|
+
isMenuOpen: false
|
|
2769
|
+
};
|
|
2770
|
+
};
|
|
2771
|
+
|
|
2772
|
+
const selectIndexRestoreFocus = async (state, item) => {
|
|
2773
|
+
await executeMenuItemCommand();
|
|
2774
|
+
return {
|
|
2775
|
+
...state,
|
|
2776
|
+
menus: [],
|
|
2777
|
+
isMenuOpen: false
|
|
2778
|
+
};
|
|
2779
|
+
};
|
|
2780
|
+
|
|
2781
|
+
const selectIndexSubMenu = async (state, menu, index) => {
|
|
2782
|
+
const {
|
|
2783
|
+
menus
|
|
2784
|
+
} = state;
|
|
2785
|
+
const {
|
|
2786
|
+
items,
|
|
1101
2787
|
x,
|
|
1102
2788
|
y,
|
|
1103
|
-
|
|
1104
|
-
|
|
2789
|
+
level
|
|
2790
|
+
} = menu;
|
|
2791
|
+
const item = items[index];
|
|
2792
|
+
const subMenuEntries = await getMenuEntries(item.id);
|
|
2793
|
+
const subMenu = {
|
|
2794
|
+
level: menus.length,
|
|
2795
|
+
items: subMenuEntries,
|
|
2796
|
+
focusedIndex: -1,
|
|
2797
|
+
x: x + MENU_WIDTH,
|
|
2798
|
+
y: y + index * 25
|
|
2799
|
+
};
|
|
2800
|
+
const newParentMenu = {
|
|
2801
|
+
...menu,
|
|
2802
|
+
focusedIndex: index
|
|
2803
|
+
};
|
|
2804
|
+
const newMenus = [...menus.slice(0, level - 1), newParentMenu, subMenu];
|
|
2805
|
+
return {
|
|
2806
|
+
...state,
|
|
2807
|
+
menus: newMenus
|
|
1105
2808
|
};
|
|
1106
2809
|
};
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
2810
|
+
|
|
2811
|
+
const handleMenuClick = (state, level, index) => {
|
|
2812
|
+
const {
|
|
2813
|
+
menus
|
|
2814
|
+
} = state;
|
|
2815
|
+
const menu = menus[level];
|
|
2816
|
+
const item = menu.items[index];
|
|
2817
|
+
switch (item.flags) {
|
|
2818
|
+
case None:
|
|
2819
|
+
return selectIndexNone(state);
|
|
2820
|
+
case SubMenu:
|
|
2821
|
+
return selectIndexSubMenu(state, menu, index);
|
|
2822
|
+
case RestoreFocus:
|
|
2823
|
+
return selectIndexRestoreFocus(state);
|
|
2824
|
+
case Ignore:
|
|
2825
|
+
return selectIndexIgnore(state);
|
|
2826
|
+
default:
|
|
2827
|
+
return state;
|
|
1116
2828
|
}
|
|
1117
|
-
return withWidths;
|
|
1118
2829
|
};
|
|
1119
|
-
|
|
2830
|
+
|
|
2831
|
+
const handleMenuMouseOver = async (state, level, index) => {
|
|
2832
|
+
object(state);
|
|
2833
|
+
number(level);
|
|
2834
|
+
number(index);
|
|
1120
2835
|
const {
|
|
1121
|
-
|
|
1122
|
-
labelFontSize,
|
|
1123
|
-
labelFontWeight,
|
|
1124
|
-
labelLetterSpacing,
|
|
1125
|
-
labelPadding
|
|
2836
|
+
menus
|
|
1126
2837
|
} = state;
|
|
1127
|
-
const
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1130
|
-
|
|
2838
|
+
const menu = menus[level];
|
|
2839
|
+
const {
|
|
2840
|
+
items,
|
|
2841
|
+
focusedIndex,
|
|
2842
|
+
y,
|
|
2843
|
+
x
|
|
2844
|
+
} = menu;
|
|
2845
|
+
const item = items[index];
|
|
2846
|
+
if (focusedIndex === index) {
|
|
2847
|
+
if (index === -1) {
|
|
2848
|
+
return state;
|
|
2849
|
+
}
|
|
2850
|
+
if (item.flags === SubMenu && level === menus.length - 2) {
|
|
2851
|
+
const subMenu = menus[level + 1];
|
|
2852
|
+
if (subMenu.focusedIndex !== -1) {
|
|
2853
|
+
const newSubMenu = {
|
|
2854
|
+
...subMenu,
|
|
2855
|
+
focusedIndex: -1
|
|
2856
|
+
};
|
|
2857
|
+
const newMenus = [...menus.slice(0, -1), newSubMenu];
|
|
2858
|
+
return {
|
|
2859
|
+
...state,
|
|
2860
|
+
menus: newMenus
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
return state;
|
|
2865
|
+
}
|
|
2866
|
+
if (index === -1) {
|
|
2867
|
+
const newMenus = [...menus.slice(0, level), {
|
|
2868
|
+
...menu,
|
|
2869
|
+
focusedIndex: -1
|
|
2870
|
+
}];
|
|
2871
|
+
return {
|
|
2872
|
+
...state,
|
|
2873
|
+
menus: newMenus
|
|
2874
|
+
};
|
|
2875
|
+
}
|
|
2876
|
+
if (item.flags === SubMenu) {
|
|
2877
|
+
const item = items[index];
|
|
2878
|
+
const subMenuEntries = await getMenuEntries(item.id);
|
|
2879
|
+
const subMenu = {
|
|
2880
|
+
level: menus.length,
|
|
2881
|
+
items: subMenuEntries,
|
|
2882
|
+
focusedIndex: -1,
|
|
2883
|
+
y: y + index * 25,
|
|
2884
|
+
x: x + MENU_WIDTH
|
|
2885
|
+
};
|
|
2886
|
+
const newParentMenu = {
|
|
2887
|
+
...menu,
|
|
2888
|
+
focusedIndex: index
|
|
2889
|
+
};
|
|
2890
|
+
const newMenus = [...menus.slice(0, level - 1), newParentMenu, subMenu];
|
|
2891
|
+
return {
|
|
2892
|
+
...state,
|
|
2893
|
+
menus: newMenus
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
const newMenus = [...menus.slice(0, level), {
|
|
2897
|
+
...menu,
|
|
2898
|
+
focusedIndex: index
|
|
2899
|
+
}];
|
|
1131
2900
|
return {
|
|
1132
2901
|
...state,
|
|
1133
|
-
|
|
2902
|
+
menus: newMenus
|
|
2903
|
+
};
|
|
2904
|
+
};
|
|
2905
|
+
|
|
2906
|
+
const handleMouseOutMenuClosed = state => {
|
|
2907
|
+
return focusIndex(state, -1);
|
|
2908
|
+
};
|
|
2909
|
+
|
|
2910
|
+
const handleMouseOutMenuOpen = state => {
|
|
2911
|
+
return state;
|
|
2912
|
+
};
|
|
2913
|
+
|
|
2914
|
+
const handleMouseOut = ifElse(handleMouseOutMenuOpen, handleMouseOutMenuClosed);
|
|
2915
|
+
|
|
2916
|
+
const handleMouseOverMenuClosed = (state, index) => {
|
|
2917
|
+
return focusIndex(state, index);
|
|
2918
|
+
};
|
|
2919
|
+
|
|
2920
|
+
const handleMouseOverMenuOpen = async (state, index) => {
|
|
2921
|
+
if (index === -1) {
|
|
2922
|
+
return state;
|
|
2923
|
+
}
|
|
2924
|
+
return focusIndex(state, index);
|
|
2925
|
+
};
|
|
2926
|
+
|
|
2927
|
+
const handleMouseOver = ifElse(handleMouseOverMenuOpen, handleMouseOverMenuClosed);
|
|
2928
|
+
|
|
2929
|
+
const toggleMenu = state => {
|
|
2930
|
+
const {
|
|
2931
|
+
isMenuOpen
|
|
2932
|
+
} = state;
|
|
2933
|
+
if (isMenuOpen) {
|
|
2934
|
+
return closeMenu(state, /* keepFocus */true);
|
|
2935
|
+
}
|
|
2936
|
+
return openMenu(state, /* focus */false);
|
|
2937
|
+
};
|
|
2938
|
+
|
|
2939
|
+
const wrapCommand = fn => {
|
|
2940
|
+
const wrapped = async (uid, ...args) => {
|
|
2941
|
+
const {
|
|
2942
|
+
newState
|
|
2943
|
+
} = get(uid);
|
|
2944
|
+
const newerState = await fn(newState, ...args);
|
|
2945
|
+
set(uid, newState, newerState);
|
|
1134
2946
|
};
|
|
2947
|
+
return wrapped;
|
|
1135
2948
|
};
|
|
1136
2949
|
|
|
1137
2950
|
const commandMap = {
|
|
2951
|
+
'TitleBarMenuBar.closeMenu': closeMenu,
|
|
1138
2952
|
'TitleBarMenuBar.create': create,
|
|
2953
|
+
'TitleBarMenuBar.focus': wrapCommand(focus),
|
|
2954
|
+
'TitleBarMenuBar.focusFirst': wrapCommand(focusFirst),
|
|
2955
|
+
'TitleBarMenuBar.focusIndex': wrapCommand(focusLast),
|
|
2956
|
+
'TitleBarMenuBar.focusLast': wrapCommand(focusIndex),
|
|
2957
|
+
'TitleBarMenuBar.focusNext': wrapCommand(focusNext),
|
|
2958
|
+
'TitleBarMenuBar.focusPrevious': wrapCommand(focusPrevious),
|
|
2959
|
+
'TitleBarMenuBar.getCommands': getCommandIds,
|
|
2960
|
+
'TitleBarMenuBar.getKeyBindings': getKeyBindings,
|
|
2961
|
+
'TitleBarMenuBar.getMenus': getMenus,
|
|
1139
2962
|
'TitleBarMenuBar.getVirtualDom': getTitleBarMenuBarVirtualDom,
|
|
1140
|
-
'TitleBarMenuBar.
|
|
1141
|
-
'TitleBarMenuBar.
|
|
2963
|
+
'TitleBarMenuBar.handleClick': wrapCommand(handleClick),
|
|
2964
|
+
'TitleBarMenuBar.handleFocus': wrapCommand(handleFocus),
|
|
2965
|
+
'TitleBarMenuBar.handleKeyArrowDown': wrapCommand(handleKeyArrowDown),
|
|
2966
|
+
'TitleBarMenuBar.handleKeyArrowLeft': wrapCommand(handleKeyArrowLeft),
|
|
2967
|
+
'TitleBarMenuBar.handleKeyArrowRight': wrapCommand(handleKeyArrowRight),
|
|
2968
|
+
'TitleBarMenuBar.handleKeyArrowUp': wrapCommand(handleKeyArrowUp),
|
|
2969
|
+
'TitleBarMenuBar.handleKeyEnd': wrapCommand(handleKeyEnd),
|
|
2970
|
+
'TitleBarMenuBar.handleKeyEnter': wrapCommand(handleKeyEnter),
|
|
2971
|
+
'TitleBarMenuBar.handleKeyEscape': wrapCommand(handleKeyEscape),
|
|
2972
|
+
'TitleBarMenuBar.saveState': saveState,
|
|
2973
|
+
'TitleBarMenuBar.handleKeyHome': wrapCommand(handleKeyHome),
|
|
2974
|
+
'TitleBarMenuBar.handleKeySpace': wrapCommand(handleKeySpace),
|
|
2975
|
+
'TitleBarMenuBar.handleMenuClick': wrapCommand(handleMenuClick),
|
|
2976
|
+
'TitleBarMenuBar.handleMenuMouseOver': wrapCommand(handleMenuMouseOver),
|
|
2977
|
+
'TitleBarMenuBar.handleMouseOut': wrapCommand(handleMouseOut),
|
|
2978
|
+
'TitleBarMenuBar.handleMouseOver': wrapCommand(handleMouseOver),
|
|
2979
|
+
'TitleBarMenuBar.loadContent': wrapCommand(loadContent),
|
|
2980
|
+
'TitleBarMenuBar.render': doRender,
|
|
2981
|
+
'TitleBarMenuBar.toggleIndex': wrapCommand(toggleIndex),
|
|
2982
|
+
'TitleBarMenuBar.toggleMenu': wrapCommand(toggleMenu),
|
|
2983
|
+
'TitleBarMenuBar.terminate': terminate
|
|
1142
2984
|
};
|
|
1143
2985
|
|
|
1144
2986
|
const listen = async () => {
|
|
1145
|
-
await WebWorkerRpcClient.create({
|
|
2987
|
+
const rpc = await WebWorkerRpcClient.create({
|
|
1146
2988
|
commandMap: commandMap
|
|
1147
2989
|
});
|
|
2990
|
+
setRpc(rpc);
|
|
1148
2991
|
};
|
|
1149
2992
|
|
|
1150
2993
|
const main = async () => {
|