@lvce-editor/main-area-worker 9.11.0 → 9.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mainAreaWorkerMain.js +723 -662
- package/package.json +1 -1
|
@@ -118,579 +118,255 @@ const terminate = () => {
|
|
|
118
118
|
globalThis.close();
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
return
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const redistributeSizesWithRounding = groups => {
|
|
132
|
-
return groups.map(group => ({
|
|
133
|
-
...group,
|
|
134
|
-
size: Math.round(100 / groups.length)
|
|
135
|
-
}));
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
const withGroupsAndActiveGroup = (state, groups, activeGroupId) => {
|
|
139
|
-
return {
|
|
140
|
-
...state,
|
|
141
|
-
layout: {
|
|
142
|
-
...state.layout,
|
|
143
|
-
activeGroupId,
|
|
144
|
-
groups
|
|
145
|
-
}
|
|
146
|
-
};
|
|
121
|
+
const normalizeLine = line => {
|
|
122
|
+
if (line.startsWith('Error: ')) {
|
|
123
|
+
return line.slice('Error: '.length);
|
|
124
|
+
}
|
|
125
|
+
if (line.startsWith('VError: ')) {
|
|
126
|
+
return line.slice('VError: '.length);
|
|
127
|
+
}
|
|
128
|
+
return line;
|
|
147
129
|
};
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
130
|
+
const getCombinedMessage = (error, message) => {
|
|
131
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
132
|
+
if (message) {
|
|
133
|
+
return `${message}: ${stringifiedError}`;
|
|
134
|
+
}
|
|
135
|
+
return stringifiedError;
|
|
151
136
|
};
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
return
|
|
155
|
-
...state,
|
|
156
|
-
layout: {
|
|
157
|
-
...state.layout,
|
|
158
|
-
groups
|
|
159
|
-
}
|
|
160
|
-
};
|
|
137
|
+
const NewLine$2 = '\n';
|
|
138
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
139
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
161
140
|
};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
activeGroupId,
|
|
166
|
-
groups
|
|
167
|
-
} = state.layout;
|
|
168
|
-
|
|
169
|
-
// Find the group to close the tab from
|
|
170
|
-
const groupIndex = getGroupIndexById(state, groupId);
|
|
171
|
-
if (groupIndex === -1) {
|
|
172
|
-
return state;
|
|
141
|
+
const mergeStacks = (parent, child) => {
|
|
142
|
+
if (!child) {
|
|
143
|
+
return parent;
|
|
173
144
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return state;
|
|
145
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
146
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
147
|
+
if (childNewLineIndex === -1) {
|
|
148
|
+
return parent;
|
|
179
149
|
}
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
isEmpty: newTabs.length === 0,
|
|
196
|
-
tabs: newTabs
|
|
197
|
-
};
|
|
150
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
151
|
+
const childRest = child.slice(childNewLineIndex);
|
|
152
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
153
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
154
|
+
return parentFirstLine + childRest;
|
|
155
|
+
}
|
|
156
|
+
return child;
|
|
157
|
+
};
|
|
158
|
+
class VError extends Error {
|
|
159
|
+
constructor(error, message) {
|
|
160
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
161
|
+
super(combinedMessage);
|
|
162
|
+
this.name = 'VError';
|
|
163
|
+
if (error instanceof Error) {
|
|
164
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
198
165
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// If there are remaining groups, redistribute sizes
|
|
208
|
-
if (remainingGroups.length > 0) {
|
|
209
|
-
const redistributedGroups = redistributeSizesWithRounding(remainingGroups);
|
|
210
|
-
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0]?.id : activeGroupId;
|
|
211
|
-
return withGroupsAndActiveGroup(state, redistributedGroups, newActiveGroupId);
|
|
166
|
+
if (error.codeFrame) {
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
this.codeFrame = error.codeFrame;
|
|
169
|
+
}
|
|
170
|
+
if (error.code) {
|
|
171
|
+
// @ts-ignore
|
|
172
|
+
this.code = error.code;
|
|
212
173
|
}
|
|
213
|
-
|
|
214
|
-
// If no remaining groups, return empty layout
|
|
215
|
-
return withEmptyGroups(state);
|
|
216
174
|
}
|
|
217
|
-
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const getFocusedGroup = state => {
|
|
221
|
-
const {
|
|
222
|
-
layout
|
|
223
|
-
} = state;
|
|
224
|
-
const {
|
|
225
|
-
groups
|
|
226
|
-
} = layout;
|
|
227
|
-
return groups.find(group => group.focused);
|
|
228
|
-
};
|
|
175
|
+
}
|
|
229
176
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
177
|
+
class AssertionError extends Error {
|
|
178
|
+
constructor(message) {
|
|
179
|
+
super(message);
|
|
180
|
+
this.name = 'AssertionError';
|
|
234
181
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
182
|
+
}
|
|
183
|
+
const Object$1 = 1;
|
|
184
|
+
const Number$1 = 2;
|
|
185
|
+
const Array$1 = 3;
|
|
186
|
+
const String$1 = 4;
|
|
187
|
+
const Boolean$1 = 5;
|
|
188
|
+
const Function = 6;
|
|
189
|
+
const Null = 7;
|
|
190
|
+
const Unknown = 8;
|
|
191
|
+
const getType = value => {
|
|
192
|
+
switch (typeof value) {
|
|
193
|
+
case 'number':
|
|
194
|
+
return Number$1;
|
|
195
|
+
case 'function':
|
|
196
|
+
return Function;
|
|
197
|
+
case 'string':
|
|
198
|
+
return String$1;
|
|
199
|
+
case 'object':
|
|
200
|
+
if (value === null) {
|
|
201
|
+
return Null;
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(value)) {
|
|
204
|
+
return Array$1;
|
|
205
|
+
}
|
|
206
|
+
return Object$1;
|
|
207
|
+
case 'boolean':
|
|
208
|
+
return Boolean$1;
|
|
209
|
+
default:
|
|
210
|
+
return Unknown;
|
|
240
211
|
}
|
|
241
|
-
return closeTab(state, focusedGroup.id, activeTabId);
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
const closeAll$1 = state => {
|
|
245
|
-
return withEmptyGroups(state);
|
|
246
212
|
};
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
...group,
|
|
253
|
-
size: baseSize + (index === groups.length - 1 ? remainder : 0)
|
|
254
|
-
}));
|
|
213
|
+
const object = value => {
|
|
214
|
+
const type = getType(value);
|
|
215
|
+
if (type !== Object$1) {
|
|
216
|
+
throw new AssertionError('expected value to be of type object');
|
|
217
|
+
}
|
|
255
218
|
};
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
if (Number
|
|
259
|
-
|
|
219
|
+
const number = value => {
|
|
220
|
+
const type = getType(value);
|
|
221
|
+
if (type !== Number$1) {
|
|
222
|
+
throw new AssertionError('expected value to be of type number');
|
|
260
223
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
groups
|
|
267
|
-
} = layout;
|
|
268
|
-
const groupIndex = getGroupIndexById(state, groupId);
|
|
269
|
-
if (groupIndex === -1 || groups.length <= 1) {
|
|
270
|
-
return state;
|
|
224
|
+
};
|
|
225
|
+
const string = value => {
|
|
226
|
+
const type = getType(value);
|
|
227
|
+
if (type !== String$1) {
|
|
228
|
+
throw new AssertionError('expected value to be of type string');
|
|
271
229
|
}
|
|
272
|
-
const remainingGroups = groups.filter(group => group.id !== groupId);
|
|
273
|
-
const redistributedGroups = redistributeSizesWithRemainder(remainingGroups);
|
|
274
|
-
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0].id : activeGroupId;
|
|
275
|
-
return withGroupsAndActiveGroup(state, redistributedGroups, newActiveGroupId);
|
|
276
230
|
};
|
|
277
231
|
|
|
278
|
-
const
|
|
279
|
-
return
|
|
232
|
+
const isMessagePort = value => {
|
|
233
|
+
return value && value instanceof MessagePort;
|
|
280
234
|
};
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
layout
|
|
284
|
-
} = state;
|
|
285
|
-
const {
|
|
286
|
-
groups
|
|
287
|
-
} = layout;
|
|
288
|
-
const focusedGroup = groups.find(isFocused);
|
|
289
|
-
if (!focusedGroup) {
|
|
290
|
-
return state;
|
|
291
|
-
}
|
|
292
|
-
const {
|
|
293
|
-
activeTabId
|
|
294
|
-
} = focusedGroup;
|
|
295
|
-
if (activeTabId === undefined) {
|
|
296
|
-
return state;
|
|
297
|
-
}
|
|
298
|
-
return closeTab(state, focusedGroup.id, activeTabId);
|
|
235
|
+
const isMessagePortMain = value => {
|
|
236
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
299
237
|
};
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (!group) {
|
|
315
|
-
return state;
|
|
316
|
-
}
|
|
317
|
-
const {
|
|
318
|
-
activeTabId
|
|
319
|
-
} = group;
|
|
320
|
-
if (activeTabId === undefined) {
|
|
321
|
-
return state;
|
|
322
|
-
}
|
|
323
|
-
const newGroups = groups.map(g => {
|
|
324
|
-
if (g.id === targetGroupId) {
|
|
325
|
-
const newTabs = g.tabs.filter(tab => tab.id === activeTabId);
|
|
326
|
-
return {
|
|
327
|
-
...g,
|
|
328
|
-
activeTabId,
|
|
329
|
-
isEmpty: newTabs.length === 0,
|
|
330
|
-
tabs: newTabs
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
return g;
|
|
334
|
-
});
|
|
335
|
-
return {
|
|
336
|
-
...state,
|
|
337
|
-
layout: {
|
|
338
|
-
...layout,
|
|
339
|
-
groups: newGroups
|
|
238
|
+
const isOffscreenCanvas = value => {
|
|
239
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
240
|
+
};
|
|
241
|
+
const isInstanceOf = (value, constructorName) => {
|
|
242
|
+
return value?.constructor?.name === constructorName;
|
|
243
|
+
};
|
|
244
|
+
const isSocket = value => {
|
|
245
|
+
return isInstanceOf(value, 'Socket');
|
|
246
|
+
};
|
|
247
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
248
|
+
const isTransferrable = value => {
|
|
249
|
+
for (const fn of transferrables) {
|
|
250
|
+
if (fn(value)) {
|
|
251
|
+
return true;
|
|
340
252
|
}
|
|
341
|
-
}
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
342
255
|
};
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return undefined;
|
|
256
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
257
|
+
if (!value) {
|
|
258
|
+
return;
|
|
347
259
|
}
|
|
348
|
-
if (
|
|
349
|
-
|
|
260
|
+
if (isTransferrable(value)) {
|
|
261
|
+
transferrables.push(value);
|
|
262
|
+
return;
|
|
350
263
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
264
|
+
if (Array.isArray(value)) {
|
|
265
|
+
for (const item of value) {
|
|
266
|
+
walkValue(item, transferrables, isTransferrable);
|
|
267
|
+
}
|
|
268
|
+
return;
|
|
354
269
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
tabs
|
|
361
|
-
} = group;
|
|
362
|
-
const newTabs = tabs.filter(tab => tab.isDirty);
|
|
363
|
-
if (newTabs.length === tabs.length) {
|
|
364
|
-
return group;
|
|
270
|
+
if (typeof value === 'object') {
|
|
271
|
+
for (const property of Object.values(value)) {
|
|
272
|
+
walkValue(property, transferrables, isTransferrable);
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
365
275
|
}
|
|
366
|
-
const newActiveTabId = getNextActiveTabId(tabs, newTabs, activeTabId);
|
|
367
|
-
return {
|
|
368
|
-
...group,
|
|
369
|
-
activeTabId: newActiveTabId,
|
|
370
|
-
isEmpty: newTabs.length === 0,
|
|
371
|
-
tabs: newTabs
|
|
372
|
-
};
|
|
373
276
|
};
|
|
374
|
-
const
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
const newGroups = groups.map(closeSavedInGroup);
|
|
379
|
-
return withGroups(state, newGroups);
|
|
277
|
+
const getTransferrables = value => {
|
|
278
|
+
const transferrables = [];
|
|
279
|
+
walkValue(value, transferrables, isTransferrable);
|
|
280
|
+
return transferrables;
|
|
380
281
|
};
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
break;
|
|
282
|
+
const removeValues = (value, toRemove) => {
|
|
283
|
+
if (!value) {
|
|
284
|
+
return value;
|
|
285
|
+
}
|
|
286
|
+
if (Array.isArray(value)) {
|
|
287
|
+
const newItems = [];
|
|
288
|
+
for (const item of value) {
|
|
289
|
+
if (!toRemove.includes(item)) {
|
|
290
|
+
newItems.push(removeValues(item, toRemove));
|
|
391
291
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
292
|
+
}
|
|
293
|
+
return newItems;
|
|
294
|
+
}
|
|
295
|
+
if (typeof value === 'object') {
|
|
296
|
+
const newObject = Object.create(null);
|
|
297
|
+
for (const [key, property] of Object.entries(value)) {
|
|
298
|
+
if (!toRemove.includes(property)) {
|
|
299
|
+
newObject[key] = removeValues(property, toRemove);
|
|
395
300
|
}
|
|
396
|
-
currentState = closeTab(currentState, matchingGroup.id, matchingTab.id);
|
|
397
301
|
}
|
|
302
|
+
return newObject;
|
|
398
303
|
}
|
|
399
|
-
return
|
|
304
|
+
return value;
|
|
400
305
|
};
|
|
401
306
|
|
|
402
|
-
|
|
403
|
-
|
|
307
|
+
// workaround for electron not supporting transferrable objects
|
|
308
|
+
// as parameters. If the transferrable object is a parameter, in electron
|
|
309
|
+
// only an empty objected is received in the main process
|
|
310
|
+
const fixElectronParameters = value => {
|
|
311
|
+
const transfer = getTransferrables(value);
|
|
312
|
+
const newValue = removeValues(value, transfer);
|
|
313
|
+
return {
|
|
314
|
+
newValue,
|
|
315
|
+
transfer
|
|
316
|
+
};
|
|
404
317
|
};
|
|
405
|
-
|
|
406
|
-
const closeTabsRight = (state, groupId) => {
|
|
407
|
-
const {
|
|
408
|
-
layout
|
|
409
|
-
} = state;
|
|
410
|
-
const {
|
|
411
|
-
groups
|
|
412
|
-
} = layout;
|
|
413
|
-
const group = getGroupById(state, groupId);
|
|
414
|
-
if (!group) {
|
|
415
|
-
return state;
|
|
416
|
-
}
|
|
318
|
+
const getActualDataElectron = event => {
|
|
417
319
|
const {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
} =
|
|
421
|
-
if (
|
|
422
|
-
return
|
|
423
|
-
}
|
|
424
|
-
const activeTabIndex = tabs.findIndex(tab => tab.id === activeTabId);
|
|
425
|
-
if (activeTabIndex === -1) {
|
|
426
|
-
return state;
|
|
427
|
-
}
|
|
428
|
-
const newTabs = tabs.slice(0, activeTabIndex + 1);
|
|
429
|
-
if (newTabs.length === tabs.length) {
|
|
430
|
-
return state;
|
|
320
|
+
data,
|
|
321
|
+
ports
|
|
322
|
+
} = event;
|
|
323
|
+
if (ports.length === 0) {
|
|
324
|
+
return data;
|
|
431
325
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
isEmpty: newTabs.length === 0,
|
|
437
|
-
tabs: newTabs
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
return g;
|
|
441
|
-
});
|
|
442
|
-
return withGroups(state, newGroups);
|
|
326
|
+
return {
|
|
327
|
+
...data,
|
|
328
|
+
params: [...ports, ...data.params]
|
|
329
|
+
};
|
|
443
330
|
};
|
|
444
|
-
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
331
|
+
const attachEvents = that => {
|
|
332
|
+
const handleMessage = (...args) => {
|
|
333
|
+
const data = that.getData(...args);
|
|
334
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
335
|
+
data
|
|
336
|
+
}));
|
|
337
|
+
};
|
|
338
|
+
that.onMessage(handleMessage);
|
|
339
|
+
const handleClose = event => {
|
|
340
|
+
that.dispatchEvent(new Event('close'));
|
|
341
|
+
};
|
|
342
|
+
that.onClose(handleClose);
|
|
453
343
|
};
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
344
|
+
class Ipc extends EventTarget {
|
|
345
|
+
constructor(rawIpc) {
|
|
346
|
+
super();
|
|
347
|
+
this._rawIpc = rawIpc;
|
|
348
|
+
attachEvents(this);
|
|
458
349
|
}
|
|
459
|
-
|
|
350
|
+
}
|
|
351
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
352
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
353
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
354
|
+
const NewLine$1 = '\n';
|
|
355
|
+
const joinLines$1 = lines => {
|
|
356
|
+
return lines.join(NewLine$1);
|
|
460
357
|
};
|
|
461
|
-
const
|
|
462
|
-
const
|
|
463
|
-
|
|
358
|
+
const RE_AT = /^\s+at/;
|
|
359
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
360
|
+
const isNormalStackLine = line => {
|
|
361
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
464
362
|
};
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
return parent;
|
|
473
|
-
}
|
|
474
|
-
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
475
|
-
const childRest = child.slice(childNewLineIndex);
|
|
476
|
-
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
477
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
478
|
-
return parentFirstLine + childRest;
|
|
479
|
-
}
|
|
480
|
-
return child;
|
|
481
|
-
};
|
|
482
|
-
class VError extends Error {
|
|
483
|
-
constructor(error, message) {
|
|
484
|
-
const combinedMessage = getCombinedMessage(error, message);
|
|
485
|
-
super(combinedMessage);
|
|
486
|
-
this.name = 'VError';
|
|
487
|
-
if (error instanceof Error) {
|
|
488
|
-
this.stack = mergeStacks(this.stack, error.stack);
|
|
489
|
-
}
|
|
490
|
-
if (error.codeFrame) {
|
|
491
|
-
// @ts-ignore
|
|
492
|
-
this.codeFrame = error.codeFrame;
|
|
493
|
-
}
|
|
494
|
-
if (error.code) {
|
|
495
|
-
// @ts-ignore
|
|
496
|
-
this.code = error.code;
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
class AssertionError extends Error {
|
|
502
|
-
constructor(message) {
|
|
503
|
-
super(message);
|
|
504
|
-
this.name = 'AssertionError';
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
const Object$1 = 1;
|
|
508
|
-
const Number$1 = 2;
|
|
509
|
-
const Array$1 = 3;
|
|
510
|
-
const String$1 = 4;
|
|
511
|
-
const Boolean$1 = 5;
|
|
512
|
-
const Function = 6;
|
|
513
|
-
const Null = 7;
|
|
514
|
-
const Unknown = 8;
|
|
515
|
-
const getType = value => {
|
|
516
|
-
switch (typeof value) {
|
|
517
|
-
case 'number':
|
|
518
|
-
return Number$1;
|
|
519
|
-
case 'function':
|
|
520
|
-
return Function;
|
|
521
|
-
case 'string':
|
|
522
|
-
return String$1;
|
|
523
|
-
case 'object':
|
|
524
|
-
if (value === null) {
|
|
525
|
-
return Null;
|
|
526
|
-
}
|
|
527
|
-
if (Array.isArray(value)) {
|
|
528
|
-
return Array$1;
|
|
529
|
-
}
|
|
530
|
-
return Object$1;
|
|
531
|
-
case 'boolean':
|
|
532
|
-
return Boolean$1;
|
|
533
|
-
default:
|
|
534
|
-
return Unknown;
|
|
535
|
-
}
|
|
536
|
-
};
|
|
537
|
-
const object = value => {
|
|
538
|
-
const type = getType(value);
|
|
539
|
-
if (type !== Object$1) {
|
|
540
|
-
throw new AssertionError('expected value to be of type object');
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
const number = value => {
|
|
544
|
-
const type = getType(value);
|
|
545
|
-
if (type !== Number$1) {
|
|
546
|
-
throw new AssertionError('expected value to be of type number');
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
const string = value => {
|
|
550
|
-
const type = getType(value);
|
|
551
|
-
if (type !== String$1) {
|
|
552
|
-
throw new AssertionError('expected value to be of type string');
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
|
|
556
|
-
const isMessagePort = value => {
|
|
557
|
-
return value && value instanceof MessagePort;
|
|
558
|
-
};
|
|
559
|
-
const isMessagePortMain = value => {
|
|
560
|
-
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
561
|
-
};
|
|
562
|
-
const isOffscreenCanvas = value => {
|
|
563
|
-
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
564
|
-
};
|
|
565
|
-
const isInstanceOf = (value, constructorName) => {
|
|
566
|
-
return value?.constructor?.name === constructorName;
|
|
567
|
-
};
|
|
568
|
-
const isSocket = value => {
|
|
569
|
-
return isInstanceOf(value, 'Socket');
|
|
570
|
-
};
|
|
571
|
-
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
572
|
-
const isTransferrable = value => {
|
|
573
|
-
for (const fn of transferrables) {
|
|
574
|
-
if (fn(value)) {
|
|
575
|
-
return true;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
return false;
|
|
579
|
-
};
|
|
580
|
-
const walkValue = (value, transferrables, isTransferrable) => {
|
|
581
|
-
if (!value) {
|
|
582
|
-
return;
|
|
583
|
-
}
|
|
584
|
-
if (isTransferrable(value)) {
|
|
585
|
-
transferrables.push(value);
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
if (Array.isArray(value)) {
|
|
589
|
-
for (const item of value) {
|
|
590
|
-
walkValue(item, transferrables, isTransferrable);
|
|
591
|
-
}
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
if (typeof value === 'object') {
|
|
595
|
-
for (const property of Object.values(value)) {
|
|
596
|
-
walkValue(property, transferrables, isTransferrable);
|
|
597
|
-
}
|
|
598
|
-
return;
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
const getTransferrables = value => {
|
|
602
|
-
const transferrables = [];
|
|
603
|
-
walkValue(value, transferrables, isTransferrable);
|
|
604
|
-
return transferrables;
|
|
605
|
-
};
|
|
606
|
-
const removeValues = (value, toRemove) => {
|
|
607
|
-
if (!value) {
|
|
608
|
-
return value;
|
|
609
|
-
}
|
|
610
|
-
if (Array.isArray(value)) {
|
|
611
|
-
const newItems = [];
|
|
612
|
-
for (const item of value) {
|
|
613
|
-
if (!toRemove.includes(item)) {
|
|
614
|
-
newItems.push(removeValues(item, toRemove));
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
return newItems;
|
|
618
|
-
}
|
|
619
|
-
if (typeof value === 'object') {
|
|
620
|
-
const newObject = Object.create(null);
|
|
621
|
-
for (const [key, property] of Object.entries(value)) {
|
|
622
|
-
if (!toRemove.includes(property)) {
|
|
623
|
-
newObject[key] = removeValues(property, toRemove);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
return newObject;
|
|
627
|
-
}
|
|
628
|
-
return value;
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
// workaround for electron not supporting transferrable objects
|
|
632
|
-
// as parameters. If the transferrable object is a parameter, in electron
|
|
633
|
-
// only an empty objected is received in the main process
|
|
634
|
-
const fixElectronParameters = value => {
|
|
635
|
-
const transfer = getTransferrables(value);
|
|
636
|
-
const newValue = removeValues(value, transfer);
|
|
637
|
-
return {
|
|
638
|
-
newValue,
|
|
639
|
-
transfer
|
|
640
|
-
};
|
|
641
|
-
};
|
|
642
|
-
const getActualDataElectron = event => {
|
|
643
|
-
const {
|
|
644
|
-
data,
|
|
645
|
-
ports
|
|
646
|
-
} = event;
|
|
647
|
-
if (ports.length === 0) {
|
|
648
|
-
return data;
|
|
649
|
-
}
|
|
650
|
-
return {
|
|
651
|
-
...data,
|
|
652
|
-
params: [...ports, ...data.params]
|
|
653
|
-
};
|
|
654
|
-
};
|
|
655
|
-
const attachEvents = that => {
|
|
656
|
-
const handleMessage = (...args) => {
|
|
657
|
-
const data = that.getData(...args);
|
|
658
|
-
that.dispatchEvent(new MessageEvent('message', {
|
|
659
|
-
data
|
|
660
|
-
}));
|
|
661
|
-
};
|
|
662
|
-
that.onMessage(handleMessage);
|
|
663
|
-
const handleClose = event => {
|
|
664
|
-
that.dispatchEvent(new Event('close'));
|
|
665
|
-
};
|
|
666
|
-
that.onClose(handleClose);
|
|
667
|
-
};
|
|
668
|
-
class Ipc extends EventTarget {
|
|
669
|
-
constructor(rawIpc) {
|
|
670
|
-
super();
|
|
671
|
-
this._rawIpc = rawIpc;
|
|
672
|
-
attachEvents(this);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
676
|
-
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
677
|
-
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
678
|
-
const NewLine$1 = '\n';
|
|
679
|
-
const joinLines$1 = lines => {
|
|
680
|
-
return lines.join(NewLine$1);
|
|
681
|
-
};
|
|
682
|
-
const RE_AT = /^\s+at/;
|
|
683
|
-
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
684
|
-
const isNormalStackLine = line => {
|
|
685
|
-
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
686
|
-
};
|
|
687
|
-
const getDetails = lines => {
|
|
688
|
-
const index = lines.findIndex(isNormalStackLine);
|
|
689
|
-
if (index === -1) {
|
|
690
|
-
return {
|
|
691
|
-
actualMessage: joinLines$1(lines),
|
|
692
|
-
rest: []
|
|
693
|
-
};
|
|
363
|
+
const getDetails = lines => {
|
|
364
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
365
|
+
if (index === -1) {
|
|
366
|
+
return {
|
|
367
|
+
actualMessage: joinLines$1(lines),
|
|
368
|
+
rest: []
|
|
369
|
+
};
|
|
694
370
|
}
|
|
695
371
|
let lastIndex = index - 1;
|
|
696
372
|
while (++lastIndex < lines.length) {
|
|
@@ -1769,6 +1445,9 @@ const {
|
|
|
1769
1445
|
invokeAndTransfer,
|
|
1770
1446
|
set: set$1
|
|
1771
1447
|
} = create$3(RendererWorker);
|
|
1448
|
+
const handleModifiedStatusChange$1 = async (uri, modified) => {
|
|
1449
|
+
return invoke('Main.handleModifiedStatusChange', uri, modified);
|
|
1450
|
+
};
|
|
1772
1451
|
const showContextMenu2 = async (uid, menuId, x, y, args) => {
|
|
1773
1452
|
number(uid);
|
|
1774
1453
|
number(menuId);
|
|
@@ -1795,6 +1474,356 @@ const writeClipBoardText = async text => {
|
|
|
1795
1474
|
await invoke('ClipBoard.writeText', /* text */text);
|
|
1796
1475
|
};
|
|
1797
1476
|
|
|
1477
|
+
const getGroupIndexById = (state, groupId) => {
|
|
1478
|
+
const {
|
|
1479
|
+
layout
|
|
1480
|
+
} = state;
|
|
1481
|
+
const {
|
|
1482
|
+
groups
|
|
1483
|
+
} = layout;
|
|
1484
|
+
return groups.findIndex(group => group.id === groupId);
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1487
|
+
const redistributeSizesWithRounding = groups => {
|
|
1488
|
+
return groups.map(group => ({
|
|
1489
|
+
...group,
|
|
1490
|
+
size: Math.round(100 / groups.length)
|
|
1491
|
+
}));
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1494
|
+
const withGroupsAndActiveGroup = (state, groups, activeGroupId) => {
|
|
1495
|
+
return {
|
|
1496
|
+
...state,
|
|
1497
|
+
layout: {
|
|
1498
|
+
...state.layout,
|
|
1499
|
+
activeGroupId,
|
|
1500
|
+
groups
|
|
1501
|
+
}
|
|
1502
|
+
};
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
const withEmptyGroups = state => {
|
|
1506
|
+
return withGroupsAndActiveGroup(state, [], undefined);
|
|
1507
|
+
};
|
|
1508
|
+
|
|
1509
|
+
const withGroups = (state, groups) => {
|
|
1510
|
+
return {
|
|
1511
|
+
...state,
|
|
1512
|
+
layout: {
|
|
1513
|
+
...state.layout,
|
|
1514
|
+
groups
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1519
|
+
const closeTab = (state, groupId, tabId) => {
|
|
1520
|
+
const {
|
|
1521
|
+
activeGroupId,
|
|
1522
|
+
groups
|
|
1523
|
+
} = state.layout;
|
|
1524
|
+
|
|
1525
|
+
// Find the group to close the tab from
|
|
1526
|
+
const groupIndex = getGroupIndexById(state, groupId);
|
|
1527
|
+
if (groupIndex === -1) {
|
|
1528
|
+
return state;
|
|
1529
|
+
}
|
|
1530
|
+
const group = groups[groupIndex];
|
|
1531
|
+
// Check if the tab exists in the group
|
|
1532
|
+
const tabWasRemoved = group.tabs.some(tab => tab.id === tabId);
|
|
1533
|
+
if (!tabWasRemoved) {
|
|
1534
|
+
return state;
|
|
1535
|
+
}
|
|
1536
|
+
const newGroups = groups.map(grp => {
|
|
1537
|
+
if (grp.id === groupId) {
|
|
1538
|
+
const newTabs = grp.tabs.filter(tab => tab.id !== tabId);
|
|
1539
|
+
let newActiveTabId = grp.activeTabId;
|
|
1540
|
+
if (grp.activeTabId === tabId) {
|
|
1541
|
+
const tabIndex = grp.tabs.findIndex(tab => tab.id === tabId);
|
|
1542
|
+
if (newTabs.length > 0) {
|
|
1543
|
+
newActiveTabId = newTabs[Math.min(tabIndex, newTabs.length - 1)].id;
|
|
1544
|
+
} else {
|
|
1545
|
+
newActiveTabId = undefined;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
return {
|
|
1549
|
+
...grp,
|
|
1550
|
+
activeTabId: newActiveTabId,
|
|
1551
|
+
isEmpty: newTabs.length === 0,
|
|
1552
|
+
tabs: newTabs
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
return grp;
|
|
1556
|
+
});
|
|
1557
|
+
|
|
1558
|
+
// If the group has no tabs left after closing, remove the group
|
|
1559
|
+
const groupIsNowEmpty = newGroups[groupIndex].tabs.length === 0;
|
|
1560
|
+
if (groupIsNowEmpty) {
|
|
1561
|
+
const remainingGroups = newGroups.filter(group => group.id !== groupId);
|
|
1562
|
+
|
|
1563
|
+
// If there are remaining groups, redistribute sizes
|
|
1564
|
+
if (remainingGroups.length > 0) {
|
|
1565
|
+
const redistributedGroups = redistributeSizesWithRounding(remainingGroups);
|
|
1566
|
+
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0]?.id : activeGroupId;
|
|
1567
|
+
return withGroupsAndActiveGroup(state, redistributedGroups, newActiveGroupId);
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
// If no remaining groups, return empty layout
|
|
1571
|
+
return withEmptyGroups(state);
|
|
1572
|
+
}
|
|
1573
|
+
return withGroups(state, newGroups);
|
|
1574
|
+
};
|
|
1575
|
+
|
|
1576
|
+
const findTabInState = (state, groupId, tabId) => {
|
|
1577
|
+
const {
|
|
1578
|
+
layout
|
|
1579
|
+
} = state;
|
|
1580
|
+
const group = layout.groups.find(g => g.id === groupId);
|
|
1581
|
+
return group?.tabs.find(t => t.id === tabId);
|
|
1582
|
+
};
|
|
1583
|
+
|
|
1584
|
+
const saveEditor = async editorUid => {
|
|
1585
|
+
return invoke('Editor.save', editorUid);
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1588
|
+
const closeTabAndSave = async (state, groupId, tabId) => {
|
|
1589
|
+
const tab = findTabInState(state, groupId, tabId);
|
|
1590
|
+
if (!tab) {
|
|
1591
|
+
return state;
|
|
1592
|
+
}
|
|
1593
|
+
if (tab.editorUid !== -1) {
|
|
1594
|
+
const editorState = await saveEditor(tab.editorUid);
|
|
1595
|
+
if (!editorState?.modified && tab.uri) {
|
|
1596
|
+
await handleModifiedStatusChange$1(tab.uri, false);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
return closeTab(state, groupId, tabId);
|
|
1600
|
+
};
|
|
1601
|
+
|
|
1602
|
+
const getFocusedGroup = state => {
|
|
1603
|
+
const {
|
|
1604
|
+
layout
|
|
1605
|
+
} = state;
|
|
1606
|
+
const {
|
|
1607
|
+
groups
|
|
1608
|
+
} = layout;
|
|
1609
|
+
return groups.find(group => group.focused);
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
const closeActiveEditor = async state => {
|
|
1613
|
+
const focusedGroup = getFocusedGroup(state);
|
|
1614
|
+
if (!focusedGroup) {
|
|
1615
|
+
return state;
|
|
1616
|
+
}
|
|
1617
|
+
const {
|
|
1618
|
+
activeTabId
|
|
1619
|
+
} = focusedGroup;
|
|
1620
|
+
if (activeTabId === undefined) {
|
|
1621
|
+
return state;
|
|
1622
|
+
}
|
|
1623
|
+
return closeTabAndSave(state, focusedGroup.id, activeTabId);
|
|
1624
|
+
};
|
|
1625
|
+
|
|
1626
|
+
const closeAll$1 = state => {
|
|
1627
|
+
return withEmptyGroups(state);
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
const redistributeSizesWithRemainder = groups => {
|
|
1631
|
+
const baseSize = Math.floor(100 / groups.length);
|
|
1632
|
+
const remainder = 100 % groups.length;
|
|
1633
|
+
return groups.map((group, index) => ({
|
|
1634
|
+
...group,
|
|
1635
|
+
size: baseSize + (index === groups.length - 1 ? remainder : 0)
|
|
1636
|
+
}));
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1639
|
+
const closeEditorGroup$1 = (state, groupId) => {
|
|
1640
|
+
if (Number.isNaN(groupId)) {
|
|
1641
|
+
return state;
|
|
1642
|
+
}
|
|
1643
|
+
const {
|
|
1644
|
+
layout
|
|
1645
|
+
} = state;
|
|
1646
|
+
const {
|
|
1647
|
+
activeGroupId,
|
|
1648
|
+
groups
|
|
1649
|
+
} = layout;
|
|
1650
|
+
const groupIndex = getGroupIndexById(state, groupId);
|
|
1651
|
+
if (groupIndex === -1 || groups.length <= 1) {
|
|
1652
|
+
return state;
|
|
1653
|
+
}
|
|
1654
|
+
const remainingGroups = groups.filter(group => group.id !== groupId);
|
|
1655
|
+
const redistributedGroups = redistributeSizesWithRemainder(remainingGroups);
|
|
1656
|
+
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0].id : activeGroupId;
|
|
1657
|
+
return withGroupsAndActiveGroup(state, redistributedGroups, newActiveGroupId);
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1660
|
+
const isFocused = group => {
|
|
1661
|
+
return group.focused;
|
|
1662
|
+
};
|
|
1663
|
+
const closeFocusedTab = async state => {
|
|
1664
|
+
const {
|
|
1665
|
+
layout
|
|
1666
|
+
} = state;
|
|
1667
|
+
const {
|
|
1668
|
+
groups
|
|
1669
|
+
} = layout;
|
|
1670
|
+
const focusedGroup = groups.find(isFocused);
|
|
1671
|
+
if (!focusedGroup) {
|
|
1672
|
+
return state;
|
|
1673
|
+
}
|
|
1674
|
+
const {
|
|
1675
|
+
activeTabId
|
|
1676
|
+
} = focusedGroup;
|
|
1677
|
+
if (activeTabId === undefined) {
|
|
1678
|
+
return state;
|
|
1679
|
+
}
|
|
1680
|
+
return closeTabAndSave(state, focusedGroup.id, activeTabId);
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1683
|
+
const closeOtherTabs = (state, groupId) => {
|
|
1684
|
+
const {
|
|
1685
|
+
layout
|
|
1686
|
+
} = state;
|
|
1687
|
+
const {
|
|
1688
|
+
activeGroupId,
|
|
1689
|
+
groups
|
|
1690
|
+
} = layout;
|
|
1691
|
+
const targetGroupId = groupId ?? activeGroupId;
|
|
1692
|
+
if (targetGroupId === undefined) {
|
|
1693
|
+
return state;
|
|
1694
|
+
}
|
|
1695
|
+
const group = groups.find(g => g.id === targetGroupId);
|
|
1696
|
+
if (!group) {
|
|
1697
|
+
return state;
|
|
1698
|
+
}
|
|
1699
|
+
const {
|
|
1700
|
+
activeTabId
|
|
1701
|
+
} = group;
|
|
1702
|
+
if (activeTabId === undefined) {
|
|
1703
|
+
return state;
|
|
1704
|
+
}
|
|
1705
|
+
const newGroups = groups.map(g => {
|
|
1706
|
+
if (g.id === targetGroupId) {
|
|
1707
|
+
const newTabs = g.tabs.filter(tab => tab.id === activeTabId);
|
|
1708
|
+
return {
|
|
1709
|
+
...g,
|
|
1710
|
+
activeTabId,
|
|
1711
|
+
isEmpty: newTabs.length === 0,
|
|
1712
|
+
tabs: newTabs
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
return g;
|
|
1716
|
+
});
|
|
1717
|
+
return {
|
|
1718
|
+
...state,
|
|
1719
|
+
layout: {
|
|
1720
|
+
...layout,
|
|
1721
|
+
groups: newGroups
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
};
|
|
1725
|
+
|
|
1726
|
+
const getNextActiveTabId = (tabs, newTabs, activeTabId) => {
|
|
1727
|
+
if (activeTabId === undefined) {
|
|
1728
|
+
return undefined;
|
|
1729
|
+
}
|
|
1730
|
+
if (newTabs.some(tab => tab.id === activeTabId)) {
|
|
1731
|
+
return activeTabId;
|
|
1732
|
+
}
|
|
1733
|
+
const activeTabIndex = tabs.findIndex(tab => tab.id === activeTabId);
|
|
1734
|
+
if (activeTabIndex === -1 || newTabs.length === 0) {
|
|
1735
|
+
return undefined;
|
|
1736
|
+
}
|
|
1737
|
+
return newTabs[Math.min(activeTabIndex, newTabs.length - 1)].id;
|
|
1738
|
+
};
|
|
1739
|
+
const closeSavedInGroup = group => {
|
|
1740
|
+
const {
|
|
1741
|
+
activeTabId,
|
|
1742
|
+
tabs
|
|
1743
|
+
} = group;
|
|
1744
|
+
const newTabs = tabs.filter(tab => tab.isDirty);
|
|
1745
|
+
if (newTabs.length === tabs.length) {
|
|
1746
|
+
return group;
|
|
1747
|
+
}
|
|
1748
|
+
const newActiveTabId = getNextActiveTabId(tabs, newTabs, activeTabId);
|
|
1749
|
+
return {
|
|
1750
|
+
...group,
|
|
1751
|
+
activeTabId: newActiveTabId,
|
|
1752
|
+
isEmpty: newTabs.length === 0,
|
|
1753
|
+
tabs: newTabs
|
|
1754
|
+
};
|
|
1755
|
+
};
|
|
1756
|
+
const closeSaved$1 = state => {
|
|
1757
|
+
const {
|
|
1758
|
+
groups
|
|
1759
|
+
} = state.layout;
|
|
1760
|
+
const newGroups = groups.map(closeSavedInGroup);
|
|
1761
|
+
return withGroups(state, newGroups);
|
|
1762
|
+
};
|
|
1763
|
+
|
|
1764
|
+
const closeTabsByUris = (state, uris) => {
|
|
1765
|
+
let currentState = state;
|
|
1766
|
+
for (const uri of uris) {
|
|
1767
|
+
while (true) {
|
|
1768
|
+
const matchingGroup = currentState.layout.groups.find(group => {
|
|
1769
|
+
return group.tabs.some(tab => tab.uri === uri);
|
|
1770
|
+
});
|
|
1771
|
+
if (!matchingGroup) {
|
|
1772
|
+
break;
|
|
1773
|
+
}
|
|
1774
|
+
const matchingTab = matchingGroup.tabs.find(tab => tab.uri === uri);
|
|
1775
|
+
if (!matchingTab) {
|
|
1776
|
+
break;
|
|
1777
|
+
}
|
|
1778
|
+
currentState = closeTab(currentState, matchingGroup.id, matchingTab.id);
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return currentState;
|
|
1782
|
+
};
|
|
1783
|
+
|
|
1784
|
+
const getGroupById = (state, groupId) => {
|
|
1785
|
+
return state.layout.groups.find(group => group.id === groupId);
|
|
1786
|
+
};
|
|
1787
|
+
|
|
1788
|
+
const closeTabsRight = (state, groupId) => {
|
|
1789
|
+
const {
|
|
1790
|
+
layout
|
|
1791
|
+
} = state;
|
|
1792
|
+
const {
|
|
1793
|
+
groups
|
|
1794
|
+
} = layout;
|
|
1795
|
+
const group = getGroupById(state, groupId);
|
|
1796
|
+
if (!group) {
|
|
1797
|
+
return state;
|
|
1798
|
+
}
|
|
1799
|
+
const {
|
|
1800
|
+
activeTabId,
|
|
1801
|
+
tabs
|
|
1802
|
+
} = group;
|
|
1803
|
+
if (activeTabId === undefined) {
|
|
1804
|
+
return state;
|
|
1805
|
+
}
|
|
1806
|
+
const activeTabIndex = tabs.findIndex(tab => tab.id === activeTabId);
|
|
1807
|
+
if (activeTabIndex === -1) {
|
|
1808
|
+
return state;
|
|
1809
|
+
}
|
|
1810
|
+
const newTabs = tabs.slice(0, activeTabIndex + 1);
|
|
1811
|
+
if (newTabs.length === tabs.length) {
|
|
1812
|
+
return state;
|
|
1813
|
+
}
|
|
1814
|
+
const newGroups = groups.map(g => {
|
|
1815
|
+
if (g.id === groupId) {
|
|
1816
|
+
return {
|
|
1817
|
+
...g,
|
|
1818
|
+
isEmpty: newTabs.length === 0,
|
|
1819
|
+
tabs: newTabs
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
return g;
|
|
1823
|
+
});
|
|
1824
|
+
return withGroups(state, newGroups);
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1798
1827
|
const copyPath$1 = async (state, path) => {
|
|
1799
1828
|
string(path);
|
|
1800
1829
|
await writeClipBoardText(path);
|
|
@@ -1899,6 +1928,99 @@ const diff2 = uid => {
|
|
|
1899
1928
|
return result;
|
|
1900
1929
|
};
|
|
1901
1930
|
|
|
1931
|
+
const getActiveTabId$1 = state => {
|
|
1932
|
+
const {
|
|
1933
|
+
layout
|
|
1934
|
+
} = state;
|
|
1935
|
+
const {
|
|
1936
|
+
activeGroupId,
|
|
1937
|
+
groups
|
|
1938
|
+
} = layout;
|
|
1939
|
+
const activeGroup = groups.find(group => group.id === activeGroupId);
|
|
1940
|
+
return activeGroup?.activeTabId;
|
|
1941
|
+
};
|
|
1942
|
+
|
|
1943
|
+
const getSelectedTabBounds = state => {
|
|
1944
|
+
return {
|
|
1945
|
+
height: state.height - state.tabHeight,
|
|
1946
|
+
width: state.width,
|
|
1947
|
+
x: state.x,
|
|
1948
|
+
y: state.y + state.tabHeight
|
|
1949
|
+
};
|
|
1950
|
+
};
|
|
1951
|
+
|
|
1952
|
+
const getSelectedTabData = (state, groupIndex, index) => {
|
|
1953
|
+
const group = state.layout.groups[groupIndex];
|
|
1954
|
+
if (!group || index < 0 || index >= group.tabs.length) {
|
|
1955
|
+
return undefined;
|
|
1956
|
+
}
|
|
1957
|
+
const tab = group.tabs[index];
|
|
1958
|
+
return {
|
|
1959
|
+
group,
|
|
1960
|
+
groupId: group.id,
|
|
1961
|
+
tab,
|
|
1962
|
+
tabId: tab.id
|
|
1963
|
+
};
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
const getUpdatedGroups = (groups, groupIndex, needsLoading, tabId) => {
|
|
1967
|
+
return groups.map((group, index) => {
|
|
1968
|
+
if (index !== groupIndex) {
|
|
1969
|
+
return {
|
|
1970
|
+
...group,
|
|
1971
|
+
focused: false
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
const tabs = needsLoading ? group.tabs.map(tab => {
|
|
1975
|
+
if (tab.id !== tabId) {
|
|
1976
|
+
return tab;
|
|
1977
|
+
}
|
|
1978
|
+
return {
|
|
1979
|
+
...tab,
|
|
1980
|
+
errorMessage: '',
|
|
1981
|
+
loadingState: 'loading'
|
|
1982
|
+
};
|
|
1983
|
+
}) : group.tabs;
|
|
1984
|
+
return {
|
|
1985
|
+
...group,
|
|
1986
|
+
activeTabId: tabId,
|
|
1987
|
+
focused: true,
|
|
1988
|
+
tabs
|
|
1989
|
+
};
|
|
1990
|
+
});
|
|
1991
|
+
};
|
|
1992
|
+
|
|
1993
|
+
const getViewletModuleId$1 = async uri => {
|
|
1994
|
+
// Query RendererWorker for viewlet module ID (optional, may fail in tests)
|
|
1995
|
+
let viewletModuleId;
|
|
1996
|
+
try {
|
|
1997
|
+
viewletModuleId = await invoke('Layout.getModuleId', uri);
|
|
1998
|
+
} catch {
|
|
1999
|
+
// Viewlet creation is optional - silently ignore if RendererWorker isn't available
|
|
2000
|
+
}
|
|
2001
|
+
return viewletModuleId;
|
|
2002
|
+
};
|
|
2003
|
+
|
|
2004
|
+
const DiffEditor = 'DiffEditor';
|
|
2005
|
+
const EditorText = 'Editor';
|
|
2006
|
+
const ExtensionDetail = 'ExtensionDetail';
|
|
2007
|
+
const QuickPick = 'QuickPick';
|
|
2008
|
+
|
|
2009
|
+
const getViewletModuleIdForEditorInput = async editorInput => {
|
|
2010
|
+
switch (editorInput.type) {
|
|
2011
|
+
case 'diff-editor':
|
|
2012
|
+
return DiffEditor;
|
|
2013
|
+
case 'editor':
|
|
2014
|
+
return getViewletModuleId$1(editorInput.uri);
|
|
2015
|
+
case 'extension-detail-view':
|
|
2016
|
+
return ExtensionDetail;
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
const getViewletModuleId = async tab => {
|
|
2021
|
+
return tab.editorInput ? getViewletModuleIdForEditorInput(tab.editorInput) : invoke('Layout.getModuleId', tab.uri);
|
|
2022
|
+
};
|
|
2023
|
+
|
|
1902
2024
|
const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
|
|
1903
2025
|
await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
|
|
1904
2026
|
};
|
|
@@ -2178,54 +2300,6 @@ const findTabById = (state, tabId) => {
|
|
|
2178
2300
|
return undefined;
|
|
2179
2301
|
};
|
|
2180
2302
|
|
|
2181
|
-
// Counter for request IDs to handle race conditions
|
|
2182
|
-
let requestIdCounter = 0;
|
|
2183
|
-
const getNextRequestId = () => {
|
|
2184
|
-
return ++requestIdCounter;
|
|
2185
|
-
};
|
|
2186
|
-
|
|
2187
|
-
const getViewletModuleId$1 = async uri => {
|
|
2188
|
-
// Query RendererWorker for viewlet module ID (optional, may fail in tests)
|
|
2189
|
-
let viewletModuleId;
|
|
2190
|
-
try {
|
|
2191
|
-
viewletModuleId = await invoke('Layout.getModuleId', uri);
|
|
2192
|
-
} catch {
|
|
2193
|
-
// Viewlet creation is optional - silently ignore if RendererWorker isn't available
|
|
2194
|
-
}
|
|
2195
|
-
return viewletModuleId;
|
|
2196
|
-
};
|
|
2197
|
-
|
|
2198
|
-
const DiffEditor = 'DiffEditor';
|
|
2199
|
-
const ExtensionDetail = 'ExtensionDetail';
|
|
2200
|
-
const QuickPick = 'QuickPick';
|
|
2201
|
-
|
|
2202
|
-
const getViewletModuleIdForEditorInput = async editorInput => {
|
|
2203
|
-
switch (editorInput.type) {
|
|
2204
|
-
case 'diff-editor':
|
|
2205
|
-
return DiffEditor;
|
|
2206
|
-
case 'editor':
|
|
2207
|
-
return getViewletModuleId$1(editorInput.uri);
|
|
2208
|
-
case 'extension-detail-view':
|
|
2209
|
-
return ExtensionDetail;
|
|
2210
|
-
}
|
|
2211
|
-
};
|
|
2212
|
-
|
|
2213
|
-
const shouldLoadContentForTab = tab => {
|
|
2214
|
-
if (tab.editorInput && tab.editorInput.type !== 'editor') {
|
|
2215
|
-
return false;
|
|
2216
|
-
}
|
|
2217
|
-
if (!tab.uri) {
|
|
2218
|
-
return false;
|
|
2219
|
-
}
|
|
2220
|
-
if (tab.loadingState === 'loading') {
|
|
2221
|
-
return false;
|
|
2222
|
-
}
|
|
2223
|
-
if (tab.loadingState === 'loaded' && tab.editorUid !== -1) {
|
|
2224
|
-
return false;
|
|
2225
|
-
}
|
|
2226
|
-
return true;
|
|
2227
|
-
};
|
|
2228
|
-
|
|
2229
2303
|
const startContentLoading = async (oldState, state, tabId, path, requestId) => {
|
|
2230
2304
|
try {
|
|
2231
2305
|
const getLatestState = () => {
|
|
@@ -2240,76 +2314,17 @@ const startContentLoading = async (oldState, state, tabId, path, requestId) => {
|
|
|
2240
2314
|
return state;
|
|
2241
2315
|
};
|
|
2242
2316
|
|
|
2243
|
-
const getActiveTabId$1 = state => {
|
|
2244
|
-
const {
|
|
2245
|
-
layout
|
|
2246
|
-
} = state;
|
|
2247
|
-
const {
|
|
2248
|
-
activeGroupId,
|
|
2249
|
-
groups
|
|
2250
|
-
} = layout;
|
|
2251
|
-
const activeGroup = groups.find(g => g.id === activeGroupId);
|
|
2252
|
-
return activeGroup?.activeTabId;
|
|
2253
|
-
};
|
|
2254
|
-
const getSelectedTabData = (state, groupIndex, index) => {
|
|
2255
|
-
const group = state.layout.groups[groupIndex];
|
|
2256
|
-
if (!group || index < 0 || index >= group.tabs.length) {
|
|
2257
|
-
return undefined;
|
|
2258
|
-
}
|
|
2259
|
-
const tab = group.tabs[index];
|
|
2260
|
-
return {
|
|
2261
|
-
group,
|
|
2262
|
-
groupId: group.id,
|
|
2263
|
-
tab,
|
|
2264
|
-
tabId: tab.id
|
|
2265
|
-
};
|
|
2266
|
-
};
|
|
2267
|
-
const getUpdatedGroups = (groups, groupIndex, needsLoading, tabId) => {
|
|
2268
|
-
return groups.map((group, index) => {
|
|
2269
|
-
if (index !== groupIndex) {
|
|
2270
|
-
return {
|
|
2271
|
-
...group,
|
|
2272
|
-
focused: false
|
|
2273
|
-
};
|
|
2274
|
-
}
|
|
2275
|
-
const tabs = needsLoading ? group.tabs.map(tab => {
|
|
2276
|
-
if (tab.id !== tabId) {
|
|
2277
|
-
return tab;
|
|
2278
|
-
}
|
|
2279
|
-
return {
|
|
2280
|
-
...tab,
|
|
2281
|
-
errorMessage: '',
|
|
2282
|
-
loadingState: 'loading'
|
|
2283
|
-
};
|
|
2284
|
-
}) : group.tabs;
|
|
2285
|
-
return {
|
|
2286
|
-
...group,
|
|
2287
|
-
activeTabId: tabId,
|
|
2288
|
-
focused: true,
|
|
2289
|
-
tabs
|
|
2290
|
-
};
|
|
2291
|
-
});
|
|
2292
|
-
};
|
|
2293
|
-
const shouldCreateViewletForSelectedTab = tab => {
|
|
2294
|
-
return Boolean(tab.uri) && (tab.editorUid === -1 || !tab.loadingState || tab.loadingState === 'loading');
|
|
2295
|
-
};
|
|
2296
|
-
const getSelectedTabBounds = state => {
|
|
2297
|
-
return {
|
|
2298
|
-
height: state.height - state.tabHeight,
|
|
2299
|
-
width: state.width,
|
|
2300
|
-
x: state.x,
|
|
2301
|
-
y: state.y + state.tabHeight
|
|
2302
|
-
};
|
|
2303
|
-
};
|
|
2304
|
-
const getViewletModuleId = async tab => {
|
|
2305
|
-
return tab.editorInput ? getViewletModuleIdForEditorInput(tab.editorInput) : invoke('Layout.getModuleId', tab.uri);
|
|
2306
|
-
};
|
|
2307
2317
|
const maybeStartLoading = async (state, newState, tabId, tab, needsLoading, requestId) => {
|
|
2308
2318
|
if (needsLoading && tab.uri) {
|
|
2309
2319
|
return startContentLoading(state, newState, tabId, tab.uri, requestId);
|
|
2310
2320
|
}
|
|
2311
2321
|
return newState;
|
|
2312
2322
|
};
|
|
2323
|
+
|
|
2324
|
+
const shouldCreateViewletForSelectedTab = tab => {
|
|
2325
|
+
return Boolean(tab.uri) && (tab.editorUid === -1 || !tab.loadingState || tab.loadingState === 'loading');
|
|
2326
|
+
};
|
|
2327
|
+
|
|
2313
2328
|
const maybeCreateViewletForSelectedTab = async (state, newState, groupIndex, index, tabId, tab, uid, needsLoading, requestId, switchCommands) => {
|
|
2314
2329
|
const selectedTab = newState.layout.groups[groupIndex].tabs[index];
|
|
2315
2330
|
if (!shouldCreateViewletForSelectedTab(selectedTab)) {
|
|
@@ -2338,6 +2353,29 @@ const maybeCreateViewletForSelectedTab = async (state, newState, groupIndex, ind
|
|
|
2338
2353
|
}
|
|
2339
2354
|
return maybeStartLoading(state, stateWithViewlet, tabId, tab, needsLoading, requestId);
|
|
2340
2355
|
};
|
|
2356
|
+
|
|
2357
|
+
// Counter for request IDs to handle race conditions
|
|
2358
|
+
let requestIdCounter = 0;
|
|
2359
|
+
const getNextRequestId = () => {
|
|
2360
|
+
return ++requestIdCounter;
|
|
2361
|
+
};
|
|
2362
|
+
|
|
2363
|
+
const shouldLoadContentForTab = tab => {
|
|
2364
|
+
if (tab.editorInput && tab.editorInput.type !== 'editor') {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
if (!tab.uri) {
|
|
2368
|
+
return false;
|
|
2369
|
+
}
|
|
2370
|
+
if (tab.loadingState === 'loading') {
|
|
2371
|
+
return false;
|
|
2372
|
+
}
|
|
2373
|
+
if (tab.loadingState === 'loaded' && tab.editorUid !== -1) {
|
|
2374
|
+
return false;
|
|
2375
|
+
}
|
|
2376
|
+
return true;
|
|
2377
|
+
};
|
|
2378
|
+
|
|
2341
2379
|
const selectTab = async (state, groupIndex, index) => {
|
|
2342
2380
|
const {
|
|
2343
2381
|
layout,
|
|
@@ -3434,7 +3472,7 @@ const handleClickAction = async (state, action, rawGroupId) => {
|
|
|
3434
3472
|
}
|
|
3435
3473
|
};
|
|
3436
3474
|
|
|
3437
|
-
const handleClickCloseTab = (state, rawGroupIndex, rawIndex) => {
|
|
3475
|
+
const handleClickCloseTab = async (state, rawGroupIndex, rawIndex) => {
|
|
3438
3476
|
if (!rawGroupIndex || !rawIndex) {
|
|
3439
3477
|
return state;
|
|
3440
3478
|
}
|
|
@@ -3458,7 +3496,7 @@ const handleClickCloseTab = (state, rawGroupIndex, rawIndex) => {
|
|
|
3458
3496
|
const tab = group.tabs[index];
|
|
3459
3497
|
const groupId = group.id;
|
|
3460
3498
|
const tabId = tab.id;
|
|
3461
|
-
return
|
|
3499
|
+
return closeTabAndSave(state, groupId, tabId);
|
|
3462
3500
|
};
|
|
3463
3501
|
|
|
3464
3502
|
const handleClickTab = async (state, groupIndexRaw, indexRaw) => {
|
|
@@ -3605,6 +3643,7 @@ const newFile = async state => {
|
|
|
3605
3643
|
x: stateWithNewTab.x,
|
|
3606
3644
|
y: stateWithNewTab.y + stateWithNewTab.tabHeight
|
|
3607
3645
|
};
|
|
3646
|
+
const viewletModuleId = EditorText;
|
|
3608
3647
|
const stateWithViewlet = createViewletForTab(stateWithNewTab, tabId);
|
|
3609
3648
|
let intermediateState = stateWithViewlet;
|
|
3610
3649
|
|
|
@@ -3626,7 +3665,7 @@ const newFile = async state => {
|
|
|
3626
3665
|
if (actualEditorUid === -1) {
|
|
3627
3666
|
throw new Error(`invalid editorUid`);
|
|
3628
3667
|
}
|
|
3629
|
-
await createViewlet(
|
|
3668
|
+
await createViewlet(viewletModuleId, actualEditorUid, tabId, bounds, newTab.uri || '');
|
|
3630
3669
|
|
|
3631
3670
|
// After viewlet is created, get the latest state and mark it as ready
|
|
3632
3671
|
const {
|
|
@@ -5553,33 +5592,54 @@ const renderEventListeners = () => {
|
|
|
5553
5592
|
}];
|
|
5554
5593
|
};
|
|
5555
5594
|
|
|
5556
|
-
const
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5595
|
+
const getLatestStoredState = (uid, fallbackState, referenceTabId, referenceTabUri, allowMissingReference = false) => {
|
|
5596
|
+
const stateFromStore = get(uid);
|
|
5597
|
+
if (!stateFromStore) {
|
|
5598
|
+
return fallbackState;
|
|
5599
|
+
}
|
|
5600
|
+
const storedState = stateFromStore.newState;
|
|
5601
|
+
const storedActiveTabData = getActiveTab(storedState);
|
|
5602
|
+
if (!storedActiveTabData) {
|
|
5603
|
+
return fallbackState;
|
|
5604
|
+
}
|
|
5605
|
+
if (allowMissingReference && referenceTabId === undefined && referenceTabUri === undefined) {
|
|
5606
|
+
return storedState;
|
|
5607
|
+
}
|
|
5608
|
+
if (storedActiveTabData.tab.id === referenceTabId) {
|
|
5609
|
+
return storedState;
|
|
5610
|
+
}
|
|
5611
|
+
if (referenceTabUri && storedActiveTabData.tab.uri === referenceTabUri) {
|
|
5612
|
+
return storedState;
|
|
5613
|
+
}
|
|
5614
|
+
return fallbackState;
|
|
5561
5615
|
};
|
|
5562
|
-
|
|
5563
5616
|
const save = async state => {
|
|
5564
|
-
const
|
|
5617
|
+
const requestedActiveTabData = getActiveTab(state);
|
|
5618
|
+
const currentState = getLatestStoredState(state.uid, state, requestedActiveTabData?.tab.id, requestedActiveTabData?.tab.uri, !requestedActiveTabData);
|
|
5619
|
+
const activeTabData = getActiveTab(currentState);
|
|
5565
5620
|
if (!activeTabData) {
|
|
5566
|
-
return
|
|
5621
|
+
return currentState;
|
|
5567
5622
|
}
|
|
5568
5623
|
const {
|
|
5569
5624
|
tab
|
|
5570
5625
|
} = activeTabData;
|
|
5571
5626
|
if (tab.loadingState === 'loading') {
|
|
5572
|
-
return
|
|
5627
|
+
return currentState;
|
|
5573
5628
|
}
|
|
5574
|
-
await saveEditor(tab.editorUid);
|
|
5575
5629
|
if (!tab.isDirty) {
|
|
5576
|
-
|
|
5630
|
+
await saveEditor(tab.editorUid);
|
|
5631
|
+
return getLatestStoredState(state.uid, currentState, tab.id, tab.uri);
|
|
5577
5632
|
}
|
|
5578
|
-
const editorState = await
|
|
5579
|
-
|
|
5580
|
-
|
|
5633
|
+
const editorState = await saveEditor(tab.editorUid);
|
|
5634
|
+
const latestState = getLatestStoredState(state.uid, currentState, tab.id, tab.uri);
|
|
5635
|
+
if (editorState?.modified) {
|
|
5636
|
+
return latestState;
|
|
5637
|
+
}
|
|
5638
|
+
if (tab.uri) {
|
|
5639
|
+
await handleModifiedStatusChange$1(tab.uri, false);
|
|
5581
5640
|
}
|
|
5582
|
-
|
|
5641
|
+
const stateAfterModifiedStatusChange = getLatestStoredState(state.uid, latestState, tab.id, tab.uri);
|
|
5642
|
+
return updateTab(stateAfterModifiedStatusChange, tab.id, {
|
|
5583
5643
|
isDirty: false
|
|
5584
5644
|
});
|
|
5585
5645
|
};
|
|
@@ -5768,6 +5828,7 @@ const commandMap = {
|
|
|
5768
5828
|
'Main.focusNextTab': wrapCommand(focusNextTab),
|
|
5769
5829
|
'Main.focusPrevious': wrapCommand(focusPreviousTab),
|
|
5770
5830
|
'Main.focusPreviousTab': wrapCommand(focusPreviousTab),
|
|
5831
|
+
'Main.handleModifiedStatusChange': wrapCommand(handleModifiedStatusChange),
|
|
5771
5832
|
'Main.handleTabContextMenu': wrapCommand(handleTabContextMenu),
|
|
5772
5833
|
'Main.openInput': wrapCommand(openInput),
|
|
5773
5834
|
'Main.openUri': wrapCommand(openUri),
|